[C++] Wiedergeben eines benutzerdefinierten AVI-Datenstroms mit QtMultimedia


Answers

Es sieht so aus, als ob Qt das Konzept der Datenströme bereits zu einem gewissen Grad unterstützt - http://doc.qt.io/qt-5/qmediastreamscontrol.html#details zeigt, dass es zu den auswählbaren Arten von Streams für eine qmediastreamscontrol gehört.

Andere Dokumente wie http://doc.qt.io/qt-5/qmediaserviceproviderplugin.html legen nahe, dass Sie ein QMediaServiceProviderPlugin erstellen QMediaServiceProviderPlugin , das Video- und Audio-QMediaControl-Interfaces implementiert (möglicherweise durch Subclassing eines vorhandenen Mediendienstleisters), und auch eigene erstellen. QMediaControl Schnittstellenunterklasse zum Erstellen eines QMediaControl zur Verarbeitung Ihrer Rohdaten.

Wenn Sie auf diese Weise hoffentlich implementieren, können Sie vorhandene Funktionen zum Aufteilen der Streams, zum Bearbeiten von Headern und ähnlichen Funktionen verwenden.

Leider scheinen die Besonderheiten beim Aufbau eines QMediaService "außerhalb des Geltungsbereichs dieser Dokumentation zu liegen und es sollte Unterstützung in den relevanten Mailinglisten oder IRC-Kanälen gesucht werden." ( http://doc.qt.io/qt-5/qmediaservice.html#details ). Die Quelle ( http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/multimedia ) könnte dabei nützlich sein, zusätzlich zu der Quelle unter http: // code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins , das die directshow / gstreamer / coreaudio-Plugins enthält.

Auf jeden Fall würde ich versuchen, so wenig wie möglich zu untergliedern und neu zu implementieren.

Question

Ich muss eine benutzerdefinierte AVI-Datei wiedergeben, die einen klassischen Videostream, einen Audiostream, aber auch einen benutzerdefinierten Datenstrom enthält .

Der benutzerdefinierte Stream enthält Daten, die von einigen benutzerdefinierten Widgets angezeigt werden. Diese Widgets benötigen nur, dass jeder benutzerdefinierte Frame zur richtigen Zeit in einen Puffer geschrieben wird.

Unsere Anwendung basiert auf Qt und verwendet bereits QMediaPlayer / QVideoWidget , um herkömmliche Videos abzuspielen, aber der zusätzliche benutzerdefinierte Stream macht die Sache komplizierter, da QMediaPlayer nur das Video / Audio QMediaPlayer und alles andere ignoriert.

Ich möchte es vermeiden, das gesamte qt-multimedia neu zu erfinden, aber ich bin mir nicht sicher, wie ich das Beste aus den verfügbaren Qt-Klassen machen kann.

Meine Ideen sind bisher:

  1. Schreiben Sie eine benutzerdefinierte Mediaplayer- Klasse, die das Video mit ffmpeg demo- piert und dekodiert, das Timing implementiert, QAudioOutput zum Abspielen des QAudioOutput verwendet, einen Stream von QVideoFrame zum QVideoFrame auf dem Video erzeugt und die benutzerdefinierten Daten zur Visualisierung in einen Puffer schreibt.

    Das Problem : Um zu vermeiden, dass der Code zum Neuskalieren / Konvertieren der Video-Frames geschrieben wird, möchte ich QVideoWidget wiederverwenden, aber es scheint nur mit dem "echten" QMediaPlayer .

  2. Demuxieren Sie die Eingabedatei, und QMediaPlayer mit den AV-Streams ein. Demux die Eingabe mit ffmpeg (möglicherweise verlassen die Decodierung an das Qt-Backend), haben ein QIODevice , um nur die Video / Audio-Streams aus der Eingabedatei und eine andere abzurufen, um den Datenstrom abzurufen. Spielen Sie das Video / Audio mit QMediaPlayer .

                  +-------+                          
                  | QFile |                          
                  +---^---+                          
                      |                              
                   inherits                          
                      |                              
            +--------------------+
            |    MyAviDemuxer    |
            |                    |
            |  holds a queue of  |
            |  demuxed packets   |
            +--------------------+
            |                    |
      readDataPacket      readVideoPacket
            |                    |
    +-------v--------+  +--------v-----------+            +-----------+
    | MyCustomReader |  | MyVideoAudioStream +--inherits--> QIODevice |
    +----------------+  +--------+-----------+            +-----------+
                                 |       
                              setMedia                  
                                 |                  
                         +-------v-------+           
                         | QMediaPlayer  |           
                         +---------------+           

    Das Problem : Synchronisieren Sie das Timing des Datenstroms mit QMediaPlayer , behandeln Sie Header und Metadaten korrekt.

Ich bin leicht zu Option 1 geneigt, nur weil es mir mehr Kontrolle gibt, aber ich frage mich, ob ich eine einfachere Lösung (sogar nur Windows) verpasst habe.