parameters - online - Ubicaciones posibles para los conjuntos de parámetros de secuencia/imagen para H.264 Stream
h264 codec free (1)
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 en un ejemplo-MP4-File con IsoViewer, dice que SPS y PPS están en el cuadro avcC.
¿Cómo funciona esto exactamente? ¿Cómo se ven los archivos .mkv u otros contenedores H.264?
¡Gracias por adelantado!
En primer lugar, es importante comprender que no existe un solo formato de flujo de bits elemental H.264 estándar. El documento de especificación contiene un Anexo, específicamente el Anexo B, que describe un posible formato, pero no es un requisito real. El estándar especifica cómo se codifica el video en paquetes individuales. Cómo se almacenan y transmiten estos paquetes queda abierto para el integrador.
1. Anexo B
Unidades de capa de abstracción de red
Los paquetes se llaman Unidades de capa de abstracción de red. A menudo abreviado NALU (o a veces simplemente NAL) cada paquete puede ser analizado y procesado 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 hace referencia a un NALU).
Hay 19 tipos diferentes de NALU definidos en dos categorías, VCL y no VCL:
- Los paquetes VCL o Video Coding Layer contienen la información visual real.
- Los no VCL contienen metadatos que pueden o no ser necesarios para decodificar el video.
Un solo NALU, o incluso un VCL NALU NO es lo mismo que un marco. Un marco puede ser ''cortado'' en varias NALU. Al igual que puedes cortar una pizza. Uno o más sectores se agrupan virtualmente en unidades de acceso (AU) que contienen un cuadro. El corte tiene un costo de calidad leve, por lo que no se usa con frecuencia.
A continuación se muestra una tabla de todos los NALU definidos.
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 donde conocerlos puede ser útil más adelante.
- Conjunto de parámetros de secuencia (SPS). Esta NALU no VCL contiene información requerida para configurar el decodificador, como perfil, nivel, resolución, velocidad de cuadro.
- 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 NALU de VCL es un segmento de imagen independiente. Es decir, un IDR se puede decodificar y mostrar sin hacer referencia a ningún otro NALU guardar SPS y PPS.
- Delimitador de la unidad de acceso (AUD). Un AUD es un NALU opcional que se puede usar para delimitar cuadros en un flujo elemental. No es obligatorio (a menos que el contenedor / protocolo indique lo contrario, como TS), y a menudo no está incluido para ahorrar espacio, pero puede ser útil encontrar el inicio de un marco sin tener que analizar por completo cada NALU.
Códigos de inicio de NALU
Un NALU no contiene su tamaño. Por lo tanto, simplemente concatenar los NALU para crear una transmisión no funcionará porque no sabrá dónde se detiene y comienza la siguiente.
La especificación del Anexo B resuelve esto al requerir que ''Códigos de Inicio'' precedan a cada NALU. Un código de inicio es 2 o 3 0x00
bytes seguido de un byte 0x01
. por ejemplo, 0x000001
o 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 a byte alinear la secuencia 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 utiliza para señalar puntos de acceso aleatorio en la transmisión, como un SPS PPS AUD e IDR Donde la variación de 3 bytes se usa en cualquier otro lugar para ahorrar espacio.
Bytes de prevención de emulación
Los códigos de inicio funcionan porque las cuatro secuencias de bytes 0x000000
, 0x000001
, 0x000002
y 0x000003
son ilegales dentro de un 0x000003
no RBSP. Por lo tanto, al crear un NALU, se debe tener cuidado para escapar de estos valores que de otra manera podrían confundirse con un código de inicio. Esto se logra insertando un byte de ''Prevención de Emulación'' 0x03
, de modo que 0x000001
convierta 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 casi en cualquier lugar dentro de una NALU, a menudo es más conveniente en la documentación suponer que ya han sido eliminados. 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
Este es un AU completo 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 0x000000
ocurrirí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 transmisión H.264 completa. Si escribe estos valores en un editor hexadecimal y guarda el archivo con una extensión .264
, podrá convertirlo a esta imagen:
El Anexo B se usa comúnmente en formatos en vivo y transmisión, tales como flujos de transporte, transmisiones por aire y DVD. En estos formatos, es común repetir el SPS y el PPS periódicamente, generalmente precediendo a cada IDR creando así un punto de acceso aleatorio para el decodificador. Esto permite la posibilidad de unirse a una transmisión ya en curso.
2. AVCC
El otro método común de 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 se pierden las características de alineación de bytes del Anexo B. Solo para complicar las cosas, la longitud se puede codificar utilizando 1, 2 o 4 bytes. Este valor se almacena en un objeto de encabezado. Este encabezado a menudo se llama ''extradata'' 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 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 están almacenados fuera de banda. Es decir, separado de los datos de la corriente elemental. El almacenamiento y la transmisión de estos datos es el trabajo 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 están insertados.
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. Por lo tanto, si NALULengthSizeMinusOne
se establece en 0, cada NALU estará precedido por un solo byte que indica su longitud. Usando un solo byte para almacenar el tamaño, el tamaño máximo de un NALU es de 255 bytes. Eso es obviamente bastante pequeño. Demasiado pequeño para un cuadro clave completo. Usar 2 bytes nos da 64k por NALU. Funcionaría en nuestro ejemplo, pero sigue siendo un límite bastante bajo. 3 bytes serían perfectos, pero por alguna razón no es universalmente compatible. Por lo tanto, 4 bytes es de lejos 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 el medio está disponible en un medio de acceso aleatorio, como un disco duro, y por lo tanto se usa en formatos de contenedor comunes como MP4 y MKV.