Audio播放流程(四)---MediaPlayerService流程之AudioTrack的创建

首先在每次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的创建

猜你喜欢

转载自blog.csdn.net/zhuyong006/article/details/86246540
今日推荐