2012-07-09 15 views
11

Tengo problemas para transmitir videos H.264 a través de RTSP. El objetivo es transmitir en vivo una imagen de cámara a un cliente RTSP (idealmente un complemento de navegador al final). Esto ha funcionado bastante bien hasta ahora, excepto por un problema: el video se demorará en el inicio, tartamudeará cada pocos segundos y tendrá un retardo de ~ 4 segundos. Esto es malo.Streaming RTP/RTSP: problemas de sincronización/indicación de la hora

Nuestra configuración es para codificar con x264 (w/zerolatency & ultrarrápido) y se empaqueta en RTSP/RTP con libavformat desde ffmpeg 0.6.5. Para las pruebas, recibo la transmisión con una tubería GStreamer con gst-launch cuando me conecto a un servidor RTSP. Sin embargo,, he podido reproducir el mismo problema al transmitir directamente desde otra instancia de GStreamer con solo RTP.

máquina de envío:

gst-launch videotestsrc ! x264enc tune=zerolatency ! rtph264pay ! udpsink host=10.89.6.3 

Recepción de la máquina:

gst-launch udpsrc ! application/x-rtp,payload=96 ! rtph264depay ! decodebin ! xvimagesink 

También puede ejecutar estos tanto en la misma máquina, basta con cambiar el host a 127.0.0.1 en el remitente. En el extremo receptor, usted debe notar el tartamudeo y generalmente de vídeo bajo rendimiento, junto con las repetidas advertencias de la consola:

WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped. 
Additional debug info: 
gstbasesink.c(2875): gst_base_sink_is_too_late(): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: 
There may be a timestamping problem, or this computer is too slow. 

Una sugerido comúnmente "solución" que he visto en todo el Internet es utilizar sync=false con xvimagesink:

gst-launch udpsrc ! application/x-rtp,payload=96 ! rtph264depay ! decodebin ! xvimagesink sync=false 

el vídeo a continuación, reproduzca con una latencia casi inexistente, aun cuando se probó con nuestro software de la cámara. Esto es útil para las pruebas, pero no es muy útil para la implementación, ya que no funcionará con Totem, VLC o sus incrustaciones de complementos del navegador.

Me gustaría tratar de resolver el problema en la fuente; Sospecho que hay algún tipo de información de marca de tiempo que falta en la transmisión H.264 por x264 o tal vez en las cargas útiles de RTP. ¿Hay alguna manera de modificar el fuente gst pipeline para que yo haga no necesito usar sync=false en el receptor?

Si eso no es posible, ¿cómo puedo decirle a los clientes (mediante SDP u otros) que la transmisión no debe sincronizarse? Finalmente, insertamos esto en el navegador utilizando un tipo de complemento VLC, por lo que una solución que funcionaría allí sería incluso mejor.

Respuesta

7

Puede agregar "sync = false" a la canalización de gst de origen. En Ubuntu 12.04 que parece eliminar los mensajes de retraso y error.

Aquí está el comando que utilicé en la fuente:

gst-launch videotestsrc ! x264enc tune=zerolatency ! rtph264pay ! udpsink host=127.0.0.1 sync=false 

y esto es lo que utilicé en el receptor:

gst-launch udpsrc ! application/x-rtp,payload=96 ! rtph264depay ! decodebin ! xvimagesink 

Por desgracia, no tengo idea de por qué esto funciona o incluso qué componente del la propiedad "sync = false" pertenece a (en la canalización de origen).

+0

Gracias .. mismo problema, pero he dado "sync = false" en el lado del receptor y funcionó para mí. –

10

Como se publicó root.ctrlc, puede usar sync = FALSE. Sin embargo, es posible que observe un gran aumento en el uso de CPU en el extremo del remitente. El motivo es que sync = FALSE le dice al receptor que elimine los búferes tan pronto como los reciba. El fregadero impulsa toda la tubería.Por lo tanto, sync = FALSE hará que la tubería codifique el video y lo empuje a UDP lo más rápido posible; usará 100% de CPU.

Lo que necesitas es el gstrtpjitterbuffer. También se ocupa de las marcas de tiempo, que están rotas aquí.

Ejemplo remitente:

gst-launch-0.10 -v videotestsrc ! videorate ! video/x-raw-yuv, framerate=30/1 ! ffmpegcolorspace ! x264enc ! rtph264pay ! udpsink port=50000 host=<sender IP> 

Ejemplo receptor:

gst-launch-0.10 udpsrc port=50000 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000 , encoding-name=(string)H264 , payload=(int)96" ! gstrtpjitterbuffer ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! videoscale ! "video/x-raw-yuv, width=320, height=240" ! xvimagesink 
+0

+1, pero ¿cómo se usa 'gstrtpjitterbuffer' cuando usamos gst-launch-0.10 -v' gstrtpbin name = rtpbin latency = 40 udpsrc caps = "... port = 50000', puedes compartir la parte del receptor mientras utilizando gstrtpbin utilizado? – YumYumYum

+0

El gsrtpbin ya incluye un gstrtpjitterbuffer. En cuanto a la línea de comando, trataré de responderte. Actualmente no puedo probarlo, ya que no tengo GStreamer 0.10 instalado aquí. (Por cierto, debería moverse a 1.0, esto viene muy recomendado.) –

+0

@dv_ Gracias por señalar 'gstrtpjitterbuffer' y por la explicación de' sink = false'. ¿Podrías explicar cómo se maneja la tubería de otro modo (cuando 'sync = true')? – joanpau

0

No sé cuánto es esto cierto, pero cuando corro mi tubería sin necesidad de conectar el cargador de batería para mi portátil, solía lanzarme la misma advertencia, y cuando enchufé la fuente de alimentación, créeme, funcionó. Creo que es debido a la vieja batería CMOS, que no funciona como debería. ya que es responsable de la generación del reloj.

+1

En este caso, sospecho que su computadora portátil tiene una opción de configuración de energía para reducir la potencia máxima disponible de la CPU cuando se ejecuta con batería. Cuando se ejecuta con el cargador, obtiene 100% de CPU, cuando funciona con batería, obtiene menos. Por lo tanto, "o esta computadora es demasiado lenta". – KevinM