Подтвердить что ты не робот

Возможные расположения для последовательности/параметров набора изображений для потока H.264

Я работаю над декодером H.264, и мне интересно, где найти SPS и PPS. В моей справочной литературе мне сообщается, что это NAL-узлы, закодированные в H.264-Stream, но когда я просматриваю пример-MP4 файл с IsoViewer, он говорит, что SPS и PPS находятся в avcC Box.

Как именно это работает? Как он ищет файлы .mkv или другие контейнеры H.264?

Спасибо заранее!

4b9b3361

Ответ 1

Во-первых, важно понимать, что нет единого стандартного формата бит-бит H.264. В документе спецификации содержится Приложение, в частности Приложение B, которое описывает один возможный формат, но это не является фактическим требованием. Стандарт определяет, как видео кодируется в отдельные пакеты. Как эти пакеты сохраняются и передаются, остается открытым для интегратора.


1. Приложение B

Единицы уровня абстракции сети

Пакеты называются единицами уровня абстракции сети. Часто сокращенный NALU (или иногда просто NAL) каждый пакет может обрабатываться отдельно и обрабатываться отдельно. Первый байт каждого NALU содержит тип NALU, в частности биты с 3 по 7. (бит 0 всегда выключен, а биты 1-2 указывают, ссылается ли NALU на другой NALU).

Существует 19 различных типов NALU, разделенных на две категории: VCL и non-VCL:

  • Пакеты VCL или Video Coding Layer содержат фактическую визуальную информацию.
  • Non-VCL содержат метаданные, которые могут потребоваться или не потребоваться для декодирования видео.

Один NALU, или даже VCL NALU - это не то же самое, что фрейм. Кадр можно "нарезать" на несколько блоков NALU. Так же, как вы можете нарезать пиццу. Затем один или несколько фрагментов фактически группируются в блоки доступа (AU), которые содержат один кадр. Нарезка действительно незначительна, поэтому ее часто не используют.

Ниже приведена таблица всех определенных NALU.

0      Unspecified                                                    non-VCL
1      Coded slice of a non-IDR picture                               VCL
2      Coded slice data partition A                                   VCL
3      Coded slice data partition B                                   VCL
4      Coded slice data partition C                                   VCL
5      Coded slice of an IDR picture                                  VCL
6      Supplemental enhancement information (SEI)                     non-VCL
7      Sequence parameter set                                         non-VCL
8      Picture parameter set                                          non-VCL
9      Access unit delimiter                                          non-VCL
10     End of sequence                                                non-VCL
11     End of stream                                                  non-VCL
12     Filler data                                                    non-VCL
13     Sequence parameter set extension                               non-VCL
14     Prefix NAL unit                                                non-VCL
15     Subset sequence parameter set                                  non-VCL
16     Depth parameter set                                            non-VCL
17..18 Reserved                                                       non-VCL
19     Coded slice of an auxiliary coded picture without partitioning non-VCL
20     Coded slice extension                                          non-VCL
21     Coded slice extension for depth view components                non-VCL
22..23 Reserved                                                       non-VCL
24..31 Unspecified                                                    non-VCL

Существует несколько типов NALU, в которых знания могут быть полезны позже.

  • Набор параметров последовательности (SPS). Этот NLU не-VCL содержит информацию, необходимую для настройки декодера, такого как профиль, уровень, разрешение, частота кадров.
  • Набор параметров изображения (PPS). Подобно SPS, этот не-VCL содержит информацию о режиме энтропийного кодирования, группах срезов, фильтрах прогнозирования движения и деблокирования.
  • Обновление мгновенного декодера (IDR). Этот VCL NALU представляет собой автономный срез изображения. То есть IDR может быть декодирован и отображен без ссылки на другие SAL и PPS NALU.
  • Разделитель блоков доступа (AUD). AUD - это дополнительный NALU, который может использоваться для разграничения кадров в элементарном потоке. Это не требуется (если иное не указано контейнером/протоколом, например TS) и часто не включается для экономии места, но может оказаться полезным найти начало кадра без полного анализа каждого NALU.

Стартовые коды NALU

A NALU не содержит его размер. Поэтому просто конкатенация NALU для создания потока не будет работать, потому что вы не будете знать, где остановиться, а затем начинается.

Спецификация Приложения B разрешает это, требуя, чтобы "Начальные коды" предшествовали каждому НАЛУ. Стартовый код - 2 или 3 0x00 байта с байтом 0x01. например 0x000001 или 0x00000001.

4-байтовая вариация полезна для передачи по последовательному соединению, так как тривиально байт выравнивает поток, ища 31 нулевой бит, за которым следует один. Если следующий бит равен 0 (поскольку каждый NALU начинается с 0 бит), это начало NALU. 4-байтовая вариация обычно используется только для сигнализации о случайных точках доступа в потоке, таких как SPS PPS AUD и IDR. Где в качестве вариации 3 байта используется везде, чтобы сэкономить место.

Байт управления предупреждением

Запуск кодов работает, потому что четыре байтовых последовательности 0x000000, 0x000001, 0x000002 и 0x000003 являются незаконными в NALU, отличном от RBSP. Поэтому, создавая NALU, берется уход за этими значениями, которые в противном случае можно было бы путать с кодом запуска. Это достигается путем вставки "Байт предупреждения эмуляции 0x03, так что 0x000001 становится 0x00000301.

При декодировании важно искать и игнорировать байты предотвращения эмуляции. Поскольку байты предотвращения эмулирования могут возникать почти в любом месте NALU, в документации часто бывает удобнее предположить, что они уже удалены. Представление без байтов предупреждения эмуляции называется полезной нагрузкой на последовательную последовательность байтов (RBSP).

Пример

Посмотрите на полный пример.

0x0000 | 00 00 00 01 67 64 00 0A AC 72 84 44 26 84 00 00
0x0010 | 03 00 04 00 00 03 00 CA 3C 48 96 11 80 00 00 00
0x0020 | 01 68 E8 43 8F 13 21 30 00 00 01 65 88 81 00 05
0x0030 | 4E 7F 87 DF 61 A5 8B 95 EE A4 E9 38 B7 6A 30 6A
0x0040 | 71 B9 55 60 0B 76 2E B5 0E E4 80 59 27 B8 67 A9
0x0050 | 63 37 5E 82 20 55 FB E4 6A E9 37 35 72 E2 22 91
0x0060 | 9E 4D FF 60 86 CE 7E 42 B7 95 CE 2A E1 26 BE 87
0x0070 | 73 84 26 BA 16 36 F4 E6 9F 17 DA D8 64 75 54 B1
0x0080 | F3 45 0C 0B 3C 74 B3 9D BC EB 53 73 87 C3 0E 62
0x0090 | 47 48 62 CA 59 EB 86 3F 3A FA 86 B5 BF A8 6D 06
0x00A0 | 16 50 82 C4 CE 62 9E 4E E6 4C C7 30 3E DE A1 0B
0x00B0 | D8 83 0B B6 B8 28 BC A9 EB 77 43 FC 7A 17 94 85
0x00C0 | 21 CA 37 6B 30 95 B5 46 77 30 60 B7 12 D6 8C C5
0x00D0 | 54 85 29 D8 69 A9 6F 12 4E 71 DF E3 E2 B1 6B 6B
0x00E0 | BF 9F FB 2E 57 30 A9 69 76 C4 46 A2 DF FA 91 D9
0x00F0 | 50 74 55 1D 49 04 5A 1C D6 86 68 7C B6 61 48 6C
0x0100 | 96 E6 12 4C 27 AD BA C7 51 99 8E D0 F0 ED 8E F6
0x0110 | 65 79 79 A6 12 A1 95 DB C8 AE E3 B6 35 E6 8D BC
0x0120 | 48 A3 7F AF 4A 28 8A 53 E2 7E 68 08 9F 67 77 98
0x0130 | 52 DB 50 84 D6 5E 25 E1 4A 99 58 34 C7 11 D6 43
0x0140 | FF C4 FD 9A 44 16 D1 B2 FB 02 DB A1 89 69 34 C2
0x0150 | 32 55 98 F9 9B B2 31 3F 49 59 0C 06 8C DB A5 B2
0x0160 | 9D 7E 12 2F D0 87 94 44 E4 0A 76 EF 99 2D 91 18
0x0170 | 39 50 3B 29 3B F5 2C 97 73 48 91 83 B0 A6 F3 4B
0x0180 | 70 2F 1C 8F 3B 78 23 C6 AA 86 46 43 1D D7 2A 23
0x0190 | 5E 2C D9 48 0A F5 F5 2C D1 FB 3F F0 4B 78 37 E9
0x01A0 | 45 DD 72 CF 80 35 C3 95 07 F3 D9 06 E5 4A 58 76
0x01B0 | 03 6C 81 20 62 45 65 44 73 BC FE C1 9F 31 E5 DB
0x01C0 | 89 5C 6B 79 D8 68 90 D7 26 A8 A1 88 86 81 DC 9A
0x01D0 | 4F 40 A5 23 C7 DE BE 6F 76 AB 79 16 51 21 67 83
0x01E0 | 2E F3 D6 27 1A 42 C2 94 D1 5D 6C DB 4A 7A E2 CB
0x01F0 | 0B B0 68 0B BE 19 59 00 50 FC C0 BD 9D F5 F5 F8
0x0200 | A8 17 19 D6 B3 E9 74 BA 50 E5 2C 45 7B F9 93 EA
0x0210 | 5A F9 A9 30 B1 6F 5B 36 24 1E 8D 55 57 F4 CC 67
0x0220 | B2 65 6A A9 36 26 D0 06 B8 E2 E3 73 8B D1 C0 1C
0x0230 | 52 15 CA B5 AC 60 3E 36 42 F1 2C BD 99 77 AB A8
0x0240 | A9 A4 8E 9C 8B 84 DE 73 F0 91 29 97 AE DB AF D6
0x0250 | F8 5E 9B 86 B3 B3 03 B3 AC 75 6F A6 11 69 2F 3D
0x0260 | 3A CE FA 53 86 60 95 6C BB C5 4E F3

Это полный АС, содержащий 3 NALU. Как вы можете видеть, мы начинаем с кода запуска, за которым следует SPS (SPS начинается с 67). Внутри SPS вы увидите два байта предупреждения эмуляции. Без этих байтов в этих позициях будет происходить незаконная последовательность 0x000000. Затем вы увидите начальный код, за которым следует PPS (PPS начинается с 68) и один окончательный код запуска, за которым следует фрагмент IDR. Это полный поток H.264. Если вы введете эти значения в шестнадцатеричный редактор и сохраните файл с расширением .264, вы сможете преобразовать его в это изображение:

Lena

Приложение B обычно используется в виде живых и потоковых форматов, таких как транспортные потоки, эфирные трансляции и DVD-диски. В этих форматах часто повторяется SPS и PPS периодически, обычно перед каждым IDR, создавая, таким образом, произвольную точку доступа для декодера. Это позволяет подключиться к уже существующему потоку.


2. AVCC

Другим распространенным способом хранения потока H.264 является формат AVCC. В этом формате каждому NALU предшествует его длина (в формате большого конца). Этот метод проще разобрать, но вы теряете функции выравнивания байтов в приложении B. Просто для усложнения вещей длина может быть закодирована с использованием 1, 2 или 4 байта. Это значение сохраняется в объекте заголовка. Этот заголовок часто называют "extradata" или "header". Его основной формат выглядит следующим образом:

bits    
8   version ( always 0x01 )
8   avc profile ( sps[0][1] )
8   avc compatibility ( sps[0][2] )
8   avc level ( sps[0][3] )
6   reserved ( all bits on )
2   NALULengthSizeMinusOne
3   reserved ( all bits on )
5   number of SPS NALUs (usually 1)
repeated once per SPS:
  16     SPS size
  variable   SPS NALU data
8   number of PPS NALUs (usually 1)
repeated once per PPS
  16    PPS size
  variable PPS NALU data

Используя тот же пример выше, AVCC extradata будет выглядеть так:

0x0000 | 01 64 00 0A FF E1 00 19 67 64 00 0A AC 72 84 44
0x0010 | 26 84 00 00 03 00 04 00 00 03 00 CA 3C 48 96 11
0x0020 | 80 01 00 07 68 E8 43 8F 13 21 30

Вы заметите, что SPS и PPS теперь хранятся вне диапазона. То есть, отдельно от данных элементарного потока. Хранение и передача этих данных - это задание контейнера файлов и выходит за рамки этого документа. Обратите внимание, что, хотя мы не используем стартовые коды, байты предотвращения эмуляции все еще вставлены.

Кроме того, существует новая переменная с именем NALULengthSizeMinusOne. Эта переменная с именованными именами указывает нам, сколько байтов использовать для хранения длины каждого NALU. Итак, если NALULengthSizeMinusOne установлено в 0, то каждому NALU предшествует один байт, указывающий его длину. Используя один байт для хранения размера, максимальный размер NALU составляет 255 байт. Это, очевидно, довольно мало. Путь слишком мал для всего ключевого кадра. Использование 2 байтов дает нам 64k за NALU. Это будет работать в нашем примере, но по-прежнему остается довольно низким. 3 байта были бы идеальны, но по какой-то причине не поддерживаются повсеместно. Таким образом, 4 байта, безусловно, наиболее распространены, и это то, что мы использовали здесь:

0x0000 | 00 00 02 41 65 88 81 00 05 4E 7F 87 DF 61 A5 8B
0x0010 | 95 EE A4 E9 38 B7 6A 30 6A 71 B9 55 60 0B 76 2E
0x0020 | B5 0E E4 80 59 27 B8 67 A9 63 37 5E 82 20 55 FB
0x0030 | E4 6A E9 37 35 72 E2 22 91 9E 4D FF 60 86 CE 7E
0x0040 | 42 B7 95 CE 2A E1 26 BE 87 73 84 26 BA 16 36 F4
0x0050 | E6 9F 17 DA D8 64 75 54 B1 F3 45 0C 0B 3C 74 B3
0x0060 | 9D BC EB 53 73 87 C3 0E 62 47 48 62 CA 59 EB 86
0x0070 | 3F 3A FA 86 B5 BF A8 6D 06 16 50 82 C4 CE 62 9E
0x0080 | 4E E6 4C C7 30 3E DE A1 0B D8 83 0B B6 B8 28 BC
0x0090 | A9 EB 77 43 FC 7A 17 94 85 21 CA 37 6B 30 95 B5
0x00A0 | 46 77 30 60 B7 12 D6 8C C5 54 85 29 D8 69 A9 6F
0x00B0 | 12 4E 71 DF E3 E2 B1 6B 6B BF 9F FB 2E 57 30 A9
0x00C0 | 69 76 C4 46 A2 DF FA 91 D9 50 74 55 1D 49 04 5A
0x00D0 | 1C D6 86 68 7C B6 61 48 6C 96 E6 12 4C 27 AD BA
0x00E0 | C7 51 99 8E D0 F0 ED 8E F6 65 79 79 A6 12 A1 95
0x00F0 | DB C8 AE E3 B6 35 E6 8D BC 48 A3 7F AF 4A 28 8A
0x0100 | 53 E2 7E 68 08 9F 67 77 98 52 DB 50 84 D6 5E 25
0x0110 | E1 4A 99 58 34 C7 11 D6 43 FF C4 FD 9A 44 16 D1
0x0120 | B2 FB 02 DB A1 89 69 34 C2 32 55 98 F9 9B B2 31
0x0130 | 3F 49 59 0C 06 8C DB A5 B2 9D 7E 12 2F D0 87 94
0x0140 | 44 E4 0A 76 EF 99 2D 91 18 39 50 3B 29 3B F5 2C
0x0150 | 97 73 48 91 83 B0 A6 F3 4B 70 2F 1C 8F 3B 78 23
0x0160 | C6 AA 86 46 43 1D D7 2A 23 5E 2C D9 48 0A F5 F5
0x0170 | 2C D1 FB 3F F0 4B 78 37 E9 45 DD 72 CF 80 35 C3
0x0180 | 95 07 F3 D9 06 E5 4A 58 76 03 6C 81 20 62 45 65
0x0190 | 44 73 BC FE C1 9F 31 E5 DB 89 5C 6B 79 D8 68 90
0x01A0 | D7 26 A8 A1 88 86 81 DC 9A 4F 40 A5 23 C7 DE BE
0x01B0 | 6F 76 AB 79 16 51 21 67 83 2E F3 D6 27 1A 42 C2
0x01C0 | 94 D1 5D 6C DB 4A 7A E2 CB 0B B0 68 0B BE 19 59
0x01D0 | 00 50 FC C0 BD 9D F5 F5 F8 A8 17 19 D6 B3 E9 74
0x01E0 | BA 50 E5 2C 45 7B F9 93 EA 5A F9 A9 30 B1 6F 5B
0x01F0 | 36 24 1E 8D 55 57 F4 CC 67 B2 65 6A A9 36 26 D0
0x0200 | 06 B8 E2 E3 73 8B D1 C0 1C 52 15 CA B5 AC 60 3E
0x0210 | 36 42 F1 2C BD 99 77 AB A8 A9 A4 8E 9C 8B 84 DE
0x0220 | 73 F0 91 29 97 AE DB AF D6 F8 5E 9B 86 B3 B3 03
0x0230 | B3 AC 75 6F A6 11 69 2F 3D 3A CE FA 53 86 60 95
0x0240 | 6C BB C5 4E F3

Преимущество этого формата - возможность конфигурировать декодер в начале и прыгать в середину потока. Это распространенный прецедент, когда носитель доступен на носителе произвольного доступа, таком как жесткий диск, и поэтому используется в обычных форматах контейнеров, таких как MP4 и MKV.