[RK3288][Android6.0] StageFright解码流程小结

原址

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    //其实就是显示了!

猜你喜欢

转载自blog.csdn.net/u010164190/article/details/82152255