现在的位置: 首页 > 综合 > 正文

stagefright框架解读(—)音视频Playback流程(二)

2013年08月25日 ⁄ 综合 ⁄ 共 3094字 ⁄ 字号 评论关闭

5.将解析后的音视频数据分别交给VideoTrack和AudioTrack:

void AwesomePlayer::setVideoSource(sp<MediaSource> source) {
    CHECK(source != NULL);

    if (mPrefetcher != NULL) {
        source = mPrefetcher->addSource(source);
    }

    mVideoTrack = source;
}

void AwesomePlayer::setAudioSource(sp<MediaSource> source) {
    CHECK(source != NULL);

    if (mPrefetcher != NULL) {
        source = mPrefetcher->addSource(source);
    }

    mAudioTrack = source;
}

6.根据mVideoTrck中的编码类型来选择 video decoder 同理根据mAudioTrack中的编码类型来选择 audio decoder:

status_t AwesomePlayer::initVideoDecoder() {
    mVideoSource = OMXCodec::Create(
            mClient.interface(), mVideoTrack->getFormat(),
            false, // createEncoder
            mVideoTrack);

    if (mVideoSource != NULL) {
        int64_t durationUs;
        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
            Mutex::Autolock autoLock(mMiscStateLock);
            if (mDurationUs < 0 || durationUs > mDurationUs) {
                mDurationUs = durationUs;
            }
        }

        CHECK(mVideoTrack->getFormat()->findInt32(kKeyWidth, &mVideoWidth));
        CHECK(mVideoTrack->getFormat()->findInt32(kKeyHeight, &mVideoHeight));

        status_t err = mVideoSource->start();

        if (err != OK) {
            mVideoSource.clear();
            return err;
        }
    }

    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
}


6.将mVideoEvent放入mQueue中,开始解码播放,并交由mvideoRenderer来画出   audio的数据则交由audioplayer来管理,它最终将解码的数据交给audioTrack并由audioTrack和audioFlinger进行交互,最终将数据交给audio hal层,这个我们以后会做讲解:

status_t AwesomePlayer::play() {
    Mutex::Autolock autoLock(mLock);
    return play_l();
}
status_t AwesomePlayer::play_l() {
    if (mFlags & PLAYING) {
        return OK;
    }

    if (!(mFlags & PREPARED)) {
        status_t err = prepare_l();

        if (err != OK) {
            return err;
        }
    }

    mFlags |= PLAYING;
    mFlags |= FIRST_FRAME;

    bool deferredAudioSeek = false;

    if (mAudioSource != NULL) {
        if (mAudioPlayer == NULL) {
            if (mAudioSink != NULL) {
                //音频数据由audioplayer进行管理
                mAudioPlayer = new AudioPlayer(mAudioSink);
                mAudioPlayer->setSource(mAudioSource);

                // We've already started the MediaSource in order to enable
                // the prefetcher to read its data.
                  //调用audioPlayer的start方法则是调用audioSource对数据进行解码
                   //并将解码似得数据最终交给audioTrack,并调用audioTrack的start方法与audioFlinger进行交互
                   status_t err = mAudioPlayer->start(
                        true /* sourceAlreadyStarted */);

                if (err != OK) {
                    delete mAudioPlayer;
                    mAudioPlayer = NULL;

                    mFlags &= ~(PLAYING | FIRST_FRAME);

                    return err;
                }

                delete mTimeSource;
                mTimeSource = mAudioPlayer;

                deferredAudioSeek = true;

                mWatchForAudioSeekComplete = false;
                mWatchForAudioEOS = true;
            }
        } else {
            mAudioPlayer->resume();
        }

        postCheckAudioStatusEvent_l();
    }

    if (mTimeSource == NULL && mAudioPlayer == NULL) {
        mTimeSource = new SystemTimeSource;
    }

    if (mVideoSource != NULL) {
        // Kick off video playback
        //将mVideoEvent放入queue中
          postVideoEvent_l();
    }

    if (deferredAudioSeek) {
        // If there was a seek request while we were paused
        // and we're just starting up again, honor the request now.
        seekAudioIfNecessary_l();
    }

    if (mFlags & AT_EOS) {
        // Legacy behaviour, if a stream finishes playing and then
        // is started again, we play from the start...
        seekTo_l(0);
    }

    if (mDecryptHandle != NULL) {
        int64_t position;
        getPosition(&position);
        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
                Playback::START, position / 1000);
    }

    return OK;
}

 void AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
    if (mVideoEventPending) {
        return;
    }

    mVideoEventPending = true;
    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
}

void AwesomePlayer::onVideoEvent()
{
  mVideoSource->read(&mVideoBuffer, &options);
  mVideoRenderer->render(mVideoBuffer);

  postVideoEvent_l();
}

抱歉!评论已关闭.