2012-03-06 7 views
10

No pude encontrar una solución para my previous question así que decidí probarlo paso a paso.Cómo escribir la secuencia de RTP/H264 como un archivo

Lo que quiero hacer ahora es almacenar la secuencia RTP/H264 como un archivo.

Lo que he encontrado hasta ahora es el siguiente:

(en primer lugar, mi RTP/H264 es FU-A, que es la forma de)

| RTP HEADER 12bytes long | FU INDICATOR 1byte | FU HEADER 1byte | FU payload | 

Según entendí RFC 6184 documento, yo soy iniciar un NAL con un paquete que tiene '1' en el primer bit del encabezado de FU y anexar los siguientes paquetes que establecen '0' en el primer bit hasta el último paquete que tiene '1' en el segundo bit de encabezado de FU.

Creo que así es como obtener un NAL completo antes de la paquetización FU-A y también lo que encontré es que necesito poner los 'bits iniciales' (0x00000001) al frente de cada NAL completo.

Pero no hay suerte hasta el momento. El siguiente es parte del registro

========= the new NAL is as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ... 
========= adding the next NAL as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ... 
========= adding the next NAL as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ... 
========= adding the next NAL as 716 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ... 
========= a NAL is summed up as 4866 
========= the new NAL is as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ... 
========= adding the next NAL as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ... 
========= adding the next NAL as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ... 
========= adding the next NAL as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ... 
========= adding the next NAL as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ... 
========= adding the next NAL as 139 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ... 
========= a NAL is summed up as 7061 
========= the new NAL is as 1377 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]41/1000001 [5]E4/11100100 [6]40/1000000 [7]1A/11010 ... 
========= a NAL is summed up as 1369 
========= the new NAL is as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E6/11100110 [7]60/1100000 ... 
========= adding the next NAL as 94 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E6/11100110 [7]60/1100000 ... 
========= a NAL is summed up as 1472 
========= the new NAL is as 447 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]41/1000001 [5]E8/11101000 [6]80/10000000 [7]16/10110 ... 
========= a NAL is summed up as 439 
========= the new NAL is as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EA/11101010 [7]A0/10100000 ... 
========= adding the next NAL as 1174 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EA/11101010 [7]A0/10100000 ... 
========= a NAL is summed up as 2552 
========= the new NAL is as 1400 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EC/11101100 [7]C0/11000000 ... 
========= adding the next NAL as 1364 
[0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EC/11101100 [7]C0/11000000 ... 
========= a NAL is summed up as 2742 
========= the new NAL is as 1400 
... 

mi pregunta es,

  1. si puedo conseguir los NAL completas de los paquetes fragmentados por Fu-A, ¿cómo puedo hacerlo como un fichero del cual es capaz de correr por VLC u otro jugador?

  2. Todavía estoy confundido si tengo que mantener el indicador FU y el encabezado FU o no. Alguien dijo que tengo que tomarlos sólo para el primer paquete (que empiezan con '1' en el encabezado FU)

Cualquier consejo será muy apreciado.

Gracias.

+0

Oye, estoy tratando de hacer exactamente lo mismo .. Leí el RFC 6184 e intenté seguir los mismos pasos y almacenarlo en un archivo ... Pero mi archivo parece no funcionar ... ¿Por favor publica la solución que usaste? Esta pregunta tiene más de 7k visitas. Será útil para todos nosotros. –

Respuesta

5
  1. Una opción es mux los datos en un formato de archivo como mp4 o avi para poder jugarlo con VLC. AFAIR avi no encajaba bien con H.264 (no recuerdo el motivo). Hay bibliotecas gratuitas, como libmp4, o si está en Windows usando DirectShow, Geraint's mp4mux.

    Otra opción es utilizar ffmpeg para convertir un archivo de 0.264 en un mp4

    ffmpeg -i test.264 test.mp4

    Esto supone que el archivo contiene 0.264 unidades NAL separadas por códigos de inicio .

  2. De RFC6184

    La carga útil FU se compone de fragmentos de la carga útil de la unidad fragmentada NAL de modo que si se concatenan secuencialmente las cargas útiles de la unidad de fragmentación de UF consecutivos, la carga útil de la fragmentada NAL la unidad puede ser reconstruida.El octeto del tipo de unidad NAL de la unidad NAL fragmentada no se incluye como tal en la carga útil de la unidad de fragmentación, sino que la información del octeto tipo unidad NAL de la unidad NAL fragmentada se transmite en los campos F y NRI de la FU. indicador octeto de la unidad de fragmentación y en el campo de tipo el encabezado FU. Una carga útil FU puede tener cualquier cantidad de octetos y MAY estar vacía.

    Usted tendría que reconstruir la unidad NAL original antes de escribirla en el archivo de 0.264 si se toma el segundo enfoque descrito en 1.

+0

Gracias de nuevo Ralf, por cierto, realmente me pregunto qué debería hacer con los sps, pps. Actualmente, el NAL completo que estoy reconstruyendo no tiene sps, paquetes de pps. Creo que tengo que ponerlos antes del primer paquete de la transmisión o necesito tener un AVCodecContext inicializado con sps, pps. ¿¿Cómo crees que?? – Jun

+0

Bien, hice algunos progresos. Puse los paquetes sps, pps en la cabecera de la transmisión y edité cada cabecera de cada nal reconstruida desde 2 bytes (todavía constaba del indicador FU, encabezado FU) en 1byte como originalmente. ahora el analizador de flujo de elecard lee el archivo pero aún no es legible para vlc o cualquier otro reproductor, pero si lo convertí en mp4 con 'ffmpeg -i src.mp4 con.mp4', el con.mp4 puede ser reproducido por reproductores de video en general. – Jun

+0

Pero necesito decodificar el archivo mediante ffmpeg api en mi propio reproductor, así que tengo que hacerlo funcionar sin la conversión. Debería ser decodificado por ffmpeg api avcodec_decode_video2() .. algún consejo ???? – Jun

6

Las unidades FU, STAP, y MTAP NAL están específico solo para la paquetización RTP ya que están diseñados para facilitar el transporte de red. En otras palabras, no confíe en que un decodificador lo analice correctamente. En última instancia, debe volver a montar las unidades NAL como en el caso de los paquetes FU o dividirlas en varias unidades NAL, el caso de STAP/MTAP.

Una vez que tiene una unidad NAL (y esto incluye PPS, SPS, SEI, particiones de división y todos los otros tipos en el rango 1-23), puede escribir en el disco junto con los códigos de inicio '0001' según H.264 anexo B.

La colocación de la secuencia H.264 del anexo B en un contenedor como MPEG-4 se puede hacer con varias herramientas de línea de comandos (estoy bastante seguro de que ffmpeg puede hacerlo).

Cuestiones relacionadas