Android N Audio播放六:如何读取buffer

  注:代码中的注释我是用JaychouNote的字样来备注。
  
  在Android N Audio播放四:start真面目 中我们知道了,在Nuplayer中当onStart方法开始以后,音频就开始播放了. 但似乎我们对如何播放的细节还知之甚少,比如怎么读取的数据,如何创建的解码器等等.
  我们再来看看GenericSource的start方法.
  ./frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp#start
  

void NuPlayer::GenericSource::start() {
    ALOGI("start");

    mStopRead = false;
    if (mAudioTrack.mSource != NULL) {
        ALOGI("start  mAudioTrack.mSource not null");
        //JaychouNote: 调用postReadBuffer把读取buffer的消息post出去
        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
    }

    if (mVideoTrack.mSource != NULL) {
        ALOGI("start  mVideoTrack.mSource not null");
        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
    }

    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
    mStarted = true;

    (new AMessage(kWhatStart, this))->post();
}
01-01 17:17:15.749 I/GenericSource(  700): start
01-01 17:17:15.750 I/GenericSource(  700): start  mAudioTrack.mSource not null

  start在这里通过调用postReadBuffer把读取buffer的消息post出去, 这一篇我们就来讨论一下如何读取的buffer.

1. 读取buffer流程图
  先来看看流程图
  readBuffer

2. 流程详解

在GenericSource的start方法中调用postReadBuffer.
  ./frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp#postReadBuffer
 

void NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
    Mutex::Autolock _l(mReadBufferLock);

    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
        mPendingReadBufferTypes |= (1 << trackType);
        sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
        msg->setInt32("trackType", trackType);
        msg->post();
    }
}

把kWhatReadBuffer消息post出去。在onMessageReceived中接收处理。

  ./frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp#onMessageReceived
 

void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
    ALOGE("GenericSource  onMessageReceived msg is %s", msg->debugString().c_str());
    switch (msg->what()) {
      case kWhatPrepareAsync:
      {
          onPrepareAsync();
          break;
      }
      ......
      case kWhatReadBuffer:
      {
          onReadBuffer(msg);
          break;
      }
      ......
      }
}     
01-01 17:17:15.751 E/GenericSource(  700): GenericSource  onMessageReceived msg is AMessage(what = 0x0000000c, target = 2) = {
01-01 17:17:15.751 E/GenericSource(  700):   int32_t trackType = 2
01-01 17:17:15.751 E/GenericSource(  700): }

这里的what=0x0000000c指的就是kWhatReadBuffer消息。接着就是onReadBuffer

./frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp#onReadBuffer

void NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
    ALOGV("GenericSource onReadBuffer");
    int32_t tmpType;
    CHECK(msg->findInt32("trackType", &tmpType));
    media_track_type trackType = (media_track_type)tmpType;
    //JaychouNote:调用readBuffer
    readBuffer(trackType);
    {
        // only protect the variable change, as readBuffer may
        // take considerable time.
        Mutex::Autolock _l(mReadBufferLock);
        mPendingReadBufferTypes &= ~(1 << trackType);
    }
}
01-01 17:17:15.751 V/GenericSource(  700): GenericSource onReadBuffer

这个方法是调用readBuffer.

./frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp#readBuffer

void NuPlayer::GenericSource::readBuffer(
        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
    ......
    switch (trackType) {
        ......
        //JaychouNote1: 我们是走的audio, 设置最大buffer为64.
        case MEDIA_TRACK_TYPE_AUDIO:
            track = &mAudioTrack;
            if (mIsWidevine) {
                maxBuffers = 8;
            } else if (mIsByteMode) {
                // byte stream mode is enabled only for mp3 & aac
                // and the parser gives a huge chunk of data per read,
                // so reading one buffer is sufficient.
                maxBuffers = 1;
            } else {
                maxBuffers = 64;
            }
            break;
        ......
    }

    const bool couldReadMultiple = (!mIsWidevine && track->mSource->supportReadMultiple());

    if (mIsWidevine || couldReadMultiple) {
        options.setNonBlocking();
    }
    ALOGE("maxBuffers is %zu", maxBuffers);
    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
        Vector<MediaBuffer *> mediaBuffers;
   
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值