video/audio playback:prepare & start

来源:互联网 发布:网络媒介公司 编辑:程序博客网 时间:2024/05/22 01:41

prepare:启动mQueue,对http://rtsp://gtalk/fmradio://rx之类的url进行mAudioTrack/mVideoTrack分离,并根据mAudioTrack/mVideoTrack编码类型选择相应的decode

1.framework/base/media/libmediaplayerservice/MediaPlayerService.cpp

status_t MediaPlayerService::Client::prepareAsync()

{….

 sp<MediaPlayerBase> p = getPlayer(); ……..  setDataSource时创建的stagefrightplayer                          

    if (p == 0) return UNKNOWN_ERROR;

    status_t ret = p->prepareAsync();

……

    return ret;

}

2.framework/base/media/libmediaplayerservice/stagefrightplayer

status_t StagefrightPlayer::prepareAsync() {

    return mPlayer->prepareAsync();…………mPlayer--->AwesomePlayer

}

3:framework/base/media/libstagefright/awesomePlayer

status_t AwesomePlayer::prepareAsync() {

…….

    return prepareAsync_l();

}

启动mQueueonPrepareAsyncEvent被触发

status_t AwesomePlayer::prepareAsync_l() {……

    if (!mQueueStarted) {

        mQueue.start();

        mQueueStarted = true;

    }

….

    mAsyncPrepareEvent = new AwesomeEvent(

           this, &AwesomePlayer::onPrepareAsyncEvent);

   mQueue.postEvent(mAsyncPrepareEvent);

    return OK;

}

 

void AwesomePlayer::onPrepareAsyncEvent() {

….

    if (mUri.size() > 0) {

        status_t err = finishSetDataSource_l();………….http://之类的url进行mAudioTrack/mVideoTrack分离

    if (mVideoTrack != NULL && mVideoSource == NULL) {

       status_t err = initVideoDecoder();……………………decode video

    }

 

    if (mAudioTrack != NULL && mAudioSource == NULL) {

       status_t err = initAudioDecoder();…………………….decode audio

           return;

        }

    }

    if (mCachedSource != NULL || mRTSPController != NULL) {

        postBufferingEvent_l();………………..触发mBufferingEvent,对应的实现在void                   AwesomePlayer::onBufferingUpdate()

    }

}

 

start:解码并播放

1,framework/base/media/libmedia/mediaPlayer.cpp

status_t MediaPlayer::start()

{……

    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |

                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {

        mPlayer->setLooping(mLoop);

        mPlayer->setVolume(mLeftVolume, mRightVolume);

        mPlayer->setAuxEffectSendLevel(mSendLevel);

        mCurrentState = MEDIA_PLAYER_STARTED;

        status_t ret = mPlayer->start();

……….

}

2,framework/base/media/libmediaPlayerService /mediaPlayerService.cpp

status_t MediaPlayerService::Client::start()

{..

    sp<MediaPlayerBase> p = getPlayer();

    p->setLooping(mLoop);

    return p->start();

}

3,framework/base/media/libmediaPlayerService/stagefrightplayer.cpp

 

status_t StagefrightPlayer::start() {

    return mPlayer->play();

}

4,framework/base/media/libstagefright/awesomePlayer.cpp

tatus_t AwesomePlayer::play() {

  ………..

  return play_l();

}

 

status_t AwesomePlayer::play_l() {

……

    if (mVideoSource != NULL) {

        // Kick off video playback

        postVideoEvent_l();……..videoEvent放入mQueue

 

}

开始解码播放,并由mVideoRenderer输出,video playback完成

void AwesomePlayer::onVideoEvent() {……………

            status_t err = mVideoSource->read(&mVideoBuffer[mVideoQueueBack], &options);

……….

    if (mVideoRenderer != NULL) {

        mVideoRenderer->render(mVideoBuffer[mVideoQueueBack]);

    }

…..

    postVideoEvent_l();

}

 

audio playerback

 

1,framework/base/media/libstagefright/awesomePlayer.cpp

status_t AwesomePlayer::play_l() {

    if (mAudioSource != NULL) {

        if (mAudioPlayer == NULL) {

            if (mAudioSink != NULL) {

                mWatchForAudioSeekComplete = false;

                mAudioPlayer = new AudioPlayer(mAudioSink, this);

               mAudioPlayer->setSource(mAudioSource);

…………..

                    }

                }

                status_t err = mAudioPlayer->start(

                       true /* sourceAlreadyStarted */);

………………..

}

2,framework/base/media/libstagefright/audioplayer.cpp

读第一手解析的数据,并开启audio output

status_t AudioPlayer::start(bool sourceAlreadyStarted) {

    if (mAudioSink.get() != NULL) {

        status_t err = mAudioSink->open(

               mSampleRate, numChannels, AudioSystem::PCM_16_BIT,

               DEFAULT_AUDIOSINK_BUFFERCOUNT,

               &AudioPlayer::AudioSinkCallback, this);

……

        mAudioSink->start();

    } else {

        mAudioTrack = new AudioTrack(

               AudioSystem::MUSIC, mSampleRate, AudioSystem::PCM_16_BIT,

               (numChannels == 2)

                   ? AudioSystem::CHANNEL_OUT_STEREO

                   : AudioSystem::CHANNEL_OUT_MONO,

               0, 0, &AudioCallback, this, 0);

….

        mAudioTrack->start();

    }

 

    mStarted = true;

 

    return OK;

}

 

开启audio output 时后把AudioSinkCallback传给它,每当调用callback时,audioplayer都回去decode获取解码后的数据

size_t AudioPlayer::AudioSinkCallback(

        MediaPlayerBase::AudioSink *audioSink,

        void *buffer, size_t size, void *cookie) {

    AudioPlayer *me = (AudioPlayer *)cookie;

 

    return me->fillBuffer(buffer, size);

}

 

size_t AudioPlayer::fillBuffer(void *data, size_t size) {

…..

            err = mSource->read(&mInputBuffer, &options);

…..    

     memcpy((char *)data + size_done,

              (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),

              copy);

…….

 

    return size_done;

}