Можливі місця для набору послідовностей / параметрів зображення для потоку H.264


85

Я працюю над декодером H.264, і мені цікаво, де знайти SPS і PPS. Моя довідкова література говорить мені, що це одиниці NAL, закодовані в потоці H.264, але коли я розглядаю приклад-MP4-файл із IsoViewer, він говорить, що SPS і PPS знаходяться в avcC Box.

Як саме це працює? Як він шукає файли .mkv чи інші контейнери H.264?

Спасибі заздалегідь!

Відповіді:


301

По-перше, важливо зрозуміти, що не існує єдиного стандартного формату елементарного потоку бітів H.264. Технічний документ містить додаток, зокрема Додаток B, який описує один із можливих форматів, але це не є фактичною вимогою. Стандарт визначає спосіб кодування відео в окремі пакети. Те, як ці пакети зберігаються та передаються, залишається відкритим для інтегратора.


1. Додаток В

Одиниці рівня мережевої абстракції

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

Визначено 19 різних типів NALU, розділених на дві категорії, VCL та non-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 для створення потоку не буде працювати, оскільки ви не будете знати, де зупиняється, а починається наступний.

Специфікація Додатка В вирішує це, вимагаючи, щоб перед кожним 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, часто в документації зручніше вважати, що вони вже були видалені. Представлення без байтів запобігання емуляції називається Raw Byte Sequence Payload (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розширенням, ви зможете перетворити його на це зображення:

Лена

Додаток B зазвичай використовується у форматах прямого та потокового передавання, таких як транспортні потоки, ефірні трансляції та DVD. У цих форматах часто повторюють SPS і PPS періодично, зазвичай перед кожним IDR, створюючи таким чином точку довільного доступу для декодера. Це дає можливість приєднатися до потоку, який уже триває.


2. AVCC

Іншим поширеним методом зберігання потоку H.264 є формат AVCC. У цьому форматі перед кожною NALU передує її довжина (у форматі big endian). Цей метод легше аналізувати, але ви втрачаєте функції вирівнювання байтів у Додатку В. Просто для того, щоб ускладнити ситуацію, довжина може кодуватися за допомогою 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.


3
Дякую, чоловіче, той справді мені допоміг! У вашій статті є деякі помилки друку ... Я думаю;) Іноді ви називаєте VCL "VLC", що може бути досить заплутаним, оскільки я знаю VLC як "кодування змінної довжини". Але все-таки ваша стаття прояснила для мене кілька речей, гарна робота! І ... вибачте, я не можу проголосувати за вас, я тут новачок і тут є якийсь фільтр newbe;)
bananenbär

6
Так, вибачте за помилки. Я трохи дислексик і дуже бідний друкар. Ви праві. VLC не має місця в цьому тексті.
szatmary

2
Чудове резюме! Це мені справді допомогло. Незважаючи на те, що очевидно, якщо придивитися до другого (AVCC) набору байтів, я думаю, варто зазначити, що значення довжини 4 байтів, яке передує даним NALU, має формат Big-Endian. Я не міг змусити декодувати потік на iOS, поки не зрозумів, що значення довжини повинно бути замінено байтами.
12on

1
Велике спасибі, чоловіче! До речі, декодер Windows Media Foundation h264 бажає лише зразки «Додатку В». На щастя, перетворити їх між додатком B та AVCC досить просто.
Soonts

2
Чи відсутній нульовий байт зі зміщенням 0x0022 прикладу екстра-даних AVCC? Опис формату говорить, що існує 16-бітове поле для розміру PPS, тому я думаю, що це має бути 0x00 0x07замість просто 0x07.
rhashimoto
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.