NuPlayerRenderer.cpp revision f57b4ea3e409537b1d5f9aaea93d356b1cebbc6a
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayerRenderer" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerRenderer.h" 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 255bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 27f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber// static 30714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huberconst int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; 31714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 32f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::Renderer( 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MediaPlayerBase::AudioSink> &sink, 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> ¬ify) 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mAudioSink(sink), 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNotify(notify), 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumFramesWritten(0), 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending(false), 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending(false), 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueueGeneration(0), 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueueGeneration(0), 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeMediaUs(-1), 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeRealUs(-1), 44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio(false), 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingVideo(false), 46bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasAudio(false), 47bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasVideo(false), 48bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mSyncQueues(false), 49714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber mPaused(false), 50f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong mVideoRenderingStarted(false), 513fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mLastPositionUpdateUs(-1ll), 523fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoLateByUs(0ll) { 53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::~Renderer() { 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 58f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueBuffer( 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<ABuffer> &buffer, 61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<AMessage> ¬ifyConsumed) { 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatQueueBuffer, id()); 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 642d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("buffer", buffer); 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setMessage("notifyConsumed", notifyConsumed); 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 69f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) { 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(finalResult, (status_t)OK); 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatQueueEOS, id()); 73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("finalResult", finalResult); 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 78f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flush(bool audio) { 79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!mFlushingAudio); 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio = true; 84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!mFlushingVideo); 86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingVideo = true; 87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatFlush, id()); 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("audio", static_cast<int32_t>(audio)); 92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 95f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::signalTimeDiscontinuity() { 96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mAudioQueue.empty()); 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mVideoQueue.empty()); 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeMediaUs = -1; 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeRealUs = -1; 1003831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mSyncQueues = mHasAudio && mHasVideo; 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 103b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::pause() { 104b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatPause, id()))->post(); 105b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 106b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 107b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::resume() { 108b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatResume, id()))->post(); 109b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 110b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 111f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainAudioQueue: 114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("generation", &generation)); 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (generation != mAudioQueueGeneration) { 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 123078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (onDrainAudioQueue()) { 124078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 125078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), 126078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (status_t)OK); 127078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 128078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPendingPlayout = 129078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten - numFramesPlayed; 130078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 131078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // This is how long the audio sink will have data to 132078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // play back. 133078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int64_t delayUs = 134078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->msecsPerFrame() 135078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber * numFramesPendingPlayout * 1000ll; 136078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 137078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // Let's give it more data after about half that time 138078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // has elapsed. 139078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber postDrainAudioQueue(delayUs / 2); 140078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatDrainVideoQueue: 145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t generation; 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("generation", &generation)); 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (generation != mVideoQueueGeneration) { 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainVideoQueue(); 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueBuffer: 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueBuffer(msg); 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatQueueEOS: 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onQueueEOS(msg); 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatFlush: 173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFlush(msg); 175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1783831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber case kWhatAudioSinkChanged: 1793831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber { 1803831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber onAudioSinkChanged(); 1813831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber break; 1823831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 1833831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 184b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatPause: 185b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 186b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onPause(); 187b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 188b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 189b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 190b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatResume: 191b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 192b408222bd9479c291874b607acae1425d6154fe7Andreas Huber onResume(); 193b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 194b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 195b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 202078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Hubervoid NuPlayer::Renderer::postDrainAudioQueue(int64_t delayUs) { 203b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mDrainAudioQueuePending || mSyncQueues || mPaused) { 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioQueue.empty()) { 208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = true; 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id()); 213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("generation", mAudioQueueGeneration); 214078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber msg->post(delayUs); 215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::signalAudioSinkChanged() { 2183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber (new AMessage(kWhatAudioSinkChanged, id()))->post(); 2193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 2203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 221078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huberbool NuPlayer::Renderer::onDrainAudioQueue() { 222078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t numFramesPlayed; 2232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mAudioSink->getPosition(&numFramesPlayed) != OK) { 2242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return false; 2252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 226078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 227078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber ssize_t numFramesAvailableToWrite = 228078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); 229078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 230078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#if 0 231078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (numFramesAvailableToWrite == mAudioSink->frameCount()) { 232df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("audio sink underrun"); 233078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 2343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("audio queue has %d frames left to play", 235078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mAudioSink->frameCount() - numFramesAvailableToWrite); 236078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 237078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber#endif 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 239078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber size_t numBytesAvailableToWrite = 240078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber numFramesAvailableToWrite * mAudioSink->frameSize(); 241078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 242078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) { 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mAudioQueue.begin(); 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 248c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyEOS(true /* audio */, entry->mFinalResult); 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 252078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return false; 253c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 254c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == 0) { 256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6); 260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeMediaUs = mediaTimeUs; 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t numFramesPlayed; 264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t numFramesPendingPlayout = 267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumFramesWritten - numFramesPlayed; 268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t realTimeOffsetUs = 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (mAudioSink->latency() / 2 /* XXX */ 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber + numFramesPendingPlayout 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * mAudioSink->msecsPerFrame()) * 1000ll; 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 274df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block // ALOGI("realTimeOffsetUs = %lld us", realTimeOffsetUs); 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeRealUs = 277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALooper::GetNowUs() + realTimeOffsetUs; 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t copy = entry->mBuffer->size() - entry->mOffset; 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (copy > numBytesAvailableToWrite) { 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber copy = numBytesAvailableToWrite; 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mAudioSink->write( 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mBuffer->data() + entry->mOffset, copy), 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (ssize_t)copy); 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mOffset += copy; 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mOffset == entry->mBuffer->size()) { 291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 2939b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent 294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 297078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber numBytesAvailableToWrite -= copy; 298078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber size_t copiedFrames = copy / mAudioSink->frameSize(); 299078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mNumFramesWritten += copiedFrames; 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 30143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 30243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber notifyPosition(); 303078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 304078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return !mAudioQueue.empty(); 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 307f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::postDrainVideoQueue() { 308b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mDrainVideoQueuePending || mSyncQueues || mPaused) { 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry &entry = *mVideoQueue.begin(); 317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, id()); 319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("generation", mVideoQueueGeneration); 320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t delayUs; 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry.mBuffer == NULL) { 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS doesn't carry a timestamp. 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber delayUs = 0; 326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAnchorTimeMediaUs < 0) { 331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber delayUs = 0; 332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3333831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (!mHasAudio) { 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeMediaUs = mediaTimeUs; 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAnchorTimeRealUs = ALooper::GetNowUs(); 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t realTimeUs = 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (mediaTimeUs - mAnchorTimeMediaUs) + mAnchorTimeRealUs; 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber delayUs = realTimeUs - ALooper::GetNowUs(); 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(delayUs); 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = true; 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 350f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainVideoQueue() { 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoQueue.empty()) { 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*mVideoQueue.begin(); 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer == NULL) { 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // EOS 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 360c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyEOS(false /* audio */, entry->mFinalResult); 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 3643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3653fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoLateByUs = 0ll; 3663fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3673fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber notifyPosition(); 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); 373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 374078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs; 3753fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoLateByUs = ALooper::GetNowUs() - realTimeUs; 376078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 3773fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber bool tooLate = (mVideoLateByUs > 40000); 3783fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3793fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (tooLate) { 380afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber ALOGV("video late by %lld us (%.2f secs)", 381afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber mVideoLateByUs, mVideoLateByUs / 1E6); 382078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } else { 3833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6); 384078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 386683525b61bc1b58b4fd9e1b3ef9ed3b0c3bf34aeGlenn Kasten entry->mNotifyConsumed->setInt32("render", !tooLate); 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.erase(mVideoQueue.begin()); 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 39043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 391f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong if (!mVideoRenderingStarted) { 392f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong mVideoRenderingStarted = true; 393f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notifyVideoRenderingStart(); 394f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong } 395f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 39643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber notifyPosition(); 397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 399f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dongvoid NuPlayer::Renderer::notifyVideoRenderingStart() { 400f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong sp<AMessage> notify = mNotify->dup(); 401f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->setInt32("what", kWhatVideoRenderingStart); 402f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong notify->post(); 403f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong} 404f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong 405c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Hubervoid NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult) { 406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatEOS); 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 409c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notify->setInt32("finalResult", finalResult); 410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 413f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { 414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 417bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber if (audio) { 418bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasAudio = true; 419bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } else { 420bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mHasVideo = true; 421bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 422bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (dropBufferWhileFlushing(audio, msg)) { 424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4272d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 4282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); 432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mBuffer = buffer; 435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mNotifyConsumed = notifyConsumed; 436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = OK; 438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainAudioQueue(); 442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 447cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { 448cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 449cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 451cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; 452cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 454cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { 455cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // EOS signalled on either queue. 456cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber syncQueuesDone(); 457cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 458cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 460cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstAudioTimeUs; 461cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t firstVideoTimeUs; 462cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstAudioBuffer->meta() 463cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstAudioTimeUs)); 464cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber CHECK(firstVideoBuffer->meta() 465cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber ->findInt64("timeUs", &firstVideoTimeUs)); 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 467cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int64_t diff = firstVideoTimeUs - firstAudioTimeUs; 468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("queueDiff = %.2f secs", diff / 1E6); 470cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 471cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber if (diff > 100000ll) { 472cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Audio data starts More than 0.1 secs before video. 473cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Drop some audio. 474cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 475cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (*mAudioQueue.begin()).mNotifyConsumed->post(); 476cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber mAudioQueue.erase(mAudioQueue.begin()); 477cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber return; 478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 479cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber 480cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber syncQueuesDone(); 481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 483f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::syncQueuesDone() { 484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mSyncQueues) { 485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSyncQueues = false; 489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mAudioQueue.empty()) { 491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainAudioQueue(); 492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!mVideoQueue.empty()) { 495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 499f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { 500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (dropBufferWhileFlushing(audio, msg)) { 504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t finalResult; 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry entry; 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mOffset = 0; 512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry.mFinalResult = finalResult; 513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioQueue.push_back(entry); 516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainAudioQueue(); 517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoQueue.push_back(entry); 519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber postDrainVideoQueue(); 520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 523f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { 524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If we're currently syncing the queues, i.e. dropping audio while 528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // aligning the first audio/video buffer times and only one of the 529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // two queues has data, we may starve that queue by not requesting 530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // more buffers from the decoder. If the other source then encounters 531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // a discontinuity that leads to flushing, we'll never find the 532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // corresponding discontinuity on the other queue. 533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Therefore we'll stop syncing the queues if at least one of them 534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // is flushed. 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber syncQueuesDone(); 536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushQueue(&mAudioQueue); 539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio = false; 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainAudioQueuePending = false; 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++mAudioQueueGeneration; 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushQueue(&mVideoQueue); 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingVideo = false; 550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDrainVideoQueuePending = false; 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++mVideoQueueGeneration; 553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyFlushComplete(audio); 556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 558f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) { 559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (!queue->empty()) { 560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber QueueEntry *entry = &*queue->begin(); 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (entry->mBuffer != NULL) { 563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry->mNotifyConsumed->post(); 564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber queue->erase(queue->begin()); 567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber entry = NULL; 568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 571f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyFlushComplete(bool audio) { 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("what", kWhatFlushComplete); 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setInt32("audio", static_cast<int32_t>(audio)); 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 578f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::Renderer::dropBufferWhileFlushing( 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio, const sp<AMessage> &msg) { 580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool flushing = false; 581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(mFlushLock); 584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushing = mFlushingAudio; 586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flushing = mFlushingVideo; 588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!flushing) { 592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyConsumed; 596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg->findMessage("notifyConsumed", ¬ifyConsumed)) { 597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyConsumed->post(); 598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::onAudioSinkChanged() { 6043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK(!mDrainAudioQueuePending); 6053831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mNumFramesWritten = 0; 6064110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen uint32_t written; 6074110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen if (mAudioSink->getFramesWritten(&written) == OK) { 6084110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen mNumFramesWritten = written; 6094110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen } 6103831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 6113831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 61243c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::Renderer::notifyPosition() { 61343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mAnchorTimeRealUs < 0 || mAnchorTimeMediaUs < 0) { 61443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber return; 61543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 61643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 61743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 618714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 619714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber if (mLastPositionUpdateUs >= 0 620714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber && nowUs < mLastPositionUpdateUs + kMinPositionUpdateDelayUs) { 621714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber return; 622714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber } 623714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber mLastPositionUpdateUs = nowUs; 624714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber 62543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs; 62643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 62743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<AMessage> notify = mNotify->dup(); 62843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber notify->setInt32("what", kWhatPosition); 62943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber notify->setInt64("positionUs", positionUs); 6303fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber notify->setInt64("videoLateByUs", mVideoLateByUs); 63143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber notify->post(); 63243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber} 63343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 634b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onPause() { 635b408222bd9479c291874b607acae1425d6154fe7Andreas Huber CHECK(!mPaused); 636b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 637b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mDrainAudioQueuePending = false; 638b408222bd9479c291874b607acae1425d6154fe7Andreas Huber ++mAudioQueueGeneration; 639b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 640b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mDrainVideoQueuePending = false; 641b408222bd9479c291874b607acae1425d6154fe7Andreas Huber ++mVideoQueueGeneration; 642b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 643b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 644b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->pause(); 645b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 646b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 647ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber ALOGV("now paused audio queue has %d entries, video has %d entries", 648ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber mAudioQueue.size(), mVideoQueue.size()); 649b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber 650b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mPaused = true; 651b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 652b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 653b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onResume() { 654b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (!mPaused) { 655b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber return; 656b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 657b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 658b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (mHasAudio) { 659b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mAudioSink->start(); 660b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 661b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 662b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mPaused = false; 663b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 664b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mAudioQueue.empty()) { 665b408222bd9479c291874b607acae1425d6154fe7Andreas Huber postDrainAudioQueue(); 666b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 667b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 668b408222bd9479c291874b607acae1425d6154fe7Andreas Huber if (!mVideoQueue.empty()) { 669b408222bd9479c291874b607acae1425d6154fe7Andreas Huber postDrainVideoQueue(); 670b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 671b408222bd9479c291874b607acae1425d6154fe7Andreas Huber} 672b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 675