DMO-Entwicklung - einige Probleme



  • Ich sitze immer noch an meinem Konverter für DirectShow nach VIP und komme jetzt nicht weiter:

    NAch den letzten Hinweisen habe ich mich an einem DMO für diese Konvertierung versucht:

    class Konvert : public IMediaObjectImpl<Konvert,1,1>//sollte eigentlich ...,1,0> werden
    

    Aber nun fangen meine Probleme an:

    Wie kann ich auf diese Weise einen DMO ohne Ausgänge erstellen? IMediaObjectImpl<...,1,0> schluckt der Compiler nicht (Arraylänge 0).
    (die Ausgabe dieses Filters soll nicht über DirectX-Kanäle erfolgen, sondern ins VIP-Framework)

    in der GetInputType bekomme ich Probleme, ein Array anzulegen:

    HRESULT Konvert::InternalGetInputType(...)
    {
      ...
      const GUID[] types = {
        MEDIASUBTYPE_RGB32,
        MEDIASUBTYPE_RGB24
      };
      ...
    }
    

    Mein Compiler beschwert sich über "cannot convert const struct _GUID to unsigned long" - wieso? (Anmerkung: Einzelne Variablen lassen sich korrekt initialisieren)

    Und nun zum Kernproblem:
    Wie kann ich dafür sorgen, daß die angeschlossene Datenquelle nach einem ProcessInput()-Aufruf abwartet, bis das aktuelle Bild weitergegeben wurde?



  • CStoll schrieb:

    Und nun zum Kernproblem:
    Wie kann ich dafür sorgen, daß die angeschlossene Datenquelle nach einem ProcessInput()-Aufruf abwartet, bis das aktuelle Bild weitergegeben wurde?

    Kannst Du nicht einfach vorher nicht zurückkehren, bevor alles von Dir verarbeitet ist?!
    Habe allerdings von DMO keine Ahnung.
    Oder wird die von aussen kontinuierlich aufgerufen?!
    Oder wie oder was?!



  • Sgt. Nukem schrieb:

    Kannst Du nicht einfach vorher nicht zurückkehren, bevor alles von Dir verarbeitet ist?

    Solange ich dort Runden drehe, kann ich allerdings nicht von VIP-Seite auf die Daten zugreifen.

    Habe allerdings von DMO keine Ahnung.

    Das sagst du mir jetzt? Du hast mir doch empfohlen, ein DMO zu verwenden.

    Oder wird die von aussen kontinuierlich aufgerufen?!

    So, wie ich das verstanden habe, ja.



  • CStoll schrieb:

    Sgt. Nukem schrieb:

    Kannst Du nicht einfach vorher nicht zurückkehren, bevor alles von Dir verarbeitet ist?

    Solange ich dort Runden drehe, kann ich allerdings nicht von VIP-Seite auf die Daten zugreifen.

    Wieso nicht?
    Den Puffer nach lokal kopieren und dann VIP_DoSomething(&buf) noch in der Func aufrufen?!

    Ansonsten: Threads. Dann aber gut syncen!

    CStoll schrieb:

    Habe allerdings von DMO keine Ahnung.

    Das sagst du mir jetzt? Du hast mir doch empfohlen, ein DMO zu verwenden.

    ROFL. Also Du wolltest wissen wie man das in DirectShow implementiert kriegt. Und ich hab' gesagt "wohl mit 'nem DirectShow Filter oder als DMO" -- daß ich sowas selber je gemacht habe habe ich sicher nicht behauptet! 💡

    CStoll schrieb:

    Oder wird die von aussen kontinuierlich aufgerufen?!

    So, wie ich das verstanden habe, ja.

    Ich meinte damit "threaded" - d.h. es kann ein weiterer Aufruf folgen während Du noch vorher bei der Abarbeitung in der Methode steckst.



  • Sgt. Nukem schrieb:

    CStoll schrieb:

    Sgt. Nukem schrieb:

    Kannst Du nicht einfach vorher nicht zurückkehren, bevor alles von Dir verarbeitet ist?

    Solange ich dort Runden drehe, kann ich allerdings nicht von VIP-Seite auf die Daten zugreifen.

    Wieso nicht?
    Den Puffer nach lokal kopieren und dann VIP_DoSomething(&buf) noch in der Func aufrufen?!

    Das VIP_DoSomething kommt aber auch von außen (wenn ein Filter auf VIP-Seite den Execute()-Befehl bekommt, schaut er nach, wie aktuell die anliegenden Eingangsdaten sind und ruft notfalls den Execute() seiner Datenquelle auf - Konvert::Execute() soll nun das letzte von ProcessInput() empfangene Bild nehmen und zurückliefern.

    Ansonsten: Threads. Dann aber gut syncen!

    Mit Threads habe ich ehrlich gesagt NULL praktische Erfahrung (die theoretischen Grundlagen sind da, aber das war's auch).



  • CStoll schrieb:

    Das VIP_DoSomething kommt aber auch von außen (wenn ein Filter auf VIP-Seite den Execute()-Befehl bekommt, schaut er nach, wie aktuell die anliegenden Eingangsdaten sind und ruft notfalls den Execute() seiner Datenquelle auf - Konvert::Execute() soll nun das letzte von ProcessInput() empfangene Bild nehmen und zurückliefern.

    Ganz hingehackt ginge vielleicht folgendes als Übergangslösung?!

    bool g_bHaveImage;
    char *g_Buffer;
    
    ctor
    {
       g_bHaveImage = false;
    }
    
    ProcessInput()
    {
       g_bHaveImage = false;
    
       g_Buffer = new char[width * height];
       CopyBuffer(input, g_Buffer);
    
       while(!g_bHaveImage)
          Sleep(0);
    }
    
    Execute()
    {
       CopyBuffer(g_Buffer, output);
    
       g_bHaveImage = true;
    }
    

    Allerdings solltest Du den Zugriff auf g_bHaveImage syncen.



  • Sgt. Nukem schrieb:

    bool g_bHaveImage;
    char *g_Buffer;
    
    ctor
    {
       g_bHaveImage = false;
    }
    
    ProcessInput()
    {
       g_bHaveImage = false;
    
       g_Buffer = new char[width * height];
       CopyBuffer(input, g_Buffer);
    
       while(!g_bHaveImage)
          Sleep(0);
    }
    
    Execute()
    {
       CopyBuffer(g_Buffer, output);
    
       g_bHaveImage = true;
    }
    

    Das wäre eine Überlegung wert - allerdings eher mit Membervariablen als global.

    Allerdings solltest Du den Zugriff auf g_bHaveImage syncen.

    Jetzt muß ich mich nur noch schlau machen, wie das (technisch) geht - und außerdem feststellen, ob ich damit nicht mein System totlege (Multi-Threading-Programmierung ist nicht meine Stärke).



  • CStoll schrieb:

    Allerdings solltest Du den Zugriff auf g_bHaveImage syncen.

    Jetzt muß ich mich nur noch schlau machen, wie das (technisch) geht - und außerdem feststellen, ob ich damit nicht mein System totlege (Multi-Threading-Programmierung ist nicht meine Stärke).

    Kannst ja erstmal so probieren. Ggf. noch eine if-Abfrage vor dem Kopieren mit weiteren Sleep()s.

    Für danach: Nach "CRITICAL SECTIONS" googlen.



  • Ja, das ist der erste Ansatz - aber vorher muß ich erstmal die Grundsätze zum Laufen bekommen 😉

    Aktuelle Fortschritte: Der Konverter steht als Fragment, parallel baue ich eine Testanwendung, um ihn praktisch ausprobieren zu können (Filtergraph aus einem Source-Filter (.MPG-File) und einem Ziel-Filter (DMO-Wrapper um meinen Konverter).
    * Wie kann ich dem DMO-Wrapper ein konkretes Objekt zuweisen? (die Init(REFCLSID,REFCLSID)-Methode ist nicht geeignet)
    oder
    * Wie kann ich aus einem bestehenden DMO-Wrapper auf den eingepackten DMO zurückgreifen?

    PS: Wie reagiert DirectShow eigentlich, wenn ich den Ausgang eines Filters offen lasse?

    PPS: Gibt es außer dir eigentlich noch andere Grafik-Experten, die hier unterwegs sind 🙄


Anmelden zum Antworten