StageFright框架流程解讀

峻峰飛陽發表於2016-06-03

1、 StageFright介紹
Android froyo版本多媒體引擎做了變動,新新增了stagefright框架,並且預設情況android選擇stagefright,並沒有完全拋棄opencore,主要是做了一個OMX層,僅僅是對 opencore的omx-component部分做了引用。stagefright是在MediaPlayerService這一層加入的,和opencore是並列的。Stagefright在 Android中是以shared library的形式存在(libstagefright.so),其中的module – AwesomePlayer可用來播放video/audio。 AwesomePlayer提供許多API,可以讓上層的應用程式(Java/JNI)來呼叫。

2、 StageFright資料流封裝
2.1》由資料來源DataSource生成MediaExtractor。通過MediaExtractor::Create(dataSource)來實現。Create方法通過兩步來生成相應的 MediaExtractor(MediaExtractor.cpp):
 通過dataSource->sniff來探測資料型別
 生成相應的Extractor:
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
|| !strcasecmp(mime, “audio/mp4”)) {
return new MPEG4Extractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
return new MP3Extractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
return new AMRExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
return new WAVExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {
return new OggExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {
return new MatroskaExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
return new MPEG2TSExtractor(source);
}

2.2》把音視訊軌道分離,生成mVideoTrack和mAudioTrack兩個MediaSource。程式碼如下(AwesomePlayer.cpp):

if (!haveVideo && !strncasecmp(mime, “video/”, 6)) {
setVideoSource(extractor->getTrack(i));
haveVideo = true;
} else if (!haveAudio && !strncasecmp(mime, “audio/”, 6)) {
setAudioSource(extractor->getTrack(i));
haveAudio = true;
}

2.3》得到的這兩個MediaSource,只具有parser功能,沒有decode功能。還需要對這兩個MediaSource做進一步的包裝,獲取了兩個MediaSource(具有parse和decode功能):

mVideoSource = OMXCodec::Create(
mClient.interface(), mVideoTrack->getFormat(),
false, // createEncoder
mVideoTrack,
NULL, flags);
mAudioSource = OMXCodec::Create(
mClient.interface(), mAudioTrack->getFormat(),
false, // createEncoder
mAudioTrack);
當呼叫MediaSource.start()方法後,它的內部就會開始從資料來源獲取資料並解析,等到緩衝區滿後便停止。在AwesomePlayer裡就可以呼叫MediaSource的read方法讀取解碼後的資料。
 對於mVideoSource來說,讀取的資料:mVideoSource->read(&mVideoBuffer, &options)交給顯示模組進行渲染,mVideoRenderer->render(mVideoBuffer);
 對mAudioSource來說,用mAudioPlayer對mAudioSource進行封裝,然後由mAudioPlayer負責讀取資料和播放控制。

3、 StageFright的Decode
經過“資料流的封裝”得到的兩個MediaSource,其實是兩個OMXCodec。AwesomePlayer和mAudioPlayer都是從MediaSource中得到資料進行播放。AwesomePlayer得到的是最終需要渲染的原始視訊資料,而mAudioPlayer讀取的是最終需要播放的原始音訊資料。也就是說,從OMXCodec中讀到的資料已經是原始資料了。
OMXCodec是怎麼把資料來源經過parse、decode兩步以後轉化成原始資料的。從OMXCodec::Create這個構造方法開始,它的引數:
 IOMX &omx指的是一個OMXNodeInstance物件的例項。
 MetaData &meta這個引數由MediaSource.getFormat獲取得到。這個物件的主要成員就是一個KeyedVector

相關文章