153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia/*
253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Copyright (C) 2010 The Android Open Source Project
353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia *
453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Licensed under the Apache License, Version 2.0 (the "License");
553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * you may not use this file except in compliance with the License.
653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * You may obtain a copy of the License at
753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia *
853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia *      http://www.apache.org/licenses/LICENSE-2.0
953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia *
1053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Unless required by applicable law or agreed to in writing, software
1153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * distributed under the License is distributed on an "AS IS" BASIS,
1253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * See the License for the specific language governing permissions and
1453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * limitations under the License.
1553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia */
1653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
1753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia//#define LOG_NDEBUG 0
1853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#define LOG_TAG "NuPlayer2Renderer"
1953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <utils/Log.h>
2053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
2153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include "JWakeLock.h"
2253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include "NuPlayer2Renderer.h"
2353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <algorithm>
2453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <cutils/properties.h>
2553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/foundation/ADebug.h>
2653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/foundation/AMessage.h>
2753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/foundation/AUtils.h>
2853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/MediaClock.h>
2953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/MediaErrors.h>
3053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/Utils.h>
3153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/VideoFrameScheduler.h>
3253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/MediaCodecBuffer.h>
3353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
3453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <inttypes.h>
3553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
3653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jianamespace android {
3753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
3853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia/*
3953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Example of common configuration settings in shell script form
4053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
4153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   #Turn offload audio off (use PCM for Play Music) -- AudioPolicyManager
4253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   adb shell setprop audio.offload.disable 1
4353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
4453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   #Allow offload audio with video (requires offloading to be enabled) -- AudioPolicyManager
4553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   adb shell setprop audio.offload.video 1
4653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
4753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   #Use audio callbacks for PCM data
4853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   adb shell setprop media.stagefright.audio.cbk 1
4953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
5053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   #Use deep buffer for PCM data with video (it is generally enabled for audio-only)
5153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   adb shell setprop media.stagefright.audio.deep 1
5253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
5353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   #Set size of buffers for pcm audio sink in msec (example: 1000 msec)
5453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia   adb shell setprop media.stagefright.audio.sink 1000
5553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
5653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * These configurations take effect for the next track played (not the current track).
5753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia */
5853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
5953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic inline bool getUseAudioCallbackSetting() {
6053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return property_get_bool("media.stagefright.audio.cbk", false /* default_value */);
6153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
6253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
6353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic inline int32_t getAudioSinkPcmMsSetting() {
6453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return property_get_int32(
6553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            "media.stagefright.audio.sink", 500 /* default_value */);
6653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
6753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
6853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
6953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// is closed to allow the audio DSP to power down.
7053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic const int64_t kOffloadPauseMaxUs = 10000000ll;
7153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
7253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// Maximum allowed delay from AudioSink, 1.5 seconds.
7353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic const int64_t kMaxAllowedAudioSinkDelayUs = 1500000ll;
7453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
7553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic const int64_t kMinimumAudioClockUpdatePeriodUs = 20 /* msec */ * 1000;
7653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
7753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// static
7853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaconst NuPlayer2::Renderer::PcmInfo NuPlayer2::Renderer::AUDIO_PCMINFO_INITIALIZER = {
7953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AUDIO_CHANNEL_NONE,
8053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AUDIO_OUTPUT_FLAG_NONE,
8153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AUDIO_FORMAT_INVALID,
8253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        0, // mNumChannels
8353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        0 // mSampleRate
8453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia};
8553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
8653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// static
8753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaconst int64_t NuPlayer2::Renderer::kMinPositionUpdateDelayUs = 100000ll;
8853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
8953692fa54d0bf1d69184035a4c05ea0601a09c14Wei JiaNuPlayer2::Renderer::Renderer(
9033abcc7f15ef40a7d57a2f49dd8cce231c405016Wei Jia        const sp<MediaPlayer2Interface::AudioSink> &sink,
9153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<MediaClock> &mediaClock,
9253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &notify,
9353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        uint32_t flags)
9453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    : mAudioSink(sink),
9553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mUseVirtualAudioSink(false),
9653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mNotify(notify),
9753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mFlags(flags),
9853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mNumFramesWritten(0),
9953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mDrainAudioQueuePending(false),
10053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mDrainVideoQueuePending(false),
10153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioQueueGeneration(0),
10253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mVideoQueueGeneration(0),
10353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioDrainGeneration(0),
10453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mVideoDrainGeneration(0),
10553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioEOSGeneration(0),
10653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mMediaClock(mediaClock),
10753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
10853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioFirstAnchorTimeMediaUs(-1),
10953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAnchorTimeMediaUs(-1),
11053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAnchorNumFramesWritten(-1),
11153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mVideoLateByUs(0ll),
11253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mNextVideoTimeMediaUs(-1),
11353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mHasAudio(false),
11453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mHasVideo(false),
11553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mNotifyCompleteAudio(false),
11653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mNotifyCompleteVideo(false),
11753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mSyncQueues(false),
11853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mPaused(false),
11953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mPauseDrainAudioAllowedUs(0),
12053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mVideoSampleReceived(false),
12153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mVideoRenderingStarted(false),
12253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mVideoRenderingStartGeneration(0),
12353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioRenderingStartGeneration(0),
12453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mRenderingDataDelivered(false),
12553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mNextAudioClockUpdateTimeUs(-1),
12653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mLastAudioMediaTimeUs(-1),
12753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioOffloadPauseTimeoutGeneration(0),
12853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mAudioTornDown(false),
12953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
13053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
13153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mTotalBuffersQueued(0),
13253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mLastAudioBufferDrained(0),
13353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mUseAudioCallback(false),
13453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia      mWakeLock(new JWakeLock()) {
13553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(mediaClock != NULL);
13653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mPlaybackRate = mPlaybackSettings.mSpeed;
13753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mMediaClock->setPlaybackRate(mPlaybackRate);
13853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
13953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
14053692fa54d0bf1d69184035a4c05ea0601a09c14Wei JiaNuPlayer2::Renderer::~Renderer() {
14153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (offloadingAudio()) {
14253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioSink->stop();
14353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioSink->flush();
14453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioSink->close();
14553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
14653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
14753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // Try to avoid racing condition in case callback is still on.
14853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
14953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mUseAudioCallback) {
15053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        flushQueue(&mAudioQueue);
15153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        flushQueue(&mVideoQueue);
15253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
15353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mWakeLock.clear();
15453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoScheduler.clear();
15553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mNotify.clear();
15653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioSink.clear();
15753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
15853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
15953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::queueBuffer(
16053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool audio,
16153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<MediaCodecBuffer> &buffer,
16253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &notifyConsumed) {
16353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this);
16453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("queueGeneration", getQueueGeneration(audio));
16553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("audio", static_cast<int32_t>(audio));
16653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setObject("buffer", buffer);
16753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setMessage("notifyConsumed", notifyConsumed);
16853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post();
16953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
17053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
17153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::queueEOS(bool audio, status_t finalResult) {
17253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK_NE(finalResult, (status_t)OK);
17353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
17453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatQueueEOS, this);
17553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("queueGeneration", getQueueGeneration(audio));
17653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("audio", static_cast<int32_t>(audio));
17753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("finalResult", finalResult);
17853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post();
17953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
18053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
18153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::setPlaybackSettings(const AudioPlaybackRate &rate) {
18253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
18353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    writeToAMessage(msg, rate);
18453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> response;
18553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t err = msg->postAndAwaitResponse(&response);
18653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (err == OK && response != NULL) {
18753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(response->findInt32("err", &err));
18853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
18953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return err;
19053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
19153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
19253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) {
19353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (rate.mSpeed == 0.f) {
19453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        onPause();
19553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // don't call audiosink's setPlaybackRate if pausing, as pitch does not
19653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // have to correspond to the any non-0 speed (e.g old speed). Keep
19753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // settings nonetheless, using the old speed, in case audiosink changes.
19853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AudioPlaybackRate newRate = rate;
19953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        newRate.mSpeed = mPlaybackSettings.mSpeed;
20053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mPlaybackSettings = newRate;
20153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return OK;
20253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
20353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
20453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioSink != NULL && mAudioSink->ready()) {
20553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        status_t err = mAudioSink->setPlaybackRate(rate);
20653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err != OK) {
20753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return err;
20853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
20953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
21053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mPlaybackSettings = rate;
21153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mPlaybackRate = rate.mSpeed;
21253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mMediaClock->setPlaybackRate(mPlaybackRate);
21353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return OK;
21453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
21553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
21653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
21753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
21853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> response;
21953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t err = msg->postAndAwaitResponse(&response);
22053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (err == OK && response != NULL) {
22153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(response->findInt32("err", &err));
22253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err == OK) {
22353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            readFromAMessage(response, rate);
22453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
22553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
22653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return err;
22753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
22853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
22953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
23053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioSink != NULL && mAudioSink->ready()) {
23153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        status_t err = mAudioSink->getPlaybackRate(rate);
23253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err == OK) {
23353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) {
23453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGW("correcting mismatch in internal/external playback rate");
23553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
23653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // get playback settings used by audiosink, as it may be
23753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // slightly off due to audiosink not taking small changes.
23853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mPlaybackSettings = *rate;
23953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mPaused) {
24053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                rate->mSpeed = 0.f;
24153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
24253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
24353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return err;
24453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
24553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    *rate = mPlaybackSettings;
24653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return OK;
24753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
24853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
24953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
25053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
25153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    writeToAMessage(msg, sync, videoFpsHint);
25253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> response;
25353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t err = msg->postAndAwaitResponse(&response);
25453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (err == OK && response != NULL) {
25553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(response->findInt32("err", &err));
25653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
25753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return err;
25853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
25953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
26053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::onConfigSync(const AVSyncSettings &sync, float videoFpsHint __unused) {
26153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
26253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return BAD_VALUE;
26353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
26453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // TODO: support sync sources
26553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return INVALID_OPERATION;
26653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
26753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
26853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
26953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
27053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> response;
27153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t err = msg->postAndAwaitResponse(&response);
27253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (err == OK && response != NULL) {
27353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(response->findInt32("err", &err));
27453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err == OK) {
27553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            readFromAMessage(response, sync, videoFps);
27653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
27753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
27853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return err;
27953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
28053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
28153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::onGetSyncSettings(
28253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
28353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    *sync = mSyncSettings;
28453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    *videoFps = -1.f;
28553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return OK;
28653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
28753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
28853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::flush(bool audio, bool notifyComplete) {
28953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    {
29053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
29153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (audio) {
29253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNotifyCompleteAudio |= notifyComplete;
29353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            clearAudioFirstAnchorTime_l();
29453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mAudioQueueGeneration;
29553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mAudioDrainGeneration;
29653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else {
29753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNotifyCompleteVideo |= notifyComplete;
29853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mVideoQueueGeneration;
29953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mVideoDrainGeneration;
30053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
30153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
30253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->clearAnchor();
30353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mVideoLateByUs = 0;
30453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mNextVideoTimeMediaUs = -1;
30553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mSyncQueues = false;
30653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
30753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
30853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatFlush, this);
30953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("audio", static_cast<int32_t>(audio));
31053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post();
31153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
31253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
31353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::signalTimeDiscontinuity() {
31453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
31553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
31653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::signalDisableOffloadAudio() {
31753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    (new AMessage(kWhatDisableOffloadAudio, this))->post();
31853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
31953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
32053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::signalEnableOffloadAudio() {
32153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    (new AMessage(kWhatEnableOffloadAudio, this))->post();
32253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
32353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
32453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::pause() {
32553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    (new AMessage(kWhatPause, this))->post();
32653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
32753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
32853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::resume() {
32953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    (new AMessage(kWhatResume, this))->post();
33053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
33153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
33253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::setVideoFrameRate(float fps) {
33353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, this);
33453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setFloat("frame-rate", fps);
33553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post();
33653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
33753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
33853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// Called on any threads without mLock acquired.
33953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::getCurrentPosition(int64_t *mediaUs) {
34053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
34153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (result == OK) {
34253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return result;
34353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
34453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
34553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // MediaClock has not started yet. Try to start it if possible.
34653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    {
34753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
34853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mAudioFirstAnchorTimeMediaUs == -1) {
34953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return result;
35053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
35153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
35253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AudioTimestamp ts;
35353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        status_t res = mAudioSink->getTimestamp(ts);
35453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (res != OK) {
35553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return result;
35653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
35753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
35853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // AudioSink has rendered some frames.
35953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t nowUs = ALooper::GetNowUs();
36053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t nowMediaUs = mAudioSink->getPlayedOutDurationUs(nowUs)
36153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                + mAudioFirstAnchorTimeMediaUs;
36253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->updateAnchor(nowMediaUs, nowUs, -1);
36353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
36453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
36553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
36653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
36753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
36853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::clearAudioFirstAnchorTime_l() {
36953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioFirstAnchorTimeMediaUs = -1;
37053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mMediaClock->setStartingTimeMedia(-1);
37153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
37253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
37353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs) {
37453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioFirstAnchorTimeMediaUs == -1) {
37553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioFirstAnchorTimeMediaUs = mediaUs;
37653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->setStartingTimeMedia(mediaUs);
37753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
37853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
37953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
38053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// Called on renderer looper.
38153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::clearAnchorTime() {
38253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mMediaClock->clearAnchor();
38353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAnchorTimeMediaUs = -1;
38453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAnchorNumFramesWritten = -1;
38553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
38653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
38753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::setVideoLateByUs(int64_t lateUs) {
38853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
38953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoLateByUs = lateUs;
39053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
39153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
39253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaint64_t NuPlayer2::Renderer::getVideoLateByUs() {
39353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
39453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return mVideoLateByUs;
39553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
39653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
39753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::openAudioSink(
39853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &format,
39953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool offloadOnly,
40053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool hasVideo,
40153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        uint32_t flags,
40253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool *isOffloaded,
40353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool isStreaming) {
40453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this);
40553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setMessage("format", format);
40653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("offload-only", offloadOnly);
40753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("has-video", hasVideo);
40853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("flags", flags);
40953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("isStreaming", isStreaming);
41053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
41153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> response;
41253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t postStatus = msg->postAndAwaitResponse(&response);
41353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
41453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t err;
41553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (postStatus != OK || response.get() == nullptr || !response->findInt32("err", &err)) {
41653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        err = INVALID_OPERATION;
41753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else if (err == OK && isOffloaded != NULL) {
41853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int32_t offload;
41953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(response->findInt32("offload", &offload));
42053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        *isOffloaded = (offload != 0);
42153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
42253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return err;
42353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
42453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
42553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::closeAudioSink() {
42653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, this);
42753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
42853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> response;
42953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->postAndAwaitResponse(&response);
43053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
43153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
43253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::changeAudioFormat(
43353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &format,
43453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool offloadOnly,
43553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool hasVideo,
43653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        uint32_t flags,
43753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool isStreaming,
43853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &notify) {
43953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> meta = new AMessage;
44053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    meta->setMessage("format", format);
44153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    meta->setInt32("offload-only", offloadOnly);
44253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    meta->setInt32("has-video", hasVideo);
44353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    meta->setInt32("flags", flags);
44453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    meta->setInt32("isStreaming", isStreaming);
44553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
44653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatChangeAudioFormat, this);
44753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("queueGeneration", getQueueGeneration(true /* audio */));
44853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setMessage("notify", notify);
44953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setMessage("meta", meta);
45053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post();
45153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
45253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
45353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onMessageReceived(const sp<AMessage> &msg) {
45453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    switch (msg->what()) {
45553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatOpenAudioSink:
45653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
45753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> format;
45853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findMessage("format", &format));
45953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
46053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t offloadOnly;
46153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("offload-only", &offloadOnly));
46253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
46353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t hasVideo;
46453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("has-video", &hasVideo));
46553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
46653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            uint32_t flags;
46753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("flags", (int32_t *)&flags));
46853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
46953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            uint32_t isStreaming;
47053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("isStreaming", (int32_t *)&isStreaming));
47153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
47253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
47353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
47453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> response = new AMessage;
47553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->setInt32("err", err);
47653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->setInt32("offload", offloadingAudio());
47753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
47853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AReplyToken> replyID;
47953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
48053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->postReply(replyID);
48153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
48253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
48353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
48453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
48553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatCloseAudioSink:
48653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
48753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AReplyToken> replyID;
48853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
48953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
49053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onCloseAudioSink();
49153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
49253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> response = new AMessage;
49353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->postReply(replyID);
49453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
49553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
49653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
49753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatStopAudioSink:
49853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
49953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->stop();
50053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
50153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
50253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
50353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatChangeAudioFormat:
50453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
50553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t queueGeneration;
50653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("queueGeneration", &queueGeneration));
50753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
50853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> notify;
50953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findMessage("notify", &notify));
51053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
51153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (offloadingAudio()) {
51253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGW("changeAudioFormat should NOT be called in offload mode");
51353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                notify->setInt32("err", INVALID_OPERATION);
51453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                notify->post();
51553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
51653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
51753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
51853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> meta;
51953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findMessage("meta", &meta));
52053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
52153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (queueGeneration != getQueueGeneration(true /* audio */)
52253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    || mAudioQueue.empty()) {
52353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                onChangeAudioFormat(meta, notify);
52453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
52553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
52653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
52753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            QueueEntry entry;
52853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry.mNotifyConsumed = notify;
52953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry.mMeta = meta;
53053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
53153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            Mutex::Autolock autoLock(mLock);
53253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioQueue.push_back(entry);
53353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            postDrainAudioQueue_l();
53453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
53553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
53653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
53753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
53853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatDrainAudioQueue:
53953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
54053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mDrainAudioQueuePending = false;
54153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
54253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t generation;
54353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("drainGeneration", &generation));
54453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (generation != getDrainGeneration(true /* audio */)) {
54553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
54653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
54753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
54853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (onDrainAudioQueue()) {
54953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                uint32_t numFramesPlayed;
55053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
55153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                         (status_t)OK);
55253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
55353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Handle AudioTrack race when start is immediately called after flush.
55453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                uint32_t numFramesPendingPlayout =
55553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    (mNumFramesWritten > numFramesPlayed ?
55653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        mNumFramesWritten - numFramesPlayed : 0);
55753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
55853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // This is how long the audio sink will have data to
55953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // play back.
56053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                int64_t delayUs =
56153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mAudioSink->msecsPerFrame()
56253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        * numFramesPendingPlayout * 1000ll;
56353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                if (mPlaybackRate > 1.0f) {
56453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    delayUs /= mPlaybackRate;
56553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                }
56653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
56753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Let's give it more data after about half that time
56853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // has elapsed.
56953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                delayUs /= 2;
57053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // check the buffer size to estimate maximum delay permitted.
57153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                const int64_t maxDrainDelayUs = std::max(
57253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        mAudioSink->getBufferDurationInUs(), (int64_t)500000 /* half second */);
57353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGD_IF(delayUs > maxDrainDelayUs, "postDrainAudioQueue long delay: %lld > %lld",
57453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        (long long)delayUs, (long long)maxDrainDelayUs);
57553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                Mutex::Autolock autoLock(mLock);
57653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                postDrainAudioQueue_l(delayUs);
57753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
57853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
57953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
58053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
58153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatDrainVideoQueue:
58253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
58353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t generation;
58453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("drainGeneration", &generation));
58553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (generation != getDrainGeneration(false /* audio */)) {
58653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
58753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
58853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
58953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mDrainVideoQueuePending = false;
59053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
59153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onDrainVideoQueue();
59253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
59353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            postDrainVideoQueue();
59453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
59553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
59653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
59753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatPostDrainVideoQueue:
59853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
59953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t generation;
60053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("drainGeneration", &generation));
60153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (generation != getDrainGeneration(false /* audio */)) {
60253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
60353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
60453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
60553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mDrainVideoQueuePending = false;
60653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            postDrainVideoQueue();
60753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
60853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
60953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
61053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatQueueBuffer:
61153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
61253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onQueueBuffer(msg);
61353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
61453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
61553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
61653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatQueueEOS:
61753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
61853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onQueueEOS(msg);
61953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
62053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
62153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
62253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatEOS:
62353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
62453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t generation;
62553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("audioEOSGeneration", &generation));
62653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (generation != mAudioEOSGeneration) {
62753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
62853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
62953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            status_t finalResult;
63053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("finalResult", &finalResult));
63153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyEOS(true /* audio */, finalResult);
63253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
63353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
63453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
63553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatConfigPlayback:
63653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
63753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AReplyToken> replyID;
63853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
63953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            AudioPlaybackRate rate;
64053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            readFromAMessage(msg, &rate);
64153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            status_t err = onConfigPlayback(rate);
64253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> response = new AMessage;
64353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->setInt32("err", err);
64453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->postReply(replyID);
64553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
64653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
64753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
64853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatGetPlaybackSettings:
64953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
65053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AReplyToken> replyID;
65153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
65253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
65353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            status_t err = onGetPlaybackSettings(&rate);
65453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> response = new AMessage;
65553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (err == OK) {
65653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                writeToAMessage(response, rate);
65753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
65853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->setInt32("err", err);
65953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->postReply(replyID);
66053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
66153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
66253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
66353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatConfigSync:
66453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
66553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AReplyToken> replyID;
66653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
66753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            AVSyncSettings sync;
66853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            float videoFpsHint;
66953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            readFromAMessage(msg, &sync, &videoFpsHint);
67053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            status_t err = onConfigSync(sync, videoFpsHint);
67153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> response = new AMessage;
67253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->setInt32("err", err);
67353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->postReply(replyID);
67453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
67553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
67653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
67753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatGetSyncSettings:
67853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
67953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AReplyToken> replyID;
68053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
68153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
68253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("kWhatGetSyncSettings");
68353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            AVSyncSettings sync;
68453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            float videoFps = -1.f;
68553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            status_t err = onGetSyncSettings(&sync, &videoFps);
68653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            sp<AMessage> response = new AMessage;
68753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (err == OK) {
68853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                writeToAMessage(response, sync, videoFps);
68953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
69053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->setInt32("err", err);
69153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            response->postReply(replyID);
69253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
69353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
69453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
69553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatFlush:
69653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
69753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onFlush(msg);
69853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
69953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
70053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
70153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatDisableOffloadAudio:
70253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
70353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onDisableOffloadAudio();
70453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
70553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
70653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
70753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatEnableOffloadAudio:
70853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
70953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onEnableOffloadAudio();
71053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
71153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
71253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
71353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatPause:
71453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
71553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onPause();
71653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
71753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
71853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
71953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatResume:
72053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
72153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onResume();
72253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
72353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
72453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
72553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatSetVideoFrameRate:
72653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
72753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            float fps;
72853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findFloat("frame-rate", &fps));
72953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onSetVideoFrameRate(fps);
73053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
73153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
73253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
73353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatAudioTearDown:
73453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
73553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t reason;
73653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("reason", &reason));
73753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
73853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onAudioTearDown((AudioTearDownReason)reason);
73953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
74053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
74153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
74253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        case kWhatAudioOffloadPauseTimeout:
74353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
74453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t generation;
74553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(msg->findInt32("drainGeneration", &generation));
74653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (generation != mAudioOffloadPauseTimeoutGeneration) {
74753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                break;
74853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
74953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("Audio Offload tear down due to pause timeout.");
75053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onAudioTearDown(kDueToTimeout);
75153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mWakeLock->release();
75253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
75353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
75453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
75553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        default:
75653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            TRESPASS();
75753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
75853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
75953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
76053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
76153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::postDrainAudioQueue_l(int64_t delayUs) {
76253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mDrainAudioQueuePending || mSyncQueues || mUseAudioCallback) {
76353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
76453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
76553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
76653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioQueue.empty()) {
76753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
76853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
76953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
77053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // FIXME: if paused, wait until AudioTrack stop() is complete before delivering data.
77153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mPaused) {
77253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const int64_t diffUs = mPauseDrainAudioAllowedUs - ALooper::GetNowUs();
77353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (diffUs > delayUs) {
77453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            delayUs = diffUs;
77553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
77653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
77753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
77853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mDrainAudioQueuePending = true;
77953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
78053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("drainGeneration", mAudioDrainGeneration);
78153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post(delayUs);
78253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
78353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
78453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::prepareForMediaRenderingStart_l() {
78553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioRenderingStartGeneration = mAudioDrainGeneration;
78653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoRenderingStartGeneration = mVideoDrainGeneration;
78753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mRenderingDataDelivered = false;
78853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
78953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
79053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyIfMediaRenderingStarted_l() {
79153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mVideoRenderingStartGeneration == mVideoDrainGeneration &&
79253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioRenderingStartGeneration == mAudioDrainGeneration) {
79353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mRenderingDataDelivered = true;
79453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mPaused) {
79553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return;
79653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
79753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mVideoRenderingStartGeneration = -1;
79853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioRenderingStartGeneration = -1;
79953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
80053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        sp<AMessage> notify = mNotify->dup();
80153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notify->setInt32("what", kWhatMediaRenderingStart);
80253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notify->post();
80353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
80453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
80553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
80653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// static
80753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiasize_t NuPlayer2::Renderer::AudioSinkCallback(
80833abcc7f15ef40a7d57a2f49dd8cce231c405016Wei Jia        MediaPlayer2Interface::AudioSink * /* audioSink */,
80953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        void *buffer,
81053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        size_t size,
81153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        void *cookie,
81233abcc7f15ef40a7d57a2f49dd8cce231c405016Wei Jia        MediaPlayer2Interface::AudioSink::cb_event_t event) {
81353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    NuPlayer2::Renderer *me = (NuPlayer2::Renderer *)cookie;
81453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
81553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    switch (event) {
81633abcc7f15ef40a7d57a2f49dd8cce231c405016Wei Jia        case MediaPlayer2Interface::AudioSink::CB_EVENT_FILL_BUFFER:
81753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
81853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return me->fillAudioBuffer(buffer, size);
81953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
82053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
82153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
82233abcc7f15ef40a7d57a2f49dd8cce231c405016Wei Jia        case MediaPlayer2Interface::AudioSink::CB_EVENT_STREAM_END:
82353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
82453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("AudioSink::CB_EVENT_STREAM_END");
82553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            me->notifyEOSCallback();
82653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
82753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
82853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
82933abcc7f15ef40a7d57a2f49dd8cce231c405016Wei Jia        case MediaPlayer2Interface::AudioSink::CB_EVENT_TEAR_DOWN:
83053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
83153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("AudioSink::CB_EVENT_TEAR_DOWN");
83253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            me->notifyAudioTearDown(kDueToError);
83353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
83453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
83553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
83653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
83753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return 0;
83853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
83953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
84053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyEOSCallback() {
84153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
84253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
84353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mUseAudioCallback) {
84453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
84553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
84653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
84753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notifyEOS_l(true /* audio */, ERROR_END_OF_STREAM);
84853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
84953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
85053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiasize_t NuPlayer2::Renderer::fillAudioBuffer(void *buffer, size_t size) {
85153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
85253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
85353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mUseAudioCallback) {
85453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return 0;
85553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
85653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
85753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    bool hasEOS = false;
85853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
85953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    size_t sizeCopied = 0;
86053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    bool firstEntry = true;
86153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    QueueEntry *entry;  // will be valid after while loop if hasEOS is set.
86253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    while (sizeCopied < size && !mAudioQueue.empty()) {
86353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        entry = &*mAudioQueue.begin();
86453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
86553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (entry->mBuffer == NULL) { // EOS
86653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            hasEOS = true;
86753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioQueue.erase(mAudioQueue.begin());
86853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
86953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
87053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
87153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (firstEntry && entry->mOffset == 0) {
87253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            firstEntry = false;
87353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t mediaTimeUs;
87453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
87553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
87653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
87753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
87853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
87953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        size_t copy = entry->mBuffer->size() - entry->mOffset;
88053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        size_t sizeRemaining = size - sizeCopied;
88153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (copy > sizeRemaining) {
88253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            copy = sizeRemaining;
88353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
88453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
88553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        memcpy((char *)buffer + sizeCopied,
88653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia               entry->mBuffer->data() + entry->mOffset,
88753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia               copy);
88853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
88953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        entry->mOffset += copy;
89053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (entry->mOffset == entry->mBuffer->size()) {
89153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry->mNotifyConsumed->post();
89253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioQueue.erase(mAudioQueue.begin());
89353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry = NULL;
89453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
89553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        sizeCopied += copy;
89653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
89753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notifyIfMediaRenderingStarted_l();
89853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
89953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
90053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioFirstAnchorTimeMediaUs >= 0) {
90153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t nowUs = ALooper::GetNowUs();
90253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t nowMediaUs =
90353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioFirstAnchorTimeMediaUs + mAudioSink->getPlayedOutDurationUs(nowUs);
90453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // we don't know how much data we are queueing for offloaded tracks.
90553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX);
90653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
90753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
90853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // for non-offloaded audio, we need to compute the frames written because
90953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // there is no EVENT_STREAM_END notification. The frames written gives
91053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // an estimate on the pending played out duration.
91153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!offloadingAudio()) {
91253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mNumFramesWritten += sizeCopied / mAudioSink->frameSize();
91353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
91453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
91553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (hasEOS) {
91653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        (new AMessage(kWhatStopAudioSink, this))->post();
91753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // As there is currently no EVENT_STREAM_END callback notification for
91853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // non-offloaded audio tracks, we need to post the EOS ourselves.
91953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (!offloadingAudio()) {
92053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t postEOSDelayUs = 0;
92153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mAudioSink->needsTrailingPadding()) {
92253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
92353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
92453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("fillAudioBuffer: notifyEOS_l "
92553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    "mNumFramesWritten:%u  finalResult:%d  postEOSDelay:%lld",
92653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs);
92753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyEOS_l(true /* audio */, entry->mFinalResult, postEOSDelayUs);
92853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
92953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
93053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return sizeCopied;
93153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
93253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
93353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::drainAudioQueueUntilLastEOS() {
93453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    List<QueueEntry>::iterator it = mAudioQueue.begin(), itEOS = it;
93553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    bool foundEOS = false;
93653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    while (it != mAudioQueue.end()) {
93753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int32_t eos;
93853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        QueueEntry *entry = &*it++;
93953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if ((entry->mBuffer == nullptr && entry->mNotifyConsumed == nullptr)
94053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                || (entry->mNotifyConsumed->findInt32("eos", &eos) && eos != 0)) {
94153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            itEOS = it;
94253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            foundEOS = true;
94353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
94453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
94553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
94653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (foundEOS) {
94753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // post all replies before EOS and drop the samples
94853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        for (it = mAudioQueue.begin(); it != itEOS; it++) {
94953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (it->mBuffer == nullptr) {
95053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                if (it->mNotifyConsumed == nullptr) {
95153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    // delay doesn't matter as we don't even have an AudioTrack
95253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    notifyEOS(true /* audio */, it->mFinalResult);
95353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                } else {
95453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    // TAG for re-opening audio sink.
95553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    onChangeAudioFormat(it->mMeta, it->mNotifyConsumed);
95653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                }
95753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            } else {
95853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                it->mNotifyConsumed->post();
95953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
96053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
96153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioQueue.erase(mAudioQueue.begin(), itEOS);
96253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
96353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
96453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
96553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiabool NuPlayer2::Renderer::onDrainAudioQueue() {
96653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // do not drain audio during teardown as queued buffers may be invalid.
96753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioTornDown) {
96853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return false;
96953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
97053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // TODO: This call to getPosition checks if AudioTrack has been created
97153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // in AudioSink before draining audio. If AudioTrack doesn't exist, then
97253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // CHECKs on getPosition will fail.
97353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // We still need to figure out why AudioTrack is not created when
97453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // this function is called. One possible reason could be leftover
97553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // audio. Another possible place is to check whether decoder
97653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // has received INFO_FORMAT_CHANGED as the first buffer since
97753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // AudioSink is opened there, and possible interactions with flush
97853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // immediately after start. Investigate error message
97953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // "vorbis_dsp_synthesis returned -135", along with RTSP.
98053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    uint32_t numFramesPlayed;
98153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
98253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // When getPosition fails, renderer will not reschedule the draining
98353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // unless new samples are queued.
98453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // If we have pending EOS (or "eos" marker for discontinuities), we need
98553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // to post these now as NuPlayer2Decoder might be waiting for it.
98653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        drainAudioQueueUntilLastEOS();
98753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
98853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGW("onDrainAudioQueue(): audio sink is not ready");
98953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return false;
99053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
99153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
99253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#if 0
99353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ssize_t numFramesAvailableToWrite =
99453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
99553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
99653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
99753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGI("audio sink underrun");
99853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
99953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGV("audio queue has %d frames left to play",
100053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia             mAudioSink->frameCount() - numFramesAvailableToWrite);
100153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
100253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#endif
100353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
100453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    uint32_t prevFramesWritten = mNumFramesWritten;
100553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    while (!mAudioQueue.empty()) {
100653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        QueueEntry *entry = &*mAudioQueue.begin();
100753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
100853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (entry->mBuffer == NULL) {
100953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (entry->mNotifyConsumed != nullptr) {
101053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // TAG for re-open audio sink.
101153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed);
101253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mAudioQueue.erase(mAudioQueue.begin());
101353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                continue;
101453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
101553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
101653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // EOS
101753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mPaused) {
101853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Do not notify EOS when paused.
101953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // This is needed to avoid switch to next clip while in pause.
102053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGV("onDrainAudioQueue(): Do not notify EOS when paused");
102153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                return false;
102253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
102353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
102453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t postEOSDelayUs = 0;
102553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mAudioSink->needsTrailingPadding()) {
102653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
102753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
102853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);
102953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mLastAudioMediaTimeUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
103053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
103153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioQueue.erase(mAudioQueue.begin());
103253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry = NULL;
103353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mAudioSink->needsTrailingPadding()) {
103453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // If we're not in gapless playback (i.e. through setNextPlayer), we
103553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // need to stop the track here, because that will play out the last
103653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // little bit at the end of the file. Otherwise short files won't play.
103753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mAudioSink->stop();
103853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mNumFramesWritten = 0;
103953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
104053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return false;
104153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
104253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
104353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mLastAudioBufferDrained = entry->mBufferOrdinal;
104453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
104553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // ignore 0-sized buffer which could be EOS marker with no data
104653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (entry->mOffset == 0 && entry->mBuffer->size() > 0) {
104753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t mediaTimeUs;
104853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
104953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("onDrainAudioQueue: rendering audio at media time %.2f secs",
105053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mediaTimeUs / 1E6);
105153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onNewAudioMediaTime(mediaTimeUs);
105253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
105353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
105453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        size_t copy = entry->mBuffer->size() - entry->mOffset;
105553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
105653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset,
105753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                                            copy, false /* blocking */);
105853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (written < 0) {
105953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // An error in AudioSink write. Perhaps the AudioSink was not properly opened.
106053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (written == WOULD_BLOCK) {
106153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGV("AudioSink write would block when writing %zu bytes", copy);
106253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            } else {
106353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
106453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // This can only happen when AudioSink was opened with doNotReconnect flag set to
106553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // true, in which case the NuPlayer2 will handle the reconnect.
106653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                notifyAudioTearDown(kDueToError);
106753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
106853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
106953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
107053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
107153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        entry->mOffset += written;
107253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        size_t remainder = entry->mBuffer->size() - entry->mOffset;
107353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if ((ssize_t)remainder < mAudioSink->frameSize()) {
107453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (remainder > 0) {
107553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGW("Corrupted audio buffer has fractional frames, discarding %zu bytes.",
107653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        remainder);
107753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                entry->mOffset += remainder;
107853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                copy -= remainder;
107953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
108053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
108153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry->mNotifyConsumed->post();
108253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioQueue.erase(mAudioQueue.begin());
108353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
108453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry = NULL;
108553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
108653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
108753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        size_t copiedFrames = written / mAudioSink->frameSize();
108853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mNumFramesWritten += copiedFrames;
108953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
109053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
109153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            Mutex::Autolock autoLock(mLock);
109253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t maxTimeMedia;
109353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            maxTimeMedia =
109453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mAnchorTimeMediaUs +
109553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
109653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                                * 1000LL * mAudioSink->msecsPerFrame());
109753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mMediaClock->updateMaxTimeMedia(maxTimeMedia);
109853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
109953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyIfMediaRenderingStarted_l();
110053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
110153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
110253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (written != (ssize_t)copy) {
110353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // A short count was received from AudioSink::write()
110453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            //
110553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // AudioSink write is called in non-blocking mode.
110653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // It may return with a short count when:
110753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            //
110853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // 1) Size to be copied is not a multiple of the frame size. Fractional frames are
110953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            //    discarded.
111053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // 2) The data to be copied exceeds the available buffer in AudioSink.
111153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // 3) An error occurs and data has been partially copied to the buffer in AudioSink.
111253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
111353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
111453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // (Case 1)
111553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Must be a multiple of the frame size.  If it is not a multiple of a frame size, it
111653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // needs to fail, as we should not carry over fractional frames between calls.
111753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            CHECK_EQ(copy % mAudioSink->frameSize(), 0u);
111853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
111953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // (Case 2, 3, 4)
112053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Return early to the caller.
112153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Beware of calling immediately again as this may busy-loop if you are not careful.
112253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("AudioSink write short frame count %zd < %zu", written, copy);
112353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            break;
112453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
112553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
112653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
112753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // calculate whether we need to reschedule another write.
112853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    bool reschedule = !mAudioQueue.empty()
112953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            && (!mPaused
113053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                || prevFramesWritten != mNumFramesWritten); // permit pause to fill buffers
113153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    //ALOGD("reschedule:%d  empty:%d  mPaused:%d  prevFramesWritten:%u  mNumFramesWritten:%u",
113253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    //        reschedule, mAudioQueue.empty(), mPaused, prevFramesWritten, mNumFramesWritten);
113353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return reschedule;
113453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
113553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
113653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaint64_t NuPlayer2::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) {
113753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t sampleRate = offloadingAudio() ?
113853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate;
113953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (sampleRate == 0) {
114053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload");
114153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return 0;
114253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
114353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
114453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate);
114553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
114653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
114753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// Calculate duration of pending samples if played at normal rate (i.e., 1.0).
114853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaint64_t NuPlayer2::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
114953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
115053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mUseVirtualAudioSink) {
115153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t nowUs = ALooper::GetNowUs();
115253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t mediaUs;
115353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
115453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return 0ll;
115553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else {
115653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
115753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
115853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
115953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
116053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    const int64_t audioSinkPlayedUs = mAudioSink->getPlayedOutDurationUs(nowUs);
116153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t pendingUs = writtenAudioDurationUs - audioSinkPlayedUs;
116253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (pendingUs < 0) {
116353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // This shouldn't happen unless the timestamp is stale.
116453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGW("%s: pendingUs %lld < 0, clamping to zero, potential resume after pause "
116553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                "writtenAudioDurationUs: %lld, audioSinkPlayedUs: %lld",
116653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                __func__, (long long)pendingUs,
116753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                (long long)writtenAudioDurationUs, (long long)audioSinkPlayedUs);
116853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        pendingUs = 0;
116953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
117053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return pendingUs;
117153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
117253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
117353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaint64_t NuPlayer2::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) {
117453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t realUs;
117553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mMediaClock->getRealTimeFor(mediaTimeUs, &realUs) != OK) {
117653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // If failed to get current position, e.g. due to audio clock is
117753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // not ready, then just play out video immediately without delay.
117853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return nowUs;
117953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
118053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return realUs;
118153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
118253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
118353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) {
118453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
118553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // TRICKY: vorbis decoder generates multiple frames with the same
118653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // timestamp, so only update on the first frame with a given timestamp
118753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mediaTimeUs == mAnchorTimeMediaUs) {
118853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
118953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
119053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
119153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
119253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // mNextAudioClockUpdateTimeUs is -1 if we're waiting for audio sink to start
119353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mNextAudioClockUpdateTimeUs == -1) {
119453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AudioTimestamp ts;
119553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mAudioSink->getTimestamp(ts) == OK && ts.mPosition > 0) {
119653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNextAudioClockUpdateTimeUs = 0; // start our clock updates
119753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
119853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
119953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t nowUs = ALooper::GetNowUs();
120053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mNextAudioClockUpdateTimeUs >= 0) {
120153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (nowUs >= mNextAudioClockUpdateTimeUs) {
120253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
120353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
120453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mUseVirtualAudioSink = false;
120553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNextAudioClockUpdateTimeUs = nowUs + kMinimumAudioClockUpdatePeriodUs;
120653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
120753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
120853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t unused;
120953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if ((mMediaClock->getMediaTime(nowUs, &unused) != OK)
121053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                && (getDurationUsIfPlayedAtSampleRate(mNumFramesWritten)
121153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        > kMaxAllowedAudioSinkDelayUs)) {
121253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Enough data has been sent to AudioSink, but AudioSink has not rendered
121353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // any data yet. Something is wrong with AudioSink, e.g., the device is not
121453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // connected to audio out.
121553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Switch to system clock. This essentially creates a virtual AudioSink with
121653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // initial latenty of getDurationUsIfPlayedAtSampleRate(mNumFramesWritten).
121753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // This virtual AudioSink renders audio data starting from the very first sample
121853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // and it's paced by system clock.
121953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGW("AudioSink stuck. ARE YOU CONNECTED TO AUDIO OUT? Switching to system clock.");
122053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mMediaClock->updateAnchor(mAudioFirstAnchorTimeMediaUs, nowUs, mediaTimeUs);
122153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mUseVirtualAudioSink = true;
122253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
122353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
122453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAnchorNumFramesWritten = mNumFramesWritten;
122553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAnchorTimeMediaUs = mediaTimeUs;
122653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
122753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
122853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// Called without mLock acquired.
122953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::postDrainVideoQueue() {
123053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mDrainVideoQueuePending
123153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            || getSyncQueues()
123253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            || (mPaused && mVideoSampleReceived)) {
123353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
123453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
123553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
123653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mVideoQueue.empty()) {
123753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
123853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
123953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
124053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    QueueEntry &entry = *mVideoQueue.begin();
124153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
124253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this);
124353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("drainGeneration", getDrainGeneration(false /* audio */));
124453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
124553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (entry.mBuffer == NULL) {
124653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // EOS doesn't carry a timestamp.
124753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->post();
124853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mDrainVideoQueuePending = true;
124953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
125053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
125153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
125253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t nowUs = ALooper::GetNowUs();
125353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mFlags & FLAG_REAL_TIME) {
125453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t realTimeUs;
125553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(entry.mBuffer->meta()->findInt64("timeUs", &realTimeUs));
125653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
125753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
125853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
125953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000);
126053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
126153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t delayUs = realTimeUs - nowUs;
126253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
126353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGW_IF(delayUs > 500000, "unusually high delayUs: %lld", (long long)delayUs);
126453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // post 2 display refreshes before rendering is due
126553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0);
126653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
126753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mDrainVideoQueuePending = true;
126853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
126953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
127053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
127153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t mediaTimeUs;
127253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
127353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
127453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    {
127553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
127653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mAnchorTimeMediaUs < 0) {
127753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs);
127853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAnchorTimeMediaUs = mediaTimeUs;
127953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
128053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
128153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mNextVideoTimeMediaUs = mediaTimeUs + 100000;
128253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mHasAudio) {
128353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // smooth out videos >= 10fps
128453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
128553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
128653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
128753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
128853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->post();
128953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
129053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000);
129153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
129253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // post 2 display refreshes before rendering is due
129353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->addTimer(msg, mediaTimeUs, -twoVsyncsUs);
129453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
129553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
129653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mDrainVideoQueuePending = true;
129753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
129853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
129953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onDrainVideoQueue() {
130053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mVideoQueue.empty()) {
130153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
130253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
130353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
130453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    QueueEntry *entry = &*mVideoQueue.begin();
130553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
130653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (entry->mBuffer == NULL) {
130753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // EOS
130853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
130953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notifyEOS(false /* audio */, entry->mFinalResult);
131053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
131153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mVideoQueue.erase(mVideoQueue.begin());
131253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        entry = NULL;
131353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
131453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        setVideoLateByUs(0);
131553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
131653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
131753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
131853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t nowUs = ALooper::GetNowUs();
131953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t realTimeUs;
132053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t mediaTimeUs = -1;
132153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mFlags & FLAG_REAL_TIME) {
132253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs));
132353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
132453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
132553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
132653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        realTimeUs = getRealTimeUs(mediaTimeUs, nowUs);
132753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
132853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
132953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
133053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    bool tooLate = false;
133153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
133253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mPaused) {
133353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        setVideoLateByUs(nowUs - realTimeUs);
133453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        tooLate = (mVideoLateByUs > 40000);
133553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
133653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (tooLate) {
133753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("video late by %lld us (%.2f secs)",
133853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                 (long long)mVideoLateByUs, mVideoLateByUs / 1E6);
133953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else {
134053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t mediaUs = 0;
134153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mMediaClock->getMediaTime(realTimeUs, &mediaUs);
134253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("rendering video at media time %.2f secs",
134353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    (mFlags & FLAG_REAL_TIME ? realTimeUs :
134453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mediaUs) / 1E6);
134553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
134653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (!(mFlags & FLAG_REAL_TIME)
134753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    && mLastAudioMediaTimeUs != -1
134853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    && mediaTimeUs > mLastAudioMediaTimeUs) {
134953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // If audio ends before video, video continues to drive media clock.
135053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Also smooth out videos >= 10fps.
135153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
135253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
135353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
135453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
135553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        setVideoLateByUs(0);
135653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (!mVideoSampleReceived && !mHasAudio) {
135753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // This will ensure that the first frame after a flush won't be used as anchor
135853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // when renderer is in paused state, because resume can happen any time after seek.
135953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            clearAnchorTime();
136053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
136153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
136253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
136353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // Always render the first video frame while keeping stats on A/V sync.
136453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mVideoSampleReceived) {
136553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        realTimeUs = nowUs;
136653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        tooLate = false;
136753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
136853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
136953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll);
137053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry->mNotifyConsumed->setInt32("render", !tooLate);
137153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry->mNotifyConsumed->post();
137253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoQueue.erase(mVideoQueue.begin());
137353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry = NULL;
137453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
137553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoSampleReceived = true;
137653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
137753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mPaused) {
137853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (!mVideoRenderingStarted) {
137953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mVideoRenderingStarted = true;
138053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyVideoRenderingStart();
138153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
138253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
138353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notifyIfMediaRenderingStarted_l();
138453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
138553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
138653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
138753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyVideoRenderingStart() {
138853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> notify = mNotify->dup();
138953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("what", kWhatVideoRenderingStart);
139053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->post();
139153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
139253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
139353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) {
139453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
139553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notifyEOS_l(audio, finalResult, delayUs);
139653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
139753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
139853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs) {
139953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audio && delayUs > 0) {
140053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        sp<AMessage> msg = new AMessage(kWhatEOS, this);
140153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->setInt32("audioEOSGeneration", mAudioEOSGeneration);
140253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->setInt32("finalResult", finalResult);
140353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->post(delayUs);
140453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
140553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
140653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> notify = mNotify->dup();
140753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("what", kWhatEOS);
140853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("audio", static_cast<int32_t>(audio));
140953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("finalResult", finalResult);
141053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->post(delayUs);
141153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
141253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audio) {
141353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // Video might outlive audio. Clear anchor to enable video only case.
141453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAnchorTimeMediaUs = -1;
141553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mHasAudio = false;
141653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mNextVideoTimeMediaUs >= 0) {
141753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int64_t mediaUs = 0;
141853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mMediaClock->getMediaTime(ALooper::GetNowUs(), &mediaUs);
141953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mNextVideoTimeMediaUs > mediaUs) {
142053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
142153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
142253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
142353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
142453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
142553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
142653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyAudioTearDown(AudioTearDownReason reason) {
142753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> msg = new AMessage(kWhatAudioTearDown, this);
142853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->setInt32("reason", reason);
142953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    msg->post();
143053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
143153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
143253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
143353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t audio;
143453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findInt32("audio", &audio));
143553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
143653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (dropBufferIfStale(audio, msg)) {
143753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
143853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
143953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
144053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audio) {
144153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mHasAudio = true;
144253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
144353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mHasVideo = true;
144453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
144553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
144653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mHasVideo) {
144753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mVideoScheduler == NULL) {
144853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mVideoScheduler = new VideoFrameScheduler();
144953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mVideoScheduler->init();
145053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
145153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
145253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
145353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<RefBase> obj;
145453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findObject("buffer", &obj));
145553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
145653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
145753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> notifyConsumed;
145853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
145953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
146053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    QueueEntry entry;
146153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mBuffer = buffer;
146253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mNotifyConsumed = notifyConsumed;
146353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mOffset = 0;
146453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mFinalResult = OK;
146553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mBufferOrdinal = ++mTotalBuffersQueued;
146653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
146753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audio) {
146853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
146953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioQueue.push_back(entry);
147053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainAudioQueue_l();
147153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
147253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mVideoQueue.push_back(entry);
147353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainVideoQueue();
147453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
147553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
147653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
147753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) {
147853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
147953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
148053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
148153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<MediaCodecBuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer;
148253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<MediaCodecBuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer;
148353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
148453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) {
148553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // EOS signalled on either queue.
148653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        syncQueuesDone_l();
148753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
148853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
148953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
149053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t firstAudioTimeUs;
149153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t firstVideoTimeUs;
149253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(firstAudioBuffer->meta()
149353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ->findInt64("timeUs", &firstAudioTimeUs));
149453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(firstVideoBuffer->meta()
149553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ->findInt64("timeUs", &firstVideoTimeUs));
149653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
149753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t diff = firstVideoTimeUs - firstAudioTimeUs;
149853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
149953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ALOGV("queueDiff = %.2f secs", diff / 1E6);
150053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
150153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (diff > 100000ll) {
150253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // Audio data starts More than 0.1 secs before video.
150353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // Drop some audio.
150453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
150553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        (*mAudioQueue.begin()).mNotifyConsumed->post();
150653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioQueue.erase(mAudioQueue.begin());
150753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
150853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
150953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
151053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    syncQueuesDone_l();
151153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
151253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
151353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::syncQueuesDone_l() {
151453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mSyncQueues) {
151553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
151653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
151753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
151853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mSyncQueues = false;
151953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
152053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mAudioQueue.empty()) {
152153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainAudioQueue_l();
152253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
152353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
152453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mVideoQueue.empty()) {
152553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mLock.unlock();
152653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainVideoQueue();
152753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mLock.lock();
152853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
152953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
153053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
153153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onQueueEOS(const sp<AMessage> &msg) {
153253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t audio;
153353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findInt32("audio", &audio));
153453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
153553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (dropBufferIfStale(audio, msg)) {
153653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
153753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
153853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
153953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t finalResult;
154053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findInt32("finalResult", &finalResult));
154153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
154253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    QueueEntry entry;
154353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mOffset = 0;
154453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    entry.mFinalResult = finalResult;
154553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
154653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audio) {
154753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
154853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mAudioQueue.empty() && mSyncQueues) {
154953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            syncQueuesDone_l();
155053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
155153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioQueue.push_back(entry);
155253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainAudioQueue_l();
155353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
155453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mVideoQueue.empty() && getSyncQueues()) {
155553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            Mutex::Autolock autoLock(mLock);
155653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            syncQueuesDone_l();
155753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
155853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mVideoQueue.push_back(entry);
155953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainVideoQueue();
156053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
156153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
156253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
156353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onFlush(const sp<AMessage> &msg) {
156453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t audio, notifyComplete;
156553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findInt32("audio", &audio));
156653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
156753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    {
156853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
156953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (audio) {
157053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyComplete = mNotifyCompleteAudio;
157153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNotifyCompleteAudio = false;
157253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mLastAudioMediaTimeUs = -1;
157353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else {
157453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyComplete = mNotifyCompleteVideo;
157553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNotifyCompleteVideo = false;
157653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
157753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
157853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // If we're currently syncing the queues, i.e. dropping audio while
157953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // aligning the first audio/video buffer times and only one of the
158053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // two queues has data, we may starve that queue by not requesting
158153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // more buffers from the decoder. If the other source then encounters
158253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // a discontinuity that leads to flushing, we'll never find the
158353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // corresponding discontinuity on the other queue.
158453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // Therefore we'll stop syncing the queues if at least one of them
158553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // is flushed.
158653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        syncQueuesDone_l();
158753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
158853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    clearAnchorTime();
158953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
159053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ALOGV("flushing %s", audio ? "audio" : "video");
159153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audio) {
159253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        {
159353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            Mutex::Autolock autoLock(mLock);
159453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            flushQueue(&mAudioQueue);
159553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
159653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mAudioDrainGeneration;
159753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mAudioEOSGeneration;
159853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            prepareForMediaRenderingStart_l();
159953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
160053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // the frame count will be reset after flush.
160153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            clearAudioFirstAnchorTime_l();
160253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
160353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
160453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mDrainAudioQueuePending = false;
160553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
160653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (offloadingAudio()) {
160753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->pause();
160853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->flush();
160953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (!mPaused) {
161053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mAudioSink->start();
161153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
161253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else {
161353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->pause();
161453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->flush();
161553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Call stop() to signal to the AudioSink to completely fill the
161653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // internal buffer before resuming playback.
161753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // FIXME: this is ignored after flush().
161853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->stop();
161953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (mPaused) {
162053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Race condition: if renderer is paused and audio sink is stopped,
162153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // we need to make sure that the audio track buffer fully drains
162253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // before delivering data.
162353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // FIXME: remove this if we can detect if stop() is complete.
162453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms)
162553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs;
162653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            } else {
162753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mAudioSink->start();
162853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
162953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mNumFramesWritten = 0;
163053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
163153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mNextAudioClockUpdateTimeUs = -1;
163253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    } else {
163353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        flushQueue(&mVideoQueue);
163453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
163553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mDrainVideoQueuePending = false;
163653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
163753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mVideoScheduler != NULL) {
163853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mVideoScheduler->restart();
163953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
164053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
164153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
164253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ++mVideoDrainGeneration;
164353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        prepareForMediaRenderingStart_l();
164453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
164553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
164653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoSampleReceived = false;
164753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
164853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (notifyComplete) {
164953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notifyFlushComplete(audio);
165053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
165153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
165253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
165353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::flushQueue(List<QueueEntry> *queue) {
165453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    while (!queue->empty()) {
165553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        QueueEntry *entry = &*queue->begin();
165653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
165753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (entry->mBuffer != NULL) {
165853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            entry->mNotifyConsumed->post();
165953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else if (entry->mNotifyConsumed != nullptr) {
166053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // Is it needed to open audio sink now?
166153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed);
166253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
166353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
166453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        queue->erase(queue->begin());
166553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        entry = NULL;
166653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
166753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
166853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
166953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::notifyFlushComplete(bool audio) {
167053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> notify = mNotify->dup();
167153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("what", kWhatFlushComplete);
167253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("audio", static_cast<int32_t>(audio));
167353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->post();
167453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
167553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
167653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiabool NuPlayer2::Renderer::dropBufferIfStale(
167753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool audio, const sp<AMessage> &msg) {
167853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t queueGeneration;
167953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(msg->findInt32("queueGeneration", &queueGeneration));
168053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
168153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (queueGeneration == getQueueGeneration(audio)) {
168253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return false;
168353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
168453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
168553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> notifyConsumed;
168653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (msg->findMessage("notifyConsumed", &notifyConsumed)) {
168753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notifyConsumed->post();
168853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
168953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
169053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return true;
169153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
169253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
169353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onAudioSinkChanged() {
169453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (offloadingAudio()) {
169553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
169653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
169753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(!mDrainAudioQueuePending);
169853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mNumFramesWritten = 0;
169953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAnchorNumFramesWritten = -1;
170053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    uint32_t written;
170153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioSink->getFramesWritten(&written) == OK) {
170253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mNumFramesWritten = written;
170353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
170453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
170553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
170653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onDisableOffloadAudio() {
170753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
170853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mFlags &= ~FLAG_OFFLOAD_AUDIO;
170953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ++mAudioDrainGeneration;
171053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioRenderingStartGeneration != -1) {
171153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        prepareForMediaRenderingStart_l();
171253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
171353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
171453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
171553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onEnableOffloadAudio() {
171653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
171753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mFlags |= FLAG_OFFLOAD_AUDIO;
171853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ++mAudioDrainGeneration;
171953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioRenderingStartGeneration != -1) {
172053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        prepareForMediaRenderingStart_l();
172153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
172253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
172353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
172453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onPause() {
172553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mPaused) {
172653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
172753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
172853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
172953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    {
173053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
173153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // we do not increment audio drain generation so that we fill audio buffer during pause.
173253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ++mVideoDrainGeneration;
173353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        prepareForMediaRenderingStart_l();
173453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mPaused = true;
173553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->setPlaybackRate(0.0);
173653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
173753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
173853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mDrainAudioQueuePending = false;
173953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mDrainVideoQueuePending = false;
174053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
174153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // Note: audio data may not have been decoded, and the AudioSink may not be opened.
174253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioSink->pause();
174353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    startAudioOffloadPauseTimeout();
174453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
174553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ALOGV("now paused audio queue has %zu entries, video has %zu entries",
174653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia          mAudioQueue.size(), mVideoQueue.size());
174753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
174853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
174953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onResume() {
175053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mPaused) {
175153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
175253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
175353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
175453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // Note: audio data may not have been decoded, and the AudioSink may not be opened.
175553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    cancelAudioOffloadPauseTimeout();
175653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioSink->ready()) {
175753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        status_t err = mAudioSink->start();
175853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err != OK) {
175953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGE("cannot start AudioSink err %d", err);
176053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyAudioTearDown(kDueToError);
176153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
176253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
176353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
176453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    {
176553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        Mutex::Autolock autoLock(mLock);
176653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mPaused = false;
176753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // rendering started message may have been delayed if we were paused.
176853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mRenderingDataDelivered) {
176953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            notifyIfMediaRenderingStarted_l();
177053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
177153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // configure audiosink as we did not do it when pausing
177253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mAudioSink != NULL && mAudioSink->ready()) {
177353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->setPlaybackRate(mPlaybackSettings);
177453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
177553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
177653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mMediaClock->setPlaybackRate(mPlaybackRate);
177753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
177853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (!mAudioQueue.empty()) {
177953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            postDrainAudioQueue_l();
178053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
178153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
178253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
178353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!mVideoQueue.empty()) {
178453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        postDrainVideoQueue();
178553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
178653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
178753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
178853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onSetVideoFrameRate(float fps) {
178953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mVideoScheduler == NULL) {
179053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mVideoScheduler = new VideoFrameScheduler();
179153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
179253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mVideoScheduler->init(fps);
179353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
179453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
179553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaint32_t NuPlayer2::Renderer::getQueueGeneration(bool audio) {
179653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
179753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return (audio ? mAudioQueueGeneration : mVideoQueueGeneration);
179853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
179953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
180053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiaint32_t NuPlayer2::Renderer::getDrainGeneration(bool audio) {
180153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
180253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return (audio ? mAudioDrainGeneration : mVideoDrainGeneration);
180353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
180453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
180553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiabool NuPlayer2::Renderer::getSyncQueues() {
180653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    Mutex::Autolock autoLock(mLock);
180753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return mSyncQueues;
180853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
180953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
181053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onAudioTearDown(AudioTearDownReason reason) {
181153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (mAudioTornDown) {
181253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        return;
181353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
181453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioTornDown = true;
181553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
181653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int64_t currentPositionUs;
181753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> notify = mNotify->dup();
181853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (getCurrentPosition(&currentPositionUs) == OK) {
181953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notify->setInt64("positionUs", currentPositionUs);
182053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
182153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
182253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioSink->stop();
182353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioSink->flush();
182453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
182553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("what", kWhatAudioTearDown);
182653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->setInt32("reason", reason);
182753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->post();
182853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
182953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
183053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::startAudioOffloadPauseTimeout() {
183153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (offloadingAudio()) {
183253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mWakeLock->acquire();
183353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, this);
183453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->setInt32("drainGeneration", mAudioOffloadPauseTimeoutGeneration);
183553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        msg->post(kOffloadPauseMaxUs);
183653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
183753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
183853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
183953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::cancelAudioOffloadPauseTimeout() {
184053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // We may have called startAudioOffloadPauseTimeout() without
184153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // the AudioSink open and with offloadingAudio enabled.
184253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    //
184353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // When we cancel, it may be that offloadingAudio is subsequently disabled, so regardless
184453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // we always release the wakelock and increment the pause timeout generation.
184553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    //
184653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // Note: The acquired wakelock prevents the device from suspending
184753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    // immediately after offload pause (in case a resume happens shortly thereafter).
184853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mWakeLock->release(true);
184953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ++mAudioOffloadPauseTimeoutGeneration;
185053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
185153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
185253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::Renderer::onOpenAudioSink(
185353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &format,
185453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool offloadOnly,
185553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool hasVideo,
185653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        uint32_t flags,
185753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        bool isStreaming) {
185853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
185953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadOnly, offloadingAudio());
186053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    bool audioSinkChanged = false;
186153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
186253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t numChannels;
186353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(format->findInt32("channel-count", &numChannels));
186453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
186553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t channelMask;
186653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!format->findInt32("channel-mask", &channelMask)) {
186753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // signal to the AudioSink to derive the mask from count.
186853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
186953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
187053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
187153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t sampleRate;
187253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(format->findInt32("sample-rate", &sampleRate));
187353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
187453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (offloadingAudio()) {
187553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
187653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        AString mime;
187753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        CHECK(format->findString("mime", &mime));
187853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
187953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
188053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err != OK) {
188153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGE("Couldn't map mime \"%s\" to a valid "
188253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    "audio_format", mime.c_str());
188353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            onDisableOffloadAudio();
188453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        } else {
188553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
188653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mime.c_str(), audioFormat);
188753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
188853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int avgBitRate = -1;
188953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            format->findInt32("bitrate", &avgBitRate);
189053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
189153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            int32_t aacProfile = -1;
189253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (audioFormat == AUDIO_FORMAT_AAC
189353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    && format->findInt32("aac-profile", &aacProfile)) {
189453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Redefine AAC format as per aac profile
189553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mapAACProfileToAudioFormat(
189653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        audioFormat,
189753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                        aacProfile);
189853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
189953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
190053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
190153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.duration_us = -1;
190253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            format->findInt64(
190353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    "durationUs", &offloadInfo.duration_us);
190453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.sample_rate = sampleRate;
190553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.channel_mask = channelMask;
190653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.format = audioFormat;
190753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
190853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.bit_rate = avgBitRate;
190953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.has_video = hasVideo;
191053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadInfo.is_streaming = isStreaming;
191153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
191253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
191353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGV("openAudioSink: no change in offload mode");
191453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // no change from previous configuration, everything ok.
191553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                return OK;
191653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
191753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
191853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
191953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("openAudioSink: try to open AudioSink in offload mode");
192053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            uint32_t offloadFlags = flags;
192153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
192253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
192353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            audioSinkChanged = true;
192453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->close();
192553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
192653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            err = mAudioSink->open(
192753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    sampleRate,
192853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    numChannels,
192953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    (audio_channel_mask_t)channelMask,
193053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    audioFormat,
193153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    0 /* bufferCount - unused */,
193253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    &NuPlayer2::Renderer::AudioSinkCallback,
193353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    this,
193453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    (audio_output_flags_t)offloadFlags,
193553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    &offloadInfo);
193653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
193753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (err == OK) {
193853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                err = mAudioSink->setPlaybackRate(mPlaybackSettings);
193953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
194053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
194153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (err == OK) {
194253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // If the playback is offloaded to h/w, we pass
194353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // the HAL some metadata information.
194453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // We don't want to do this for PCM because it
194553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // will be going through the AudioFlinger mixer
194653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // before reaching the hardware.
194753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // TODO
194853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mCurrentOffloadInfo = offloadInfo;
194953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                if (!mPaused) { // for preview mode, don't start if paused
195053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    err = mAudioSink->start();
195153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                }
195253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
195353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
195453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            if (err != OK) {
195553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                // Clean up, fall back to non offload mode.
195653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mAudioSink->close();
195753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                onDisableOffloadAudio();
195853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
195953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ALOGV("openAudioSink: offload failed");
196053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                if (offloadOnly) {
196153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    notifyAudioTearDown(kForceNonOffload);
196253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                }
196353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            } else {
196453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                mUseAudioCallback = true;  // offload mode transfers data through callback
196553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                ++mAudioDrainGeneration;  // discard pending kWhatDrainAudioQueue message.
196653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            }
196753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
196853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
196953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (!offloadOnly && !offloadingAudio()) {
197053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        ALOGV("openAudioSink: open AudioSink in NON-offload mode");
197153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        uint32_t pcmFlags = flags;
197253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
197353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
197453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const PcmInfo info = {
197553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                (audio_channel_mask_t)channelMask,
197653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                (audio_output_flags_t)pcmFlags,
197753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
197853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                numChannels,
197953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                sampleRate
198053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        };
198153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) {
198253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGV("openAudioSink: no change in pcm mode");
198353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            // no change from previous configuration, everything ok.
198453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return OK;
198553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
198653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
198753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        audioSinkChanged = true;
198853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mAudioSink->close();
198953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
199053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // Note: It is possible to set up the callback, but not use it to send audio data.
199153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // This requires a fix in AudioSink to explicitly specify the transfer mode.
199253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mUseAudioCallback = getUseAudioCallbackSetting();
199353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (mUseAudioCallback) {
199453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ++mAudioDrainGeneration;  // discard pending kWhatDrainAudioQueue message.
199553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
199653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
199753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // Compute the desired buffer size.
199853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // For callback mode, the amount of time before wakeup is about half the buffer size.
199953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const uint32_t frameCount =
200053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000;
200153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
200253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // The doNotReconnect means AudioSink will signal back and let NuPlayer2 to re-construct
200353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // AudioSink. We don't want this when there's video because it will cause a video seek to
200453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // the previous I frame. But we do want this when there's only audio because it will give
200553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // NuPlayer2 a chance to switch from non-offload mode to offload mode.
200653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // So we only set doNotReconnect when there's no video.
200753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const bool doNotReconnect = !hasVideo;
200853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
200953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        // We should always be able to set our playback settings if the sink is closed.
201053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK,
201153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                "onOpenAudioSink: can't set playback rate on closed sink");
201253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        status_t err = mAudioSink->open(
201353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    sampleRate,
201453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    numChannels,
201553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    (audio_channel_mask_t)channelMask,
201653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    AUDIO_FORMAT_PCM_16_BIT,
201753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    0 /* bufferCount - unused */,
201853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mUseAudioCallback ? &NuPlayer2::Renderer::AudioSinkCallback : NULL,
201953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    mUseAudioCallback ? this : NULL,
202053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    (audio_output_flags_t)pcmFlags,
202153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    NULL,
202253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    doNotReconnect,
202353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia                    frameCount);
202453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (err != OK) {
202553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            ALOGW("openAudioSink: non offloaded open failed status: %d", err);
202653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->close();
202753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
202853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            return err;
202953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
203053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        mCurrentPcmInfo = info;
203153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        if (!mPaused) { // for preview mode, don't start if paused
203253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia            mAudioSink->start();
203353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        }
203453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
203553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (audioSinkChanged) {
203653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        onAudioSinkChanged();
203753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
203853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioTornDown = false;
203953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    return OK;
204053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
204153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
204253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onCloseAudioSink() {
204353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mAudioSink->close();
204453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
204553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
204653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
204753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
204853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::Renderer::onChangeAudioFormat(
204953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        const sp<AMessage> &meta, const sp<AMessage> &notify) {
205053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    sp<AMessage> format;
205153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(meta->findMessage("format", &format));
205253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
205353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t offloadOnly;
205453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(meta->findInt32("offload-only", &offloadOnly));
205553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
205653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    int32_t hasVideo;
205753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(meta->findInt32("has-video", &hasVideo));
205853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
205953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    uint32_t flags;
206053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(meta->findInt32("flags", (int32_t *)&flags));
206153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
206253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    uint32_t isStreaming;
206353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    CHECK(meta->findInt32("isStreaming", (int32_t *)&isStreaming));
206453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
206553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
206653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
206753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    if (err != OK) {
206853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia        notify->setInt32("err", err);
206953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    }
207053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia    notify->post();
207153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}
207253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
207353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia}  // namespace android
207453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia
2075