在《Stagefright
(1) – Video Playback的流程》中,我們並沒有詳述Stagefright是如何根據影片檔的類型來選擇適合的video
decoder,現在,就讓我們來看一看。
(1) Video decoder是在onPrepareAsyncEvent中的initVideoDecoder被決定的
OMXCodec::Create()會回傳video decoder給mVideoSource。
status_t AwesomePlayer::initVideoDecoder() {
mVideoSource = OMXCodec::Create(mClient.interface(),
mVideoTrack->getFormat(),
false,
mVideoTrack); }
sp<MediaSource> OMXCodec::Create(&omx,
&meta, createEncoder,
&source, matchComponentName) {
meta->findCString(kKeyMIMEType,
&mime);
findMatchingCodecs(mime,
...,
&matchingCodecs);
........
(2)
for (size_t i
= 0; i
< matchingCodecs.size();
++i)
{
componentName = matchingCodecs[i].string();
softwareCodec =
InstantiateSoftwareCodec(componentName,
...);
.....
(3)
if (softwareCodec
!=
NULL) return softwareCodec;
err = omx->allocateNode(componentName,
...,
&node);
...
(4)
if (err
== OK)
{
codec = new OMXCodec(...,
componentName, ...);
......
(5)
return codec;
}
} }
|
(2) 根據mVideoTrack的MIME從kDecoderInfo挑出合適的components
void OMXCodec::findMatchingCodecs(mime,
..., matchingCodecs) {
for (int index
= 0;;
++index)
{
componentName = GetCodec(
kDecoderInfo,
sizeof(kDecoderInfo)/sizeof(kDecoderInfo[0]),
mime,
index);
matchingCodecs->push(String8(componentName));
} }
static const CodecInfo kDecoderInfo[]
= {
...
{ 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挑出所有的component
name,然後存到matchingCodecs中。
(3)
根據matchingCodecs中component的順序,我們會先去檢查其是否為software
decoder
static sp<MediaSource> InstantiateSoftwareCodec(name,
...) {
FactoryInfo kFactoryInfo[]
=
{
...
FACTORY_REF(M4vH263Decoder)
...
};
for (i
= 0; i <
sizeof(kFactoryInfo)/sizeof(kFactoryInfo[0]);
++i)
{
if (!strcmp(name, kFactoryInfo[i].name))
return (*kFactoryInfo[i].CreateFunc)(source);
} }
|
所有的software decoder都會被列在kFactoryInfo中,我們藉由傳進來的name來對應到適合的decoder。
(4)
如果該component不是software
decoder,則試著去配置對應的OMX component
status_t OMX::allocateNode(name,
..., node) {
mMaster->makeComponentInstance(
name,
&OMXNodeInstance::kCallbacks,
instance,
handle); }
OMX_ERRORTYPE OMXMaster::makeComponentInstance(name,
...) {
plugin->makeComponentInstance(name,
...); }
OMX_ERRORTYPE OMXPVCodecsPlugin::makeComponentInstance(name,
...) {
return OMX_MasterGetHandle(..., name,
...); }
OMX_ERRORTYPE OMX_MasterGetHandle(...) {
return OMX_GetHandle(...); }
|
(5)
若該component為OMX
deocder,則回傳;否則繼續檢查下一個component
|
|