前一阵给 [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() 中可以得到跳转的类型、格式、起始位置、结束位置等等信息。非清除缓冲类型的跳转比较简单,在处理函数中,直接跳转到相应位置就可以了。不清除缓冲模式稍微麻烦一点:
-
gst_pad_push_event发一个开始清除缓冲(gst_event_new_flush_start())的事件 -
GST_PAD_STREAM_LOCK将 sinkpad 锁住,不再接收或者读取数据 - 进行跳转操作
-
gst_pad_push_event发一个完成清除缓冲(gst_event_new_flush_stop())的事件 -
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