lundi 6 janvier 2014

Gstreamer et Serveur de streaming RTSP sur Raspberry Pi (2eme Partie)

Je vais partir du postulat que vous connaissez les bases de GStreamer (source, sink, pipeline, etc ...) sinon, je vous conseille fortement d'aller jeter un coup d'œil sur le blog de nicolargo section GStreamer. Vous y trouverez toutes les informations nécessaires à la compréhension de la suite du billet.
Je me suis même inspiré d'un de ses billets (j'ai streamé avec GStreamer) pour rédiger le mien.

Les tests réalisés sont :

  • Streaming UDP avec encodage vidéo Theora d'une vidéo test (Mire)
  • Streaming UDP avec encodage vidéo H264 d'une vidéo test (Mire)
  • Streaming TCP avec encodage vidéo H264 d'une vidéo test (Mire)
  • Streaming RTP/RTCP avec encodage vidéo H264 d'une vidéo test (Mire)
  • Streaming RTSP avec encodage vidéo H264 d'une vidéo test (Mire)
  • Utilisation de la Webcam PS3 EyeToy. 




Préambule


On vérifie que tous les plugins nécessaires à la diffusion de notre vidéo test sont disponibles sur la raspberry pi et, pour cela, on va lancer la commande gst-inspect-1.0.

# gst-inspect-1.0 |grep test

audiotestsrc:  audiotestsrc: Audio test source
videotestsrc:  videotestsrc: Video test source

Il est possible d'inspecter chaque élément et de déterminer les propriétés nécessaires de chaque élément de notre chaîne avec la commande gst-inspect-1.0.
Nous utiliserons la propriété is-live de videotestsrc pour nos tests.
Il est également possible de jouer avec le paramètre pattern pour générer différents types de vidéos test.

# gst-inspect-1.0 videotestsrc
Factory Details:
  Rank                     none (0)
  Long-name                Video test source
  Klass                    Source/Video
  Description              Creates a test video stream
  Author                   David A. Schleef 

Plugin Details:
  Name                     videotestsrc
  Description              Creates a test video stream
  Filename                 /usr/lib/gstreamer-1.0/libgstvideotestsrc.so
  Version                  1.2.0
  License                  LGPL
  Source module            gst-plugins-base
  Source release date      2013-09-24
  Binary package           GStreamer Base Plug-ins source release
  Origin URL               Unknown package origin

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseSrc
                         +----GstPushSrc
                               +----GstVideoTestSrc

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/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, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE }
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]
      video/x-bayer
                 format: { bggr, rggb, grbg, gbrg }
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]


Element Flags:
  no flags set

Element Implementation:
  Has change_state() function: gst_base_src_change_state

Element has no clocking capabilities.
Element has no indexing capabilities.
Element has no URI handling capabilities.

Pads:
  SRC: 'src'
    Implementation:
      Has getrangefunc(): gst_base_src_getrange
      Has custom eventfunc(): gst_base_src_event
      Has custom queryfunc(): gst_base_src_query
      Has custom iterintlinkfunc(): gst_pad_iterate_internal_links_default
    Pad Template: 'src'

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: "videotestsrc0"
  parent              : The parent of the object
                        flags: readable, writable
                        Object of type "GstObject"
  blocksize           : Size in bytes to read per buffer (-1 = default)
                        flags: readable, writable
                        Unsigned Integer. Range: 0 - 4294967295 Default: 4096 
  num-buffers         : Number of buffers to output before sending EOS (-1 = unlimited)
                        flags: readable, writable
                        Integer. Range: -1 - 2147483647 Default: -1 
  typefind            : Run typefind before negotiating
                        flags: readable, writable
                        Boolean. Default: false
  do-timestamp        : Apply current stream time to buffers
                        flags: readable, writable
                        Boolean. Default: false
  pattern             : Type of test pattern to generate
                        flags: readable, writable
                        Enum "GstVideoTestSrcPattern" Default: 0, "smpte"
                           (0): smpte            - SMPTE 100% color bars
                           (1): snow             - Random (television snow)
                           (2): black            - 100% Black
                           (3): white            - 100% White
                           (4): red              - Red
                           (5): green            - Green
                           (6): blue             - Blue
                           (7): checkers-1       - Checkers 1px
                           (8): checkers-2       - Checkers 2px
                           (9): checkers-4       - Checkers 4px
                           (10): checkers-8       - Checkers 8px
                           (11): circular         - Circular
                           (12): blink            - Blink
                           (13): smpte75          - SMPTE 75% color bars
                           (14): zone-plate       - Zone plate
                           (15): gamut            - Gamut checkers
                           (16): chroma-zone-plate - Chroma zone plate
                           (17): solid-color      - Solid color
                           (18): ball             - Moving ball
                           (19): smpte100         - SMPTE 100% color bars
                           (20): bar              - Bar
                           (21): pinwheel         - Pinwheel
                           (22): spokes           - Spokes
  timestamp-offset    : An offset added to timestamps set on buffers (in ns)
                        flags: readable, writable
                        Integer64. Range: -9223372036854775808 - 9223372036854775807 Default: 0 
  is-live             : Whether to act as a live source
                        flags: readable, writable
                        Boolean. Default: false
  k0                  : Zoneplate zero order phase, for generating plain fields or phase offsets
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kx                  : Zoneplate 1st order x phase, for generating constant horizontal frequencies
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  ky                  : Zoneplate 1st order y phase, for generating contant vertical frequencies
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kt                  : Zoneplate 1st order t phase, for generating phase rotation as a function of time
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kxt                 : Zoneplate x*t product phase, normalised to kxy/256 cycles per vertical pixel at width/2 from origin
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kyt                 : Zoneplate y*t product phase
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kxy                 : Zoneplate x*y product phase
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kx2                 : Zoneplate 2nd order x phase, normalised to kx2/256 cycles per horizontal pixel at width/2 from origin
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  ky2                 : Zoneplate 2nd order y phase, normailsed to ky2/256 cycles per vertical pixel at height/2 from origin
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  kt2                 : Zoneplate 2nd order t phase, t*t/256 cycles per picture
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  xoffset             : Zoneplate 2nd order products x offset
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  yoffset             : Zoneplate 2nd order products y offset
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0 
  foreground-color    : Foreground color to use (big-endian ARGB)
                        flags: readable, writable, controllable
                        Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 
  background-color    : Background color to use (big-endian ARGB)
                        flags: readable, writable, controllable
                        Unsigned Integer. Range: 0 - 4294967295 Default: 4278190080 
  horizontal-speed    : Scroll image number of pixels per frame (positive is scroll to the left)
                        flags: readable, writable
                        Integer. Range: -2147483648 - 2147483647 Default: 0

Nous allons utiliser l'encodeur vidéo H264 fourni avec la librairie OpenMAX.

H.264, ou MPEG-4 AVC (Advanced Video Coding), ou MPEG-4 Part 10, est une norme de codage vidéo développée conjointement par l'UIT-T Q.6/SG16 Video Coding Experts Group (VCEG) ainsi que l'ISO/CEI Moving Picture Experts Group (MPEG) et est le produit d'un effort de partenariat connu sous le nom Joint Video Team (JVT). La norme UIT-T H.264 et la norme ISO/CEI MPEG-4 Part 10 (ISO/CEI 14496-10) sont techniquement identiques, et la technologie employée est aussi connue sous le nom AVC, pour Advanced Video Coding. (source wikipedia)

# gst-inspect-1.0 |grep omx

omx:  omxmpeg2videodec: OpenMAX MPEG2 Video Decoder
omx:  omxmpeg4videodec: OpenMAX MPEG4 Video Decoder
omx:  omxh263dec: OpenMAX H.263 Video Decoder
omx:  omxh264dec: OpenMAX H.264 Video Decoder
omx:  omxtheoradec: OpenMAX Theora Video Decoder
omx:  omxvp8dec: OpenMAX VP8 Video Decoder
omx:  omxmjpegdec: OpenMAX MJPEG Video Decoder
omx:  omxvc1dec: OpenMAX WMV Video Decoder
omx:  omxh264enc: OpenMAX H.264 Video Encoder

Nous allons utiliser l'encodeur vidéo Theora.

Theora est un format de compression vidéo ouvert et sans brevets promu par la fondation Xiph.org. C'est un des composants de leur projet de format d'encapsulation Ogg, qui a pour but de créer un ensemble de standards ouverts concernant le traitement de signaux multimédia (son, vidéo). Theora fournit la vidéo. (source wikipedia)

# gst-inspect-1.0 |grep theora

rtp:  rtptheoradepay: RTP Theora depayloader
rtp:  rtptheorapay: RTP Theora payloader
typefindfunctions: video/x-theora: no extensions
theora:  theoradec: Theora video decoder
theora:  theoraenc: Theora video encoder
theora:  theoraparse: Theora video parser
omx:  omxtheoradec: OpenMAX Theora Video Decoder

Debug


Il est possible d'avoir différentes traces de debug supplémentaires de tous les éléments d'une chaîne ou seulement quelques-uns en particulier, grâce à la variable d'environnement GST_DEBUG.

# GST_DEBUG=1
# gst-launch-1.0 ....

Le numéro correspond au niveau de traces de debug désirées.
  • 1 : ERROR - Traces de toutes les erreurs fatales
  • 2 : WARNING - Traces de tous les warning 
  • 3 : FIXME - Traces de tous les FIXME (morceau de code pas complètement implémenté)
  • 4 : INFO - Traces tous les message d'informations
  • 5 : DEBUG - Traces tous les messages de debug
  • 6 : LOG - Traces tous les messages de log
  • 7 : TRACE  - Traces tous les messages
  • 9 : MEMDUMP - Traces tous les messages de memory dump.
Ca peut vite devenir le bordel car si vous tracez tous les messages sur votre console, vous n'allez pas vous y retrouver, donc il est possible de tracer que quelques éléments d'une chaîne. exemple :

# GST_DEBUG="videotestsrc:7, omxh264enc:1"
# gst-launch-1.0 -v videotestsrc is-live=1 ! omxh264enc ! mpegtsmux ! udpsink host=192.168.1.5 port=9999

Sur cet exemple, je ne vais tracer que tous les messages provenant de l'élément videotestsrc et toutes les erreurs provenant de l'élément omxh264enc.
Ce qui va réduire, considérablement, les messages affichés sur la console.


Mire + Encodeur vidéo Theora + streaming UDP



Sur le PC avec GStreamer :

Commande à lancer avant celle sur la raspberry pi :

# gst-launch-1.0 -v udpsrc port=9998 ! oggdemux ! theoradec ! autovideosink sync=false
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock

Sur la raspberry pi :

On peut jouer avec le bitrate (75, 150, 300, ...)
theroaenc : encodeur video
oggmux : conteneur video

Conteneur video : un format de fichier pouvant contenir divers types de données. Les spécifications du format conteneur décrivent la façon dont sont organisées les données à l'intérieur du fichier. Les conteneurs sont beaucoup utilisés dans le domaine du multimédia ; ils peuvent contenir des flux vidéo et/ou audio, en général compressés à l'aide de codecs normalisés. Des conteneurs plus avancés permettent également de stocker des sous-titres, des éléments de chapitrage, ainsi que d'autres informations sur le média (appelées métadonnées ou tags). (source wikipedia)

# gst-launch-1.0 -v videotestsrc is-live=1 ! theoraenc bitrate=300 ! video/x-theora, framerate=15/1 ! oggmux ! udpsink host=192.168.1.5 port=9998

La mire apparaît sur le PC avec un saccadement de la vidéo due a une charge d'encodage trop importante sur la raspberry pi :


la charge CPU de la raspberry pi nous montre que toutes les ressources du processeur sont utilisées pour l'encodage vidéo et l'envoie des trames UDP.

Mem: 33192K used, 378276K free, 0K shrd, 1412K buff, 18952K cached
CPU:  99% usr   0% sys   0% nic   0% idle   0% io   0% irq   0% sirq
Load average: 1.16 0.54 0.23 2/52 132
PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
122   111 root     S    37176   9%  99% gst-launch-1.0 -v videotestsrc is-live=1 ! theoraenc bitrate=300 ! video/x-theora, framerate=15/1 ! oggmux ! udpsink host=192.168.1.5 port=9998
132   127 root     R     2348   1%   0% top
126    88 root     S     2144   1%   0% /usr/sbin/dropbear
 17     2 root     SW       0   0%   0% [kworker/0:1]
 40     2 root     SW<      0   0%   0% [kworker/0:1H]
103     1 root     S    20468   5%   0% /usr/sbin/vcfiled
111   110 root     S     2348   1%   0% -sh
127   126 root     S     2348   1%   0% -sh
108     1 root     S     2268   1%   0% /sbin/getty -L ttyAMA0 115200 vt100

Il est également possible d'afficher la mire sur un lecteur vidéo comme VLC :

Voici le type d'URL à utiliser pour lire le flux vidéo :


et vous obtenez le même résultat qu'avec GStreamer.



Mire + Encodeur vidéo H264 + streaming UDP



Pour exploiter au mieux les capacités de la raspberry pi, on va encoder la vidéo test avec le GPU de la raspberry pi et ainsi libérer de la charge CPU pour d'autres traitements.

Sur le PC avec GStreamer :

Commande à lancer avant celle sur la raspberry pi :

# gst-launch-1.0 -v udpsrc port=9999 ! decodebin ! autovideosink sync=false

Sur la raspbeery pi :

# gst-launch-1.0 -v videotestsrc is-live=1 ! omxh264enc ! mpegtsmux ! udpsink host=192.168.1.5 port=9999

La mire apparaît sur le PC sans aucun saccadement maintenant :


La charge CPU est maintenant plus acceptable :

Mem: 28188K used, 383280K free, 0K shrd, 3852K buff, 12616K cached
CPU:  34% usr   1% sys   0% nic  63% idle   0% io   0% irq   0% sirq
Load average: 0.72 0.42 0.18 1/61 201
PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
184   107 root     S      99m  25%  35% gst-launch-1.0 -v videotestsrc is-live=1 ! omxh264enc ! mpegtsmux ! udpsink host=192.168.1.5 port=9999
 30     2 root     SW<      0   0%   1% [VCHIQ-0]
201   197 root     R     2348   1%   0% top
196    84 root     S     2144   1%   0% /usr/sbin/dropbear
  7     2 root     SW       0   0%   0% [rcu_preempt]
100     1 root     S    20468   5%   0% /usr/sbin/vcfiled
107   106 root     S     2348   1%   0% -sh
197   196 root     S     2348   1%   0% -sh
105     1 root     S     2268   1%   0% /sbin/getty -L ttyAMA0 115200 vt100
  1     0 root     S     2264   1%   0% init


Mire + Encodeur vidéo H264 + streaming TCP



Sur le PC avec GStreamer :

Le PC va servir de serveur TCP donc il sera nécessaire de le lancer avant le client TCP de la raspberry pi.

# gst-launch-1.0 -v tcpserversrc host=192.168.1.5 port=9876 ! decodebin ! autovideosink sync=false

Sur la raspberry pi :

La raspberry pi va être configurée comme client TCP.

# gst-launch-1.0 -v videotestsrc is-live=1 ! omxh264enc ! mpegtsmux ! tcpclientsink host=192.168.1.5 port=9876

La mire apparaît sur le PC :



La charge CPU est sensiblement la même qu'en UDP.

Mem: 28172K used, 383296K free, 0K shrd, 3864K buff, 12704K cached
CPU:  36% usr   2% sys   0% nic  60% idle   0% io   0% irq   0% sirq
Load average: 0.91 0.68 0.35 1/59 262
PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
251   107 root     S    92996  23%  36% gst-launch-1.0 -v videotestsrc is-live=1 ! omxh264enc ! mpegtsmux ! tcpclientsink host=192.168.1.5 port=9876
 30     2 root     SW<      0   0%   1% [VCHIQ-0]
262   197 root     R     2348   1%   0% top
196    84 root     S     2144   1%   0% /usr/sbin/dropbear
  7     2 root     SW       0   0%   0% [rcu_preempt]
  3     2 root     SW       0   0%   0% [ksoftirqd/0]
100     1 root     S    20468   5%   0% /usr/sbin/vcfiled
107   106 root     S     2348   1%   0% -sh
197   196 root     S     2348   1%   0% -sh
105     1 root     S     2268   1%   0% /sbin/getty -L ttyAMA0 115200 vt100
  1     0 root     S     2264   1%   0% init


Mire + Encodeur vidéo H264 + streaming RTP/RTCP



RTP (Real-Time Transport Protocol) et RTCP (Real-Time Transport Control Protocol) sont des protocoles de transport de données ayant la particularité d'avoir des propriétés temps-réel.
Le but du RTP est de fournir au client connecté à celui-ci, une séquence de paquets permettant de reconstituer l'informations originelle (audio ou vidéo) même si les paquets réseaux sont arrivés dans le mauvais ordre.
Le but du RTCP est de fournir des informations de qualité de service (QoS), qualité de transmission, pertes de paquets etc ... 


Pour lancer une diffusion de notre flux vidéo test avec le protocole RTP/RTCP, nous allons avoir besoin de récupérer le champs caps (long : capabilities) du serveur, décrivant le type de media streamé, et le fournir au client dans sa chaîne.

Sur la raspberry pi :

# gst-launch-1.0 -v videotestsrc is-live=1 ! 'video/x-raw, format=I420, width=320, height=240, framerate=(fraction)15/1' ! omxh264enc ! rtph264pay name=pay0 pt=96 config-interval=2 ! udpsink host=192.168.1.5 port=5000

Au niveau des traces sur la console, nous avons quelque chose comme :

[...]
/GstPipeline:pipeline0/GstRtpH264Pay:pay0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQKD9APEiagA\=\,KO4CXLAA", payload=(int)96, ssrc=(uint)401291925, timestamp-offset=(uint)1224952945, seqnum-offset=(uint)25331
/GstPipeline:pipeline0/GstUDPSink:udpsink0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQKD9APEiagA\=\,KO4CXLAA", payload=(int)96, ssrc=(uint)401291925, timestamp-offset=(uint)1224952945, seqnum-offset=(uint)25331
[...]

Et le caps à récupérer est la dernière ligne : caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQKD9APEiagA\=\,KO4CXLAA", payload=(int)96, ssrc=(uint)401291925, timestamp-offset=(uint)1224952945, seqnum-offset=(uint)25331

Sur le PC avec GStreamer :

gst-launch-1.0 -v udpsrc port=5000 caps='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQKD9APEiagA\=\,KO4CXLAA", payload=(int)96, ssrc=(uint)401291925, timestamp-offset=(uint)1224952945, seqnum-offset=(uint)25331' ! rtph264depay ! decodebin ! autovideosink sync=false

Sur le PC avec VLC :

Pour VLC, pour la réception d'un flux RTP, nous créons un fichier session SDP, par exemple : test.sdp.

v=0
o=- 1188340656180883 1 IN IP4 127.0.0.1
s=Session streamed by GStreamer
i=server.sh
t=0 0
a=tool:GStreamer
a=type:broadcast
m=video 5000 RTP/AVP 96
c=IN IP4 127.0.0.1
a=rtpmap:96 H264/90000

et il suffit simplement d'ouvrir le fichier SDP avec VLC pour voir apparaître la mire.


Mire + Encodeur vidéo H264 + Serveur RTSP



Le package gst-rtsp-server fournit quelques exemples et notamment un (test-readme.c) qui nous servira de modèle pour ce petit serveur test, donc a partir de ce fichier source, nous allons créer un petit projet (fichier source et makefile).

Le Makefile :

BUILDROOT_PATH = VOTRE CHEMIN VERS BUILDROOT
SYSROOT_PATH = $(BUILDROOT_PATH)/output/host/usr/arm-buildroot-linux-gnueabi/sysroot
CC = $(BUILDROOT_PATH)/output/host/usr/bin/arm-bcm2708-linux-gnueabi-gcc
CFLAGS = -I$(SYSROOT_PATH)/usr/include -I$(SYSROOT_PATH)/usr/include/gstreamer-1.0 -I$(SYSROOT_PATH)/usr/include/glib-2.0 -
I$(SYSROOT_PATH)/usr/lib/glib-2.0/include -I$(BUILDROOT_PATH)/output/build/gst1-rtsp-server-master -W -Wall
LDFLAGS = -L$(SYSROOT_PATH)/usr/lib -lgio-2.0 -lglib-2.0 -lgobject-2.0 -lgstreamer-1.0 -lgstrtspserver-1.0
EXEC = test-readme
OBJS = test-readme.o

all: $(EXEC)

$(EXEC):$(OBJS)
	@$(CC) -o $(EXEC) $^ $(LDFLAGS)

%.o:%.c
	@echo [CC] $^
	@$(CC) -o $@ -c $^ $(CFLAGS)

clean:
	@echo [CLEAN]
	@rm *.o $(EXEC) -f

Voici le fichier source test-readme.c modifié pour y intégrer l'encodeur openMAX, on remarque que la fonction gst_rtsp_media_factory_set_launch() du serveur va utiliser une chaîne d'éléments comme avec la commande gst-launch-1.0.

int
main (int argc, char *argv[])
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;

  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);

  /* create a server instance */
  server = gst_rtsp_server_new ();

  /* Configure server to accept connections on the given address */
  //gst_rtsp_server_set_address(server, "127.0.0.1");

  /* get the mount points for this server, every server has a default object
   * that be used to map uri mount points to media factories */
  mounts = gst_rtsp_server_get_mount_points (server);

  /* make a media factory for a test stream. The default media factory can use
   * gst-launch syntax to create pipelines. 
   * any launch line works as long as it contains elements named pay%d. 
   * Each element with pay%d names will be a stream */
  factory = gst_rtsp_media_factory_new ();
  gst_rtsp_media_factory_set_launch (factory, "( videotestsrc is-live=1 ! video/x-raw, format=I420, width=320, height=240, framerate=(fraction)15/1 ! omxh264enc ! video/x-h264, profile=(string)high, level=(string)4 ! rtph264pay name=pay0 pt=96 config-interval=2 )");
  
  gst_rtsp_media_factory_set_shared (factory, TRUE);

  /* attach the test factory to the /test url */
  gst_rtsp_mount_points_add_factory (mounts, "/test", factory);

  /* don't need the ref to the mapper anymore */
  g_object_unref (mounts);

  /* attach the server to the default maincontext */
  gst_rtsp_server_attach (server, NULL);

  /* start serving */
  g_print ("stream ready at rtsp://%s:%s/test\n", 
           gst_rtsp_server_get_address(server),
           gst_rtsp_server_get_service(server));
  g_main_loop_run (loop);

  return 0;
}

On compile notre petit projet :

# make
[CC] test-readme.c

puis on le transfert sur la raspberry pi :

# scp -P 22 test-readme root@192.168.1.10:

On utiliser les traces de debug sur la console :

# export GST_DEBUG="rtsp*:7"
# ./test-readme
0:00:00.196330000   121   0xe98e00 DEBUG        rtspmountpoints rtsp-mount-points.c:131:gst_rtsp_mount_points_init: created
0:00:00.200053000   121   0xe98e00 INFO         rtspmountpoints rtsp-mount-points.c:326:gst_rtsp_mount_points_add_factory: adding media factory 0xe9f430 for path /test
0:00:00.201302000   121   0xe98e00 DEBUG             rtspserver rtsp-server.c:803:gst_rtsp_server_create_socket: getting address info of 0.0.0.0/8554
0:00:00.210187000   121   0xe98e00 DEBUG             rtspserver rtsp-server.c:887:gst_rtsp_server_create_socket: opened sending server socket
0:00:00.211642000   121   0xe98e00 DEBUG             rtspserver rtsp-server.c:915:gst_rtsp_server_create_socket: listening on server socket 0xea1808 with queue of 5
stream ready at rtsp://0.0.0.0:8554/test

Après le lancement du serveur, on se rend compte que lorsqu'aucun client n'est connecté, la raspberry pi n'encode rien et n'envoie aucune donnée.

Mem: 28168K used, 383300K free, 0K shrd, 6036K buff, 11636K cached
CPU:   0% usr   0% sys   0% nic  99% idle   0% io   0% irq   0% sirq
Load average: 0.03 0.03 0.04 1/50 128
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
  128   123 root     R     2348   1%   0% top
  122    84 root     S     2144   1%   0% /usr/sbin/dropbear
   39     2 root     SW       0   0%   0% [mmcqd/0]
  100     1 root     S    20468   5%   0% /usr/sbin/vcfiled
  121   107 root     S     7632   2%   0% ./test-readme
  107   106 root     S     2348   1%   0% -sh
  123   122 root     S     2348   1%   0% -sh
  105     1 root     S     2268   1%   0% /sbin/getty -L ttyAMA0 115200 vt100
    1     0 root     S     2264   1%   0% init

Client RTSP sur PC avec VLC :

Ouvrir le flux réseau avec l'adresse : rtsp://192.168.1.10:8554/test


Ensuite la mire apparaît.


Au niveau des traces du serveur, on voit apparaître les différentes opérations réalisées avant la diffusion de la mire.



Utilisation de la Webcam PS3 EyeToy




La webcam PS3 EyeToy est basé sur un capteur vidéo omnivision OV534, donc il va falloir chargé le bon driver ainsi que ses dépendances.

# modprobe gspca_ov534
# lsmod
Module                  Size  Used by    Not tainted
gspca_ov534             9162  0 
gspca_main             20125  1 gspca_ov534
videodev               90333  2 gspca_ov534,gspca_main
media                   9512  1 videodev

Pour l'utiliser avec GStreamer, il suffit de remplacer :

videotestsrc is-live=1

par :

v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, format=(string)I420, width=640, height=480, framerate=(fraction)30/1

Amusez-vous bien !!!

3 commentaires:

  1. on comprend rien
    manque des codes sources

    RépondreSupprimer
  2. Le site force IE à utiliser le mode IE7. Ce qui, étrangement, empêche certains blocs de code de s'afficher.

    En attendant que le site soit mis à jour, il est possible de contourner le problème en appuyant sur F12 et en passant en mode de document "Edge" (dernière version).

    RépondreSupprimer
  3. À l'attention du webmaster :
    Sous IE 9 et +, votre site fonctionne parfaitement bien.
    Vous pouvez donc retirer la balise META suivante de votre site pour résoudre les problème cités ci-dessus :
    http-equiv="X-UA-Compatible" content="IE=EmulateIE7"

    RépondreSupprimer