NuPlayerRenderer.cpp revision b408222bd9479c291874b607acae1425d6154fe7
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
29f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::Renderer(
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<MediaPlayerBase::AudioSink> &sink,
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &notify)
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mAudioSink(sink),
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mNotify(notify),
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mNumFramesWritten(0),
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mDrainAudioQueuePending(false),
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mDrainVideoQueuePending(false),
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAudioQueueGeneration(0),
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoQueueGeneration(0),
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAnchorTimeMediaUs(-1),
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAnchorTimeRealUs(-1),
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingAudio(false),
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingVideo(false),
433831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber      mHasAudio(mAudioSink != NULL),
443831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber      mHasVideo(true),
45b408222bd9479c291874b607acae1425d6154fe7Andreas Huber      mSyncQueues(mHasAudio && mHasVideo),
46b408222bd9479c291874b607acae1425d6154fe7Andreas Huber      mPaused(false) {
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Renderer::~Renderer() {
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueBuffer(
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool audio,
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<ABuffer> &buffer,
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &notifyConsumed) {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueBuffer, id());
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("audio", static_cast<int32_t>(audio));
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("buffer", buffer);
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setMessage("notifyConsumed", notifyConsumed);
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_NE(finalResult, (status_t)OK);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueEOS, id());
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("audio", static_cast<int32_t>(audio));
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("finalResult", finalResult);
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flush(bool audio) {
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    {
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        Mutex::Autolock autoLock(mFlushLock);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (audio) {
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(!mFlushingAudio);
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mFlushingAudio = true;
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(!mFlushingVideo);
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mFlushingVideo = true;
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatFlush, id());
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("audio", static_cast<int32_t>(audio));
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
89f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::signalTimeDiscontinuity() {
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mAudioQueue.empty());
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mVideoQueue.empty());
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mAnchorTimeMediaUs = -1;
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mAnchorTimeRealUs = -1;
943831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mSyncQueues = mHasAudio && mHasVideo;
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
97b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::pause() {
98b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
99b408222bd9479c291874b607acae1425d6154fe7Andreas Huber}
100b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
101b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::resume() {
102b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatResume, id()))->post();
103b408222bd9479c291874b607acae1425d6154fe7Andreas Huber}
104b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
105f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatDrainAudioQueue:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t generation;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("generation", &generation));
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (generation != mAudioQueueGeneration) {
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mDrainAudioQueuePending = false;
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onDrainAudioQueue();
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postDrainAudioQueue();
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatDrainVideoQueue:
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t generation;
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("generation", &generation));
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (generation != mVideoQueueGeneration) {
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mDrainVideoQueuePending = false;
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onDrainVideoQueue();
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postDrainVideoQueue();
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatQueueBuffer:
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onQueueBuffer(msg);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatQueueEOS:
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onQueueEOS(msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onFlush(msg);
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1573831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        case kWhatAudioSinkChanged:
1583831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        {
1593831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            onAudioSinkChanged();
1603831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            break;
1613831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        }
1623831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
163b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
164b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
165b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            onPause();
166b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
167b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
168b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
169b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatResume:
170b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
171b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            onResume();
172b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
173b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
174b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
181f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::postDrainAudioQueue() {
182b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    if (mDrainAudioQueuePending || mSyncQueues || mPaused) {
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioQueue.empty()) {
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDrainAudioQueuePending = true;
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("generation", mAudioQueueGeneration);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post(10000);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1963831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::signalAudioSinkChanged() {
1973831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    (new AMessage(kWhatAudioSinkChanged, id()))->post();
1983831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber}
1993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainAudioQueue() {
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    uint32_t numFramesPlayed;
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t numFramesAvailableToWrite =
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GE(numFramesAvailableToWrite, 0);
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t numBytesAvailableToWrite =
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        numFramesAvailableToWrite * mAudioSink->frameSize();
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (numBytesAvailableToWrite > 0) {
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mAudioQueue.empty()) {
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        QueueEntry *entry = &*mAudioQueue.begin();
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (entry->mBuffer == NULL) {
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // EOS
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notifyEOS(true /* audio */);
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioQueue.erase(mAudioQueue.begin());
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            entry = NULL;
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (entry->mOffset == 0) {
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t mediaTimeUs;
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            LOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAnchorTimeMediaUs = mediaTimeUs;
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            uint32_t numFramesPlayed;
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            uint32_t numFramesPendingPlayout =
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNumFramesWritten - numFramesPlayed;
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t realTimeOffsetUs =
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                (mAudioSink->latency() / 2  /* XXX */
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    + numFramesPendingPlayout
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        * mAudioSink->msecsPerFrame()) * 1000ll;
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // LOGI("realTimeOffsetUs = %lld us", realTimeOffsetUs);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAnchorTimeRealUs =
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ALooper::GetNowUs() + realTimeOffsetUs;
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t copy = entry->mBuffer->size() - entry->mOffset;
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (copy > numBytesAvailableToWrite) {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            copy = numBytesAvailableToWrite;
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mAudioSink->write(
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    entry->mBuffer->data() + entry->mOffset, copy),
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (ssize_t)copy);
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        entry->mOffset += copy;
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (entry->mOffset == entry->mBuffer->size()) {
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            entry->mNotifyConsumed->post();
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioQueue.erase(mAudioQueue.begin());
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            entry = NULL;
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        numBytesAvailableToWrite -= copy;
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNumFramesWritten += copy / mAudioSink->frameSize();
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
27343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
27443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    notifyPosition();
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::postDrainVideoQueue() {
278b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    if (mDrainVideoQueuePending || mSyncQueues || mPaused) {
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mVideoQueue.empty()) {
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    QueueEntry &entry = *mVideoQueue.begin();
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, id());
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("generation", mVideoQueueGeneration);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t delayUs;
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (entry.mBuffer == NULL) {
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // EOS doesn't carry a timestamp.
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        delayUs = 0;
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t mediaTimeUs;
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mAnchorTimeMediaUs < 0) {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            delayUs = 0;
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            if (!mHasAudio) {
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAnchorTimeMediaUs = mediaTimeUs;
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAnchorTimeRealUs = ALooper::GetNowUs();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t realTimeUs =
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                (mediaTimeUs - mAnchorTimeMediaUs) + mAnchorTimeRealUs;
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            delayUs = realTimeUs - ALooper::GetNowUs();
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post(delayUs);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDrainVideoQueuePending = true;
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onDrainVideoQueue() {
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mVideoQueue.empty()) {
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    QueueEntry *entry = &*mVideoQueue.begin();
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (entry->mBuffer == NULL) {
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // EOS
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notifyEOS(false /* audio */);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mVideoQueue.erase(mVideoQueue.begin());
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        entry = NULL;
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaTimeUs;
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LOGI("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry->mNotifyConsumed->setInt32("render", true);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry->mNotifyConsumed->post();
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mVideoQueue.erase(mVideoQueue.begin());
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry = NULL;
34843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
34943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    notifyPosition();
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyEOS(bool audio) {
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mNotify->dup();
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", kWhatEOS);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("audio", static_cast<int32_t>(audio));
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t audio;
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("audio", &audio));
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (dropBufferWhileFlushing(audio, msg)) {
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findObject("buffer", &obj));
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notifyConsumed;
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    QueueEntry entry;
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry.mBuffer = buffer;
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry.mNotifyConsumed = notifyConsumed;
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry.mOffset = 0;
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry.mFinalResult = OK;
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audio) {
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioQueue.push_back(entry);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postDrainAudioQueue();
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mVideoQueue.push_back(entry);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postDrainVideoQueue();
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mSyncQueues && !mAudioQueue.empty() && !mVideoQueue.empty()) {
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t firstAudioTimeUs;
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t firstVideoTimeUs;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK((*mAudioQueue.begin()).mBuffer->meta()
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ->findInt64("timeUs", &firstAudioTimeUs));
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK((*mVideoQueue.begin()).mBuffer->meta()
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ->findInt64("timeUs", &firstVideoTimeUs));
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t diff = firstVideoTimeUs - firstAudioTimeUs;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        LOGV("queueDiff = %.2f secs", diff / 1E6);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (diff > 100000ll) {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Audio data starts More than 0.1 secs before video.
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Drop some audio.
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (*mAudioQueue.begin()).mNotifyConsumed->post();
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioQueue.erase(mAudioQueue.begin());
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        syncQueuesDone();
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::syncQueuesDone() {
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!mSyncQueues) {
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mSyncQueues = false;
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!mAudioQueue.empty()) {
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postDrainAudioQueue();
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!mVideoQueue.empty()) {
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postDrainVideoQueue();
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) {
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t audio;
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("audio", &audio));
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (dropBufferWhileFlushing(audio, msg)) {
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t finalResult;
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("finalResult", &finalResult));
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    QueueEntry entry;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry.mOffset = 0;
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    entry.mFinalResult = finalResult;
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audio) {
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioQueue.push_back(entry);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postDrainAudioQueue();
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mVideoQueue.push_back(entry);
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postDrainVideoQueue();
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t audio;
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("audio", &audio));
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // If we're currently syncing the queues, i.e. dropping audio while
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // aligning the first audio/video buffer times and only one of the
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // two queues has data, we may starve that queue by not requesting
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // more buffers from the decoder. If the other source then encounters
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // a discontinuity that leads to flushing, we'll never find the
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // corresponding discontinuity on the other queue.
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Therefore we'll stop syncing the queues if at least one of them
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // is flushed.
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    syncQueuesDone();
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audio) {
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        flushQueue(&mAudioQueue);
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        Mutex::Autolock autoLock(mFlushLock);
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mFlushingAudio = false;
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mDrainAudioQueuePending = false;
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++mAudioQueueGeneration;
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        flushQueue(&mVideoQueue);
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        Mutex::Autolock autoLock(mFlushLock);
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mFlushingVideo = false;
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mDrainVideoQueuePending = false;
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++mVideoQueueGeneration;
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notifyFlushComplete(audio);
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) {
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (!queue->empty()) {
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        QueueEntry *entry = &*queue->begin();
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (entry->mBuffer != NULL) {
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            entry->mNotifyConsumed->post();
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        queue->erase(queue->begin());
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        entry = NULL;
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Renderer::notifyFlushComplete(bool audio) {
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mNotify->dup();
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", kWhatFlushComplete);
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("audio", static_cast<int32_t>(audio));
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::Renderer::dropBufferWhileFlushing(
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool audio, const sp<AMessage> &msg) {
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool flushing = false;
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    {
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        Mutex::Autolock autoLock(mFlushLock);
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (audio) {
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            flushing = mFlushingAudio;
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            flushing = mFlushingVideo;
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!flushing) {
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notifyConsumed;
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findMessage("notifyConsumed", &notifyConsumed)) {
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notifyConsumed->post();
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5333831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Renderer::onAudioSinkChanged() {
5343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    CHECK(!mDrainAudioQueuePending);
5353831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mNumFramesWritten = 0;
5363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber}
5373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
53843c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::Renderer::notifyPosition() {
53943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mAnchorTimeRealUs < 0 || mAnchorTimeMediaUs < 0) {
54043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        return;
54143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
54243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
54343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int64_t nowUs = ALooper::GetNowUs();
54443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs;
54543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
54643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> notify = mNotify->dup();
54743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    notify->setInt32("what", kWhatPosition);
54843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    notify->setInt64("positionUs", positionUs);
54943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    notify->post();
55043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
55143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
552b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onPause() {
553b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    CHECK(!mPaused);
554b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
555b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    mDrainAudioQueuePending = false;
556b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    ++mAudioQueueGeneration;
557b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
558b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    mDrainVideoQueuePending = false;
559b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    ++mVideoQueueGeneration;
560b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
561b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    if (mHasAudio) {
562b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        mAudioSink->pause();
563b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    }
564b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
565b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    mPaused = true;
566b408222bd9479c291874b607acae1425d6154fe7Andreas Huber}
567b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
568b408222bd9479c291874b607acae1425d6154fe7Andreas Hubervoid NuPlayer::Renderer::onResume() {
569b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    CHECK(mPaused);
570b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
571b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    if (mHasAudio) {
572b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        mAudioSink->start();
573b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    }
574b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
575b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    mPaused = false;
576b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
577b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    if (!mAudioQueue.empty()) {
578b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        postDrainAudioQueue();
579b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    }
580b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
581b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    if (!mVideoQueue.empty()) {
582b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        postDrainVideoQueue();
583b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    }
584b408222bd9479c291874b607acae1425d6154fe7Andreas Huber}
585b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588