Vidéo embarquée depuis un véhicule grâce à GStreamer
Ce billet invité a été rédigé par Damien Archenault et Clément Brunel. Merci à eux de nous faire partager leur expérience passionnante de l'utilisation de GStreamer ! (Nicolargo)
Au cours de la dernière année scolaire, deux jeunes étudiants de l’Ecole Supérieure des Sciences et des Technologies de L’Ingénieur de Nancy (ESSTIN), ont élaboré une vidéo embarquée fonctionnant avec GStreamer. Ils ont réalisé ce projet pour leur nouveau véhicule participant au Shell Eco-marathon.
Q’est ce que le Shell Eco-marathon ?
Il s’agit d’une compétition qui depuis 27 ans réunit diverses écoles d’ingénieurs, universités et établissements de l’enseignement supérieur européen pour une course à l'économie d'énergie. Depuis 12 ans, l’ESSTIN, par le biais de l’Eco Motion Team by ESSTIN (qui est le nom de l’équipe de l’école), y engage des véhicules fonctionnant avec différentes énergies.
Le principe de la compétition du Shell Eco-marathon est de parcourir un certain nombre de kilomètres en un temps limité, le tout en consommant le moins d’énergie possible.
L’équipe (composée de 20 élèves de 3ème année, 7 de 4ème année et 2 de 5ème année, encadrés par 7 tuteurs) a participé cette année à la 28ème édition de la course qui s’est déroulée du 26 au 28 mai 2011, sur le circuit de l’EuroSpeedway à Lausitz en Allemagne.
Elle y a fait concourir son tout nouveau prototype Vir’Volt intégrant toutes ses innovations technologiques, dont la vidéo embarquée que vous pouvez voir sur le sommet du véhicule:
Ce projet de vidéo embarquée est en effet tout nouveau, il a été réalisé cette année par Damien Archenault et Clément Brunel qui sont membres de l’équipe, pour répondre à la demande des médias et des sponsors d’avoir des images embarquées en temps réel. Ce qui a pu être réalisé en rediffusant les images sur internet.
Matériel utilisé
Nous avons travaillé cette année avec la société Eukrea qui nous a fournis une carte de développement GNU/Linux embarqué fonctionnant avec un processeur IMX27 et fonctionnant avec une version de linux allégée et OpenEmbedded qui permet de configurer la distribution.
GStreamer et RTSP
Nous avons d’abord essayé d’utiliser un serveur RTSP qui correspondait parfaitement à l’utilisation que nous voulions faire, à savoir diffuser un flux en streaming et profiter des options de lecture standards (lire, pause, stop, déplacement temporel).
Nous allons donc expliquer son installation.On ne peut pas utiliser le gestionnaire de paquet comme sur un système GNU/Linux standard. Il est nécessaire de cross-compiler les fichiers pour qu’ils soient valides pour l’architecture de la carte.
Pour y parvenir, nous utilisons OpenEmbedded qui facilite grandement les choses en proposant lui aussi une liste des paquets disponibles une fois l’environnement de développement correctement installé.
Pour se faire, utilisez la commande:
bitbake gst-rtsp
Un fichier .ipk sera créé et devra être transféré (par tftp et minicom) puis installé via les commandes:
tftp -gr « nom du fichier à télécharger sur la carte » « ip de l’ordinateur cible »
opkg install nomdupaquet.ipk
Une fois installé, vous pouvez utiliser votre serveur en configurant le fichier comme sur ce précédent article du blog et en l’adaptant aux modules spécifiques de l’embarqué. (Utilisez un gst-inspect sur la carte pour les découvrir !).
Vous verrez que mfw_v4lsrc, mfw_vpuencoder font leur apparition et servent à récupérer le flux de la caméra et à l’encoder de façon « plus économe » en ressource pour le « petit » processeur de la carte.
Je ne détaillerai pas plus pour le serveur RTSP, car nous n’avons malheureusement jamais réussi à le faire fonctionner, une erreur survenant lorsqu’un client venait se connecter au serveur.
Passage en GStreamer UDP
Nous nous sommes donc rabattu sur le protocole UDP (avec une couche RTP) pour transférer notre flux vidéo, qui a au moins pour avantage d’optimiser la bande passante, car moins d’informations de sécurité et de contrôle sont envoyées. De plus, en cas de perte de paquet, ou d’arrivée dans un mauvais ordre, les perturbations pour le visiteur sont souvent minimes grâce à la persistance rétinienne.
Pour faire fonctionner le protocole UDP qui est un protocole de la couche réseau (voir modèle OSI) et non de la couche session comme RTSP, nous avons besoin des paquets gst-plugin-rtp, gst-plugin-udp, libgstnetbuffer et gst-plugin-videoscale à installer via opkg install comme précédemment.
Au niveau de l’implantation de ce protocole, il y a donc deux pipelines Gstreamer, une sur la carte (véhicule) et une autre sur le PC client qui va recevoir et afficher le flux vidéo.
Celui de la carte :
La première ligne, pointe vers le client où nous voulons envoyer les images. Dans cet exemple, sur un serveur Dyndns dont nous verrons l’utilité un peu plus loin.
La deuxième commande, la plus complexe, est celle de l’initialisation du flux :
gst-launch-0.10 mfw_v4lsrc capture-width=320 capture-height=240 ! mfw_vpuencoder width=320 height=240 codec-type=std_mpeg4 framerate=13 bitrate=250 gopsize=8 ! rtpmp4vpay send-config=true ! udpsink host=$HOST port=5000
Voici le détail:
- gst-launch-0.10 : c’est la commande de base, à laquelle on va ajouter des paramètres. (ajouter –v) pour voir le détail de la commande qui s’exécute et avoir la « config » pour le client
- mfw_v4lsrc : elle permet de sélectionner la caméra comme source du flux
- -- capture-width=320 : Largeur de la fenêtre capturée
- -- capture-height=240 : Hauteur de la fenêtre capturée
- mfw_vpuencoder : C’est ce plugin qui va nous permettre d’encoder le flux
- -- width=320 : largeur de la fenêtre encodée
- -- height=240 : hauteur de la fenêtre encodée
- -- codec-type=std_mpeg4 : le codec utilisé est le codec mpeg4, ce n’est pas le meilleur codec de compression qui est h264, mais nous avions des erreurs avec ce dernier quand le client venait à se connecter.
- -- framerate=13 : Nombre d’image par seconde transmise
- -- bitrate=250 : quantité de donnée transmises. Il doit être en adéquation avec le type de réseau utilisé : réseau local filaire, réseau wifi, réseau mobile (EDGE, 3G et 3G+ ayant un débit très différent les uns des autres).
- -- gopsize=8 ! (group of picture) représente le nombre d’image envoyé simultanément sur le réseau, ce nom est proche de la moitié du framerate, et favorise la compression.
- rtpmp4vpay : regroupe les données dans des paquets RTP
- -- send-config=true : envoie la configuration du canal au client. Utile pour récupérer la clé pour synchroniser le client (voir page suivante)
- udpsink host=$HOST : adresse à laquelle on veut envoyer les données
- -- port=5000 : le port de la liaison entre les deux hôtes.
Celui du client :
Cette commande à l’air compliqué, mais elle est en fait plus simple que la commande de la carte.
gst-launch-0.10 -v --gst-debug=2 udpsrc port=5000 caps="application/x-rtp, media=(string)video,clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)4, config=(string)000001b004000001b59113000001000000012000c888800f514043c14103, payload=(int)96,ssrc=(uint)1960725087, clock-base=(uint)849638580, seqnum-base=(uint)55554" ! gstrtpjitterbuffer latency=3000 ! rtpmp4vdepay ! ffdec_mpeg4 ! autovideosink
Détail:
- gst-launch-0.10 -v --gst-debug=2 : on lance la commande en debug, pour avoir toutes les infos en cas de dysfonctionnement.
- udpsrc port=5000 port sur lequel on reçoit les données, il doit correspondre à celui de la commande de la carte.
- -- caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)4, config=(string)000001b004000001b59113000001000000012000c888800f514043c14103, payload=(int)96, ssrc=(uint)1960725087, clock-base=(uint)849638580, seqnum-base=(uint)55554" : il s’agit ici de la clé qui caractérise complètement le flux entrant. On la trouve en appliquant le –v sur la commande de la carte, puis en faisant un copier coller de la dernière ligne notée « caps »
- gstrtpjitterbuffer latency=3000 : il s’agit d’un buffer de 3secondes, non obligatoire, mais améliorant fortement la qualité et les aléas de connexion.
- rtpmp4vdepay : extraire les données des paquets RTP
- ffdec_mpeg4 : décode les données qui sont en mpeg4
- autovideosink : affiche le flux sur l’écran.
Une fois ces deux pipelines initialisés correctement (le serveur puis le client) on peut ensuite récupérer l’ordinateur sur un ordinateur quelconque et cela grâce à l’utilisation d’un serveur DNS comme Dyndns.
L’ordinateur chargé de récupérer les images doit juste être synchronisé avec le serveur DNS à l’aide d’un client comme inadyn ou ddclient, dont le fichier de configuration est le suivant :
## ddclient configuration file temps entre chaque rafraichissement de l’ip
daemon=60
# check every 60 seconds
syslog=yes
# log update msgs to syslog
mail-failure=########### #
pid=/var/run/ddclient.pid
# record PID in file.
## Detect IP with our CheckIP server
use=web, web=checkip.dyndns.com/, web-skip='IP Address'
## DynDNS username and password here
login=#####
password=#######
## Default options
protocol=dyndns2
server=members.dyndns.org
## Dynamic DNS hosts
NOMDEVOTREDNS.dyndns.org
Diffusion du flux sur Internet
Enfin, pour rediffuser en direct sur internet, nous avons utilisé deux outils formidables que sont webcamstudio qui permet de transformer un flux distant en un flux webcam et le site livestream.com qui permet justement de diffuser au monde entier les images d’une webcam, ou dans notre cas de notre vidéo embarquée.
Voici le résultat tel que les Internautes pouvaient le voir:
Conclusion
Le développement d’un tel projet prend beaucoup de temps car est malheureusement assez peu documenté, mais vous partez déjà avec une bonne piste grâce à cet article.
Merci pour votre lecture, et merci à Nicolargo (NDLR: mais c'est avec plaisir !) qui nous permet de publier via son blog.