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


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

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

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

2 66

2 ответа:

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


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

Уровень Абстракции Сети Единицы

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

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

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

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

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

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, этот non-VCL содержит информацию о режим энтропийного кодирования, группы срезов, предсказание движения и деблокирующие фильтры.
  • мгновенное обновление декодера (IDR). этот VCL NALU является автономным фрагментом изображения. То есть IDR может быть декодирован и отображен без ссылки на любые другие NALU save SPS и PPS.
  • разделитель блока доступа (AUD). AUD-это необязательный NALU, который можно использовать для разделения кадров в элементарном потоке. Не требуется (если иное не предусмотрено контейнер / протокол, например TS), и часто не включается для экономии места, но может быть полезно найти начало кадра без необходимости полного разбора каждого NALU.

коды запуска NALU

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

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

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

Байты Предотвращения Эмуляции

коды запуска работают, потому что четыре байтовые последовательности 0x000000,0x000001,0x000002 и 0x000003 являются незаконными в рамках не-RBSP NALU. Поэтому при создании NALU необходимо позаботиться о том, чтобы избежать этих значений, которые в противном случае можно было бы спутать с начальным кодом. Это достигается путем вставки байта 'Emulation Prevention'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

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

Lena

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


2. AVCC

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

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 байт дает нам 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.

Я недавно работал над чем-то вроде этого.

Проверьте mp4 инспектор. Как вы можете видеть на этом рисунке mp4 имеет много коробок, которые должны быть проанализированы, чтобы найти необходимые данные.

enter image description here

здесь я обозначил части коробки avcc

enter image description here

Я только что написал блог с несколькими сообщениями о моей работе с h264. Я думаю, что это слишком долго, чтобы опубликовать здесь http://cagneymoreau.com/stream-video-android/