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> ¬ify, 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> ¬ifyConsumed) { 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> ¬ify) { 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", ¬ify)); 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", ¬ifyConsumed)); 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", ¬ifyConsumed)) { 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(¤tPositionUs) == 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> ¬ify) { 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