2012-07-18 20 views
13

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:

  1. Escribir el NAL Prefijo (0x00 0x00 0x01) y luego los datos de SPS o PPS

Fragmentación con bit de inicio

  1. Escribir NAL Prefijo
  2. unidad de escritura NAL Byte
  3. Escribir restante datos en bruto

fragmentación sin bit de inicio

  1. 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:

  1. Encabezado: El archivo FFmpeg tiene como unos 0x30 bytes de cabecera
  2. pie de página: el archivo FFmpeg también tiene un pie de página
  3. 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?

+1

¿Pudo lograr esto? En caso afirmativo, ¿está dispuesto a compartir la solución? ¡Gracias! –

Respuesta

0

Parece que la transmisión se empaquetó. Muchos formatos de contenedor dividen el flujo de bits en paquetes y agregan un poco de información como marcas de tiempo, longitud del paquete, etc. Esto da ganchos al decodificador para omitir el archivo sin decodificar todo, resolviendo cuando se pierde un paquete, sincronizando de audio/vídeo, la combinación de múltiples flujos, etc.

Mira la información de formato de archivo MP4 para más información:
http://en.wikipedia.org/wiki/MPEG-4_Part_14

2

Además de añadir el contenedor MP4, H.264 fFmpeg convierte su anexo flujo de bytes B (con Prefijos NAL) a un formato de prefijo de longitud.

Su [0x00 0x00] [2 Bytes "Aleatorios"] es un entero de 32 bits, dando la longitud de la siguiente unidad NAL en bytes.

-1

Puede leer más sobre sus cambios en h264 specs abierto. Capítulo Anexo B.

Cuestiones relacionadas