您的位置:首页 > 移动开发 > Android开发

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

2016-09-21 17:17 615 查看
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    //其实就是显示了!

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: