Lecture d’un stream de données avi personnalisé à l’aide de QtMultimedia

Je dois lire un fichier AVI personnalisé contenant un stream vidéo classique, un stream audio mais également un stream de données personnalisé .

Le stream personnalisé contient des données qui sont visualisées par certains widgets personnalisés; ces widgets ont seulement besoin que chaque cadre personnalisé soit écrit dans un tampon au bon moment.

Notre application est basée sur Qt et utilise déjà QMediaPlayer / QVideoWidget pour lire des vidéos traditionnelles, mais le stream personnalisé supplémentaire rend les choses plus compliquées car AFAIK QMediaPlayer ne QMediaPlayer que la vidéo / audio et ignore tout le rest.

Je voudrais éviter de réinventer tout le qt-multimedia , mais je ne suis pas sûr de savoir comment tirer le meilleur parti des classes Qt disponibles.


Mes idées sont jusqu’ici:

  1. Écrivez une classe de lecteur multimédia personnalisée qui démultiplie et décode la vidéo à l’aide de ffmpeg , implémente la synchronisation, utilise QAudioOutput pour lire l’audio, produit un stream de QVideoFrame à lire sur la vidéo et écrit les données personnalisées pour la visualisation.

    Le problème : pour éviter d’écrire le code pour redimensionner / convertir les images vidéo, je voudrais réutiliser QVideoWidget , mais il ne semble fonctionner qu’avec le “vrai” QMediaPlayer .

  2. Demux le fichier d’entrée et alimente QMediaPlayer avec les stream AV. Demux l’entrée avec ffmpeg (en laissant éventuellement le décodage au backend Qt), dispose d’un QIODevice pour récupérer uniquement les stream vidéo / audio du fichier d’entrée et un autre pour récupérer le stream de données. Jouez la vidéo / audio avec QMediaPlayer .

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

    Le problème : synchroniser la synchronisation du stream de données avec QMediaPlayer , gérer correctement les en-têtes et les métadonnées.


Je suis légèrement enclin à l’option 1, simplement parce que cela me donne plus de contrôle, mais je me demande si j’ai manqué une solution plus simple (même Windows uniquement).

Je comprends que vous avez une structure de cours assez personnalisée, mais vous pourriez peut-être utiliser les conseils d’un débutant en programmation. Je pense que vous devriez utiliser des types de données existants plus basiques avec vos classes personnalisées.

Solution pour: synchroniser la synchronisation du stream de données avec QMediaPlayer:
Essayez d’utiliser des fils de timer (combinaison de filetage et de timer ). Faites-en un qui utilise quel que soit l’index du stream de MyVideoAudioStream (en utilisant l’heure comme variable dans l’index) et “Mycustomreader” (en utilisant un tableau de paquets avec le temps comme variable dans l’index) comme son corps. Ajoutez dans le corps une logique qui parcourt la position (@param: time) dans QMediaPlayer. De là, vous pouvez parsingr le code d’exécution des deux en même temps. À mesure que le temps augmente, la position dans QMediaPlayer et l’index de votre stream augmenteraient.

Si vous n’avez pas d’index ou de position dans votre stream personnalisé, je vous suggère fortement d’en créer un.

Il semble que Qt supporte déjà le concept de stream de données dans une certaine mesure – http://doc.qt.io/qt-5/qmediastreamscontrol.html#details montre qu’il fait partie des types de stream sélectionnables pour un qmediastreamscontrol.

D’autres documents, notamment http://doc.qt.io/qt-5/qmediaserviceproviderplugin.html, suggèrent que vous puissiez créer un QMediaServiceProviderPlugin qui implémente des interfaces QMediaControl vidéo et audio (éventuellement en sous-classant un fournisseur de service de média existant), et créez également le vôtre. QMediaControl sous-classe d’interface QMediaControl pour créer un contrôle pour gérer vos données brutes.

Nous espérons que la mise en œuvre de cette manière vous permettra d’utiliser les fonctionnalités existantes pour séparer les stream, gérer les en-têtes et les fonctionnalités similaires.

Malheureusement, les spécificités de la création d’un QMediaService semblent être “hors de la scope de cette documentation et une assistance sur les listes de diffusion ou les canaux IRC pertinents doit être recherchée”. ( http://doc.qt.io/qt-5/qmediaservice.html#details ). La source ( http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/multimedia ) pourrait être utile pour cela, en plus, peut-être, de la source sur http: // code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins , qui inclut les plugins directshow / gstreamer / coreaudio.

En tout cas, j’essaierais de sous-classer et de ré-implémenter le moins possible