NuPlayerRenderer.cpp revision 3491232a7c0d953fa021f6a81baee64c44f364f3
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayerRenderer" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerRenderer.h" 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 255bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 26a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu#include <media/stagefright/foundation/AUtils.h> 27bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MediaErrors.h> 28bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MetaData.h> 293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang#include <media/stagefright/Utils.h> 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 31dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar#include <VideoFrameScheduler.h> 32dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 33095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <inttypes.h> 34095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 35f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 37f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink 38f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// is closed to allow the audio DSP to power down. 39a5d316fd802cfc92954527f27e6f32206a896113Eric Laurentstatic const int64_t kOffloadPauseMaxUs = 10000000ll; 40f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 41714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber// static 42714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huberconst int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; 43714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 44f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::Renderer( 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MediaPlayerBase::AudioSink> &sink, 46d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber const sp<AMessage> ¬ify, 47d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber uint32_t flags) 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mAudioSink(sink), 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNotify(notify), 50d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mFlags(flags), 51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumFramesWritten(0), 52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending(false), 53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending(false), 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueueGeneration(0), 55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueueGeneration(0), 56a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs(-1), 57eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeMediaUs(-1), 58eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeRealUs(-1), 59f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten(-1), 60f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs(-1), 61a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs(0ll), 62bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasAudio(false), 63bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasVideo(false), 64a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mPauseStartedTimeRealUs(-1), 65a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mFlushingAudio(false), 66a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mFlushingVideo(false), 677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio(false), 687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo(false), 69bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mSyncQueues(false), 70714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber mPaused(false), 7109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung mVideoSampleReceived(false), 72f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong mVideoRenderingStarted(false), 73cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration(0), 74cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration(0), 75f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu mAudioOffloadPauseTimeoutGeneration(0), 763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioOffloadTornDown(false), 77d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), 78d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mTotalBuffersQueued(0), 79d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mLastAudioBufferDrained(0) { 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 82f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::~Renderer() { 83bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 84bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 85bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 86bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->close(); 87bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 90f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueBuffer( 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, 92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<ABuffer> &buffer, 93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> ¬ifyConsumed) { 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatQueueBuffer, id()); 95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 962d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("buffer", buffer); 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setMessage("notifyConsumed", notifyConsumed); 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 101f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) { 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(finalResult, (status_t)OK); 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatQueueEOS, id()); 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("finalResult", finalResult); 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Renderer::flush(bool audio, bool notifyComplete) { 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio |= notifyComplete; 11528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (mFlushingAudio) { 11628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia return; 11728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio = true; 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo |= notifyComplete; 12128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (mFlushingVideo) { 12228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia return; 12328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingVideo = true; 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatFlush, id()); 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 133f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::signalTimeDiscontinuity() { 134bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 13514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // CHECK(mAudioQueue.empty()); 13614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // CHECK(mVideoQueue.empty()); 137a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setAudioFirstAnchorTime(-1); 138eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAnchorTime(-1, -1); 139a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 14014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mSyncQueues = false; 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jiavoid NuPlayer::Renderer::signalAudioSinkChanged() { 14428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia (new AMessage(kWhatAudioSinkChanged, id()))->post(); 14528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 14628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 14728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jiavoid NuPlayer::Renderer::signalDisableOffloadAudio() { 14828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia (new AMessage(kWhatDisableOffloadAudio, id()))->post(); 14928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 15028a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 151a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::signalEnableOffloadAudio() { 152a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu (new AMessage(kWhatEnableOffloadAudio, id()))->post(); 153a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 154a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 155b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::pause() { 156b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatPause, id()))->post(); 157b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 158b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 159b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::resume() { 160b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatResume, id()))->post(); 161b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 162b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 163c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::setVideoFrameRate(float fps) { 164c851b5de495169d7e9528644c2592746021bd968Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, id()); 165c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->setFloat("frame-rate", fps); 166c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->post(); 167c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 168c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 169a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wustatus_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) { 170a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return getCurrentPosition(mediaUs, ALooper::GetNowUs()); 171a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 172a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 173f592671336be0a061799033e47ceeacb648ed3bfLajos Molnarstatus_t NuPlayer::Renderer::getCurrentPosition( 174f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) { 175a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 176a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (!mHasAudio && !mHasVideo) { 177a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return NO_INIT; 178a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 179a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 180eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mAnchorTimeMediaUs < 0) { 181eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return NO_INIT; 182eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 183f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 184eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs; 185a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 186eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mPauseStartedTimeRealUs != -1) { 187eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu positionUs -= (nowUs - mPauseStartedTimeRealUs); 188eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 189eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 190f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar // limit position to the last queued media time (for video only stream 191f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar // position will be discrete as we don't know how long each frame lasts) 192f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (mAnchorMaxMediaUs >= 0 && !allowPastQueuedVideo) { 193f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (positionUs > mAnchorMaxMediaUs) { 194f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar positionUs = mAnchorMaxMediaUs; 195f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 196f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 197f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 198eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (positionUs < mAudioFirstAnchorTimeMediaUs) { 199eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu positionUs = mAudioFirstAnchorTimeMediaUs; 200a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 201eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 202a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu *mediaUs = (positionUs <= 0) ? 0 : positionUs; 203a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return OK; 204a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 205a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 206a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setHasMedia(bool audio) { 207a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 208a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (audio) { 209a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mHasAudio = true; 210a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } else { 211a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mHasVideo = true; 212a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 213a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 214a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 215a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setAudioFirstAnchorTime(int64_t mediaUs) { 216a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 217a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs = mediaUs; 218a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 219a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 220a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs) { 221a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 222a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mAudioFirstAnchorTimeMediaUs == -1) { 223a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs = mediaUs; 224a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 225a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 226a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 227f592671336be0a061799033e47ceeacb648ed3bfLajos Molnarvoid NuPlayer::Renderer::setAnchorTime( 228f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t mediaUs, int64_t realUs, int64_t numFramesWritten, bool resume) { 229a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 230eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeMediaUs = mediaUs; 231eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeRealUs = realUs; 232f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten = numFramesWritten; 233eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (resume) { 234eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mPauseStartedTimeRealUs = -1; 235eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 236a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 237a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 238a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setVideoLateByUs(int64_t lateUs) { 239a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 240a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs = lateUs; 241a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 242a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 243a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getVideoLateByUs() { 244a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 245a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return mVideoLateByUs; 246a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 247a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 248a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setPauseStartedTimeRealUs(int64_t realUs) { 249a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 250a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mPauseStartedTimeRealUs = realUs; 251a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 252a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 253202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::openAudioSink( 2543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 2553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 2563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 257202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung uint32_t flags, 258202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung bool *isOffloaded) { 2593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, id()); 2603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setMessage("format", format); 2613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("offload-only", offloadOnly); 2623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("has-video", hasVideo); 2633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("flags", flags); 2643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 2653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 2663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 2673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 268202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t err; 269202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (!response->findInt32("err", &err)) { 270202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung err = INVALID_OPERATION; 271202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } else if (err == OK && isOffloaded != NULL) { 272202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t offload; 273202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung CHECK(response->findInt32("offload", &offload)); 274202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung *isOffloaded = (offload != 0); 275202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 276202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 2773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 2783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 2793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::closeAudioSink() { 2803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, id()); 2813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 2823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 2833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 2843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 2853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 286f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 2883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatOpenAudioSink: 2893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 2903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> format; 2913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findMessage("format", &format)); 2923b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 2933b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t offloadOnly; 2943b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("offload-only", &offloadOnly)); 2953b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 2963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t hasVideo; 2973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("has-video", &hasVideo)); 2983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 2993b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags; 3003b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 3013b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 302202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags); 3033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3043b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 305202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("err", err); 306202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("offload", offloadingAudio()); 3073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t replyID; 3093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 3103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 3113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 3133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 3143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatCloseAudioSink: 3163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 3173b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t replyID; 3183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 3193b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3203b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onCloseAudioSink(); 3213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 3233b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 3243b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 3253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 3263b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 327bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatStopAudioSink: 328bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 329bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 330bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 331bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 332bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainAudioQueue: 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("generation", &generation)); 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (generation != mAudioQueueGeneration) { 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 343078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (onDrainAudioQueue()) { 344078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 345078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), 346078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (status_t)OK); 347078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 348078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPendingPlayout = 349078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten - numFramesPlayed; 350078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 351078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // This is how long the audio sink will have data to 352078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // play back. 353078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int64_t delayUs = 354078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->msecsPerFrame() 355078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber * numFramesPendingPlayout * 1000ll; 356078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 357078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // Let's give it more data after about half that time 358078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // has elapsed. 359bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia // kWhatDrainAudioQueue is used for non-offloading mode, 360bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia // and mLock is used only for offloading mode. Therefore, 361bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia // no need to acquire mLock here. 362bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(delayUs / 2); 363078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainVideoQueue: 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("generation", &generation)); 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (generation != mVideoQueueGeneration) { 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainVideoQueue(); 378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 383d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar case kWhatPostDrainVideoQueue: 384d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar { 385d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int32_t generation; 386d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar CHECK(msg->findInt32("generation", &generation)); 387d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (generation != mVideoQueueGeneration) { 388d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 389d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 390d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 391d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = false; 392d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar postDrainVideoQueue(); 393d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 394d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 395d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueBuffer: 397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueBuffer(msg); 399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueEOS: 403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueEOS(msg); 405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFlush(msg); 411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4143831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber case kWhatAudioSinkChanged: 4153831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber { 4163831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber onAudioSinkChanged(); 4173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber break; 4183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 420bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatDisableOffloadAudio: 421bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 422bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia onDisableOffloadAudio(); 423bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 424bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 425bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 426a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu case kWhatEnableOffloadAudio: 427a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu { 428a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu onEnableOffloadAudio(); 429a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu break; 430a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu } 431a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 432b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatPause: 433b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 434b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onPause(); 435b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 436b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 437b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 438b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatResume: 439b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 440b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onResume(); 441b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 442b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 443b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 444c851b5de495169d7e9528644c2592746021bd968Lajos Molnar case kWhatSetVideoFrameRate: 445c851b5de495169d7e9528644c2592746021bd968Lajos Molnar { 446c851b5de495169d7e9528644c2592746021bd968Lajos Molnar float fps; 447c851b5de495169d7e9528644c2592746021bd968Lajos Molnar CHECK(msg->findFloat("frame-rate", &fps)); 448c851b5de495169d7e9528644c2592746021bd968Lajos Molnar onSetVideoFrameRate(fps); 449c851b5de495169d7e9528644c2592746021bd968Lajos Molnar break; 450c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 451c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 4523a2956d148d81194e297408179e84a47a309ef48Wei Jia case kWhatAudioOffloadTearDown: 4533a2956d148d81194e297408179e84a47a309ef48Wei Jia { 4540852917279f79a94907e9906d0533ae409a30f6aRonghua Wu onAudioOffloadTearDown(kDueToError); 4553a2956d148d81194e297408179e84a47a309ef48Wei Jia break; 4563a2956d148d81194e297408179e84a47a309ef48Wei Jia } 4573a2956d148d81194e297408179e84a47a309ef48Wei Jia 458f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu case kWhatAudioOffloadPauseTimeout: 459f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu { 460f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu int32_t generation; 461f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu CHECK(msg->findInt32("generation", &generation)); 462f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (generation != mAudioOffloadPauseTimeoutGeneration) { 463f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 464f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 4650852917279f79a94907e9906d0533ae409a30f6aRonghua Wu ALOGV("Audio Offload tear down due to pause timeout."); 4660852917279f79a94907e9906d0533ae409a30f6aRonghua Wu onAudioOffloadTearDown(kDueToTimeout); 467f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 468f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 469f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 476bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) { 477bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (mDrainAudioQueuePending || mSyncQueues || mPaused 478bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia || offloadingAudio()) { 479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioQueue.empty()) { 483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = true; 487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id()); 488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("generation", mAudioQueueGeneration); 489078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber msg->post(delayUs); 490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 492cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnarvoid NuPlayer::Renderer::prepareForMediaRenderingStart() { 493cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration = mAudioQueueGeneration; 494cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration = mVideoQueueGeneration; 495cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 496cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 497cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnarvoid NuPlayer::Renderer::notifyIfMediaRenderingStarted() { 498cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar if (mVideoRenderingStartGeneration == mVideoQueueGeneration && 499cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration == mAudioQueueGeneration) { 500cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration = -1; 501cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration = -1; 502cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 503cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar sp<AMessage> notify = mNotify->dup(); 504cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->setInt32("what", kWhatMediaRenderingStart); 505cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->post(); 506cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar } 507cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 508cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 509bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia// static 510bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::AudioSinkCallback( 511bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink * /* audioSink */, 512bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *buffer, 513bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t size, 514bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *cookie, 515bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink::cb_event_t event) { 516bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia NuPlayer::Renderer *me = (NuPlayer::Renderer *)cookie; 517bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 518bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia switch (event) { 519bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER: 520bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 521bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return me->fillAudioBuffer(buffer, size); 522bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 523bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 524bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 525bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END: 526bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 527bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia me->notifyEOS(true /* audio */, ERROR_END_OF_STREAM); 528bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 529bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 530bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 531bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN: 532bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 5333a2956d148d81194e297408179e84a47a309ef48Wei Jia me->notifyAudioOffloadTearDown(); 534bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 535bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 536bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 537bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 538bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 539bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 540bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 541bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { 542bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 543bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 54473ddd210ea572375198cac1d4960df793745fb4bWei Jia if (!offloadingAudio() || mPaused) { 545bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 546bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 547bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 548bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia bool hasEOS = false; 549bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 550bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeCopied = 0; 5513e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu bool firstEntry = true; 552bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia while (sizeCopied < size && !mAudioQueue.empty()) { 553bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia QueueEntry *entry = &*mAudioQueue.begin(); 554bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 555bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mBuffer == NULL) { // EOS 556bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia hasEOS = true; 557bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 558bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry = NULL; 559bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 560bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 561bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 5623e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu if (firstEntry && entry->mOffset == 0) { 5633e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu firstEntry = false; 564bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int64_t mediaTimeUs; 565bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 566bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 567f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAudioFirstAnchorTimeIfNeeded(mediaTimeUs); 568bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 569bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 570bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t copy = entry->mBuffer->size() - entry->mOffset; 571bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeRemaining = size - sizeCopied; 572bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (copy > sizeRemaining) { 573bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy = sizeRemaining; 574bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 575bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 576bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia memcpy((char *)buffer + sizeCopied, 577bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mBuffer->data() + entry->mOffset, 578bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy); 579bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 580bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mOffset += copy; 581bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mOffset == entry->mBuffer->size()) { 582bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mNotifyConsumed->post(); 583bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 584bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry = NULL; 585bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 586bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia sizeCopied += copy; 587bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia notifyIfMediaRenderingStarted(); 588bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 589bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 590f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (mAudioFirstAnchorTimeMediaUs >= 0) { 591f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 592f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAnchorTime(mAudioFirstAnchorTimeMediaUs, nowUs - getPlayedOutAudioDurationUs(nowUs)); 593f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 594f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 595f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar // we don't know how much data we are queueing for offloaded tracks 596f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs = -1; 597f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 598bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (hasEOS) { 599bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia (new AMessage(kWhatStopAudioSink, id()))->post(); 600bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 601bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 602bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return sizeCopied; 603bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 604bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 605078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huberbool NuPlayer::Renderer::onDrainAudioQueue() { 606078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 6072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mAudioSink->getPosition(&numFramesPlayed) != OK) { 6082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return false; 6092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 610078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 611078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber ssize_t numFramesAvailableToWrite = 612078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); 613078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 614078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#if 0 615078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (numFramesAvailableToWrite == mAudioSink->frameCount()) { 616df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("audio sink underrun"); 617078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 6183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("audio queue has %d frames left to play", 619078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - numFramesAvailableToWrite); 620078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 621078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#endif 622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 623078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber size_t numBytesAvailableToWrite = 624078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber numFramesAvailableToWrite * mAudioSink->frameSize(); 625078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 626078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) { 627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mAudioQueue.begin(); 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 629d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mLastAudioBufferDrained = entry->mBufferOrdinal; 630d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 6335095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu int64_t postEOSDelayUs = 0; 6345095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu if (mAudioSink->needsTrailingPadding()) { 63506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); 6365095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu } 6375095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); 638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 6413491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung if (mAudioSink->needsTrailingPadding()) { 6423491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // If we're not in gapless playback (i.e. through setNextPlayer), we 6433491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // need to stop the track here, because that will play out the last 6443491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // little bit at the end of the file. Otherwise short files won't play. 6453491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mAudioSink->stop(); 6463491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mNumFramesWritten = 0; 6473491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung } 648078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return false; 649c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 650c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == 0) { 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 6543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 655eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu onNewAudioMediaTime(mediaTimeUs); 656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t copy = entry->mBuffer->size() - entry->mOffset; 659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (copy > numBytesAvailableToWrite) { 660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber copy = numBytesAvailableToWrite; 661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 663a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, copy); 664a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written < 0) { 665202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // An error in AudioSink write. Perhaps the AudioSink was not properly opened. 666202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy); 667202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung break; 668a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 670a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung entry->mOffset += written; 671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == entry->mBuffer->size()) { 672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 6749b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent 675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 678a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung numBytesAvailableToWrite -= written; 679a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung size_t copiedFrames = written / mAudioSink->frameSize(); 680078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten += copiedFrames; 681cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 682cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notifyIfMediaRenderingStarted(); 68343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 684a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written != (ssize_t)copy) { 685a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // A short count was received from AudioSink::write() 686a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 687a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // AudioSink write should block until exactly the number of bytes are delivered. 688a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // But it may return with a short count (without an error) when: 689a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 690a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 1) Size to be copied is not a multiple of the frame size. We consider this fatal. 691a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 2) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded. 692a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 693a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // (Case 1) 694a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Must be a multiple of the frame size. If it is not a multiple of a frame size, it 695a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // needs to fail, as we should not carry over fractional frames between calls. 696a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung CHECK_EQ(copy % mAudioSink->frameSize(), 0); 697a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 698a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // (Case 2) 699a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Return early to the caller. 700a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Beware of calling immediately again as this may busy-loop if you are not careful. 701a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung ALOGW("AudioSink write short frame count %zd < %zu", written, copy); 702a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung break; 703a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 704a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 705f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs = 706f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorTimeMediaUs + 707f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL) 708f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar * 1000LL * mAudioSink->msecsPerFrame()); 709f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 710078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return !mAudioQueue.empty(); 711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 71306ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnarint64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) { 71406ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar int64_t writtenAudioDurationUs = 71506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar mNumFramesWritten * 1000LL * mAudioSink->msecsPerFrame(); 71606ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar return writtenAudioDurationUs - getPlayedOutAudioDurationUs(nowUs); 7175095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu} 7185095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu 719a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) { 720a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t currentPositionUs; 721f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (getCurrentPosition(¤tPositionUs, nowUs, true /* allowPastQueuedVideo */) != OK) { 722eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // If failed to get current position, e.g. due to audio clock is not ready, then just 723eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // play out video immediately without delay. 724eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return nowUs; 725a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 726a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return (mediaTimeUs - currentPositionUs) + nowUs; 727a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 728a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 729eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wuvoid NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) { 730eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // TRICKY: vorbis decoder generates multiple frames with the same 731eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // timestamp, so only update on the first frame with a given timestamp 732eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mediaTimeUs == mAnchorTimeMediaUs) { 733eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return; 734eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 735eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAudioFirstAnchorTimeIfNeeded(mediaTimeUs); 736eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu int64_t nowUs = ALooper::GetNowUs(); 737f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAnchorTime( 738f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mediaTimeUs, nowUs + getPendingAudioPlayoutDurationUs(nowUs), mNumFramesWritten); 739eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu} 740eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 741f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::postDrainVideoQueue() { 742fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (mDrainVideoQueuePending 743fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang || mSyncQueues 744fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang || (mPaused && mVideoSampleReceived)) { 745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry &entry = *mVideoQueue.begin(); 753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, id()); 755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("generation", mVideoQueueGeneration); 756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry.mBuffer == NULL) { 758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS doesn't carry a timestamp. 759dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(); 760dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mDrainVideoQueuePending = true; 761dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar return; 762dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 763dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 764dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t delayUs; 765dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 766dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t realTimeUs; 767dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mFlags & FLAG_REAL_TIME) { 768d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t mediaTimeUs; 769d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 770dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mediaTimeUs; 771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 775eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mAnchorTimeMediaUs < 0) { 776eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAnchorTime(mediaTimeUs, nowUs); 777474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia mAnchorMaxMediaUs = mediaTimeUs; 778dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = nowUs; 779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 780a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 782f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (!mHasAudio) { 783f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs = mediaTimeUs + 100000; // smooth out videos >= 10fps 784f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 785d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 786d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // Heuristics to handle situation when media time changed without a 787d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // discontinuity. If we have not drained an audio buffer that was 788d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // received after this buffer, repost in 10 msec. Otherwise repost 789d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // in 500 msec. 790d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar delayUs = realTimeUs - nowUs; 791d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (delayUs > 500000) { 792d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int64_t postDelayUs = 500000; 793d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (mHasAudio && (mLastAudioBufferDrained - entry.mBufferOrdinal) <= 0) { 794d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar postDelayUs = 10000; 795d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 796d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->setWhat(kWhatPostDrainVideoQueue); 797d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->post(postDelayUs); 798d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mVideoScheduler->restart(); 799d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar ALOGI("possible video time jump of %dms, retrying in %dms", 800d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar (int)(delayUs / 1000), (int)(postDelayUs / 1000)); 801d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = true; 802d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar return; 803d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 806dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000; 807dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000); 808dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 809dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar delayUs = realTimeUs - nowUs; 810dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 811095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); 812dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar // post 2 display refreshes before rendering is due 813dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0); 814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = true; 816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 818f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainVideoQueue() { 819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mVideoQueue.begin(); 824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 828c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyEOS(false /* audio */, entry->mFinalResult); 829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 8323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 833a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 837a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t nowUs = -1; 838d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t realTimeUs; 839d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber if (mFlags & FLAG_REAL_TIME) { 840d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs)); 841d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } else { 842d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t mediaTimeUs; 843d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 844d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber 845a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu nowUs = ALooper::GetNowUs(); 846a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 847d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } 848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 849fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang bool tooLate = false; 8503fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 851fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 852a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (nowUs == -1) { 853a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu nowUs = ALooper::GetNowUs(); 854a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 855a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(nowUs - realTimeUs); 856fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang tooLate = (mVideoLateByUs > 40000); 857fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang 858fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (tooLate) { 859fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("video late by %lld us (%.2f secs)", 860fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoLateByUs, mVideoLateByUs / 1E6); 861fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } else { 862fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("rendering video at media time %.2f secs", 863fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang (mFlags & FLAG_REAL_TIME ? realTimeUs : 864eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6); 865fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 866078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 867a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 868eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (!mVideoSampleReceived && !mHasAudio) { 869a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // This will ensure that the first frame after a flush won't be used as anchor 870a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // when renderer is in paused state, because resume can happen any time after seek. 871eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAnchorTime(-1, -1); 87249966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia } 873078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 875dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll); 876683525b61bc1b58b4fd9e1b3ef9ed3b0c3bf34aeGlenn Kasten entry->mNotifyConsumed->setInt32("render", !tooLate); 877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 88043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 881fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = true; 882f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 883fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 884fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mVideoRenderingStarted) { 885fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoRenderingStarted = true; 886fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang notifyVideoRenderingStart(); 887fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 888fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang notifyIfMediaRenderingStarted(); 889fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 892f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dongvoid NuPlayer::Renderer::notifyVideoRenderingStart() { 893f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong sp<AMessage> notify = mNotify->dup(); 894f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->setInt32("what", kWhatVideoRenderingStart); 895f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->post(); 896f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong} 897f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 8985095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wuvoid NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) { 899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatEOS); 901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 902c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notify->setInt32("finalResult", finalResult); 9035095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notify->post(delayUs); 904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9063a2956d148d81194e297408179e84a47a309ef48Wei Jiavoid NuPlayer::Renderer::notifyAudioOffloadTearDown() { 9073a2956d148d81194e297408179e84a47a309ef48Wei Jia (new AMessage(kWhatAudioOffloadTearDown, id()))->post(); 9083a2956d148d81194e297408179e84a47a309ef48Wei Jia} 9093a2956d148d81194e297408179e84a47a309ef48Wei Jia 910f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { 911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 914a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setHasMedia(audio); 915a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 916a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mHasVideo) { 917dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mVideoScheduler == NULL) { 918dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler = new VideoFrameScheduler(); 919dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler->init(); 920dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 921bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 922bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (dropBufferWhileFlushing(audio, msg)) { 924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9272d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 9282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); 932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mBuffer = buffer; 935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mNotifyConsumed = notifyConsumed; 936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = OK; 938d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar entry.mBufferOrdinal = ++mTotalBuffersQueued; 939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 941bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 943bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 949bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 950cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { 951cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 952cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 954cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; 955cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; 956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 957cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { 958cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // EOS signalled on either queue. 959bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 960cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 961cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 963cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstAudioTimeUs; 964cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstVideoTimeUs; 965cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstAudioBuffer->meta() 966cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstAudioTimeUs)); 967cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstVideoBuffer->meta() 968cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstVideoTimeUs)); 969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 970cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t diff = firstVideoTimeUs - firstAudioTimeUs; 971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("queueDiff = %.2f secs", diff / 1E6); 973cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 974cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (diff > 100000ll) { 975cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Audio data starts More than 0.1 secs before video. 976cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Drop some audio. 977cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 978cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (*mAudioQueue.begin()).mNotifyConsumed->post(); 979cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 980cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 982cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 983bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 986bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::syncQueuesDone_l() { 987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mSyncQueues) { 988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSyncQueues = false; 992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mAudioQueue.empty()) { 994bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mVideoQueue.empty()) { 998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1002f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { 1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (dropBufferWhileFlushing(audio, msg)) { 1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t finalResult; 1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = finalResult; 1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1018bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1019b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson if (mAudioQueue.empty() && mSyncQueues) { 1020bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1021b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 1023bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1025b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson if (mVideoQueue.empty() && mSyncQueues) { 1026bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1027bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1028b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1034f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { 10357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t audio, notifyComplete; 1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 103828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 103928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia Mutex::Autolock autoLock(mFlushLock); 104028a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (audio) { 104128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mFlushingAudio = false; 10427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteAudio; 10437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio = false; 104428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } else { 104528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mFlushingVideo = false; 10467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteVideo; 10477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo = false; 104828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 104928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 105028a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If we're currently syncing the queues, i.e. dropping audio while 1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // aligning the first audio/video buffer times and only one of the 1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // two queues has data, we may starve that queue by not requesting 1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // more buffers from the decoder. If the other source then encounters 1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // a discontinuity that leads to flushing, we'll never find the 1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // corresponding discontinuity on the other queue. 1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Therefore we'll stop syncing the queues if at least one of them 1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // is flushed. 1059bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 1060bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1061bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1062a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setPauseStartedTimeRealUs(-1); 1063f83408b41bbd796b7923d719e7e3799ddc7acaffRonghua Wu setAnchorTime(-1, -1); 1064bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1066cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar ALOGV("flushing %s", audio ? "audio" : "video"); 1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1068bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 1069bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1070bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia flushQueue(&mAudioQueue); 1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 107228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia ++mAudioQueueGeneration; 107328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia prepareForMediaRenderingStart(); 107428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 107528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (offloadingAudio()) { 1076a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setAudioFirstAnchorTime(-1); 107728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 107828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 1081cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1082bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1083bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->pause(); 1084bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 1085bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->start(); 1086bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushQueue(&mVideoQueue); 1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++mVideoQueueGeneration; 1092cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1093c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler != NULL) { 1094c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->restart(); 1095c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1096c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 1097cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar prepareForMediaRenderingStart(); 1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1100fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = false; 11017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 11027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 11037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyFlushComplete(audio); 11047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1107f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) { 1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (!queue->empty()) { 1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*queue->begin(); 1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer != NULL) { 1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber queue->erase(queue->begin()); 1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1120f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyFlushComplete(bool audio) { 1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatFlushComplete); 1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::Renderer::dropBufferWhileFlushing( 1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, const sp<AMessage> &msg) { 1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool flushing = false; 1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushing = mFlushingAudio; 1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushing = mFlushingVideo; 1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!flushing) { 1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg->findMessage("notifyConsumed", ¬ifyConsumed)) { 1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyConsumed->post(); 1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 11523831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::onAudioSinkChanged() { 1153bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1154bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return; 1155bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 11563831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK(!mDrainAudioQueuePending); 11573831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mNumFramesWritten = 0; 1158f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten = -1; 11594110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen uint32_t written; 11604110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen if (mAudioSink->getFramesWritten(&written) == OK) { 11614110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen mNumFramesWritten = written; 11624110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen } 11633831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 11643831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 1165bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::onDisableOffloadAudio() { 1166bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1167bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mFlags &= ~FLAG_OFFLOAD_AUDIO; 11683a2956d148d81194e297408179e84a47a309ef48Wei Jia ++mAudioQueueGeneration; 1169bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 1170bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 1171a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::onEnableOffloadAudio() { 1172a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu Mutex::Autolock autoLock(mLock); 1173a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu mFlags |= FLAG_OFFLOAD_AUDIO; 1174a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu ++mAudioQueueGeneration; 1175a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 1176a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 1177b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onPause() { 11788592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad if (mPaused) { 11798592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad ALOGW("Renderer::onPause() called while already paused!"); 11808592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad return; 11818592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad } 118228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 118328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia Mutex::Autolock autoLock(mLock); 118428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia ++mAudioQueueGeneration; 118528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia ++mVideoQueueGeneration; 118628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia prepareForMediaRenderingStart(); 118773ddd210ea572375198cac1d4960df793745fb4bWei Jia mPaused = true; 1188a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setPauseStartedTimeRealUs(ALooper::GetNowUs()); 118928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1190b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 119128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mDrainAudioQueuePending = false; 1192b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mDrainVideoQueuePending = false; 1193cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1194b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 1195b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->pause(); 1196f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu startAudioOffloadPauseTimeout(); 1197b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1198b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1199ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber ALOGV("now paused audio queue has %d entries, video has %d entries", 1200ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber mAudioQueue.size(), mVideoQueue.size()); 1201b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1202b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1203b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onResume() { 1204b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (!mPaused) { 1205b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber return; 1206b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 1207b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1208b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 1209f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu cancelAudioOffloadPauseTimeout(); 1210b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->start(); 1211b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1212b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 121373ddd210ea572375198cac1d4960df793745fb4bWei Jia Mutex::Autolock autoLock(mLock); 1214b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mPaused = false; 1215a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mPauseStartedTimeRealUs != -1) { 1216a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t newAnchorRealUs = 1217eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeRealUs + ALooper::GetNowUs() - mPauseStartedTimeRealUs; 1218f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAnchorTime( 1219f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorTimeMediaUs, newAnchorRealUs, mAnchorNumFramesWritten, true /* resume */); 122049966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia } 1221b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1222b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mAudioQueue.empty()) { 1223bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1224b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1225b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1226b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mVideoQueue.empty()) { 1227b408222bd9479c291874b607acae1425d6154fe7Andreas Huber postDrainVideoQueue(); 1228b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1229b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1230b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1231c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::onSetVideoFrameRate(float fps) { 1232c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler == NULL) { 1233c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler = new VideoFrameScheduler(); 1234c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1235c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->init(fps); 1236c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 1237c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 123809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// TODO: Remove unnecessary calls to getPlayedOutAudioDurationUs() 123909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// as it acquires locks and may query the audio driver. 124009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// 124109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// Some calls could conceivably retrieve extrapolated data instead of 124209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// accessing getTimestamp() or getPosition() every time a data buffer with 124309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// a media time is received. 124409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// 124506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnarint64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) { 12463a2956d148d81194e297408179e84a47a309ef48Wei Jia uint32_t numFramesPlayed; 124706ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar int64_t numFramesPlayedAt; 124806ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar AudioTimestamp ts; 124909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung static const int64_t kStaleTimestamp100ms = 100000; 125009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung 125106ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar status_t res = mAudioSink->getTimestamp(ts); 125209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung if (res == OK) { // case 1: mixing audio tracks and offloaded tracks. 125306ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayed = ts.mPosition; 125406ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayedAt = 125506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000; 125609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung const int64_t timestampAge = nowUs - numFramesPlayedAt; 125709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung if (timestampAge > kStaleTimestamp100ms) { 125809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // This is an audio FIXME. 125909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // getTimestamp returns a timestamp which may come from audio mixing threads. 126009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // After pausing, the MixerThread may go idle, thus the mTime estimate may 126109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // become stale. Assuming that the MixerThread runs 20ms, with FastMixer at 5ms, 126209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // the max latency should be about 25ms with an average around 12ms (to be verified). 126309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // For safety we use 100ms. 12642abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung ALOGV("getTimestamp: returned stale timestamp nowUs(%lld) numFramesPlayedAt(%lld)", 126509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung (long long)nowUs, (long long)numFramesPlayedAt); 126609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung numFramesPlayedAt = nowUs - kStaleTimestamp100ms; 126709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } 126809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAt); 126909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } else if (res == WOULD_BLOCK) { // case 2: transitory state on start of a new track 127009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung numFramesPlayed = 0; 127109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung numFramesPlayedAt = nowUs; 127209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //ALOGD("getTimestamp: WOULD_BLOCK %d %lld", 127309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // numFramesPlayed, (long long)numFramesPlayedAt); 127409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } else { // case 3: transitory at new track or audio fast tracks. 127506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar res = mAudioSink->getPosition(&numFramesPlayed); 127606ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar CHECK_EQ(res, (status_t)OK); 127706ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayedAt = nowUs; 127806ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */ 127909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //ALOGD("getPosition: %d %lld", numFramesPlayed, numFramesPlayedAt); 128006ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar } 128109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung 128209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours. 128309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //CHECK_EQ(numFramesPlayed & (1 << 31), 0); // can't be negative until 12.4 hrs, test 1284eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000LL * mAudioSink->msecsPerFrame()) 128506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar + nowUs - numFramesPlayedAt; 128609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung if (durationUs < 0) { 128709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // Occurs when numFramesPlayed position is very small and the following: 128809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // (1) In case 1, the time nowUs is computed before getTimestamp() is called and 128909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // numFramesPlayedAt is greater than nowUs by time more than numFramesPlayed. 129009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // (2) In case 3, using getPosition and adding mAudioSink->latency() to 129109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // numFramesPlayedAt, by a time amount greater than numFramesPlayed. 129209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // 129309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // Both of these are transitory conditions. 12942abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung ALOGV("getPlayedOutAudioDurationUs: negative duration %lld set to zero", (long long)durationUs); 129509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung durationUs = 0; 129609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } 129709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung ALOGV("getPlayedOutAudioDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)", 129809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung (long long)durationUs, (long long)nowUs, numFramesPlayed, (long long)numFramesPlayedAt); 129909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung return durationUs; 130006ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar} 13013a2956d148d81194e297408179e84a47a309ef48Wei Jia 13020852917279f79a94907e9906d0533ae409a30f6aRonghua Wuvoid NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reason) { 1303f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (mAudioOffloadTornDown) { 1304f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu return; 1305f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1306f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu mAudioOffloadTornDown = true; 1307f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1308a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t currentPositionUs; 1309a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (getCurrentPosition(¤tPositionUs) != OK) { 1310a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu currentPositionUs = 0; 131128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 131206ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar 13133a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->stop(); 13143a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->flush(); 13153a2956d148d81194e297408179e84a47a309ef48Wei Jia 13163a2956d148d81194e297408179e84a47a309ef48Wei Jia sp<AMessage> notify = mNotify->dup(); 13173a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->setInt32("what", kWhatAudioOffloadTearDown); 13183a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->setInt64("positionUs", currentPositionUs); 13190852917279f79a94907e9906d0533ae409a30f6aRonghua Wu notify->setInt32("reason", reason); 13203a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->post(); 13213a2956d148d81194e297408179e84a47a309ef48Wei Jia} 13223a2956d148d81194e297408179e84a47a309ef48Wei Jia 1323f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::startAudioOffloadPauseTimeout() { 1324f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 1325f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, id()); 1326f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu msg->setInt32("generation", mAudioOffloadPauseTimeoutGeneration); 1327f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu msg->post(kOffloadPauseMaxUs); 1328f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1329f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1330f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1331f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() { 1332f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 1333f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu ++mAudioOffloadPauseTimeoutGeneration; 1334f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1335f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1336f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1337202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::onOpenAudioSink( 13383b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 13393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 13403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 13413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags) { 13423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)", 13433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadOnly, offloadingAudio()); 13443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool audioSinkChanged = false; 13453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t numChannels; 13473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("channel-count", &numChannels)); 13483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t channelMask; 13503b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!format->findInt32("channel-mask", &channelMask)) { 13513b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // signal to the AudioSink to derive the mask from count. 13523b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 13533b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 13543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t sampleRate; 13563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("sample-rate", &sampleRate)); 13573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (offloadingAudio()) { 13593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; 13603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AString mime; 13613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findString("mime", &mime)); 13623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str()); 13633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 13653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGE("Couldn't map mime \"%s\" to a valid " 13663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "audio_format", mime.c_str()); 13673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 13683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } else { 13693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("Mime \"%s\" mapped to audio_format 0x%x", 13703b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mime.c_str(), audioFormat); 13713b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int avgBitRate = -1; 13733b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt32("bit-rate", &avgBitRate); 13743b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13753b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t aacProfile = -1; 13763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioFormat == AUDIO_FORMAT_AAC 13773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang && format->findInt32("aac-profile", &aacProfile)) { 13783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Redefine AAC format as per aac profile 13793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mapAACProfileToAudioFormat( 13803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 13813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang aacProfile); 13823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 13833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 13853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.duration_us = -1; 13863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt64( 13873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "durationUs", &offloadInfo.duration_us); 13883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.sample_rate = sampleRate; 13893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.channel_mask = channelMask; 13903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.format = audioFormat; 13913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.stream_type = AUDIO_STREAM_MUSIC; 13923b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.bit_rate = avgBitRate; 13933b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.has_video = hasVideo; 13943b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.is_streaming = true; 13953b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 13963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) { 13973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: no change in offload mode"); 13983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // no change from previous configuration, everything ok. 1399202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 14003b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14013b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: try to open AudioSink in offload mode"); 1402d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t offloadFlags = flags; 1403d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1404d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 14053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 14063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 14073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang err = mAudioSink->open( 14083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 14093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 14103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 14113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 14123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 8 /* bufferCount */, 14133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &NuPlayer::Renderer::AudioSinkCallback, 14143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang this, 1415d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent (audio_output_flags_t)offloadFlags, 14163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &offloadInfo); 14173b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err == OK) { 14193b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // If the playback is offloaded to h/w, we pass 14203b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // the HAL some metadata information. 14213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // We don't want to do this for PCM because it 14223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // will be going through the AudioFlinger mixer 14233b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // before reaching the hardware. 14243b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // TODO 14253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = offloadInfo; 14263b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang err = mAudioSink->start(); 14273b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV_IF(err == OK, "openAudioSink: offload succeeded"); 14283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 14303b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Clean up, fall back to non offload mode. 14313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 14323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 14333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 14343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offload failed"); 14353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14373b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14383b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!offloadOnly && !offloadingAudio()) { 14393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: open AudioSink in NON-offload mode"); 1440d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t pcmFlags = flags; 1441d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 14423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 14433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 14443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 1445202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = mAudioSink->open( 14463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 14473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 14483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 14493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AUDIO_FORMAT_PCM_16_BIT, 14503b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 8 /* bufferCount */, 14513b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang NULL, 14523b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang NULL, 1453202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung (audio_output_flags_t)pcmFlags); 1454202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (err != OK) { 1455202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGW("openAudioSink: non offloaded open failed status: %d", err); 1456202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 1457202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 14583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->start(); 14593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioSinkChanged) { 14613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onAudioSinkChanged(); 14623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 1463a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu if (offloadingAudio()) { 1464a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu mAudioOffloadTornDown = false; 1465a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu } 1466202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 14673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 14683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::onCloseAudioSink() { 14703b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 14713b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 14723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 14733b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1476