2011-04-01 18 views
8

Tengo el video FFMPEG de línea base de transmisión h264, que tengo que encapsular en RTP y enviar a los teléfonos SIP para su decodificación. Estoy utilizando Linphone con el complemento h264 para Windows y Mirial para el progreso de decodificación. Sin embargo, a veces obtengo un gran tamaño de fotograma (3Kb ~ 9Kb) del FFMPEG, que obviamente no cabe en la MTU.Cómo fragmentar los paquetes H264 en RTP que cumplen con RFC3984

Si envío estos cuadros "tal cual" y confío en la función de fragmentación de IP, algunos teléfonos pueden reproducirlo lo suficientemente bien, pero otros se ahogan y no pueden decodificar la transmisión. Creo que esto se debe a que la transmisión no cumple con el RFC 3984 que especifica que los paquetes que no encajan en la MTU deben separarse en diferentes NALU y marcar el final de una Trama con la función de Marca de RTP.

¿Cómo sé dónde puedo "cortar" el marco I o P? Noté que los paquetes h264 fragmentados (los que no tienen la etiqueta Mark) a veces terminan en 0xF8 pero no pudieron obtener un patrón y en el RFC 3984 que describe cómo enviar estos paquetes a través de RTP no especifica cómo hacerlo.

ACTUALIZACIÓN: ¿Alguien sabe cómo decirle a la biblioteca X264 cómo generar NALU de un tamaño máximo? de esa manera debería ser capaz de evitar este problema. Gracias a todos

Respuesta

12

Como autor de RFC 3984bis (para ser RFC 6184), se detalla exactamente cómo convertir NAL H.264 en paquetes RFC 3984. Hay 3 modos: 0 (solo-NAL), 1 (permite fragmentar y combinar NAL) y 2 (le permite fragmentar, combinar e intercalar la orden de transmisión para cambiar la forma en que una pérdida de ráfaga afectará una transmisión, entre otras cosas) Ver SDP packetization-mode. Solo se requiere el modo 0.

El modo 0 (Single-NAL) requiere que utilice la fragmentación UDP (desaconsejado) o indique al codificador que no genere NAL mayores que MTU-X. Usted debería ser capaz de decirle esto al codificador.

El modo 1 le permite fragmentar. Consulte el RFC sobre cómo configurar un paquete FU-A. La información de fragmentación está en el frente. También puede usar STAP para agregar NAL pequeños como paquetes SPS y PPS enviados antes de los IDR (normalmente). Cada paquete requiere encabezados RTP normales con números de secuencia incrementados (pero con la misma marca de tiempo).

Se espera una marca en el último paquete RTP de un marco (no de un fragmento o NAL) pero no debe contar con ello.

+0

@jesusp Gracias por su respuesta! sin embargo, estoy usando X264 como la capa del codificador y no conozco una forma de decirle al codificador que genere NALU de 1500 bytes como máximo. Buscando en Google me consiguió aquí: [link] (http://comments.gmane.org/gmane.comp.video.x264.devel/5460). Sin embargo, parece que no se ha fusionado en la biblioteca. ¿Alguien sabe una forma de hacerlo usando X264? De lo contrario, tendré que implementar packetization-mode = 1. Gracias a todos –

+0

@jesup ¿Puedes explicar por qué la fragmentación UDP es mala? Según entiendo, la fragmentación UDP (o mejor, la fragmentación de IP) debería conducir a menos tráfico de red ya que no tiene que codificar un encabezado RTP (UDP respectivamente) para cada paquete (para que gane de 12 a 20 bytes por paquete) . – xryl669

+0

Hay mucha verborrea en esto ... Algunos enrutadores no admiten la fragmentación en absoluto. Varios OS y otros cuadros intermedios pueden necesitar volver a ensamblar el paquete fragmentado, y todos tienen límites en el tamaño reensamblado, generalmente muy por debajo del tamaño máximo de UDP de 65535 bytes (a menudo alrededor de 4K). No hay un tamaño máximo estándar. la fragmentación lo deja más vulnerable a la pérdida de paquetes (aunque si los datos son inutilizables en paquetes únicos que pueden no ser de mucha ayuda). Tal vez esto debería ser revisado, pero la falta de un tamaño estándar útil es un gran problema. – jesup

5

En x264, creo que el int i_slice_max_size en x264_param_t se puede usar para controlar el tamaño. Eche un vistazo a x264.h No recuerdo dónde lo leí, pero la publicación dice que este miembro de la estructura se puede usar para controlar el tamaño NAL, pero no lo he probado yo mismo.

int i_slice_max_size;/* Tamaño máximo por porción en bytes; incluye gastos generales NAL estimados. */

EDIT: He encontrado la fuente

http://mailman.videolan.org/pipermail/x264-devel/2011-February/008263.html

+0

Gracias! Me estoy metiendo en esto esta tarde, pero ya lo revisé y no va a ser un problema aplicar estos cambios. ¡Muchas gracias por tu ayuda! –

Cuestiones relacionadas