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" 22f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung#include <algorithm> 23a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung#include <cutils/properties.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> 337e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h> 34dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 35095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <inttypes.h> 36095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 37f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 39a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung/* 40a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * Example of common configuration settings in shell script form 41a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 42a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung #Turn offload audio off (use PCM for Play Music) -- AudioPolicyManager 43a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung adb shell setprop audio.offload.disable 1 44a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 45a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung #Allow offload audio with video (requires offloading to be enabled) -- AudioPolicyManager 46a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung adb shell setprop audio.offload.video 1 47a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 48a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung #Use audio callbacks for PCM data 49a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung adb shell setprop media.stagefright.audio.cbk 1 50a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 51288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung #Use deep buffer for PCM data with video (it is generally enabled for audio-only) 52288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung adb shell setprop media.stagefright.audio.deep 1 53288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung 54179652ee2a508361df1aa18e99000373886f0816Andy Hung #Set size of buffers for pcm audio sink in msec (example: 1000 msec) 55179652ee2a508361df1aa18e99000373886f0816Andy Hung adb shell setprop media.stagefright.audio.sink 1000 56179652ee2a508361df1aa18e99000373886f0816Andy Hung 57a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * These configurations take effect for the next track played (not the current track). 58a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung */ 59a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 60a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hungstatic inline bool getUseAudioCallbackSetting() { 61a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung return property_get_bool("media.stagefright.audio.cbk", false /* default_value */); 62a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung} 63a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 64179652ee2a508361df1aa18e99000373886f0816Andy Hungstatic inline int32_t getAudioSinkPcmMsSetting() { 65179652ee2a508361df1aa18e99000373886f0816Andy Hung return property_get_int32( 66179652ee2a508361df1aa18e99000373886f0816Andy Hung "media.stagefright.audio.sink", 500 /* default_value */); 67179652ee2a508361df1aa18e99000373886f0816Andy Hung} 68179652ee2a508361df1aa18e99000373886f0816Andy Hung 69f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink 70f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu// is closed to allow the audio DSP to power down. 71a5d316fd802cfc92954527f27e6f32206a896113Eric Laurentstatic const int64_t kOffloadPauseMaxUs = 10000000ll; 72f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 7312b6265f1d4be368957f91104d5210cf604ac4ccWei Jia// Maximum allowed delay from AudioSink, 1.5 seconds. 7412b6265f1d4be368957f91104d5210cf604ac4ccWei Jiastatic const int64_t kMaxAllowedAudioSinkDelayUs = 1500000ll; 7512b6265f1d4be368957f91104d5210cf604ac4ccWei Jia 76528c8403ad2ede53054a706a20c00b710fa08166Andy Hungstatic const int64_t kMinimumAudioClockUpdatePeriodUs = 20 /* msec */ * 1000; 77528c8403ad2ede53054a706a20c00b710fa08166Andy Hung 78714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber// static 79f0e83644637bd05852c244df481f21a0d435ff66Andy Hungconst NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = { 80f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_CHANNEL_NONE, 81f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_OUTPUT_FLAG_NONE, 82f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_FORMAT_INVALID, 83f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 0, // mNumChannels 84f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 0 // mSampleRate 85f0e83644637bd05852c244df481f21a0d435ff66Andy Hung}; 86f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 87f0e83644637bd05852c244df481f21a0d435ff66Andy Hung// static 88714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huberconst int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; 89714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 90f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::Renderer( 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MediaPlayerBase::AudioSink> &sink, 92d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber const sp<AMessage> ¬ify, 93d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber uint32_t flags) 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mAudioSink(sink), 95d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia mUseVirtualAudioSink(false), 96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNotify(notify), 97d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mFlags(flags), 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumFramesWritten(0), 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending(false), 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending(false), 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueueGeneration(0), 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueueGeneration(0), 1037b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioDrainGeneration(0), 1047b15cb33847e6282ea8352c98894683b796127f3Wei Jia mVideoDrainGeneration(0), 1057c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia mAudioEOSGeneration(0), 1063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT), 107a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs(-1), 108eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu mAnchorTimeMediaUs(-1), 109f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar mAnchorNumFramesWritten(-1), 110a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs(0ll), 111bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasAudio(false), 112bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasVideo(false), 1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio(false), 1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo(false), 115bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mSyncQueues(false), 116714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber mPaused(false), 117b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung mPauseDrainAudioAllowedUs(0), 11809e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung mVideoSampleReceived(false), 119f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong mVideoRenderingStarted(false), 120cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration(0), 121cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration(0), 122b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung mRenderingDataDelivered(false), 123528c8403ad2ede53054a706a20c00b710fa08166Andy Hung mNextAudioClockUpdateTimeUs(-1), 1242995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mLastAudioMediaTimeUs(-1), 125f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu mAudioOffloadPauseTimeoutGeneration(0), 126faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mAudioTornDown(false), 127d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), 128f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER), 129d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mTotalBuffersQueued(0), 13035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mLastAudioBufferDrained(0), 131a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback(false), 13235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock(new AWakeLock()) { 1337b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock = new MediaClock; 1343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackRate = mPlaybackSettings.mSpeed; 1353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mMediaClock->setPlaybackRate(mPlaybackRate); 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 138f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::~Renderer() { 139bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 140bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 141bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 142bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->close(); 143bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1444c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia 1454c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia // Try to avoid racing condition in case callback is still on. 1464c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia Mutex::Autolock autoLock(mLock); 1479a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (mUseAudioCallback) { 1489a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia flushQueue(&mAudioQueue); 1499a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia flushQueue(&mVideoQueue); 1509a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 1514c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia mWakeLock.clear(); 1524c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia mMediaClock.clear(); 1534c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia mVideoScheduler.clear(); 1544c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia mNotify.clear(); 1554c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia mAudioSink.clear(); 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 158f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueBuffer( 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, 1607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim const sp<MediaCodecBuffer> &buffer, 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> ¬ifyConsumed) { 1621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this); 1637b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("queueGeneration", getQueueGeneration(audio)); 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 1657e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim msg->setObject("buffer", buffer); 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setMessage("notifyConsumed", notifyConsumed); 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 170f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) { 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(finalResult, (status_t)OK); 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueEOS, this); 1747b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("queueGeneration", getQueueGeneration(audio)); 175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("finalResult", finalResult); 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::setPlaybackSettings(const AudioPlaybackRate &rate) { 1813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this); 1823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(msg, rate); 1833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 1843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 1853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 1863a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 1873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 1893a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 1903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 1913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) { 1923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (rate.mSpeed == 0.f) { 1933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar onPause(); 1943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // don't call audiosink's setPlaybackRate if pausing, as pitch does not 1953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // have to correspond to the any non-0 speed (e.g old speed). Keep 1963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // settings nonetheless, using the old speed, in case audiosink changes. 1973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AudioPlaybackRate newRate = rate; 1983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar newRate.mSpeed = mPlaybackSettings.mSpeed; 1993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = newRate; 2003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 2013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 20327ea08e3811dc8057685258af52a7d40474eba16Wei Jia if (mAudioSink != NULL && mAudioSink->ready()) { 2043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = mAudioSink->setPlaybackRate(rate); 2053a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err != OK) { 2063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = rate; 2103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackRate = rate.mSpeed; 2113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mMediaClock->setPlaybackRate(mPlaybackRate); 2123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 2133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) { 2163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this); 2173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 2183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 2193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 2203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 2213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 2223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(response, rate); 2233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) { 22927ea08e3811dc8057685258af52a7d40474eba16Wei Jia if (mAudioSink != NULL && mAudioSink->ready()) { 2303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = mAudioSink->getPlaybackRate(rate); 2313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 2323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) { 2333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGW("correcting mismatch in internal/external playback rate"); 2343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // get playback settings used by audiosink, as it may be 2363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // slightly off due to audiosink not taking small changes. 2373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = *rate; 2383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mPaused) { 2393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar rate->mSpeed = 0.f; 2403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *rate = mPlaybackSettings; 2453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 2463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) { 2493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigSync, this); 2503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(msg, sync, videoFpsHint); 2513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 2523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 2533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 2543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 2553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onConfigSync(const AVSyncSettings &sync, float videoFpsHint __unused) { 2603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (sync.mSource != AVSYNC_SOURCE_DEFAULT) { 2613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 2623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // TODO: support sync sources 2643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return INVALID_OPERATION; 2653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::getSyncSettings(AVSyncSettings *sync, float *videoFps) { 2683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this); 2693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response; 2703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 2713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK && response != NULL) { 2723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(response->findInt32("err", &err)); 2733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 2743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(response, sync, videoFps); 2753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 2773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 2783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 2793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 2803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t NuPlayer::Renderer::onGetSyncSettings( 2813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) { 2823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *sync = mSyncSettings; 2833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *videoFps = -1.f; 2843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 2859816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia} 2869816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia 2877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Renderer::flush(bool audio, bool notifyComplete) { 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2897b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio |= notifyComplete; 2923b0cd26dbb0ce37d220db9ff0fa8172a7ef1c5cbWei Jia clearAudioFirstAnchorTime_l(); 2937b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioQueueGeneration; 2947b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 2967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo |= notifyComplete; 2977b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoQueueGeneration; 2987b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoDrainGeneration; 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3007b15cb33847e6282ea8352c98894683b796127f3Wei Jia 3019a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia mMediaClock->clearAnchor(); 3027b15cb33847e6282ea8352c98894683b796127f3Wei Jia mVideoLateByUs = 0; 3037b15cb33847e6282ea8352c98894683b796127f3Wei Jia mSyncQueues = false; 304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 311f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::signalTimeDiscontinuity() { 31228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 31328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 31428a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jiavoid NuPlayer::Renderer::signalDisableOffloadAudio() { 3151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatDisableOffloadAudio, this))->post(); 31628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia} 31728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 318a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::signalEnableOffloadAudio() { 3191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatEnableOffloadAudio, this))->post(); 320a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 321a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 322b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::pause() { 3231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatPause, this))->post(); 324b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 325b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 326b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::resume() { 3271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatResume, this))->post(); 328b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 329b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 330c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::setVideoFrameRate(float fps) { 3311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, this); 332c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->setFloat("frame-rate", fps); 333c851b5de495169d7e9528644c2592746021bd968Lajos Molnar msg->post(); 334c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 335c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 3364ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia// Called on any threads without mLock acquired. 3377b15cb33847e6282ea8352c98894683b796127f3Wei Jiastatus_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) { 3384ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs); 3394ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (result == OK) { 3404ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia return result; 3414ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3424ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3434ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia // MediaClock has not started yet. Try to start it if possible. 3444ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia { 3454ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia Mutex::Autolock autoLock(mLock); 3464ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (mAudioFirstAnchorTimeMediaUs == -1) { 3474ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia return result; 3484ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3494ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3504ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia AudioTimestamp ts; 3514ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia status_t res = mAudioSink->getTimestamp(ts); 3524ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia if (res != OK) { 3534ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia return result; 3544ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3554ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3564ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia // AudioSink has rendered some frames. 3574ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia int64_t nowUs = ALooper::GetNowUs(); 358d855a738735a3df8863b486f5d3b5e404cef15c1Wei Jia int64_t nowMediaUs = mAudioSink->getPlayedOutDurationUs(nowUs) 3594ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia + mAudioFirstAnchorTimeMediaUs; 3604ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia mMediaClock->updateAnchor(nowMediaUs, nowUs, -1); 3614ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 3624ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 3639816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs); 364a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 365a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 3667b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::clearAudioFirstAnchorTime_l() { 3677b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioFirstAnchorTimeMediaUs = -1; 3687b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->setStartingTimeMedia(-1); 369a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 370a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 3717b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs) { 372a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mAudioFirstAnchorTimeMediaUs == -1) { 373a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mAudioFirstAnchorTimeMediaUs = mediaUs; 3747b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->setStartingTimeMedia(mediaUs); 375a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 376a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 377a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 3789a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia// Called on renderer looper. 3799a3101b22b5115717faeac986b43fc6618fd3b30Wei Jiavoid NuPlayer::Renderer::clearAnchorTime() { 3807b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->clearAnchor(); 3817b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorTimeMediaUs = -1; 3827b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorNumFramesWritten = -1; 383a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 384a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 385a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::Renderer::setVideoLateByUs(int64_t lateUs) { 3867b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 387a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu mVideoLateByUs = lateUs; 388a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 389a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 390a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getVideoLateByUs() { 3917b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 392a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu return mVideoLateByUs; 393a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 394a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 395202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::openAudioSink( 3963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 3973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 3983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 399202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung uint32_t flags, 400c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar bool *isOffloaded, 401c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar bool isStreaming) { 4021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this); 4033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setMessage("format", format); 4043b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("offload-only", offloadOnly); 4053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("has-video", hasVideo); 4063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->setInt32("flags", flags); 407c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar msg->setInt32("isStreaming", isStreaming); 4083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 41066e4c4779f17198dd3cb0b13b97a7943c6eae3e5Leena Winterrowd status_t postStatus = msg->postAndAwaitResponse(&response); 4113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 412202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t err; 41366e4c4779f17198dd3cb0b13b97a7943c6eae3e5Leena Winterrowd if (postStatus != OK || response.get() == nullptr || !response->findInt32("err", &err)) { 414202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung err = INVALID_OPERATION; 415202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } else if (err == OK && isOffloaded != NULL) { 416202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung int32_t offload; 417202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung CHECK(response->findInt32("offload", &offload)); 418202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung *isOffloaded = (offload != 0); 419202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 420202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 4213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 4223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4233b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::closeAudioSink() { 4241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, this); 4253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4263b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response; 4273b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang msg->postAndAwaitResponse(&response); 4283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 4293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4309a3101b22b5115717faeac986b43fc6618fd3b30Wei Jiavoid NuPlayer::Renderer::changeAudioFormat( 4319a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia const sp<AMessage> &format, 4329a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia bool offloadOnly, 4339a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia bool hasVideo, 4349a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia uint32_t flags, 435c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar bool isStreaming, 4369a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia const sp<AMessage> ¬ify) { 4379a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia sp<AMessage> meta = new AMessage; 4389a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia meta->setMessage("format", format); 4399a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia meta->setInt32("offload-only", offloadOnly); 4409a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia meta->setInt32("has-video", hasVideo); 4419a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia meta->setInt32("flags", flags); 442c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar meta->setInt32("isStreaming", isStreaming); 4439a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 4449a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia sp<AMessage> msg = new AMessage(kWhatChangeAudioFormat, this); 4459a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia msg->setInt32("queueGeneration", getQueueGeneration(true /* audio */)); 4469a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia msg->setMessage("notify", notify); 4479a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia msg->setMessage("meta", meta); 4489a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia msg->post(); 4499a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia} 4509a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 451f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 4533b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatOpenAudioSink: 4543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 4553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> format; 4563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findMessage("format", &format)); 4573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t offloadOnly; 4593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("offload-only", &offloadOnly)); 4603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t hasVideo; 4623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("has-video", &hasVideo)); 4633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang uint32_t flags; 4653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 4663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 467c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar uint32_t isStreaming; 468c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar CHECK(msg->findInt32("isStreaming", (int32_t *)&isStreaming)); 469c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar 470c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming); 4713b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 473202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("err", err); 474202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung response->setInt32("offload", offloadingAudio()); 4753b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4763f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 4773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 4783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 4793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 4813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 4823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang case kWhatCloseAudioSink: 4843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang { 4853f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 4863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 4873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onCloseAudioSink(); 4893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 4903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sp<AMessage> response = new AMessage; 4913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang response->postReply(replyID); 4923b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang break; 4933b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 4943b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 495bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatStopAudioSink: 496bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 497bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->stop(); 498bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 499bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 500bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 5019a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia case kWhatChangeAudioFormat: 5029a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia { 5039a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia int32_t queueGeneration; 5049a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(msg->findInt32("queueGeneration", &queueGeneration)); 5059a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5069a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia sp<AMessage> notify; 5079a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(msg->findMessage("notify", ¬ify)); 5089a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5099a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (offloadingAudio()) { 5109a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia ALOGW("changeAudioFormat should NOT be called in offload mode"); 5119a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia notify->setInt32("err", INVALID_OPERATION); 5129a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia notify->post(); 5139a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia break; 5149a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 5159a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5169a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia sp<AMessage> meta; 5179a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(msg->findMessage("meta", &meta)); 5189a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5199a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (queueGeneration != getQueueGeneration(true /* audio */) 5209a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia || mAudioQueue.empty()) { 5219a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia onChangeAudioFormat(meta, notify); 5229a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia break; 5239a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 5249a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5259a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia QueueEntry entry; 5269a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia entry.mNotifyConsumed = notify; 5279a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia entry.mMeta = meta; 5289a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5299a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia Mutex::Autolock autoLock(mLock); 5309a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia mAudioQueue.push_back(entry); 5319a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia postDrainAudioQueue_l(); 5329a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 5339a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia break; 5349a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 5359a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainAudioQueue: 537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5383ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia mDrainAudioQueuePending = false; 5393ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 5417b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 5427b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (generation != getDrainGeneration(true /* audio */)) { 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 546078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (onDrainAudioQueue()) { 547078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 548078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), 549078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (status_t)OK); 550078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 551078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPendingPlayout = 552078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten - numFramesPlayed; 553078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 554078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // This is how long the audio sink will have data to 555078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // play back. 556078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int64_t delayUs = 557078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->msecsPerFrame() 558078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber * numFramesPendingPlayout * 1000ll; 559d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia if (mPlaybackRate > 1.0f) { 560d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia delayUs /= mPlaybackRate; 561d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia } 562078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 563078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // Let's give it more data after about half that time 564078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // has elapsed. 565f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung delayUs /= 2; 566f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung // check the buffer size to estimate maximum delay permitted. 567f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung const int64_t maxDrainDelayUs = std::max( 568f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung mAudioSink->getBufferDurationInUs(), (int64_t)500000 /* half second */); 569f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung ALOGD_IF(delayUs > maxDrainDelayUs, "postDrainAudioQueue long delay: %lld > %lld", 570f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung (long long)delayUs, (long long)maxDrainDelayUs); 5717b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 572f2c87b3f88d987d2af6322e9763eb8224a2bae48Andy Hung postDrainAudioQueue_l(delayUs); 573078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainVideoQueue: 578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 5807b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 5817b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (generation != getDrainGeneration(false /* audio */)) { 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainVideoQueue(); 588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5897b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 593d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar case kWhatPostDrainVideoQueue: 594d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar { 595d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar int32_t generation; 5967b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 5977b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (generation != getDrainGeneration(false /* audio */)) { 598d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 599d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 600d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 601d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = false; 6027b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 603d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar break; 604d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 605d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueBuffer: 607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueBuffer(msg); 609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueEOS: 613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueEOS(msg); 615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6187c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia case kWhatEOS: 6197c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia { 6207c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia int32_t generation; 6217c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia CHECK(msg->findInt32("audioEOSGeneration", &generation)); 6227c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia if (generation != mAudioEOSGeneration) { 6237c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia break; 6247c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia } 6257c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia status_t finalResult; 6267c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia CHECK(msg->findInt32("finalResult", &finalResult)); 6277c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia notifyEOS(true /* audio */, finalResult); 6287c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia break; 6297c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia } 6307c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia 6313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatConfigPlayback: 6329816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia { 6333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 6343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 6353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AudioPlaybackRate rate; 6363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(msg, &rate); 6373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onConfigPlayback(rate); 6383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 6393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 6403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 6413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 6423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 6433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 6443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatGetPlaybackSettings: 6453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar { 6463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 6473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 6483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; 6493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onGetPlaybackSettings(&rate); 6503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 6513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 6523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(response, rate); 6533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 6543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 6553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 6563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 6573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 6583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 6593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatConfigSync: 6603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar { 6613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 6623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 6633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings sync; 6643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar float videoFpsHint; 6653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar readFromAMessage(msg, &sync, &videoFpsHint); 6663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onConfigSync(sync, videoFpsHint); 6673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 6683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 6693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 6703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 6713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 6723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 6733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case kWhatGetSyncSettings: 6743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar { 6753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AReplyToken> replyID; 6763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 6773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 6783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGV("kWhatGetSyncSettings"); 6793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings sync; 6803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar float videoFps = -1.f; 6813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = onGetSyncSettings(&sync, &videoFps); 6823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar sp<AMessage> response = new AMessage; 6833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 6843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar writeToAMessage(response, sync, videoFps); 6853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 6863a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->setInt32("err", err); 6873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar response->postReply(replyID); 6889816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia break; 6899816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia } 6909816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia 691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFlush(msg); 694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 697bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatDisableOffloadAudio: 698bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 699bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia onDisableOffloadAudio(); 700bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 701bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 702bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 703a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu case kWhatEnableOffloadAudio: 704a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu { 705a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu onEnableOffloadAudio(); 706a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu break; 707a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu } 708a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 709b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatPause: 710b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 711b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onPause(); 712b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 713b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 714b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 715b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatResume: 716b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 717b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onResume(); 718b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 719b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 720b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 721c851b5de495169d7e9528644c2592746021bd968Lajos Molnar case kWhatSetVideoFrameRate: 722c851b5de495169d7e9528644c2592746021bd968Lajos Molnar { 723c851b5de495169d7e9528644c2592746021bd968Lajos Molnar float fps; 724c851b5de495169d7e9528644c2592746021bd968Lajos Molnar CHECK(msg->findFloat("frame-rate", &fps)); 725c851b5de495169d7e9528644c2592746021bd968Lajos Molnar onSetVideoFrameRate(fps); 726c851b5de495169d7e9528644c2592746021bd968Lajos Molnar break; 727c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 728c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 729faeb0f291330134dc4468359a36e099aae508449Ronghua Wu case kWhatAudioTearDown: 7303a2956d148d81194e297408179e84a47a309ef48Wei Jia { 731a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia int32_t reason; 732a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia CHECK(msg->findInt32("reason", &reason)); 733a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia 734a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia onAudioTearDown((AudioTearDownReason)reason); 7353a2956d148d81194e297408179e84a47a309ef48Wei Jia break; 7363a2956d148d81194e297408179e84a47a309ef48Wei Jia } 7373a2956d148d81194e297408179e84a47a309ef48Wei Jia 738f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu case kWhatAudioOffloadPauseTimeout: 739f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu { 740f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu int32_t generation; 7417b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("drainGeneration", &generation)); 742f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (generation != mAudioOffloadPauseTimeoutGeneration) { 743f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 744f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 7450852917279f79a94907e9906d0533ae409a30f6aRonghua Wu ALOGV("Audio Offload tear down due to pause timeout."); 746faeb0f291330134dc4468359a36e099aae508449Ronghua Wu onAudioTearDown(kDueToTimeout); 74735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->release(); 748f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu break; 749f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 750f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 757bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) { 758005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung if (mDrainAudioQueuePending || mSyncQueues || mUseAudioCallback) { 759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioQueue.empty()) { 763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 766b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // FIXME: if paused, wait until AudioTrack stop() is complete before delivering data. 767b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung if (mPaused) { 768b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung const int64_t diffUs = mPauseDrainAudioAllowedUs - ALooper::GetNowUs(); 769b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung if (diffUs > delayUs) { 770b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung delayUs = diffUs; 771b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung } 772b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung } 773b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung 774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = true; 7751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this); 7767b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("drainGeneration", mAudioDrainGeneration); 777078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber msg->post(delayUs); 778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7807b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::prepareForMediaRenderingStart_l() { 7817b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioRenderingStartGeneration = mAudioDrainGeneration; 7827b15cb33847e6282ea8352c98894683b796127f3Wei Jia mVideoRenderingStartGeneration = mVideoDrainGeneration; 783b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung mRenderingDataDelivered = false; 784cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 785cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 7867b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::notifyIfMediaRenderingStarted_l() { 7877b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (mVideoRenderingStartGeneration == mVideoDrainGeneration && 7887b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAudioRenderingStartGeneration == mAudioDrainGeneration) { 789b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung mRenderingDataDelivered = true; 790b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung if (mPaused) { 791b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung return; 792b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung } 793cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mVideoRenderingStartGeneration = -1; 794cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar mAudioRenderingStartGeneration = -1; 795cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 796cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar sp<AMessage> notify = mNotify->dup(); 797cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->setInt32("what", kWhatMediaRenderingStart); 798cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar notify->post(); 799cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar } 800cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar} 801cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 802bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia// static 803bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::AudioSinkCallback( 804bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink * /* audioSink */, 805bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *buffer, 806bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t size, 807bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia void *cookie, 808bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia MediaPlayerBase::AudioSink::cb_event_t event) { 809bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia NuPlayer::Renderer *me = (NuPlayer::Renderer *)cookie; 810bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 811bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia switch (event) { 812bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER: 813bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 814bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return me->fillAudioBuffer(buffer, size); 815bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 816bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 817bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 818bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END: 819bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 820a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("AudioSink::CB_EVENT_STREAM_END"); 8214c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia me->notifyEOSCallback(); 822bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 823bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 824bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 825bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN: 826bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 827a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("AudioSink::CB_EVENT_TEAR_DOWN"); 828a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia me->notifyAudioTearDown(kDueToError); 829bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 830bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 831bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 832bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 833bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 834bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 835bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 8364c74fde2ef5b582196b296a8263cd39143e7abcaWei Jiavoid NuPlayer::Renderer::notifyEOSCallback() { 8374c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia Mutex::Autolock autoLock(mLock); 8384c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia 8394c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia if (!mUseAudioCallback) { 8404c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia return; 8414c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia } 8424c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia 8434c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia notifyEOS(true /* audio */, ERROR_END_OF_STREAM); 8444c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia} 8454c74fde2ef5b582196b296a8263cd39143e7abcaWei Jia 846bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiasize_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { 847bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 848bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 84985e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung if (!mUseAudioCallback) { 850bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return 0; 851bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 852bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 853bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia bool hasEOS = false; 854bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 855bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeCopied = 0; 8563e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu bool firstEntry = true; 857a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung QueueEntry *entry; // will be valid after while loop if hasEOS is set. 858bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia while (sizeCopied < size && !mAudioQueue.empty()) { 859a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung entry = &*mAudioQueue.begin(); 860bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 861bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mBuffer == NULL) { // EOS 862bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia hasEOS = true; 863bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 864bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 865bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 866bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 8673e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu if (firstEntry && entry->mOffset == 0) { 8683e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu firstEntry = false; 869bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int64_t mediaTimeUs; 870bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 871a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 8727b15cb33847e6282ea8352c98894683b796127f3Wei Jia setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs); 873bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 874bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 875bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t copy = entry->mBuffer->size() - entry->mOffset; 876bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia size_t sizeRemaining = size - sizeCopied; 877bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (copy > sizeRemaining) { 878bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy = sizeRemaining; 879bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 880bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 881bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia memcpy((char *)buffer + sizeCopied, 882bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mBuffer->data() + entry->mOffset, 883bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia copy); 884bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 885bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mOffset += copy; 886bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (entry->mOffset == entry->mBuffer->size()) { 887bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry->mNotifyConsumed->post(); 888bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 889bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia entry = NULL; 890bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 891bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia sizeCopied += copy; 8927b15cb33847e6282ea8352c98894683b796127f3Wei Jia 8937b15cb33847e6282ea8352c98894683b796127f3Wei Jia notifyIfMediaRenderingStarted_l(); 894bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 895bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 896f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (mAudioFirstAnchorTimeMediaUs >= 0) { 897f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 8989816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t nowMediaUs = 899c4ac8173f911aeac8d5006b19ba48fb51a865115Wei Jia mAudioFirstAnchorTimeMediaUs + mAudioSink->getPlayedOutDurationUs(nowUs); 9007b15cb33847e6282ea8352c98894683b796127f3Wei Jia // we don't know how much data we are queueing for offloaded tracks. 9019816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX); 902f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 903f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 904a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // for non-offloaded audio, we need to compute the frames written because 905a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // there is no EVENT_STREAM_END notification. The frames written gives 906a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // an estimate on the pending played out duration. 907a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung if (!offloadingAudio()) { 908a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mNumFramesWritten += sizeCopied / mAudioSink->frameSize(); 909a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung } 910a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 911bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (hasEOS) { 9121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStopAudioSink, this))->post(); 913a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // As there is currently no EVENT_STREAM_END callback notification for 914a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // non-offloaded audio tracks, we need to post the EOS ourselves. 915a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung if (!offloadingAudio()) { 916a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung int64_t postEOSDelayUs = 0; 917a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung if (mAudioSink->needsTrailingPadding()) { 918a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); 919a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung } 920a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("fillAudioBuffer: notifyEOS " 921a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung "mNumFramesWritten:%u finalResult:%d postEOSDelay:%lld", 922a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs); 923a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); 924a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung } 925bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 926bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return sizeCopied; 927bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 928bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 9299da0ce44f228408d73a4dea0be972c785095dcccChong Zhangvoid NuPlayer::Renderer::drainAudioQueueUntilLastEOS() { 9309da0ce44f228408d73a4dea0be972c785095dcccChong Zhang List<QueueEntry>::iterator it = mAudioQueue.begin(), itEOS = it; 9319da0ce44f228408d73a4dea0be972c785095dcccChong Zhang bool foundEOS = false; 9329da0ce44f228408d73a4dea0be972c785095dcccChong Zhang while (it != mAudioQueue.end()) { 9339da0ce44f228408d73a4dea0be972c785095dcccChong Zhang int32_t eos; 9349da0ce44f228408d73a4dea0be972c785095dcccChong Zhang QueueEntry *entry = &*it++; 9359a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if ((entry->mBuffer == nullptr && entry->mNotifyConsumed == nullptr) 9369da0ce44f228408d73a4dea0be972c785095dcccChong Zhang || (entry->mNotifyConsumed->findInt32("eos", &eos) && eos != 0)) { 9379da0ce44f228408d73a4dea0be972c785095dcccChong Zhang itEOS = it; 9389da0ce44f228408d73a4dea0be972c785095dcccChong Zhang foundEOS = true; 9399da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 9409da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 9419da0ce44f228408d73a4dea0be972c785095dcccChong Zhang 9429da0ce44f228408d73a4dea0be972c785095dcccChong Zhang if (foundEOS) { 9439da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // post all replies before EOS and drop the samples 9449da0ce44f228408d73a4dea0be972c785095dcccChong Zhang for (it = mAudioQueue.begin(); it != itEOS; it++) { 9459a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (it->mBuffer == nullptr) { 9469a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (it->mNotifyConsumed == nullptr) { 9479a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia // delay doesn't matter as we don't even have an AudioTrack 9489a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia notifyEOS(true /* audio */, it->mFinalResult); 9499a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } else { 9509a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia // TAG for re-opening audio sink. 9519a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia onChangeAudioFormat(it->mMeta, it->mNotifyConsumed); 9529a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 9539da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } else { 9549da0ce44f228408d73a4dea0be972c785095dcccChong Zhang it->mNotifyConsumed->post(); 9559da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 9569da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 9579da0ce44f228408d73a4dea0be972c785095dcccChong Zhang mAudioQueue.erase(mAudioQueue.begin(), itEOS); 9589da0ce44f228408d73a4dea0be972c785095dcccChong Zhang } 9599da0ce44f228408d73a4dea0be972c785095dcccChong Zhang} 9609da0ce44f228408d73a4dea0be972c785095dcccChong Zhang 961078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huberbool NuPlayer::Renderer::onDrainAudioQueue() { 96258d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung // do not drain audio during teardown as queued buffers may be invalid. 96358d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung if (mAudioTornDown) { 96458d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung return false; 96558d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung } 966230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // TODO: This call to getPosition checks if AudioTrack has been created 967230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // in AudioSink before draining audio. If AudioTrack doesn't exist, then 968230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // CHECKs on getPosition will fail. 969230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // We still need to figure out why AudioTrack is not created when 970230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // this function is called. One possible reason could be leftover 971230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // audio. Another possible place is to check whether decoder 972230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // has received INFO_FORMAT_CHANGED as the first buffer since 973230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // AudioSink is opened there, and possible interactions with flush 974230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // immediately after start. Investigate error message 975230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia // "vorbis_dsp_synthesis returned -135", along with RTSP. 976078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 9772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mAudioSink->getPosition(&numFramesPlayed) != OK) { 9789da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // When getPosition fails, renderer will not reschedule the draining 9799da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // unless new samples are queued. 9809da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // If we have pending EOS (or "eos" marker for discontinuities), we need 9819da0ce44f228408d73a4dea0be972c785095dcccChong Zhang // to post these now as NuPlayerDecoder might be waiting for it. 9829da0ce44f228408d73a4dea0be972c785095dcccChong Zhang drainAudioQueueUntilLastEOS(); 9839da0ce44f228408d73a4dea0be972c785095dcccChong Zhang 9849da0ce44f228408d73a4dea0be972c785095dcccChong Zhang ALOGW("onDrainAudioQueue(): audio sink is not ready"); 9852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return false; 9862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 987078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 988230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia#if 0 989078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber ssize_t numFramesAvailableToWrite = 990078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); 991078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 992078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (numFramesAvailableToWrite == mAudioSink->frameCount()) { 993df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("audio sink underrun"); 994078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 9953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("audio queue has %d frames left to play", 996078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - numFramesAvailableToWrite); 997078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 998078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#endif 999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1000005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung uint32_t prevFramesWritten = mNumFramesWritten; 10017d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia while (!mAudioQueue.empty()) { 1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mAudioQueue.begin(); 1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 10059a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (entry->mNotifyConsumed != nullptr) { 10069a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia // TAG for re-open audio sink. 10079a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed); 10089a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia mAudioQueue.erase(mAudioQueue.begin()); 10099a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia continue; 10109a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 10119a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 101362d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George if (mPaused) { 101462d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George // Do not notify EOS when paused. 101562d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George // This is needed to avoid switch to next clip while in pause. 101662d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George ALOGV("onDrainAudioQueue(): Do not notify EOS when paused"); 101762d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George return false; 101862d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George } 101962d4e07eb5f99bd469f92897e47f5598abef99d3Haynes Mathew George 10205095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu int64_t postEOSDelayUs = 0; 10215095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu if (mAudioSink->needsTrailingPadding()) { 102206ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs()); 10235095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu } 10245095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs); 10252995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mLastAudioMediaTimeUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten); 1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 10293491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung if (mAudioSink->needsTrailingPadding()) { 10303491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // If we're not in gapless playback (i.e. through setNextPlayer), we 10313491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // need to stop the track here, because that will play out the last 10323491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung // little bit at the end of the file. Otherwise short files won't play. 10333491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mAudioSink->stop(); 10343491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung mNumFramesWritten = 0; 10353491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung } 1036078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return false; 1037c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 1038c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 10399a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia mLastAudioBufferDrained = entry->mBufferOrdinal; 10409a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 104181636761bead03f13b4ed9320a7f25ce1354f1aeChong Zhang // ignore 0-sized buffer which could be EOS marker with no data 104281636761bead03f13b4ed9320a7f25ce1354f1aeChong Zhang if (entry->mOffset == 0 && entry->mBuffer->size() > 0) { 1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1045a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung ALOGV("onDrainAudioQueue: rendering audio at media time %.2f secs", 1046a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mediaTimeUs / 1E6); 1047eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu onNewAudioMediaTime(mediaTimeUs); 1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t copy = entry->mBuffer->size() - entry->mOffset; 1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10527d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, 10537d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia copy, false /* blocking */); 1054a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written < 0) { 1055202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // An error in AudioSink write. Perhaps the AudioSink was not properly opened. 10567d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia if (written == WOULD_BLOCK) { 1057df809479696725faf5d3424b11fa8a07bd94cb5eWei Jia ALOGV("AudioSink write would block when writing %zu bytes", copy); 10587d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia } else { 10597d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy); 10607665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // This can only happen when AudioSink was opened with doNotReconnect flag set to 10617665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // true, in which case the NuPlayer will handle the reconnect. 1062a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia notifyAudioTearDown(kDueToError); 10637d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia } 1064202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung break; 1065a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1067a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung entry->mOffset += written; 106803cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia size_t remainder = entry->mBuffer->size() - entry->mOffset; 106903cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia if ((ssize_t)remainder < mAudioSink->frameSize()) { 107003cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia if (remainder > 0) { 107103cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia ALOGW("Corrupted audio buffer has fractional frames, discarding %zu bytes.", 107203cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia remainder); 107303cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia entry->mOffset += remainder; 107403cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia copy -= remainder; 107503cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia } 107603cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia 1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 10799b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent 1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1083a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung size_t copiedFrames = written / mAudioSink->frameSize(); 1084078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten += copiedFrames; 1085cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 10867b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 10877b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1088d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia int64_t maxTimeMedia; 1089d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia maxTimeMedia = 1090d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia mAnchorTimeMediaUs + 1091d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL) 1092d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia * 1000LL * mAudioSink->msecsPerFrame()); 1093d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia mMediaClock->updateMaxTimeMedia(maxTimeMedia); 1094d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia 10957b15cb33847e6282ea8352c98894683b796127f3Wei Jia notifyIfMediaRenderingStarted_l(); 10967b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 109743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1098a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung if (written != (ssize_t)copy) { 1099a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // A short count was received from AudioSink::write() 1100a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 11017d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // AudioSink write is called in non-blocking mode. 11027d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // It may return with a short count when: 1103a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // 110403cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia // 1) Size to be copied is not a multiple of the frame size. Fractional frames are 110503cee24b8d54e5b5a94957b9fb7049738ff68765Wei Jia // discarded. 11067d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // 2) The data to be copied exceeds the available buffer in AudioSink. 11077d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // 3) An error occurs and data has been partially copied to the buffer in AudioSink. 11087d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded. 1109a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 1110a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // (Case 1) 1111a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Must be a multiple of the frame size. If it is not a multiple of a frame size, it 1112a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // needs to fail, as we should not carry over fractional frames between calls. 1113a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung CHECK_EQ(copy % mAudioSink->frameSize(), 0); 1114a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung 11157d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia // (Case 2, 3, 4) 1116a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Return early to the caller. 1117a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung // Beware of calling immediately again as this may busy-loop if you are not careful. 11187d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia ALOGV("AudioSink write short frame count %zd < %zu", written, copy); 1119a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung break; 1120a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 1121a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung } 1122f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar 1123005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung // calculate whether we need to reschedule another write. 1124005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung bool reschedule = !mAudioQueue.empty() 1125005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung && (!mPaused 1126005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung || prevFramesWritten != mNumFramesWritten); // permit pause to fill buffers 1127005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung //ALOGD("reschedule:%d empty:%d mPaused:%d prevFramesWritten:%u mNumFramesWritten:%u", 1128005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung // reschedule, mAudioQueue.empty(), mPaused, prevFramesWritten, mNumFramesWritten); 1129005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung return reschedule; 1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 11329816016afb2a13c6a866cd047d57020566a8b9a9Wei Jiaint64_t NuPlayer::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) { 11339816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int32_t sampleRate = offloadingAudio() ? 11349816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate; 11354d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia if (sampleRate == 0) { 11364d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload"); 11374d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia return 0; 11384d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia } 11399816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours. 11409816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate); 11419816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia} 11429816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia 11439816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia// Calculate duration of pending samples if played at normal rate (i.e., 1.0). 114406ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnarint64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) { 11459816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten); 1146d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia if (mUseVirtualAudioSink) { 1147d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia int64_t nowUs = ALooper::GetNowUs(); 1148d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia int64_t mediaUs; 1149d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) { 1150d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia return 0ll; 1151d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia } else { 1152d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs); 1153d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia } 1154d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia } 1155c4ac8173f911aeac8d5006b19ba48fb51a865115Wei Jia return writtenAudioDurationUs - mAudioSink->getPlayedOutDurationUs(nowUs); 11565095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu} 11575095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu 1158a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuint64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) { 11599816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t realUs; 11609816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia if (mMediaClock->getRealTimeFor(mediaTimeUs, &realUs) != OK) { 11617b15cb33847e6282ea8352c98894683b796127f3Wei Jia // If failed to get current position, e.g. due to audio clock is 11627b15cb33847e6282ea8352c98894683b796127f3Wei Jia // not ready, then just play out video immediately without delay. 1163eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return nowUs; 1164a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu } 11659816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia return realUs; 1166a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu} 1167a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 1168eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wuvoid NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) { 11697b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1170eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // TRICKY: vorbis decoder generates multiple frames with the same 1171eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu // timestamp, so only update on the first frame with a given timestamp 1172eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (mediaTimeUs == mAnchorTimeMediaUs) { 1173eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu return; 1174eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu } 11757b15cb33847e6282ea8352c98894683b796127f3Wei Jia setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs); 11764ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia 1177528c8403ad2ede53054a706a20c00b710fa08166Andy Hung // mNextAudioClockUpdateTimeUs is -1 if we're waiting for audio sink to start 1178528c8403ad2ede53054a706a20c00b710fa08166Andy Hung if (mNextAudioClockUpdateTimeUs == -1) { 1179528c8403ad2ede53054a706a20c00b710fa08166Andy Hung AudioTimestamp ts; 1180528c8403ad2ede53054a706a20c00b710fa08166Andy Hung if (mAudioSink->getTimestamp(ts) == OK && ts.mPosition > 0) { 1181528c8403ad2ede53054a706a20c00b710fa08166Andy Hung mNextAudioClockUpdateTimeUs = 0; // start our clock updates 1182528c8403ad2ede53054a706a20c00b710fa08166Andy Hung } 1183528c8403ad2ede53054a706a20c00b710fa08166Andy Hung } 118412b6265f1d4be368957f91104d5210cf604ac4ccWei Jia int64_t nowUs = ALooper::GetNowUs(); 1185528c8403ad2ede53054a706a20c00b710fa08166Andy Hung if (mNextAudioClockUpdateTimeUs >= 0) { 1186528c8403ad2ede53054a706a20c00b710fa08166Andy Hung if (nowUs >= mNextAudioClockUpdateTimeUs) { 1187528c8403ad2ede53054a706a20c00b710fa08166Andy Hung int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs); 1188528c8403ad2ede53054a706a20c00b710fa08166Andy Hung mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs); 1189d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia mUseVirtualAudioSink = false; 1190528c8403ad2ede53054a706a20c00b710fa08166Andy Hung mNextAudioClockUpdateTimeUs = nowUs + kMinimumAudioClockUpdatePeriodUs; 1191528c8403ad2ede53054a706a20c00b710fa08166Andy Hung } 119212b6265f1d4be368957f91104d5210cf604ac4ccWei Jia } else { 119312b6265f1d4be368957f91104d5210cf604ac4ccWei Jia int64_t unused; 119412b6265f1d4be368957f91104d5210cf604ac4ccWei Jia if ((mMediaClock->getMediaTime(nowUs, &unused) != OK) 119512b6265f1d4be368957f91104d5210cf604ac4ccWei Jia && (getDurationUsIfPlayedAtSampleRate(mNumFramesWritten) 119612b6265f1d4be368957f91104d5210cf604ac4ccWei Jia > kMaxAllowedAudioSinkDelayUs)) { 119712b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // Enough data has been sent to AudioSink, but AudioSink has not rendered 119812b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // any data yet. Something is wrong with AudioSink, e.g., the device is not 119912b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // connected to audio out. 120012b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // Switch to system clock. This essentially creates a virtual AudioSink with 120112b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // initial latenty of getDurationUsIfPlayedAtSampleRate(mNumFramesWritten). 120212b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // This virtual AudioSink renders audio data starting from the very first sample 120312b6265f1d4be368957f91104d5210cf604ac4ccWei Jia // and it's paced by system clock. 120407af6518b7b7eeb730ded9c5fd6fd6fb3a462bc5Wei Jia ALOGW("AudioSink stuck. ARE YOU CONNECTED TO AUDIO OUT? Switching to system clock."); 120512b6265f1d4be368957f91104d5210cf604ac4ccWei Jia mMediaClock->updateAnchor(mAudioFirstAnchorTimeMediaUs, nowUs, mediaTimeUs); 1206d2f35de429c67a156299f662b0783fbcead13cb6Wei Jia mUseVirtualAudioSink = true; 120712b6265f1d4be368957f91104d5210cf604ac4ccWei Jia } 12084ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia } 12098edb3f85f58e8738582e8f9abbc018c85100b712Wei Jia mAnchorNumFramesWritten = mNumFramesWritten; 12107b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorTimeMediaUs = mediaTimeUs; 1211eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu} 1212eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu 12137b15cb33847e6282ea8352c98894683b796127f3Wei Jia// Called without mLock acquired. 12147b15cb33847e6282ea8352c98894683b796127f3Wei Jiavoid NuPlayer::Renderer::postDrainVideoQueue() { 1215fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (mDrainVideoQueuePending 12167b15cb33847e6282ea8352c98894683b796127f3Wei Jia || getSyncQueues() 1217fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang || (mPaused && mVideoSampleReceived)) { 1218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry &entry = *mVideoQueue.begin(); 1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this); 12287b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("drainGeneration", getDrainGeneration(false /* audio */)); 1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry.mBuffer == NULL) { 1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS doesn't carry a timestamp. 1232dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(); 1233dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mDrainVideoQueuePending = true; 1234dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar return; 1235dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 1236dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 123700541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih bool needRepostDrainVideoQueue = false; 1238dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t delayUs; 1239dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t nowUs = ALooper::GetNowUs(); 1240dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t realTimeUs; 1241dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mFlags & FLAG_REAL_TIME) { 1242d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t mediaTimeUs; 1243d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1244dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mediaTimeUs; 1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12497b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 12507b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 12517b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (mAnchorTimeMediaUs < 0) { 12527b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs); 12537b15cb33847e6282ea8352c98894683b796127f3Wei Jia mAnchorTimeMediaUs = mediaTimeUs; 12547b15cb33847e6282ea8352c98894683b796127f3Wei Jia realTimeUs = nowUs; 125525d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia } else if (!mVideoSampleReceived) { 125625d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia // Always render the first video frame. 125725d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia realTimeUs = nowUs; 125800541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih } else if (mAudioFirstAnchorTimeMediaUs < 0 125900541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih || mMediaClock->getRealTimeFor(mediaTimeUs, &realTimeUs) == OK) { 12607b15cb33847e6282ea8352c98894683b796127f3Wei Jia realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 126100541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih } else if (mediaTimeUs - mAudioFirstAnchorTimeMediaUs >= 0) { 126200541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih needRepostDrainVideoQueue = true; 126300541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih realTimeUs = nowUs; 126400541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih } else { 126500541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih realTimeUs = nowUs; 12667b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1268f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar if (!mHasAudio) { 12697b15cb33847e6282ea8352c98894683b796127f3Wei Jia // smooth out videos >= 10fps 12707b15cb33847e6282ea8352c98894683b796127f3Wei Jia mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000); 1271f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar } 1272d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar 1273d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // Heuristics to handle situation when media time changed without a 1274d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // discontinuity. If we have not drained an audio buffer that was 1275d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // received after this buffer, repost in 10 msec. Otherwise repost 1276d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar // in 500 msec. 1277d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar delayUs = realTimeUs - nowUs; 127800541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih int64_t postDelayUs = -1; 1279d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (delayUs > 500000) { 128000541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih postDelayUs = 500000; 1281d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar if (mHasAudio && (mLastAudioBufferDrained - entry.mBufferOrdinal) <= 0) { 1282d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar postDelayUs = 10000; 1283d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 128400541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih } else if (needRepostDrainVideoQueue) { 128500541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih // CHECK(mPlaybackRate > 0); 128600541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih // CHECK(mAudioFirstAnchorTimeMediaUs >= 0); 128700541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih // CHECK(mediaTimeUs - mAudioFirstAnchorTimeMediaUs >= 0); 128800541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih postDelayUs = mediaTimeUs - mAudioFirstAnchorTimeMediaUs; 128900541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih postDelayUs /= mPlaybackRate; 129000541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih } 129100541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih 129200541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih if (postDelayUs >= 0) { 1293d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->setWhat(kWhatPostDrainVideoQueue); 1294d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar msg->post(postDelayUs); 1295d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mVideoScheduler->restart(); 1296238e1247a1fde2c7857ec243563126de72346a89Wei Jia ALOGI("possible video time jump of %dms (%lld : %lld) or uninitialized media clock," 1297238e1247a1fde2c7857ec243563126de72346a89Wei Jia " retrying in %dms", 1298238e1247a1fde2c7857ec243563126de72346a89Wei Jia (int)(delayUs / 1000), (long long)mediaTimeUs, 1299238e1247a1fde2c7857ec243563126de72346a89Wei Jia (long long)mAudioFirstAnchorTimeMediaUs, (int)(postDelayUs / 1000)); 1300d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar mDrainVideoQueuePending = true; 1301d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar return; 1302d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar } 1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1305dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000; 1306dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000); 1307dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 1308dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar delayUs = realTimeUs - nowUs; 1309dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar 1310095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); 1311dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar // post 2 display refreshes before rendering is due 1312dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0); 1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = true; 1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1317f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainVideoQueue() { 1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mVideoQueue.begin(); 1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1327c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyEOS(false /* audio */, entry->mFinalResult); 1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 13313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 1332a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 133625d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia int64_t nowUs = ALooper::GetNowUs(); 1337d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t realTimeUs; 13382995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia int64_t mediaTimeUs = -1; 1339d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber if (mFlags & FLAG_REAL_TIME) { 1340d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs)); 1341d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } else { 1342d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1343d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber 1344a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); 1345d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } 1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1347fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang bool tooLate = false; 13483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 1349fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 1350a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(nowUs - realTimeUs); 1351fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang tooLate = (mVideoLateByUs > 40000); 1352fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang 1353fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (tooLate) { 1354fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("video late by %lld us (%.2f secs)", 13556d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar (long long)mVideoLateByUs, mVideoLateByUs / 1E6); 1356fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } else { 13579816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia int64_t mediaUs = 0; 13589816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->getMediaTime(realTimeUs, &mediaUs); 1359fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang ALOGV("rendering video at media time %.2f secs", 1360fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang (mFlags & FLAG_REAL_TIME ? realTimeUs : 13619816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mediaUs) / 1E6); 13622995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia 13632995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia if (!(mFlags & FLAG_REAL_TIME) 13642995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia && mLastAudioMediaTimeUs != -1 13652995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia && mediaTimeUs > mLastAudioMediaTimeUs) { 13662995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia // If audio ends before video, video continues to drive media clock. 13672995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia // Also smooth out videos >= 10fps. 13682995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000); 13692995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia } 1370fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 1371078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 1372a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu setVideoLateByUs(0); 1373eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu if (!mVideoSampleReceived && !mHasAudio) { 1374a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // This will ensure that the first frame after a flush won't be used as anchor 1375a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu // when renderer is in paused state, because resume can happen any time after seek. 13769a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia clearAnchorTime(); 137749966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia } 1378078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 138025d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia // Always render the first video frame while keeping stats on A/V sync. 138125d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia if (!mVideoSampleReceived) { 138225d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia realTimeUs = nowUs; 138325d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia tooLate = false; 138425d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia } 138525d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia 1386dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll); 1387683525b61bc1b58b4fd9e1b3ef9ed3b0c3bf34aeGlenn Kasten entry->mNotifyConsumed->setInt32("render", !tooLate); 1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 139143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1392fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = true; 1393f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 1394fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mPaused) { 1395fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang if (!mVideoRenderingStarted) { 1396fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoRenderingStarted = true; 1397fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang notifyVideoRenderingStart(); 1398fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 13997b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 14007b15cb33847e6282ea8352c98894683b796127f3Wei Jia notifyIfMediaRenderingStarted_l(); 1401fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang } 1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1404f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dongvoid NuPlayer::Renderer::notifyVideoRenderingStart() { 1405f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong sp<AMessage> notify = mNotify->dup(); 1406f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->setInt32("what", kWhatVideoRenderingStart); 1407f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->post(); 1408f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong} 1409f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 14105095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wuvoid NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) { 14117c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia if (audio && delayUs > 0) { 14127c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia sp<AMessage> msg = new AMessage(kWhatEOS, this); 14137c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia msg->setInt32("audioEOSGeneration", mAudioEOSGeneration); 14147c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia msg->setInt32("finalResult", finalResult); 14157c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia msg->post(delayUs); 14167c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia return; 14177c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia } 1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatEOS); 1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 1421c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notify->setInt32("finalResult", finalResult); 14225095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu notify->post(delayUs); 1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1425a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jiavoid NuPlayer::Renderer::notifyAudioTearDown(AudioTearDownReason reason) { 1426a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia sp<AMessage> msg = new AMessage(kWhatAudioTearDown, this); 1427a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia msg->setInt32("reason", reason); 1428a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia msg->post(); 14293a2956d148d81194e297408179e84a47a309ef48Wei Jia} 14303a2956d148d81194e297408179e84a47a309ef48Wei Jia 1431f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { 1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14357b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (dropBufferIfStale(audio, msg)) { 14367b15cb33847e6282ea8352c98894683b796127f3Wei Jia return; 14377b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 14387b15cb33847e6282ea8352c98894683b796127f3Wei Jia 14397b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (audio) { 14407b15cb33847e6282ea8352c98894683b796127f3Wei Jia mHasAudio = true; 14417b15cb33847e6282ea8352c98894683b796127f3Wei Jia } else { 14427b15cb33847e6282ea8352c98894683b796127f3Wei Jia mHasVideo = true; 14437b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 1444a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu 1445a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu if (mHasVideo) { 1446dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar if (mVideoScheduler == NULL) { 1447dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler = new VideoFrameScheduler(); 1448dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar mVideoScheduler->init(); 1449dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar } 1450bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 1451bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 14527e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<RefBase> obj; 14537e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim CHECK(msg->findObject("buffer", &obj)); 14547e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); 1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mBuffer = buffer; 1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mNotifyConsumed = notifyConsumed; 1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = OK; 1464d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar entry.mBufferOrdinal = ++mTotalBuffersQueued; 1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 14677b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 1469bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 14727b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14757b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1476cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { 1477cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1478cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14807e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; 14817e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; 1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1483cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { 1484cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // EOS signalled on either queue. 1485bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1486cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1487cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1489cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstAudioTimeUs; 1490cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstVideoTimeUs; 1491cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstAudioBuffer->meta() 1492cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstAudioTimeUs)); 1493cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstVideoBuffer->meta() 1494cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstVideoTimeUs)); 1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1496cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t diff = firstVideoTimeUs - firstAudioTimeUs; 1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("queueDiff = %.2f secs", diff / 1E6); 1499cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1500cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (diff > 100000ll) { 1501cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Audio data starts More than 0.1 secs before video. 1502cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Drop some audio. 1503cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1504cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (*mAudioQueue.begin()).mNotifyConsumed->post(); 1505cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 1506cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 1507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1508cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 1509bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1512bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::syncQueuesDone_l() { 1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mSyncQueues) { 1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSyncQueues = false; 1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mAudioQueue.empty()) { 1520bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mVideoQueue.empty()) { 15247b15cb33847e6282ea8352c98894683b796127f3Wei Jia mLock.unlock(); 15257b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 15267b15cb33847e6282ea8352c98894683b796127f3Wei Jia mLock.lock(); 1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1530f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { 1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 15347b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (dropBufferIfStale(audio, msg)) { 1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t finalResult; 1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = finalResult; 1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 15467b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1547b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson if (mAudioQueue.empty() && mSyncQueues) { 1548bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1549b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 1551bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia postDrainAudioQueue_l(); 1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 15537b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (mVideoQueue.empty() && getSyncQueues()) { 15547b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 1555bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia syncQueuesDone_l(); 1556b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson } 1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 15587b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1562f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { 15637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t audio, notifyComplete; 1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 156628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 15677b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 156828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia if (audio) { 15697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteAudio; 15707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteAudio = false; 15712995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia mLastAudioMediaTimeUs = -1; 157228a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } else { 15737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyComplete = mNotifyCompleteVideo; 15747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNotifyCompleteVideo = false; 157528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 157628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 15777b15cb33847e6282ea8352c98894683b796127f3Wei Jia // If we're currently syncing the queues, i.e. dropping audio while 15787b15cb33847e6282ea8352c98894683b796127f3Wei Jia // aligning the first audio/video buffer times and only one of the 15797b15cb33847e6282ea8352c98894683b796127f3Wei Jia // two queues has data, we may starve that queue by not requesting 15807b15cb33847e6282ea8352c98894683b796127f3Wei Jia // more buffers from the decoder. If the other source then encounters 15817b15cb33847e6282ea8352c98894683b796127f3Wei Jia // a discontinuity that leads to flushing, we'll never find the 15827b15cb33847e6282ea8352c98894683b796127f3Wei Jia // corresponding discontinuity on the other queue. 15837b15cb33847e6282ea8352c98894683b796127f3Wei Jia // Therefore we'll stop syncing the queues if at least one of them 15847b15cb33847e6282ea8352c98894683b796127f3Wei Jia // is flushed. 15857b15cb33847e6282ea8352c98894683b796127f3Wei Jia syncQueuesDone_l(); 1586bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 15879a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia clearAnchorTime(); 1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1589cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar ALOGV("flushing %s", audio ? "audio" : "video"); 1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 1591bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 1592bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1593bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia flushQueue(&mAudioQueue); 1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 15957b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 15967c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia ++mAudioEOSGeneration; 15977b15cb33847e6282ea8352c98894683b796127f3Wei Jia prepareForMediaRenderingStart_l(); 159828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia 1599a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // the frame count will be reset after flush. 1600a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung clearAudioFirstAnchorTime_l(); 160128a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 1604cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1605bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1606bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->pause(); 1607bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mAudioSink->flush(); 160885e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung if (!mPaused) { 160985e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung mAudioSink->start(); 161085e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung } 16119e7ed3315298b42db485963b182a572e9ab42f9fWei Jia } else { 16129e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->pause(); 16139e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->flush(); 16149e7ed3315298b42db485963b182a572e9ab42f9fWei Jia // Call stop() to signal to the AudioSink to completely fill the 16159e7ed3315298b42db485963b182a572e9ab42f9fWei Jia // internal buffer before resuming playback. 1616b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // FIXME: this is ignored after flush(). 16179e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->stop(); 1618b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung if (mPaused) { 1619b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // Race condition: if renderer is paused and audio sink is stopped, 1620b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // we need to make sure that the audio track buffer fully drains 1621b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // before delivering data. 1622b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung // FIXME: remove this if we can detect if stop() is complete. 1623b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms) 1624b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs; 1625b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung } else { 16269e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mAudioSink->start(); 16279e7ed3315298b42db485963b182a572e9ab42f9fWei Jia } 16289e7ed3315298b42db485963b182a572e9ab42f9fWei Jia mNumFramesWritten = 0; 1629bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 1630528c8403ad2ede53054a706a20c00b710fa08166Andy Hung mNextAudioClockUpdateTimeUs = -1; 1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushQueue(&mVideoQueue); 1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 1635cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 1636c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler != NULL) { 1637c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->restart(); 1638c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1639c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 16407b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 16417b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoDrainGeneration; 16427b15cb33847e6282ea8352c98894683b796127f3Wei Jia prepareForMediaRenderingStart_l(); 1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1645fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang mVideoSampleReceived = false; 16467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 16477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 16487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notifyFlushComplete(audio); 16497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1652f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) { 1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (!queue->empty()) { 1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*queue->begin(); 1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer != NULL) { 1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 16589a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } else if (entry->mNotifyConsumed != nullptr) { 16599a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia // Is it needed to open audio sink now? 16609a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed); 1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber queue->erase(queue->begin()); 1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1668f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyFlushComplete(bool audio) { 1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatFlushComplete); 1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 16757b15cb33847e6282ea8352c98894683b796127f3Wei Jiabool NuPlayer::Renderer::dropBufferIfStale( 1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, const sp<AMessage> &msg) { 16777b15cb33847e6282ea8352c98894683b796127f3Wei Jia int32_t queueGeneration; 16787b15cb33847e6282ea8352c98894683b796127f3Wei Jia CHECK(msg->findInt32("queueGeneration", &queueGeneration)); 1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 16807b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (queueGeneration == getQueueGeneration(audio)) { 1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg->findMessage("notifyConsumed", ¬ifyConsumed)) { 1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyConsumed->post(); 1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 16923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::onAudioSinkChanged() { 1693bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (offloadingAudio()) { 1694bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return; 1695bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 16963831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK(!mDrainAudioQueuePending); 16973831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mNumFramesWritten = 0; 16989a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia mAnchorNumFramesWritten = -1; 16994110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen uint32_t written; 17004110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen if (mAudioSink->getFramesWritten(&written) == OK) { 17014110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen mNumFramesWritten = written; 17024110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen } 17033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 17043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 1705bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::Renderer::onDisableOffloadAudio() { 1706bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia Mutex::Autolock autoLock(mLock); 1707bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mFlags &= ~FLAG_OFFLOAD_AUDIO; 17087b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 1709e1d701902765c710398133025cfeee3ea8b6d280Robert Shih if (mAudioRenderingStartGeneration != -1) { 1710e1d701902765c710398133025cfeee3ea8b6d280Robert Shih prepareForMediaRenderingStart_l(); 1711e1d701902765c710398133025cfeee3ea8b6d280Robert Shih } 1712bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 1713bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 1714a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wuvoid NuPlayer::Renderer::onEnableOffloadAudio() { 1715a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu Mutex::Autolock autoLock(mLock); 1716a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu mFlags |= FLAG_OFFLOAD_AUDIO; 17177b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mAudioDrainGeneration; 1718e1d701902765c710398133025cfeee3ea8b6d280Robert Shih if (mAudioRenderingStartGeneration != -1) { 1719e1d701902765c710398133025cfeee3ea8b6d280Robert Shih prepareForMediaRenderingStart_l(); 1720e1d701902765c710398133025cfeee3ea8b6d280Robert Shih } 1721a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu} 1722a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu 1723b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onPause() { 17248592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad if (mPaused) { 17258592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad return; 17268592dbbdf5339890db2b14f83bcd6da2ffb023d2Rachad } 17276d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar 172828a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia { 172928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia Mutex::Autolock autoLock(mLock); 1730005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung // we do not increment audio drain generation so that we fill audio buffer during pause. 17317b15cb33847e6282ea8352c98894683b796127f3Wei Jia ++mVideoDrainGeneration; 17327b15cb33847e6282ea8352c98894683b796127f3Wei Jia prepareForMediaRenderingStart_l(); 173373ddd210ea572375198cac1d4960df793745fb4bWei Jia mPaused = true; 17349816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->setPlaybackRate(0.0); 173528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 1736b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 173728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia mDrainAudioQueuePending = false; 1738b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mDrainVideoQueuePending = false; 1739cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar 17408420073fda0f6f6c68c952e030b0dbc184112e42Andy Hung // Note: audio data may not have been decoded, and the AudioSink may not be opened. 17418420073fda0f6f6c68c952e030b0dbc184112e42Andy Hung mAudioSink->pause(); 17428420073fda0f6f6c68c952e030b0dbc184112e42Andy Hung startAudioOffloadPauseTimeout(); 1743b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 17446d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar ALOGV("now paused audio queue has %zu entries, video has %zu entries", 1745ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber mAudioQueue.size(), mVideoQueue.size()); 1746b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1747b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1748b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onResume() { 1749b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (!mPaused) { 1750b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber return; 1751b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 1752b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 17538420073fda0f6f6c68c952e030b0dbc184112e42Andy Hung // Note: audio data may not have been decoded, and the AudioSink may not be opened. 17548420073fda0f6f6c68c952e030b0dbc184112e42Andy Hung cancelAudioOffloadPauseTimeout(); 17558420073fda0f6f6c68c952e030b0dbc184112e42Andy Hung if (mAudioSink->ready()) { 175697c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent status_t err = mAudioSink->start(); 175797c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent if (err != OK) { 175858d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung ALOGE("cannot start AudioSink err %d", err); 1759a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia notifyAudioTearDown(kDueToError); 176097c9f4fd7bc31e2968d816402659ba1c64f10b42Eric Laurent } 1761b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1762b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 17637b15cb33847e6282ea8352c98894683b796127f3Wei Jia { 17647b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 17657b15cb33847e6282ea8352c98894683b796127f3Wei Jia mPaused = false; 1766b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung // rendering started message may have been delayed if we were paused. 1767b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung if (mRenderingDataDelivered) { 1768b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung notifyIfMediaRenderingStarted_l(); 1769b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung } 17703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // configure audiosink as we did not do it when pausing 177127ea08e3811dc8057685258af52a7d40474eba16Wei Jia if (mAudioSink != NULL && mAudioSink->ready()) { 17723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mAudioSink->setPlaybackRate(mPlaybackSettings); 17733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 17743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 17759816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia mMediaClock->setPlaybackRate(mPlaybackRate); 1776b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 17777b15cb33847e6282ea8352c98894683b796127f3Wei Jia if (!mAudioQueue.empty()) { 17787b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainAudioQueue_l(); 17797b15cb33847e6282ea8352c98894683b796127f3Wei Jia } 1780b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1781b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1782b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mVideoQueue.empty()) { 17837b15cb33847e6282ea8352c98894683b796127f3Wei Jia postDrainVideoQueue(); 1784b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 1785b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 1786b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 1787c851b5de495169d7e9528644c2592746021bd968Lajos Molnarvoid NuPlayer::Renderer::onSetVideoFrameRate(float fps) { 1788c851b5de495169d7e9528644c2592746021bd968Lajos Molnar if (mVideoScheduler == NULL) { 1789c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler = new VideoFrameScheduler(); 1790c851b5de495169d7e9528644c2592746021bd968Lajos Molnar } 1791c851b5de495169d7e9528644c2592746021bd968Lajos Molnar mVideoScheduler->init(fps); 1792c851b5de495169d7e9528644c2592746021bd968Lajos Molnar} 1793c851b5de495169d7e9528644c2592746021bd968Lajos Molnar 17947b15cb33847e6282ea8352c98894683b796127f3Wei Jiaint32_t NuPlayer::Renderer::getQueueGeneration(bool audio) { 17957b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 17967b15cb33847e6282ea8352c98894683b796127f3Wei Jia return (audio ? mAudioQueueGeneration : mVideoQueueGeneration); 17977b15cb33847e6282ea8352c98894683b796127f3Wei Jia} 17987b15cb33847e6282ea8352c98894683b796127f3Wei Jia 17997b15cb33847e6282ea8352c98894683b796127f3Wei Jiaint32_t NuPlayer::Renderer::getDrainGeneration(bool audio) { 18007b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 18017b15cb33847e6282ea8352c98894683b796127f3Wei Jia return (audio ? mAudioDrainGeneration : mVideoDrainGeneration); 18027b15cb33847e6282ea8352c98894683b796127f3Wei Jia} 18037b15cb33847e6282ea8352c98894683b796127f3Wei Jia 18047b15cb33847e6282ea8352c98894683b796127f3Wei Jiabool NuPlayer::Renderer::getSyncQueues() { 18057b15cb33847e6282ea8352c98894683b796127f3Wei Jia Mutex::Autolock autoLock(mLock); 18067b15cb33847e6282ea8352c98894683b796127f3Wei Jia return mSyncQueues; 18077b15cb33847e6282ea8352c98894683b796127f3Wei Jia} 18087b15cb33847e6282ea8352c98894683b796127f3Wei Jia 1809faeb0f291330134dc4468359a36e099aae508449Ronghua Wuvoid NuPlayer::Renderer::onAudioTearDown(AudioTearDownReason reason) { 1810faeb0f291330134dc4468359a36e099aae508449Ronghua Wu if (mAudioTornDown) { 1811f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu return; 1812f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1813faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mAudioTornDown = true; 1814f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1815a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu int64_t currentPositionUs; 18161a5c859016e743779e4db25855390b3ce523cd48Robert Shih sp<AMessage> notify = mNotify->dup(); 18171a5c859016e743779e4db25855390b3ce523cd48Robert Shih if (getCurrentPosition(¤tPositionUs) == OK) { 18181a5c859016e743779e4db25855390b3ce523cd48Robert Shih notify->setInt64("positionUs", currentPositionUs); 181928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia } 182006ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar 18213a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->stop(); 18223a2956d148d81194e297408179e84a47a309ef48Wei Jia mAudioSink->flush(); 18233a2956d148d81194e297408179e84a47a309ef48Wei Jia 1824faeb0f291330134dc4468359a36e099aae508449Ronghua Wu notify->setInt32("what", kWhatAudioTearDown); 18250852917279f79a94907e9906d0533ae409a30f6aRonghua Wu notify->setInt32("reason", reason); 18263a2956d148d81194e297408179e84a47a309ef48Wei Jia notify->post(); 18273a2956d148d81194e297408179e84a47a309ef48Wei Jia} 18283a2956d148d81194e297408179e84a47a309ef48Wei Jia 1829f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::startAudioOffloadPauseTimeout() { 1830f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu if (offloadingAudio()) { 183135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang mWakeLock->acquire(); 18321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, this); 18337b15cb33847e6282ea8352c98894683b796127f3Wei Jia msg->setInt32("drainGeneration", mAudioOffloadPauseTimeoutGeneration); 1834f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu msg->post(kOffloadPauseMaxUs); 1835f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu } 1836f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1837f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1838f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wuvoid NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() { 183921afe805580c1fdf394415648fba8e1c482def60Andy Hung // We may have called startAudioOffloadPauseTimeout() without 184021afe805580c1fdf394415648fba8e1c482def60Andy Hung // the AudioSink open and with offloadingAudio enabled. 184121afe805580c1fdf394415648fba8e1c482def60Andy Hung // 184221afe805580c1fdf394415648fba8e1c482def60Andy Hung // When we cancel, it may be that offloadingAudio is subsequently disabled, so regardless 184321afe805580c1fdf394415648fba8e1c482def60Andy Hung // we always release the wakelock and increment the pause timeout generation. 184421afe805580c1fdf394415648fba8e1c482def60Andy Hung // 184521afe805580c1fdf394415648fba8e1c482def60Andy Hung // Note: The acquired wakelock prevents the device from suspending 184621afe805580c1fdf394415648fba8e1c482def60Andy Hung // immediately after offload pause (in case a resume happens shortly thereafter). 184721afe805580c1fdf394415648fba8e1c482def60Andy Hung mWakeLock->release(true); 184821afe805580c1fdf394415648fba8e1c482def60Andy Hung ++mAudioOffloadPauseTimeoutGeneration; 1849f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu} 1850f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu 1851202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungstatus_t NuPlayer::Renderer::onOpenAudioSink( 18523b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang const sp<AMessage> &format, 18533b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool offloadOnly, 18543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool hasVideo, 1855c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar uint32_t flags, 1856c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar bool isStreaming) { 18573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)", 18583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadOnly, offloadingAudio()); 18593b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang bool audioSinkChanged = false; 18603b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18613b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t numChannels; 18623b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("channel-count", &numChannels)); 18633b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18643b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t channelMask; 18653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!format->findInt32("channel-mask", &channelMask)) { 18663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // signal to the AudioSink to derive the mask from count. 18673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 18683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 18693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18703b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t sampleRate; 18713b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findInt32("sample-rate", &sampleRate)); 18723b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18733b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (offloadingAudio()) { 18743b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; 18753b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AString mime; 18763b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang CHECK(format->findString("mime", &mime)); 18773b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str()); 18783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 18803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGE("Couldn't map mime \"%s\" to a valid " 18813b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "audio_format", mime.c_str()); 18823b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 18833b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } else { 18843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("Mime \"%s\" mapped to audio_format 0x%x", 18853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mime.c_str(), audioFormat); 18863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int avgBitRate = -1; 188846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar format->findInt32("bitrate", &avgBitRate); 18893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang int32_t aacProfile = -1; 18913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioFormat == AUDIO_FORMAT_AAC 18923b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang && format->findInt32("aac-profile", &aacProfile)) { 18933b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Redefine AAC format as per aac profile 18943b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mapAACProfileToAudioFormat( 18953b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 18963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang aacProfile); 18973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 18983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 18993b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 19003b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.duration_us = -1; 19013b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang format->findInt64( 19023b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang "durationUs", &offloadInfo.duration_us); 19033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.sample_rate = sampleRate; 19043b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.channel_mask = channelMask; 19053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.format = audioFormat; 19063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.stream_type = AUDIO_STREAM_MUSIC; 19073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.bit_rate = avgBitRate; 19083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang offloadInfo.has_video = hasVideo; 1909c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar offloadInfo.is_streaming = isStreaming; 19103b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 19113b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) { 19123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: no change in offload mode"); 19133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // no change from previous configuration, everything ok. 1914202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 19153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 1916f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 1917f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 19183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: try to open AudioSink in offload mode"); 1919d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t offloadFlags = flags; 1920d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1921d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 19223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 19233b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 1924a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung 19253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang err = mAudioSink->open( 19263b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 19273b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 19283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 19293b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioFormat, 1930179652ee2a508361df1aa18e99000373886f0816Andy Hung 0 /* bufferCount - unused */, 19313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &NuPlayer::Renderer::AudioSinkCallback, 19323b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang this, 1933d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent (audio_output_flags_t)offloadFlags, 19343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang &offloadInfo); 19353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 19363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err == OK) { 19373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar err = mAudioSink->setPlaybackRate(mPlaybackSettings); 19383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 19393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 19403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 19413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // If the playback is offloaded to h/w, we pass 19423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // the HAL some metadata information. 19433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // We don't want to do this for PCM because it 19443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // will be going through the AudioFlinger mixer 19453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // before reaching the hardware. 19463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // TODO 19473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = offloadInfo; 194885e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung if (!mPaused) { // for preview mode, don't start if paused 194985e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung err = mAudioSink->start(); 195085e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung } 19513b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV_IF(err == OK, "openAudioSink: offload succeeded"); 19523b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 19533b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (err != OK) { 19543b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang // Clean up, fall back to non offload mode. 19553b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 19563b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onDisableOffloadAudio(); 19573b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 19583b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: offload failed"); 1959a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia if (offloadOnly) { 1960a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia notifyAudioTearDown(kForceNonOffload); 1961a05f1e3a8eb80a0a9f19456aea357d6d8e405794Wei Jia } 19623ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia } else { 19633ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia mUseAudioCallback = true; // offload mode transfers data through callback 19643ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia ++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message. 19653b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 19663b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 19673b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 19683b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (!offloadOnly && !offloadingAudio()) { 19693b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang ALOGV("openAudioSink: open AudioSink in NON-offload mode"); 1970d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent uint32_t pcmFlags = flags; 1971d88c3cafb439367f2a245b625e0a74bcd785f099Eric Laurent pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 1972f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 1973f0e83644637bd05852c244df481f21a0d435ff66Andy Hung const PcmInfo info = { 1974f0e83644637bd05852c244df481f21a0d435ff66Andy Hung (audio_channel_mask_t)channelMask, 1975f0e83644637bd05852c244df481f21a0d435ff66Andy Hung (audio_output_flags_t)pcmFlags, 1976f0e83644637bd05852c244df481f21a0d435ff66Andy Hung AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat 1977f0e83644637bd05852c244df481f21a0d435ff66Andy Hung numChannels, 1978f0e83644637bd05852c244df481f21a0d435ff66Andy Hung sampleRate 1979f0e83644637bd05852c244df481f21a0d435ff66Andy Hung }; 1980f0e83644637bd05852c244df481f21a0d435ff66Andy Hung if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) { 1981f0e83644637bd05852c244df481f21a0d435ff66Andy Hung ALOGV("openAudioSink: no change in pcm mode"); 1982f0e83644637bd05852c244df481f21a0d435ff66Andy Hung // no change from previous configuration, everything ok. 1983f0e83644637bd05852c244df481f21a0d435ff66Andy Hung return OK; 1984f0e83644637bd05852c244df481f21a0d435ff66Andy Hung } 1985f0e83644637bd05852c244df481f21a0d435ff66Andy Hung 19863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang audioSinkChanged = true; 19873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 19883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 1989a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // Note: It is possible to set up the callback, but not use it to send audio data. 1990a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung // This requires a fix in AudioSink to explicitly specify the transfer mode. 1991a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback = getUseAudioCallbackSetting(); 19923ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia if (mUseAudioCallback) { 19933ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia ++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message. 19943ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia } 1995179652ee2a508361df1aa18e99000373886f0816Andy Hung 1996179652ee2a508361df1aa18e99000373886f0816Andy Hung // Compute the desired buffer size. 1997179652ee2a508361df1aa18e99000373886f0816Andy Hung // For callback mode, the amount of time before wakeup is about half the buffer size. 1998179652ee2a508361df1aa18e99000373886f0816Andy Hung const uint32_t frameCount = 1999179652ee2a508361df1aa18e99000373886f0816Andy Hung (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000; 2000179652ee2a508361df1aa18e99000373886f0816Andy Hung 20017665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // The doNotReconnect means AudioSink will signal back and let NuPlayer to re-construct 20027665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // AudioSink. We don't want this when there's video because it will cause a video seek to 20037665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // the previous I frame. But we do want this when there's only audio because it will give 20047665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // NuPlayer a chance to switch from non-offload mode to offload mode. 20057665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu // So we only set doNotReconnect when there's no video. 20067665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu const bool doNotReconnect = !hasVideo; 2007ff874dc957f9ea70d87f4d627bf903e1fc86d58bAndy Hung 2008ff874dc957f9ea70d87f4d627bf903e1fc86d58bAndy Hung // We should always be able to set our playback settings if the sink is closed. 2009ff874dc957f9ea70d87f4d627bf903e1fc86d58bAndy Hung LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK, 2010ff874dc957f9ea70d87f4d627bf903e1fc86d58bAndy Hung "onOpenAudioSink: can't set playback rate on closed sink"); 2011202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = mAudioSink->open( 20123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang sampleRate, 20133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang numChannels, 20143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang (audio_channel_mask_t)channelMask, 20153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang AUDIO_FORMAT_PCM_16_BIT, 2016179652ee2a508361df1aa18e99000373886f0816Andy Hung 0 /* bufferCount - unused */, 2017a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback ? &NuPlayer::Renderer::AudioSinkCallback : NULL, 2018a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung mUseAudioCallback ? this : NULL, 2019faeb0f291330134dc4468359a36e099aae508449Ronghua Wu (audio_output_flags_t)pcmFlags, 2020faeb0f291330134dc4468359a36e099aae508449Ronghua Wu NULL, 20217665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu doNotReconnect, 2022179652ee2a508361df1aa18e99000373886f0816Andy Hung frameCount); 2023202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (err != OK) { 2024202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGW("openAudioSink: non offloaded open failed status: %d", err); 20254d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia mAudioSink->close(); 2026f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 2027202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return err; 2028202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 2029f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = info; 2030005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung if (!mPaused) { // for preview mode, don't start if paused 2031005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung mAudioSink->start(); 2032005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung } 20333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 20343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang if (audioSinkChanged) { 20353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang onAudioSinkChanged(); 20363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang } 2037faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mAudioTornDown = false; 2038202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return OK; 20393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 20403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 20413b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangvoid NuPlayer::Renderer::onCloseAudioSink() { 20423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mAudioSink->close(); 20433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; 2044f0e83644637bd05852c244df481f21a0d435ff66Andy Hung mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; 20453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang} 20463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang 20479a3101b22b5115717faeac986b43fc6618fd3b30Wei Jiavoid NuPlayer::Renderer::onChangeAudioFormat( 20489a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia const sp<AMessage> &meta, const sp<AMessage> ¬ify) { 20499a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia sp<AMessage> format; 20509a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(meta->findMessage("format", &format)); 20519a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 20529a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia int32_t offloadOnly; 20539a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(meta->findInt32("offload-only", &offloadOnly)); 20549a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 20559a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia int32_t hasVideo; 20569a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(meta->findInt32("has-video", &hasVideo)); 20579a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 20589a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia uint32_t flags; 20599a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia CHECK(meta->findInt32("flags", (int32_t *)&flags)); 20609a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 2061c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar uint32_t isStreaming; 2062c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar CHECK(meta->findInt32("isStreaming", (int32_t *)&isStreaming)); 2063c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar 2064c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming); 20659a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 20669a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (err != OK) { 20679a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia notify->setInt32("err", err); 20689a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 20699a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia notify->post(); 20709a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia} 20719a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2074