Streaming vidéo HD avec Gstreamer

Publié le 16 février 2010 par Nicolargo

Nous allons dans ce billet essayer d’optimiser le streaming d’un flux HD sur un réseau local (LAN de 100 Mbps) en utilisant le framework GStreamer.

Environnement des tests

Deux PC Ubuntu connectés sur un même switch (100 Mbps full-duplex).

  • PC serveur: Intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz / 2 Go RAM
  • PC client: Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz / 1 Go RAM

GStreamer version 0.10.25.

Vidéo source: Big Buck Bunny 480p

Tests avec le codec X.264

Ligne de commande sur la machine générant le streaming (serveur):
serveur> gst-launch -v \
        filesrc location="../Vidéos/big_buck_bunny_480p_stereo.ogg" \
        ! queue ! decodebin \
        ! queue ! videoscale method=1 ! video/x-raw-yuv,width=854,height=480 \
        ! queue ! videorate ! video/x-raw-yuv,framerate=\(fraction\)24/1 \
        ! queue ! x264enc byte-stream=true bitrate=2000 bframes=4 ref=4 me=hex subme=4 weightb=true threads=0 \
        ! queue ! rtph264pay \
        ! queue ! udpsink port=5000 host=192.168.29.150 sync=false async=false

Ligne de commande sur la machine recevant le streaming (client):
client> gst-launch -v udpsrc caps="application/x-rtp, media=\(string\)video, clock-rate=\(int\)90000, encoding-name=\(string\)H264, payload=\(int\)96" port=5000 \
 ! queue ! rtph264depay \
 ! queue ! ffdec_h264 ! xvimagesink

Résultat:
Visuel: vidéo saccadé (environ 2 img/sec)
Bande passante mesurée: entre 2 et 3 Mbps
Resource serveur: %CPU=135 / %MEM=5
Resource client: %CPU=10 / %MEM=2

On ajoute un buffer juste avant le depay et le décodage (au niveau du client):

client> gst-launch -v udpsrc caps="application/x-rtp, media=\(string\)video, clock-rate=\(int\)90000, encoding-name=\(string\)H264, payload=\(int\)96" port=5000 \
        ! queue ! gstrtpjitterbuffer latency=3000 \
        ! queue ! rtph264depay \
        ! queue ! ffdec_h264 ! xvimagesink

Résultat:
Visuel: vidéo beaucoup plus fluide mais variation de la gigue (accéleration de la video par moment). On a par contre un décalage de 3 secondes, donc inutilisable pour des flux lives.
Bande passante mesurée: entre 2 et 3 Mbps
Resource serveur: %CPU=140 / %MEM=6
Resource client: %CPU=14 / %MEM=2

On modifie ensuite les paramètres d’encodage X.264 (au niveau du serveur):

serveur> gst-launch -v --gst-debug-level=2 \
        filesrc location="../Vidéos/big_buck_bunny_480p_stereo.ogg" \
        ! queue ! decodebin \
        ! queue ! videoscale method=1 ! video/x-raw-yuv,width=720,height=480 \
        ! queue ! videorate ! video/x-raw-yuv,framerate=\(fraction\)24/1 \
        ! queue ! x264enc vbv-buf-capacity=3000 byte-stream=true bitrate=900 subme=4 ref=2 bframes=1 b-pyramid=true weightb=true \
        ! queue ! rtph264pay \
        ! queue ! udpsink port=5000 host=192.168.29.150 sync=false async=false

Résultat:
Visuel: Presque plus de sacade ni de variation de gigue. On a par contre un décalage de 3 secondes, donc inutilisable pour des flux lives.
Bande passante mesurée: entre 2 et 3 Mbps
Resource serveur: %CPU=120 / %MEM=4
Resource client: %CPU=10 / %MEM=2