android5.0 音乐播放,加载extractor

来源:互联网 发布:淘宝论文修改多少钱 编辑:程序博客网 时间:2024/06/05 23:08

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了。






0 0