首先在每次MediaPlayer调用create创建的时候,会调用一次prepare,这个时候会走入NuPlayerDriver::prepareAsync中的STATE_UNPREPARED,之后会先调用stop一下,从而将NuPlayer播放器的状态切换为STATE_STOPPED
态,之后再次调用prepare进入NuPlayerDriver::prepareAsync的STATE_STOPPED流程
第二次在prepareAsync调用中
status_t NuPlayerDriver::prepareAsync() {
ALOGV("prepareAsync(%p)", this);
Mutex::Autolock autoLock(mLock);
switch (mState) {
case STATE_UNPREPARED:
mState = STATE_PREPARING;
mIsAsyncPrepare = true;
mPlayer->prepareAsync();
return OK;
case STATE_STOPPED:
// this is really just paused. handle as seek to start
mAtEOS = false;
mState = STATE_STOPPED_AND_PREPARING;
mIsAsyncPrepare = true;
mPlayer->seekToAsync(0, true /* needNotify */);
return OK;
default:
return INVALID_OPERATION;
};
}
这里会将播放器的seek调整到0,同时播放器的状态切换为STATE_STOPPED_AND_PREPARING
void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
android::CallStack cs("JON");
sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("seekTimeUs", seekTimeUs);
msg->setInt32("needNotify", needNotify);
msg->post();
}
消息发往NuPlayerDriver在构造的时候开启的线程"NuPlayerDriver Looper"
void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
...
case kWhatSeek:
onStart(seekTimeUs);
...
}
void NuPlayer::onStart(int64_t startPositionUs) {
...
postScanSources();
...
}
...
void NuPlayer::postScanSources() {
if (mScanSourcesPending) {
return;
}
sp<AMessage> msg = new AMessage(kWhatScanSources, this);
msg->setInt32("generation", mScanSourcesGeneration);
msg->post();
mScanSourcesPending = true;
}
消息继续发往子线程处理
void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatScanSources:
{
if (mAudioSink != NULL && mAudioDecoder == NULL) {
if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
rescan = true;
}
}
...
}
}
...
status_t NuPlayer::instantiateDecoder(
bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
if (audio) {
...
这里是关键
if (checkAudioModeChange) {
determineAudioModeChange(format);
}
if (mOffloadAudio) {
const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
format->setInt32("has-video", hasVideo);
*decoder = AVNuFactory::get()->createPassThruDecoder(notify, mSource, mRenderer);
} else {
AVNuUtils::get()->setCodecOutputFormat(format);
mSource->setOffloadAudio(false /* offload */);
*decoder = AVNuFactory::get()->createDecoder(notify, mSource, mPID, mRenderer);
}
...
}
如上会完成2件重要的事情,一个是调用determineAudioModeChange
完成AudioTrack的创建,另外就是创建音频的decoder,我们当前只关注AudioTrack的创建
void NuPlayer::determineAudioModeChange(const sp<AMessage> &audioFormat) {
...
走offload模式
if (canOffload) {
tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
}
....
}
void NuPlayer::tryOpenAudioSinkForOffload(
const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
// Note: This is called early in NuPlayer to determine whether offloading
// is possible; otherwise the decoders call the renderer openAudioSink directly.
status_t err = mRenderer->openAudioSink(
format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
if (err != OK) {
// Any failure we turn off mOffloadAudio.
mOffloadAudio = false;
} else if (mOffloadAudio) {
sendMetaDataToHal(mAudioSink, audioMeta);
}
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerRenderer.cpp
status_t NuPlayer::Renderer::openAudioSink(
const sp<AMessage> &format,
bool offloadOnly,
bool hasVideo,
uint32_t flags,
bool *isOffloaded,
bool isStreaming) {
sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this);
msg->setMessage("format", format);
msg->setInt32("offload-only", offloadOnly);
msg->setInt32("has-video", hasVideo);
msg->setInt32("flags", flags);
msg->setInt32("isStreaming", isStreaming);
sp<AMessage> response;
status_t postStatus = msg->postAndAwaitResponse(&response);
...
}
如上消息发往Renderer的子线程NuPlayerRenderer
处理,之后调用onOpenAudioSink
status_t NuPlayer::Renderer::onOpenAudioSink(
const sp<AMessage> &format,
bool offloadOnly,
bool hasVideo,
uint32_t flags,
bool isStreaming) {
...
err = mAudioSink->open(
sampleRate,
numChannels,
(audio_channel_mask_t)channelMask,
audioFormat,
0 /* bufferCount - unused */,
&NuPlayer::Renderer::AudioSinkCallback,
this,
(audio_output_flags_t)offloadFlags,
&offloadInfo);
...
err = mAudioSink->start();
...
}
这里的mAudioSink在Audio播放流程(二)—NuPlayer流程之setDataSource中的setDataSource_pre有完成设置,指向的是MediaPlayerService中的AudioOutput
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::AudioOutput::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
AudioCallback cb, void *cookie,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo,
bool doNotReconnect,
uint32_t suggestedFrameCount)
{
...
t = new AudioTrack(
mStreamType,
sampleRate,
format,
channelMask,
frameCount,
flags,
NULL, // callback
NULL, // user data
0, // notification frames
mSessionId,
AudioTrack::TRANSFER_DEFAULT,
NULL, // offload info
mUid,
mPid,
mAttributes,
doNotReconnect,
targetSpeed);
t->setVolume(mLeftVolume, mRightVolume);
mTrack = t;
...
}
如上完成了AudioTrack的创建