Как разобрать модуль доступа в h.264

Я работаю в проекте, который должен сократить некоторые Access units в H.264 Необработанный элементарный поток, например, удалить 4 единицы доступа и воспроизвести оставшееся видео.

За это я взял Access unit Delimiter (NAL Unit Type:9) в качестве границы для Access Unit и вырезать видео, но видео закончилось потерей пакета. Но если бы я взял Sequence parameter set (NAL Unit type :7) как граничное, результирующее воспроизведение видео без потери пакетов.
Кто-нибудь, пожалуйста, помогите мне, как решить эту проблему: где я должен вырезать видео?

2 ответа

Поскольку вы не описали свой поток более подробно, например, какие NALU присутствуют и как они отформатированы, вот некоторые общие рекомендации:

Вам всегда нужен SPS/PPS, поскольку они содержат информацию о том, как декодировать кадры. Я предполагаю, что вы получаете поток типа Приложения B, в этом случае кешируйте последний SPS/PPS, пока не появится новый, декодируйте оставшиеся изображения со старым и затем примените новый.

Если у вас есть AUD NALU, то у вас уже есть конец последнего блока доступа, и вы можете легко разделить видео, и не нужно много делать.

В случае, если вам нужно копать глубже, вот выдержка из спецификаций, касающихся порядка блоков NAL и того, как обнаружить первый блок VAL NAL первичного кодированного изображения.

Из МСЭ-Т H.264 (05/2013)

7.4.1.2.3 Порядок блоков NAL и кодированных изображений и привязка к блокам доступа

В этом разделе указывается порядок блоков NAL и кодированных изображений, а также привязка к модулю доступа для кодированных видеопоследовательностей, которые соответствуют одному или нескольким профилям, указанным в Приложении A, и декодируются с использованием процесса декодирования, указанного в пунктах 2-9.

Блок доступа состоит из одного первичного кодированного изображения, нуля или более соответствующих избыточных кодированных изображений и нуля или более блоков NAL без VCL. Ассоциация блоков VAL NAL с первичными или избыточными кодированными изображениями описана в пункте 7.4.1.2.5.

Первый блок доступа в битовом потоке начинается с первого блока NAL битового потока.

Первый из любого из следующих блоков NAL после последнего блока NAL VCL первичного кодированного изображения указывает начало нового блока доступа:

  • разделитель блока доступа блок NAL (если имеется),

  • набор параметров последовательности блока NAL (если имеется),

  • параметр изображения установлен в единицу NAL (если имеется),

  • Блок SEI NAL (если имеется),

  • NAL-единицы с nal_unit_type в диапазоне от 14 до 18 включительно (при наличии),

  • первый блок VCL NAL первичного кодированного изображения (всегда присутствует).

Ограничения для обнаружения первого блока NAL VCL первичного кодированного изображения определены в подпункте 7.4.1.2.4.

Следующие ограничения должны соблюдаться в соответствии с порядком кодированных изображений и блоков NAL не-VCL в блоке доступа:

  • Когда присутствует блок NAL с разделителем блока доступа, он должен быть первым блоком NAL. В любом модуле доступа должно быть не более одного блока NAL с разделителями.

  • Когда присутствуют какие-либо блоки SEI NAL, они должны предшествовать первичной кодированной картинке.

  • Когда присутствует блок SEI NAL, содержащий сообщение SEI периода буферизации, сообщение SEI периода буферизации должно быть первой полезной нагрузкой сообщения SEI первого блока SEI NAL в блоке доступа.

  • Первичное кодированное изображение должно предшествовать соответствующим избыточным кодированным изображениям.

  • Когда присутствуют избыточные кодированные изображения, они должны быть упорядочены в порядке возрастания значения redundant_pic_cnt.

  • Когда присутствует блок NAL расширения набора параметров последовательности, он должен быть следующим блоком NAL после блока NAL набора параметров последовательности, имеющего то же значение seq_parameter_set_id, что и в блоке NAL расширения набора параметров последовательности.

  • Когда присутствует один или несколько кодированных фрагментов вспомогательного кодированного изображения без разделения блоков NAL, они должны следовать первичному кодированному изображению и всем избыточным кодированным изображениям (если таковые имеются).

  • Когда присутствует блок NAL конца последовательности, он должен следовать первичному кодированному изображению и всем избыточным кодированным изображениям (если они есть) и всем кодированному фрагменту вспомогательного кодированного изображения без разделения блоков NAL (если таковые имеются).

  • Когда присутствует блок NAL конца потока, он должен быть последним блоком NAL.

  • Блоки NAL, имеющие nal_unit_type, равный 0, 12 или в диапазоне от 20 до 31 включительно, не должны предшествовать первому блоку NAL VCL первичного кодированного изображения.

(ПРИМЕЧАНИЕ 2. - Блоки NAL набора параметров последовательности или блоки NAL набора параметров изображения могут присутствовать в блоке доступа, но не могут следовать за последним блоком NAL VCL первичного кодированного изображения в блоке доступа, так как это условие будет определять начало новый блок доступа.)

(ПРИМЕЧАНИЕ 3. - Когда блок NAL, имеющий nal_unit_type, равный 7 или 8, присутствует в блоке доступа, он может или не может упоминаться в кодированных изображениях блока доступа, в котором он присутствует, и может упоминаться в закодированные изображения последующих блоков доступа.)

Структура блоков доступа, не содержащих блоков NAL с nal_unit_type, равным 0, 7, 8 или в диапазоне от 12 до 18 включительно или в диапазоне от 20 до 31 включительно, показана на рисунке 7-1.

7.4.1.2.4 Обнаружение первого блока NAL VCL первичного кодированного изображения

В этом разделе определяются ограничения на синтаксис блока NAL VCL, которые достаточны для того, чтобы разрешить обнаружение первого блока NAL VCL каждого первичного кодированного изображения для кодированных видеопоследовательностей, которые соответствуют одному или нескольким профилям, указанным в Приложении A, и декодируются с использованием декодирования. процесс, указанный в пунктах 2-9.

Любой блок NAL кодированного слайса или раздел данных кодированного слайса Блок NAL первичного кодированного изображения текущего блока доступа должен отличаться от любого блока NAL кодированного слайса или раздела данных кодированного слайса блок NAL первичного кодированного изображения предыдущего блока доступа одним или несколькими из следующих способов:

  • frame_num отличается по значению. Значение frame_num, используемое для проверки этого условия, является значением frame_num, которое появляется в синтаксисе заголовка слайса, независимо от того, было ли это значение равным 0 для последующего использования в процессе декодирования из-за наличия memory_management_control_operation равно 5.

(ПРИМЕЧАНИЕ 1. - Следствием вышеприведенного утверждения является то, что первичное кодированное изображение, имеющее frame_num, равное 1, не может содержать memory_management_control_operation, равное 5, если не выполнено некоторое другое перечисленное ниже условие для следующего первичного кодированного изображения, которое следует за ним (если оно есть),

  • pic_parameter_set_id отличается по значению.

  • field_pic_flag отличается по значению.

  • bottom_field_flag присутствует в обоих и отличается по значению.

  • nal_ref_idc отличается по значению, при этом одно из значений nal_ref_idc равно 0.

  • pic_order_cnt_type равно 0 для обоих, и либо pic_order_cnt_lsb отличается по значению, либо delta_pic_order_cnt_bottom отличается по значению.

  • pic_order_cnt_type равно 1 для обоих, и либо delta_pic_order_cnt[ 0 ] отличается по значению, либо delta_pic_order_cnt[ 1 ] отличается по значению.

  • IdrPicFlag отличается по значению.

  • IdrPicFlag равен 1 для обоих и idr_pic_id отличается по значению.

(ПРИМЕЧАНИЕ 2. - Некоторые из блоков NAL VCL в избыточных кодированных изображениях или некоторые блоки NAL, отличные от VCL (например, блок NAL с разделителями блоков доступа), также могут использоваться для обнаружения границы между блоками доступа и, следовательно, могут помочь в обнаружение начала нового первичного кодированного изображения.)

Насколько мне известно, разделитель модуля доступа не является обязательным. И поток h.264 часто содержит только один набор параметров последовательности в начале потока.

Я не думаю, что вы можете безопасно найти границы единиц доступа на основе только одной информации заголовка блока. Вам нужно будет проанализировать некоторую информацию из заголовка слайса. Параметр frame_num идентифицирует изображение и, следовательно, модуль доступа, но для его анализа вам может потребоваться еще больше информации из потока битов.

Вы можете попытать счастья, предположив, что один блок доступа всегда содержит только один фрагмент (типы блоков 1-5), хотя это определенно не соответствует стандарту.

Другие вопросы по тегам