video - mpeg4 - h264 mp4
Obteniendo las dimensiones de una transmisiĆ³n de video H264 (4)
Estoy tratando de obtener las dimensiones (alto y ancho) de una secuencia H264. Sé que para obtener los mismos detalles de una secuencia mpeg2, debe observar los cuatro bytes que siguen al código de inicio del encabezado de secuencia ((01B3)). ¿Funcionará la misma lógica para H264? Agradecería cualquier ayuda que obtenga ...
En cuanto al cálculo del tamaño del cuadro, la fórmula anterior no es correcta.
Cuando chroma_format_idc
está presente, entonces tenemos que extraerlo del SPS. Cuando chroma_format_idc
no está presente, se chroma_format_idc
es igual a 1 (4: 2: 0 formato cromático). En ese caso, el separate_color_plane_flag
no está configurado. Eso significa que chromaArrayType = chroma_format_idc
y subWidthC
y subHeightC
son iguales a 2.
Las variables cropUnitX y cropUnitY se obtienen de la siguiente manera:
Si
chromaArrayType
es igual a0
,cropUnitX
ycropUnitY
se derivan como:cropUnitX = 1 cropUnitY = 2 - frame_mbs_only_flag
De lo contrario (
chromaArrayType
es igual a1
,2
o3
),cropUnitX
ycropUnitY
se derivan como:cropUnitX = subWidthC cropUnitY = subHeightC * ( 2 - frame_mbs_only_flag )
Ahora puede usar cropUnitX
y cropUnitY
en la fórmula anterior para obtener los valores correctos para el tamaño del marco.
En realidad, los parámetros de recorte deben usarse solo cuando [frame_cropping_flag] está habilitado en SPS. ¡Disfruta H.264!
Los cálculos de tamaño son desafortunados desafortunadamente y deberían ser:
width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_left_offset*2 - frame_crop_right_offset*2;
height= ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);
¡¡¡NO!!!
Debe ejecutar una función compleja para extraer las dimensiones de video de Conjuntos de parámetros de secuencia. ¿Como hacer esto? Bueno, primero debe escribir su propio decodificador Exp-Golomb, o encontrar uno en línea ... en el código fuente de live555 en algún lugar hay uno, por ejemplo ...
Entonces debes obtener un marco SPS. Tiene NAL=0x67
(NAL es el primer byte en un marco H.264) y puede encontrarlo como una cadena codificada en Base64 en SDP bajo sprop-parameter-sets
es la primera cadena de Base64 anterior a la primera coma. Otras cadenas separadas por comas hay conjuntos de parámetros de imagen ... Este es un SPS de SDP Z0KAKYiLQDIBL0IAAB1MAAK/IAg=
necesita decodificar algo así desde Base64 en una matriz de bytes.
¡Entonces debe extraer RAW BYTE SECUENCIA DE CARGA, seguido de NAL UNIT HEADER en esa matriz de bytes! Por lo general, es de un byte de longitud, pero seq_parameter_set_data( )
leyendo para estar seguro ... RBSP contiene los bytes necesarios para ejecutar la función seq_parameter_set_data( )
. Por lo tanto, primero debe quitar el NAL UNIT HEADER (uno o más bytes).
Aquí está la función que extrae los bytes RBSP de SPS NAL UNIT:
Luego, cuando tiene SPS (RBSP bytes), necesita realizar una función que analiza bits en esta matriz de bytes. Aquí está la función con todos los parámetros analizados (el documento completo se puede encontrar aquí: http://www.itu.int/rec/T-REC-H.264-201003-I/en y es gratis):
Ahí puedes ver algunas cosas extrañas ... primero, tus dimensiones de video se calculan así:
Width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_right_offset*2 - frame_crop_left_offset*2;
Height = ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);
En segundo lugar, y lo más importante, en la columna DESCRIPTOR de esta tabla de códigos, se establece lo que debe hacer para leer el parámetro de texto en negrita en la primera columna. Esto es lo que significan los valores:
- u (N) - Lee un número sin firmar que tiene N bits de longitud
- s (N) - Lee un número firmado que tiene N bits de longitud
- ue (v) - Lee un número Exp-Golomb sin signo (v es para longitud variable, por lo que es igual a
ue()
) - se (v) - Leer un número Exp-Golomb firmado
Aquí es donde su decodificador Exp-Golomb es útil ...
Entonces, implemente esta función, analice SPS, y obtendrá su ancho y alto. Disfruta ... :)