Интеграция ffmpeg4 с Pyglet. Какой правильный метод для идентификации потоков с альфа?

350
Neon22

Мы пытаемся объединить ffmpeg4 с Pyglet.

Все идет очень хорошо, но у нас есть одна проблема:

Если файл VP9 (или VP8) создается с использованием ffmpeg4, из файлов png с альфа-версией мы получаем видеофайл (webm) с внутренним альфа-каналом. ffmpeg -i image_seq%03d.png -qmin 0 -qmax 50 -crf 5 -b:v 1M output.webm

Образцы веб-видео с альфа-версией можно найти на этой странице: https://simpl.info/videoalpha/

Однако при воспроизведении мы не получим альфу, если не переопределим кодек для libvpx. (такое же поведение можно продемонстрировать в CLI-версии ffplay). Мы упаковываем avutil, avcodec, etc.

Вопрос: Как правильно определить (в коде), что поток VP8 или VP9 имеет альфа-компонент? (Таким образом, мы можем загрузить его и получить к нему доступ AVFrame()для использования в качестве текстуры RGBA.)

Более конкретно:

Мы получаем FormatContext из файла с помощью AVFormatContextи поток AVStreamиз этого FormatContext.

Затем AVStreamмы получаем параметр codecpar.

Из AVCodecParametersмы можем рассмотреть codec_id (167 - VP9) и другие полезные параметры, такие как bits_per_coded_sample.

Интересно, что эти значения кажутся правильными для потоков, таких как H264 (codec_id = 27) в 24 битах, но помечены как 0 для кодека VP9. Приводит меня к мысли, что это не правильное место, чтобы найти правильную ценность.

2

1 ответ на вопрос

0
Neon22

ОК, нативный кодек просто не так хорош, как кодек libvpx, предоставляемый Webm peeps. Поэтому, если вы хотите получить эту альфа-информацию, вы должны перегрузить кодек при загрузке с помощью кодека libvpx.

Как вы это сделаете - см. Здесь: https://stackoverflow.com/questions/35340437/how-can-i-use-avformat-open-input-function-ffmpeg

По сути, третий аргумент avformat_open_input()должен быть av_find_input_format("libvpx")типомAVInputFormat

Если вы не уверены, является ли он кодеком VP8,9 в контексте файла, вам необходимо сначала проверить файл, обнаружить кодек, а затем перезаписать его при фактической загрузке. Смотрите здесь, чтобы узнать, как это сделать: https://stackoverflow.com/questions/14134589/what-does-the-avformat-open-input-do

и, наконец, - если вы хотите использовать собственный кодек вместо webm-кодека, если у него нет альфы (но зачем вам), то вы можете проверить, установлен ли его альфа-флаг, проверив данные стороны AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL.

Проверьте AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, если side_data начинается с (uint64_t) 1, есть слой прозрачности.

Но общее мнение таково: всегда использовать декодер libvpx.

Изменить: подробнее ID кодека Google VP8 - 139. и 167 - кодек Google VP9. Чтобы заменить версиями libvpx, вам нужно найти "libvpx-vp8" и "libvpx-vp9", используя, например, avcodec_find_decoder_by_name ("libvpx-vp9")

Похожие вопросы