NuPlayerRenderer.cpp revision c4ac8173f911aeac8d5006b19ba48fb51a865115
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" 22a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung#include <cutils/properties.h> 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> 285833b6aad2c46ba516bdc8262f4fc4667e8018edWei Jia#include <media/stagefright/MediaClock.h> 29bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MediaErrors.h> 30bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MetaData.h> 313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang#include <media/stagefright/Utils.h> 32a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar#include <media/stagefright/VideoFrameScheduler.h> 33dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 34095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <inttypes.h> 35095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 36f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 38a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung/* 39a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * Example of common configuration settings in shell script form 40a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 41a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung #Turn offload audio off (use PCM for Play Music) -- AudioPolicyManager 42a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung adb shell setprop audio.offload.disable 1 43a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 44a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung #Allow offload audio with video (requires offloading to be enabled) -- AudioPolicyManager 45a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung adb shell setprop audio.offload.video 1 46a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 47a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung #Use audio callbacks for PCM data 48a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung adb shell setprop media.stagefright.audio.cbk 1 49a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 50288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung #Use deep buffer for PCM data with video (it is generally enabled for audio-only) 51288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung adb shell setprop media.stagefright.audio.deep 1 52288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung 53179652ee2a508361df1aa18e99000373886f0816Andy Hung #Set size of buffers for pcm audio sink in msec (example: 1000 msec) 54179652ee2a508361df1aa18e99000373886f0816Andy Hung adb shell setprop media.stagefright.audio.sink 1000 55179652ee2a508361df1aa18e99000373886f0816Andy Hung 56a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * These configurations take effect for the next track played (not the current track). 57a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung */ 58a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 59a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hungstatic inline bool getUseAudioCallbackSetting() { 60a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung return property_get_bool("media.stagefright.audio.cbk", false /* default_value */); 61a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung} 62a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 63179652ee2a508361df1aa18e99000373886f0816Andy Hungstatic inline int32_t getAudioSinkPcmMsSetting() { 64179652ee2a508361df1aa18e99000373886f0816Andy Hung return property_get_int32( 65179652ee2a508361df1aa18e99000373886f0816Andy Hung "media.stagefright.audio.sink", 500 /* default_value */); 66179652ee2a508361df1aa18e99000373886f0816Andy Hung} 67179652ee2a508361df1aa18e99000373886f0816Andy Hung 68f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink 69f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// is closed to allow the audio DSP to power down. 70a5d316fd802cfc92954527f27e6f32206a896113Eric Laurentstatic const int64_t kOffloadPauseMaxUs = 10000000ll; 71f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 72714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber// static 73f0e83644637bd05852c244df481f21a0d435ff66Andy Hungconst NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = { 74f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_CHANNEL_NONE, 75f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_OUTPUT_FLAG_NONE, 76f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_FORMAT_INVALID, 77f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 0, // mNumChannels 78f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 0 // mSampleRate 79f0e83644637bd05852c244df481f21a0d435ff66Andy Hung}; 80f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 81f0e83644637bd05852c244df481f21a0d435ff66Andy Hung// static 82714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huberconst int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; 83714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 84f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::Renderer( 85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MediaPlayerBase::AudioSink> &sink, 86d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber const sp<AMessage> ¬ify, 87d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber uint32_t flags) 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mAudioSink(sink), 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNotify(notify), 90d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mFlags(flags), 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumFramesWritten(0), 92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending(false), 93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending(false), 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueueGeneration(0), 95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueueGeneration(0), 967b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioDrainGeneration(0), 977b15cb33847e6282ea8352c98894683b796127f3Wei Jia mVideoDrainGeneration(0), 987c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia mAudioEOSGeneration(0), 993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT), 100a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs(-1), 101eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeMediaUs(-1), 102f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten(-1), 103a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs(0ll), 104bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasAudio(false), 105bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasVideo(false), 1067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio(false), 1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo(false), 108bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mSyncQueues(false), 109714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber mPaused(false), 110b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung mPauseDrainAudioAllowedUs(0), 11109e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung mVideoSampleReceived(false), 112f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong mVideoRenderingStarted(false), 113cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration(0), 114cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration(0), 115b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung mRenderingDataDelivered(false), 1162995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mLastAudioMediaTimeUs(-1), 117f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu mAudioOffloadPauseTimeoutGeneration(0), 118faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mAudioTornDown(false), 119d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), 120f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER), 121d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mTotalBuffersQueued(0), 12235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mLastAudioBufferDrained(0), 123a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback(false), 12435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock(new AWakeLock()) { 1257b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock = new MediaClock; 1263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackRate = mPlaybackSettings.mSpeed; 1273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mMediaClock->setPlaybackRate(mPlaybackRate); 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 130f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::~Renderer() { 131bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 132bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 133bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 134bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->close(); 135bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 138f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueBuffer( 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<ABuffer> &buffer, 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> ¬ifyConsumed) { 1421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this); 1437b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("queueGeneration", getQueueGeneration(audio)); 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 1452d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("buffer", buffer); 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setMessage("notifyConsumed", notifyConsumed); 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 150f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) { 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(finalResult, (status_t)OK); 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueEOS, this); 1547b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("queueGeneration", getQueueGeneration(audio)); 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("finalResult", finalResult); 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::setPlaybackSettings(const AudioPlaybackRate &rate) { 1613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this); 1623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(msg, rate); 1633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 1643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 1653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 1663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 1673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 1693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 1703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 1713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) { 1723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (rate.mSpeed == 0.f) { 1733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar onPause(); 1743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // don't call audiosink's setPlaybackRate if pausing, as pitch does not 1753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // have to correspond to the any non-0 speed (e.g old speed). Keep 1763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // settings nonetheless, using the old speed, in case audiosink changes. 1773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AudioPlaybackRate newRate = rate; 1783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar newRate.mSpeed = mPlaybackSettings.mSpeed; 1793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = newRate; 1803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 1813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 18327ea08e3811dc8057685258af52a7d40474eba16Wei Jia if (mAudioSink != NULL && mAudioSink->ready()) { 1843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = mAudioSink->setPlaybackRate(rate); 1853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err != OK) { 1863a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 1873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1893a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = rate; 1903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackRate = rate.mSpeed; 1913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mMediaClock->setPlaybackRate(mPlaybackRate); 1923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 1933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 1943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 1953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) { 1963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this); 1973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 1983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 1993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 2003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 2013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 2023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(response, rate); 2033a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2053a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) { 20927ea08e3811dc8057685258af52a7d40474eba16Wei Jia if (mAudioSink != NULL && mAudioSink->ready()) { 2103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = mAudioSink->getPlaybackRate(rate); 2113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 2123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) { 2133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGW("correcting mismatch in internal/external playback rate"); 2143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // get playback settings used by audiosink, as it may be 2163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // slightly off due to audiosink not taking small changes. 2173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = *rate; 2183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mPaused) { 2193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar rate->mSpeed = 0.f; 2203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *rate = mPlaybackSettings; 2253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 2263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) { 2293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigSync, this); 2303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(msg, sync, videoFpsHint); 2313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 2323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 2333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 2343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 2353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onConfigSync(const AVSyncSettings &sync, float videoFpsHint __unused) { 2403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (sync.mSource != AVSYNC_SOURCE_DEFAULT) { 2413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 2423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // TODO: support sync sources 2443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return INVALID_OPERATION; 2453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::getSyncSettings(AVSyncSettings *sync, float *videoFps) { 2483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this); 2493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 2503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 2513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 2523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 2533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 2543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(response, sync, videoFps); 2553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onGetSyncSettings( 2613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) { 2623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *sync = mSyncSettings; 2633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *videoFps = -1.f; 2643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 2659816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia} 2669816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia 2677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Renderer::flush(bool audio, bool notifyComplete) { 268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2697b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 2717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio |= notifyComplete; 2723b0cd26dbb0ce37d220db9ff0fa8172a7ef1c5cbWei Jia clearAudioFirstAnchorTime_l(); 2737b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioQueueGeneration; 2747b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 2767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo |= notifyComplete; 2777b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoQueueGeneration; 2787b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoDrainGeneration; 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2807b15cb33847e6282ea8352c98894683b796127f3Wei Jia 2817b15cb33847e6282ea8352c98894683b796127f3Wei Jia clearAnchorTime_l(); 2827b15cb33847e6282ea8352c98894683b796127f3Wei Jia mVideoLateByUs = 0; 2837b15cb33847e6282ea8352c98894683b796127f3Wei Jia mSyncQueues = false; 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 291f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::signalTimeDiscontinuity() { 29228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 29328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 29428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jiavoid NuPlayer::Renderer::signalDisableOffloadAudio() { 2951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatDisableOffloadAudio, this))->post(); 29628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 29728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 298a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::signalEnableOffloadAudio() { 2991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatEnableOffloadAudio, this))->post(); 300a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 301a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 302b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::pause() { 3031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatPause, this))->post(); 304b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 305b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 306b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::resume() { 3071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatResume, this))->post(); 308b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 309b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 310c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::setVideoFrameRate(float fps) { 3111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, this); 312c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->setFloat("frame-rate", fps); 313c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->post(); 314c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 315c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 3164ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia// Called on any threads without mLock acquired. 3177b15cb33847e6282ea8352c98894683b796127f3Wei Jiastatus_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) { 3184ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs); 3194ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (result == OK) { 3204ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia return result; 3214ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3224ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3234ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia // MediaClock has not started yet. Try to start it if possible. 3244ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia { 3254ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia Mutex::Autolock autoLock(mLock); 3264ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (mAudioFirstAnchorTimeMediaUs == -1) { 3274ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia return result; 3284ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3294ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3304ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia AudioTimestamp ts; 3314ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia status_t res = mAudioSink->getTimestamp(ts); 3324ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (res != OK) { 3334ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia return result; 3344ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3354ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3364ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia // AudioSink has rendered some frames. 3374ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia int64_t nowUs = ALooper::GetNowUs(); 3384ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia int64_t nowMediaUs = getPlayedOutAudioDurationUs(nowUs) 3394ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia + mAudioFirstAnchorTimeMediaUs; 3404ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia mMediaClock->updateAnchor(nowMediaUs, nowUs, -1); 3414ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3424ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3439816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs); 344a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 345a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 3467b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::clearAudioFirstAnchorTime_l() { 3477b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioFirstAnchorTimeMediaUs = -1; 3487b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->setStartingTimeMedia(-1); 349a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 350a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 3517b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs) { 352a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mAudioFirstAnchorTimeMediaUs == -1) { 353a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs = mediaUs; 3547b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->setStartingTimeMedia(mediaUs); 355a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 356a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 357a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 3587b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::clearAnchorTime_l() { 3597b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->clearAnchor(); 3607b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorTimeMediaUs = -1; 3617b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorNumFramesWritten = -1; 362a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 363a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 364a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setVideoLateByUs(int64_t lateUs) { 3657b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 366a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs = lateUs; 367a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 368a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 369a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getVideoLateByUs() { 3707b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 371a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return mVideoLateByUs; 372a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 373a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 374202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::openAudioSink( 3753b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 3763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 3773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 378202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung uint32_t flags, 379202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung bool *isOffloaded) { 3801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this); 3813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setMessage("format", format); 3823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("offload-only", offloadOnly); 3833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("has-video", hasVideo); 3843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("flags", flags); 3853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 3863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 3873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 3883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 389202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t err; 390202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (!response->findInt32("err", &err)) { 391202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung err = INVALID_OPERATION; 392202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } else if (err == OK && isOffloaded != NULL) { 393202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t offload; 394202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung CHECK(response->findInt32("offload", &offload)); 395202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung *isOffloaded = (offload != 0); 396202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 397202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 3983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 3993b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4003b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::closeAudioSink() { 4011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, this); 4023b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 4043b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 4053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 4063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 407f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 4093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatOpenAudioSink: 4103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 4113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> format; 4123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findMessage("format", &format)); 4133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t offloadOnly; 4153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("offload-only", &offloadOnly)); 4163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4173b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t hasVideo; 4183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("has-video", &hasVideo)); 4193b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4203b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags; 4213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 4223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 423202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags); 4243b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 426202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("err", err); 427202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("offload", offloadingAudio()); 4283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 4303b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 4313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 4323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 4343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 4353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatCloseAudioSink: 4373b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 4383f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 4393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 4403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onCloseAudioSink(); 4423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 4443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 4453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 4463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 4473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 448bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatStopAudioSink: 449bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 450bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 451bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 452bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 453bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainAudioQueue: 455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 4563ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia mDrainAudioQueuePending = false; 4573ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia 458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 4597b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 4607b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (generation != getDrainGeneration(true /* audio */)) { 461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 464078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (onDrainAudioQueue()) { 465078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 466078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), 467078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (status_t)OK); 468078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 469078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPendingPlayout = 470078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten - numFramesPlayed; 471078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 472078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // This is how long the audio sink will have data to 473078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // play back. 474078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int64_t delayUs = 475078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->msecsPerFrame() 476078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber * numFramesPendingPlayout * 1000ll; 477d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia if (mPlaybackRate > 1.0f) { 478d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia delayUs /= mPlaybackRate; 479d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia } 480078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 481078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // Let's give it more data after about half that time 482078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // has elapsed. 4837b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 484bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(delayUs / 2); 485078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainVideoQueue: 490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 4927b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 4937b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (generation != getDrainGeneration(false /* audio */)) { 494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainVideoQueue(); 500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5017b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 505d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar case kWhatPostDrainVideoQueue: 506d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar { 507d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int32_t generation; 5087b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 5097b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (generation != getDrainGeneration(false /* audio */)) { 510d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 511d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 512d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 513d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = false; 5147b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 515d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 516d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 517d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueBuffer: 519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueBuffer(msg); 521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueEOS: 525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueEOS(msg); 527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5307c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia case kWhatEOS: 5317c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia { 5327c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia int32_t generation; 5337c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia CHECK(msg->findInt32("audioEOSGeneration", &generation)); 5347c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia if (generation != mAudioEOSGeneration) { 5357c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia break; 5367c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia } 5377c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia status_t finalResult; 5387c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia CHECK(msg->findInt32("finalResult", &finalResult)); 5397c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia notifyEOS(true /* audio */, finalResult); 5407c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia break; 5417c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia } 5427c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia 5433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatConfigPlayback: 5449816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia { 5453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 5463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 5473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AudioPlaybackRate rate; 5483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(msg, &rate); 5493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onConfigPlayback(rate); 5503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 5513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 5523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 5533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 5543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 5553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 5563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatGetPlaybackSettings: 5573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar { 5583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 5593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 5603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; 5613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onGetPlaybackSettings(&rate); 5623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 5633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 5643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(response, rate); 5653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 5663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 5673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 5683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 5693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 5703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 5713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatConfigSync: 5723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar { 5733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 5743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 5753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings sync; 5763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar float videoFpsHint; 5773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(msg, &sync, &videoFpsHint); 5783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onConfigSync(sync, videoFpsHint); 5793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 5803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 5813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 5823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 5833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 5843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 5853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatGetSyncSettings: 5863a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar { 5873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 5883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 5893a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 5903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGV("kWhatGetSyncSettings"); 5913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings sync; 5923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar float videoFps = -1.f; 5933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onGetSyncSettings(&sync, &videoFps); 5943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 5953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 5963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(response, sync, videoFps); 5973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 5983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 5993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 6009816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia break; 6019816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia } 6029816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia 603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFlush(msg); 606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 609bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatDisableOffloadAudio: 610bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 611bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia onDisableOffloadAudio(); 612bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 613bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 614bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 615a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu case kWhatEnableOffloadAudio: 616a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu { 617a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu onEnableOffloadAudio(); 618a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu break; 619a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu } 620a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 621b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatPause: 622b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 623b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onPause(); 624b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 625b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 626b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 627b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatResume: 628b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 629b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onResume(); 630b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 631b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 632b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 633c851b5de495169d7e9528644c2592746021bd968Lajos Molnar case kWhatSetVideoFrameRate: 634c851b5de495169d7e9528644c2592746021bd968Lajos Molnar { 635c851b5de495169d7e9528644c2592746021bd968Lajos Molnar float fps; 636c851b5de495169d7e9528644c2592746021bd968Lajos Molnar CHECK(msg->findFloat("frame-rate", &fps)); 637c851b5de495169d7e9528644c2592746021bd968Lajos Molnar onSetVideoFrameRate(fps); 638c851b5de495169d7e9528644c2592746021bd968Lajos Molnar break; 639c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 640c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 641faeb0f291330134dc4468359a36e099aae508449Ronghua Wu case kWhatAudioTearDown: 6423a2956d148d81194e297408179e84a47a309ef48Wei Jia { 643faeb0f291330134dc4468359a36e099aae508449Ronghua Wu onAudioTearDown(kDueToError); 6443a2956d148d81194e297408179e84a47a309ef48Wei Jia break; 6453a2956d148d81194e297408179e84a47a309ef48Wei Jia } 6463a2956d148d81194e297408179e84a47a309ef48Wei Jia 647f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu case kWhatAudioOffloadPauseTimeout: 648f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu { 649f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu int32_t generation; 6507b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 651f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (generation != mAudioOffloadPauseTimeoutGeneration) { 652f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 653f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 6540852917279f79a94907e9906d0533ae409a30f6aRonghua Wu ALOGV("Audio Offload tear down due to pause timeout."); 655faeb0f291330134dc4468359a36e099aae508449Ronghua Wu onAudioTearDown(kDueToTimeout); 65635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->release(); 657f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 658f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 659f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 666bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) { 667005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung if (mDrainAudioQueuePending || mSyncQueues || mUseAudioCallback) { 668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioQueue.empty()) { 672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 675b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // FIXME: if paused, wait until AudioTrack stop() is complete before delivering data. 676b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung if (mPaused) { 677b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung const int64_t diffUs = mPauseDrainAudioAllowedUs - ALooper::GetNowUs(); 678b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung if (diffUs > delayUs) { 679b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung delayUs = diffUs; 680b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung } 681b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung } 682b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung 683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = true; 6841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this); 6857b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("drainGeneration", mAudioDrainGeneration); 686078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber msg->post(delayUs); 687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6897b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::prepareForMediaRenderingStart_l() { 6907b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioRenderingStartGeneration = mAudioDrainGeneration; 6917b15cb33847e6282ea8352c98894683b796127f3Wei Jia mVideoRenderingStartGeneration = mVideoDrainGeneration; 692b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung mRenderingDataDelivered = false; 693cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 694cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 6957b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::notifyIfMediaRenderingStarted_l() { 6967b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (mVideoRenderingStartGeneration == mVideoDrainGeneration && 6977b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioRenderingStartGeneration == mAudioDrainGeneration) { 698b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung mRenderingDataDelivered = true; 699b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung if (mPaused) { 700b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung return; 701b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung } 702cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration = -1; 703cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration = -1; 704cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 705cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar sp<AMessage> notify = mNotify->dup(); 706cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->setInt32("what", kWhatMediaRenderingStart); 707cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->post(); 708cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar } 709cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 710cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 711bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia// static 712bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::AudioSinkCallback( 713bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink * /* audioSink */, 714bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *buffer, 715bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t size, 716bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *cookie, 717bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink::cb_event_t event) { 718bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia NuPlayer::Renderer *me = (NuPlayer::Renderer *)cookie; 719bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 720bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia switch (event) { 721bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER: 722bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 723bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return me->fillAudioBuffer(buffer, size); 724bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 725bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 726bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 727bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END: 728bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 729a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("AudioSink::CB_EVENT_STREAM_END"); 730bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia me->notifyEOS(true /* audio */, ERROR_END_OF_STREAM); 731bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 732bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 733bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 734bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN: 735bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 736a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("AudioSink::CB_EVENT_TEAR_DOWN"); 737faeb0f291330134dc4468359a36e099aae508449Ronghua Wu me->notifyAudioTearDown(); 738bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 739bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 740bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 741bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 742bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 743bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 744bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 745bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { 746bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 747bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 74885e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung if (!mUseAudioCallback) { 749bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 750bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 751bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 752bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia bool hasEOS = false; 753bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 754bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeCopied = 0; 7553e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu bool firstEntry = true; 756a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung QueueEntry *entry; // will be valid after while loop if hasEOS is set. 757bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia while (sizeCopied < size && !mAudioQueue.empty()) { 758a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung entry = &*mAudioQueue.begin(); 759bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 760bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mBuffer == NULL) { // EOS 761bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia hasEOS = true; 762bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 763bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 764bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 765bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 7663e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu if (firstEntry && entry->mOffset == 0) { 7673e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu firstEntry = false; 768bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int64_t mediaTimeUs; 769bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 770a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 7717b15cb33847e6282ea8352c98894683b796127f3Wei Jia setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs); 772bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 773bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 774bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t copy = entry->mBuffer->size() - entry->mOffset; 775bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeRemaining = size - sizeCopied; 776bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (copy > sizeRemaining) { 777bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy = sizeRemaining; 778bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 779bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 780bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia memcpy((char *)buffer + sizeCopied, 781bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mBuffer->data() + entry->mOffset, 782bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy); 783bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 784bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mOffset += copy; 785bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mOffset == entry->mBuffer->size()) { 786bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mNotifyConsumed->post(); 787bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 788bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry = NULL; 789bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 790bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia sizeCopied += copy; 7917b15cb33847e6282ea8352c98894683b796127f3Wei Jia 7927b15cb33847e6282ea8352c98894683b796127f3Wei Jia notifyIfMediaRenderingStarted_l(); 793bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 794bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 795f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (mAudioFirstAnchorTimeMediaUs >= 0) { 796f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 7979816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t nowMediaUs = 798c4ac8173f911aeac8d5006b19ba48fb51a865115Wei Jia mAudioFirstAnchorTimeMediaUs + mAudioSink->getPlayedOutDurationUs(nowUs); 7997b15cb33847e6282ea8352c98894683b796127f3Wei Jia // we don't know how much data we are queueing for offloaded tracks. 8009816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX); 801f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 802f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 803a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // for non-offloaded audio, we need to compute the frames written because 804a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // there is no EVENT_STREAM_END notification. The frames written gives 805a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // an estimate on the pending played out duration. 806a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung if (!offloadingAudio()) { 807a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mNumFramesWritten += sizeCopied / mAudioSink->frameSize(); 808a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung } 809a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 810bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (hasEOS) { 8111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStopAudioSink, this))->post(); 812a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // As there is currently no EVENT_STREAM_END callback notification for 813a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // non-offloaded audio tracks, we need to post the EOS ourselves. 814a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung if (!offloadingAudio()) { 815a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung int64_t postEOSDelayUs = 0; 816a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung if (mAudioSink->needsTrailingPadding()) { 817a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); 818a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung } 819a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("fillAudioBuffer: notifyEOS " 820a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung "mNumFramesWritten:%u finalResult:%d postEOSDelay:%lld", 821a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs); 822a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); 823a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung } 824bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 825bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return sizeCopied; 826bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 827bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 8289da0ce44f228408d73a4dea0be972c785095dcccChong Zhangvoid NuPlayer::Renderer::drainAudioQueueUntilLastEOS() { 8299da0ce44f228408d73a4dea0be972c785095dcccChong Zhang List<QueueEntry>::iterator it = mAudioQueue.begin(), itEOS = it; 8309da0ce44f228408d73a4dea0be972c785095dcccChong Zhang bool foundEOS = false; 8319da0ce44f228408d73a4dea0be972c785095dcccChong Zhang while (it != mAudioQueue.end()) { 8329da0ce44f228408d73a4dea0be972c785095dcccChong Zhang int32_t eos; 8339da0ce44f228408d73a4dea0be972c785095dcccChong Zhang QueueEntry *entry = &*it++; 8349da0ce44f228408d73a4dea0be972c785095dcccChong Zhang if (entry->mBuffer == NULL 8359da0ce44f228408d73a4dea0be972c785095dcccChong Zhang || (entry->mNotifyConsumed->findInt32("eos", &eos) && eos != 0)) { 8369da0ce44f228408d73a4dea0be972c785095dcccChong Zhang itEOS = it; 8379da0ce44f228408d73a4dea0be972c785095dcccChong Zhang foundEOS = true; 8389da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 8399da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 8409da0ce44f228408d73a4dea0be972c785095dcccChong Zhang 8419da0ce44f228408d73a4dea0be972c785095dcccChong Zhang if (foundEOS) { 8429da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // post all replies before EOS and drop the samples 8439da0ce44f228408d73a4dea0be972c785095dcccChong Zhang for (it = mAudioQueue.begin(); it != itEOS; it++) { 8449da0ce44f228408d73a4dea0be972c785095dcccChong Zhang if (it->mBuffer == NULL) { 8459da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // delay doesn't matter as we don't even have an AudioTrack 8469da0ce44f228408d73a4dea0be972c785095dcccChong Zhang notifyEOS(true /* audio */, it->mFinalResult); 8479da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } else { 8489da0ce44f228408d73a4dea0be972c785095dcccChong Zhang it->mNotifyConsumed->post(); 8499da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 8509da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 8519da0ce44f228408d73a4dea0be972c785095dcccChong Zhang mAudioQueue.erase(mAudioQueue.begin(), itEOS); 8529da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 8539da0ce44f228408d73a4dea0be972c785095dcccChong Zhang} 8549da0ce44f228408d73a4dea0be972c785095dcccChong Zhang 855078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huberbool NuPlayer::Renderer::onDrainAudioQueue() { 85658d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung // do not drain audio during teardown as queued buffers may be invalid. 85758d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung if (mAudioTornDown) { 85858d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung return false; 85958d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung } 860230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // TODO: This call to getPosition checks if AudioTrack has been created 861230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // in AudioSink before draining audio. If AudioTrack doesn't exist, then 862230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // CHECKs on getPosition will fail. 863230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // We still need to figure out why AudioTrack is not created when 864230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // this function is called. One possible reason could be leftover 865230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // audio. Another possible place is to check whether decoder 866230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // has received INFO_FORMAT_CHANGED as the first buffer since 867230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // AudioSink is opened there, and possible interactions with flush 868230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // immediately after start. Investigate error message 869230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // "vorbis_dsp_synthesis returned -135", along with RTSP. 870078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 8712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mAudioSink->getPosition(&numFramesPlayed) != OK) { 8729da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // When getPosition fails, renderer will not reschedule the draining 8739da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // unless new samples are queued. 8749da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // If we have pending EOS (or "eos" marker for discontinuities), we need 8759da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // to post these now as NuPlayerDecoder might be waiting for it. 8769da0ce44f228408d73a4dea0be972c785095dcccChong Zhang drainAudioQueueUntilLastEOS(); 8779da0ce44f228408d73a4dea0be972c785095dcccChong Zhang 8789da0ce44f228408d73a4dea0be972c785095dcccChong Zhang ALOGW("onDrainAudioQueue(): audio sink is not ready"); 8792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return false; 8802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 881078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 882230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia#if 0 883078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber ssize_t numFramesAvailableToWrite = 884078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); 885078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 886078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (numFramesAvailableToWrite == mAudioSink->frameCount()) { 887df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("audio sink underrun"); 888078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 8893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("audio queue has %d frames left to play", 890078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - numFramesAvailableToWrite); 891078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 892078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#endif 893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 894005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung uint32_t prevFramesWritten = mNumFramesWritten; 8957d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia while (!mAudioQueue.empty()) { 896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mAudioQueue.begin(); 897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 898d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mLastAudioBufferDrained = entry->mBufferOrdinal; 899d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 9025095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu int64_t postEOSDelayUs = 0; 9035095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu if (mAudioSink->needsTrailingPadding()) { 90406ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); 9055095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu } 9065095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); 9072995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mLastAudioMediaTimeUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten); 908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 9113491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung if (mAudioSink->needsTrailingPadding()) { 9123491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // If we're not in gapless playback (i.e. through setNextPlayer), we 9133491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // need to stop the track here, because that will play out the last 9143491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // little bit at the end of the file. Otherwise short files won't play. 9153491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mAudioSink->stop(); 9163491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mNumFramesWritten = 0; 9173491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung } 918078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return false; 919c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 920c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 92181636761bead03f13b4ed9320a7f25ce1354f1aeChong Zhang // ignore 0-sized buffer which could be EOS marker with no data 92281636761bead03f13b4ed9320a7f25ce1354f1aeChong Zhang if (entry->mOffset == 0 && entry->mBuffer->size() > 0) { 923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 925a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("onDrainAudioQueue: rendering audio at media time %.2f secs", 926a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mediaTimeUs / 1E6); 927eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu onNewAudioMediaTime(mediaTimeUs); 928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t copy = entry->mBuffer->size() - entry->mOffset; 931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9327d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, 9337d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia copy, false /* blocking */); 934a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written < 0) { 935202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // An error in AudioSink write. Perhaps the AudioSink was not properly opened. 9367d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia if (written == WOULD_BLOCK) { 937df809479696725faf5d3424b11fa8a07bd94cb5eWei Jia ALOGV("AudioSink write would block when writing %zu bytes", copy); 9387d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia } else { 9397d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy); 9407665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // This can only happen when AudioSink was opened with doNotReconnect flag set to 9417665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // true, in which case the NuPlayer will handle the reconnect. 942faeb0f291330134dc4468359a36e099aae508449Ronghua Wu notifyAudioTearDown(); 9437d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia } 944202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung break; 945a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 947a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung entry->mOffset += written; 948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == entry->mBuffer->size()) { 949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 9519b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent 952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 955a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung size_t copiedFrames = written / mAudioSink->frameSize(); 956078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten += copiedFrames; 957cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 9587b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 9597b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 960d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia int64_t maxTimeMedia; 961d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia maxTimeMedia = 962d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia mAnchorTimeMediaUs + 963d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL) 964d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia * 1000LL * mAudioSink->msecsPerFrame()); 965d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia mMediaClock->updateMaxTimeMedia(maxTimeMedia); 966d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia 9677b15cb33847e6282ea8352c98894683b796127f3Wei Jia notifyIfMediaRenderingStarted_l(); 9687b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 96943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 970a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written != (ssize_t)copy) { 971a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // A short count was received from AudioSink::write() 972a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 9737d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // AudioSink write is called in non-blocking mode. 9747d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // It may return with a short count when: 975a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 976a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 1) Size to be copied is not a multiple of the frame size. We consider this fatal. 9777d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // 2) The data to be copied exceeds the available buffer in AudioSink. 9787d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // 3) An error occurs and data has been partially copied to the buffer in AudioSink. 9797d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded. 980a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 981a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // (Case 1) 982a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Must be a multiple of the frame size. If it is not a multiple of a frame size, it 983a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // needs to fail, as we should not carry over fractional frames between calls. 984a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung CHECK_EQ(copy % mAudioSink->frameSize(), 0); 985a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 9867d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // (Case 2, 3, 4) 987a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Return early to the caller. 988a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Beware of calling immediately again as this may busy-loop if you are not careful. 9897d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia ALOGV("AudioSink write short frame count %zd < %zu", written, copy); 990a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung break; 991a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 992a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 993f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 994005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung // calculate whether we need to reschedule another write. 995005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung bool reschedule = !mAudioQueue.empty() 996005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung && (!mPaused 997005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung || prevFramesWritten != mNumFramesWritten); // permit pause to fill buffers 998005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung //ALOGD("reschedule:%d empty:%d mPaused:%d prevFramesWritten:%u mNumFramesWritten:%u", 999005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung // reschedule, mAudioQueue.empty(), mPaused, prevFramesWritten, mNumFramesWritten); 1000005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung return reschedule; 1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10039816016afb2a13c6a866cd047d57020566a8b9a9Wei Jiaint64_t NuPlayer::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) { 10049816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int32_t sampleRate = offloadingAudio() ? 10059816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate; 10064d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia if (sampleRate == 0) { 10074d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload"); 10084d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia return 0; 10094d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia } 10109816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours. 10119816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate); 10129816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia} 10139816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia 10149816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia// Calculate duration of pending samples if played at normal rate (i.e., 1.0). 101506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnarint64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) { 10169816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten); 1017c4ac8173f911aeac8d5006b19ba48fb51a865115Wei Jia return writtenAudioDurationUs - mAudioSink->getPlayedOutDurationUs(nowUs); 10185095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu} 10195095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu 1020a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) { 10219816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t realUs; 10229816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia if (mMediaClock->getRealTimeFor(mediaTimeUs, &realUs) != OK) { 10237b15cb33847e6282ea8352c98894683b796127f3Wei Jia // If failed to get current position, e.g. due to audio clock is 10247b15cb33847e6282ea8352c98894683b796127f3Wei Jia // not ready, then just play out video immediately without delay. 1025eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return nowUs; 1026a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 10279816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia return realUs; 1028a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 1029a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 1030eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wuvoid NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) { 10317b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1032eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // TRICKY: vorbis decoder generates multiple frames with the same 1033eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // timestamp, so only update on the first frame with a given timestamp 1034eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mediaTimeUs == mAnchorTimeMediaUs) { 1035eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return; 1036eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 10377b15cb33847e6282ea8352c98894683b796127f3Wei Jia setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs); 10384ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 10394ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia AudioTimestamp ts; 10404ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia status_t res = mAudioSink->getTimestamp(ts); 10414ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (res == OK) { 10424ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia int64_t nowUs = ALooper::GetNowUs(); 10434ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs); 10444ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs); 10454ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 10468edb3f85f58e8738582e8f9abbc018c85100b712Wei Jia mAnchorNumFramesWritten = mNumFramesWritten; 10477b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorTimeMediaUs = mediaTimeUs; 1048eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu} 1049eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 10507b15cb33847e6282ea8352c98894683b796127f3Wei Jia// Called without mLock acquired. 10517b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::postDrainVideoQueue() { 1052fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (mDrainVideoQueuePending 10537b15cb33847e6282ea8352c98894683b796127f3Wei Jia || getSyncQueues() 1054fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang || (mPaused && mVideoSampleReceived)) { 1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry &entry = *mVideoQueue.begin(); 1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10641d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this); 10657b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("drainGeneration", getDrainGeneration(false /* audio */)); 1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry.mBuffer == NULL) { 1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS doesn't carry a timestamp. 1069dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(); 1070dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mDrainVideoQueuePending = true; 1071dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar return; 1072dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 1073dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 1074dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t delayUs; 1075dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 1076dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t realTimeUs; 1077dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mFlags & FLAG_REAL_TIME) { 1078d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t mediaTimeUs; 1079d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1080dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mediaTimeUs; 1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10857b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 10867b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 10877b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (mAnchorTimeMediaUs < 0) { 10887b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs); 10897b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorTimeMediaUs = mediaTimeUs; 10907b15cb33847e6282ea8352c98894683b796127f3Wei Jia realTimeUs = nowUs; 10917b15cb33847e6282ea8352c98894683b796127f3Wei Jia } else { 10927b15cb33847e6282ea8352c98894683b796127f3Wei Jia realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 10937b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1095f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (!mHasAudio) { 10967b15cb33847e6282ea8352c98894683b796127f3Wei Jia // smooth out videos >= 10fps 10977b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000); 1098f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 1099d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 1100d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // Heuristics to handle situation when media time changed without a 1101d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // discontinuity. If we have not drained an audio buffer that was 1102d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // received after this buffer, repost in 10 msec. Otherwise repost 1103d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // in 500 msec. 1104d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar delayUs = realTimeUs - nowUs; 1105d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (delayUs > 500000) { 1106d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int64_t postDelayUs = 500000; 1107d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (mHasAudio && (mLastAudioBufferDrained - entry.mBufferOrdinal) <= 0) { 1108d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar postDelayUs = 10000; 1109d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 1110d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->setWhat(kWhatPostDrainVideoQueue); 1111d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->post(postDelayUs); 1112d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mVideoScheduler->restart(); 1113d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar ALOGI("possible video time jump of %dms, retrying in %dms", 1114d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar (int)(delayUs / 1000), (int)(postDelayUs / 1000)); 1115d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = true; 1116d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar return; 1117d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1120dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000; 1121dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000); 1122dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 1123dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar delayUs = realTimeUs - nowUs; 1124dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 1125095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); 1126dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar // post 2 display refreshes before rendering is due 1127dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0); 1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = true; 1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1132f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainVideoQueue() { 1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mVideoQueue.begin(); 1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1142c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyEOS(false /* audio */, entry->mFinalResult); 1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 11463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 1147a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1151a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t nowUs = -1; 1152d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t realTimeUs; 11532995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia int64_t mediaTimeUs = -1; 1154d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber if (mFlags & FLAG_REAL_TIME) { 1155d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs)); 1156d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } else { 1157d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1158d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber 1159a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu nowUs = ALooper::GetNowUs(); 1160a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 1161d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } 1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1163fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang bool tooLate = false; 11643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 1165fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 1166a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (nowUs == -1) { 1167a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu nowUs = ALooper::GetNowUs(); 1168a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 1169a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(nowUs - realTimeUs); 1170fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang tooLate = (mVideoLateByUs > 40000); 1171fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang 1172fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (tooLate) { 1173fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("video late by %lld us (%.2f secs)", 11746d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar (long long)mVideoLateByUs, mVideoLateByUs / 1E6); 1175fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } else { 11769816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t mediaUs = 0; 11779816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->getMediaTime(realTimeUs, &mediaUs); 1178fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("rendering video at media time %.2f secs", 1179fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang (mFlags & FLAG_REAL_TIME ? realTimeUs : 11809816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mediaUs) / 1E6); 11812995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia 11822995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia if (!(mFlags & FLAG_REAL_TIME) 11832995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia && mLastAudioMediaTimeUs != -1 11842995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia && mediaTimeUs > mLastAudioMediaTimeUs) { 11852995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia // If audio ends before video, video continues to drive media clock. 11862995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia // Also smooth out videos >= 10fps. 11872995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000); 11882995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia } 1189fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 1190078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 1191a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 1192eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (!mVideoSampleReceived && !mHasAudio) { 1193a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // This will ensure that the first frame after a flush won't be used as anchor 1194a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // when renderer is in paused state, because resume can happen any time after seek. 11957b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 11967b15cb33847e6282ea8352c98894683b796127f3Wei Jia clearAnchorTime_l(); 119749966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia } 1198078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1200dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll); 1201683525b61bc1b58b4fd9e1b3ef9ed3b0c3bf34aeGlenn Kasten entry->mNotifyConsumed->setInt32("render", !tooLate); 1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 120543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1206fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = true; 1207f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 1208fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 1209fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mVideoRenderingStarted) { 1210fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoRenderingStarted = true; 1211fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang notifyVideoRenderingStart(); 1212fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 12137b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 12147b15cb33847e6282ea8352c98894683b796127f3Wei Jia notifyIfMediaRenderingStarted_l(); 1215fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1218f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dongvoid NuPlayer::Renderer::notifyVideoRenderingStart() { 1219f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong sp<AMessage> notify = mNotify->dup(); 1220f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->setInt32("what", kWhatVideoRenderingStart); 1221f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->post(); 1222f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong} 1223f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 12245095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wuvoid NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) { 12257c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia if (audio && delayUs > 0) { 12267c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia sp<AMessage> msg = new AMessage(kWhatEOS, this); 12277c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia msg->setInt32("audioEOSGeneration", mAudioEOSGeneration); 12287c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia msg->setInt32("finalResult", finalResult); 12297c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia msg->post(delayUs); 12307c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia return; 12317c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia } 1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatEOS); 1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 1235c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notify->setInt32("finalResult", finalResult); 12365095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notify->post(delayUs); 1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1239faeb0f291330134dc4468359a36e099aae508449Ronghua Wuvoid NuPlayer::Renderer::notifyAudioTearDown() { 1240faeb0f291330134dc4468359a36e099aae508449Ronghua Wu (new AMessage(kWhatAudioTearDown, this))->post(); 12413a2956d148d81194e297408179e84a47a309ef48Wei Jia} 12423a2956d148d81194e297408179e84a47a309ef48Wei Jia 1243f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { 1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12477b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (dropBufferIfStale(audio, msg)) { 12487b15cb33847e6282ea8352c98894683b796127f3Wei Jia return; 12497b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 12507b15cb33847e6282ea8352c98894683b796127f3Wei Jia 12517b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (audio) { 12527b15cb33847e6282ea8352c98894683b796127f3Wei Jia mHasAudio = true; 12537b15cb33847e6282ea8352c98894683b796127f3Wei Jia } else { 12547b15cb33847e6282ea8352c98894683b796127f3Wei Jia mHasVideo = true; 12557b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 1256a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 1257a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mHasVideo) { 1258dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mVideoScheduler == NULL) { 1259dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler = new VideoFrameScheduler(); 1260dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler->init(); 1261dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 1262bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 1263bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 12642d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 12652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); 1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mBuffer = buffer; 1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mNotifyConsumed = notifyConsumed; 1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = OK; 1275d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar entry.mBufferOrdinal = ++mTotalBuffersQueued; 1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 12787b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 1280bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 12837b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12867b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1287cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { 1288cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1289cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1291cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; 1292cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; 1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1294cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { 1295cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // EOS signalled on either queue. 1296bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1297cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1298cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1300cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstAudioTimeUs; 1301cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstVideoTimeUs; 1302cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstAudioBuffer->meta() 1303cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstAudioTimeUs)); 1304cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstVideoBuffer->meta() 1305cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstVideoTimeUs)); 1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1307cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t diff = firstVideoTimeUs - firstAudioTimeUs; 1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 13093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("queueDiff = %.2f secs", diff / 1E6); 1310cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1311cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (diff > 100000ll) { 1312cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Audio data starts More than 0.1 secs before video. 1313cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Drop some audio. 1314cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1315cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (*mAudioQueue.begin()).mNotifyConsumed->post(); 1316cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 1317cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1319cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1320bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1323bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::syncQueuesDone_l() { 1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mSyncQueues) { 1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSyncQueues = false; 1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mAudioQueue.empty()) { 1331bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mVideoQueue.empty()) { 13357b15cb33847e6282ea8352c98894683b796127f3Wei Jia mLock.unlock(); 13367b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 13377b15cb33847e6282ea8352c98894683b796127f3Wei Jia mLock.lock(); 1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1341f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { 1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 13457b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (dropBufferIfStale(audio, msg)) { 1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t finalResult; 1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = finalResult; 1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 13577b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1358b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson if (mAudioQueue.empty() && mSyncQueues) { 1359bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1360b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 1362bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 13647b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (mVideoQueue.empty() && getSyncQueues()) { 13657b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1366bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1367b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 13697b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1373f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { 13747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t audio, notifyComplete; 1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 137728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 13787b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 137928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (audio) { 13807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteAudio; 13817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio = false; 13822995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mLastAudioMediaTimeUs = -1; 138328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } else { 13847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteVideo; 13857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo = false; 138628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 138728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 13887b15cb33847e6282ea8352c98894683b796127f3Wei Jia // If we're currently syncing the queues, i.e. dropping audio while 13897b15cb33847e6282ea8352c98894683b796127f3Wei Jia // aligning the first audio/video buffer times and only one of the 13907b15cb33847e6282ea8352c98894683b796127f3Wei Jia // two queues has data, we may starve that queue by not requesting 13917b15cb33847e6282ea8352c98894683b796127f3Wei Jia // more buffers from the decoder. If the other source then encounters 13927b15cb33847e6282ea8352c98894683b796127f3Wei Jia // a discontinuity that leads to flushing, we'll never find the 13937b15cb33847e6282ea8352c98894683b796127f3Wei Jia // corresponding discontinuity on the other queue. 13947b15cb33847e6282ea8352c98894683b796127f3Wei Jia // Therefore we'll stop syncing the queues if at least one of them 13957b15cb33847e6282ea8352c98894683b796127f3Wei Jia // is flushed. 13967b15cb33847e6282ea8352c98894683b796127f3Wei Jia syncQueuesDone_l(); 13977b15cb33847e6282ea8352c98894683b796127f3Wei Jia clearAnchorTime_l(); 1398bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1400cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar ALOGV("flushing %s", audio ? "audio" : "video"); 1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1402bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 1403bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1404bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia flushQueue(&mAudioQueue); 1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14067b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 14077c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia ++mAudioEOSGeneration; 14087b15cb33847e6282ea8352c98894683b796127f3Wei Jia prepareForMediaRenderingStart_l(); 140928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 1410a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // the frame count will be reset after flush. 1411a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung clearAudioFirstAnchorTime_l(); 141228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 1415cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1416bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1417bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->pause(); 1418bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 141985e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung if (!mPaused) { 142085e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung mAudioSink->start(); 142185e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung } 14229e7ed3315298b42db485963b182a572e9ab42f9fWei Jia } else { 14239e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->pause(); 14249e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->flush(); 14259e7ed3315298b42db485963b182a572e9ab42f9fWei Jia // Call stop() to signal to the AudioSink to completely fill the 14269e7ed3315298b42db485963b182a572e9ab42f9fWei Jia // internal buffer before resuming playback. 1427b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // FIXME: this is ignored after flush(). 14289e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->stop(); 1429b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung if (mPaused) { 1430b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // Race condition: if renderer is paused and audio sink is stopped, 1431b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // we need to make sure that the audio track buffer fully drains 1432b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // before delivering data. 1433b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // FIXME: remove this if we can detect if stop() is complete. 1434b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms) 1435b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs; 1436b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung } else { 14379e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->start(); 14389e7ed3315298b42db485963b182a572e9ab42f9fWei Jia } 14399e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mNumFramesWritten = 0; 1440bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushQueue(&mVideoQueue); 1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 1445cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1446c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler != NULL) { 1447c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->restart(); 1448c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1449c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 14507b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 14517b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoDrainGeneration; 14527b15cb33847e6282ea8352c98894683b796127f3Wei Jia prepareForMediaRenderingStart_l(); 1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1455fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = false; 14567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 14577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 14587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyFlushComplete(audio); 14597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1462f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) { 1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (!queue->empty()) { 1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*queue->begin(); 1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer != NULL) { 1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber queue->erase(queue->begin()); 1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1475f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyFlushComplete(bool audio) { 1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatFlushComplete); 1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14827b15cb33847e6282ea8352c98894683b796127f3Wei Jiabool NuPlayer::Renderer::dropBufferIfStale( 1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, const sp<AMessage> &msg) { 14847b15cb33847e6282ea8352c98894683b796127f3Wei Jia int32_t queueGeneration; 14857b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("queueGeneration", &queueGeneration)); 1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14877b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (queueGeneration == getQueueGeneration(audio)) { 1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg->findMessage("notifyConsumed", ¬ifyConsumed)) { 1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyConsumed->post(); 1494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::onAudioSinkChanged() { 1500bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1501bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return; 1502bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 15033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK(!mDrainAudioQueuePending); 15043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mNumFramesWritten = 0; 15057b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 15067b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 15077b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorNumFramesWritten = -1; 15087b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 15094110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen uint32_t written; 15104110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen if (mAudioSink->getFramesWritten(&written) == OK) { 15114110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen mNumFramesWritten = written; 15124110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen } 15133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 15143831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 1515bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::onDisableOffloadAudio() { 1516bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1517bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mFlags &= ~FLAG_OFFLOAD_AUDIO; 15187b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 1519e1d701902765c710398133025cfeee3ea8b6d280Robert Shih if (mAudioRenderingStartGeneration != -1) { 1520e1d701902765c710398133025cfeee3ea8b6d280Robert Shih prepareForMediaRenderingStart_l(); 1521e1d701902765c710398133025cfeee3ea8b6d280Robert Shih } 1522bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 1523bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 1524a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::onEnableOffloadAudio() { 1525a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu Mutex::Autolock autoLock(mLock); 1526a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu mFlags |= FLAG_OFFLOAD_AUDIO; 15277b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 1528e1d701902765c710398133025cfeee3ea8b6d280Robert Shih if (mAudioRenderingStartGeneration != -1) { 1529e1d701902765c710398133025cfeee3ea8b6d280Robert Shih prepareForMediaRenderingStart_l(); 1530e1d701902765c710398133025cfeee3ea8b6d280Robert Shih } 1531a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 1532a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 1533b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onPause() { 15348592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad if (mPaused) { 15358592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad return; 15368592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad } 15376d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar 153828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 153928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia Mutex::Autolock autoLock(mLock); 1540005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung // we do not increment audio drain generation so that we fill audio buffer during pause. 15417b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoDrainGeneration; 15427b15cb33847e6282ea8352c98894683b796127f3Wei Jia prepareForMediaRenderingStart_l(); 154373ddd210ea572375198cac1d4960df793745fb4bWei Jia mPaused = true; 15449816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->setPlaybackRate(0.0); 154528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1546b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 154728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mDrainAudioQueuePending = false; 1548b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mDrainVideoQueuePending = false; 1549cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1550b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 1551b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->pause(); 1552f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu startAudioOffloadPauseTimeout(); 1553b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1554b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 15556d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar ALOGV("now paused audio queue has %zu entries, video has %zu entries", 1556ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber mAudioQueue.size(), mVideoQueue.size()); 1557b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1558b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1559b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onResume() { 1560b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (!mPaused) { 1561b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber return; 1562b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 1563b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1564b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 1565f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu cancelAudioOffloadPauseTimeout(); 156697c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent status_t err = mAudioSink->start(); 156797c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent if (err != OK) { 156858d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung ALOGE("cannot start AudioSink err %d", err); 156997c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent notifyAudioTearDown(); 157097c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent } 1571b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1572b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 15737b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 15747b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 15757b15cb33847e6282ea8352c98894683b796127f3Wei Jia mPaused = false; 1576b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung // rendering started message may have been delayed if we were paused. 1577b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung if (mRenderingDataDelivered) { 1578b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung notifyIfMediaRenderingStarted_l(); 1579b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung } 15803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // configure audiosink as we did not do it when pausing 158127ea08e3811dc8057685258af52a7d40474eba16Wei Jia if (mAudioSink != NULL && mAudioSink->ready()) { 15823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mAudioSink->setPlaybackRate(mPlaybackSettings); 15833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 15843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 15859816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->setPlaybackRate(mPlaybackRate); 1586b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 15877b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (!mAudioQueue.empty()) { 15887b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainAudioQueue_l(); 15897b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 1590b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1591b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1592b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mVideoQueue.empty()) { 15937b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 1594b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1595b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1596b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1597c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::onSetVideoFrameRate(float fps) { 1598c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler == NULL) { 1599c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler = new VideoFrameScheduler(); 1600c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1601c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->init(fps); 1602c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 1603c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 16047b15cb33847e6282ea8352c98894683b796127f3Wei Jiaint32_t NuPlayer::Renderer::getQueueGeneration(bool audio) { 16057b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 16067b15cb33847e6282ea8352c98894683b796127f3Wei Jia return (audio ? mAudioQueueGeneration : mVideoQueueGeneration); 16077b15cb33847e6282ea8352c98894683b796127f3Wei Jia} 16087b15cb33847e6282ea8352c98894683b796127f3Wei Jia 16097b15cb33847e6282ea8352c98894683b796127f3Wei Jiaint32_t NuPlayer::Renderer::getDrainGeneration(bool audio) { 16107b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 16117b15cb33847e6282ea8352c98894683b796127f3Wei Jia return (audio ? mAudioDrainGeneration : mVideoDrainGeneration); 16127b15cb33847e6282ea8352c98894683b796127f3Wei Jia} 16137b15cb33847e6282ea8352c98894683b796127f3Wei Jia 16147b15cb33847e6282ea8352c98894683b796127f3Wei Jiabool NuPlayer::Renderer::getSyncQueues() { 16157b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 16167b15cb33847e6282ea8352c98894683b796127f3Wei Jia return mSyncQueues; 16177b15cb33847e6282ea8352c98894683b796127f3Wei Jia} 16187b15cb33847e6282ea8352c98894683b796127f3Wei Jia 1619faeb0f291330134dc4468359a36e099aae508449Ronghua Wuvoid NuPlayer::Renderer::onAudioTearDown(AudioTearDownReason reason) { 1620faeb0f291330134dc4468359a36e099aae508449Ronghua Wu if (mAudioTornDown) { 1621f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu return; 1622f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1623faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mAudioTornDown = true; 1624f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1625a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t currentPositionUs; 16261a5c859016e743779e4db25855390b3ce523cd48Robert Shih sp<AMessage> notify = mNotify->dup(); 16271a5c859016e743779e4db25855390b3ce523cd48Robert Shih if (getCurrentPosition(¤tPositionUs) == OK) { 16281a5c859016e743779e4db25855390b3ce523cd48Robert Shih notify->setInt64("positionUs", currentPositionUs); 162928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 163006ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar 16313a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->stop(); 16323a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->flush(); 16333a2956d148d81194e297408179e84a47a309ef48Wei Jia 1634faeb0f291330134dc4468359a36e099aae508449Ronghua Wu notify->setInt32("what", kWhatAudioTearDown); 16350852917279f79a94907e9906d0533ae409a30f6aRonghua Wu notify->setInt32("reason", reason); 16363a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->post(); 16373a2956d148d81194e297408179e84a47a309ef48Wei Jia} 16383a2956d148d81194e297408179e84a47a309ef48Wei Jia 1639f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::startAudioOffloadPauseTimeout() { 1640f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 164135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->acquire(); 16421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, this); 16437b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("drainGeneration", mAudioOffloadPauseTimeoutGeneration); 1644f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu msg->post(kOffloadPauseMaxUs); 1645f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1646f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1647f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1648f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() { 1649f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 165035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->release(true); 1651f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu ++mAudioOffloadPauseTimeoutGeneration; 1652f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1653f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1654f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1655202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::onOpenAudioSink( 16563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 16573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 16583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 16593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags) { 16603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)", 16613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadOnly, offloadingAudio()); 16623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool audioSinkChanged = false; 16633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t numChannels; 16653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("channel-count", &numChannels)); 16663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t channelMask; 16683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!format->findInt32("channel-mask", &channelMask)) { 16693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // signal to the AudioSink to derive the mask from count. 16703b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 16713b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 16723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16733b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t sampleRate; 16743b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("sample-rate", &sampleRate)); 16753b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (offloadingAudio()) { 16773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; 16783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AString mime; 16793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findString("mime", &mime)); 16803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str()); 16813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 16833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGE("Couldn't map mime \"%s\" to a valid " 16843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "audio_format", mime.c_str()); 16853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 16863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } else { 16873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("Mime \"%s\" mapped to audio_format 0x%x", 16883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mime.c_str(), audioFormat); 16893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int avgBitRate = -1; 16913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt32("bit-rate", &avgBitRate); 16923b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 16933b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t aacProfile = -1; 16943b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioFormat == AUDIO_FORMAT_AAC 16953b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang && format->findInt32("aac-profile", &aacProfile)) { 16963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Redefine AAC format as per aac profile 16973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mapAACProfileToAudioFormat( 16983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 16993b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang aacProfile); 17003b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 17013b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 17023b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 17033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.duration_us = -1; 17043b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt64( 17053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "durationUs", &offloadInfo.duration_us); 17063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.sample_rate = sampleRate; 17073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.channel_mask = channelMask; 17083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.format = audioFormat; 17093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.stream_type = AUDIO_STREAM_MUSIC; 17103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.bit_rate = avgBitRate; 17113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.has_video = hasVideo; 17123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.is_streaming = true; 17133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 17143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) { 17153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: no change in offload mode"); 17163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // no change from previous configuration, everything ok. 1717202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 17183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 1719f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 1720f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 17213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: try to open AudioSink in offload mode"); 1722d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t offloadFlags = flags; 1723d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1724d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 17253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 17263b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 1727a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 17283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang err = mAudioSink->open( 17293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 17303b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 17313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 17323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 1733179652ee2a508361df1aa18e99000373886f0816Andy Hung 0 /* bufferCount - unused */, 17343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &NuPlayer::Renderer::AudioSinkCallback, 17353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang this, 1736d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent (audio_output_flags_t)offloadFlags, 17373b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &offloadInfo); 17383b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 17393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err == OK) { 17403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar err = mAudioSink->setPlaybackRate(mPlaybackSettings); 17413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 17423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 17433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 17443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // If the playback is offloaded to h/w, we pass 17453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // the HAL some metadata information. 17463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // We don't want to do this for PCM because it 17473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // will be going through the AudioFlinger mixer 17483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // before reaching the hardware. 17493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // TODO 17503b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = offloadInfo; 175185e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung if (!mPaused) { // for preview mode, don't start if paused 175285e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung err = mAudioSink->start(); 175385e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung } 17543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV_IF(err == OK, "openAudioSink: offload succeeded"); 17553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 17563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 17573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Clean up, fall back to non offload mode. 17583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 17593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 17603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 17613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offload failed"); 17623ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia } else { 17633ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia mUseAudioCallback = true; // offload mode transfers data through callback 17643ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia ++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message. 17653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 17663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 17673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 17683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!offloadOnly && !offloadingAudio()) { 17693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: open AudioSink in NON-offload mode"); 1770d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t pcmFlags = flags; 1771d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1772f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 1773f0e83644637bd05852c244df481f21a0d435ff66Andy Hung const PcmInfo info = { 1774f0e83644637bd05852c244df481f21a0d435ff66Andy Hung (audio_channel_mask_t)channelMask, 1775f0e83644637bd05852c244df481f21a0d435ff66Andy Hung (audio_output_flags_t)pcmFlags, 1776f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat 1777f0e83644637bd05852c244df481f21a0d435ff66Andy Hung numChannels, 1778f0e83644637bd05852c244df481f21a0d435ff66Andy Hung sampleRate 1779f0e83644637bd05852c244df481f21a0d435ff66Andy Hung }; 1780f0e83644637bd05852c244df481f21a0d435ff66Andy Hung if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) { 1781f0e83644637bd05852c244df481f21a0d435ff66Andy Hung ALOGV("openAudioSink: no change in pcm mode"); 1782f0e83644637bd05852c244df481f21a0d435ff66Andy Hung // no change from previous configuration, everything ok. 1783f0e83644637bd05852c244df481f21a0d435ff66Andy Hung return OK; 1784f0e83644637bd05852c244df481f21a0d435ff66Andy Hung } 1785f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 17863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 17873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 17883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 1789a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // Note: It is possible to set up the callback, but not use it to send audio data. 1790a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // This requires a fix in AudioSink to explicitly specify the transfer mode. 1791a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback = getUseAudioCallbackSetting(); 17923ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia if (mUseAudioCallback) { 17933ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia ++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message. 17943ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia } 1795179652ee2a508361df1aa18e99000373886f0816Andy Hung 1796179652ee2a508361df1aa18e99000373886f0816Andy Hung // Compute the desired buffer size. 1797179652ee2a508361df1aa18e99000373886f0816Andy Hung // For callback mode, the amount of time before wakeup is about half the buffer size. 1798179652ee2a508361df1aa18e99000373886f0816Andy Hung const uint32_t frameCount = 1799179652ee2a508361df1aa18e99000373886f0816Andy Hung (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000; 1800179652ee2a508361df1aa18e99000373886f0816Andy Hung 18017665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // The doNotReconnect means AudioSink will signal back and let NuPlayer to re-construct 18027665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // AudioSink. We don't want this when there's video because it will cause a video seek to 18037665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // the previous I frame. But we do want this when there's only audio because it will give 18047665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // NuPlayer a chance to switch from non-offload mode to offload mode. 18057665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // So we only set doNotReconnect when there's no video. 18067665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu const bool doNotReconnect = !hasVideo; 1807202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = mAudioSink->open( 18083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 18093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 18103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 18113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AUDIO_FORMAT_PCM_16_BIT, 1812179652ee2a508361df1aa18e99000373886f0816Andy Hung 0 /* bufferCount - unused */, 1813a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback ? &NuPlayer::Renderer::AudioSinkCallback : NULL, 1814a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback ? this : NULL, 1815faeb0f291330134dc4468359a36e099aae508449Ronghua Wu (audio_output_flags_t)pcmFlags, 1816faeb0f291330134dc4468359a36e099aae508449Ronghua Wu NULL, 18177665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu doNotReconnect, 1818179652ee2a508361df1aa18e99000373886f0816Andy Hung frameCount); 18193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 18203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar err = mAudioSink->setPlaybackRate(mPlaybackSettings); 18213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1822202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (err != OK) { 1823202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGW("openAudioSink: non offloaded open failed status: %d", err); 18244d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia mAudioSink->close(); 1825f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 1826202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 1827202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 1828f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = info; 1829005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung if (!mPaused) { // for preview mode, don't start if paused 1830005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung mAudioSink->start(); 1831005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung } 18323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 18333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioSinkChanged) { 18343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onAudioSinkChanged(); 18353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 1836faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mAudioTornDown = false; 1837202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 18383b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 18393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::onCloseAudioSink() { 18413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 18423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 1843f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 18443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 18453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 1846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1848