Воспроизведение пользовательского потока данных avi с использованием QtMultimedia
Мне нужно воспроизвести пользовательский файл AVI, содержащий классический видеопоток, аудиопоток , а также пользовательский поток данных.
Пользовательский поток содержит данные, которые визуализируются с помощью некоторых пользовательских виджетов; эти виджеты нуждаются только в том, чтобы каждый пользовательский кадр записывался в буфер в нужное время.
Наше приложение основано на Qt и уже использует QMediaPlayer
/QVideoWidget
для воспроизведения традиционных видео, но дополнительный пользовательский поток усложняет работу, потому что AFAIK QMediaPlayer
воспроизводит только видео/аудио и игнорирует все остальное.
Я бы хотел избежать повторного использования всего qt-multimedia
, но я не уверен, как сделать все возможное из доступных классов Qt.
Мои идеи до сих пор:
-
Создайте собственный медиаплеер, который демультиплексирует и декодирует видео с помощью ffmpeg
, реализует синхронизацию, использует QAudioOutput
для воспроизведения звука, создает поток QVideoFrame
для воспроизведения на видео и записи пользовательских данных в некоторый буфер для визуализации.
Проблема. Чтобы избежать написания кода для масштабирования/преобразования видеокадров, я хотел бы повторно использовать QVideoWidget
, но, похоже, работает только с "реальным" QMediaPlayer
.
-
Demux входной файл и канал QMediaPlayer
с AV-потоками.
Demux введите ffmpeg
(возможно, оставив декодирование в бэкенд Qt), попросите QIODevice
извлечь только видео/аудиопотоки из входного файла, а другой - для получения потока данных. Воспроизведите видео/аудио с помощью QMediaPlayer
.
+-------+
| QFile |
+---^---+
|
inherits
|
+--------------------+
| MyAviDemuxer |
| |
| holds a queue of |
| demuxed packets |
+--------------------+
| |
readDataPacket readVideoPacket
| |
+-------v--------+ +--------v-----------+ +-----------+
| MyCustomReader | | MyVideoAudioStream +--inherits--> QIODevice |
+----------------+ +--------+-----------+ +-----------+
|
setMedia
|
+-------v-------+
| QMediaPlayer |
+---------------+
Проблема: синхронизировать синхронизацию потока данных с QMediaPlayer
, обработать заголовки и метаданные правильно.
Я немного склонен к варианту 1, только потому, что он дает мне больше контроля, но мне интересно, пропустил ли я более простое решение (даже для Windows).
Ответы
Ответ 1
Я понимаю, что у вас есть настроенная структура классов, но, возможно, вы можете использовать некоторые советы новичка-кодировщика.
Я думаю, вы должны использовать еще несколько базовых существующих типов данных вместе с вашими пользовательскими классами.
Решение для: синхронизации времени потока данных с QMediaPlayer:
Попробуйте использовать некоторые таймерные потоки (сочетание Thread и таймер). Создайте тот, который использует любой индекс потока из MyVideoAudioStream (используя время как переменную в индексе) и "Mycustomreader" (используя массив пакетов со временем как переменную в индексе) в качестве тела. Добавьте в тело некоторую логику, которая циклически проходит через позицию (@param: time) в QMediaPlayer. Из этого вы можете проанализировать код выполнения обоих одновременно. По мере увеличения времени позиция в QMediaPlayer и индекс вашего потока будут увеличиваться.
Если у вас нет указателя или позиции в пользовательском потоке, я настоятельно рекомендую вам создать его.
Ответ 2
Похоже, что Qt на самом деле уже в некоторой степени поддерживает концепцию потоков данных - http://doc.qt.io/qt-5/qmediastreamscontrol.html#details показывает, что это среди выбираемых типов потоков для контроля qmediastreams.
Другие документы, включая http://doc.qt.io/qt-5/qmediaserviceproviderplugin.html, предполагают, что вы можете создать QMediaServiceProviderPlugin
, который реализует видео и аудио интерфейсы QMediaControl (возможно, путем подкласса существующего поставщик медиа-услуг), также создайте собственный подкласмент интерфейса QMediaControl
, чтобы создать элемент управления для обработки ваших необработанных данных.
Надеемся, что реализация таким образом позволит вам использовать существующие возможности для разделения потоков, обработки заголовков и аналогичных функций.
К сожалению, особенности построения QMediaService, по-видимому, "вне сферы действия этой документации и поддержки в соответствующих списках рассылки или IRC-каналах". (http://doc.qt.io/qt-5/qmediaservice.html#details). Источник (http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/multimedia) мог бы использовать это, однако, в дополнение к, возможно, источнику в http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins, который включает в себя плагины directshow/gstreamer/coreaudio.
В любом случае я попытался бы подклассом и повторно реализовать как можно меньше