Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1062273
  • 博文数量: 77
  • 博客积分: 821
  • 博客等级: 军士长
  • 技术积分: 1905
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-23 16:17
个人简介

学校:上海交通大学软件工程 学历:硕士 行业:从事流媒体移动开发 QQ: 412595942 邮箱:yiikai1987910@gmail.com

文章分类

全部博文(77)

文章存档

2016年(4)

2015年(15)

2014年(16)

2013年(12)

2012年(21)

2011年(9)

分类: LINUX

2012-05-30 14:22:53

  最近在着手开发gstreamer的插件,遇到不少问题,有木有!论坛,qq群上所谓的鸟侠关键时候都不懂了,也没人回答,有木有!  尼玛!坑嗲啊!    
  凡是还是要靠自己,拿出源码,自己好好的分析了一把,果然验证了那句老话,源码面前了无秘密!有木有!
  言归正转,gstreamer官方的插件手册我看来基本没有,只是介绍了插件的含义,最为关键的动态加载插件的方式没有过多的介绍。所以我记录下源插件制作过程以备忘记!
  插件的模板创建过程就不多说了参考手册就知道了!
  

  我的插件主要是想通过playbin2来动态的调用我的插件实现所期望的功能,那自然要清楚playbin2的运行流程,我们会发现,运行playbin2 uri=file:///home/1.mp4命令行的时候,在playbin2的内部其实是把参数uri传给其中的uridecodebin,那我们来看侠uridecodebin中的实现过程.
   当传入uri后,会进入下面这个uridecodebin的接口,

点击(此处)折叠或打开

  1. static GstElement *
  2. gen_source_element (GstURIDecodeBin * decoder)
  3. {
  4.   GstElement *source;

  5.   if (!decoder->uri)
  6.     goto no_uri;

  7.   GST_LOG_OBJECT (decoder, "finding source for %s", decoder->uri);

  8.   if (!gst_uri_is_valid (decoder->uri))
  9.     goto invalid_uri;

  10.   if (IS_BLACKLISTED_URI (decoder->uri))
  11.     goto uri_blacklisted;

  12.   source = gst_element_make_from_uri (GST_URI_SRC, decoder->uri, "source");
  13.   if (!source)
  14.     goto no_source;
这个函数主要是做写对uri的格式判断,当认为uri的格式没有问题后,就会调用gst_element_make_from_uri接口,然后我们在来看这个接口。接口代码如下

点击(此处)折叠或打开

  1. GstElement *
  2. gst_element_make_from_uri (const GstURIType type, const gchar * uri,
  3.     const gchar * elementname)
  4. {
  5.   GList *possibilities, *walk;
  6.   gchar *protocol;
  7.   GstElement *ret = NULL;

  8.   g_return_val_if_fail (GST_URI_TYPE_IS_VALID (type), NULL);
  9.   g_return_val_if_fail (gst_uri_is_valid (uri), NULL);

  10.   protocol = gst_uri_get_protocol (uri);
  11.   possibilities = get_element_factories_from_uri_protocol (type, protocol);
  12.   g_free (protocol);

  13.   if (!possibilities) {
  14.     GST_DEBUG ("No %s for URI '%s'", type == GST_URI_SINK ? "sink" : "source",
  15.         uri);
  16.     return NULL;
  17.   }

  18.   possibilities = g_list_sort (possibilities, (GCompareFunc) sort_by_rank);
  19.   walk = possibilities;
  20.   while (walk) {
  21.     if ((ret =
  22.             gst_element_factory_create (GST_ELEMENT_FACTORY_CAST (walk->data),
  23.                 elementname)) != NULL) {
  24.       GstURIHandler *handler = GST_URI_HANDLER (ret);

  25.       if (gst_uri_handler_set_uri (handler, uri))
  26.         break;
  27.       gst_object_unref (ret);
  28.       ret = NULL;
  29.     }
  30.     walk = walk->next;
  31.   }
  32.   gst_plugin_feature_list_free (possibilities);

  33.   GST_LOG_OBJECT (ret, "created %s for URL '%s'",
  34.       type == GST_URI_SINK ? "sink" : "source", uri);
  35.   return ret;
  get_element_factories_from_uri_protocol (type, protocol)函数实现了主要的插件自动加载机制,我们跟进这个函数看下
  

点击(此处)折叠或打开

  1. static GList *
  2. get_element_factories_from_uri_protocol (const GstURIType type,
  3.     const gchar * protocol)
  4. {
  5.   GList *possibilities;
  6.   SearchEntry entry;

  7.   g_return_val_if_fail (protocol, NULL);

  8.   entry.type = type;
  9.   entry.protocol = protocol;
  10.   possibilities = gst_registry_feature_filter (gst_registry_get_default (),
  11.       search_by_entry, FALSE, &entry);

  12.   return possibilities;
  13. }
发现内部把插件的type和前面解析出来的协议头分配给了entry对象,然后看gst_registry_feature_filter的实现

点击(此处)折叠或打开

  1. static gboolean
  2. search_by_entry (GstPluginFeature * feature, gpointer search_entry)
  3. {
  4.   gchar **protocols;
  5.   GstElementFactory *factory;
  6.   SearchEntry *entry = (SearchEntry *) search_entry;

  7.   if (!GST_IS_ELEMENT_FACTORY (feature))
  8.     return FALSE;
  9.   factory = GST_ELEMENT_FACTORY_CAST (feature);

  10.   if (factory->uri_type != entry->type)
  11.     return FALSE;

  12.   protocols = gst_element_factory_get_uri_protocols (factory);

  13.   if (protocols == NULL) {
  14.     g_warning ("Factory '%s' implements GstUriHandler interface but returned "
  15.         "no supported protocols!", gst_plugin_feature_get_name (feature));
  16.     return FALSE;
  17.   }

  18.   while (*protocols != NULL) {
  19.     if (g_ascii_strcasecmp (*protocols, entry->protocol) == 0)
  20.       return TRUE;
  21.     protocols++;
  22.   }
  23.   return FALSE;
  24. }
在进行了一番判断后,进入了gst_element_factory_get_uri_protocols

点击(此处)折叠或打开

  1. gchar **
  2. gst_element_factory_get_uri_protocols (GstElementFactory * factory)
  3. {
  4.   g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);

  5.   return factory->uri_protocols;
  6. }
发现最后这个接口返回的是要动态绑定的插件的协议数据,现在回到gst_element_make_from_uri接口
就会发现之后就会通过将获得插件元件转换成Gsturihandler来完成对插件的uri设定,主要流程就是这样


从上面的分析也可以知道插件编写的过程中,也要实现GstURIHandlerInterface的一套方法
可以参照已有的gstreamer插件来实现
阅读(9373) | 评论(0) | 转发(0) |
0

上一篇:GST开发笔记

下一篇:ubuntu 开启nfs服务

给主人留下些什么吧!~~