doubango把功能劃分為很多部件稳摄,如音視頻的生產(chǎn)者producer儒搭,音視頻的消耗者consumer,負(fù)責(zé)編解碼的codec等棉浸。每個部件其實(shí)可以有不同的實(shí)現(xiàn)揖曾。如producer在不同平臺上就有不同的實(shí)現(xiàn)贩毕,即使是同一平臺悯许,如音頻的生產(chǎn),也可以直接采集麥克風(fēng)辉阶,或者從文件獲取音頻數(shù)據(jù)先壕。
doubango通過插件的方式來管理這些不同的選擇。
插件的定義
插件的定義在tinyMedia目錄谆甜,而插件的具體實(shí)現(xiàn)在tinyDav目錄垃僚。
以consumer部件為例。
首先在tinyMedia目錄规辱,定義了一個tmedia_consumer_t
結(jié)構(gòu)谆棺,用于存放所有consumer插件都需要的一些公共數(shù)據(jù)。緊接著定義了tmedia_consumer_plugin_def_t
結(jié)構(gòu)按摘,用于描述插件應(yīng)該支持的行為包券。tmedia_consumer_plugin_def_t
包含了具體插件的xx_def_t
(里面包含plugin的size和構(gòu)造析構(gòu)函數(shù))的指針,以及應(yīng)該支持的函數(shù)炫贤。
當(dāng)定義一個具體的consumer插件時溅固,如video_consumer_android_t
,需要直接或者間接繼承tmedia_consumer_t
結(jié)構(gòu)。并提供一個tmedia_consumer_plugin_def_t
全局變量來保存自己作為consumer_plugin提供的函數(shù)及其他信息兰珍。
static const tmedia_consumer_plugin_def_t video_consumer_android_plugin_def_s =
{
&video_consumer_android_def_s,
tmedia_video,
"ANDROID video consumer",
video_consumer_android_set,
tsk_null,
video_consumer_android_prepare,
video_consumer_android_start,
video_consumer_android_consume,
video_consumer_android_pause,
video_consumer_android_stop
};
const tmedia_consumer_plugin_def_t *video_consumer_android_plugin_def_t = &video_consumer_android_plugin_def_s;
插件的注冊
tinyMedia里還提供了consumer插件的注冊函數(shù)tmedia_consumer_plugin_register
侍郭。調(diào)用注冊函數(shù)后,創(chuàng)建tmedia_consumer_t
時就可以創(chuàng)建該插件了掠河。
插件的注冊亮元,放在tdav_init
函數(shù)中調(diào)用。
tmedia_consumer_plugin_register (audio_consumer_android_plugin_def_t);
部件的創(chuàng)建
tmedia_consumer_t
中有一個plugin(xxx_plugin_def_t類型)的變量唠摹。當(dāng)調(diào)用tmedia_consumer_create
創(chuàng)建tmedia_consumer_t
時爆捞,會從已經(jīng)注冊的插件列表中,找到合適的插件勾拉,生成一個實(shí)例煮甥,作為tmedia_consumer_t
返回給調(diào)用方(插件是繼承tmedia_consumer_t,還記得嗎)藕赞。并把該插件的xxx_plugin_def_t賦值給plugin變量成肘。
typedef struct tmedia_consumer_s
{
//其他變量
const struct tmedia_consumer_plugin_def_s* plugin;
} tmedia_consumer_t;
對部件的操作
現(xiàn)在對部件進(jìn)行操作的時候,就可以委托給plugin的對應(yīng)函數(shù)了斧蜕。
這里的plugin
其實(shí)是regist的video_consumer_android_plugin_def_t
双霍;
plugin->consume
就是video_consumer_android_consume
。
而tmedia_consumer_t *self
則是返回出去的video_consumer_android_t
對象。在video_consumer_android_consume
可以強(qiáng)轉(zhuǎn)為video_consumer_android_t
類型洒闸。
int tmedia_consumer_consume (tmedia_consumer_t *self, const void *buffer, tsk_size_t size, tsk_object_t *proto_hdr)
{
if (!self || !self->plugin || !self->plugin->consume || !proto_hdr)
{
TSK_DEBUG_ERROR ("Invalid parameter");
return -1;
}
return self->plugin->consume (self, buffer, size, proto_hdr);
}