注:代码中的注释我是用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流程图
先来看看流程图
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;