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> &notify)
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> &notifyConsumed) {
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", &notifyConsumed));
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", &notifyConsumed)) {
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