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);