Поясню на примере. Видеодекодеры 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