gstreamer
gstreamer
- 概述
GStreamer是一个创建流媒体应用程序的框架。其基本设计思想来自于俄勒冈(Oregon)研究生学院有关视频管道的创意, 同时也借鉴了DirectShow的设计思想。 - 设计原则
- 结构清晰,功能强大
- 面向对象的编程思想
- 灵活的可扩展功能
- 高性能
- 核心库与插件分离
-
gstreamer 架构
核心:与媒体无关
glib 交叉编译
export CC=arm-hisiv400-linux-gcc
- zlib 交叉编译
cd zlib-1.2.11
./configure --prefix=./output --enable-shared
make
make install
- libffi 交叉编译
cd libffi-3.2
./configure --prefix=./output --host=arm-hisiv400-linux
make
make install
- gettext 交叉编译
./configure --prefix=./output --enable-shared --host=arm-hisiv400-linux
make
make install
- glib 交叉编译
cd glib-2.56.0
./configure --host=arm-hisiv400-linux --prefix=./output \
PKG_CONFIG_PATH=./output/lib/pkgconfig \
glib_cv_stack_grows=no \
glib_cv_uscore=no \
ac_cv_func_posix_getpwuid_r=yes \
ac_cv_func_posix_getgrgid_r=yes \
--with-pcre=internal \
--enable-libmount=no \
make
make install
gstreamer 交叉编译
- orc 交叉编译
cd orc-0.4.28
./configure --prefix=./output --host=arm-hisiv400-linux
make
make install
- x264 交叉编译
cd x264
./configure --prefix=./output --enable-shared --host=arm-hisiv400-linux --disable-asm \
--cross-prefix=arm-hisiv400-linux-
make
make install
- libxml2 交叉编译
cd libxml2-2.9.8
./configure --prefix=./output --enable-shared \
--host=arm-hisiv400-linux\
CROSS_COMPILE=arm-hisiv400-linux- \
--with-python=no
make && make install
- openssl 交叉编译
cd openssl-1.1.0h
./config --prefix=./output shared no-asm
sed -i "s/-m64//g" ./Makefile
make && make install
- gstreamer-1.14.0 交叉编译
cd gstreamer-1.14.0
./configure --prefix=./output --host=arm-hisiv400-linux\
LDFLAGS="-Wl,--unresolved-symbols=ignore-in-shared-libs" \
PKG_CONFIG_PATH=./output/lib/pkgconfig \
GIO_LIBS="-L./output/lib -lgio-2.0 -lgobject-2.0 -lglib-2.0" \
GLIB_LIBS="-L./output/lib -lglib-2.0 -lgobject-2.0 -lgthread-2.0 -lgmodule-2.0" \
--disable-loadsave \
--disable-gtk-doc \
ac_cv_func_register_printf_function=no \
--disable-tests \
--disable-valgrind \
make && make install
- gst-plugins-base-1.14.0 交叉编译
cd gst-plugins-base-1.14.0
./configure --prefix=./output --host=arm-hisiv400-linux
make && make install
- gst-plugins-good-1.14.0 交叉编译
cd gst-plugins-good-1.14.0
./configure --prefix=./output --host=arm-hisiv400-linux
make && make install
- gst-plugins-bad-1.14.0 交叉编译
cd gst-plugins-bad-1.14.0
./configure --prefix=./output --host=arm-hisiv400-linux --disable-dvb
make && make install
- gst-plugins-ugly-1.14.0 交叉编译
cd gst-plugins-ugly-1.14.0
./configure --prefix=./output --host=arm-hisiv400-linux \
--with-x264-libraries=./output/lib/libx264.so
make && make install
- gst-rtsp-server-1.14.0 交叉编译
cd gst-rtsp-server-1.14.0
./configure --prefix=./output --host=arm-hisiv400-linux
make && make install
gstreamer 基本概念
- 元件(element)
Elements 是组成管道的最基本的构件。
可以将若干个元件(Elements)连接在一起,从而创建一个管道(pipeline)来完成一个特殊的任务,例如,媒体播放或者录像。
Elements 根据功能分类:
- Source elements
- Sink elements
-
Filter elements
如下图:
通过一个fakesrc工厂对象来创建一个名叫source的元件:
GstElement *element = gst_element_factory_make ("fakesrc", "source");
-
箱柜(bin) 和管道(Pipeline)
箱柜(Bins)是一个可以装载元件(element)的容器。管道(pipelines)是箱柜(Bins)的一个特殊的子类型,管道(pipelines)可以操作包含在它自身内部的所有元件(element)。
如下图:
#include <gst/gst.h>
int main (int argc,
char *argv[])
{
GstElement *pipeline;
GstElement *source, *filter, *sink;
/* init */
gst_init (&argc, &argv);
/* create pipeline */
pipeline = gst_pipeline_new ("my-pipeline");
/* create elements */
source = gst_element_factory_make ("fakesrc", "source");
filter = gst_element_factory_make ("identity", "filter");
sink = gst_element_factory_make ("fakesink", "sink");
/* must add elements to pipeline before linking them */
gst_bin_add_many (GST_BIN (pipeline), source, filter, sink, NULL);
/* link */
if (!gst_element_link_many (source, filter, sink, NULL)) {
g_warning ("Failed to link elements!");
}
[..]
}
- 衬垫(Pad)
衬垫(Pads)相当于一个元件的接口,各个元件(element)通过这个接口进行连接,这样数据流就可以在这些元件中进行传输。
Pads 分类:
永久型(always)
随机型(sometimes)
请求型 (on request)
如下:filsrc 衬垫类型为永久型
./gst-inspect-1.0 filsrc
Pad Templates:
SRC template: 'src'
Availability: Always
Capabilities:
ANY
- 功能(Cap)
Caps描述了能够通过衬垫或当前通过衬垫的数据流格式。
通过 gst-inspect-1.0 命令可以查看元件所支持的媒体类型。
如:
./gst-inspect-1.0 rtph264depay
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
application/x-rtp
media: video
clock-rate: 90000
encoding-name: H264
SRC template: 'src'
Availability: Always
Capabilities:
video/x-h264
stream-format: avc
alignment: au
video/x-h264
stream-format: byte-stream
alignment: { nal, au }
- 总线(Bus)
每一个管道默认包含一个总线,应用程序不需要再创建总线。应用程序在总线上设置一个消息处理器。当主循环运行的时候,总线将会轮询这个消息处理器是否有新的消息,当消息被采集到后,总线将呼叫相应的回调函数来完成任务。
gint main (gint argc,
gchar *argv[])
{
GstElement *pipeline;
GstBus *bus;
/* init */
gst_init (&argc, &argv);
/* create pipeline, add handler */
pipeline = gst_pipeline_new ("my_pipeline");
/* adds a watch for new message on our pipeline's message bus to
* the default GLib main context, which is the main context that our
* GLib main loop is attached to below
*/
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, my_bus_callback, NULL);
gst_object_unref (bus);
[..]
- 缓冲区(Buffer)
缓冲区包含了创建的管道里的数据流。通常一个源元件会创建一个新的缓冲区,同时元件还将会把缓冲区的数据传递给下一个元件。当使用GStreamer底层构造来创建一个媒体管道的时候,不需要自己来处理缓冲区,元件将会自动处理这些缓冲区。
一个缓冲区主要由以下一个组成:
- 指向某块内存的指针
- 内存的大小
- 缓冲区的时间戳
- 一个引用计数,指出了缓冲区所使用的元件数。没有元件可引用的时候,这个引用将用于销毁缓冲区
- 事件(Events)
事件包括管道里的控制信息,如寻找信息和流的终止信号。
gstreamer 基本命令
播放本地文件:
gst-launch-1.0 playbin uri=file:/home/duxj/testvideo/sintel.ts
播放同时录制视频
gst-launch-1.0 rtspsrc location =rtsp://127.0.0.1:8554/test ! rtph264depay ! mpegtsmux ! tee name=t t. ! queue ! filesink location=bla.ts t. ! queue ! decodebin ! autovideosink
gstreamer 实现播放器
#include <gst/gst.h>
int main(int argc, char *argv[])
{
GstElement *pipeline;
GstBus *bus;
GstMessage *msg;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Build the pipeline */
pipeline = gst_parse_launch ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Free resources */
if (msg != NULL)
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
插件编写
- 从模板生成gstreamer插件
获取插件模板:
git clone git://anongit.freedesktop.org/gstreamer/gst-template.git
cd gst-template/gst-plugin/src
通过make_element 生成 插件文件:
../tools/make_element ExampleFilter
生成 gstexamplefilter.c gstexamplefilter.h
修改src/Makefile.am
vi Makefile.am
plugin_LTLIBRARIES = libgstexamplefilter.la
libgstexamplefilter_la_SOURCES = gstexamplefilter.c
libgstexamplefilter_la_CFLAGS = $(GST_CFLAGS)
libgstexamplefilter_la_LIBADD = $(GST_LIBS)
libgstexamplefilter_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstexamplefilter_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstexamplefilter.h
编译
./autogen.sh
CC=arm-hisiv400-linux-gcc
./configure --prefix=./output --host=arm-hisiv400-linux \
PKG_CONFIG_PATH=./output/lib/pkgconfig \
make
make install
将编译好的libgstexamplefilter.la libgstexamplefilter.so 复制到指定的运行目录下。
测试插件:
./gst-inspect-1.0 examplefilter
- 参考 svn 的已写的插件编写新插件
从 svn 上下载 /nvr/development/examples/gst_plugin_demo 工程,复制工程修改ProjectMetadata.cmake配置文件
make - 插件基本函数
注册插件
gst_element_register
#类似于C++里面的构造函数,该初始化过程只进行一次
gst_demo_class_init
# 实例的初始化, 结构体赋初值
gst_demo_init
# 设置属性函数
gst_demo_set_property
# 获取属性值
gst_demo_get_property
# pipeline 事件的处理
gst_demo_sink_event
# pipeline 数据的处理
gst_demo_chain