Posibles ubicaciones para los conjuntos de parámetros de secuencia / imagen para la transmisión H.264

82

Estoy trabajando en un decodificador H.264 y me pregunto dónde encontrar el SPS y el PPS. Mi literatura de referencia me dice que esas son unidades NAL codificadas en H.264-Stream, pero cuando miro un archivo MP4 de ejemplo con IsoViewer, dice que SPS y PPS están en la caja avcC.

¿Cómo funciona esto exactamente? ¿Cómo busca archivos .mkv u otros contenedores H.264?

¡Gracias por adelantado!

bananenbär
fuente

Respuestas:

291

En primer lugar, es importante comprender que no existe un único formato de flujo de bits elemental estándar H.264. El documento de especificación contiene un anexo, específicamente el anexo B, que describe un formato posible, pero no es un requisito real. El estándar especifica cómo se codifica el video en paquetes individuales. La forma en que estos paquetes se almacenan y transmiten queda abierta al integrador.


1. Anexo B

Unidades de capa de abstracción de red

Los paquetes se denominan unidades de capa de abstracción de red. A menudo abreviado como NALU (o, a veces, simplemente NAL), cada paquete se puede analizar y procesar individualmente. El primer byte de cada NALU contiene el tipo NALU, específicamente los bits 3 a 7. (el bit 0 siempre está desactivado y los bits 1-2 indican si una NALU está referenciada por otra NALU).

Hay 19 tipos diferentes de NALU definidos separados en dos categorías, VCL y no VCL:

  • Los paquetes VCL o Video Coding Layer contienen la información visual real.
  • Los que no son VCL contienen metadatos que pueden ser necesarios o no para decodificar el video.

Un solo NALU, o incluso un VCL NALU NO es lo mismo que un marco. Un fotograma se puede "cortar" en varias NALU. Al igual que puedes cortar una pizza. Luego, uno o más segmentos se agrupan virtualmente en unidades de acceso (AU) que contienen un marco. Cortar en rodajas tiene un ligero costo de calidad, por lo que no se usa a menudo.

A continuación se muestra una tabla de todas las NALU definidas.

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

Hay un par de tipos de NALU de los que tener conocimiento puede resultar útil más adelante.

  • Conjunto de parámetros de secuencia (SPS). Esta NALU no VCL contiene la información necesaria para configurar el decodificador, como el perfil, el nivel, la resolución y la velocidad de fotogramas.
  • Conjunto de parámetros de imagen (PPS). Al igual que el SPS, este no VCL contiene información sobre el modo de codificación de entropía, grupos de corte, predicción de movimiento y filtros de desbloqueo.
  • Actualización instantánea del decodificador (IDR). Este VCL NALU es un segmento de imagen autónomo. Es decir, un IDR se puede decodificar y mostrar sin hacer referencia a ningún otro NALU salvo SPS y PPS.
  • Delimitador de unidad de acceso (AUD). Un AUD es una NALU opcional que se puede utilizar para delimitar tramas en una secuencia elemental. No es necesario (a menos que el contenedor / protocolo indique lo contrario, como TS) y, a menudo, no se incluye para ahorrar espacio, pero puede ser útil para encontrar el inicio de un marco sin tener que analizar completamente cada NALU.

Códigos de inicio NALU

Un NALU no contiene su tamaño. Por lo tanto, simplemente concatenar las NALU para crear una secuencia no funcionará porque no sabrá dónde se detiene una y comienza la siguiente.

La especificación del Anexo B resuelve esto al requerir 'códigos de inicio' que precedan a cada NALU. Un código de inicio tiene 2 o 3 0x00bytes seguidos de un 0x01byte. p . ej . 0x000001o 0x00000001.

La variación de 4 bytes es útil para la transmisión a través de una conexión en serie, ya que es trivial alinear el flujo de bytes buscando 31 bits cero seguidos de uno. Si el siguiente bit es 0 (porque cada NALU comienza con un bit 0), es el comienzo de una NALU. La variación de 4 bytes generalmente solo se usa para señalizar puntos de acceso aleatorio en el flujo, como SPS PPS AUD e IDR, mientras que la variación de 3 bytes se usa en cualquier otro lugar para ahorrar espacio.

Bytes de prevención de emulación

Códigos de empezar a trabajar porque las cuatro secuencias de bytes 0x000000, 0x000001, 0x000002y 0x000003son ilegales dentro de un no-RBSP NALU. Por lo tanto, al crear una NALU, se debe tener cuidado de escapar de estos valores que de otro modo podrían confundirse con un código de inicio. Esto se logra insertando un byte de 'Prevención de emulación' 0x03, por lo que se 0x000001convierte en 0x00000301.

Al decodificar, es importante buscar e ignorar los bytes de prevención de emulación. Debido a que los bytes de prevención de emulación pueden ocurrir en casi cualquier lugar dentro de una NALU, a menudo es más conveniente en la documentación asumir que ya se han eliminado. Una representación sin bytes de prevención de emulación se denomina Carga útil de secuencia de bytes sin procesar (RBSP).

Ejemplo

Veamos un ejemplo completo.

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

Esta es una AU completa que contiene 3 NALU. Como puede ver, comenzamos con un código de inicio seguido de un SPS (SPS comienza con 67). Dentro del SPS, verá dos bytes de Prevención de emulación. Sin estos bytes, la secuencia ilegal 0x000000se produciría en estas posiciones. A continuación, verá un código de inicio seguido de un PPS (PPS comienza con 68) y un código de inicio final seguido de un segmento IDR. Esta es una secuencia H.264 completa. Si escribe estos valores en un editor hexadecimal y guarda el archivo con una .264extensión, podrá convertirlo a esta imagen:

Lena

El Anexo B se usa comúnmente en formatos en vivo y de transmisión, como transmisiones de transporte, transmisiones por aire y DVD. En estos formatos es común repetir el SPS y PPS periódicamente, generalmente antes de cada IDR creando así un punto de acceso aleatorio para el decodificador. Esto habilita la posibilidad de unirse a una transmisión que ya está en curso.


2. AVCC

El otro método común para almacenar una secuencia H.264 es el formato AVCC. En este formato, cada NALU está precedido por su longitud (en formato big endian). Este método es más fácil de analizar, pero pierde las características de alineación de bytes del Anexo B. Para complicar las cosas, la longitud puede codificarse usando 1, 2 o 4 bytes. Este valor se almacena en un objeto de encabezado. Este encabezado a menudo se denomina 'extradatos' o 'encabezado de secuencia'. Su formato básico es el siguiente:

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

Usando el mismo ejemplo anterior, los extradatos de AVCC se verán así:

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

Notará que SPS y PPS ahora se almacenan fuera de banda. Es decir, separados de los datos de flujo elementales. El almacenamiento y la transmisión de estos datos es tarea del contenedor de archivos y está fuera del alcance de este documento. Tenga en cuenta que, aunque no estamos utilizando códigos de inicio, los bytes de prevención de emulación todavía se insertan.

Además, hay una nueva variable llamada NALULengthSizeMinusOne. Esta variable de nombre confuso nos dice cuántos bytes usar para almacenar la longitud de cada NALU. Entonces, si NALULengthSizeMinusOnese establece en 0, entonces cada NALU está precedido por un solo byte que indica su longitud. Usando un solo byte para almacenar el tamaño, el tamaño máximo de una NALU es 255 bytes. Eso es obviamente bastante pequeño. Demasiado pequeño para un fotograma clave completo. El uso de 2 bytes nos da 64k por NALU. Funcionaría en nuestro ejemplo, pero sigue siendo un límite bastante bajo. 3 bytes sería perfecto, pero por alguna razón no es universalmente compatible. Por lo tanto, 4 bytes es, con mucho, el más común, y es lo que usamos aquí:

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

Una ventaja de este formato es la capacidad de configurar el decodificador al inicio y saltar al medio de una secuencia. Este es un caso de uso común en el que los medios están disponibles en un medio de acceso aleatorio como un disco duro y, por lo tanto, se utilizan en formatos de contenedor comunes como MP4 y MKV.

szatmary
fuente
2
¡Gracias tío, ese realmente me ayudó! Sin embargo, tiene algunos errores de escritura en su artículo ... creo;) A veces se refiere a VCL como 'VLC', lo que puede ser bastante confuso porque conozco VLC como 'codificación de longitud variable'. Pero aún así, tu artículo me aclaró algunas cosas, ¡buen trabajo! Y ... lo siento, no puedo darte un voto positivo, soy nuevo aquí y hay algún tipo de filtro newbe aquí;)
bananenbär
5
Sí, lo siento por los errores tipográficos. Soy un poco disléxico y muy pobre mecanógrafo. Estás en lo correcto. VLC no tiene lugar en este texto.
szatmary
2
¡Gran resumen! Esto realmente me ayudó. Aunque es obvio si uno mira de cerca el segundo conjunto de bytes (AVCC), creo que vale la pena señalar que el valor de longitud de 4 bytes que precede a los datos NALU está en formato Big-Endian. No pude hacer que la transmisión se decodificara en iOS hasta que me di cuenta de que el valor de longitud tenía que intercambiarse bytes.
2014
1
¡Muchas gracias hombre! Por cierto, el decodificador de Windows Media Foundation h264 solo quiere muestras del “Anexo B”. Afortunadamente, es bastante sencillo convertirlos entre el Anexo B y AVCC.
Soonts
2
¿Falta un byte cero en el desplazamiento 0x0022 del ejemplo de extradatos de AVCC? La descripción del formato dice que hay un campo de 16 bits para el tamaño de PPS, así que creo que debería ser en 0x00 0x07lugar de solo 0x07.
rhashimoto