主要包括三个命令行工具的使用:gst-discover,gst-inspect,gst-launch
gst-discoverer-1.0
查看某一文件的基本属性
gst-discoverer-1.0 those_years.mp4
gst-inspect-1.0
查看目前gstreamer所有可用于构建pipeline的element
gst-inspect-1.0
查看某一element的详细信息,包括properties和caps
gst-inspect-1.0 v4l2src
查看某一so中包含的plugins
gst-inspect-1.0 /usr/local/lib/gstreamer-1.0/libgstaudiomixer.so
gst-launch-1.0
一些常见的插件:
videoconvert 颜色空间转换,应该是yuv和rgb等格式的互转
videoscale 对 raw video 做尺寸缩放
rtph264pay 将编码了的x264 packets转换得到rtp数据包
decodebin 集成了demux+(a/v)decode 功能的超级element
uridecodebin 集成了 filesrc/souphttpsrc/.. + decodebin 功能的超级element
h264parse (看起来对于解包时候很有用,可以省去很多额外的参数让其自动解析,输出就是串行的 h264-packets)
queue 队列,gstreamer创建多线程的一种方式,sink pad仅仅将数据放入队列,另外一个线程从队列中取出数据,并传递到下一个Element
一些常见的命令行例子:
//测试,videotestsrc 和 audiotestsrc 可以输出未经编码的 video/audio frame
gst-launch-1.0 videotestsrc pattern=0 ! xvimagesink
gst-launch-1.0 audiotestsrc wave=6 ! audioconvert ! audioresample ! autoaudiosink
//添加了caps filter的,gst-inspect videotestsrc可以查看videotestsrc的caps,这里给出其中的一个子集
gst-launch-1.0 videotestsrc ! 'video/x-raw,format=(string)YV12;video/x-raw,format=(string)BGR' ! xvimagesink
//直接使用playbin无脑完成播放操作
gst-launch-1.0 playbin uri=file:///home/fang/Desktop/Titanic.ts
//decodebin看起来自带了demux的功能,输出为audio/video frame
//name可以用来多分支,还可以用name指定pad名,"decoder." 其实是将pad名缺省了
gst-launch-1.0 filesrc location=/home/fang/Desktop/Titanic.ts ! decodebin name=decoder \
decoder. ! queue ! audioconvert ! audioresample ! autoaudiosink \
decoder. ! videoconvert ! xvimagesink
gst-launch-1.0 filesrc location=/home/fang/Desktop/Titanic.ts ! decodebin name=decoder \
decoder. ! queue ! audioconvert ! audioresample ! autoaudiosink \
decoder. ! queue ! videoconvert ! xvimagesink //这里多一个queue,貌似影响不大
//将 videotestsrc 产生的raw video data编码为h264数据后,封装为rtp数据通过udp传输出去
gst-launch-1.0 -ve videotestsrc \
! videoconvert \
! x264enc noise-reduction=10000 tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true \
! rtph264pay pt=96 \
! udpsink host=localhost port=5000
//在接受端接受上面的数据
gst-launch-1.0 -ve udpsrc port=5000 ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 \
! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! ximagesink sync=false
//格式转换,将ts文件中video以x264重新编码,audio以aac格式重新编码,得到test.avi作为输出
gst-launch-1.0 -v uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \
decoder. ! queue2 ! videoconvert ! x264enc ! avimux name=mux mux. ! filesink location="test.avi" \
decoder. ! queue2 ! audioconvert ! faac ! mux.
//和上面一样的,只是写法更好一些
gst-launch-1.0 -v uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \
decoder. ! queue2 ! videoconvert ! x264enc ! avimux name=mux \
decoder. ! queue2 ! audioconvert ! faac ! mux. \
mux. ! filesink location="test.avi"
//一边播放声音,一边可视化audio波形(验证可用)
gst-launch-1.0 -v audiotestsrc freq=215.0 ! tee name=tee0 \
tee0. ! queue ! audioconvert ! audioresample ! autoaudiosink \
tee0. ! queue ! wavescope shader=0 style=1 ! videoconvert ! autovideosink
//边做格式转换边播放(理论上是没问题的,但不知为何没有test.avi输出??? tee插件有些问题??)
#gst-launch-1.0 -v uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \
#decoder. ! tee name=tee0 \
#tee0. ! queue2 ! videoconvert ! videoscale ! ximagesink \
#tee0. ! queue2 ! videoconvert ! x264enc ! avimux name=mux \
#mux. ! filesink location=”test.avi” \
#decoder. ! tee name=tee1 \
#tee1. ! queue2 ! audioconvert ! autoaudiosink \
#tee1. ! queue2 ! audioconvert ! faac ! mux.
//解析范式,能解析出多少就多少,例如下面 rtpbin name=rtpbin latency=100 就是一个解析范式,并没有立刻使用
//而是作为 uridecodebin 的其中一个tee的输出(rtpbin.send_rtp_sink_0)使用 。同时 rtpbin.send_rtp_src_0 ! …
//作为一个新起的范式被解析。下面的命令未经过验证
#gst-launch-1.0 -v rtpbin name=rtpbin latency=100 uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \
#decoder. ! tee name=tee0 \
#tee0. ! queue2 ! videoconvert ! videoscale ! ximagesink \
#tee0. ! queue2 ! videoconvert ! x264enc ! rtph264pay pt=96 ! queue2 ! rtpbin.send_rtp_sink_0 rtpbin.send_rtp_src_0 ! \
# queue2 ! udpsink host=192.168.1.1 port=5000 async=false \
#decoder. ! tee name=tee1 \
#tee1. ! queue2 ! audioconvert ! autoaudiosink \
#tee1. ! queue2 ! audioconvert ! faac ! rtpmp4apay pt=96 ! queue2 ! rtpbin.send_rtp_sink_1 rtpbin.send_rtp_src_1 ! \
# queue2 ! udpsink host=192.168.1.1 port=5003 async=false
//和上面一样的,只是写法更好一些
gst-launch-1.0 -v \
rtpbin name=rtpbin latency=100 \
uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \
decoder. ! tee name=tee0 \
tee0. ! queue2 ! videoconvert ! videoscale ! ximagesink \
tee0. ! queue2 ! videoconvert ! x264enc ! rtph264pay pt=96 ! queue2 ! rtpbin.send_rtp_sink_0 \
decoder. ! tee name=tee1 \
tee1. ! queue2 ! audioconvert ! autoaudiosink \
tee1. ! queue2 ! audioconvert ! faac ! rtpmp4apay pt=96 ! queue2 ! rtpbin.send_rtp_sink_1 \
rtpbin.send_rtp_src_0 ! queue2 ! udpsink host=192.168.1.1 port=5000 async=false \
rtpbin.send_rtp_src_1 ! queue2 ! udpsink host=192.168.1.1 port=5003 async=false
//接收端?未经过验证
#gst-launch-1.0 -v rtpbin name=rtpbin latency=100 \
#udpsrc caps=”application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,sprop-parameter-sets=(string)\”Z0LAH9kAtD2wEQAAAwABdzWUAA8YMkgA\\,aMuMsg\\=\\=\”,ssrc=(uint)2094326868,payload=(int)96,clock-base=(uint)2855623946,seqnum-base=(uint)57709″ \
#port=5000 ! queue ! rtpbin.recv_rtp_sink_0 rtpbin. ! rtph264depay ! tee name=teevideo \
#teevideo. ! avdec_h264 ! videoscale ! videoconvert ! autovideosink \
#teevideo. ! queue ! “video/x-h264,width=720,height=480,framerate=(fraction)25/1” ! avdec_h264 ! videoconvert ! avenc_mjpeg ! avimux name=mux \
#mux. ! filesink location=”test.avi” \
#\
#udpsrc caps=”application/x-rtp,media=(string)audio,clock-rate=(int)44100,encoding-name=(string)MP4A-LATM,cpresent=(string)0,config=(string)40002420,ssrc=(uint)277283185,payload=(int)96,clock-base=(uint)3973143737,seqnum-base=(uint)63683″ \
#port=5003 ! queue ! rtpbin.recv_rtp_sink_1 rtpbin. ! rtpmp4adepay ! tee name=teeaudio \
#teeaudio. ! queue ! faad ! audioconvert ! autoaudiosink \
#teeaudio. ! queue ! aacparse ! mux.
关于摄像头:
//查看摄像头支持的 formats:apt-get install v4l-utils, v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.033s (30.000 fps)
//使用gstreamer实时显示摄像头数据,
gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 ! videoconvert ! autovideosink
gst-launch-1.0 v4l2src ! video/x-raw,framerate=30/1 ! videoconvert ! autovideosink
gst-launch-1.0 v4l2src ! 'video/x-raw,format=(string)YUY2,framerate=30/1' ! videoconvert ! autovideosink //caps filter限制越多,越容易出现 streaming stopped, reason not-negotiated (-4)
gst-launch-1.0 v4l2src ! 'video/x-raw,format=(string)YUY2,framerate=30/1' ! videoconvert ! videoscale ! 'video/x-raw,width=1280,height=960' ! autovideosink
//录制摄像头数据得到 out.264,可以使用ffplay正常播放
gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 ! videoconvert ! x264enc ! filesink location='./out.h264'
//将摄像头数据经过x264编码后,封装为ts包,通过 udpsink 发送到127.0.0.1:5000
gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 \
! videoconvert \
! x264enc noise-reduction=10000 tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true \
! mpegtsmux \
! udpsink host=localhost port=5000
//接收端显示从 udpsrc 拿到的数据(经过验证可以正常播放)
gst-launch-1.0 -ve udpsrc port=5000 ! tsparse ! tsdemux ! h264parse ! avdec_h264 ! videoconvert ! ximagesink sync=false
//同上,只是没有经过 mpegtsmux 变为ts包,而是打包成rtp数据
gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 \
! videoconvert \
! x264enc noise-reduction=10000 tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true \
! rtph264pay pt=96 \
! udpsink host=localhost port=5000
//接收端显示从 udpsrc 拿到的数据(经过验证可以正常播放)。因为没有parse元素,所以需要指定'payload...'等很多参数
gst-launch-1.0 -ve udpsrc port=5000 ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 \
! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! ximagesink sync=false
生成pipeline构件图
以上使用的命令都可以在应用程序中通过 gst_parse_launch()这个api完成。 关于如何生成pipeline构件图,可以参看
https://blog.csdn.net/u013554213/article/details/98078955.
总结一下就是:
sudo apt-get install graphviz
export GST_DEBUG_DUMP_DOT_DIR=/home/fang/gstreamer/gst_pipeline_pngs
gst-launch-1.0 .....
dot -Tpng /home/fang/gstreamer/gst_pipeline_pngs/xxx.PLAYING_PAUSED.dot >pipeline.png
至于在code中生成pipeline图,zx_gst_player是将 GST_DEBUG_BIN_TO_DOT_FILE(xxx) 放在了 change_state函数ready_to_pause & paused_to_playing 中。运行时 GST_DEBUG_DUMP_DOT_DIR=/data/ zx_gst_player -p 0
https://gstreamer.freedesktop.org/dev/
https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html?gi-language=c
https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/rtp?h=0.10
http://orangeamoy.com/2019/06/28/GStreamerAndDeepStream/
https://recomm.cnblogs.com/blogpost/9198471
https://www.cnblogs.com/dong1/p/10423743.html
https://www.cnblogs.com/huty/p/8517326.html
https://blog.csdn.net/u010312436/article/details/53668083