Streaming vidéo SD avec Gstreamer
Nous allons dans ce billet essayer d'optimiser le streaming d'un flux SD 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