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> 2735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include <media/stagefright/foundation/AWakeLock.h> 28bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MediaErrors.h> 29bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MetaData.h> 303b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang#include <media/stagefright/Utils.h> 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 32dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar#include <VideoFrameScheduler.h> 33dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 34095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <inttypes.h> 35095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 36f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 38f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink 39f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// is closed to allow the audio DSP to power down. 40a5d316fd802cfc92954527f27e6f32206a896113Eric Laurentstatic const int64_t kOffloadPauseMaxUs = 10000000ll; 41f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 42714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber// static 43f0e83644637bd05852c244df481f21a0d435ff66Andy Hungconst NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = { 44f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_CHANNEL_NONE, 45f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_OUTPUT_FLAG_NONE, 46f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_FORMAT_INVALID, 47f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 0, // mNumChannels 48f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 0 // mSampleRate 49f0e83644637bd05852c244df481f21a0d435ff66Andy Hung}; 50f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 51f0e83644637bd05852c244df481f21a0d435ff66Andy Hung// static 52714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huberconst int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; 53714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 54f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::Renderer( 55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MediaPlayerBase::AudioSink> &sink, 56d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber const sp<AMessage> ¬ify, 57d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber uint32_t flags) 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mAudioSink(sink), 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNotify(notify), 60d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mFlags(flags), 61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumFramesWritten(0), 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending(false), 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending(false), 64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueueGeneration(0), 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueueGeneration(0), 66a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs(-1), 67eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeMediaUs(-1), 68eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeRealUs(-1), 69f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten(-1), 70f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs(-1), 71a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs(0ll), 72bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasAudio(false), 73bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasVideo(false), 74a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mPauseStartedTimeRealUs(-1), 75a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mFlushingAudio(false), 76a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mFlushingVideo(false), 777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio(false), 787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo(false), 79bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mSyncQueues(false), 80714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber mPaused(false), 81cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang mPausePositionMediaTimeUs(-1), 8209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung mVideoSampleReceived(false), 83f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong mVideoRenderingStarted(false), 84cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration(0), 85cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration(0), 86f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu mAudioOffloadPauseTimeoutGeneration(0), 873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioOffloadTornDown(false), 88d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), 89f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER), 90d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mTotalBuffersQueued(0), 9135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mLastAudioBufferDrained(0), 9235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock(new AWakeLock()) { 9335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 96f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::~Renderer() { 97bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 98bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 99bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 100bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->close(); 101bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 104f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueBuffer( 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<ABuffer> &buffer, 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> ¬ifyConsumed) { 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatQueueBuffer, id()); 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 1102d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("buffer", buffer); 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setMessage("notifyConsumed", notifyConsumed); 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 115f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) { 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(finalResult, (status_t)OK); 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatQueueEOS, id()); 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("finalResult", finalResult); 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Renderer::flush(bool audio, bool notifyComplete) { 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio |= notifyComplete; 12928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (mFlushingAudio) { 13028a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia return; 13128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio = true; 133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo |= notifyComplete; 13528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (mFlushingVideo) { 13628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia return; 13728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingVideo = true; 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatFlush, id()); 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 147f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::signalTimeDiscontinuity() { 148bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 14914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // CHECK(mAudioQueue.empty()); 15014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // CHECK(mVideoQueue.empty()); 151a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setAudioFirstAnchorTime(-1); 152eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAnchorTime(-1, -1); 153a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 15414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mSyncQueues = false; 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 15728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jiavoid NuPlayer::Renderer::signalAudioSinkChanged() { 15828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia (new AMessage(kWhatAudioSinkChanged, id()))->post(); 15928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 16028a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 16128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jiavoid NuPlayer::Renderer::signalDisableOffloadAudio() { 16228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia (new AMessage(kWhatDisableOffloadAudio, id()))->post(); 16328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 16428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 165a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::signalEnableOffloadAudio() { 166a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu (new AMessage(kWhatEnableOffloadAudio, id()))->post(); 167a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 168a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 169b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::pause() { 170b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatPause, id()))->post(); 171b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 172b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 173b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::resume() { 174b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatResume, id()))->post(); 175b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 176b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 177c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::setVideoFrameRate(float fps) { 178c851b5de495169d7e9528644c2592746021bd968Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, id()); 179c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->setFloat("frame-rate", fps); 180c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->post(); 181c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 182c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 183d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// Called on any threads, except renderer's thread. 184a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wustatus_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) { 185d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia { 186d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia Mutex::Autolock autoLock(mLock); 187d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia int64_t currentPositionUs; 188d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia if (getCurrentPositionIfPaused_l(¤tPositionUs)) { 189d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia *mediaUs = currentPositionUs; 190d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return OK; 191d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia } 192d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia } 193d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return getCurrentPositionFromAnchor(mediaUs, ALooper::GetNowUs()); 194d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia} 195d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia 196d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// Called on only renderer's thread. 197d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jiastatus_t NuPlayer::Renderer::getCurrentPositionOnLooper(int64_t *mediaUs) { 198d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return getCurrentPositionOnLooper(mediaUs, ALooper::GetNowUs()); 199a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 200a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 201d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// Called on only renderer's thread. 202d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// Since mPaused and mPausePositionMediaTimeUs are changed only on renderer's 203d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// thread, no need to acquire mLock. 204d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jiastatus_t NuPlayer::Renderer::getCurrentPositionOnLooper( 205d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) { 206d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia int64_t currentPositionUs; 207d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia if (getCurrentPositionIfPaused_l(¤tPositionUs)) { 208d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia *mediaUs = currentPositionUs; 209d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return OK; 210d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia } 211d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return getCurrentPositionFromAnchor(mediaUs, nowUs, allowPastQueuedVideo); 212d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia} 213d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia 214d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// Called either with mLock acquired or on renderer's thread. 215d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jiabool NuPlayer::Renderer::getCurrentPositionIfPaused_l(int64_t *mediaUs) { 216cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang if (!mPaused || mPausePositionMediaTimeUs < 0ll) { 217d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return false; 218d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia } 219d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia *mediaUs = mPausePositionMediaTimeUs; 220d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia return true; 221d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia} 222d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia 223d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia// Called on any threads. 224d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jiastatus_t NuPlayer::Renderer::getCurrentPositionFromAnchor( 225f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) { 226a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 227a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (!mHasAudio && !mHasVideo) { 228a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return NO_INIT; 229a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 230a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 231eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mAnchorTimeMediaUs < 0) { 232eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return NO_INIT; 233eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 234f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 235eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs; 236a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 237eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mPauseStartedTimeRealUs != -1) { 238eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu positionUs -= (nowUs - mPauseStartedTimeRealUs); 239eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 240eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 241f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar // limit position to the last queued media time (for video only stream 242f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar // position will be discrete as we don't know how long each frame lasts) 243f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (mAnchorMaxMediaUs >= 0 && !allowPastQueuedVideo) { 244f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (positionUs > mAnchorMaxMediaUs) { 245f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar positionUs = mAnchorMaxMediaUs; 246f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 247f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 248f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 249eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (positionUs < mAudioFirstAnchorTimeMediaUs) { 250eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu positionUs = mAudioFirstAnchorTimeMediaUs; 251a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 252eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 253a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu *mediaUs = (positionUs <= 0) ? 0 : positionUs; 254a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return OK; 255a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 256a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 257a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setHasMedia(bool audio) { 258a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 259a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (audio) { 260a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mHasAudio = true; 261a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } else { 262a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mHasVideo = true; 263a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 264a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 265a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 266a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setAudioFirstAnchorTime(int64_t mediaUs) { 267a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 268a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs = mediaUs; 269a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 270a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 271a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs) { 272a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 273a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mAudioFirstAnchorTimeMediaUs == -1) { 274a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs = mediaUs; 275a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 276a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 277a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 278f592671336be0a061799033e47ceeacb648ed3bfLajos Molnarvoid NuPlayer::Renderer::setAnchorTime( 279f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t mediaUs, int64_t realUs, int64_t numFramesWritten, bool resume) { 280a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 281eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeMediaUs = mediaUs; 282eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeRealUs = realUs; 283f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten = numFramesWritten; 284eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (resume) { 285eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mPauseStartedTimeRealUs = -1; 286eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 287a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 288a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 289a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setVideoLateByUs(int64_t lateUs) { 290a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 291a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs = lateUs; 292a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 293a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 294a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getVideoLateByUs() { 295a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 296a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return mVideoLateByUs; 297a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 298a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 299a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setPauseStartedTimeRealUs(int64_t realUs) { 300a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu Mutex::Autolock autoLock(mTimeLock); 301a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mPauseStartedTimeRealUs = realUs; 302a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 303a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 304202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::openAudioSink( 3053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 3063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 3073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 308202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung uint32_t flags, 309202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung bool *isOffloaded) { 3103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, id()); 3113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setMessage("format", format); 3123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("offload-only", offloadOnly); 3133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("has-video", hasVideo); 3143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("flags", flags); 3153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 3173b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 3183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 319202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t err; 320202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (!response->findInt32("err", &err)) { 321202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung err = INVALID_OPERATION; 322202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } else if (err == OK && isOffloaded != NULL) { 323202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t offload; 324202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung CHECK(response->findInt32("offload", &offload)); 325202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung *isOffloaded = (offload != 0); 326202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 327202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 3283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 3293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3303b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::closeAudioSink() { 3313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, id()); 3323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 3343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 3353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 3363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 337f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 3393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatOpenAudioSink: 3403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 3413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> format; 3423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findMessage("format", &format)); 3433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t offloadOnly; 3453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("offload-only", &offloadOnly)); 3463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t hasVideo; 3483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("has-video", &hasVideo)); 3493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3503b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags; 3513b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 3523b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 353202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags); 3543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 356202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("err", err); 357202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("offload", offloadingAudio()); 3583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t replyID; 3603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 3613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 3623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 3643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 3653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatCloseAudioSink: 3673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 3683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t replyID; 3693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 3703b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3713b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onCloseAudioSink(); 3723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3733b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 3743b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 3753b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 3763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 3773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 378bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatStopAudioSink: 379bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 380bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 381bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 382bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 383bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainAudioQueue: 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("generation", &generation)); 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (generation != mAudioQueueGeneration) { 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 394078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (onDrainAudioQueue()) { 395078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 396078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), 397078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (status_t)OK); 398078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 399078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPendingPlayout = 400078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten - numFramesPlayed; 401078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 402078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // This is how long the audio sink will have data to 403078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // play back. 404078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int64_t delayUs = 405078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->msecsPerFrame() 406078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber * numFramesPendingPlayout * 1000ll; 407078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 408078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // Let's give it more data after about half that time 409078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // has elapsed. 410bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia // kWhatDrainAudioQueue is used for non-offloading mode, 411bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia // and mLock is used only for offloading mode. Therefore, 412bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia // no need to acquire mLock here. 413bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(delayUs / 2); 414078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainVideoQueue: 419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("generation", &generation)); 422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (generation != mVideoQueueGeneration) { 423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainVideoQueue(); 429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 430231406d597cca1c9c009f870fbb62e46b8475186Wei Jia Mutex::Autolock autoLock(mLock); 431231406d597cca1c9c009f870fbb62e46b8475186Wei Jia postDrainVideoQueue_l(); 432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 435d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar case kWhatPostDrainVideoQueue: 436d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar { 437d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int32_t generation; 438d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar CHECK(msg->findInt32("generation", &generation)); 439d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (generation != mVideoQueueGeneration) { 440d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 441d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 442d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 443d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = false; 444231406d597cca1c9c009f870fbb62e46b8475186Wei Jia Mutex::Autolock autoLock(mLock); 445231406d597cca1c9c009f870fbb62e46b8475186Wei Jia postDrainVideoQueue_l(); 446d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 447d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 448d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueBuffer: 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueBuffer(msg); 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueEOS: 456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueEOS(msg); 458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFlush(msg); 464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4673831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber case kWhatAudioSinkChanged: 4683831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber { 4693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber onAudioSinkChanged(); 4703831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber break; 4713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4723831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 473bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatDisableOffloadAudio: 474bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 475bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia onDisableOffloadAudio(); 476bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 477bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 478bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 479a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu case kWhatEnableOffloadAudio: 480a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu { 481a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu onEnableOffloadAudio(); 482a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu break; 483a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu } 484a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 485b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatPause: 486b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 487b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onPause(); 488b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 489b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 490b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 491b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatResume: 492b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 493b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onResume(); 494b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 495b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 496b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 497c851b5de495169d7e9528644c2592746021bd968Lajos Molnar case kWhatSetVideoFrameRate: 498c851b5de495169d7e9528644c2592746021bd968Lajos Molnar { 499c851b5de495169d7e9528644c2592746021bd968Lajos Molnar float fps; 500c851b5de495169d7e9528644c2592746021bd968Lajos Molnar CHECK(msg->findFloat("frame-rate", &fps)); 501c851b5de495169d7e9528644c2592746021bd968Lajos Molnar onSetVideoFrameRate(fps); 502c851b5de495169d7e9528644c2592746021bd968Lajos Molnar break; 503c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 504c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 5053a2956d148d81194e297408179e84a47a309ef48Wei Jia case kWhatAudioOffloadTearDown: 5063a2956d148d81194e297408179e84a47a309ef48Wei Jia { 5070852917279f79a94907e9906d0533ae409a30f6aRonghua Wu onAudioOffloadTearDown(kDueToError); 5083a2956d148d81194e297408179e84a47a309ef48Wei Jia break; 5093a2956d148d81194e297408179e84a47a309ef48Wei Jia } 5103a2956d148d81194e297408179e84a47a309ef48Wei Jia 511f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu case kWhatAudioOffloadPauseTimeout: 512f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu { 513f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu int32_t generation; 514f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu CHECK(msg->findInt32("generation", &generation)); 515f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (generation != mAudioOffloadPauseTimeoutGeneration) { 516f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 517f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 5180852917279f79a94907e9906d0533ae409a30f6aRonghua Wu ALOGV("Audio Offload tear down due to pause timeout."); 5190852917279f79a94907e9906d0533ae409a30f6aRonghua Wu onAudioOffloadTearDown(kDueToTimeout); 52035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->release(); 521f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 522f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 523f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 530bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) { 531bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (mDrainAudioQueuePending || mSyncQueues || mPaused 532bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia || offloadingAudio()) { 533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioQueue.empty()) { 537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = true; 541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id()); 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("generation", mAudioQueueGeneration); 543078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber msg->post(delayUs); 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 546cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnarvoid NuPlayer::Renderer::prepareForMediaRenderingStart() { 547cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration = mAudioQueueGeneration; 548cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration = mVideoQueueGeneration; 549cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 550cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 551cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnarvoid NuPlayer::Renderer::notifyIfMediaRenderingStarted() { 552cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar if (mVideoRenderingStartGeneration == mVideoQueueGeneration && 553cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration == mAudioQueueGeneration) { 554cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration = -1; 555cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration = -1; 556cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 557cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar sp<AMessage> notify = mNotify->dup(); 558cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->setInt32("what", kWhatMediaRenderingStart); 559cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->post(); 560cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar } 561cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 562cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 563bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia// static 564bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::AudioSinkCallback( 565bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink * /* audioSink */, 566bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *buffer, 567bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t size, 568bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *cookie, 569bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink::cb_event_t event) { 570bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia NuPlayer::Renderer *me = (NuPlayer::Renderer *)cookie; 571bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 572bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia switch (event) { 573bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER: 574bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 575bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return me->fillAudioBuffer(buffer, size); 576bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 577bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 578bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 579bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END: 580bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 581bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia me->notifyEOS(true /* audio */, ERROR_END_OF_STREAM); 582bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 583bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 584bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 585bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN: 586bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 5873a2956d148d81194e297408179e84a47a309ef48Wei Jia me->notifyAudioOffloadTearDown(); 588bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 589bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 590bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 591bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 592bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 593bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 594bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 595bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { 596bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 597bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 59873ddd210ea572375198cac1d4960df793745fb4bWei Jia if (!offloadingAudio() || mPaused) { 599bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 600bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 601bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 602bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia bool hasEOS = false; 603bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 604bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeCopied = 0; 6053e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu bool firstEntry = true; 606bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia while (sizeCopied < size && !mAudioQueue.empty()) { 607bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia QueueEntry *entry = &*mAudioQueue.begin(); 608bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 609bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mBuffer == NULL) { // EOS 610bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia hasEOS = true; 611bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 612bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry = NULL; 613bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 614bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 615bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 6163e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu if (firstEntry && entry->mOffset == 0) { 6173e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu firstEntry = false; 618bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int64_t mediaTimeUs; 619bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 620bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 621f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAudioFirstAnchorTimeIfNeeded(mediaTimeUs); 622bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 623bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 624bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t copy = entry->mBuffer->size() - entry->mOffset; 625bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeRemaining = size - sizeCopied; 626bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (copy > sizeRemaining) { 627bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy = sizeRemaining; 628bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 629bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 630bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia memcpy((char *)buffer + sizeCopied, 631bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mBuffer->data() + entry->mOffset, 632bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy); 633bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 634bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mOffset += copy; 635bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mOffset == entry->mBuffer->size()) { 636bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mNotifyConsumed->post(); 637bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 638bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry = NULL; 639bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 640bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia sizeCopied += copy; 641bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia notifyIfMediaRenderingStarted(); 642bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 643bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 644f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (mAudioFirstAnchorTimeMediaUs >= 0) { 645f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 646f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAnchorTime(mAudioFirstAnchorTimeMediaUs, nowUs - getPlayedOutAudioDurationUs(nowUs)); 647f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 648f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 649f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar // we don't know how much data we are queueing for offloaded tracks 650f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs = -1; 651f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 652bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (hasEOS) { 653bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia (new AMessage(kWhatStopAudioSink, id()))->post(); 654bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 655bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 656bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return sizeCopied; 657bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 658bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 659078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huberbool NuPlayer::Renderer::onDrainAudioQueue() { 660078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mAudioSink->getPosition(&numFramesPlayed) != OK) { 6622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return false; 6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 664078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 665078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber ssize_t numFramesAvailableToWrite = 666078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); 667078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 668078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#if 0 669078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (numFramesAvailableToWrite == mAudioSink->frameCount()) { 670df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("audio sink underrun"); 671078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 6723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("audio queue has %d frames left to play", 673078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - numFramesAvailableToWrite); 674078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 675078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#endif 676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 677078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber size_t numBytesAvailableToWrite = 678078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber numFramesAvailableToWrite * mAudioSink->frameSize(); 679078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 680078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) { 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mAudioQueue.begin(); 682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 683d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mLastAudioBufferDrained = entry->mBufferOrdinal; 684d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 6875095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu int64_t postEOSDelayUs = 0; 6885095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu if (mAudioSink->needsTrailingPadding()) { 68906ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); 6905095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu } 6915095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); 692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 6953491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung if (mAudioSink->needsTrailingPadding()) { 6963491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // If we're not in gapless playback (i.e. through setNextPlayer), we 6973491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // need to stop the track here, because that will play out the last 6983491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // little bit at the end of the file. Otherwise short files won't play. 6993491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mAudioSink->stop(); 7003491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mNumFramesWritten = 0; 7013491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung } 702078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return false; 703c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 704c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == 0) { 706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 7083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 709eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu onNewAudioMediaTime(mediaTimeUs); 710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t copy = entry->mBuffer->size() - entry->mOffset; 713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (copy > numBytesAvailableToWrite) { 714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber copy = numBytesAvailableToWrite; 715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 717a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, copy); 718a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written < 0) { 719202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // An error in AudioSink write. Perhaps the AudioSink was not properly opened. 720202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy); 721202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung break; 722a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 724a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung entry->mOffset += written; 725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == entry->mBuffer->size()) { 726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 7289b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent 729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 732a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung numBytesAvailableToWrite -= written; 733a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung size_t copiedFrames = written / mAudioSink->frameSize(); 734078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten += copiedFrames; 735cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 736cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notifyIfMediaRenderingStarted(); 73743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 738a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written != (ssize_t)copy) { 739a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // A short count was received from AudioSink::write() 740a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 741a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // AudioSink write should block until exactly the number of bytes are delivered. 742a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // But it may return with a short count (without an error) when: 743a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 744a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 1) Size to be copied is not a multiple of the frame size. We consider this fatal. 745a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 2) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded. 746a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 747a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // (Case 1) 748a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Must be a multiple of the frame size. If it is not a multiple of a frame size, it 749a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // needs to fail, as we should not carry over fractional frames between calls. 750a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung CHECK_EQ(copy % mAudioSink->frameSize(), 0); 751a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 752a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // (Case 2) 753a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Return early to the caller. 754a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Beware of calling immediately again as this may busy-loop if you are not careful. 755a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung ALOGW("AudioSink write short frame count %zd < %zu", written, copy); 756a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung break; 757a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 758a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 759f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs = 760f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorTimeMediaUs + 761f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL) 762f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar * 1000LL * mAudioSink->msecsPerFrame()); 763f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 764078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return !mAudioQueue.empty(); 765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 76706ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnarint64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) { 76806ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar int64_t writtenAudioDurationUs = 76906ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar mNumFramesWritten * 1000LL * mAudioSink->msecsPerFrame(); 77006ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar return writtenAudioDurationUs - getPlayedOutAudioDurationUs(nowUs); 7715095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu} 7725095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu 773a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) { 774a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t currentPositionUs; 775231406d597cca1c9c009f870fbb62e46b8475186Wei Jia if (mPaused || getCurrentPositionOnLooper( 776d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia ¤tPositionUs, nowUs, true /* allowPastQueuedVideo */) != OK) { 777eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // If failed to get current position, e.g. due to audio clock is not ready, then just 778eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // play out video immediately without delay. 779eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return nowUs; 780a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 781a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return (mediaTimeUs - currentPositionUs) + nowUs; 782a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 783a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 784eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wuvoid NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) { 785eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // TRICKY: vorbis decoder generates multiple frames with the same 786eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // timestamp, so only update on the first frame with a given timestamp 787eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mediaTimeUs == mAnchorTimeMediaUs) { 788eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return; 789eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 790eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAudioFirstAnchorTimeIfNeeded(mediaTimeUs); 791eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu int64_t nowUs = ALooper::GetNowUs(); 792f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAnchorTime( 793f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mediaTimeUs, nowUs + getPendingAudioPlayoutDurationUs(nowUs), mNumFramesWritten); 794eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu} 795eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 796231406d597cca1c9c009f870fbb62e46b8475186Wei Jiavoid NuPlayer::Renderer::postDrainVideoQueue_l() { 797fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (mDrainVideoQueuePending 798fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang || mSyncQueues 799fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang || (mPaused && mVideoSampleReceived)) { 800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry &entry = *mVideoQueue.begin(); 808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, id()); 810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("generation", mVideoQueueGeneration); 811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry.mBuffer == NULL) { 813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS doesn't carry a timestamp. 814dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(); 815dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mDrainVideoQueuePending = true; 816dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar return; 817dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 818dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 819dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t delayUs; 820dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 821dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t realTimeUs; 822dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mFlags & FLAG_REAL_TIME) { 823d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t mediaTimeUs; 824d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 825dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mediaTimeUs; 826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 830eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mAnchorTimeMediaUs < 0) { 831eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAnchorTime(mediaTimeUs, nowUs); 832231406d597cca1c9c009f870fbb62e46b8475186Wei Jia mPausePositionMediaTimeUs = mediaTimeUs; 833474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia mAnchorMaxMediaUs = mediaTimeUs; 834dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = nowUs; 835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 836a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 838f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (!mHasAudio) { 839f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorMaxMediaUs = mediaTimeUs + 100000; // smooth out videos >= 10fps 840f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 841d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 842d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // Heuristics to handle situation when media time changed without a 843d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // discontinuity. If we have not drained an audio buffer that was 844d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // received after this buffer, repost in 10 msec. Otherwise repost 845d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // in 500 msec. 846d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar delayUs = realTimeUs - nowUs; 847d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (delayUs > 500000) { 848d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int64_t postDelayUs = 500000; 849d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (mHasAudio && (mLastAudioBufferDrained - entry.mBufferOrdinal) <= 0) { 850d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar postDelayUs = 10000; 851d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 852d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->setWhat(kWhatPostDrainVideoQueue); 853d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->post(postDelayUs); 854d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mVideoScheduler->restart(); 855d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar ALOGI("possible video time jump of %dms, retrying in %dms", 856d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar (int)(delayUs / 1000), (int)(postDelayUs / 1000)); 857d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = true; 858d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar return; 859d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 862dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000; 863dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000); 864dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 865dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar delayUs = realTimeUs - nowUs; 866dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 867095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); 868dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar // post 2 display refreshes before rendering is due 869dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0); 870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = true; 872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 874f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainVideoQueue() { 875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mVideoQueue.begin(); 880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 884c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyEOS(false /* audio */, entry->mFinalResult); 885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 8883fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 889a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 893a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t nowUs = -1; 894d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t realTimeUs; 895d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber if (mFlags & FLAG_REAL_TIME) { 896d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs)); 897d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } else { 898d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t mediaTimeUs; 899d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 900d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber 901a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu nowUs = ALooper::GetNowUs(); 902a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 903d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } 904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 905fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang bool tooLate = false; 9063fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 907fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 908a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (nowUs == -1) { 909a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu nowUs = ALooper::GetNowUs(); 910a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 911a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(nowUs - realTimeUs); 912fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang tooLate = (mVideoLateByUs > 40000); 913fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang 914fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (tooLate) { 915fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("video late by %lld us (%.2f secs)", 916fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoLateByUs, mVideoLateByUs / 1E6); 917fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } else { 918fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("rendering video at media time %.2f secs", 919fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang (mFlags & FLAG_REAL_TIME ? realTimeUs : 920eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6); 921fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 922078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 923a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 924eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (!mVideoSampleReceived && !mHasAudio) { 925a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // This will ensure that the first frame after a flush won't be used as anchor 926a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // when renderer is in paused state, because resume can happen any time after seek. 927eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu setAnchorTime(-1, -1); 92849966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia } 929078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 931dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll); 932683525b61bc1b58b4fd9e1b3ef9ed3b0c3bf34aeGlenn Kasten entry->mNotifyConsumed->setInt32("render", !tooLate); 933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 93643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 937fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = true; 938f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 939fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 940fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mVideoRenderingStarted) { 941fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoRenderingStarted = true; 942fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang notifyVideoRenderingStart(); 943fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 944fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang notifyIfMediaRenderingStarted(); 945fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 948f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dongvoid NuPlayer::Renderer::notifyVideoRenderingStart() { 949f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong sp<AMessage> notify = mNotify->dup(); 950f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->setInt32("what", kWhatVideoRenderingStart); 951f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->post(); 952f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong} 953f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 9545095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wuvoid NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) { 955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatEOS); 957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 958c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notify->setInt32("finalResult", finalResult); 9595095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notify->post(delayUs); 960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9623a2956d148d81194e297408179e84a47a309ef48Wei Jiavoid NuPlayer::Renderer::notifyAudioOffloadTearDown() { 9633a2956d148d81194e297408179e84a47a309ef48Wei Jia (new AMessage(kWhatAudioOffloadTearDown, id()))->post(); 9643a2956d148d81194e297408179e84a47a309ef48Wei Jia} 9653a2956d148d81194e297408179e84a47a309ef48Wei Jia 966f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { 967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 970a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setHasMedia(audio); 971a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 972a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mHasVideo) { 973dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mVideoScheduler == NULL) { 974dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler = new VideoFrameScheduler(); 975dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler->init(); 976dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 977bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 978bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (dropBufferWhileFlushing(audio, msg)) { 980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9832d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 9842d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); 988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mBuffer = buffer; 991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mNotifyConsumed = notifyConsumed; 992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = OK; 994d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar entry.mBufferOrdinal = ++mTotalBuffersQueued; 995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 996231406d597cca1c9c009f870fbb62e46b8475186Wei Jia Mutex::Autolock autoLock(mLock); 997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 999bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 1002231406d597cca1c9c009f870fbb62e46b8475186Wei Jia postDrainVideoQueue_l(); 1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1005cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { 1006cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1007cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1009cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; 1010cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; 1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1012cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { 1013cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // EOS signalled on either queue. 1014bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1015cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1016cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1018cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstAudioTimeUs; 1019cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstVideoTimeUs; 1020cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstAudioBuffer->meta() 1021cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstAudioTimeUs)); 1022cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstVideoBuffer->meta() 1023cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstVideoTimeUs)); 1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1025cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t diff = firstVideoTimeUs - firstAudioTimeUs; 1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("queueDiff = %.2f secs", diff / 1E6); 1028cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1029cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (diff > 100000ll) { 1030cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Audio data starts More than 0.1 secs before video. 1031cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Drop some audio. 1032cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1033cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (*mAudioQueue.begin()).mNotifyConsumed->post(); 1034cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 1035cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1037cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1038bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1041bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::syncQueuesDone_l() { 1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mSyncQueues) { 1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSyncQueues = false; 1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mAudioQueue.empty()) { 1049bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mVideoQueue.empty()) { 1053231406d597cca1c9c009f870fbb62e46b8475186Wei Jia postDrainVideoQueue_l(); 1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1057f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { 1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (dropBufferWhileFlushing(audio, msg)) { 1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t finalResult; 1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = finalResult; 1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1072231406d597cca1c9c009f870fbb62e46b8475186Wei Jia Mutex::Autolock autoLock(mLock); 1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1074b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson if (mAudioQueue.empty() && mSyncQueues) { 1075bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1076b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 1078bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1080b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson if (mVideoQueue.empty() && mSyncQueues) { 1081bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1082b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 1084231406d597cca1c9c009f870fbb62e46b8475186Wei Jia postDrainVideoQueue_l(); 1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1088f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { 10897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t audio, notifyComplete; 1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 109228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 109328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia Mutex::Autolock autoLock(mFlushLock); 109428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (audio) { 109528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mFlushingAudio = false; 10967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteAudio; 10977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio = false; 109828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } else { 109928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mFlushingVideo = false; 11007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteVideo; 11017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo = false; 110228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 110328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 110428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If we're currently syncing the queues, i.e. dropping audio while 1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // aligning the first audio/video buffer times and only one of the 1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // two queues has data, we may starve that queue by not requesting 1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // more buffers from the decoder. If the other source then encounters 1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // a discontinuity that leads to flushing, we'll never find the 1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // corresponding discontinuity on the other queue. 1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Therefore we'll stop syncing the queues if at least one of them 1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // is flushed. 1113bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 1114bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1115bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1116a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setPauseStartedTimeRealUs(-1); 1117f83408b41bbd796b7923d719e7e3799ddc7acaffRonghua Wu setAnchorTime(-1, -1); 1118bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1120cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar ALOGV("flushing %s", audio ? "audio" : "video"); 1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1122bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 1123bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1124bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia flushQueue(&mAudioQueue); 1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 112628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia ++mAudioQueueGeneration; 112728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia prepareForMediaRenderingStart(); 112828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 112928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (offloadingAudio()) { 1130a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setAudioFirstAnchorTime(-1); 113128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 113228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 1135cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1136bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1137bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->pause(); 1138bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 1139bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->start(); 1140bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushQueue(&mVideoQueue); 1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++mVideoQueueGeneration; 1146cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1147c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler != NULL) { 1148c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->restart(); 1149c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1150c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 1151cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar prepareForMediaRenderingStart(); 1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1154fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = false; 11557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 11567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 11577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyFlushComplete(audio); 11587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1161f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) { 1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (!queue->empty()) { 1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*queue->begin(); 1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer != NULL) { 1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber queue->erase(queue->begin()); 1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1174f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyFlushComplete(bool audio) { 1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatFlushComplete); 1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::Renderer::dropBufferWhileFlushing( 1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, const sp<AMessage> &msg) { 1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool flushing = false; 1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushing = mFlushingAudio; 1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushing = mFlushingVideo; 1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!flushing) { 1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg->findMessage("notifyConsumed", ¬ifyConsumed)) { 1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyConsumed->post(); 1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12063831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::onAudioSinkChanged() { 1207bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1208bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return; 1209bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 12103831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK(!mDrainAudioQueuePending); 12113831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mNumFramesWritten = 0; 1212f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten = -1; 12134110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen uint32_t written; 12144110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen if (mAudioSink->getFramesWritten(&written) == OK) { 12154110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen mNumFramesWritten = written; 12164110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen } 12173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 12183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 1219bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::onDisableOffloadAudio() { 1220bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1221bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mFlags &= ~FLAG_OFFLOAD_AUDIO; 12223a2956d148d81194e297408179e84a47a309ef48Wei Jia ++mAudioQueueGeneration; 1223bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 1224bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 1225a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::onEnableOffloadAudio() { 1226a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu Mutex::Autolock autoLock(mLock); 1227a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu mFlags |= FLAG_OFFLOAD_AUDIO; 1228a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu ++mAudioQueueGeneration; 1229a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 1230a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 1231b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onPause() { 12328592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad if (mPaused) { 12338592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad ALOGW("Renderer::onPause() called while already paused!"); 12348592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad return; 12358592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad } 1236d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia int64_t currentPositionUs; 1237231406d597cca1c9c009f870fbb62e46b8475186Wei Jia int64_t pausePositionMediaTimeUs; 1238d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia if (getCurrentPositionFromAnchor( 1239d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia ¤tPositionUs, ALooper::GetNowUs()) == OK) { 1240231406d597cca1c9c009f870fbb62e46b8475186Wei Jia pausePositionMediaTimeUs = currentPositionUs; 1241cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang } else { 1242cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang // Set paused position to -1 (unavailabe) if we don't have anchor time 1243cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang // This could happen if client does a seekTo() immediately followed by 1244cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang // pause(). Renderer will be flushed with anchor time cleared. We don't 1245cec7febc48ff76b293ace0cc12a6288f13f72293Chong Zhang // want to leave stale value in mPausePositionMediaTimeUs. 1246231406d597cca1c9c009f870fbb62e46b8475186Wei Jia pausePositionMediaTimeUs = -1; 1247d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia } 124828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 124928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia Mutex::Autolock autoLock(mLock); 1250231406d597cca1c9c009f870fbb62e46b8475186Wei Jia mPausePositionMediaTimeUs = pausePositionMediaTimeUs; 125128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia ++mAudioQueueGeneration; 125228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia ++mVideoQueueGeneration; 125328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia prepareForMediaRenderingStart(); 125473ddd210ea572375198cac1d4960df793745fb4bWei Jia mPaused = true; 1255a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setPauseStartedTimeRealUs(ALooper::GetNowUs()); 125628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1257b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 125828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mDrainAudioQueuePending = false; 1259b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mDrainVideoQueuePending = false; 1260cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1261b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 1262b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->pause(); 1263f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu startAudioOffloadPauseTimeout(); 1264b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1265b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1266ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber ALOGV("now paused audio queue has %d entries, video has %d entries", 1267ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber mAudioQueue.size(), mVideoQueue.size()); 1268b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1269b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1270b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onResume() { 1271b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (!mPaused) { 1272b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber return; 1273b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 1274b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1275b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 1276f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu cancelAudioOffloadPauseTimeout(); 1277b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->start(); 1278b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1279b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 128073ddd210ea572375198cac1d4960df793745fb4bWei Jia Mutex::Autolock autoLock(mLock); 1281b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mPaused = false; 1282a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mPauseStartedTimeRealUs != -1) { 1283a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t newAnchorRealUs = 1284eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeRealUs + ALooper::GetNowUs() - mPauseStartedTimeRealUs; 1285f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar setAnchorTime( 1286f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorTimeMediaUs, newAnchorRealUs, mAnchorNumFramesWritten, true /* resume */); 128749966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia } 1288b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1289b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mAudioQueue.empty()) { 1290bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1291b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1292b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1293b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mVideoQueue.empty()) { 1294231406d597cca1c9c009f870fbb62e46b8475186Wei Jia postDrainVideoQueue_l(); 1295b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1296b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1297b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1298c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::onSetVideoFrameRate(float fps) { 1299c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler == NULL) { 1300c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler = new VideoFrameScheduler(); 1301c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1302c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->init(fps); 1303c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 1304c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 130509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// TODO: Remove unnecessary calls to getPlayedOutAudioDurationUs() 130609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// as it acquires locks and may query the audio driver. 130709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// 130809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// Some calls could conceivably retrieve extrapolated data instead of 130909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// accessing getTimestamp() or getPosition() every time a data buffer with 131009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// a media time is received. 131109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung// 131206ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnarint64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) { 13133a2956d148d81194e297408179e84a47a309ef48Wei Jia uint32_t numFramesPlayed; 131406ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar int64_t numFramesPlayedAt; 131506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar AudioTimestamp ts; 131609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung static const int64_t kStaleTimestamp100ms = 100000; 131709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung 131806ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar status_t res = mAudioSink->getTimestamp(ts); 131909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung if (res == OK) { // case 1: mixing audio tracks and offloaded tracks. 132006ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayed = ts.mPosition; 132106ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayedAt = 132206ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000; 132309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung const int64_t timestampAge = nowUs - numFramesPlayedAt; 132409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung if (timestampAge > kStaleTimestamp100ms) { 132509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // This is an audio FIXME. 132609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // getTimestamp returns a timestamp which may come from audio mixing threads. 132709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // After pausing, the MixerThread may go idle, thus the mTime estimate may 132809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // become stale. Assuming that the MixerThread runs 20ms, with FastMixer at 5ms, 132909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // the max latency should be about 25ms with an average around 12ms (to be verified). 133009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // For safety we use 100ms. 13312abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung ALOGV("getTimestamp: returned stale timestamp nowUs(%lld) numFramesPlayedAt(%lld)", 133209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung (long long)nowUs, (long long)numFramesPlayedAt); 133309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung numFramesPlayedAt = nowUs - kStaleTimestamp100ms; 133409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } 133509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAt); 133609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } else if (res == WOULD_BLOCK) { // case 2: transitory state on start of a new track 133709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung numFramesPlayed = 0; 133809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung numFramesPlayedAt = nowUs; 133909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //ALOGD("getTimestamp: WOULD_BLOCK %d %lld", 134009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // numFramesPlayed, (long long)numFramesPlayedAt); 134109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } else { // case 3: transitory at new track or audio fast tracks. 134206ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar res = mAudioSink->getPosition(&numFramesPlayed); 134306ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar CHECK_EQ(res, (status_t)OK); 134406ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayedAt = nowUs; 134506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */ 134609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //ALOGD("getPosition: %d %lld", numFramesPlayed, numFramesPlayedAt); 134706ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar } 134809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung 134909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours. 135009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung //CHECK_EQ(numFramesPlayed & (1 << 31), 0); // can't be negative until 12.4 hrs, test 1351eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000LL * mAudioSink->msecsPerFrame()) 135206ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar + nowUs - numFramesPlayedAt; 135309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung if (durationUs < 0) { 135409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // Occurs when numFramesPlayed position is very small and the following: 135509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // (1) In case 1, the time nowUs is computed before getTimestamp() is called and 135609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // numFramesPlayedAt is greater than nowUs by time more than numFramesPlayed. 135709e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // (2) In case 3, using getPosition and adding mAudioSink->latency() to 135809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // numFramesPlayedAt, by a time amount greater than numFramesPlayed. 135909e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // 136009e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung // Both of these are transitory conditions. 13612abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung ALOGV("getPlayedOutAudioDurationUs: negative duration %lld set to zero", (long long)durationUs); 136209e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung durationUs = 0; 136309e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung } 136409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung ALOGV("getPlayedOutAudioDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)", 136509e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung (long long)durationUs, (long long)nowUs, numFramesPlayed, (long long)numFramesPlayedAt); 136609e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung return durationUs; 136706ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar} 13683a2956d148d81194e297408179e84a47a309ef48Wei Jia 13690852917279f79a94907e9906d0533ae409a30f6aRonghua Wuvoid NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reason) { 1370f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (mAudioOffloadTornDown) { 1371f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu return; 1372f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1373f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu mAudioOffloadTornDown = true; 1374f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1375a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t currentPositionUs; 1376d4cdba18ba7d0057ae54ec7efa5871b1a9d8becaWei Jia if (getCurrentPositionOnLooper(¤tPositionUs) != OK) { 1377a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu currentPositionUs = 0; 137828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 137906ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar 13803a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->stop(); 13813a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->flush(); 13823a2956d148d81194e297408179e84a47a309ef48Wei Jia 13833a2956d148d81194e297408179e84a47a309ef48Wei Jia sp<AMessage> notify = mNotify->dup(); 13843a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->setInt32("what", kWhatAudioOffloadTearDown); 13853a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->setInt64("positionUs", currentPositionUs); 13860852917279f79a94907e9906d0533ae409a30f6aRonghua Wu notify->setInt32("reason", reason); 13873a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->post(); 13883a2956d148d81194e297408179e84a47a309ef48Wei Jia} 13893a2956d148d81194e297408179e84a47a309ef48Wei Jia 1390f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::startAudioOffloadPauseTimeout() { 1391f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 139235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->acquire(); 1393f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, id()); 1394f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu msg->setInt32("generation", mAudioOffloadPauseTimeoutGeneration); 1395f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu msg->post(kOffloadPauseMaxUs); 1396f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1397f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1398f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1399f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() { 1400f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 140135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->release(true); 1402f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu ++mAudioOffloadPauseTimeoutGeneration; 1403f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1404f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1405f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1406202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::onOpenAudioSink( 14073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 14083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 14093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 14103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags) { 14113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)", 14123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadOnly, offloadingAudio()); 14133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool audioSinkChanged = false; 14143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t numChannels; 14163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("channel-count", &numChannels)); 14173b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t channelMask; 14193b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!format->findInt32("channel-mask", &channelMask)) { 14203b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // signal to the AudioSink to derive the mask from count. 14213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 14223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14233b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14243b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t sampleRate; 14253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("sample-rate", &sampleRate)); 14263b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14273b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (offloadingAudio()) { 14283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; 14293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AString mime; 14303b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findString("mime", &mime)); 14313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str()); 14323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 14343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGE("Couldn't map mime \"%s\" to a valid " 14353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "audio_format", mime.c_str()); 14363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 14373b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } else { 14383b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("Mime \"%s\" mapped to audio_format 0x%x", 14393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mime.c_str(), audioFormat); 14403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int avgBitRate = -1; 14423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt32("bit-rate", &avgBitRate); 14433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t aacProfile = -1; 14453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioFormat == AUDIO_FORMAT_AAC 14463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang && format->findInt32("aac-profile", &aacProfile)) { 14473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Redefine AAC format as per aac profile 14483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mapAACProfileToAudioFormat( 14493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 14503b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang aacProfile); 14513b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 14523b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14533b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 14543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.duration_us = -1; 14553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt64( 14563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "durationUs", &offloadInfo.duration_us); 14573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.sample_rate = sampleRate; 14583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.channel_mask = channelMask; 14593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.format = audioFormat; 14603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.stream_type = AUDIO_STREAM_MUSIC; 14613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.bit_rate = avgBitRate; 14623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.has_video = hasVideo; 14633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.is_streaming = true; 14643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) { 14663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: no change in offload mode"); 14673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // no change from previous configuration, everything ok. 1468202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 14693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 1470f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 1471f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 14723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: try to open AudioSink in offload mode"); 1473d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t offloadFlags = flags; 1474d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1475d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 14763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 14773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 14783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang err = mAudioSink->open( 14793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 14803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 14813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 14823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 14833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 8 /* bufferCount */, 14843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &NuPlayer::Renderer::AudioSinkCallback, 14853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang this, 1486d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent (audio_output_flags_t)offloadFlags, 14873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &offloadInfo); 14883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 14893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err == OK) { 14903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // If the playback is offloaded to h/w, we pass 14913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // the HAL some metadata information. 14923b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // We don't want to do this for PCM because it 14933b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // will be going through the AudioFlinger mixer 14943b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // before reaching the hardware. 14953b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // TODO 14963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = offloadInfo; 14973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang err = mAudioSink->start(); 14983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV_IF(err == OK, "openAudioSink: offload succeeded"); 14993b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 15003b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 15013b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Clean up, fall back to non offload mode. 15023b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 15033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 15043b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 15053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offload failed"); 15063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 15073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 15083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 15093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!offloadOnly && !offloadingAudio()) { 15103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: open AudioSink in NON-offload mode"); 1511d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t pcmFlags = flags; 1512d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1513f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 1514f0e83644637bd05852c244df481f21a0d435ff66Andy Hung const PcmInfo info = { 1515f0e83644637bd05852c244df481f21a0d435ff66Andy Hung (audio_channel_mask_t)channelMask, 1516f0e83644637bd05852c244df481f21a0d435ff66Andy Hung (audio_output_flags_t)pcmFlags, 1517f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat 1518f0e83644637bd05852c244df481f21a0d435ff66Andy Hung numChannels, 1519f0e83644637bd05852c244df481f21a0d435ff66Andy Hung sampleRate 1520f0e83644637bd05852c244df481f21a0d435ff66Andy Hung }; 1521f0e83644637bd05852c244df481f21a0d435ff66Andy Hung if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) { 1522f0e83644637bd05852c244df481f21a0d435ff66Andy Hung ALOGV("openAudioSink: no change in pcm mode"); 1523f0e83644637bd05852c244df481f21a0d435ff66Andy Hung // no change from previous configuration, everything ok. 1524f0e83644637bd05852c244df481f21a0d435ff66Andy Hung return OK; 1525f0e83644637bd05852c244df481f21a0d435ff66Andy Hung } 1526f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 15273b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 15283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 15293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 1530202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = mAudioSink->open( 15313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 15323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 15333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 15343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AUDIO_FORMAT_PCM_16_BIT, 15353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 8 /* bufferCount */, 15363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang NULL, 15373b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang NULL, 1538202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung (audio_output_flags_t)pcmFlags); 1539202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (err != OK) { 1540202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGW("openAudioSink: non offloaded open failed status: %d", err); 1541f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 1542202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 1543202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 1544f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = info; 15453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->start(); 15463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 15473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioSinkChanged) { 15483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onAudioSinkChanged(); 15493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 1550a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu if (offloadingAudio()) { 1551a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu mAudioOffloadTornDown = false; 1552a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu } 1553202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 15543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 15553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 15563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::onCloseAudioSink() { 15573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 15583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 1559f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 15603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 15613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1564