Прежде всего, важно понимать, что не существует единого стандартного формата элементарного потока битов H.264. Документ спецификации действительно содержит Приложение, в частности Приложение B, которое описывает один из возможных форматов, но это не фактическое требование. Стандарт определяет, как видео кодируется в отдельные пакеты. Как эти пакеты хранятся и передаются, остается открытым для интегратора.
1. Приложение B
Единицы уровня сетевой абстракции
Пакеты называются модулями уровня абстракции сети. Часто сокращенно NALU (или иногда просто NAL) каждый пакет может быть индивидуально проанализирован и обработан. Первый байт каждого NALU содержит тип NALU, а именно биты с 3 по 7. (бит 0 всегда выключен, а биты 1-2 указывают, ссылается ли на NALU другой NALU).
Существует 19 различных типов NALU, разделенных на две категории: VCL и не-VCL:
- Пакеты VCL или Video Coding Layer содержат фактическую визуальную информацию.
- Не-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).Этот не-VCL NALU содержит информацию, необходимую для настройки декодера, такую как профиль, уровень, разрешение, частота кадров.
- Набор параметров изображения (PPS).Подобно SPS, этот не-VCL содержит информацию о режиме энтропийного кодирования, группах слайсов, фильтрах прогнозирования движения и удаления блочности.
- Мгновенное обновление декодера (IDR).Этот VCL NALU представляет собой автономный фрагмент изображения. То есть IDR может быть декодирован и отображен без ссылки на какие-либо другие NALU, сохраняющие SPS и PPS.
- Разделитель единиц доступа (AUD). AUD - это необязательный NALU, который можно использовать для разграничения кадров в элементарном потоке. Это не требуется (если иное не указано в контейнере / протоколе, например TS), и часто не включается в целях экономии места, но может быть полезно найти начало кадра без необходимости полного анализа каждого NALU.
Коды запуска NALU
NALU не содержит его размера. Поэтому простое объединение NALU для создания потока не сработает, потому что вы не будете знать, где заканчивается один и начинается следующий.
Спецификация Приложения B решает эту проблему, требуя, чтобы «Стартовые коды» предшествовали каждому NALU. Начальный код - это 2 или 3 0x00
байта, за которыми следует 0x01
байт. например 0x000001
или 0x00000001
.
4-байтовый вариант полезен для передачи по последовательному соединению, поскольку побайтовое выравнивание потока является тривиальным путем поиска 31 нулевого бита, за которым следует единица. Если следующий бит равен 0 (поскольку каждый NALU начинается с 0 бита), это начало NALU. 4-байтовый вариант обычно используется только для сигнализации точек произвольного доступа в потоке, таких как SPS PPS AUD и IDR, тогда как 3-байтовый вариант используется везде для экономии места.
Байты предотвращения эмуляции
Начало коды работают из - за четыре последовательностей байт 0x000000
, 0x000001
, 0x000002
и 0x000003
являются незаконными в не-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
Это полный AU, содержащий 3 NALU. Как видите, мы начинаем с кода запуска, за которым следует SPS (SPS начинается с 67). В SPS вы увидите два байта предотвращения эмуляции. Без этих байтов 0x000000
на этих позициях возникла бы недопустимая последовательность . Затем вы увидите стартовый код, за которым следует PPS (PPS начинается с 68) и один последний стартовый код, за которым следует IDR-фрагмент. Это полный поток H.264. Если вы введете эти значения в шестнадцатеричный редактор и сохраните файл с .264
расширением, вы сможете преобразовать его в это изображение:
Приложение B обычно используется в прямых и потоковых форматах, таких как транспортные потоки, эфирное вещание и DVD. В этих форматах обычно периодически повторяются SPS и PPS, обычно перед каждым IDR, создавая таким образом точку произвольного доступа для декодера. Это дает возможность присоединиться к уже идущему потоку.
2. AVCC
Другой распространенный метод хранения потока H.264 - это формат AVCC. В этом формате каждому NALU предшествует его длина (в формате big endian). Этот метод легче анализировать, но вы теряете возможности выравнивания байтов, указанные в Приложении B. Чтобы усложнить ситуацию, длина может быть закодирована с использованием 1, 2 или 4 байтов. Это значение хранится в объекте заголовка. Этот заголовок часто называют «дополнительными данными» или «заголовком последовательности». Его основной формат выглядит следующим образом:
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 будут выглядеть следующим образом:
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 байтов дает нам 64 КБ на 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.
0x00 0x07
а не просто0x07
.