blob: 48b517e2867a62ec3009fd10e823a1d4db69d4e5 [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>
Glenn Kasten11731182011-02-08 17:26:17 -080040#include <gui/ISurfaceTexture.h>
Andreas Huberf9334412010-12-15 15:17:42 -080041
42namespace android {
43
44////////////////////////////////////////////////////////////////////////////////
45
46NuPlayer::NuPlayer()
Andreas Huber5bc087c2010-12-23 10:27:40 -080047 : mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -080048 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -080049 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -080050 mScanSourcesGeneration(0),
Andreas Huberf9334412010-12-15 15:17:42 -080051 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -080052 mFlushingVideo(NONE),
53 mResetInProgress(false),
54 mResetPostponed(false) {
Andreas Huberf9334412010-12-15 15:17:42 -080055}
56
57NuPlayer::~NuPlayer() {
58}
59
Andreas Huber43c3e6c2011-01-05 12:17:08 -080060void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
61 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -080062}
63
64void NuPlayer::setDataSource(const sp<IStreamSource> &source) {
65 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
66
Andreas Huber5bc087c2010-12-23 10:27:40 -080067 msg->setObject("source", new StreamingSource(source));
68 msg->post();
69}
Andreas Huberf9334412010-12-15 15:17:42 -080070
Andreas Huber5bc087c2010-12-23 10:27:40 -080071void NuPlayer::setDataSource(
72 const char *url, const KeyedVector<String8, String8> *headers) {
73 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
74
75 msg->setObject("source", new HTTPLiveSource(url));
Andreas Huberf9334412010-12-15 15:17:42 -080076 msg->post();
77}
78
79void NuPlayer::setVideoSurface(const sp<Surface> &surface) {
Glenn Kasten11731182011-02-08 17:26:17 -080080 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
81 msg->setObject("native-window", new NativeWindowWrapper(surface));
82 msg->post();
83}
84
85void NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
86 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
87 sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
88 new SurfaceTextureClient(surfaceTexture) : NULL);
89 msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
Andreas Huberf9334412010-12-15 15:17:42 -080090 msg->post();
91}
92
93void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
94 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
95 msg->setObject("sink", sink);
96 msg->post();
97}
98
99void NuPlayer::start() {
100 (new AMessage(kWhatStart, id()))->post();
101}
102
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800103void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800104 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800105}
106
107void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800108 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800109}
110
Andreas Huber1aef2112011-01-04 14:01:29 -0800111void NuPlayer::resetAsync() {
112 (new AMessage(kWhatReset, id()))->post();
113}
114
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800115void NuPlayer::seekToAsync(int64_t seekTimeUs) {
116 sp<AMessage> msg = new AMessage(kWhatSeek, id());
117 msg->setInt64("seekTimeUs", seekTimeUs);
118 msg->post();
119}
120
Andreas Huber53df1a42010-12-22 10:03:04 -0800121// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800122bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800123 switch (state) {
124 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800125 if (needShutdown != NULL) {
126 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800127 }
128 return true;
129
Andreas Huber1aef2112011-01-04 14:01:29 -0800130 case FLUSHING_DECODER_SHUTDOWN:
131 if (needShutdown != NULL) {
132 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800133 }
134 return true;
135
136 default:
137 return false;
138 }
139}
140
Andreas Huberf9334412010-12-15 15:17:42 -0800141void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
142 switch (msg->what()) {
143 case kWhatSetDataSource:
144 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800145 LOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800146
147 CHECK(mSource == NULL);
148
Andreas Huber5bc087c2010-12-23 10:27:40 -0800149 sp<RefBase> obj;
150 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800151
Andreas Huber5bc087c2010-12-23 10:27:40 -0800152 mSource = static_cast<Source *>(obj.get());
Andreas Huberf9334412010-12-15 15:17:42 -0800153 break;
154 }
155
Glenn Kasten11731182011-02-08 17:26:17 -0800156 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800157 {
Glenn Kasten11731182011-02-08 17:26:17 -0800158 LOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800159
160 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800161 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800162
Glenn Kasten11731182011-02-08 17:26:17 -0800163 mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
Andreas Huberf9334412010-12-15 15:17:42 -0800164 break;
165 }
166
167 case kWhatSetAudioSink:
168 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800169 LOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800170
171 sp<RefBase> obj;
172 CHECK(msg->findObject("sink", &obj));
173
174 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
175 break;
176 }
177
178 case kWhatStart:
179 {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800180 LOGV("kWhatStart");
181
Andreas Huber1aef2112011-01-04 14:01:29 -0800182 mAudioEOS = false;
183 mVideoEOS = false;
184
Andreas Huber5bc087c2010-12-23 10:27:40 -0800185 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800186
187 mRenderer = new Renderer(
188 mAudioSink,
189 new AMessage(kWhatRendererNotify, id()));
190
191 looper()->registerHandler(mRenderer);
192
Andreas Huber1aef2112011-01-04 14:01:29 -0800193 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800194 break;
195 }
196
197 case kWhatScanSources:
198 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800199 int32_t generation;
200 CHECK(msg->findInt32("generation", &generation));
201 if (generation != mScanSourcesGeneration) {
202 // Drop obsolete msg.
203 break;
204 }
205
Andreas Huber5bc087c2010-12-23 10:27:40 -0800206 mScanSourcesPending = false;
207
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800208 LOGV("scanning sources haveAudio=%d, haveVideo=%d",
209 mAudioDecoder != NULL, mVideoDecoder != NULL);
210
Andreas Huber5bc087c2010-12-23 10:27:40 -0800211 instantiateDecoder(false, &mVideoDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800212
213 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800214 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800215 }
216
Andreas Huber5bc087c2010-12-23 10:27:40 -0800217 if (!mSource->feedMoreTSData()) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800218 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
219 // We're not currently decoding anything (no audio or
220 // video tracks found) and we just ran out of input data.
221 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
222 }
Andreas Huberf9334412010-12-15 15:17:42 -0800223 break;
224 }
225
Andreas Huberf9334412010-12-15 15:17:42 -0800226 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
227 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800228 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800229 }
230 break;
231 }
232
233 case kWhatVideoNotify:
234 case kWhatAudioNotify:
235 {
236 bool audio = msg->what() == kWhatAudioNotify;
237
238 sp<AMessage> codecRequest;
239 CHECK(msg->findMessage("codec-request", &codecRequest));
240
241 int32_t what;
242 CHECK(codecRequest->findInt32("what", &what));
243
244 if (what == ACodec::kWhatFillThisBuffer) {
245 status_t err = feedDecoderInputData(
246 audio, codecRequest);
247
Andreas Huber5bc087c2010-12-23 10:27:40 -0800248 if (err == -EWOULDBLOCK) {
249 if (mSource->feedMoreTSData()) {
250 msg->post();
251 }
Andreas Huberf9334412010-12-15 15:17:42 -0800252 }
253 } else if (what == ACodec::kWhatEOS) {
254 mRenderer->queueEOS(audio, ERROR_END_OF_STREAM);
255 } else if (what == ACodec::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800256 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800257
Andreas Huberf9334412010-12-15 15:17:42 -0800258 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800259 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800260 mFlushingAudio = FLUSHED;
261 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800262 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800263 mFlushingVideo = FLUSHED;
264 }
265
Andreas Huber1aef2112011-01-04 14:01:29 -0800266 LOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800267
Andreas Huber1aef2112011-01-04 14:01:29 -0800268 if (needShutdown) {
269 LOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800270 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800271
Andreas Huber53df1a42010-12-22 10:03:04 -0800272 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800273
Andreas Huber53df1a42010-12-22 10:03:04 -0800274 if (audio) {
275 mFlushingAudio = SHUTTING_DOWN_DECODER;
276 } else {
277 mFlushingVideo = SHUTTING_DOWN_DECODER;
278 }
Andreas Huberf9334412010-12-15 15:17:42 -0800279 }
Andreas Huber3831a062010-12-21 10:22:33 -0800280
281 finishFlushIfPossible();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800282 } else if (what == ACodec::kWhatOutputFormatChanged) {
Andreas Huber31e25082011-01-10 10:38:31 -0800283 if (audio) {
284 int32_t numChannels;
285 CHECK(codecRequest->findInt32("channel-count", &numChannels));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800286
Andreas Huber31e25082011-01-10 10:38:31 -0800287 int32_t sampleRate;
288 CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800289
Andreas Huber31e25082011-01-10 10:38:31 -0800290 LOGV("Audio output format changed to %d Hz, %d channels",
291 sampleRate, numChannels);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800292
Andreas Huber31e25082011-01-10 10:38:31 -0800293 mAudioSink->close();
294 CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
295 mAudioSink->start();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800296
Andreas Huber31e25082011-01-10 10:38:31 -0800297 mRenderer->signalAudioSinkChanged();
298 } else {
299 // video
Andreas Huber3831a062010-12-21 10:22:33 -0800300
Andreas Huber31e25082011-01-10 10:38:31 -0800301 int32_t width, height;
302 CHECK(codecRequest->findInt32("width", &width));
303 CHECK(codecRequest->findInt32("height", &height));
304
305 int32_t cropLeft, cropTop, cropRight, cropBottom;
306 CHECK(codecRequest->findRect(
307 "crop",
308 &cropLeft, &cropTop, &cropRight, &cropBottom));
309
310 LOGV("Video output format changed to %d x %d "
311 "(crop: %d, %d, %d, %d)",
312 width, height,
313 cropLeft, cropTop, cropRight, cropBottom);
314
315 notifyListener(
316 MEDIA_SET_VIDEO_SIZE,
317 cropRight - cropLeft + 1,
318 cropBottom - cropTop + 1);
319 }
Andreas Huber3831a062010-12-21 10:22:33 -0800320 } else if (what == ACodec::kWhatShutdownCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800321 LOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800322 if (audio) {
323 mAudioDecoder.clear();
324
325 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
326 mFlushingAudio = SHUT_DOWN;
327 } else {
328 mVideoDecoder.clear();
329
330 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
331 mFlushingVideo = SHUT_DOWN;
332 }
333
334 finishFlushIfPossible();
Andreas Huberf9334412010-12-15 15:17:42 -0800335 } else {
336 CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
337
338 renderBuffer(audio, codecRequest);
339 }
340
341 break;
342 }
343
344 case kWhatRendererNotify:
345 {
346 int32_t what;
347 CHECK(msg->findInt32("what", &what));
348
349 if (what == Renderer::kWhatEOS) {
350 int32_t audio;
351 CHECK(msg->findInt32("audio", &audio));
352
353 if (audio) {
354 mAudioEOS = true;
355 } else {
356 mVideoEOS = true;
357 }
358
Andreas Huber1aef2112011-01-04 14:01:29 -0800359 LOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800360
361 if ((mAudioEOS || mAudioDecoder == NULL)
362 && (mVideoEOS || mVideoDecoder == NULL)) {
363 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
364 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800365 } else if (what == Renderer::kWhatPosition) {
366 int64_t positionUs;
367 CHECK(msg->findInt64("positionUs", &positionUs));
368
369 if (mDriver != NULL) {
370 sp<NuPlayerDriver> driver = mDriver.promote();
371 if (driver != NULL) {
372 driver->notifyPosition(positionUs);
373 }
374 }
Andreas Huberf9334412010-12-15 15:17:42 -0800375 } else {
376 CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
377
378 int32_t audio;
379 CHECK(msg->findInt32("audio", &audio));
380
Andreas Huber1aef2112011-01-04 14:01:29 -0800381 LOGV("renderer %s flush completed.", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800382 }
383 break;
384 }
385
386 case kWhatMoreDataQueued:
387 {
388 break;
389 }
390
Andreas Huber1aef2112011-01-04 14:01:29 -0800391 case kWhatReset:
392 {
393 LOGV("kWhatReset");
394
395 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
396 // We're currently flushing, postpone the reset until that's
397 // completed.
398
399 LOGV("postponing reset");
400
401 mResetPostponed = true;
402 break;
403 }
404
405 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
406 finishReset();
407 break;
408 }
409
410 if (mAudioDecoder != NULL) {
411 flushDecoder(true /* audio */, true /* needShutdown */);
412 }
413
414 if (mVideoDecoder != NULL) {
415 flushDecoder(false /* audio */, true /* needShutdown */);
416 }
417
418 mResetInProgress = true;
419 break;
420 }
421
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800422 case kWhatSeek:
423 {
424 int64_t seekTimeUs;
425 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
426
Andreas Huber22fc52f2011-01-05 16:24:27 -0800427 LOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800428 seekTimeUs, seekTimeUs / 1E6);
429
430 mSource->seekTo(seekTimeUs);
431
432 if (mDriver != NULL) {
433 sp<NuPlayerDriver> driver = mDriver.promote();
434 if (driver != NULL) {
435 driver->notifySeekComplete();
436 }
437 }
438
439 break;
440 }
441
Andreas Huberb4082222011-01-20 15:23:04 -0800442 case kWhatPause:
443 {
444 CHECK(mRenderer != NULL);
445 mRenderer->pause();
446 break;
447 }
448
449 case kWhatResume:
450 {
451 CHECK(mRenderer != NULL);
452 mRenderer->resume();
453 break;
454 }
455
Andreas Huberf9334412010-12-15 15:17:42 -0800456 default:
457 TRESPASS();
458 break;
459 }
460}
461
Andreas Huber3831a062010-12-21 10:22:33 -0800462void NuPlayer::finishFlushIfPossible() {
463 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
464 return;
465 }
466
467 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
468 return;
469 }
470
Andreas Huber1aef2112011-01-04 14:01:29 -0800471 LOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800472
473 mRenderer->signalTimeDiscontinuity();
474
Andreas Huber22fc52f2011-01-05 16:24:27 -0800475 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800476 mAudioDecoder->signalResume();
477 }
478
Andreas Huber22fc52f2011-01-05 16:24:27 -0800479 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800480 mVideoDecoder->signalResume();
481 }
482
483 mFlushingAudio = NONE;
484 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800485
Andreas Huber1aef2112011-01-04 14:01:29 -0800486 if (mResetInProgress) {
487 LOGV("reset completed");
488
489 mResetInProgress = false;
490 finishReset();
491 } else if (mResetPostponed) {
492 (new AMessage(kWhatReset, id()))->post();
493 mResetPostponed = false;
Andreas Huber22fc52f2011-01-05 16:24:27 -0800494 } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800495 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800496 }
497}
498
Andreas Huber1aef2112011-01-04 14:01:29 -0800499void NuPlayer::finishReset() {
500 CHECK(mAudioDecoder == NULL);
501 CHECK(mVideoDecoder == NULL);
502
503 mRenderer.clear();
504 mSource.clear();
505
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800506 if (mDriver != NULL) {
507 sp<NuPlayerDriver> driver = mDriver.promote();
508 if (driver != NULL) {
509 driver->notifyResetComplete();
510 }
511 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800512}
513
514void NuPlayer::postScanSources() {
515 if (mScanSourcesPending) {
516 return;
517 }
518
519 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
520 msg->setInt32("generation", mScanSourcesGeneration);
521 msg->post();
522
523 mScanSourcesPending = true;
524}
525
Andreas Huber5bc087c2010-12-23 10:27:40 -0800526status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800527 if (*decoder != NULL) {
528 return OK;
529 }
530
Andreas Huber5bc087c2010-12-23 10:27:40 -0800531 sp<MetaData> meta = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800532
Andreas Huber5bc087c2010-12-23 10:27:40 -0800533 if (meta == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800534 return -EWOULDBLOCK;
535 }
536
537 sp<AMessage> notify =
538 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
539 id());
540
Glenn Kasten11731182011-02-08 17:26:17 -0800541 *decoder = audio ? new Decoder(notify) :
542 new Decoder(notify, mNativeWindow);
Andreas Huberf9334412010-12-15 15:17:42 -0800543 looper()->registerHandler(*decoder);
544
Andreas Huber5bc087c2010-12-23 10:27:40 -0800545 (*decoder)->configure(meta);
Andreas Huberf9334412010-12-15 15:17:42 -0800546
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800547 int64_t durationUs;
548 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
549 sp<NuPlayerDriver> driver = mDriver.promote();
550 if (driver != NULL) {
551 driver->notifyDuration(durationUs);
552 }
553 }
554
Andreas Huberf9334412010-12-15 15:17:42 -0800555 return OK;
556}
557
558status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
559 sp<AMessage> reply;
560 CHECK(msg->findMessage("reply", &reply));
561
Andreas Huber53df1a42010-12-22 10:03:04 -0800562 if ((audio && IsFlushingState(mFlushingAudio))
563 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800564 reply->setInt32("err", INFO_DISCONTINUITY);
565 reply->post();
566 return OK;
567 }
568
569 sp<ABuffer> accessUnit;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800570 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800571
572 if (err == -EWOULDBLOCK) {
573 return err;
574 } else if (err != OK) {
575 if (err == INFO_DISCONTINUITY) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800576 int32_t type;
577 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
578
579 bool formatChange =
580 type == ATSParser::DISCONTINUITY_FORMATCHANGE;
Andreas Huber53df1a42010-12-22 10:03:04 -0800581
Andreas Huber1aef2112011-01-04 14:01:29 -0800582 LOGV("%s discontinuity (formatChange=%d)",
Andreas Huber53df1a42010-12-22 10:03:04 -0800583 audio ? "audio" : "video", formatChange);
584
Andreas Huber1aef2112011-01-04 14:01:29 -0800585 flushDecoder(audio, formatChange);
Andreas Huberf9334412010-12-15 15:17:42 -0800586 }
587
588 reply->setInt32("err", err);
589 reply->post();
590 return OK;
591 }
592
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800593 // LOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800594
595#if 0
596 int64_t mediaTimeUs;
597 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Andreas Huber1aef2112011-01-04 14:01:29 -0800598 LOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800599 audio ? "audio" : "video",
600 mediaTimeUs / 1E6);
601#endif
602
603 reply->setObject("buffer", accessUnit);
604 reply->post();
605
606 return OK;
607}
608
609void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800610 // LOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800611
612 sp<AMessage> reply;
613 CHECK(msg->findMessage("reply", &reply));
614
615 sp<RefBase> obj;
616 CHECK(msg->findObject("buffer", &obj));
617
618 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
619
620 mRenderer->queueBuffer(audio, buffer, reply);
621}
622
623void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800624 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800625 return;
626 }
627
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800628 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -0800629
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800630 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800631 return;
632 }
633
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800634 driver->sendEvent(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -0800635}
636
Andreas Huber1aef2112011-01-04 14:01:29 -0800637void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
638 // Make sure we don't continue to scan sources until we finish flushing.
639 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800640 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800641
642 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
643 mRenderer->flush(audio);
644
645 FlushStatus newStatus =
646 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
647
648 if (audio) {
649 CHECK(mFlushingAudio == NONE
650 || mFlushingAudio == AWAITING_DISCONTINUITY);
651
652 mFlushingAudio = newStatus;
653
654 if (mFlushingVideo == NONE) {
655 mFlushingVideo = (mVideoDecoder != NULL)
656 ? AWAITING_DISCONTINUITY
657 : FLUSHED;
658 }
659 } else {
660 CHECK(mFlushingVideo == NONE
661 || mFlushingVideo == AWAITING_DISCONTINUITY);
662
663 mFlushingVideo = newStatus;
664
665 if (mFlushingAudio == NONE) {
666 mFlushingAudio = (mAudioDecoder != NULL)
667 ? AWAITING_DISCONTINUITY
668 : FLUSHED;
669 }
670 }
671}
672
Andreas Huberf9334412010-12-15 15:17:42 -0800673} // namespace android