Manera moderna de transmitir H.264 desde la Raspberry Cam

16

Obtuve el Pi B + y la cámara Pi y ahora estoy tratando de encontrar la configuración más eficiente (CPU baja) y la latencia más baja para transmitir video codificado H.264 desde la cámara al servidor de mi casa.

He leído lo siguiente:

  1. http://pi.gbaman.info/?p=150

  2. http://blog.tkjelectronics.dk/2013/06/how-to-stream-video-and-audio-from-a-raspberry-pi-with-no-latency/comment-page-1/#comments

  3. http://www.raspberrypi.org/forums/viewtopic.php?p=464522

(Todos los enlaces usan gstreamer-1.0 de deb http://vontaene.de/raspbian-updates/ . main.)

Se ha hecho mucho al respecto en los últimos años.

Originalmente, teníamos que canalizar la salida de raspividen gst-launch-1.0(ver enlace 1).

Luego (enlace 2) se creó el controlador oficial V4L2, que ahora es estándar, y permite obtener directamente los datos sin una tubería, utilizando solo gstreamer (ver especialmente la publicación de towolf »sáb 07 de diciembre de 2013 3:34 pm en el enlace 2):

Remitente (Pi): gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=192.168.178.20 port=5000

Receptor: gst-launch-1.0 -v udpsrc port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false

Si entiendo correctamente, ambas formas usan la GPU para hacer la decodificación H264, pero la última es un poco más eficiente ya que no necesita pasar por el núcleo otra vez ya que no hay una tubería entre los procesos involucrados.


Ahora tengo algunas preguntas sobre esto.

  1. ¿Sigue siendo la última la forma más reciente de obtener eficientemente H264 de la cámara? He leído sobre gst-omx, lo que permite las tuberías gstreamer como ... video/x-raw ! omxh264enc ! .... ¿Esto hace algo diferente al simple uso video/x-h264, o podría incluso ser más eficiente? ¿Cual es la diferencia?

  2. ¿Cómo puedo saber qué plugin de codificación gstreamer se usa realmente cuando uso la video/x-h264 ...canalización? Esto parece estar especificando el formato que quiero, en comparación con las otras partes de la tubería, donde explícitamente nombro el componente (código) (como h264parseo fpsdisplaysink).

  3. En esta respuesta al enlace 1, Mikael Lepistö menciona "Eliminé un paso de filtro innecesario del lado de transmisión" , lo que significa que cortó el gdppayy gdpdepay. ¿Qué hacen esos? ¿Por qué son necesarios? ¿Realmente puedo quitarlos?

  4. También menciona que al especificar caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"parámetros para el udpsrclado receptor, puede iniciar / reanudar la transmisión en el medio de la transmisión. ¿Qué logran estos límites, por qué estas opciones específicas, dónde puedo leer más sobre ellos?

  5. Cuando hago lo que se sugiere en las preguntas 3 y 4 (agregando caps, soltando gdppayy gdpdepay), mi latencia de video se vuelve mucho peor (y parece acumularse, la latencia aumenta con el tiempo, y después de unos minutos, el video se detiene). ¿Por qué podría ser eso? Me gustaría obtener la latencia que obtuve con el comando original, pero también tengo la característica de poder unirme a la transmisión en cualquier momento.

  6. He leído que RTSP + RTP usualmente usan una combinación de TCP y UDP: TCP para mensajes de control y otras cosas que no deben perderse, y UDP para la transmisión de datos de video real. En las configuraciones anteriores, ¿estoy realmente usando eso, o solo estoy usando UDP? Es un poco opaco para mí si gstreamer se encarga de esto o no.

¡Agradecería cualquier respuesta a una sola de estas preguntas!

nh2
fuente
La idea de que usar una tubería |crea algún problema en este contexto es una pieza increíble de BS ¿Has probado algún raspivid | cvlcmétodo? No he tenido la cámara durante mucho tiempo o mucho tiempo para jugar con ella, pero usar eso para producir una transmisión http (visible en Linux en el otro extremo con vlc) parece funcionar bien.
Ricitos de oro
@goldilocks No estoy diciendo que la tubería sea un "problema", solo que no es necesario y tiene algo de sobrecarga, al igual que en cat file | grep ...lugar de grep ... file. La tubería agrega otra capa de copia hacia y desde el núcleo, que es fácilmente medible, especialmente en dispositivos con poco ancho de banda de memoria. Si gstreamer puede leer directamente el archivo del dispositivo, ¿por qué no usarlo? Con respecto a su raspivid | cvlcsugerencia: estaba usando esto antes de cambiar a la solución basada en gstreamer, tiene una latencia de hasta 3 segundos más que gstreamer (no sé por qué).
nh2
Sí, definitivamente tiene algo de latencia. WRT la tubería, mi punto sobre el "contexto" es que esto no puede ser un cuello de botella aquí: la E / S de la red será mucho más lenta, etc. Sin embargo, tiene razón, puede agregar un poco a la CPU hora. Solo apostaría que no mucho; ejecutar eso a resolución completa, cvlcusa ~ 45%, pero solo pasar por una tubería a esa velocidad de datos (teniendo en cuenta nuevamente que la tubería no lo está desacelerando ) apenas movería la aguja, creo. Me gusta <5%. No es totalmente insignificante si quieres hacer esto de la manera más eficiente posible, por supuesto ...
goldilocks
... Simplemente no quiero que nadie más que lea esto tenga la impresión de que usar una tubería aquí podría ser responsable de problemas de latencia u otros problemas. Eso es un arenque rojo. O podría estar equivocado;)
Ricitos de
Si lo que busca es la eficiencia, es posible que desee incluir el uso total observado de la CPU para varios métodos a una resolución / velocidad de fotogramas específica. El único que probé es el raspivid | cvlcque es 40-50%. Las personas pueden responder mejor a una pregunta que los desafía a mejorar en una figura específica. En este momento estás preguntando mucho por qué, sin explicar por qué cada uno es significativo.
Ricitos de oro

Respuestas:

8

Las opciones:

  1. raspivid -t 0 -o - | nc -k -l 1234

  2. raspivid -t 0 -o - | cvlc stream:///dev/stdin --sout "#rtp{sdp=rtsp://:1234/}" :demux=h264

  3. cvlc v4l2:///dev/video0 --v4l2-chroma h264 --sout '#rtp{sdp=rtsp://:8554/}'

  4. raspivid -t 0 -o - | gst-launch-1.0 fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=SERVER_IP port=1234

  5. gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=SERVER_IP port=1234

  6. uv4l --driver raspicam

  7. picam --alsadev hw:1,0

Cosas para considerar

  • latencia [ms] (con y sin pedirle al cliente que quiera más fps que el servidor)
  • CPU inactiva [%] (medida por top -d 10)
  • CPU 1 cliente [%]
  • RAM [MB] (RES)
  • misma configuración de codificación
  • mismas características
    • audio
    • reconectar
    • Cliente independiente del sistema operativo (vlc, webrtc, etc.)

Comparación:

            1    2    3    4    5    6    7
latency     2000 5000 ?    ?    ?    ?    1300
CPU         ?    1.4  ?    ?    ?    ?    ?
CPU 1       ?    1.8  ?    ?    ?    ?    ?
RAM         ?    14   ?    ?    ?    ?    ?
encoding    ?    ?    ?    ?    ?    ?    ?
audio       n    ?    ?    ?    ?    y    ?
reconnect   y    y    ?    ?    ?    y    ?
any OS      n    y    ?    ?    ?    y    ?
latency fps ?    ?    ?    ?    ?    ?    ?
revs usuario1133275
fuente
1
¿Por qué todos los valores en esta tabla " ?"?
Larsks
@larsks porque a nadie le importa probar y completar los datos en este 'wiki comunitario'
usuario1133275
6

La única forma moderna de transmitir H264 a un navegador es con UV4L : sin latencia, sin configuración, con audio opcional, audio / video bidireccional opcional. No hay salsa GStreamer mágica, pero es posible extender su uso.

prinxis
fuente
Como quiero transmitir a mi servidor y posiblemente a teléfonos inteligentes, no es un requisito transmitir a un navegador. Además, el navegador puede ponerle restricciones adicionales (por ejemplo, sin RTSP, posiblemente sin TCP a menos que use WebRTC, pero eso es complicado). Pero UV4L todavía parece prometedor. ¿Podría vincular a un lugar donde pueda leer sobre cómo usarlo / extraer los datos para transmitirlos a través de la red?
nh2
Santa vaca, creo que encontré la página de ejemplo ... ¡esta cosa parece ser capaz de hacer todo ! RTMP, RTSP, transmisión HTTPS, WebRTC, "Detección de objetos en tiempo real y seguimiento de objetos + detección de rostros" : ¿qué demonios? Cada uno con algunos indicadores de línea de comandos simples a uv4l? ¡Mi tubería gstreamer se ve bastante anticuada ahora! ¡No puedo esperar para probar cómo es la latencia!
nh2
1
Oh no, es fuente cerrada :( Eso lo descalifica para el uso de vigilancia en el hogar que tenía en mente :(
nh2
admite WebRTC, WebRTC bidireccional. la latencia es de ~ 200 ms de audio / video, probablemente menos audio
prinxis
@ nh2, el enlace parece estar roto, ¿tiene alguna ubicación actualizada para esa página de ejemplo?
Punit Soni
1

1.) transmisión de h264es a través de la red (solo muestra)

en el servidor:

raspivid -v -a 524 -a 4 -a "rpi-0 %Y-%m-%d %X" -fps 15 -n -md 2 -ih -t 0 -l -o tcp://0.0.0.0:5001

en el cliente:

mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer h264es ffmpeg://tcp://<rpi-ip-address>:5001

2.) transmisión de mjpeg a través de la red (solo muestra)

en el servidor:

/usr/local/bin/mjpg_streamer -o output_http.so -w ./www -i input_raspicam.so -x 1920 -y 1440 -fps 3

en el cliente:

mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer lavf http://<rpi-ip-address>:8080/?action=stream

todo esto incluso funciona en un RPi Zero W (configurado como servidor)

chispa
fuente
Hola, gracias por tu respuesta, ¿qué sample onlysignifica?
nh2
Quería decir 'es solo un ejemplo'. Puede adaptar esto a sus necesidades.
sparkie