Transmita video h264 sin transcodificar desde una cámara Logitech C920



El retraso no fue más de 0.3 segundos, dado el hecho de que la cámara está conectada a un BeagleBone Blue débil con una carga de procesador de no más del 30% y la transmisión de video se transmite a través de un enrutador wifi a una computadora portátil.

Inicialmente, la tarea era transmitir video desde el robot a una computadora grande sin cargar el procesador en el robot y sin demoras. En el proceso de buscar cámaras y programas en Google para esta tarea, se descubrió que hay cámaras con codificación de video basada en hardware en la propia cámara , después de lo cual se compró la cámara Logitech C920. Y comenzaron las pruebas y experimentos, durante los cuales se encontraron dos opciones de traducción sin transcodificación.

Todas las acciones adicionales se verifican en Ubuntu 16.04, la segunda opción probablemente funcione en Windows

Transmita video codificado por hardware desde una cámara Logitech C920 a través de cvlc y v4l2


clvc: el servidor transmite video a través de vlc desde la línea de comandos.

Hardware que codifica una transmisión de video


Establecer cámaras de formato de píxel a H264

v4l2-ctl --device=/dev/video1 --set-fmt-video=width=800,height=600,pixelformat=1 

Pruebe H264 con vlc, por lo que no restablecerá la configuración:

 cvlc v4l2:///dev/video1 --demux h264 

Si intenta esto, vlc restablecerá la configuración antes de jugar:

 cvlc v4l2:///dev/video1:chroma=h264 

La reproducción funciona. Obtenemos el flujo H264 de la cámara. Ahora pasemos por la red a través de HTTP:

 cvlc v4l2:///dev/video1:chroma=h264:width=800:height=600 --sout '#standard{access=http,mux=ts,dst=localhost:8080,name=stream,mime=video/ts}' -vvv 

(en la red, debe usar la dirección IP de su dispositivo local en lugar de localhost)

Lanzamiento del receptor:

 mplayer http://localhost:8080/ 

Resulta que MPEG-TS permite que mplayer se conecte a la transmisión en cualquier momento con un ligero retraso (probablemente esperando un fotograma clave o algo).

Si usa mux = avi, mime = video / avi, debe ejecutar mplayer en el momento en que inicia vlc, de lo contrario, mplayer no comenzará a reproducirse.

Error de ffmpeg


  • Si prueba ffmpeg en lugar de vlc para jugar, probablemente se encontrará con este problema: ffmpeg.org/trac/ffmpeg/ticket/1387
  • Tan pronto como ejecute ffmpeg, cambiará a "Video: rawvideo (YUY2 / 0x32595559)"
  • Si bien acepta MJPEG, no funcionará con H.264
  • Lo mismo sucede cuando se usa qv4l2: al iniciar la captura en modo H264, en realidad se obtiene la ventana de video YUY2

Reproducir video decodificado por hardware


Mplayer puede reproducir framebuffer, asegúrese de que X no funcione e ingrese:

 mplayer http://192.168.1.100:8080/ -fs -framedrop -vo fbdev 

También puedes jugar en la ventana X si quieres: ejecuta X desde la línea de comando:

 Xorg -retro &> /dev/zero 

Hay toneladas de mensajes de error de fbdev que silenciosamente colocamos en / dev / zero

Reproduzca una transmisión de video desde una fuente LAN vlc (consulte la sección anterior):

 DISPLAY=":0" mplayer http://192.168.1.100:8080/ -fs -framedrop 

  • Si hacemos esto, notaremos que todavía no estamos utilizando Xvideo o ninguna aceleración de hardware
  • linux-sunxi.org/CedarX parece proporcionarnos una biblioteca de VPU, que desafortunadamente es una cosa insegura de Allwinner
  • Pero hay un VLC pirateado que puede usarlo: linux-sunxi.org/VLC
  • Compilado con éxito

Raspberry pi


En caso de que experimente artefactos en la imagen y transmisiones de Raspberry Pi, use:

 cvlc v4l2:///dev/video0:chroma=h264 ... 

Es posible que deba actualizar el firmware:

 apt-get install rpi-update raspi-config rpi-update reboot 

Resumen de difusión a través de cvlc y v4l2


Las pruebas mostraron que la carga del procesador en Beaglebone Blue no es más del 30%, lo cual es muy bueno para un procesador débil, pero no está claro cómo empujar este video a ROS.

Si el ancho de banda wifi no es suficiente, el retraso del video aumenta considerablemente, en teoría esto se puede resolver cambiando de tcp a udp, la documentación de cvlc menciona la posibilidad de transmitir a través de udp.

Transmita video codificado por hardware desde una cámara Logitech C920 a través de Gstreamer


Artículo original del desarrollador que admite este método en Gstreamer.
Instalar gstreamer en Ubuntu 16.04

 sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools sudo apt-get install libgstreamer-plugins-base1.0-dev 

La fuente uvch264src le permite:


  • Capture simultáneamente una transmisión de video codificada por hardware h264 y una transmisión de video del rastreador.
  • Configure la codificación de video de hardware (velocidad de bits, fotogramas clave y más)

La fuente del visor secundario es un concepto interesante. Además de la transmisión principal H.264, obtienes una transmisión secundaria de baja resolución en formato MJPG o YUV. No estoy seguro de si esta es una característica de la cámara, el controlador o el bloque fuente de gstreamer, pero espero que sea útil para nuestras cámaras Beaglebone, siempre que la función no utilice un procesador demasiado grande para convertir entre raw y jpg.

El siguiente es un ejemplo de una tubería que muestra una transmisión H.264 de alta resolución y una transmisión del visor:

 gst-launch-1.0 -v -e uvch264src device=/dev/video0 name=src auto-start=true src.vfsrc ! queue ! video/x-raw,format=YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false 

El flujo primario H.264 se decodifica utilizando el bloque avdec_h264, accesible a través del paquete gst-libav, consulte las notas en el wiki de oz9aec . El panel del visor se puede conectar al fakelink si no es necesario, pero no creo que se pueda deshabilitar (aún puede deshabilitarlo). Al menos esta es la impresión de que estoy leyendo la publicación original del blog KaKaRoTo .

Probablemente se sobrecargará cuando vea una gran cantidad de parámetros que se pueden configurar para este bloque de origen:

 gst-inspect-1.0 uvch264src 

Lista de parámetros de Uvch264src
Detalles de la fábrica:
Rango ninguno (0)
Fuente UVC H264 de nombre largo
Fuente de Klass / video
Descripción Fuente de cámara de codificación UVC H264
Autora Youness Alaoui <youness.alaoui@collabora.co.uk>

Detalles del complemento:
Nombre uvch264
Descripción Complemento de cámaras de codificación H264 compatible con UVC
Nombre de archivo /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstuvch264.so
Version 1.8.3
Licencia LGPL
Módulo fuente gst-plugins-bad
Fecha de lanzamiento de origen 2016-08-19
Paquete binario GStreamer Bad Plugins (Ubuntu)
URL de origen launchpad.net/distros/ubuntu/+source/gst-plugins-bad1.0

GObject
+ ---- GInicialmente desconocido
+ ---- GstObject
+ ---- GstElement
+ ---- GstBin
+ ---- GstBaseCameraSrc
+ ---- GstUvcH264Src

Interfaces implementadas:
Gstchildproxy

Plantillas de almohadilla:
Plantilla SRC: 'vidsrc'
Disponibilidad: siempre
Capacidades:
video / x-raw
formato: {I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16 , NV61, NV24, GREY8, GREY16_BE, GREY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10_104, , GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE}
ancho: [1, 2147483647]
altura: [1, 2147483647]
velocidad de fotogramas: [0/1, 2147483647/1]
imagen / jpeg
ancho: [1, 2147483647]
altura: [1, 2147483647]
velocidad de fotogramas: [0/1, 2147483647/1]
video / x-h264
ancho: [1, 2147483647]
altura: [1, 2147483647]
velocidad de fotogramas: [0/1, 2147483647/1]
formato de transmisión: {byte-stream, avc}
alineación: au
perfil: {alto, principal, línea base, línea base restringida}

Plantilla SRC: 'imgsrc'
Disponibilidad: siempre
Capacidades:
VACÍO

Plantilla SRC: 'vfsrc'
Disponibilidad: siempre
Capacidades:
video / x-raw
formato: {I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16 , NV61, NV24, GREY8, GREY16_BE, GREY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10_104, , GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE}
ancho: [1, 2147483647]
altura: [1, 2147483647]
velocidad de fotogramas: [0/1, 2147483647/1]
imagen / jpeg
ancho: [1, 2147483647]
altura: [1, 2147483647]
velocidad de fotogramas: [0/1, 2147483647/1]

Banderas de elementos:
sin banderas

Banderas de la papelera:
sin banderas

Implementación de elementos:
Tiene la función change_state (): 0x7ff438f22ba0

Element no tiene capacidades de reloj.
Element no tiene capacidades de manejo de URI.

Almohadillas:
Src: 'vfsrc'
Src: 'imgsrc'
SRC: 'vidsrc'

Propiedades del elemento:
nombre: el nombre del objeto
banderas: leer, escribir
Cadena Valor predeterminado: "uvch264src0"
parent: el padre del objeto
banderas: leer, escribir
Objeto de tipo "GstObject"
manejo asíncrono: el contenedor manejará cambios de estado asincrónicos
banderas: leer, escribir
Booleano Predeterminado: falso
message-forward: reenvía todos los mensajes secundarios
banderas: leer, escribir
Booleano Predeterminado: falso
modo: el modo de captura (captura de imágenes fijas o grabación de video)
banderas: leer, escribir
Enum "GstCameraBin2Mode" Predeterminado: 2, "mode-video"
(1): mode-image - Captura de imagen fija (predeterminado)
(2): modo-video - Grabación de video
zoom: factor de zoom digital (por ejemplo, 1.5 significa 1.5x)
banderas: leer, escribir
Flotador Rango: 1 - 3.402823e + 38 Valor predeterminado: 1
zoom máximo: factor de zoom digital (por ejemplo, 1.5 significa 1.5x)
banderas: legible
Flotador Rango: 1 - 3.402823e + 38 Valor predeterminado: 10
listo para capturar: informa que este elemento está listo para comenzar otra captura
banderas: legible
Booleano Predeterminado: verdadero
vistas previas posteriores: si las imágenes de vista previa de captura deben publicarse en el bus
banderas: leer, escribir
Booleano Predeterminado: verdadero
preview-caps: los caps de la imagen de vista previa que se publicará (NULL significa CUALQUIERA)
banderas: leer, escribir
Cualquier

vista previa-filtro: un filtro de vista previa personalizado para procesar datos de vista previa de la imagen
banderas: leer, escribir
Objeto de tipo "GstElement"
inicio automático: inicia automáticamente la captura cuando pasa al estado PAUSADO
banderas: leer, escribir
Booleano Predeterminado: falso
nombre del espacio de colores: el nombre del elemento del espacio de colores
banderas: leer, escribir, solo puede ser NULL o READY
Cadena Valor predeterminado: "videoconvert"
jpeg-decoder-name: el nombre del elemento decodificador jpeg
banderas: leer, escribir, solo puede ser NULL o READY
Cadena Valor predeterminado: "jpegdec"
num-clock-samples: número de muestras de reloj para recopilar para la sincronización PTS (-1 = ilimitado)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: 0 - 2147483647 Valor predeterminado: 0
num-buffers: Número de buffers para generar antes de enviar EOS (-1 = ilimitado)
banderas: leer, escribir
Entero Rango: -1 - 2147483647 Valor predeterminado: -1
dispositivo: ubicación del dispositivo
banderas: leer, escribir
Cadena Valor predeterminado: "/ dev / video0"
nombre-dispositivo: nombre del dispositivo
banderas: legible
Cadena Predeterminado: ""
velocidad de bits inicial: velocidad de bits inicial en bits / segundo (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Entero sin signo. Rango: 0 - 4294967295 Valor predeterminado: 3,000,000
unidades de corte: unidades de corte (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Entero sin signo. Rango: 0-65535 Valor predeterminado: 4
modo de división: define la unidad de la propiedad de unidades de división (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Enum "UvcH264SliceMode" Predeterminado: 3, "slice / frame"
(0): ignorado - Ignorado
(1): bits / segmento - Bits por segmento
(2): MB / segmento - MB por segmento
(3): corte / marco - Corte por marco
iframe-period: tiempo entre tramas IDR en milisegundos (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Entero sin signo. Rango: 0-65535 Valor predeterminado: 10000
tipo de uso: el tipo de uso (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Enum "UvcH264UsageType" Valor predeterminado: 1, "en tiempo real"
(1): tiempo real - Tiempo real (videoconferencia)
(2): transmisión - Transmisión
(3): almacenamiento - Almacenamiento
(4): ucconfig0 - UCConfig 0
(5): ucconfig1 - UCConfig 1
(6): ucconfig2q - UCConfig 2Q
(7): ucconfig2s - UCConfig 2S
(8): ucconfig3 - UCConfig 3
entropía: entropía (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Enum "UvcH264Entropy" Valor predeterminado: 0, "cavlc"
(0): cavlc - CAVLC
(1): cabac - CABAC
enable-sei: Habilita el tiempo de imagen SEI (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Booleano Predeterminado: falso
num-reorder-frames: Número de cuadros B entre los cuadros de referencia (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Entero sin signo. Rango: 0-255 Predeterminado: 0
vista previa volteada: imagen volteada horizontal para flujos no H.264 (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Booleano Predeterminado: falso
tamaño del cubo con fugas: tamaño del tamaño del cubo con fugas en milisegundos (control estático)
banderas: leer, escribir, solo puede ser NULL o READY
Entero sin signo. Rango: 0-65535 Valor predeterminado: 1000
control de velocidad: modo de control de velocidad (control estático y dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Enum "UvcH264RateControl" Valor predeterminado: 1, "cbr"
(1): cbr - Velocidad de bits constante
(2): vbr - Velocidad de bits variable
(3): qp - QP constante
velocidad de fotogramas fija: velocidad de fotogramas fija (control estático y dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Booleano Predeterminado: falso
max-mbps: el número de macrobloques por segundo para la velocidad de procesamiento máxima
banderas: legible
Entero sin signo. Rango: 0 - 4294967295 Valor predeterminado: 0
level-idc: Level IDC (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero sin signo. Rango: 0-255 Predeterminado: 40
velocidad de bits máxima: la velocidad de bits máxima en bits / segundo (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero sin signo. Rango: 0 - 4294967295 Valor predeterminado: 3,000,000
velocidad de bits promedio: la velocidad de bits promedio en bits / segundo (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero sin signo. Rango: 0 - 4294967295 Valor predeterminado: 3,000,000
min-iframe-qp: el tamaño mínimo del paso de cuantización para cuadros I (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: -127-127 Predeterminado: 10
max-iframe-qp: el tamaño mínimo del paso de cuantización para cuadros I (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: -127-127 Predeterminado: 46
min-pframe-qp: el tamaño mínimo del paso de cuantización para cuadros P (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: -127-127 Predeterminado: 10
max-pframe-qp: el tamaño mínimo del paso de cuantización para cuadros P (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: -127-127 Predeterminado: 46
min-bframe-qp: el tamaño mínimo del paso de cuantización para cuadros B (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: -127-127 Predeterminado: 10
max-bframe-qp: el tamaño mínimo del paso de cuantización para cuadros B (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: -127-127 Predeterminado: 46
ltr-buffer-size: número total de marcos de referencia a largo plazo (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: 0-255 Predeterminado: 0
ltr-encoder-control: número de tramas LTR que el dispositivo puede controlar (control dinámico)
banderas: leer, escribir, puede ser NULO, LISTO, PAUSADO o JUGANDO
Entero Rango: 0-255 Predeterminado: 0

Acciones de elementos:
"Get-enum-setting": gboolean user_function (objeto GstElement *,
gchararray arg0,
gpointer arg1,
gpointer arg2);
"Get-boolean-setting": gboolean user_function (objeto GstElement *,
gchararray arg0,
gpointer arg1,
gpointer arg2);
"Get-int-setting": gboolean user_function (objeto GstElement *,
gchararray arg0,
gpointer arg1,
gpointer arg2,
gpointer arg3);
"Start-capture": void user_function (objeto GstElement *);
"Stop-capture": void user_function (objeto GstElement *);

Muchos de estos parámetros se pueden usar para configurar parámetros en compresión H.264. Esto me parece bastante sorprendente dado que la compresión se realiza mediante el chip dentro de la cámara. El siguiente ejemplo aumenta la velocidad de datos predeterminada de 3 a 5 Mbps y reduce el intervalo de fotogramas clave predeterminado de 10 a 3 segundos:

 gst-launch-1.0 -v -e uvch264src initial-bitrate=5000000 average-bitrate=5000000 iframe-period=3000 device=/dev/video0 name=src auto-start=true src.vfsrc ! queue ! video/x-raw,format=YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false 

Por otro lado, no hay parámetros para ajustar los parámetros habituales de la cámara web, como contraste, brillo, enfoque, etc. Por lo tanto, para configurarlos, todavía necesitamos herramientas externas, como v4l2.ctl, o la opción mencionada en siguiente sección

v4l2src


Parece que también podemos usar el viejo v4l2src para capturar transmisiones codificadas H.264 del Logitech C920:

 gst-launch-1.0 -v -e v4l2src device=/dev/video1 ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false 

Esto probablemente se deba a la evolución de gstreamer y V4L2. Esta opción parece más simple si no necesita cambiar la configuración de compresión H.264, y esto nos da acceso a la configuración de la cámara, como el brillo y el contraste. También tiene la ventaja de estar en un buen paquete de complementos que podría mantenerse mejor en el futuro.

Transmisión web a través de Gstreamer


En la computadora receptora, inicie el receptor:

 gst-launch-1.0 -v udpsrc port=6666 ! application/x-rtp, encoding-name=H264 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink 

En un dispositivo con cámara, comenzamos a transmitir video codificado por hardware:

 gst-launch-1.0 uvch264src name=src auto-start=true src.vidsrc ! video/x-h264,width=160,height=120,framerate=30/1 ! h264parse ! rtph264pay ! udpsink host=192.168.1.196 port=6666 

Un agradecimiento especial a Amomum por ayudarme a escribir este código.

Resumen del retraso de la transmisión de video a través de Gstreamer


Incluso con una resolución de 1920 * 1080, la carga del procesador en Beaglebone Blue no superó el 30%, y el retraso del video no fue más de 0.3 segundos. Sí, dado que el video en esta versión se transmitió a través de udp, cuando se pierden los paquetes, la imagen se desmorona al siguiente cuadro clave, pero podemos configurarlo para que los cuadros clave se envíen con más frecuencia.

Tareas ROS


Ahora solo queda insertar el video recibido en ROS, si alguien puede ayudar con esto, escriba un mensaje personal.

Source: https://habr.com/ru/post/es415567/


All Articles