blob: a607b31483a29c6af18b9634f467fec54db0a4ba [file] [log] [blame]
Andreas Huberf9334412010-12-15 15:17:42 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "NuPlayer"
19#include <utils/Log.h>
20
21#include "NuPlayer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080022
23#include "HTTPLiveSource.h"
Andreas Huberf9334412010-12-15 15:17:42 -080024#include "NuPlayerDecoder.h"
Andreas Huber43c3e6c2011-01-05 12:17:08 -080025#include "NuPlayerDriver.h"
Andreas Huberf9334412010-12-15 15:17:42 -080026#include "NuPlayerRenderer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080027#include "NuPlayerSource.h"
28#include "StreamingSource.h"
29
30#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080031
Andreas Huber3831a062010-12-21 10:22:33 -080032#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080033#include <media/stagefright/foundation/ABuffer.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AMessage.h>
36#include <media/stagefright/ACodec.h>
37#include <media/stagefright/MediaErrors.h>
38#include <media/stagefright/MetaData.h>
39#include <surfaceflinger/Surface.h>
40
41namespace android {
42
43////////////////////////////////////////////////////////////////////////////////
44
45NuPlayer::NuPlayer()
Andreas Huber5bc087c2010-12-23 10:27:40 -080046 : mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -080047 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -080048 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -080049 mScanSourcesGeneration(0),
Andreas Huberf9334412010-12-15 15:17:42 -080050 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -080051 mFlushingVideo(NONE),
52 mResetInProgress(false),
53 mResetPostponed(false) {
Andreas Huberf9334412010-12-15 15:17:42 -080054}
55
56NuPlayer::~NuPlayer() {
57}
58
Andreas Huber43c3e6c2011-01-05 12:17:08 -080059void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
60 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -080061}
62
63void NuPlayer::setDataSource(const sp<IStreamSource> &source) {
64 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
65
Andreas Huber5bc087c2010-12-23 10:27:40 -080066 msg->setObject("source", new StreamingSource(source));
67 msg->post();
68}
Andreas Huberf9334412010-12-15 15:17:42 -080069
Andreas Huber5bc087c2010-12-23 10:27:40 -080070void NuPlayer::setDataSource(
71 const char *url, const KeyedVector<String8, String8> *headers) {
72 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
73
74 msg->setObject("source", new HTTPLiveSource(url));
Andreas Huberf9334412010-12-15 15:17:42 -080075 msg->post();
76}
77
78void NuPlayer::setVideoSurface(const sp<Surface> &surface) {
79 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, id());
80 msg->setObject("surface", surface);
81 msg->post();
82}
83
84void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
85 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
86 msg->setObject("sink", sink);
87 msg->post();
88}
89
90void NuPlayer::start() {
91 (new AMessage(kWhatStart, id()))->post();
92}
93
Andreas Huber43c3e6c2011-01-05 12:17:08 -080094void NuPlayer::pause() {
95 // XXX to be implemented
96}
97
98void NuPlayer::resume() {
99 // XXX to be implemented
100}
101
Andreas Huber1aef2112011-01-04 14:01:29 -0800102void NuPlayer::resetAsync() {
103 (new AMessage(kWhatReset, id()))->post();
104}
105
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800106void NuPlayer::seekToAsync(int64_t seekTimeUs) {
107 sp<AMessage> msg = new AMessage(kWhatSeek, id());
108 msg->setInt64("seekTimeUs", seekTimeUs);
109 msg->post();
110}
111
Andreas Huber53df1a42010-12-22 10:03:04 -0800112// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800113bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800114 switch (state) {
115 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800116 if (needShutdown != NULL) {
117 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800118 }
119 return true;
120
Andreas Huber1aef2112011-01-04 14:01:29 -0800121 case FLUSHING_DECODER_SHUTDOWN:
122 if (needShutdown != NULL) {
123 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800124 }
125 return true;
126
127 default:
128 return false;
129 }
130}
131
Andreas Huberf9334412010-12-15 15:17:42 -0800132void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
133 switch (msg->what()) {
134 case kWhatSetDataSource:
135 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800136 LOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800137
138 CHECK(mSource == NULL);
139
Andreas Huber5bc087c2010-12-23 10:27:40 -0800140 sp<RefBase> obj;
141 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800142
Andreas Huber5bc087c2010-12-23 10:27:40 -0800143 mSource = static_cast<Source *>(obj.get());
Andreas Huberf9334412010-12-15 15:17:42 -0800144 break;
145 }
146
147 case kWhatSetVideoSurface:
148 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800149 LOGV("kWhatSetVideoSurface");
Andreas Huberf9334412010-12-15 15:17:42 -0800150
151 sp<RefBase> obj;
152 CHECK(msg->findObject("surface", &obj));
153
154 mSurface = static_cast<Surface *>(obj.get());
155 break;
156 }
157
158 case kWhatSetAudioSink:
159 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800160 LOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800161
162 sp<RefBase> obj;
163 CHECK(msg->findObject("sink", &obj));
164
165 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
166 break;
167 }
168
169 case kWhatStart:
170 {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800171 LOGV("kWhatStart");
172
Andreas Huber1aef2112011-01-04 14:01:29 -0800173 mAudioEOS = false;
174 mVideoEOS = false;
175
Andreas Huber5bc087c2010-12-23 10:27:40 -0800176 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800177
178 mRenderer = new Renderer(
179 mAudioSink,
180 new AMessage(kWhatRendererNotify, id()));
181
182 looper()->registerHandler(mRenderer);
183
Andreas Huber1aef2112011-01-04 14:01:29 -0800184 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800185 break;
186 }
187
188 case kWhatScanSources:
189 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800190 int32_t generation;
191 CHECK(msg->findInt32("generation", &generation));
192 if (generation != mScanSourcesGeneration) {
193 // Drop obsolete msg.
194 break;
195 }
196
Andreas Huber5bc087c2010-12-23 10:27:40 -0800197 mScanSourcesPending = false;
198
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800199 LOGV("scanning sources haveAudio=%d, haveVideo=%d",
200 mAudioDecoder != NULL, mVideoDecoder != NULL);
201
Andreas Huber5bc087c2010-12-23 10:27:40 -0800202 instantiateDecoder(false, &mVideoDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800203
204 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800205 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800206 }
207
Andreas Huber5bc087c2010-12-23 10:27:40 -0800208 if (!mSource->feedMoreTSData()) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800209 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
210 // We're not currently decoding anything (no audio or
211 // video tracks found) and we just ran out of input data.
212 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
213 }
Andreas Huberf9334412010-12-15 15:17:42 -0800214 break;
215 }
216
Andreas Huberf9334412010-12-15 15:17:42 -0800217 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
218 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800219 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800220 }
221 break;
222 }
223
224 case kWhatVideoNotify:
225 case kWhatAudioNotify:
226 {
227 bool audio = msg->what() == kWhatAudioNotify;
228
229 sp<AMessage> codecRequest;
230 CHECK(msg->findMessage("codec-request", &codecRequest));
231
232 int32_t what;
233 CHECK(codecRequest->findInt32("what", &what));
234
235 if (what == ACodec::kWhatFillThisBuffer) {
236 status_t err = feedDecoderInputData(
237 audio, codecRequest);
238
Andreas Huber5bc087c2010-12-23 10:27:40 -0800239 if (err == -EWOULDBLOCK) {
240 if (mSource->feedMoreTSData()) {
241 msg->post();
242 }
Andreas Huberf9334412010-12-15 15:17:42 -0800243 }
244 } else if (what == ACodec::kWhatEOS) {
245 mRenderer->queueEOS(audio, ERROR_END_OF_STREAM);
246 } else if (what == ACodec::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800247 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800248
Andreas Huberf9334412010-12-15 15:17:42 -0800249 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800250 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800251 mFlushingAudio = FLUSHED;
252 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800253 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800254 mFlushingVideo = FLUSHED;
255 }
256
Andreas Huber1aef2112011-01-04 14:01:29 -0800257 LOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800258
Andreas Huber1aef2112011-01-04 14:01:29 -0800259 if (needShutdown) {
260 LOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800261 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800262
Andreas Huber53df1a42010-12-22 10:03:04 -0800263 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800264
Andreas Huber53df1a42010-12-22 10:03:04 -0800265 if (audio) {
266 mFlushingAudio = SHUTTING_DOWN_DECODER;
267 } else {
268 mFlushingVideo = SHUTTING_DOWN_DECODER;
269 }
Andreas Huberf9334412010-12-15 15:17:42 -0800270 }
Andreas Huber3831a062010-12-21 10:22:33 -0800271
272 finishFlushIfPossible();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800273 } else if (what == ACodec::kWhatOutputFormatChanged) {
274 CHECK(audio);
275
276 int32_t numChannels;
277 CHECK(codecRequest->findInt32("channel-count", &numChannels));
278
279 int32_t sampleRate;
280 CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
281
Andreas Huber1aef2112011-01-04 14:01:29 -0800282 LOGV("Audio output format changed to %d Hz, %d channels",
Andreas Huber2c2814b2010-12-15 17:18:20 -0800283 sampleRate, numChannels);
284
285 mAudioSink->close();
286 CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
287 mAudioSink->start();
Andreas Huber3831a062010-12-21 10:22:33 -0800288
289 mRenderer->signalAudioSinkChanged();
290 } else if (what == ACodec::kWhatShutdownCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800291 LOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800292 if (audio) {
293 mAudioDecoder.clear();
294
295 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
296 mFlushingAudio = SHUT_DOWN;
297 } else {
298 mVideoDecoder.clear();
299
300 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
301 mFlushingVideo = SHUT_DOWN;
302 }
303
304 finishFlushIfPossible();
Andreas Huberf9334412010-12-15 15:17:42 -0800305 } else {
306 CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
307
308 renderBuffer(audio, codecRequest);
309 }
310
311 break;
312 }
313
314 case kWhatRendererNotify:
315 {
316 int32_t what;
317 CHECK(msg->findInt32("what", &what));
318
319 if (what == Renderer::kWhatEOS) {
320 int32_t audio;
321 CHECK(msg->findInt32("audio", &audio));
322
323 if (audio) {
324 mAudioEOS = true;
325 } else {
326 mVideoEOS = true;
327 }
328
Andreas Huber1aef2112011-01-04 14:01:29 -0800329 LOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800330
331 if ((mAudioEOS || mAudioDecoder == NULL)
332 && (mVideoEOS || mVideoDecoder == NULL)) {
333 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
334 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800335 } else if (what == Renderer::kWhatPosition) {
336 int64_t positionUs;
337 CHECK(msg->findInt64("positionUs", &positionUs));
338
339 if (mDriver != NULL) {
340 sp<NuPlayerDriver> driver = mDriver.promote();
341 if (driver != NULL) {
342 driver->notifyPosition(positionUs);
343 }
344 }
Andreas Huberf9334412010-12-15 15:17:42 -0800345 } else {
346 CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
347
348 int32_t audio;
349 CHECK(msg->findInt32("audio", &audio));
350
Andreas Huber1aef2112011-01-04 14:01:29 -0800351 LOGV("renderer %s flush completed.", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800352 }
353 break;
354 }
355
356 case kWhatMoreDataQueued:
357 {
358 break;
359 }
360
Andreas Huber1aef2112011-01-04 14:01:29 -0800361 case kWhatReset:
362 {
363 LOGV("kWhatReset");
364
365 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
366 // We're currently flushing, postpone the reset until that's
367 // completed.
368
369 LOGV("postponing reset");
370
371 mResetPostponed = true;
372 break;
373 }
374
375 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
376 finishReset();
377 break;
378 }
379
380 if (mAudioDecoder != NULL) {
381 flushDecoder(true /* audio */, true /* needShutdown */);
382 }
383
384 if (mVideoDecoder != NULL) {
385 flushDecoder(false /* audio */, true /* needShutdown */);
386 }
387
388 mResetInProgress = true;
389 break;
390 }
391
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800392 case kWhatSeek:
393 {
394 int64_t seekTimeUs;
395 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
396
397 LOGI("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
398 seekTimeUs, seekTimeUs / 1E6);
399
400 mSource->seekTo(seekTimeUs);
401
402 if (mDriver != NULL) {
403 sp<NuPlayerDriver> driver = mDriver.promote();
404 if (driver != NULL) {
405 driver->notifySeekComplete();
406 }
407 }
408
409 break;
410 }
411
Andreas Huberf9334412010-12-15 15:17:42 -0800412 default:
413 TRESPASS();
414 break;
415 }
416}
417
Andreas Huber3831a062010-12-21 10:22:33 -0800418void NuPlayer::finishFlushIfPossible() {
419 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
420 return;
421 }
422
423 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
424 return;
425 }
426
Andreas Huber1aef2112011-01-04 14:01:29 -0800427 LOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800428
429 mRenderer->signalTimeDiscontinuity();
430
Andreas Huber5bc087c2010-12-23 10:27:40 -0800431 bool scanSourcesAgain = false;
432
Andreas Huber3831a062010-12-21 10:22:33 -0800433 if (mFlushingAudio == SHUT_DOWN) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800434 scanSourcesAgain = true;
Andreas Huber3831a062010-12-21 10:22:33 -0800435 } else if (mAudioDecoder != NULL) {
436 mAudioDecoder->signalResume();
437 }
438
439 if (mFlushingVideo == SHUT_DOWN) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800440 scanSourcesAgain = true;
Andreas Huber3831a062010-12-21 10:22:33 -0800441 } else if (mVideoDecoder != NULL) {
442 mVideoDecoder->signalResume();
443 }
444
445 mFlushingAudio = NONE;
446 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800447
Andreas Huber1aef2112011-01-04 14:01:29 -0800448 if (mResetInProgress) {
449 LOGV("reset completed");
450
451 mResetInProgress = false;
452 finishReset();
453 } else if (mResetPostponed) {
454 (new AMessage(kWhatReset, id()))->post();
455 mResetPostponed = false;
456 } else if (scanSourcesAgain) {
457 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800458 }
459}
460
Andreas Huber1aef2112011-01-04 14:01:29 -0800461void NuPlayer::finishReset() {
462 CHECK(mAudioDecoder == NULL);
463 CHECK(mVideoDecoder == NULL);
464
465 mRenderer.clear();
466 mSource.clear();
467
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800468 if (mDriver != NULL) {
469 sp<NuPlayerDriver> driver = mDriver.promote();
470 if (driver != NULL) {
471 driver->notifyResetComplete();
472 }
473 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800474}
475
476void NuPlayer::postScanSources() {
477 if (mScanSourcesPending) {
478 return;
479 }
480
481 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
482 msg->setInt32("generation", mScanSourcesGeneration);
483 msg->post();
484
485 mScanSourcesPending = true;
486}
487
Andreas Huber5bc087c2010-12-23 10:27:40 -0800488status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800489 if (*decoder != NULL) {
490 return OK;
491 }
492
Andreas Huber5bc087c2010-12-23 10:27:40 -0800493 sp<MetaData> meta = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800494
Andreas Huber5bc087c2010-12-23 10:27:40 -0800495 if (meta == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800496 return -EWOULDBLOCK;
497 }
498
499 sp<AMessage> notify =
500 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
501 id());
502
503 *decoder = new Decoder(notify, audio ? NULL : mSurface);
504 looper()->registerHandler(*decoder);
505
Andreas Huber5bc087c2010-12-23 10:27:40 -0800506 (*decoder)->configure(meta);
Andreas Huberf9334412010-12-15 15:17:42 -0800507
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800508 int64_t durationUs;
509 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
510 sp<NuPlayerDriver> driver = mDriver.promote();
511 if (driver != NULL) {
512 driver->notifyDuration(durationUs);
513 }
514 }
515
Andreas Huberf9334412010-12-15 15:17:42 -0800516 return OK;
517}
518
519status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
520 sp<AMessage> reply;
521 CHECK(msg->findMessage("reply", &reply));
522
Andreas Huber53df1a42010-12-22 10:03:04 -0800523 if ((audio && IsFlushingState(mFlushingAudio))
524 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800525 reply->setInt32("err", INFO_DISCONTINUITY);
526 reply->post();
527 return OK;
528 }
529
530 sp<ABuffer> accessUnit;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800531 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800532
533 if (err == -EWOULDBLOCK) {
534 return err;
535 } else if (err != OK) {
536 if (err == INFO_DISCONTINUITY) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800537 int32_t type;
538 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
539
540 bool formatChange =
541 type == ATSParser::DISCONTINUITY_FORMATCHANGE;
Andreas Huber53df1a42010-12-22 10:03:04 -0800542
Andreas Huber1aef2112011-01-04 14:01:29 -0800543 LOGV("%s discontinuity (formatChange=%d)",
Andreas Huber53df1a42010-12-22 10:03:04 -0800544 audio ? "audio" : "video", formatChange);
545
Andreas Huber1aef2112011-01-04 14:01:29 -0800546 flushDecoder(audio, formatChange);
Andreas Huberf9334412010-12-15 15:17:42 -0800547 }
548
549 reply->setInt32("err", err);
550 reply->post();
551 return OK;
552 }
553
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800554 // LOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800555
556#if 0
557 int64_t mediaTimeUs;
558 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Andreas Huber1aef2112011-01-04 14:01:29 -0800559 LOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800560 audio ? "audio" : "video",
561 mediaTimeUs / 1E6);
562#endif
563
564 reply->setObject("buffer", accessUnit);
565 reply->post();
566
567 return OK;
568}
569
570void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800571 // LOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800572
573 sp<AMessage> reply;
574 CHECK(msg->findMessage("reply", &reply));
575
576 sp<RefBase> obj;
577 CHECK(msg->findObject("buffer", &obj));
578
579 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
580
581 mRenderer->queueBuffer(audio, buffer, reply);
582}
583
584void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800585 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800586 return;
587 }
588
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800589 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -0800590
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800591 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800592 return;
593 }
594
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800595 driver->sendEvent(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -0800596}
597
Andreas Huber1aef2112011-01-04 14:01:29 -0800598void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
599 // Make sure we don't continue to scan sources until we finish flushing.
600 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800601 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800602
603 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
604 mRenderer->flush(audio);
605
606 FlushStatus newStatus =
607 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
608
609 if (audio) {
610 CHECK(mFlushingAudio == NONE
611 || mFlushingAudio == AWAITING_DISCONTINUITY);
612
613 mFlushingAudio = newStatus;
614
615 if (mFlushingVideo == NONE) {
616 mFlushingVideo = (mVideoDecoder != NULL)
617 ? AWAITING_DISCONTINUITY
618 : FLUSHED;
619 }
620 } else {
621 CHECK(mFlushingVideo == NONE
622 || mFlushingVideo == AWAITING_DISCONTINUITY);
623
624 mFlushingVideo = newStatus;
625
626 if (mFlushingAudio == NONE) {
627 mFlushingAudio = (mAudioDecoder != NULL)
628 ? AWAITING_DISCONTINUITY
629 : FLUSHED;
630 }
631 }
632}
633
Andreas Huberf9334412010-12-15 15:17:42 -0800634} // namespace android