GStreamer aime les caméras IP Axis

Date: 7/04/2009 | Catégories: Hardware,Open-source,Reseau,Systeme | Tags: ,,,

Si vous lisez régulièrement ce blog, vous savez que je m'intéresse au FrameWork multimédia GStreamer (cliquez ici pour voir la liste des billets sur le sujet). Nous allons poursuivre la découverte de cette superbe trousse à outil multimédia en l'appliquant sur la récupération et l'exploitation de flux vidéo venant de caméras IP. Nous nous focaliserons ici sur les caméras IP AXIS, non pas que j'ai des actions dans cette société mais il faut avouer que leurs caméras sont de très bonne qualité et l'accès aux flux vidéos assez simple.

Avant de nous plonger dans le vif du sujet et si vous souhaitez faire ces tests chez vous, il faut au préhalable installer GStreamer sur votre système.

Ma configuration de test est la suivante:

Lors de la rédaction de ce billet, j'ai utilisé la caméra AXIS 213:

La configuration de cette caméra (cam01) est la suivante:

Format CIF
Compression 50%
Frame rate: 25 images/s

Configuration du PC1:

OS: GNU/Linux Debian 5.0 + Gstreamer 0.10.19-3
Hardware: Pentium Quad core CPU 2.8 Ghz + 4 Go RAM

Configuration du PC2:

OS: GNU/Linux Ubuntu 8.10 + Gstreamer 0.10.21-4
Hardware: Pentium Dual core CPU 3.0 Ghz + 512 Mo RAM

Affichage du flux vidéo

Cette caméra (comme toutes les caméras AXIS) permet la diffusion sur le réseau en utilisant deux formats:

  • MJPEG sur HTTP
  • MPEG-4 sur RTSP

Affichage du flux MJPEG/HTTP

On lance la commande suivante sur la machine PC1:

gst-launch gnomevfssrc location=http://cam01/axis-cgi/mjpg/video.cgi?resolution=CIF ! jpegdec ! ffmpegcolorspace ! autovideosink

Un rapide ntop sur notre machine PC1 nous indique que le fux est gourmand en bande passante (de l'ordre de 3.3 Mbps). L'occupation CPU varie entre 20% et 60%. La vidéo est fluide.

Affichage du flux MPEG4/RTSP

On lance la commande suivante sur la machine PC1:

gst-launch-0.10 rtspsrc location=rtsp://cam01:554/mpeg4/media.amp latency=0 ! decodebin ! ffmpegcolorspace ! autovideosink

La bande passante entre la caméra et le PC1 est alors de 1 Mbps en pics (moyenne de 400 Kbps quand il y a peu de mouvement devant la caméra). L'occupation CPU varie entre 5% et 15%. La vidéo est fluide.

Le paramètre latency (qui est par défaut à 3000, soit 3 secondes) permet de réduire la taille du buffer d'entrée. Si vous êtes sur un réseau LAN, vous pouvez sans problème mettre comme valeur 0 (comme je l'ai fait dans mon exemple). Par contre sur des réseaux moins performant (en terme de débit, de perte de paquets...), il vaut mieux conserver un buffer un peu plus élevé.

Encodage du flux vidéo dans un fichier

Nous allons continuer notre test en essayant d'encoder "à la volée" le flux vidéo venant de la caméra IP. Détaillons un peu notre pipeline:

  • récupérer le flux MPEG4/RTSP de la caméra
  • l'afficher sur l'écran
  • réduire le nombre d'images par seconde (fps) à 1
  • encoder le flux en MJPG
  • sauvegarder dans un fichier AVI (output.avi)

La ligne de commande correspondante à lancer sur PC1 est:

gst-launch rtspsrc location=rtsp://cam01:554/mpeg4/media.amp latency=0 ! queue ! decodebin ! ffmpegcolorspace ! tee name=save ! queue ! autovideosink save. ! queue ! videorate ! capsfilter caps="video/x-raw-yuv,framerate=(fraction)1/1" ! queue ! jpegenc ! avimux ! filesink location=output.avi .save

Le fichier généré (output.avi) occupe un espace disque d'environ 15 Ko par seconde (soit 54 Mo/heure).

Afin d'optimiser cette taille, il est possible d'utiliser Theora (dans un fichier OGG), un codec vidéo libre et efficace. La commande devient alors:

gst-launch rtspsrc location=rtsp://cam01:554/mpeg4/media.amp latency=0 ! queue ! decodebin ! ffmpegcolorspace ! tee name=save ! queue ! autovideosink save. ! queue ! videorate ! capsfilter caps="video/x-raw-yuv,framerate=(fraction)1/1" ! queue ! theoraenc ! oggmux ! filesink location=output.ogg .save

On a alors une taille de fichier de sortie (output/ogg) d'environ 6 Ko par seconde (soit 21 Mo/heure).

Mixer plusieurs vidéos en une

Si vous disposé de plusieurs caméras, il peut être utile de mixer ces différentes sources dans une même image (un peu comme le mode PIN des télévisions).

Je vais dans l'exemple ci-dessous, prendre deux sources (Camera AXIS + Webcam USB) et les mixer:

La pipeline est la suivante:

gst-launch  v4l2src ! queue ! videoscale ! capsfilter caps="video/x-raw-yuv,width=64,height=48,framerate=(fraction)5/1" ! ffmpegcolorspace ! videobox border-alpha=0 alpha=1.0 top=-230 left=-278 ! videomixer name=mix ! ffmpegcolorspace ! autovideosink mix. rtspsrc location=rtsp://cam01:554/mpeg4/media.amp latency=0 ! queue ! decodebin ! queue ! videorate ! capsfilter caps="video/x-raw-yuv,width=352,height=288,framerate=(fraction)25/1" ! ffmpegcolorspace ! mix.

Attention de bien fixer les framerates (videorate ou videoscale + capsfilter), car videomixer (le plugin qui s'occupe de faire le mixage vidéo) semble assez sensible sur ce point.

Streaming vers une autre machine

Nous allons maintenant voir comment transcoder le flux vidéo d'une caméra IP pour le diffuser (streamer vers une autre machine).

La description du pipeline du PC1 est la suivante:

  • récupérer le flux MPEG4/RTSP de la caméra
  • réencodage en Theora (à 250 Kbps)
  • diffusion en UDP vers le PC2

puis celle du PC2:

  • récupérer de flux Theora/UDP venant du PC1
  • décodage Theora
  • affichage de la vidéo

et les commandes correspondantes, sur le PC2 (il faut lancer cette commande en premier):

gst-launch -v udpsrc port=1234 ! theoradec ! autovideosink

puis sur le PC1:

gst-launch rtspsrc location=rtsp://cam01:554/mpeg4/media.amp latency=0 ! queue ! decodebin ! ffmpegcolorspace ! queue ! videorate ! capsfilter caps="video/x-raw-yuv,framerate=(fraction)25/1" ! queue ! theoraenc bitrate=250 ! queue ! udpsink host=pc2 port=1234

En moyenne, le débit observé entre PC1 et PC2 est de l'ordre de 250 Kbps (conforme donc a ce que l'on a configuré dans le plugin theoraenc), on observe cependant des pics à 250 Kps+30%. La consommation de CPU est de l'ordre de 25% sur PC1 et de 5% sur PC2. La vidéo est recue de manière fluide sur le PC2. Là encore, il ne faut pas oublier de fixer le nombre d'images par seconde avec videorate + capsfilter.

L'avantage avec GStreamer, c'est qu'il intégre une liste de plugins assez impressionnante, il est alors facile de les insérer dans notre pipeline. Par exemple, si l'on souhaite reprendre l'exemple ci-dessus et y ajouter un texte en sur-impression (overlay), il suffit d'utiliser le plugin cairotextoverlay.

La commande sur le PC1 devient alors:

gst-launch-0.10 rtspsrc location=rtsp://cam01:554/mpeg4/media.amp latency=0 ! queue ! decodebin ! ffmpegcolorspace ! queue ! cairotextoverlay text="Attention Tigrou !" shaded-background=true ! queue ! videorate ! capsfilter caps="video/x-raw-yuv,framerate=(fraction)25/1" ! queue ! theoraenc bitrate=250 ! queue ! udpsink host=pc2 port=1234

et le résultat sur PC2:

Pour conclure

Ce billet nous a permis de mettre le pied dans le monde passionnant du traitement des flux vidéo. Ce n'est qu'une introduction et la seule limite est votre imagination. Je vous rappelle que GStreamer peut être simplement intégré à vos applications grâce aux API disponibles. Si vous avez des questions et remarques sur le sujet, il existe une section spéciale dans le forum !

  • Cenwen

    Ce billet est aussi interressant que les precedants meme si les cameras axis ne sont pas données et donc difficilement accessibles pour mettre en application ce nouveau tutoriel.
    J’en profite, si je peux me permettre, il doit y avoir une erreur d’ecriture dans le 1er para$ affichage du flux mjpeg/http ce serait plutot autovideosink au lieu de autovideosinksink. Dans la meme optique, dans le 2eme article sur gstreamer (1er streaming video) dans le 2eme para$ theora et tcp il doit manquer sur le serveur « videoscale method=1! » si j’ai
    bien compris.
    En tout cas merci de m’avoir fait decouvrir les enormes possibilités non exploités de gstreamer dont je suis devenu accros. D’ailleurs je pense que je vais m’inscrire sur le forum et vivement les prochains articles.

  • @Cenwen: merci pour cette relecture attentive (je corrige le billet). En ce qui concerne le choix de ces caméras IP,c’est simplement que j’en ai à disposition au boulot… Mais je pense que le process est adaptable à d’autre caméra IP…

  • Super toutes ces explications !
    Je pense que ça pourra bien m’aider.
    Cependant (dans le cadre de mon projet d’école), je souhaite aussi récupérer le son de la camera IP (Axis 207). J’ai donc utilisé la commande suivante :
    gst-launch rtspsrc location=rtsp://172.16.14.120:554/mpeg4/media.amp ! decodebin name=demux \
    demux. ! queue ! ffmpegcolorspace ! autovideosink \
    demux. ! queue ! autoaudiosink
    Voyant que cela ne fonctionnait pas (l’image fige direct) alors que la lecture vidéo uniquement fonctionne, je me suis donc focalisé sur l’audio avec :
    gst-launch rtspsrc location=rtsp://172.16.14.120:554/mpeg4/media.amp ! decodebin ! faad ! audioconvert ! audioresample ! autoaudiosink

    Erreur :
    ERREUR : de l’élément /pipeline0/rtspsrc0/udpsrc6 : Erreur interne de flux de données.
    Information de débogage supplémentaire :
    gstbasesrc.c(2193): gst_base_src_loop (): /pipeline0/rtspsrc0/udpsrc6:
    streaming task paused, reason not-linked (-1)
    Execution ended after 230769225 ns.

    J’ai remarqué par ailleurs que VLC détecte le stream video (#0.0) mais pas l’audio…
    Pour info, ma camera IP diffuse un flux rtsp en mpeg4/aac et les librairies faac et faad sont présentes sur ma machine…

    Une idée ? Peut-être un demux plus adapté ?

    merci d’avance

  • K

    Hello Nico,

    super intéressant, je pense tester d’ici peu le process (il faut d’abord que j’achète les cams).
    Dans ce billet tu donnes l’exemple de mix de deux cams mais utilisant un protocole différent.
    Je suppose que l’on peux faire marcher plusieurs cam ip pour ce genre d’exercice?

    Bien à toi.

  • @k: oui sans problème…

  • k

    Hello Nico,
    je viens d’acquérir une axis 206. L’installation sur Ubuntu 9.04 se fait sans problème. Par contre à l’affichage du flux vidéo, une paire d’erreur apparait dans on terminal (la même en rtsp):

    # gst-launch gnomevfssrc location=http://192.168.1.90/axis-cgi/mjpg/video.cgi?resolution=640×480 ! jpegdec ! ffmpegcolorspace

    réponse à la commande:
    Définition du pipeline à PAUSED…
    Le pipeline a terminé la phase PREROLL…
    Passage du pipeline à la phase PLAYING…
    New clock: GstSystemClock
    ERREUR : de l’élément /GstPipeline:pipeline0/GstGnomeVFSSrc:gnomevfssrc0 : Erreur interne de flux de données.
    Information de débogage supplémentaire :
    gstbasesrc.c(2330): gst_base_src_loop (): /GstPipeline:pipeline0/GstGnomeVFSSrc:gnomevfssrc0:
    streaming task paused, reason not-linked (-1)
    Execution ended after 35011154 ns.
    Définition du pipeline à PAUSED…
    Définition du pipeline à READY (prêt)…
    Définition du pipeline à NULL…
    Libération du pipeline (FREE)…

    J’ai bien lu tt tes billets mais je ne vois pas d’ou viens le problème… J’ai peut être omis quelques chose?….

    Merci d’avance.
    Bien à toi.

  • bloubs

    Bonsoir Nico,

    peut on penser à la même configuration Cam IP / Machine via internet et non pas en réseau local?…

    merci d’avance 🙂

  • Salut Nico,
    Super interressant ce post,
    est ce que tu pourrai m’orienter vers un modèle de cam autre que la AXIS (un peu moins chere) avec laquelle on peut appliquer ce process.
    merci pour tes explications détaillées et merci d’avance pour ta réponse
    a+

  • @duelduweb: tu peux regarder du coté de la société Comelit qui fait des camera IP de qualité et moins chère que les Axis ( http://www.comelit.it/FR/fr/Download/Catalogues/Catalogo_Videoor.pdf )

  • T’es trop fort, quelle réactivité…
    j’y vais de ce pas, merci pour l’info
    a+

  • damien

    salut

    super tuto

    je voudrais savoir si il est possible de récupérer le flux d’ une cam et le rediriger dans une page php/html poser sur le serveur(camera ip axis sur reseau local —> serveur web ovh —> page php)

    merci
    si vous avez des idées 🙂
    ps: le flux est en rtsp

    • Flumotion fait cela très bien. Fais une recherche sur le blog, tu devrais trouver des pistes…

  • Wilkin André

    Bonjour je voudrais savoir si il y moyen de streamer le flux d’une camera (qui diffuse du h264 en rtsp) (avec mot de pass et user ) vers un flux http (c’est pour mon serveur domotique (jeedom)pas encore de plugin gerant le rtsp) merci et bravo pour ce post