Интеграция ffmpeg4 с Pyglet. Какой правильный метод для идентификации потоков с альфа?
Мы пытаемся объединить 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. Приводит меня к мысли, что это не правильное место, чтобы найти правильную ценность.
1 ответ
ОК, нативный кодек просто не так хорош, как кодек 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")