GStreamer开发,主要分为两块:应用开发、插件开发。
插件开发人员,通常是编解码库的作者(做出了编解码库后,希望gstreamer能用起来这个库,因此增加这个适配层)、芯片原厂人员(将自家的hw适配到gstreamer框架下)、其他(对muxer/demux软件库较熟悉的自愿整合奉献)。
应用开发人员,调通用的标准接口,进行多媒体处理。
本篇是针对app开发者来介绍的。
需求:命令行的管道方式可以播放一个文件,但如果在应用程序中播放,如何做呢?
这个一个基本流程:
0. pipeline生成:gst_pipeline_new(const gchar * name)
是对下条接口的封装:gst_element_factory_make("pipeline", name);
其实,pipeline就是一个element,其直接父类为GstBin,爷爷类为GstElement,太爷类为GstObject,再上面一层是GInitiallyUnowned,再再上面一层为GInitiallyUnowned
1. element生成:gst_element_factory_make(const gchar * factoryname, const gchar * name)
某个element生成流程:先找到某个elemnent factory,再用该工厂生产出某个具体element
step1: factory = gst_element_factory_find(factoryname)
step2: element = gst_element_factory_create(factory, name)
注意:factoryname必须准确,否则找不到工厂,但某个element的名字name可以随意变化(即使为NULL也行),但最好命名符合意义。
pipeline的生成也是直接调这个接口的。
2. 某个factory的寻找:gst_element_factory_find(const gchar* name)
先从注册的插件系统中寻找该feature,再引用该feature
step1: GstPluginFeature *feature = gst_registry_find_feature(gst_registry_get(), name, GST_TYPE_ELEMENT_FACTORY);
step2: GST_ELEMENT_FACTORY(feature); //把GstPluginFeature *转换为GstElementFactory *
3. 拿到pipeline的消息总线(GstBus*):gst_pipeline_get_bus(GST_PIPELINE(pipeline))
gst_pipeline_xx的参数只能针对GstPipeline类型的
先转换为element,再拿element的bus(只有element才有bus)
step1: gst_element_get_bus(GST_ELEMENT_CAST(pipeline));
step2: gst_element_get_bus(GstElement * element); //拿Bus时要对element加锁
4. 注册总线观察者:gst_bus_add_watch(bus, bus_call, loop);
gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT, func, user_data, NULL);
gst_bus_add_watch_full_unlocked()
step1: GSource *source = get_bus_create_watch(bus)
step2: g_source_set_callback(source, (GSourceFunc)func, user_data, notify);
step3: GMainContext *ctx = g_main_context_get_thread_default();
step4: guint id = g_source_attach(source, ctx);
step5: g_source_unref(source);
5. bin中添加element:gst_bin_add_many(GST_BIN(pipeline), src, decoder, sink, NULL);
依次将各element添加到bin中:
while (element1) {
gst_bin_add(bin, element1);
element_1 = va_arg(args, GstElement*);
}
6. 串联各element:gst_element_link_many(src, decoder, sink, NULL);
与上条类似,依次将各element串联起来(gst_element_link(element_1, element_2))
7. 设置pipeline状态:gst_element_set_state(pipeline, GST_STATE_PLAYING);
先拿到GstElementClass类,再对其进行状态设置
step1: GstElementClass *oclass = GST_ELEMENT_GET_CLASS(element);
step2: oclass->set_state(element, state);