Medio Ambiente:conversión H.264 con FFmpeg (de un flujo RTP)
tengo una cámara IP, que es capaz de streaming de datos a través de RTP en un formato codificado H.264. Esta corriente sin procesar se registra desde ethernet. Con esa información tengo que trabajar.
Objetivo:
Al final quiero tener un archivo .mp4 *, que puedo jugar con los reproductores de medios comunes (como VLC o Windows MP).
¿Qué he hecho hasta ahora:
que tomar ese flujo de datos en bruto que tengo y analizarlo. Como los datos se han transmitido a través de RTP, debo ocuparme de los NAL Bytes, SPS y PPS.
1. Escribir un archivo RAW
Primero determinar el tipo de cada trama recibida a través de Ethernet. Para hacerlo, analizo los primeros dos bytes de cada carga útil de RTP, de modo que puedo obtener los 8 bits de unidad NAL, los bits de tipo de fragmento y los bits de inicio, reservado y final. En la carga útil, que están dispuestos de la siguiente manera:
Byte 1: [ 3 NAL Unit Bits | 5 Fragment Type Bits]
Byte 2: [Start Bit | Reserved Bit | End Bit | 5 NAL Unit Bits]
De esto se puede determinar:
- inicio y final de un fotograma de vídeo -> Start Bit Bit y Fin Tipo de
- la Carga -> 5 Fragmento tipo Bits
- unidad NAL Byte
los tipos de fragmentos que sean necesarias mi caso son:
Fragment Type 7 = SPS
Fragment Type 8 = PPS
Fragment Type 28 = Video Fragment
El Byte NAL se crea poniendo los bits de la unidad NAL del byte 1 y 2 juntos.
Ahora dependiendo del tipo de fragmentación hago lo siguiente:
SPS/PPS:
- Escribir el NAL Prefijo (
0x00 0x00 0x01
) y luego los datos de SPS o PPS
Fragmentación con bit de inicio
- Escribir NAL Prefijo
- unidad de escritura NAL Byte
- Escribir restante datos en bruto
fragmentación sin bit de inicio
- escribir datos en bruto
Esto significa que mi archivo sin formato parece algo li ke esto:
[NAL Prefix][SPS][NAL Prefix][PPS][NAL Prefix][NAL Unit Byte][Raw Video Data][Raw Video Data]....[NAL Prefix][NAL Unit Byte][Raw Video Data]...
Por cada PPS y SPS que encuentro en mis datos de la secuencia, acabo de escribir NAL Prefijo (0x00 0x00 0x01) y luego el SPS/PPS en sí.
ahora no puedo jugar estos datos con algún reproductor de medios, lo que me lleva a:
2. Convertir el archivo
Como quería evitar trabajar tanto con los codecs que acabo fue a usar una aplicación existente -> FFmpeg. Esta Estoy llamando con esos parámetros:
ffmpeg.exe -f h264 -i <RawInputFile> -vcodec copy -r 25 <OutPutFilename>.mp4
-f h264
: Esto debería decir ffmpeg He una h264 codificado corriente
-vcodec copy
: Presupuesto de la página de manual:
Force video codec to codec. Use the "copy" special value to tell that the raw codec data must be copied as is.
-r 25
: Establece la velocidad de cuadros a 25 FPS.
Cuando llamo a ffmpeg con esos parámetros obtengo un archivo .mp4, que puedo reproducir con VLC y Windows MP, por lo que realmente funciona. Pero el archivo ahora se ve un poco diferente de mi archivo sin formato.
Esto me lleva a mi pregunta:
¿Qué he hecho yo?
Mi problema no es que no funcione. Solo quiero/necesito saber lo que hice en realidad al llamar a ffmpeg. Tenía un archivo H264 sin formato que I no pudo reproducir.Después de usar FFmpeg I puede reproducirlo.
Existen las siguientes diferencias entre el archivo RAW original (que he escrito) y el escrito por FFmpeg:
- Encabezado: El archivo FFmpeg tiene como unos 0x30 bytes de cabecera
- pie de página: el archivo FFmpeg también tiene un pie de página
- cambiado Prefijo y 2 nuevos Bytes:
Mientras que un nuevo marco de vídeo desde el archivo RAW comenzó como [NAL Prefix][NAL Unit Byte][Raw Video Data]
en el nuevo archivo que tiene el siguiente aspecto:
[0x00 0x00][2 "Random" Bytes][NAL Unit Byte][Raw Video Data].....[0x00 0x00[2 other "Random" Bytes][NAL Unit Byte][Raw Video Data]...
entiendo que el flujo de vídeo necesita un formato contenedor (corrígeme si estoy equivocado, pero supongo que la nueva cabecera y el pie son responsables de eso). Pero, ¿por qué cambia realmente algunos Bytes en los datos brutos? No puede tratarse de una decodificación, ya que la secuencia en sí misma debe ser decodificada por el jugador y no ffmpeg.
Como puede ver, no necesito una nueva solución para mi problema como mucho más una explicación (para que pueda explicarlo por mí mismo). ¿Qué hace ffmpeg en realidad? ¿Y por qué cambia algunos bytes dentro de los datos de video?
¿Pudo lograr esto? En caso afirmativo, ¿está dispuesto a compartir la solución? ¡Gracias! –