stagefright框架20.docx
- 文档编号:10761744
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:24
- 大小:447.12KB
stagefright框架20.docx
《stagefright框架20.docx》由会员分享,可在线阅读,更多相关《stagefright框架20.docx(24页珍藏版)》请在冰豆网上搜索。
stagefright框架20
stagefright框架
(一)VideoPlayback的流程
在Android上,預設的多媒體框架(multimediaframework)是OpenCORE。
OpenCORE的優點是兼顧了跨平台的移植性,而且已經過多方驗證,所以相對來說較為穩定;但是其缺點是過於龐大複雜,需要耗費相當多的時間去維護。
從Android2.0開始,Google引進了架構稍為簡潔的Stagefright,並且有逐漸取代OpenCORE的趨勢 (註1)。
[圖1]Stagefright在Android多媒體架構中的位置。
[圖2]Stagefright所涵蓋的模組(註2)。
以下我們就先來看看Stagefright是如何播放一個影片檔。
Stagefright在Android中是以sharedlibrary的形式存在(libstagefright.so),其中的module--AwesomePlayer可用來播放video/audio(註3)。
AwesomePlayer提供許多API,可以讓上層的應用程式(Java/JNI)來呼叫,我們以一個簡單的程式來說明videoplayback的流程。
在Java中,若要播放一個影片檔,我們會這樣寫:
MediaPlayermp=newMediaPlayer();
mp.setDataSource(PATH_TO_FILE);......
(1)
mp.prepare();........................
(2)、(3)
mp.start();..........................(4)
在Stagefright中,則會看到相對應的處理;
(1)將檔案的絕對路徑指定給mUri
status_tAwesomePlayer:
:
setDataSource(constchar*uri,...)
{
returnsetDataSource_l(uri,...);
}
status_tAwesomePlayer:
:
setDataSource_l(constchar*uri,...)
{
mUri=uri;
}
(2)啟動mQueue,作為eventhandler
status_tAwesomePlayer:
:
prepare()
{
returnprepare_l();
}
status_tAwesomePlayer:
:
prepare_l()
{
prepareAsync_l();
while(mFlags&PREPARING)
{
mPreparedCondition.wait(mLock);
}
}
status_tAwesomePlayer:
:
prepareAsync_l()
{
mQueue.start();
mFlags|=PREPARING;
mAsyncPrepareEvent=newAwesomeEvent(
this
&AwesomePlayer:
:
onPrepareAsyncEvent);
mQueue.postEvent(mAsyncPrepareEvent);
}
(3)onPrepareAsyncEvent被觸發
voidAwesomePlayer:
:
onPrepareAsyncEvent()
{
finishSetDataSource_l();
initVideoDecoder();......(3.3)
initAudioDecoder();
}
status_tAwesomePlayer:
:
finishSetDataSource_l()
{
dataSource=DataSource:
:
CreateFromURI(mUri.string(),...);
sp
MediaExtractor:
:
Create(dataSource);.....(3.1)
returnsetDataSource_l(extractor);.........................(3.2)
}
(3.1)解析mUri所指定的檔案,並且根據其header來選擇對應的extractor
sp
:
Create(constsp
{
source->sniff(&tmp,...);
mime=tmp.string();
if(!
strcasecmp(mime,MEDIA_MIMETYPE_CONTAINER_MPEG4)
{
returnnewMPEG4Extractor(source);
}
elseif(!
strcasecmp(mime,MEDIA_MIMETYPE_AUDIO_MPEG))
{
returnnewMP3Extractor(source);
}
elseif(!
strcasecmp(mime,MEDIA_MIMETYPE_AUDIO_AMR_NB)
{
returnnewAMRExtractor(source);
}
}
(3.2)使用extractor對檔案做A/V的分離(mVideoTrack/mAudioTrack)
status_tAwesomePlayer:
:
setDataSource_l(constsp
{
for(size_ti=0;i
{
sp
CHECK(meta->findCString(kKeyMIMEType,&mime));
if(!
haveVideo&&!
strncasecmp(mime,"video/",6))
{
setVideoSource(extractor->getTrack(i));
haveVideo=true;
}
elseif(!
haveAudio&&!
strncasecmp(mime,"audio/",6))
{
setAudioSource(extractor->getTrack(i));
haveAudio=true;
}
}
}
voidAwesomePlayer:
:
setVideoSource(sp
{
mVideoTrack=source;
}
(3.3)根據mVideoTrack中的編碼類型來選擇videodecoder(mVideoSource)
status_tAwesomePlayer:
:
initVideoDecoder()
{
mVideoSource=OMXCodec:
:
Create(mClient.interface(),
mVideoTrack->getFormat(),
false,
mVideoTrack);
}
(4)將mVideoEvent放入mQueue中,開始解碼播放,並交由mVideoRenderer來畫出
status_tAwesomePlayer:
:
play()
{
returnplay_l();
}
status_tAwesomePlayer:
:
play_l()
{
postVideoEvent_l();
}
voidAwesomePlayer:
:
postVideoEvent_l(int64_tdelayUs)
{
mQueue.postEventWithDelay(mVideoEvent,delayUs);
}
voidAwesomePlayer:
:
onVideoEvent()
{
mVideoSource->read(&mVideoBuffer,&options);
[CheckTimestamp]
mVideoRenderer->render(mVideoBuffer);
postVideoEvent_l();
}
(註1)從Android2.3(Gingerbread)開始,預設的多媒體框架為Stagefright。
(註2)Stagefright的架構尚不斷在演進中,本系列文章並未含括所有的模組。
(註3)Audio的播放是交由AudioPlayer來處理,請參考《Stagefright(6)-AudioPlayback的流程》。
stagefright框架
(二)-和OpenMAX的運作
转载学习2011-03-2219:
41:
57阅读111评论0 字号:
大中小 订阅
Stagefright的編解碼功能是利用OpenMAX框架,而且用的還是OpenCORE之OMX的實作,我們來看一下Stagefright和OMX是如何運作的。
(1)OMX_Init
OMXClientmClient;
AwesomePlayer:
:
AwesomePlayer()
{
mClient.connect();
}
status_tOMXClient:
:
connect()
{
mOMX=service->getOMX();
}
sp
:
getOMX()
{
mOMX=newOMX;
}
OMX:
:
OMX():
mMaster(newOMXMaster)
OMXMaster:
:
OMXMaster()
{
addPlugin(newOMXPVCodecsPlugin);
}
OMXPVCodecsPlugin:
:
OMXPVCodecsPlugin()
{
OMX_MasterInit();
}
OMX_ERRORTYPEOMX_MasterInit()<--underOpenCORE
{
returnOMX_Init();
}
(2)OMX_SendCommand
OMXCodec:
:
function_name()
{
mOMX->sendCommand(mNode,OMX_CommandStateSet,OMX_StateIdle);
}
status_tOMX:
:
sendCommand(node,cmd,param)
{
returnfindInstance(node)->sendCommand(cmd,param);
}
status_tOMXNodeInstance:
:
sendCommand(cmd,param)
{
OMX_SendCommand(mHandle,cmd,param,NULL);
}
(3) 其他作用在OMX元件的指令
其他作用在OMX元件的指令也和OMX_SendCommand的callpath一樣,請見下表:
OMXCodec
OMX
OMXNodeInstance
useBuffer
useBuffer(OMX_UseBuffer)
getParameter
getParameter(OMX_GetParameter)
fillBuffer
fillBuffer(OMX_FillThisBuffer)
emptyBuffer
emptyBuffer(OMX_EmptyThisBuffer)
(4)CallbackFunctions
OMX_CALLBACKTYPEOMXNodeInstance:
:
kCallbacks=
{
&OnEvent,<---------------omx_message:
:
EVENT
&OnEmptyBufferDone,<-----omx_message:
:
EMPTY_BUFFER_DONE
&OnFillBufferDone<-------omx_message:
:
FILL_BUFFER_DONE
}
stagefright框架(三)-選擇VideoDecoder
转载学习2011-03-2219:
42:
51阅读75评论0 字号:
大中小 订阅
在《Stagefright
(1)–VideoPlayback的流程》中,我們並沒有詳述Stagefright是如何根據影片檔的類型來選擇適合的videodecoder,現在,就讓我們來看一看。
(1)Videodecoder是在onPrepareAsyncEvent中的initVideoDecoder被決定的
OMXCodec:
:
Create()會回傳videodecoder給mVideoSource。
status_tAwesomePlayer:
:
initVideoDecoder()
{
mVideoSource=OMXCodec:
:
Create(mClient.interface(),
mVideoTrack->getFormat(),
false,
mVideoTrack);
}
sp
:
Create(&omx,&meta,createEncoder,&source,matchComponentName)
{
meta->findCString(kKeyMIMEType,&mime);
findMatchingCodecs(mime,...,&matchingCodecs);........
(2)
for(size_ti=0;i { componentName=matchingCodecs[i].string(); softwareCodec= InstantiateSoftwareCodec(componentName,...);.....(3) if(softwareCodec! =NULL)returnsoftwareCodec; err=omx->allocateNode(componentName,...,&node);...(4) if(err==OK) { codec=newOMXCodec(...,componentName,...);......(5) returncodec; } } } (2)根據mVideoTrack的MIME從kDecoderInfo挑出合適的components voidOMXCodec: : findMatchingCodecs(mime,...,matchingCodecs) { for(intindex=0;;++index) { componentName=GetCodec( kDecoderInfo, sizeof(kDecoderInfo)/sizeof(kDecoderInfo[0]), mime, index); matchingCodecs->push(String8(componentName)); } } staticconstCodecInfokDecoderInfo[]= { ... {MEDIA_MIMETYPE_VIDEO_MPEG4,"OMX.qcom.video.decoder.mpeg4"}, {MEDIA_MIMETYPE_VIDEO_MPEG4,"OMX.TI.Video.Decoder"}, {MEDIA_MIMETYPE_VIDEO_MPEG4,"M4vH263Decoder"}, ... } GetCodec會依據mime從kDecoderInfo挑出所有的componentname,然後存到matchingCodecs中。 (3)根據matchingCodecs中component的順序,我們會先去檢查其是否為softwaredecoder staticsp { FactoryInfokFactoryInfo[]= { ... FACTORY_REF(M4vH263Decoder) ... }; for(i=0;i { if(! strcmp(name,kFactoryInfo[i].name)) return(*kFactoryInfo[i].CreateFunc)(source); } } 所有的softwaredecoder都會被列在kFactoryInfo中,我們藉由傳進來的name來對應到適合的decoder。 (4)如果該component不是softwaredecoder,則試著去配置對應的OMXcomponent status_tOMX: : allocateNode(name,...,node) { mMaster->makeComponentInstance( name, &OMXNodeInstance: : kCallbacks, instance, handle); } OMX_ERRORTYPEOMXMaster: : makeComponentInstance(name,...) { plugin->makeComponentInstance(name,...); } OMX_ERRORTYPEOMXPVCodecsPlugin: : makeComponentInstance(name,...) { returnOMX_MasterGetHandle(...,name,...); } OMX_ERRORTYPEOMX_MasterGetHandle(...) { returnOMX_GetHandle(...); } (5)若該component為OMXdeocder,則回傳;否則繼續檢查下一個component stagefright框架(四)-VideoBuffer傳輸流程 转载学习2011-03-2219: 44: 07阅读67评论0 字号: 大中小 订阅 這篇文章將介紹Stagefright中是如何和OMXvideodecoder傳遞buffer。 (1)OMXCodec會在一開始的時候透過read函式來傳送未解碼的data給decoder,並且要求decoder將解碼後的data傳回來 status_tOMXCodec: : read(...) { if(mInitialBufferSubmit) { mInitialBufferSubmit=false; drainInputBuffers();<-----OMX_EmptyThisBuffer fillOutputBuffers();<-----OMX_FillThisBuffer } ... } voidOMXCodec: : drainInputBuffers() { Vector for(i=0;i { drainInputBuffer(&buffers->editItemAt(i)); } } voidOMXCodec: : drainInputBuffer(BufferInfo*info) { mOMX->emptyBuffer(...); } voidOMXCodec: : fillOutputBuffers() { Vector for(i=0;i { fillOutputBuffer(&buffers->editItemAt(i)); } } voidOMXCodec: : fillOutputBuffer(BufferInfo*info) { mOMX->fillBuffer(...); } (2)Decoder從inputport讀取資料後,開始進行解碼,並且回傳EmptyBufferDone通知OMXCodec voidOMXCodec: : on_messag
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- stagefright 框架 20