国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
OpenCores框架

媒體播放引擎

v     opencore中由PVPlayerEngine負(fù)責(zé)媒體播放功能的實現(xiàn);

v     PVPlayerEngine中負(fù)責(zé)創(chuàng)建各個節(jié)點來完成媒體文件格式解析(SourceNode)、媒體數(shù)據(jù)編解碼(DecodeNode/EncNode)以及媒體數(shù)據(jù)的輸出(MediaOutputNode);

v     PlayerDriver負(fù)責(zé)opencoreandroid媒體框架的適配;

v     AndroidAudioOutput負(fù)責(zé)音頻數(shù)據(jù)輸出到android-audioflinger服務(wù)輸出,由AndroidSurfaceOutput來負(fù)責(zé)將視頻數(shù)據(jù)輸出到android-surfaceflinger服務(wù)輸出;

 

媒體播放引擎-驅(qū)動層

v     驅(qū)動層包括:PVPlayerPlayerDriver組成;

v     PVPlayer負(fù)責(zé)將上層應(yīng)用的命令轉(zhuǎn)換成PlayerDriver可以內(nèi)部命令加入到其命令隊列中,由PlayerDriver負(fù)責(zé)執(zhí)行,并負(fù)責(zé)將命令執(zhí)行的結(jié)果回送給上層媒體框架以及JAVA程序;

v     PlayerDriver中有一個消息循環(huán)負(fù)責(zé)處理PVPlayer發(fā)送過來的命令,調(diào)用PVPlayerEngine相應(yīng)的接口來完成媒體控制;

v     在創(chuàng)建PlayerDriver對象時會生成opencore主線程,并調(diào)用OsclExecScheduler.StartScheduler來開始opencore主線程循環(huán);

v     源碼文件:

v     android/playerdriver.cpp

v     android/playerdriver.h

媒體播放引擎-文件格式識別

v     opencore中由PVPlayerRecognizerRegistry負(fù)責(zé)文件格式識別,并將結(jié)果返回給PVPlayerEngine;

v     PVPlayerEngine根據(jù)類型來創(chuàng)建對應(yīng)的文件解析節(jié)點ParseNode

v     opencore中對文件格式的識別時通過讀取文件頭的方式進(jìn)行的,而不是根據(jù)文件擴(kuò)展名;

v     opencore中通過向系統(tǒng)中注冊文件識別插件的方式來提供文件格式識別的功能,系統(tǒng)通過循環(huán)調(diào)用每個注冊插件的Recognize()函數(shù)來進(jìn)行格式識別;

v     在創(chuàng)建媒體播放引擎的時候會通過PVPlayerRegistryPopulator::Populate()函數(shù)來注冊所有的文件識別插件到系統(tǒng)中

 

v     源碼文件:

v     pvmi/recognizer/src/pvmf_recognizer_registry.cpp

v     pvmi/recognizer/src/pvmf_recognizer_registry_impl.cpp

v     pvmi/recognizer/plugins/目錄下所有的子目錄中存放著文件識別插件的代碼;

媒體播放引擎-文件格式解析節(jié)點

v     opencore中通過文件解析節(jié)點(ParseNode)來完成音視頻文件格式的解析,并將文件中的音頻、視頻數(shù)據(jù)送到對應(yīng)的解碼節(jié)點進(jìn)行解碼;

v     PVPlayerEngine通過PVMFNodeInterface接口來完成對ParseNode的操作;ParseNode通過提供擴(kuò)展接口來實現(xiàn)通用Node接口不能實現(xiàn)的功能;

v     常用的擴(kuò)展接口如:PvmiCapabilityAndConfig;

v     opencore中通過注冊的方式向系統(tǒng)中注冊文件格式解析節(jié)點

 

媒體播放引擎-節(jié)點注冊

v     1、每個節(jié)點都有一個對應(yīng)的PVMFXXXXFactrory來負(fù)責(zé)創(chuàng)建;

v     2、系統(tǒng)中通過PVPlayerRegistryPopulator. RegisterAllNodes()來注冊所有支持的節(jié)點;

v     3opencore首先調(diào)用PVPlayerNodeRegistry-> QueryRegistry()函數(shù)查詢對于指定的輸入&輸出格式的NodeUUID,然后通過PVPlayerNodeRegistry-> CreateNode ()創(chuàng)建指定的Node

v     4、PVPlayerEngine就是通過文件格式識別插件返回的媒體類型來創(chuàng)建對應(yīng)的文件解析節(jié)點的

void PVMFMP4FFParserNode::Run()

{

   //Process commands.

   if (!iInputCommands.empty())

    {

       ProcessCommand();

    }

 

   while (!iPortActivityQueue.empty() && (iInterfaceState ==EPVMFNodeStarted ||                            FlushPending()))

    {

       ProcessPortActivity();

    }

 

   if (iInterfaceState == EPVMFNodeStarted && !FlushPending())

    {

       HandleTrackState();

    }

 

   //Check for completion of a flush command...

   if (FlushPending() && iPortActivityQueue.empty())

    {

       //Flush is complete.

       CommandComplete(iCurrentCommand,iCurrentCommand.front(), PVMFSuccess);

    }

}

 voidPVMFMP4FFParserNode::HandleTrackState()

{

   for (uint32 i = 0; i < iNodeTrackPortList.size(); ++i)

    {

       switch (iNodeTrackPortList[i].iState)

       {

            casePVMP4FFNodeTrackPortInfo::TRACKSTATE_UNINITIALIZED:

                ……

 

           case PVMP4FFNodeTrackPortInfo::TRACKSTATE_TRANSMITTING_GETDATA:

                ……

                if(!RetrieveTrackData(iNodeTrackPortList[i]))

                {

                    ……

                }

                ……

 

           case PVMP4FFNodeTrackPortInfo::TRACKSTATE_TRANSMITTING_SENDDATA:

                if(SendTrackData(iNodeTrackPortList[i]))

                {

                    ……

                }

                break;

 

           ……

       }

    }

}

媒體播放引擎-解碼節(jié)點

v     opencore中由DecNode節(jié)點負(fù)責(zé)媒體數(shù)據(jù)的解碼工作;

v     DecNode通過調(diào)用底層的opencoreMAX通用接口實現(xiàn)媒體數(shù)據(jù)的解碼;

v     對于一個普通的視頻文件,存在2個解碼節(jié)點:音頻解碼節(jié)點和視頻解碼節(jié)點;

 

 

boolPVMFOMXBaseDecNode::SendInputBufferToOMXComponent()

{

    ……

   OMX_EmptyThisBuffer(iOMXDecoder, input_buf->pBufHdr);

    ……

}

PVMFOMXBaseDecNode::SendOutputBufferToOMXComponent()

{

    ……

   OMX_FillThisBuffer(iOMXDecoder, output_buf->pBufHdr);

    ……

}

OMX_ERRORTYPE PVMFOMXBaseDecNode::EmptyBufferDoneProcessing(OMX_OUTOMX_HANDLETYPE aComponent,

       OMX_OUT OMX_PTR aAppData,

       OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)

{

    ……

}

OMX_ERRORTYPEPVMFOMXBaseDecNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,

       OMX_OUT OMX_PTR aAppData,

       OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)

{

    ……

}

v     源碼文件:

v     nodes/pvomxbasedecnode/

v     nodes/pvomxvideodecnode/

v     codecs_v2/omx/

媒體播放引擎-媒體輸出節(jié)點

v     MediaOutputNode負(fù)責(zé)接收DecNode的解碼后數(shù)據(jù),并將數(shù)據(jù)輸出到MIO;同時在輸出前作視頻的同步;

v     MIO負(fù)責(zé)將數(shù)據(jù)輸出到surfaceFlingerAudioFlinger;

v     視頻數(shù)據(jù)在輸出前需要做顏色空間的轉(zhuǎn)換(YUV->RGB)和縮放,這部分的工作也在MIO中完成;

v     節(jié)點源碼:

v     nodes/pvmediaoutputnode/

v     MIO源碼:

v     android/android_surface_output.cpp

v     android/android_audio_output.cpp

v     android/android_audio_mio.cpp

v      http://zhaixishan.cublog.cn

 

附錄:

具體的代碼閱讀:


目錄結(jié)構(gòu)
OpenCore的代碼在以下目錄中:external/opencore/。這個目錄是OpenCore的根目錄,其中包含的子目錄如下所示:

    * android:這里面是一個上層的庫,它基于PVPlayer和PVAuthor的SDK實現(xiàn)了一個為Android使用的Player和Author。
    * baselibs:包含數(shù)據(jù)結(jié)構(gòu)和線程安全等內(nèi)容的底層庫
    * codecs_v2:這是一個內(nèi)容較多的庫,主要包含編解碼的實現(xiàn),以及一個OpenMAX的實現(xiàn)
    * engines:包含PVPlayer和PVAuthor引擎的實現(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類是通過PVMFWAVFFParserNodeFactoryCreatePVMFWAVFFParserNode()成員函數(shù)生成的。而CreatePVMFWAVFFParserNode()函數(shù)是在PVPlayerNodeRegistry::PVPlayerNodeRegistry()類構(gòu)造函數(shù)中通過PVPlayerNodeInfo類被注冊到Oscl_Vector<PVPlayerNodeInfo, OsclMemAllocator> 的vector中,在這個構(gòu)造函數(shù)中,AMR,mp3等node也是同樣被注冊的。
由上可知,Opencore中對splitter的管理也是與ffmpeg等類似,都是在框架的初始化時注冊的,只不過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的匹配過程
PVMFStatusPVPlayerNodeRegistry::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之中定義了一個JNINativeMethodJAVA本地調(diào)用方法)類型的數(shù)組gMethods,供java代碼中調(diào)用MultiPlayer類的setDataSource成員函數(shù)時找到對應(yīng)的c++函數(shù)  
    {"setDataSource",       "(Ljava/lang/String;)V",            (void *)android_media_MediaPlayer_setDataSource},
  • static void android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path)

    此函數(shù)中先得到當(dāng)前的MediaPlayer實例,然后調(diào)用其setDataSource函數(shù),傳入路徑

  • 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ù),ClientMediaPlayerService的一個內(nèi)部類。
    MediaPlayerService::Client::setDataSource中,調(diào)sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
    
生成一個繼承自MediaPlayerBase的PVPlayer實例,
    PVPlayer的繼承關(guān)系如下:
    PVPlayer-->MediaPlayerInterface-->MediaPlayerBase
    最后調(diào)PVPlayer的setDataSource()函數(shù)

  • status_t PVPlayer::setDataSource(const char *url)
  • status_t PVPlayer::prepare()

    此函數(shù)開頭執(zhí)行ret = mPlayerDriver->enqueueCommand(new PlayerSetDataSource(mDataSourcePath,0,0));
    PlayerSetDataSource 的command類加入到PlayerDriver的command處理隊列中,
    在void PlayerDriver::Run()函數(shù)中處理此command,調(diào)用下面的handleSetDataSource函數(shù)。

  • void PlayerDriver::handleSetDataSource(PlayerSetDataSource* ec)
  • PVCommandId PVPlayerEngine::AddDataSource(PVPlayerDataSource& aDataSource, const OsclAny* aContextData)

        This function allows a player data source to be specified for playback. This function must be called

  • PVMFStatus PVPlayerEngine::DoAddDataSource(PVPlayerEngineCommand& aCmd)
  • PVMFStatus PVPlayerEngine::DoSetupSourceNode(PVCommandId aCmdId, OsclAny* aCmdContext)
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
opencore and stagefright
【轉(zhuǎn)】 Android多媒體支撐庫OpenCore視頻硬件加速
opencore Init的調(diào)用流程
Android的多媒體框架OpenCore介紹 第二部分 OpenCore的代碼結(jié)構(gòu)
OpenCore隨想
AndroidPVPlayer介紹
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服