android5.0和以前的版本有变动,音乐播放不在走awesomeplay,audiotrack了;现在走nuplayerdriver,nuplayer,nuplayerrender。
音乐播放:
1。mediaplay
status_t MediaPlayer::prepare()
{
status_t ret = prepareAsync_l();
}
status_t MediaPlayer::prepareAsync_l()
{
return mPlayer->prepareAsync();
}
mplayer就是nuplayerdriver了,不在是awesome了。这是5.0的改动。
2.NuplayerDriver
status_t NuPlayerDriver::prepareAsync() {
switch (mState) {
case STATE_UNPREPARED:
mState = STATE_PREPARING;
mIsAsyncPrepare = true;
mPlayer->prepareAsync();
return OK;
}
这里是准备阶段,刚开始准备,所示state是STATE_UNPREPARED。
可以看到mPlayer的定义: sp<NuPlayer> mPlayer;,即上面调用了Nuplayer。
3.Nuplayer
void NuPlayer::prepareAsync() {
(new AMessage(kWhatPrepare, id()))->post();
}
这是发送消息:kWhatPrepare。
在这个文件里有消息接受处理函数。
void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatPrepare:
{
mSource->prepareAsync();
break;
}
}
这里调用mSource的prepareAsync函数,但是mSource是谁呢?
还是在这个文件里面,我们来看一下代码:
void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID);
status_t err = source->setDataSource(fd, offset, length);
if (err != OK) {
ALOGE("Failed to set data source!");
source = NULL;
}
msg->setObject("source", source);
msg->post();
}
是 GenericSource,也就是调用到了 GenericSource的prepareAsync函数。
4.GenericSource
void NuPlayer::GenericSource::prepareAsync() {
if (mLooper == NULL) {
mLooper = new ALooper;
mLooper->setName("generic");
mLooper->start();
mLooper->registerHandler(this);
}
sp<AMessage> msg = new AMessage(kWhatPrepareAsync, id());
msg->post();
}
这里还是消息机制,发送一个kWhatPrepareAsync消息。
那么发送消息了,必然有接受消息的,在这个文件中,如下函数:
void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatPrepareAsync:
{
onPrepareAsync();
break;
}
}
调用了onPrepareAsync函数。我也觉得很烦,为什么不知接调用,要这么麻烦的不断采用消息机制,理解了的TX帮忙解释下吧。
void NuPlayer::GenericSource::onPrepareAsync() {
。。。。。。。。
else {
// set to false first, if the extractor
// comes back as secure, set it to true then.
mIsWidevine = false;
mDataSource = new FileSource(mFd, mOffset, mLength);
}
。。。。
// init extrator from data source
err = initFromDataSource();
}
这里,initFromDataSource就是去extractor了。
status_t NuPlayer::GenericSource::initFromDataSource() {
sp<MediaExtractor> extractor;
。。。。。
else {
extractor = MediaExtractor::Create(mDataSource,
mSniffedMIME.empty() ? NULL:
}
。。。
}
5.MediaExtractor
进入到MediaExtractor.cpp
sp<MediaExtractor> MediaExtractor::Create(
const sp<DataSource> &source, const char *mime) {
。。。
mime = tmp.string();
。。。
//拿到音频文件的格式,放到mime里。
MediaExtractor *ret = NULL;
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
|| !strcasecmp(mime, "audio/mp4")) {
ret = new MPEG4Extractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) ||
!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_BP3)) {ALOGD("shitao.li----mp3extroctor");
ret = new MP3Extractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR)) {
ret = new AMRExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
ret = new FLACExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV) ||
!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV2)) {
ret = new WAVExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG) ||
!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG2)) {
ret = new OggExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA) ||
!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WEBM)) {
ret = new MatroskaExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
ret = new MPEG2TSExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_AVI) ||
!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MSVIDEO)) {
ret = new AVIExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
// Return now. WVExtractor should not have the DrmFlag set in the block below.
return new WVMExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS) ||
!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC2)) {
ret = new AACExtractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
ret = new MPEG2PSExtractor(source);
} else {
if (isDrm) {
ret = new MPEG4Extractor(source);
}
}
。。。。。。
}
使用mime得到的类型和提供的类型作对比,就找到队形的extroctor了。