Android中對于圖形界面以及多媒體的相關(guān)操作比較容易實(shí)現(xiàn),。而且對于大多數(shù)手機(jī)用戶來說,他們主要也就是根據(jù)這些方面的功能來對系統(tǒng)那個進(jìn)行修改。我們可以通過本文介紹的Android多媒體框架的源碼解讀,,來具體分析一下這方面的基本知識。
Android多媒體框架的代碼在以下目錄中:external/opencore/,。這個目錄是Android多媒體框架的根目錄,,其中包含的子目錄如下所示:
* android:這里面是一個上層的庫,,它基于PVPlayer和PVAuthor的SDK實(shí)現(xiàn)了一個為Android使用的Player和Author。
* baselibs:包含數(shù)據(jù)結(jié)構(gòu)和線程安全等內(nèi)容的底層庫
* codecs_v2:這是一個內(nèi)容較多的庫,,主要包含編解碼的實(shí)現(xiàn),,以及一個OpenMAX的實(shí)現(xiàn)
* engines:包含PVPlayer和PVAuthor引擎的實(shí)現(xiàn)
* extern_libs_v2:包含了khronos的OpenMAX的頭文件
* fileformats:文件格式的據(jù)具體解析(parser)類
* nodes:編解碼和文件解析的各個node類。
* oscl:操作系統(tǒng)兼容庫
* pvmi: 輸入輸出控制的抽象接口
* protocols:主要是與網(wǎng)絡(luò)相關(guān)的RTSP,、RTP,、HTTP等協(xié)議的相關(guān)內(nèi)容
* pvcommon:pvcommon庫文件的Android.mk文件,沒有源文件,。
* pvplayer:pvplayer庫文件的Android.mk文件,,沒有源文件。
* pvauthor:pvauthor庫文件的Android.mk文件,,沒有源文件,。
* tools_v2:編譯工具以及一些可注冊的模塊。
Splitter的定義與初始化
以wav的splitter為例,,在fileformats目錄下有解析wav文件格式的pvwavfileparser.cpp文件,,在nodes目錄下有pvmf_wavffparser_factory.cpp,pvmf_wavffparser_node.h,, pvmf_wavffparser_port.h等文件,。
我們由底往上看,vwavfileparser.cpp中的PV_Wav_Parser類有InitWavParser(),,GetPCMData(),,RetrieveFileInfo()等解析wav格式的成員函數(shù),此類應(yīng)該就是最終的解析類,。我們搜索PV_Wav_Parser類被用到的地方可知,,在PVMFWAVFFParserNode類中有PV_Wav_Parser的一個指針成員變量。
再搜索可知,,PVMFWAVFFParserNode類是通過PVMFWAVFFParserNodeFactory的CreatePVMFWAVFFParserNode()成員函數(shù)生成的,。而CreatePVMFWAVFFParserNode()函數(shù)是在PVPlayerNodeRegistry::PVPlayerNodeRegistry()類構(gòu)造函數(shù)中通過PVPlayerNodeInfo類被注冊到Oscl_Vector《PVPlayerNodeInfo, OsclMemAllocator》 的vector中,,在這個構(gòu)造函數(shù)中,,AMR,mp3等node也是同樣被注冊的,。
由上可知,,Android多媒體框架中對splitter的管理也是與ffmpeg等類似,都是在框架的初始化時(shí)注冊的,,只不過Opencore注冊的是每個splitter的factory函數(shù),。
綜述一下splitter的定義與初始化過程:
每個splitter都在fileformats目錄下有個對應(yīng)的子目錄,其下有各自的解析類。
每個splitter都在nodes目錄下有關(guān)對應(yīng)的子目錄,,其下有各自的統(tǒng)一接口的node類和node factory類,。
播放引擎PVPlayerEngine類中有PVPlayerNodeRegistry iPlayerNodeRegistry成員變量,。
在PVPlayerNodeRegistry的構(gòu)造函數(shù)中,,將 AMR, AAC,, MP3等splitter的輸入與輸出類型標(biāo)示和node factory類中的create node與release delete接口通過PVPlayerNodeInfo類push到Oscl_Vector《PVPlayerNodeInfo,, OsclMemAllocator》 iType成員變量中。
當(dāng)前Splitter的匹配過程
PVMFStatus PVPlayerNodeRegistry::QueryRegistry(PVMFFormatType& aInputType,, PVMFFormatType& aOutputType,, Oscl_Vector《PVUuid, OsclMemAllocator》& aUuids)函數(shù)的功能是根據(jù)輸入類型和輸出類型,,在已注冊的node vector中尋找是否有匹配的node,,有的話傳回其唯一識別標(biāo)識PVUuid。
從QueryRegistry這個函數(shù)至底向上搜索可得到,,在android中splitter的匹配過程如下:
android_media_MediaPlayer.cpp之中定義了一個JNINativeMethod(JAVA本地調(diào)用方法)類型的數(shù)組gMethods,,供java代碼中調(diào)用MultiPlayer類的setDataSource成員函數(shù)時(shí)找到對應(yīng)的c++函數(shù)
1.{“setDataSource”, “(Ljava/lang/String;)V”,, (void *)
android_media_MediaPlayer_setDataSource},,
2.static void android_media_MediaPlayer_setDataSource
(JNIEnv *env,, jobject thiz,, jstring path)
此函數(shù)中先得到當(dāng)前的MediaPlayer實(shí)例,然后調(diào)用其setDataSource函數(shù),,傳入路徑
3.status_t MediaPlayer::setDataSource(const char *url)
此函數(shù)通過調(diào)getMediaPlayerService()先得到當(dāng)前的MediaPlayerService,, const sp《IMediaPlayerService》& service(getMediaPlayerService());
然后新建一個IMediaPlayer變量, sp《IMediaPlayer》 player(service-》create(getpid(), this,, fd,, offset, length));
在sp《IMediaPlayer》 MediaPlayerService::create(pid_t pid,, const sp《IMediaPlayerClient》& client, const char* url)中
調(diào)status_t MediaPlayerService::Client::setDataSource(const char *url)函數(shù),,Client是MediaPlayerService的一個內(nèi)部類,。
在MediaPlayerService::Client::setDataSource中,調(diào)sp《MediaPlayerBase》 MediaPlayerService::Client::createPlayer(player_type playerType)
生成一個繼承自MediaPlayerBase的PVPlayer實(shí)例,。
以上就是對Android多媒體框架的源代碼的解讀,。