Что такое фильтры битового потока в ffmpeg?

После внимательного прочтения документации FFmpeg Bitstream Filters я так и не понял, что это такое действительно для.

В документе указано, что фильтр:

выполняет модификации уровня битового потока без выполнения декодирования

Может ли кто-нибудь еще объяснить это мне? Вариант использования мог бы многое прояснить. Кроме того, там явно разные фильтры. Чем они отличаются?


person Joe    schedule 15.08.2015    source источник


Ответы (1)


Поясню на примере. Видеодекодеры FFmpeg обычно работают путем преобразования одного видеокадра за вызов в avcodec_decode_video2. Таким образом, ожидается, что ввод будет состоять из данных битового потока «одно изображение». Давайте на секунду рассмотрим вопрос перехода от файла (массива байтов на диске) к изображениям.

Для «сырых» (приложениеb) H264 (файлы .h264/.bin/.264) данные отдельных конечных единиц (битовые потоки заголовков sps/pps или данные кадра, закодированные в формате CABAC) объединяются в последовательность конечных единиц с началом код (00 00 01 XX) между ними, где XX — тип конечного блока. (Чтобы не допустить, чтобы сами окончательные данные содержали данные 00 00 01, это экранирование RBSP.) Итак, парсер кадра h264 может просто обрезать файл по маркерам стартового кода. Они ищут последовательные пакеты, которые начинаются с 00 00 01 включительно, до следующего вхождения 00 00 01 и исключая его. единиц, составляющих один кадр, в качестве входных данных для декодера h264.

Однако данные H264 в файлах .mp4 отличаются. Вы можете себе представить, что начальный код 00 00 01 можно считать избыточным, если в формате мультиплексирования уже есть маркеры длины, как в случае с mp4. Итак, чтобы сэкономить 3 байта на кадр, они убирают префикс 00 00 01. Они также помещают PPS/SPS в заголовок файла вместо того, чтобы добавлять его перед первым кадром, и в них также отсутствуют префиксы 00 00 01. Итак, если бы я ввел это в декодер h264, который ожидает префиксы для всех конечных единиц, это не сработало бы. Фильтр битового потока h264_mp4toannexb исправляет это, идентифицируя pps/sps в извлеченные части заголовка файла (ffmpeg называет это «дополнительными данными»), добавляя к этому и каждому nal из отдельных пакетов кадров начальный код и объединяя их вместе перед вводом их в декодер h264.

Теперь вы можете почувствовать, что существует очень тонкая грань между «парсером» и «фильтром битового потока». Это верно. Я думаю, что официальное определение состоит в том, что синтаксический анализатор берет последовательность входных данных и разбивает ее на кадры, не отбрасывая и не добавляя никаких данных. Единственное, что делает синтаксический анализатор, — это изменяет границы пакетов. С другой стороны, фильтру битового потока разрешено фактически изменять данные. Я не уверен, что это определение полностью верно (см., например, vp9 ниже), но это концептуальная причина, по которой mp4toannexb является BSF, а не синтаксическим анализатором (поскольку он добавляет префиксы 00 00 01).

Другие случаи, когда такие «настройки битового потока» помогают сохранить простоту и единообразие декодеров, но позволяют нам поддерживать все варианты файлов, которые существуют в дикой природе:

  • mpeg4 (divx) распаковка b-кадров (чтобы получить последовательности B-кадров, например IBP, которые закодированы как IPB, в AVI и имеют правильные временные метки, люди придумали эту концепцию упаковки B-кадров, где I-B-P / I-P-B упакованы в кадры как I-(PB)-(), т. е. третий пакет пуст, а второй содержит два кадра. Это означает отметку времени, связанную с P и кадр B на этапе декодирования верен. Это также означает, что у вас есть два кадра входных данных для одного пакета, что нарушает концепцию ffmpeg «один кадр в одном кадре», поэтому мы написали bsf для разделения пакета обратно на два — вместе с удалением маркера, который говорит, что пакет содержит два кадра, следовательно, BSF, а не синтаксический анализатор — перед вводом его в декодер.На практике это решает сложные проблемы с многопоточностью кадров. То же самое (называемое суперфреймами), но разбивает кадры в парсере, поэтому парсер Разделение /BSF теоретически не всегда идеально; возможно, VP9 следует называть BSF)
  • Преобразование hevc mp4 в приложениеb (та же история, что и выше, но для hevc)
  • Преобразование aac adts в asc (это в основном то же самое, что и h264/hevc приложениеb по сравнению с mp4, но для аудио в формате aac)
person Ronald S. Bultje    schedule 16.08.2015
comment
Обратите внимание, что фильтры и синтаксические анализаторы битовых потоков отличаются от обычных видео- и аудиофильтров тем, что они работают с закодированным (обычно сжатым) битовым потоком, тогда как обычные видео- и аудиофильтры работают с несжатыми видео- и аудиофайлами. - person mark4o; 16.08.2015
comment
Подобно тому, что говорит mark4o, обратите внимание, что при запуске ffmpeg и отсутствии копирования потока (т.е. фактического перекодирования видео) фильтры битового потока применяются после повторного кодирования. - person bhh1988; 16.11.2015
comment
фильтры Bitstream имеют какое-то отношение к извлечению потока? Например, могут ли они помочь быстрее извлекать субтитры или аудиопотоки из видеоконтейнера? - person user25; 18.08.2018
comment
Там (или как) такую ​​информацию можно [официально] найти? Пришел к этому ответу после очень долгого поиска. Почти все примеры демультиплексирования/декодирования просто не охватывают ни фильтрацию битовых потоков, ни анализ пакетов. Меня очень смущает тот факт, что мне просто нужно каким-то образом придумать специальные приемы для каждого возможного видеоформата, который я могу встретить, - пока я пытаюсь использовать ffmpeg, который позаботится обо всей тяжелой работе за вас, просто чтобы избежать всего этого. .. (Мой контекст: я пытаюсь демультиплексировать видеофайлы с помощью ffmpeg и передавать данные кадра в NVDEC для декодирования) - person vsvasya; 21.12.2018
comment
Если вы используете инструмент ffmpeg или стандартный API libavformat/avcodec, он позаботится об этом за вас. Фильтры битового потока автоматически вставляются, а парсеры автоматически используются при использовании официальных API read_frame() и send_packet(). Однако, если вы используете свои собственные демультиплексоры, вам необходимо убедиться, что выходные данные вашего демультиплексора находятся в том же формате, что и входные данные для декодера, и поэтому также доступны отдельные API BSF/парсера. - person Ronald S. Bultje; 21.12.2018
comment
Да, я использую libavformat API. Но он не фильтрует пакеты автоматически внутри read_frame(). Я пришел к решению, в котором я должен проверить данные пакета на наличие кода запуска 00 00 00 01 и пропустить пакет через фильтр, если нет. Может быть, это было изменено в новейших версиях ffmpeg? (Однако мы все равно должны поддерживать ffmpeg2.8...) - person vsvasya; 26.12.2018
comment
А, понятно. Они применяются автоматически только в комбинации read_frame()/send_packet(). Точнее, где-то внутри send_packet — это не наш случай, так как мы используем другой декодер (пытаемся связать его со стандартным демультиплексором ffmpeg). Так что все еще ищу, как избежать конкретных знаний о том, какой фильтр я должен применить к каждому из возможных форматов. Документы FFmpeg довольно скудны, а исходный код не так просто найти, не тратя много времени. - person vsvasya; 04.01.2019