[Android6.0] StageFright解码流程小结
2016-10-14 17:21
429 查看
Platform: RK3288
OS: Android 6.0
Kernel: 3.10.92
以Gallery播放视频为例(只关注MediaPlayer相关部分):
rk用的是ffplayer,但是没有开源,所以这里就以stagefright为例了解解码流程.
创建:
onCreate -> MovieActivity.java
mPlayer = new MoviePlayer -> MoviePlayer.java
mVideoView = (VideoView) rootView.findViewById ->
VideoView -> VideoView.java
initVideoView
mVideoView.setVideoURI(mUri)
setVideoURI -> //VideoView.java
openVideo ->
mMediaPlayer = new MediaPlayer ->
MediaPlayer -> MediaPlayer.java
native_setup ->
android_media_MediaPlayer_native_setup -> android_media_MediaPlayer.cpp
new MediaPlayer ->
MediaPlayer::MediaPlayer mediaplayer.cpp
AudioSystem::acquireAudioSessionId //获取AudioFlinger.
mMediaPlayer.setDataSource ->
_setDataSource ->
android_media_MediaPlayer_setDataSourceFD -> android_media_MediaPlayer.cpp
getMediaPlayer
mp->setDataSource ->
MediaPlayer::setDataSource ->
service->create
MediaPlayerService::create ->
new Client
player->setDataSource ->
MediaPlayerService::Client::setDataSource ->
MediaPlayerFactory::getPlayerType //根据当前的文件格式类型来确定应该使用哪个player
setDataSource_pre -> //返回对应的player.
createPlayer ->
MediaPlayerFactory::createPlayer ->
factory = sFactoryMap.valueFor //根据之前在MediaPlayerService中注册的player来选择一个对应type.
factory->createPlayer //对应player的调用,假设这里是stagefrightplayer.
new StagefrightPlayer ->
new AwesomePlayer //真正实现的是AwesomePlayer
new AudioOutput //创建audio输出
attachNewPlayer
mMediaPlayer.setDisplay -> //设置对应surface.
_setVideoSurface
updateSurfaceScreenOn
mMediaPlayer.setAudioStreamType //tpye是STREAM_MUSIC
点击屏幕播放:
onKeyDown -> MovieActivity.java
mPlayer.onKeyDown
onKeyDown -> MoviePlayer.java
playVideo ->
mVideoView.start ->
start -> VideoView.java
mMediaPlayer.start ->
_start -> MediaPlayer.java
android_media_MediaPlayer_start -> android_media_MediaPlayer.cpp
mp->start
MediaPlayer::start -> mediaplayer.cpp
mPlayer->setVolume
mPlayer->start ->
MediaPlayerService::Client::start ->
p->start -> //当前对应的是StagefrightPlayer
StagefrightPlayer::start -> StagefrightPlayer.cpp
mPlayer->play -> //AwesomePlayer去实现
AwesomePlayer::play -> AwesomePlayer.cpp
AwesomePlayer::play_l ->
prepare_l ->
prepareAsync_l ->
mQueue.postEvent -> //event: mAsyncPrepareEvent
AwesomePlayer::onPrepareAsyncEvent ->
beginPrepareAsync_l ->
finishSetDataSource_l ->
DataSource::CreateFromURI ->
new FileSource
MediaExtractor::Create -> //根据播放type来选择相应的Extractor,用来将视频和音频分离.
new MPEG4Extractor
setDataSource_l -> //设定上面的extractor为track.
setVideoSource
setAudioSource
initVideoDecoder ->
mVideoSource = OMXCodec::Create -> //得到video source.
findMatchingCodecs -> OMXCodec.cpp,codecs在mediaplayerservice初始化,比如获得的codec名是OMX.rk.video_encoder.avc
MediaCodecList::getInstance ->
service->getCodecList ->
MediaPlayerService::getCodecList ->
MediaCodecList::getLocalInstance ->
new MediaCodecList ->
parseTopLevelXMLFile // /etc/media_codecs.xml
parseTopLevelXMLFile // /etc/media_codecs_performance.xml
info->getCodecName //获取codec name
matchingCodecs->add //有可能有多个,比如hw/sw都支持解码,依次添加进去.
这里有个函数IsSoftwareCodec(),通过实现可以知道是否是hw codec可以通过前缀来区分.
InstantiateSoftwareCodec //目前只支持匹配RkAudioDecoder或者FLACDecoder,不匹配就继续往下走
omx->allocateNode -> //omx是OMXClient::connect中初始化的,指向的是mps里的OMX
OMX::allocateNode -> OMX.cpp
mMaster->makeComponentInstance //mMaster在OMX初始化的时候new的,指向OMXMaster
OMXMaster::makeComponentInstance -> OMXMaster.cpp
plugin->makeComponentInstance //plugin在OMXMaster初始化是new的,是SoftOMXPlugin
SoftOMXPlugin::makeComponentInstance -> //看看sw的codec有没有符合的,支持的codec全部在kComponents数组中
new OMXCodec
codec->configureCodec ->
OMXCodec::configureCodec ->
setVideoOutputFormat
initNativeWindow //关联window
mVideoSource->start ->
OMXCodec::start ->
mSource->start -> //mSource是mVideoTrack,最终指向MPEG4Source
MPEG4Source::start ->
new MediaBufferGroup //分配buffer
mGroup->add_buffer //new MediaBuffer
initAudioDecoder //获取audio decoder,流程和上面的initVideoDecoder基本上一样,只是因为mime不同因此得到的decoder不同.
finishAsyncPrepare_l ->
mPreparedCondition.broadcast //AwesomePlayer的prepare_l()等待返回准备执行start()
createAudioPlayer_l ->
new AudioPlayer
mAudioPlayer->setSource
postVideoEvent_l ->
mQueue.postEventWithDelay ->
AwesomePlayer::onVideoEvent ->
initRenderer_l //初始化 mVideoRenderer为new AwesomeNativeWindowRenderer
mVideoSource->read -> //取原始的压缩数据
OMXCodec::read ->
drainInputBuffers ->
drainInputBuffer ->
mSource->read ->
MPEG4Source::read ->
mDataSource->readAt //从之前解析出来的datasoure中读取
fillOutputBuffers ->
OMXCodec::fillOutputBuffer ->
mOMX->fillBuffer ->
OMX::fillBuffer ->
OMXNodeInstance::fillBuffer ->
OMX_FillThisBuffer -> //参数handle和node关联,在OMX::allocateNode()赋值,指向了当前使用的decoder,所以硬件解码器相关的库了.
waitForBufferFilled_l
mVideoRenderer->render -> //mVideoRenderer指向AwesomeNativeWindowRenderer
render -> AwesomePlayer.cpp
mNativeWindow->queueBuffer //其实就是显示了!
OS: Android 6.0
Kernel: 3.10.92
以Gallery播放视频为例(只关注MediaPlayer相关部分):
rk用的是ffplayer,但是没有开源,所以这里就以stagefright为例了解解码流程.
创建:
onCreate -> MovieActivity.java
mPlayer = new MoviePlayer -> MoviePlayer.java
mVideoView = (VideoView) rootView.findViewById ->
VideoView -> VideoView.java
initVideoView
mVideoView.setVideoURI(mUri)
setVideoURI -> //VideoView.java
openVideo ->
mMediaPlayer = new MediaPlayer ->
MediaPlayer -> MediaPlayer.java
native_setup ->
android_media_MediaPlayer_native_setup -> android_media_MediaPlayer.cpp
new MediaPlayer ->
MediaPlayer::MediaPlayer mediaplayer.cpp
AudioSystem::acquireAudioSessionId //获取AudioFlinger.
mMediaPlayer.setDataSource ->
_setDataSource ->
android_media_MediaPlayer_setDataSourceFD -> android_media_MediaPlayer.cpp
getMediaPlayer
mp->setDataSource ->
MediaPlayer::setDataSource ->
service->create
MediaPlayerService::create ->
new Client
player->setDataSource ->
MediaPlayerService::Client::setDataSource ->
MediaPlayerFactory::getPlayerType //根据当前的文件格式类型来确定应该使用哪个player
setDataSource_pre -> //返回对应的player.
createPlayer ->
MediaPlayerFactory::createPlayer ->
factory = sFactoryMap.valueFor //根据之前在MediaPlayerService中注册的player来选择一个对应type.
factory->createPlayer //对应player的调用,假设这里是stagefrightplayer.
new StagefrightPlayer ->
new AwesomePlayer //真正实现的是AwesomePlayer
new AudioOutput //创建audio输出
attachNewPlayer
mMediaPlayer.setDisplay -> //设置对应surface.
_setVideoSurface
updateSurfaceScreenOn
mMediaPlayer.setAudioStreamType //tpye是STREAM_MUSIC
点击屏幕播放:
onKeyDown -> MovieActivity.java
mPlayer.onKeyDown
onKeyDown -> MoviePlayer.java
playVideo ->
mVideoView.start ->
start -> VideoView.java
mMediaPlayer.start ->
_start -> MediaPlayer.java
android_media_MediaPlayer_start -> android_media_MediaPlayer.cpp
mp->start
MediaPlayer::start -> mediaplayer.cpp
mPlayer->setVolume
mPlayer->start ->
MediaPlayerService::Client::start ->
p->start -> //当前对应的是StagefrightPlayer
StagefrightPlayer::start -> StagefrightPlayer.cpp
mPlayer->play -> //AwesomePlayer去实现
AwesomePlayer::play -> AwesomePlayer.cpp
AwesomePlayer::play_l ->
prepare_l ->
prepareAsync_l ->
mQueue.postEvent -> //event: mAsyncPrepareEvent
AwesomePlayer::onPrepareAsyncEvent ->
beginPrepareAsync_l ->
finishSetDataSource_l ->
DataSource::CreateFromURI ->
new FileSource
MediaExtractor::Create -> //根据播放type来选择相应的Extractor,用来将视频和音频分离.
new MPEG4Extractor
setDataSource_l -> //设定上面的extractor为track.
setVideoSource
setAudioSource
initVideoDecoder ->
mVideoSource = OMXCodec::Create -> //得到video source.
findMatchingCodecs -> OMXCodec.cpp,codecs在mediaplayerservice初始化,比如获得的codec名是OMX.rk.video_encoder.avc
MediaCodecList::getInstance ->
service->getCodecList ->
MediaPlayerService::getCodecList ->
MediaCodecList::getLocalInstance ->
new MediaCodecList ->
parseTopLevelXMLFile // /etc/media_codecs.xml
parseTopLevelXMLFile // /etc/media_codecs_performance.xml
info->getCodecName //获取codec name
matchingCodecs->add //有可能有多个,比如hw/sw都支持解码,依次添加进去.
这里有个函数IsSoftwareCodec(),通过实现可以知道是否是hw codec可以通过前缀来区分.
InstantiateSoftwareCodec //目前只支持匹配RkAudioDecoder或者FLACDecoder,不匹配就继续往下走
omx->allocateNode -> //omx是OMXClient::connect中初始化的,指向的是mps里的OMX
OMX::allocateNode -> OMX.cpp
mMaster->makeComponentInstance //mMaster在OMX初始化的时候new的,指向OMXMaster
OMXMaster::makeComponentInstance -> OMXMaster.cpp
plugin->makeComponentInstance //plugin在OMXMaster初始化是new的,是SoftOMXPlugin
SoftOMXPlugin::makeComponentInstance -> //看看sw的codec有没有符合的,支持的codec全部在kComponents数组中
new OMXCodec
codec->configureCodec ->
OMXCodec::configureCodec ->
setVideoOutputFormat
initNativeWindow //关联window
mVideoSource->start ->
OMXCodec::start ->
mSource->start -> //mSource是mVideoTrack,最终指向MPEG4Source
MPEG4Source::start ->
new MediaBufferGroup //分配buffer
mGroup->add_buffer //new MediaBuffer
initAudioDecoder //获取audio decoder,流程和上面的initVideoDecoder基本上一样,只是因为mime不同因此得到的decoder不同.
finishAsyncPrepare_l ->
mPreparedCondition.broadcast //AwesomePlayer的prepare_l()等待返回准备执行start()
createAudioPlayer_l ->
new AudioPlayer
mAudioPlayer->setSource
postVideoEvent_l ->
mQueue.postEventWithDelay ->
AwesomePlayer::onVideoEvent ->
initRenderer_l //初始化 mVideoRenderer为new AwesomeNativeWindowRenderer
mVideoSource->read -> //取原始的压缩数据
OMXCodec::read ->
drainInputBuffers ->
drainInputBuffer ->
mSource->read ->
MPEG4Source::read ->
mDataSource->readAt //从之前解析出来的datasoure中读取
fillOutputBuffers ->
OMXCodec::fillOutputBuffer ->
mOMX->fillBuffer ->
OMX::fillBuffer ->
OMXNodeInstance::fillBuffer ->
OMX_FillThisBuffer -> //参数handle和node关联,在OMX::allocateNode()赋值,指向了当前使用的decoder,所以硬件解码器相关的库了.
waitForBufferFilled_l
mVideoRenderer->render -> //mVideoRenderer指向AwesomeNativeWindowRenderer
render -> AwesomePlayer.cpp
mNativeWindow->queueBuffer //其实就是显示了!
相关文章推荐
- [RK3288][Android6.0] StageFright解码流程小结
- [RK3288][Android6.0] 开机播放音乐流程小结
- [RK3288][Android6.0] 网络服务Netd初始化流程小结
- [RK3288][Android6.0] WiFi在Settings中的热点开启流程小结
- [RK3288][Android6.0] PWM backlight 驱动流程小结
- [RK3288][Android6.0] ION 驱动流程小结
- [RK3288][Android6.0] Camera HAL层拍照编码成JPEG流程小结
- [RK3288][Android6.0] DDR Frequency控制流程小结
- [RK3288][Android6.0] USB WiFi驱动流程小结
- [RK3288][Android6.0] Wifi Service初始化流程小结
- [RK3288][Android6.0] U-boot 启动流程小结
- [RK3288][Android6.0] Display驱动初始化流程小结
- [RK3288][Android6.0] U-boot显示模块部分流程小结
- [RK3288][Android6.0] Audio录音frame rate设置流程小结
- [RK3288][Android6.0] Camera HAL流程小结
- [RK3288][Android6.0] TS-ADC驱动流程小结【转】
- [RK3288][Android6.0] Camera HAL流程小结
- [RK3288][Android6.0] USB Mass Storage流程小结
- [RK3288][Android6.0] U-boot 启动流程小结【转】
- [RK3288][Android6.0] Audio的音量设置流程小结