[atmocontroller] Betrieb unter Windows

  • Hallo Igor,


    das Projekt ist mit Visual Studio 2005 erstellt, natürlich C++ unmanaged.


    Das DirectX SDK bringt nichts, da DirectShow nicht mehr in DirectX enthalten ist, sondern im Plattform SDK zu finden ist.
    Plattform SDK:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74DD6E2D-89C6-4E1E-AF00-FC7D70F15439&displaylang=en


    Ich schicke das komplette Projekt als Zip Datei, ist nicht sehr groß (ca. 300kB).


    Werde die Dateien noch etwas umbenennen, so dass man einen besseren Programmrumpf hat.



    Gruß Bernd

  • Bernd
    kann ich das SDK auch problemlos in meine Visual Studio 2003 einbinden? (hab leider nix neueres...) - ich dachte eigentlich bis zum DX9 SDK wäre DirectShow noch dort dabei gewesen... dachte erst bei den späteren SDK's hat mans dort rausgenommen... naja...


    hoffentlich kann VS 2003 das 2005 Projekt öffnen - oder gibts da im VS2005 ein "speichern als Version"?


    Igor

  • Das SDK geht schon mit VS2003, es ist die Frage ob man es wirklich braucht.


    VS2005 Projekte mit VS2003 zu öffnen geht nicht.


    Der Source ist als Zip ca. 450kB groß. Was soll ich tun? Als Dateianhang geht doch nur 50kB.

  • brshub

    Zitat

    VS2005 Projekte mit VS2003 zu öffnen geht nicht.


    und ein speichern unter als älter Version hat MS wohl nicht im Angebot?


    Kannst du mir evtl. gleich mal ein paar Screenshot der Suchpfad und evtl. weiteren .lib abhängigkeiten dazupacken? wenn ich dein Projekt schon nicht benutzen kann? - Ich hasse diese Sucherei.. :)


    Zitat

    Der Source ist als Zip ca. 450kB groß. Was soll ich tun? Als Dateianhang geht doch nur 50kB


    schau mal in deine PM's da findest du meine Mail Adresse...


    Igor

  • Hallo Igor,


    meine Idee ist folgende:


    der DirectShow Filter stellt ein Com-Interface zur Verfügung mit der Funktion HRESULT GetBitmapInfo(VARIANT* var); er registriert sich in der ROT (Running object table), erstellt mit SafeArrayCreate einen Speicherbereich, der prozessübergreifend verwendet werden kann. Er schreibt das 64x48 Thumbnail in das Array. AtmoWin.exe enumeriert die ROT und liest daraus das Interface, ruft GetBitmapInfo auf und bekommt aus dem SafeArray ein LPBITMAPINFO mit SafeArrayAcessData. Der Rest der Verarbeitung liegt bei AtmoWin. Der Filter wäre relativ rivial.
    Ich denke das müßte geschwindigkeitsmäßig gut klappen, wenn SafeArrayAccessData sich nicht ausbremst (von unterschiedlichen Prozessen).


    Ich könnte das testhalber in den Filter einbauen, aber erst am Wochenende.



    Gruß Bernd

  • brshub


    Vielleicht währe es umgekehrt besser? - d.h. der Filter ruft einen Com Server von AtmoWin auf - jedesmal wenn ein neues Frame vorliegt - sonst müsste man ja den Filter wieder via Polling abfragen - da könnte man dann ja wieder wesentlich schneller in das Problem der Synchronisation der beiden Zugriffe geraten - wenn man unkontrolliert von AtmoWin aus dem Buffer zugreift...


    Das größte Problem wovor es mir bei COM gruselt ist der Thread übergreifende Zugriff auf die Objekte... damit hab ich nicht wirklich gute Erfahrungen gemacht.


    ich würde dann lieber einen Com Objekt in die ROT eintragen was dann der Filter Aufruft und mir so die Frames reindrückt.... wenn du Dich in diese Richtung ein wenig auskennst --- wäre das natürlich gut...


    mein Com Objekt im AtmoWin müsste dann so aussehen:


    comObj->SetLiveViewSrcMode(EXTERNAL);


    comObj->SetNewPixelData(int format, VARIANT* var)


    comObj->SetLiveViewSrcMode(GDI);


    * SetLiveViewSrcMode
    - sollte aufgerufen werden - wenn der DirectShow Filter geladen wird, um die AtmoWin Quelle umzuschalten ... von GDI auf die externe Quelle.


    * SetNewPixelData( .... )
    --> format: RGB, HSV, YUV etc... damit ist dann Atmowin für die Umrechnung zuständig...
    --> var Pixeldaten...


    Zitat

    Ich denke das müßte geschwindigkeitsmäßig gut klappen, wenn SafeArrayAccessData sich nicht ausbremst (von unterschiedlichen Prozessen).


    aus dem Grund würde ich den Zugriff umdrehen - und der Filter teilt mir mit wann er neue Daten hat - so wäre der Zugriff auf den Buffer "seriell" und man läuft nicht gefahrt sich gegenseitig auszusperren - wenn man den Buffer via Polling abrufen würde?


    Am Wochenende würde uns ja reichen*g*


    Igor


    EDIT:
    SetLiveViewSrcMode - sollte während der Initialisierung des Filters aufgerufen werden - und beim auflösen der Filterkette - d.h. freigeben des COM Objektes... damit AtmoWin wieder in den GDI Modus schaltet...

  • brshub


    hab dir mal eine Mail geschickt mit einer AtmoWin - welche um einen COM Server erweitert wurde und diesen in die Running Object Table (ROT) einträgt - die Guids und .h Files sind im Paket enthalten...
    derzeit geben die Methoden nur MessageBoxen aus ... also nicht zu oft aufrufen sonst erstickst du unter MessageBoxen.


    Allerdings hab ich die .Exe nicht in die Registry als ComServer / Active eingetragen - d.h. die AtmoWin.exe muss händig gestartet werden denk ich damit es geht - d.h. ein CoCreateInstance(...) wird nicht funktionieren -- nur GetActiveObject( ...) sollte gehen.


    Freue mich schon auf ne Developer Session am WE... kann ab Samstag Nachmittag mich einmischen und testen.




    Igor

  • Igor


    ich werde schauen, was ich machen kann. Für eine Developer Session (ganzes WE) habe ich aber nicht die Zeit.
    Aben wenn ich ja einen COM Server schon habe, brauche ich das Interface ja nur noch zu implementieren.
    Ich denke es wäre gut, wenn der Filter die Funktion SetNewPixelData(int format, VARIANT* var) in einem separaten Thread aufruft, dass falls die Verarbeitung in AtmoWin.exe lange dauert, der Videostream in der VideoApp nicht blockiert ist.


    Bernd.

  • brshub
    naja du brauchst ja nur mein Interface aufrufen und die PixelDaten "reinschieben" - die Funktion kehrt unmittelbar zurück - d.h. die Verarbeitung der übergebenen Daten wird in einem extra Thread erfolgen. d.h. die Laufzeit meiner Funktion dürfte wohl nur bedingt durch den Call-Overhead über die Prozessgrenze bestehen und das anfertigen der Kopie der Daten (memcpy)...
    Vielleicht sollten wir bei den Pixeldaten noch ein Height und Width mitgeben - falls wir später nochmal die Auflösung ändern wollen? sind ja nur zwei Parameter...
    Wobei ich gerne festlegen würde das Width ein vielfaches von 8 sein sollte - damit lassen sich einige Optimierungen besser machen ;)


    Zitat

    Ich denke es wäre gut, wenn der Filter die Funktion SetNewPixelData(int format, VARIANT* var) in einem separaten Thread aufruft, dass falls die Verarbeitung in AtmoWin.exe lange dauert, der Videostream in der VideoApp nicht blockiert ist.


    Das hatte ich sowieso vor gehabt - weil mir schon klar ist dass ich deinen Thread nicht blockieren darf - sonst ruckelt das Video ja... ist mir klar.
    Du brauchst also eigentlich keinen eigenen Thread nur für den Aufruf - es sei denn du willst das "skalieren" der Quelldaten auch aus der eigentlichen Verarbeitungskette heraushalten?




    Und du stimmst meiner Idee zu - das de COM Server in der AtmoWin.exe implementiert ist? und du diesen aufrufst sobald du ein Frame erzeugt hast.


    Ebenso die Funktion für das Umschalten des AtmoWin Modus -- zwischen GDI und DirectShow (COM-Schnittstelle?) - diese müsstest du halt während der Initialisierung deines Filters und dessen Zerstörung aufrufen...


    Igor

  • Na das hört sich doch hervorragend an! Mit diesem zusätzlichen Filter umgeht man dann die CPU-Lastprobleme beim Live-Bild+Video. :) Ich bin schon jetzt auf die Ergebnisse gespannt!


    Viel Erfolg und gutes Gelingen am Wochenende, ich werde auf eine Test-Version warten... :D

  • Igor


    Zitat

    Und du stimmst meiner Idee zu - das de COM Server in der AtmoWin.exe implementiert ist? und du diesen aufrufst sobald du ein Frame erzeugt hast.


    Das klingt sehr logisch. Evtl. könnte man sich das mit der ROT dann auch sparen wenn man den COM server singleton-mäßig macht.


    Zitat

    Vielleicht sollten wir bei den Pixeldaten noch ein Height und Width mitgeben - falls wir später nochmal die Auflösung ändern wollen? sind ja nur zwei Parameter...


    Das müssen wir eigentlich nicht, denn es wird ja im Variant ein BITMAPINFO incl. Pixeldaten übergeben. Auch den ersten Parameter für das Format kann man sich sparen, wenn man z.B. bmiHeader.biCompression = FCC('YV12') setzt.



    Matthiaz
    mcdonald


    ich wollte eigentlich keine so hohe Erwartungshaltung erzeugen.



    Bernd

  • brshub


    so nachdem mein Browser mein Posting mittels Dr. Watson gekillt hat - nochmal in Kurzform;-)


    Zitat

    Das klingt sehr logisch. Evtl. könnte man sich das mit der ROT dann auch sparen wenn man den COM server singleton-mäßig macht.


    halte die Lösung mittels Rot für einfacher zu handeln - speziell was den Fall angeht das man die Exe sonst komplett in der Registry anmelden müsste damit CoCreateInstance(...) den ComServer selbst starten kann - was ich ehrlich gesagt nicht besonders mag... -- von daher wäre mir das Konstrukt mittels GetActiveObject lieber...



    Zitat

    Das müssen wir eigentlich nicht, denn es wird ja im Variant ein BITMAPINFO incl. Pixeldaten übergeben. Auch den ersten Parameter für das Format kann man sich sparen, wenn man z.B. bmiHeader.biCompression = FCC('YV12') setzt.


    nagut ist zwar ne kleine "Vergewaltigung" des Feldes biCompression so zu verwenden - aber wenn wir es dokumentieren - so dass es für andere verständlich ist was wir machen geht das klar.


    Ich würde aber der Funktion dann zwei Variant Byte Arrays übergeben wollen - PixelDaten und Header getrennt... wäre für die weitere Verarbeitung für mich praktischer... sonst muss ich es halt wieder aufteilen manuell.


    Wie erzeugst du in deinem Filter das 64x48 Bildchen? verwendest du für die Skalierung BitBlt oder ähnliches? das wäre keine gute Idee - günstiger ist es mit ein paar schleifen und vorher berechneten Abständen einfach die Pixel aus der Quelle zu kopieren - als Windows damit zu belästigen?


    Matthiaz
    mcdonald
    immer mit der Ruhe - noch ist das ganze experimentell - denn ob es mit jedem Player geht ist so ne Sache - da sich nicht jeder Player in seine Filterkette pfuschen läßt... und so brav unseren Filter mit aufruft.


    Igor

  • Zitat

    Original von Igor
    immer mit der Ruhe - noch ist das ganze experimentell - denn ob es mit jedem Player geht ist so ne Sache - da sich nicht jeder Player in seine Filterkette pfuschen läßt... und so brav unseren Filter mit aufruft. Igor


    Muss ja auch nicht jeder sein: einer reicht mir. :) VLC oder Media Player Classic erlauben doch sogar explizit ein Filter zu laden.


    Aber jetzt lassen wir den Bernd erst mal ein wenig zaubern, und schauen weiter. Ich will hier auch gar keine Hektik machen oder so, nur mal hin und wieder Hallo sagen... :)

  • Matthiaz..


    so Bernd kann mal loszaubern... für mir gibts ein neues Source Paket - aber nur auf meinem Rechner.... inkl. einer Beispielanwendung welche meine aktuelle Com Schnittstelle aufruft... und ein wahres Farbenchaos fabriziert... Hauptsache bunt... aber Bernd wird schon verstehen wie ichs meine...


    !!EXPERIMENTELL!! Als Stabil gilt weiterhin die 0.42!


    die AtmoWin Software:
    http://eldo.gotdns.com/atmowin/atmoX_bin.zip
    http://eldo.gotdns.com/atmowin/atmoX_src.zip


    http://eldo.gotdns.com/atmowin/comclient_atmoX_bin.zip
    http://eldo.gotdns.com/atmowin/comclient_atmoX_src.zip


    Damit der Com Client funktioniert muss die Datei AtmoWinA.Reg zunächst an eure Pfade angepasst werden und dann mittels Doppelklick in die Registry geladen werden... ;)


    Dann kann man wenn AtmoWin gestartet ist und sich im LiveView Modus befindet -- mit der "AtmoWinSampleComClient.exe" ein Feuerwerk aufs AtmoLight bekommen... ist eher ein Testprogramm für die Schnittstelle... ;) und für Bernd ne Vorlage...


    Allerdings bin ich zur Zeit noch nicht so recht zufrieden - mit der Konstruktion - viel zu viele Zugriffe auf Globale Objekte - kreuz und quer - und das bei Multithreaded Aktionen - das schreit nach Fehlern... und Synchronisationsproblemen ... bessere wäre wahrscheinlich statt eines Com Objektes was alles macht und die Ereignisse verteilt mehrere zu verwenden... die nur dann in der Rot herumlungern wenns auch Sinn macht... derzeit erfolgt die Kommunikation so:


    DirectShow --> CAtmoRemoteControlImpl::SetPixelData --> holt sich aktiven EffektThread - wenn Modus LiveView --> prüft ob LiveView auf Extern steht --> holt sich davon den Input Thread und castet den nach CAtmoExternalCaptureInput ... und füttert dort die Daten in den Thread...


    folgende Risiken sind dabei IMHO noch offen und unbehandelt:
    -- was passiert wenn jemand genau in dem Moment wo so eine Aktion läuft via Context Menü den Effect wechselt? - dann hat das Com Objekt plötzlich völlig falsche Zeiger in Händen... Ergebnis Dr. Watson..


    Was passiert wenn jemand während Com Calls laufen AtmoWin beendet? ...... nicht wirklich ne gute Idee...


    bessere wäre - ein Interface COM Objekt was immer Bestand hat - worüber man den aktuellen Effekt abrufen und setzen kann..., vielleicht die Statische Farben ändern...


    sobald der Modus LiveView gestartet ist - implementiert dieser Thread gleichzeit ein weiteres Interface ILiveView... oder so ... und trägt dieses in die Rot ein... sobald LiveView endet trägt er es aus...
    -- Problem: kann LiveView vom User via Context Menü beendet werden solange noch ne andere Anwendung Referenzen darauf hält? ;)
    (diese ILiveView - interface dient auch dem DirectShow Interface - um den Input zu switchen - d.h. GDI oder Extern ... sobald der Modus auf Extern schaltet - wird ein weiteres Objekt in die ROT gehangen - was den Zugriff auf den ExternCaptureSource ... vom DirectShow Plugin aus ermöglicht... somit hätte ich auch meine obigen Bedenken ein wenig beruhig - das Aufruf an das jetzige Test - Com - Konstrukt ins "Klo" greifen...


    so das war das Wort zum Samstag... ich wünsch ne Gute Nacht...


    Igor

  • ^^ Hui... Da lass ich jetzt erst mal lieber die Finger von. Das wird mir schon wieder viel zu komplex alles! Aber ihr macht das schon... :)


    Was mir nochmal eingefallen ist: können Programme erkennen, wenn Windows den Standby Modus aktiviert? Bisher läuft es ja einfach munter weiter, und bleibt bei der aktuellen Farbe "hängen". Angenehmer wäre es da, die optionale Farbwahl (die fürs Beenden) zu aktivieren, oder?


    Wäre praktisch, wenn das noch implementiert wird, weil bisher beende ich AtmoWin vorher immer per Skript, wenn Standby aktivert wird.

  • Matthiaz
    naja komplex ist das nicht ... man muss sich halt einlesen... dazu ist es jetzt denke ich mal noch nicht zu spät... je grösser der Code wird - destwo schwieriger wird es...


    Zitat

    Was mir nochmal eingefallen ist: können Programme erkennen, wenn Windows den Standby Modus aktiviert? Bisher läuft es ja einfach munter weiter, und bleibt bei der aktuellen Farbe "hängen". Angenehmer wäre es da, die optionale Farbwahl (die fürs Beenden) zu aktivieren, oder?


    Wäre praktisch, wenn das noch implementiert wird, weil bisher beende ich AtmoWin vorher immer per Skript, wenn Standby aktivert wird.


    klar können sie dass - probier mal mal die Version unten aus... sollte eigentlich gehen ... (ist aber immer noch Beta!) - da ich mit dem COM Schnittstellen noch Hadere wo ich diese am besten implementiere - hat zum Glück auf die Arbeit von Bernd so gut wie keine Auswirkung.


    brshub
    für Dich ist in der Version auch was dabei - da du ja noch kein Atmo Hardware hast? - gibt es jetzt unter Einstellungen in der Liste der Seriellen Schnittstellenen eine Namens "Dummy" - diese öffnet ein Fenster mit simuliertem AtmoLight :) *g*



    Igor



    http://eldo.gotdns.com/atmowin/atmoX_srcbin.zip

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!