¿Por qué el uso de H264 en emisor / receptor tuberías introducir retardo simplemente enorme?

StackOverflow https://stackoverflow.com/questions/2893407

Pregunta

Cuando intento crear oleoducto que usos H264 de vídeo de transmisión, consigo algún retraso enorme, hasta 10 segundos de video para transmisión de mi máquina a ... mi máquina! Esto es inaceptable para mis objetivos y me gustaría consultar StackOverflow sobre lo que (u otra persona) hecho mal.

Tomé tuberías de página de documentación gstrtpbin y ligeramente modificado para utilizar los Speex:

Esta es la tubería del remitente: #! / Bin / sh

gst-launch -v gstrtpbin name=rtpbin \
        v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        pulsesrc ! audioconvert ! audioresample  ! audio/x-raw-int,rate=16000 !    \
                  speexenc bitrate=16000 ! rtpspeexpay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

tubería del receptor:

! / Bin / sh

gst-launch -v\
    gstrtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video, clock-rate=(int)90000, encoding-name=(string)H263-1998" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! rtpspeexdepay ! speexdec ! audioresample ! audioconvert ! alsasink \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5007 sync=false async=false

Estas tuberías, una combinación de H263 y Speex, lo suficientemente fino trabajo. Chasquee los dedos cerca de la cámara y micropohne y luego veo el movimiento y escuchar el sonido al mismo tiempo.

Luego cambió tuberías de usar H264 lo largo de la ruta de vídeo.

El remitente pasa a ser: #! / Bin / sh

gst-launch -v gstrtpbin name=rtpbin \
        v4l2src ! ffmpegcolorspace ! x264enc bitrate=300 ! rtph264pay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        pulsesrc ! audioconvert ! audioresample  ! audio/x-raw-int,rate=16000 !    \
                  speexenc bitrate=16000 ! rtpspeexpay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

y el receptor se convierte en: #! / Bin / sh

gst-launch -v\
    gstrtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! rtph264depay ! ffdec_h264 ! xvimagesink                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! rtpspeexdepay ! speexdec ! audioresample ! audioconvert ! alsasink \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5007 sync=false async=false

Esto es lo que sucede bajo Ubuntu 10.04. No me di cuenta de tales enormes retrasos en Ubuntu 9.04 -. Los retrasos que había en la gama 2-3 segundos, AFAIR

¿Fue útil?

Solución

Con la ayuda de "Sharktooth" en el # x264 en Freenode, descubrí que la versión git de soportes gst-plugins-ugly la "latencia cero" preestablecido.

http://cgit.freedesktop.org/gstreamer/gst-plugins-ugly

Me pellizqué el ejemplo de conjunto "x264enc pass = cali cuantificador = 20 = sintonizar ZeroLatency", y la latencia parece permanecer en 0.7 - 0.9 segundos. No puedo encontrar la manera de conseguir que cualquier menor.

Otros consejos

Algo allí se almacena en búfer, más probable es que el codificador. Cuantos más datos se tiene que trabajar con, la compresión más eficaz que puede lograr. No estoy familiarizado con ese codificador, pero por lo general hay un ajuste para la cantidad de almacenamiento en búfer.

x264 por defecto amortigua la entrada para tener más datos para trabajar con ellos. El aumento de la demora de Ubuntu 10.04 es muy probablemente debido a que se ha quedado atascado en una versión x264 de edad, antes de la introducción de --mbtree y --rc-búsqueda hacia delante.

Esta página de Mewiki se puede ver la forma de calcular la latencia, en el número de marcos, y la siguiente, sobre lo que debe desactivar primero para reducir la latencia:

La reducción de la latencia de x264 es posible, pero reduce la calidad. Si no desea la latencia, establecer ZeroLatency --tune. Si usted puede manejar una pequeña latencia (es decir, menos de 1 segundo), es bien vale la pena que ajustar las opciones para permitir esto. Aquí hay una serie de pasos que puede seguir para reducir la latencia de forma incremental. Pare cuando su latencia es lo suficientemente bajo como:

  1. Comience con valores por defecto
  2. Kill sync-lookahead
  3. rc-gota de búsqueda hacia delante a no menos de 10 ~
  4. hilos de caer a un valor inferior (es decir, decir 6 en lugar de 12)
  5. Uso rodajas hilos
  6. Desactivar rc-lookahead
  7. Inhabilitar fotogramas B
  8. Ahora estás en --tune ZeroLatency

Por lo tanto, primero debe tratar de añadir a su línea de comandos algo así como

La sincronización de búsqueda hacia delante = 0, rc-lookahead = 10 (no estoy seguro del formato de la línea de comandos de la aplicación)

Esto debe afeitarse la mayor parte de la latencia, a un costo baja eficiencia de compresión. Si usted tiene muchos núcleos (un cuádruple núcleo con HT, por ejemplo), sino que también puede valer la pena número 4. Do, en un pequeño coste velocidad.

Uso sintonizar = ZeroLatency, según el consejo Sharktooth, si esto todavía no es suficiente.

Más sobre el tema: http://x264dev.multimedia.cx/archives/249

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top