GStreamer 的 Monkey's Audio 插件

前一阵给 [GStreamer] [Monkey's Audio][mac-port][插件]的作者 Jérémy Simon 发了封信,询问插件的开发情况,并说如果他没时间做的话,我可以提供一些帮助,接着做完,最起码要支持现在发布的 0.10 版本。毕竟 GStreamer 也算是一个大的框架,很多其他程序都是用它作为后端,数不胜数,但现在的这个比较老,而且已经一年多没有更新,更谈不上对新版本的支持。他回信说可以让我来做。

然后昨天就开工,首先是解决了 auto* 配置问题,然后首先就是解码。以前在[多媒体播放模式]一文中简单谈到了 GStreamer,这次就需要仔细看看了,还是一样,时间不多精力不够,不太可能看代码,只好翻文档。它官方网站上给出的文档对于了解它的架构基本上没什么作用,还好找到了它的[设计文档],能了解到很多架构上的设计,当然很多东西了解得也不是很透彻,不过也足够了,以后有机会再翻代码。当然几个必要的东西得打开,API 参考、设计文档、还有 [FLAC 的插件实现]用于参考,有个例子可真是帮了大忙了。

首先解决的问题是 IO,正如以前所说,MAC 库是完全的拉模式,自己控制所有的数据读写,而 GStreamer 同时支持推模式和拉模式,在实现上稍有不同。所以得在 GStreamer 上构建一个适配器用于 MAC。原来的插件适用于 0.8.0,用的是一个 bitstream 的东东,0.10 已经没有了,而是直接在 sinkpad 上直接支持,当然相对应的 srcpad 必须是 seekable (可搜索的)。拉模式最重要的一点就是 gst_pad_pull_range() 这个函数了,继承一个 CIO 就行了,这个没什么问题。

然后就在原来的基础上参照 FLAC 插件的实现,改吧改吧,主要就是一些函数上的改变。首先要激活 pad,gst_pad_set_activate_function()gst_pad_set_activatepull_function(),由于只使用拉模式,所以只设置 pull 的就可以了。在激活函数中,用 gst_pad_start_task() 来开始一个循环。拉模式必须得有一个解码循环(decode loop),在这里其实循环不是自己来做的,这个解码循环就相当于真正的循环体,每次读出数据,然后用 gst_pad_push() 扔给自己的 srcpad 就可以了。

调试起来也很方便,GStreamer 有一个工具 gst-launch,可以用命令行直接构造流水线(pipeline)实现简单的功能,不过这对测试也就够了。调用的命令行是:gst-launch filesrc location=APE_FILE_PATH ! monkeysdec ! audioconvert ! audioresample ! autoaudiosink,其中 monkeysdec 就是本插件的名字。最开始的时候一直说 audioconvert 的 sinkpad 没有进行协商,后来发现对于仍到 srcpad 的缓冲区数据也必须得设 caps (capability 能力),比如用 gst_pad_alloc_buffer_and_set_caps(),把在初始化阶段设到 srcpad 里的 caps 设置进去,这样流水线下一个元素的 sinkpad 拿到数据后就知道里面是什么样的数据了。哈,至此最基本的播放功能就完成了。

然后是跳转(seek)功能。这就稍微麻烦一些了,GStreamer 里面有好几种不同的 seek,清除缓冲(flush)、不清除缓冲、不同的分段跳转等等。经过研究,只支持了 前面两个,看起来似乎容易一些。GSteamer 的跳转是通过事件(event)来进行的,需要一个事件处理函数,在此函数中对跳转事件进行处理。用 gst_event_parse_seek() 中可以得到跳转的类型、格式、起始位置、结束位置等等信息。非清除缓冲类型的跳转比较简单,在处理函数中,直接跳转到相应位置就可以了。不清除缓冲模式稍微麻烦一点:

  1. gst_pad_push_event 发一个开始清除缓冲(gst_event_new_flush_start())的事件
  2. GST_PAD_STREAM_LOCK 将 sinkpad 锁住,不再接收或者读取数据
  3. 进行跳转操作
  4. gst_pad_push_event 发一个完成清除缓冲(gst_event_new_flush_stop())的事件
  5. GST_PAD_STREAM_UNLOCK 将 sinkpad 解锁

还要将解码循环的任务暂停 gst_pad_pause_task

测试也有点麻烦,因为 gst-launch 不能跳转,刚开始想使用外部程序来做,比如使用 GStreamer 作为后端的那些播放器,发现都太大了。后来发现在 CVS 上有[测试程序],拿下来稍微改一改就可以用了。最后都通过,哈,解码部分就完成了。

剩下的还有编码和元数据,以后再说。

不过现在感到 MAC 的这种实现方法有很大的问题,对于推模式而言,感觉非常难受,甚至有些功能可能实现不了。Frank Klemm(原来也 port 一个老版本到 Linux 上)也在考虑是否写一个[C 版本]的。不知道原作者 Matt 对于算法本身有什么特殊的授权没有,我也正有重写的意思。

THX your great work. hope

THX your great work.

hope MAC For GStreamer 0.10 coming soon.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • You can use BBCode tags in the text.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
one plus 42 equals
Solve this math question and enter the solution with digits. E.g. for "two plus four = ?" enter "6".