Diffusez de la vidéo h264 sans transcodage à partir d'une caméra Logitech C920



Le retard n'était pas supérieur à 0,3 seconde, étant donné que la caméra est connectée à un BeagleBone Blue faible avec une charge de processeur ne dépassant pas 30% et que le flux vidéo est transmis via un routeur wifi à un ordinateur portable.

Initialement, la tâche consistait à diffuser la vidéo du robot vers un grand ordinateur sans charger le processeur sur le robot et sans retards. Dans le processus de recherche de caméras et de programmes pour cette tâche, il a été constaté qu'il existe des caméras avec un codage vidéo matériel sur la caméra elle - même , après quoi la caméra Logitech C920 a été achetée. Et des tests et expériences ont commencé, au cours desquels deux options de traduction ont été trouvées sans transcodage.

Toutes les autres actions sont vérifiées sur Ubuntu 16.04, la deuxième option fonctionne probablement sur Windows

Diffuser de la vidéo codée par matériel à partir d'une caméra Logitech C920 via cvlc et v4l2


clvc - serveur de diffusion vidéo via vlc à partir de la ligne de commande.

Encodage matériel d'un flux vidéo


Réglez les caméras au format pixel sur H264

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

Testez H264 avec vlc, il ne réinitialisera donc pas les paramètres:

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

Si vous essayez ceci, vlc réinitialisera les paramètres avant de jouer:

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

La lecture fonctionne. Nous obtenons le flux H264 de la caméra. Passons maintenant sur le réseau via 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 

(sur le réseau, vous devez utiliser l'adresse IP de votre appareil local au lieu de localhost)

Lancement du récepteur:

 mplayer http://localhost:8080/ 

Il s'avère que MPEG-TS permet à mplayer de se connecter au flux à tout moment avec un léger retard (probablement en attente d'une image clé ou de qch).

Si vous utilisez mux = avi, mime = video / avi, vous devez exécuter mplayer au moment où vous démarrez vlc, sinon mplayer ne commencera pas à jouer.

Erreur Ffmpeg


  • Si vous essayez ffmpeg au lieu de vlc pour jouer, vous rencontrerez probablement ce problème: ffmpeg.org/trac/ffmpeg/ticket/1387
  • Dès que vous exécutez ffmpeg, il passera à «Vidéo: rawvideo (YUY2 / 0x32595559)»
  • Bien qu'il accepte MJPEG, il ne fonctionnera pas avec H.264
  • La même chose se produit lors de l'utilisation de qv4l2: le démarrage de la capture en mode H264 vous donne en fait la fenêtre vidéo YUY2

Lire la vidéo décodée par le matériel


Mplayer est capable de jouer au framebuffer, assurez-vous que X ne fonctionne pas et entrez:

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

Vous pouvez également jouer dans la fenêtre X si vous le souhaitez: exécutez X à partir de la ligne de commande:

 Xorg -retro &> /dev/zero 

Il y a des tonnes de messages d'erreur fbdev que nous déposons silencieusement dans / dev / zero

Lire un flux vidéo à partir d'une source LAN vlc (voir la section ci-dessus):

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

  • Si nous le faisons, nous remarquerons que nous n'utilisons pas encore Xvideo ou toute accélération matérielle
  • linux-sunxi.org/CedarX semble nous fournir une bibliothèque VPU, qui est malheureusement une chose peu sûre pour Allwinner
  • Mais il existe un VLC piraté qui peut l'utiliser: linux-sunxi.org/VLC
  • Compilé avec succès

Raspberry pi


Si vous rencontrez des artefacts dans l'image et que les flux provenant de Raspberry Pi utilisent:

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

Vous devrez peut-être mettre à jour le firmware:

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

Résumé de la diffusion via cvlc et v4l2


Les tests ont montré que la charge du processeur sur Beaglebone Blue ne dépasse pas 30%, ce qui est très bon pour un processeur faible, mais il n'est pas clair comment pousser ensuite cette vidéo dans ROS.

Si la bande passante wifi n'est pas suffisante, le retard vidéo augmente considérablement, en théorie cela peut être résolu en passant de tcp à udp, la documentation cvlc mentionne la possibilité de diffuser via udp.

Diffuser du matériel vidéo encodé à partir d'une caméra Logitech C920 via Gstreamer


Article de développeur original prenant en charge cette méthode dans Gstreamer.
Installer gstreamer sur 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 source uvch264src vous permet de:


  • Capturez simultanément un flux vidéo codé matériel H264 et un flux vidéo sur chenilles.
  • Configurer l'encodage vidéo matériel (bitrate, images clés et plus)

La source du viseur secondaire est un concept intéressant. En plus du flux principal H.264, vous obtenez un flux secondaire basse résolution au format MJPG ou YUV. Je ne sais pas s'il s'agit d'une fonctionnalité de la caméra, du pilote ou du bloc source gstreamer, mais j'espère que cela sera utile pour nos caméras Beaglebone, à condition que la fonction n'utilise pas un processeur trop grand pour convertir entre raw et jpg.

Voici un exemple de pipeline qui affiche un flux H.264 haute résolution et un flux viseur:

 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 

Le flux principal H.264 est décodé à l'aide du bloc avdec_h264, accessible via le package gst-libav, voir les notes sur le wiki oz9aec . Le panneau du viseur peut être connecté au fakelink s'il n'est pas nécessaire, mais je ne pense pas qu'il puisse être désactivé (vous pouvez toujours le désactiver). C'est du moins l'impression que je lis le billet de blog KaKaRoTo original.

Vous serez probablement surchargé lorsque vous verrez un grand nombre de paramètres pouvant être configurés pour ce bloc source:

 gst-inspect-1.0 uvch264src 

Liste des paramètres uvch264src
Détails d'usine:
Aucun (0)
Nom UVC H264 de longue date
Source / vidéo Klass
Description UVC H264 Source de caméra d'encodage
Auteur Youness Alaoui <youness.alaoui@collabora.co.uk>

Détails du plugin:
Nom uvch264
Description Plugin des caméras d'encodage H264 conforme UVC
Nom de fichier /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstuvch264.so
Version 1.8.3
Licence LGPL
Module source gst-plugins-bad
Date de sortie de la source 2016-08-19
Package binaire GStreamer Bad Plugins (Ubuntu)
URL d'origine launchpad.net/distros/ubuntu/+source/gst-plugins-bad1.0

GObject
+ ---- GInitiallyUnown
+ ---- GstObject
+ ---- GstElement
+ ---- GstBin
+ ---- GstBaseCameraSrc
+ ---- GstUvcH264Src

Interfaces implémentées:
Gstchildproxy

Modèles de pads:
Modèle SRC: 'vidsrc'
Disponibilité: Toujours
Capacités:
vidéo / x-raw
format: {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, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_22_10410 , GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE}
largeur: [1, 2147483647]
hauteur: [1, 2147483647]
cadence d'images: [0/1, 2147483647/1]
image / jpeg
largeur: [1, 2147483647]
hauteur: [1, 2147483647]
cadence d'images: [0/1, 2147483647/1]
vidéo / x-h264
largeur: [1, 2147483647]
hauteur: [1, 2147483647]
cadence d'images: [0/1, 2147483647/1]
format de flux: {byte-stream, avc}
alignement: au
profil: {élevé, principal, ligne de base, ligne de base contrainte}

Modèle SRC: «imgsrc»
Disponibilité: Toujours
Capacités:
VIDE

Modèle SRC: 'vfsrc'
Disponibilité: Toujours
Capacités:
vidéo / x-raw
format: {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, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_22_10410 , GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE}
largeur: [1, 2147483647]
hauteur: [1, 2147483647]
cadence d'images: [0/1, 2147483647/1]
image / jpeg
largeur: [1, 2147483647]
hauteur: [1, 2147483647]
cadence d'images: [0/1, 2147483647/1]

Drapeaux d'élément:
aucun jeu de drapeaux

Indicateurs de bac:
aucun jeu de drapeaux

Mise en œuvre de l'élément:
A la fonction change_state (): 0x7ff438f22ba0

L'élément n'a aucune capacité de synchronisation.
L'élément n'a aucune capacité de gestion d'URI.

Tampons:
Src: 'vfsrc'
Src: «imgsrc»
SRC: «vidsrc»

Propriétés des éléments:
name: le nom de l'objet
drapeaux: lire, écrire
String Par défaut: "uvch264src0"
parent: parent de l'objet
drapeaux: lire, écrire
Objet de type "GstObject"
gestion asynchrone: le bac gérera les changements d'état asynchrones
drapeaux: lire, écrire
Booléen. Par défaut: faux
message-forward: transfère tous les messages enfants
drapeaux: lire, écrire
Booléen. Par défaut: faux
mode: Le mode de capture (capture d'images fixes ou enregistrement vidéo)
drapeaux: lire, écrire
Enum "GstCameraBin2Mode" Par défaut: 2, "mode-video"
(1): mode-image - Capture d'images fixes (par défaut)
(2): mode-vidéo - Enregistrement vidéo
zoom: facteur de zoom numérique (par exemple 1,5 signifie 1,5x)
drapeaux: lire, écrire
Flotter. Plage: 1 - 3.402823e + 38 Par défaut: 1
zoom max: facteur de zoom numérique (par exemple 1,5 signifie 1,5x)
drapeaux: lisibles
Flotter. Plage: 1 - 3.402823e + 38 Par défaut: 10
ready-for-capture: informe que cet élément est prêt à démarrer une autre capture
drapeaux: lisibles
Booléen. Par défaut: vrai
post-aperçus: si des images d'aperçu de capture doivent être publiées sur le bus
drapeaux: lire, écrire
Booléen. Par défaut: vrai
preview-caps: les majuscules de l'image d'aperçu à publier (NULL signifie TOUT)
drapeaux: lire, écrire
TOUT

preview-filter: Un filtre d'aperçu personnalisé pour traiter les données d'image d'aperçu
drapeaux: lire, écrire
Objet de type "GstElement"
démarrage automatique: démarre automatiquement la capture lorsque vous passez à l'état PAUSED
drapeaux: lire, écrire
Booléen. Par défaut: faux
colorspace-name: nom de l'élément de l'espace colorimétrique
drapeaux: lecture, écriture, ne peut être que NULL ou READY
String Par défaut: "vidéoconvert"
jpeg-decoder-name: nom de l'élément décodeur jpeg
drapeaux: lecture, écriture, ne peut être que NULL ou READY
String Par défaut: "jpegdec"
num-clock-samples: nombre d'échantillons d'horloge à collecter pour la synchronisation PTS (-1 = illimité)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: 0 - 2147483647 Par défaut: 0
num-buffers: Nombre de tampons à sortir avant d'envoyer EOS (-1 = illimité)
drapeaux: lire, écrire
Entier Plage: -1 - 2147483647 Par défaut: -1
appareil: emplacement de l'appareil
drapeaux: lire, écrire
String Par défaut: "/ dev / video0"
nom-périphérique: nom du périphérique
drapeaux: lisibles
String Par défaut: ""
bitrate initial: bitrate initial en bits / seconde (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Entier non signé. Plage: 0 - 4294967295 Par défaut: 3 000 000
slice-units: Slice units (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Entier non signé. Plage: 0 - 65535 Par défaut: 4
slice-mode: définit l'unité de la propriété slice-units (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Énumération "UvcH264SliceMode" Par défaut: 3, "tranche / trame"
(0): ignoré - Ignoré
(1): bits / tranche - Bits par tranche
(2): Mo / tranche - Mo par tranche
(3): tranche / image - tranche par image
iframe-period: temps entre les trames IDR en millisecondes (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Entier non signé. Plage: 0 - 65535 Par défaut: 10000
type-utilisation: type d'utilisation (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Énumération "UvcH264UsageType" Par défaut: 1, "temps réel"
(1): temps réel - Temps réel (vidéoconférence)
(2): diffusion - diffusion
(3): stockage - Stockage
(4): ucconfig0 - UCConfig 0
(5): ucconfig1 - UCConfig 1
(6): ucconfig2q - UCConfig 2Q
(7): ucconfig2s - UCConfig 2S
(8): ucconfig3 - UCConfig 3
entropie: entropie (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Enum "UvcH264Entropy" Par défaut: 0, "cavlc"
(0): cavlc - CAVLC
(1): cabac - CABAC
enable-sei: active la temporisation de l'image SEI (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Booléen. Par défaut: faux
num-reorder-frames: nombre de cadres B entre les cadres de référence (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Entier non signé. Plage: 0 - 255 Par défaut: 0
Aperçu inversé: image inversée horizontalement pour les flux non H.264 (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Booléen. Par défaut: faux
leaky-bucket-size: taille de la taille du seau qui fuit en millisecondes (contrôle statique)
drapeaux: lecture, écriture, ne peut être que NULL ou READY
Entier non signé. Plage: 0 - 65535 Par défaut: 1000
contrôle du taux: mode de contrôle du taux (contrôle statique et dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Enum "UvcH264RateControl" Par défaut: 1, "cbr"
(1): cbr - Débit binaire constant
(2): vbr - Débit binaire variable
(3): qp - QP constant
Fixed-Framerate: Framerate fixe (contrôle statique et dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Booléen. Par défaut: faux
max-mbps: le nombre de macroblocs par seconde pour la vitesse de traitement maximale
drapeaux: lisibles
Entier non signé. Plage: 0 - 4294967295 Par défaut: 0
level-idc: Level IDC (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier non signé. Plage: 0 - 255 Par défaut: 40
débit binaire de crête: le débit binaire de pointe en bits / seconde (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier non signé. Plage: 0 - 4294967295 Par défaut: 3 000 000
bitrate moyen: le bitrate moyen en bits / seconde (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier non signé. Plage: 0 - 4294967295 Par défaut: 3 000 000
min-iframe-qp: taille minimale du pas de quantification pour les trames I (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: -127 - 127 Par défaut: 10
max-iframe-qp: taille minimale du pas de quantification pour les trames I (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: -127 - 127 Par défaut: 46
min-pframe-qp: taille minimale du pas de quantification pour les trames P (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: -127 - 127 Par défaut: 10
max-pframe-qp: la taille minimale du pas de quantification pour les trames P (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: -127 - 127 Par défaut: 46
min-bframe-qp: taille minimale du pas de quantification pour les trames B (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: -127 - 127 Par défaut: 10
max-bframe-qp: la taille minimale du pas de quantification pour les trames B (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: -127 - 127 Par défaut: 46
ltr-buffer-size: nombre total de trames de référence à long terme (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: 0 - 255 Par défaut: 0
ltr-encoder-control: nombre de trames LTR que l'appareil peut contrôler (contrôle dynamique)
drapeaux: lire, écrire, peut être NULL, READY, PAUSED ou PLAYING
Entier Plage: 0 - 255 Par défaut: 0

Actions des éléments:
"Get-enum-setting": gboolean user_function (objet GstElement *,
gchararray arg0,
gpointer arg1,
gpointer arg2);
"Get-boolean-setting": gboolean user_function (objet GstElement *,
gchararray arg0,
gpointer arg1,
gpointer arg2);
"Get-int-setting": gboolean user_function (objet GstElement *,
gchararray arg0,
gpointer arg1,
gpointer arg2,
gpointer arg3);
"Start-capture": void user_function (objet GstElement *);
"Stop-capture": void user_function (objet GstElement *);

Beaucoup de ces paramètres peuvent être utilisés pour configurer des paramètres dans la compression H.264. Je trouve cela plutôt surprenant étant donné que la compression est effectuée par la puce à l'intérieur de la caméra. L'exemple suivant augmente le débit de données par défaut de 3 à 5 Mbps et réduit l'intervalle d'images clés par défaut de 10 à 3 secondes:

 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 

D'un autre côté, il n'y a pas de paramètres pour ajuster les paramètres habituels de la webcam, tels que le contraste, la luminosité, la mise au point, etc. Ainsi, pour les configurer, nous avons encore besoin d'outils externes, tels que v4l2.ctl, ou l'option mentionnée dans section suivante.

v4l2src


Il semble que nous pouvons également utiliser le bon vieux v4l2src pour capturer les flux codés H.264 à partir du 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 

Cela est probablement dû à l'évolution de gstreamer et de V4L2. Cette option semble plus simple si vous n'avez pas besoin de modifier les paramètres de compression H.264, ce qui nous donne accès aux paramètres de la caméra tels que la luminosité et le contraste. Il a également l'avantage d'être dans un bon package de plugins qui pourrait être mieux conservé à l'avenir.

Webdiffusion via Gstreamer


Sur l'ordinateur récepteur, démarrez le récepteur:

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

Sur un appareil avec une caméra, nous commençons à transmettre de la vidéo codée par matériel:

 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 merci spécial à Amomum pour m'avoir aidé à écrire ce code.

Résumé du délai de diffusion vidéo via Gstreamer


Même avec une résolution de 1920 * 1080, la charge du processeur sur Beaglebone Blue ne dépassait pas 30% et le retard vidéo ne dépassait pas 0,3 seconde. Oui, puisque la vidéo de cette version a été diffusée via udp, lorsque des paquets sont perdus, l'image se désagrège à l'image clé suivante, mais nous pouvons la configurer de sorte que les images clés soient envoyées plus souvent.

Tâches ROS


Il ne reste plus qu'à pousser la vidéo reçue dans ROS, si quelqu'un peut vous aider, écrivez de manière personnelle.

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


All Articles