blob: 5387e1a09a59cfcefcf9502df6f5531a253e1bf8 [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"
Andreas Huber2bfdd422011-10-11 15:24:07 -070028#include "RTSPSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080029#include "StreamingSource.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070030#include "GenericSource.h"
Andreas Huber84066782011-08-16 09:34:26 -070031#include "mp4/MP4Source.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080032
33#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080034
Andreas Huber84066782011-08-16 09:34:26 -070035#include <cutils/properties.h> // for property_get
Andreas Huber3831a062010-12-21 10:22:33 -080036#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080037#include <media/stagefright/foundation/ABuffer.h>
38#include <media/stagefright/foundation/ADebug.h>
39#include <media/stagefright/foundation/AMessage.h>
40#include <media/stagefright/ACodec.h>
Andreas Huber3fe62152011-09-16 15:09:22 -070041#include <media/stagefright/MediaDefs.h>
Andreas Huberf9334412010-12-15 15:17:42 -080042#include <media/stagefright/MediaErrors.h>
43#include <media/stagefright/MetaData.h>
Andy McFadden8ba01022012-12-18 09:46:54 -080044#include <gui/IGraphicBufferProducer.h>
Andreas Huberf9334412010-12-15 15:17:42 -080045
Andreas Huber3fe62152011-09-16 15:09:22 -070046#include "avc_utils.h"
47
Andreas Huber84066782011-08-16 09:34:26 -070048#include "ESDS.h"
49#include <media/stagefright/Utils.h>
50
Andreas Huberf9334412010-12-15 15:17:42 -080051namespace android {
52
Andreas Hubera1f8ab02012-11-30 10:53:22 -080053struct NuPlayer::Action : public RefBase {
54 Action() {}
55
56 virtual void execute(NuPlayer *player) = 0;
57
58private:
59 DISALLOW_EVIL_CONSTRUCTORS(Action);
60};
61
62struct NuPlayer::SeekAction : public Action {
63 SeekAction(int64_t seekTimeUs)
64 : mSeekTimeUs(seekTimeUs) {
65 }
66
67 virtual void execute(NuPlayer *player) {
68 player->performSeek(mSeekTimeUs);
69 }
70
71private:
72 int64_t mSeekTimeUs;
73
74 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
75};
76
Andreas Huber57a339c2012-12-03 11:18:00 -080077struct NuPlayer::SetSurfaceAction : public Action {
78 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
79 : mWrapper(wrapper) {
80 }
81
82 virtual void execute(NuPlayer *player) {
83 player->performSetSurface(mWrapper);
84 }
85
86private:
87 sp<NativeWindowWrapper> mWrapper;
88
89 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
90};
91
Andreas Hubera1f8ab02012-11-30 10:53:22 -080092// Use this if there's no state necessary to save in order to execute
93// the action.
94struct NuPlayer::SimpleAction : public Action {
95 typedef void (NuPlayer::*ActionFunc)();
96
97 SimpleAction(ActionFunc func)
98 : mFunc(func) {
99 }
100
101 virtual void execute(NuPlayer *player) {
102 (player->*mFunc)();
103 }
104
105private:
106 ActionFunc mFunc;
107
108 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
109};
110
Andreas Huberf9334412010-12-15 15:17:42 -0800111////////////////////////////////////////////////////////////////////////////////
112
113NuPlayer::NuPlayer()
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700114 : mUIDValid(false),
Andreas Huber9575c962013-02-05 13:59:56 -0800115 mSourceFlags(0),
Andreas Huber3fe62152011-09-16 15:09:22 -0700116 mVideoIsAVC(false),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700117 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800118 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800119 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800120 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800121 mPollDurationGeneration(0),
Andreas Huber6e3d3112011-11-28 12:36:11 -0800122 mTimeDiscontinuityPending(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800123 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800124 mFlushingVideo(NONE),
Andreas Huber3fe62152011-09-16 15:09:22 -0700125 mSkipRenderingAudioUntilMediaTimeUs(-1ll),
126 mSkipRenderingVideoUntilMediaTimeUs(-1ll),
127 mVideoLateByUs(0ll),
128 mNumFramesTotal(0ll),
James Dong0d268a32012-08-31 12:18:27 -0700129 mNumFramesDropped(0ll),
Andreas Huber57a339c2012-12-03 11:18:00 -0800130 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
131 mStarted(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800132}
133
134NuPlayer::~NuPlayer() {
135}
136
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700137void NuPlayer::setUID(uid_t uid) {
138 mUIDValid = true;
139 mUID = uid;
140}
141
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800142void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
143 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800144}
145
Andreas Huber9575c962013-02-05 13:59:56 -0800146void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Andreas Huberf9334412010-12-15 15:17:42 -0800147 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
148
Andreas Huberb5f25f02013-02-05 10:14:26 -0800149 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
150
Andreas Huber84066782011-08-16 09:34:26 -0700151 char prop[PROPERTY_VALUE_MAX];
152 if (property_get("media.stagefright.use-mp4source", prop, NULL)
153 && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800154 msg->setObject("source", new MP4Source(notify, source));
Andreas Huber84066782011-08-16 09:34:26 -0700155 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800156 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber84066782011-08-16 09:34:26 -0700157 }
158
Andreas Huber5bc087c2010-12-23 10:27:40 -0800159 msg->post();
160}
Andreas Huberf9334412010-12-15 15:17:42 -0800161
Andreas Huberafed0e12011-09-20 15:39:58 -0700162static bool IsHTTPLiveURL(const char *url) {
163 if (!strncasecmp("http://", url, 7)
164 || !strncasecmp("https://", url, 8)) {
165 size_t len = strlen(url);
166 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
167 return true;
168 }
169
170 if (strstr(url,"m3u8")) {
171 return true;
172 }
173 }
174
175 return false;
176}
177
Andreas Huber9575c962013-02-05 13:59:56 -0800178void NuPlayer::setDataSourceAsync(
Andreas Huber5bc087c2010-12-23 10:27:40 -0800179 const char *url, const KeyedVector<String8, String8> *headers) {
180 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100181 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800182
Andreas Huberb5f25f02013-02-05 10:14:26 -0800183 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
184
Andreas Huberafed0e12011-09-20 15:39:58 -0700185 sp<Source> source;
186 if (IsHTTPLiveURL(url)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800187 source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
Andreas Huberafed0e12011-09-20 15:39:58 -0700188 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800189 source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100190 } else if ((!strncasecmp(url, "http://", 7)
191 || !strncasecmp(url, "https://", 8))
192 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
193 || strstr(url, ".sdp?"))) {
194 source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700195 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800196 source = new GenericSource(notify, url, headers, mUIDValid, mUID);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700197 }
198
Andreas Huberafed0e12011-09-20 15:39:58 -0700199 msg->setObject("source", source);
200 msg->post();
201}
202
Andreas Huber9575c962013-02-05 13:59:56 -0800203void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700204 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
205
Andreas Huberb5f25f02013-02-05 10:14:26 -0800206 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
207
208 sp<Source> source = new GenericSource(notify, fd, offset, length);
Andreas Huberafed0e12011-09-20 15:39:58 -0700209 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800210 msg->post();
211}
212
Andreas Huber9575c962013-02-05 13:59:56 -0800213void NuPlayer::prepareAsync() {
214 (new AMessage(kWhatPrepare, id()))->post();
215}
216
Andreas Huber57a339c2012-12-03 11:18:00 -0800217void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800218 const sp<IGraphicBufferProducer> &bufferProducer) {
Glenn Kasten11731182011-02-08 17:26:17 -0800219 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
Andreas Huber57a339c2012-12-03 11:18:00 -0800220
Andy McFadden8ba01022012-12-18 09:46:54 -0800221 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800222 msg->setObject("native-window", NULL);
223 } else {
224 msg->setObject(
225 "native-window",
226 new NativeWindowWrapper(
Mathias Agopian1a2952a2013-02-14 17:11:27 -0800227 new Surface(bufferProducer)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800228 }
229
Andreas Huberf9334412010-12-15 15:17:42 -0800230 msg->post();
231}
232
233void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
234 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
235 msg->setObject("sink", sink);
236 msg->post();
237}
238
239void NuPlayer::start() {
240 (new AMessage(kWhatStart, id()))->post();
241}
242
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800243void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800244 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800245}
246
247void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800248 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800249}
250
Andreas Huber1aef2112011-01-04 14:01:29 -0800251void NuPlayer::resetAsync() {
252 (new AMessage(kWhatReset, id()))->post();
253}
254
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800255void NuPlayer::seekToAsync(int64_t seekTimeUs) {
256 sp<AMessage> msg = new AMessage(kWhatSeek, id());
257 msg->setInt64("seekTimeUs", seekTimeUs);
258 msg->post();
259}
260
Andreas Huber53df1a42010-12-22 10:03:04 -0800261// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800262bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800263 switch (state) {
264 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800265 if (needShutdown != NULL) {
266 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800267 }
268 return true;
269
Andreas Huber1aef2112011-01-04 14:01:29 -0800270 case FLUSHING_DECODER_SHUTDOWN:
271 if (needShutdown != NULL) {
272 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800273 }
274 return true;
275
276 default:
277 return false;
278 }
279}
280
Andreas Huberf9334412010-12-15 15:17:42 -0800281void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
282 switch (msg->what()) {
283 case kWhatSetDataSource:
284 {
Steve Block3856b092011-10-20 11:56:00 +0100285 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800286
287 CHECK(mSource == NULL);
288
Andreas Huber5bc087c2010-12-23 10:27:40 -0800289 sp<RefBase> obj;
290 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800291
Andreas Huber5bc087c2010-12-23 10:27:40 -0800292 mSource = static_cast<Source *>(obj.get());
Andreas Huberb5f25f02013-02-05 10:14:26 -0800293
294 looper()->registerHandler(mSource);
Andreas Huber9575c962013-02-05 13:59:56 -0800295
296 CHECK(mDriver != NULL);
297 sp<NuPlayerDriver> driver = mDriver.promote();
298 if (driver != NULL) {
299 driver->notifySetDataSourceCompleted(OK);
300 }
301 break;
302 }
303
304 case kWhatPrepare:
305 {
306 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800307 break;
308 }
309
Andreas Huberb7c8e912012-11-27 15:02:53 -0800310 case kWhatPollDuration:
311 {
312 int32_t generation;
313 CHECK(msg->findInt32("generation", &generation));
314
315 if (generation != mPollDurationGeneration) {
316 // stale
317 break;
318 }
319
320 int64_t durationUs;
321 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
322 sp<NuPlayerDriver> driver = mDriver.promote();
323 if (driver != NULL) {
324 driver->notifyDuration(durationUs);
325 }
326 }
327
328 msg->post(1000000ll); // poll again in a second.
329 break;
330 }
331
Glenn Kasten11731182011-02-08 17:26:17 -0800332 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800333 {
Steve Block3856b092011-10-20 11:56:00 +0100334 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800335
Andreas Huber57a339c2012-12-03 11:18:00 -0800336 mDeferredActions.push_back(
337 new SimpleAction(&NuPlayer::performDecoderShutdown));
338
Andreas Huberf9334412010-12-15 15:17:42 -0800339 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800340 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800341
Andreas Huber57a339c2012-12-03 11:18:00 -0800342 mDeferredActions.push_back(
343 new SetSurfaceAction(
344 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700345
Andreas Huber57a339c2012-12-03 11:18:00 -0800346 if (obj != NULL) {
347 // If there is a new surface texture, instantiate decoders
348 // again if possible.
349 mDeferredActions.push_back(
350 new SimpleAction(&NuPlayer::performScanSources));
351 }
352
353 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800354 break;
355 }
356
357 case kWhatSetAudioSink:
358 {
Steve Block3856b092011-10-20 11:56:00 +0100359 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800360
361 sp<RefBase> obj;
362 CHECK(msg->findObject("sink", &obj));
363
364 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
365 break;
366 }
367
368 case kWhatStart:
369 {
Steve Block3856b092011-10-20 11:56:00 +0100370 ALOGV("kWhatStart");
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800371
Andreas Huber3fe62152011-09-16 15:09:22 -0700372 mVideoIsAVC = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800373 mAudioEOS = false;
374 mVideoEOS = false;
Andreas Huber32f3cef2011-03-02 15:34:46 -0800375 mSkipRenderingAudioUntilMediaTimeUs = -1;
376 mSkipRenderingVideoUntilMediaTimeUs = -1;
Andreas Huber3fe62152011-09-16 15:09:22 -0700377 mVideoLateByUs = 0;
378 mNumFramesTotal = 0;
379 mNumFramesDropped = 0;
Andreas Huber57a339c2012-12-03 11:18:00 -0800380 mStarted = true;
Andreas Huber1aef2112011-01-04 14:01:29 -0800381
Andreas Huber5bc087c2010-12-23 10:27:40 -0800382 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800383
Andreas Huberd5e56232013-03-12 11:01:43 -0700384 uint32_t flags = 0;
385
386 if (mSource->isRealTime()) {
387 flags |= Renderer::FLAG_REAL_TIME;
388 }
389
Andreas Huberf9334412010-12-15 15:17:42 -0800390 mRenderer = new Renderer(
391 mAudioSink,
Andreas Huberd5e56232013-03-12 11:01:43 -0700392 new AMessage(kWhatRendererNotify, id()),
393 flags);
Andreas Huberf9334412010-12-15 15:17:42 -0800394
395 looper()->registerHandler(mRenderer);
396
Andreas Huber1aef2112011-01-04 14:01:29 -0800397 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800398 break;
399 }
400
401 case kWhatScanSources:
402 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800403 int32_t generation;
404 CHECK(msg->findInt32("generation", &generation));
405 if (generation != mScanSourcesGeneration) {
406 // Drop obsolete msg.
407 break;
408 }
409
Andreas Huber5bc087c2010-12-23 10:27:40 -0800410 mScanSourcesPending = false;
411
Steve Block3856b092011-10-20 11:56:00 +0100412 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800413 mAudioDecoder != NULL, mVideoDecoder != NULL);
414
Andreas Huberb7c8e912012-11-27 15:02:53 -0800415 bool mHadAnySourcesBefore =
416 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
417
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700418 if (mNativeWindow != NULL) {
419 instantiateDecoder(false, &mVideoDecoder);
420 }
Andreas Huberf9334412010-12-15 15:17:42 -0800421
422 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800423 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800424 }
425
Andreas Huberb7c8e912012-11-27 15:02:53 -0800426 if (!mHadAnySourcesBefore
427 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
428 // This is the first time we've found anything playable.
429
Andreas Huber9575c962013-02-05 13:59:56 -0800430 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800431 schedulePollDuration();
432 }
433 }
434
Andreas Hubereac68ba2011-09-27 12:12:25 -0700435 status_t err;
436 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800437 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
438 // We're not currently decoding anything (no audio or
439 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700440
441 if (err == ERROR_END_OF_STREAM) {
442 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
443 } else {
444 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
445 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800446 }
Andreas Huberf9334412010-12-15 15:17:42 -0800447 break;
448 }
449
Andreas Huberfbe9d812012-08-31 14:05:27 -0700450 if ((mAudioDecoder == NULL && mAudioSink != NULL)
451 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800452 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800453 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800454 }
455 break;
456 }
457
458 case kWhatVideoNotify:
459 case kWhatAudioNotify:
460 {
461 bool audio = msg->what() == kWhatAudioNotify;
462
463 sp<AMessage> codecRequest;
464 CHECK(msg->findMessage("codec-request", &codecRequest));
465
466 int32_t what;
467 CHECK(codecRequest->findInt32("what", &what));
468
469 if (what == ACodec::kWhatFillThisBuffer) {
470 status_t err = feedDecoderInputData(
471 audio, codecRequest);
472
Andreas Huber5bc087c2010-12-23 10:27:40 -0800473 if (err == -EWOULDBLOCK) {
Andreas Hubereac68ba2011-09-27 12:12:25 -0700474 if (mSource->feedMoreTSData() == OK) {
Andreas Huber1183a4a2011-11-03 11:00:21 -0700475 msg->post(10000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800476 }
Andreas Huberf9334412010-12-15 15:17:42 -0800477 }
478 } else if (what == ACodec::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700479 int32_t err;
480 CHECK(codecRequest->findInt32("err", &err));
481
482 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100483 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700484 } else {
Steve Block3856b092011-10-20 11:56:00 +0100485 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700486 audio ? "audio" : "video",
487 err);
488 }
489
490 mRenderer->queueEOS(audio, err);
Andreas Huberf9334412010-12-15 15:17:42 -0800491 } else if (what == ACodec::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800492 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800493
Andreas Huberf9334412010-12-15 15:17:42 -0800494 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800495 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800496 mFlushingAudio = FLUSHED;
497 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800498 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800499 mFlushingVideo = FLUSHED;
Andreas Huber3fe62152011-09-16 15:09:22 -0700500
501 mVideoLateByUs = 0;
Andreas Huberf9334412010-12-15 15:17:42 -0800502 }
503
Steve Block3856b092011-10-20 11:56:00 +0100504 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800505
Andreas Huber1aef2112011-01-04 14:01:29 -0800506 if (needShutdown) {
Steve Block3856b092011-10-20 11:56:00 +0100507 ALOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800508 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800509
Andreas Huber53df1a42010-12-22 10:03:04 -0800510 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800511
Andreas Huber53df1a42010-12-22 10:03:04 -0800512 if (audio) {
513 mFlushingAudio = SHUTTING_DOWN_DECODER;
514 } else {
515 mFlushingVideo = SHUTTING_DOWN_DECODER;
516 }
Andreas Huberf9334412010-12-15 15:17:42 -0800517 }
Andreas Huber3831a062010-12-21 10:22:33 -0800518
519 finishFlushIfPossible();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800520 } else if (what == ACodec::kWhatOutputFormatChanged) {
Andreas Huber31e25082011-01-10 10:38:31 -0800521 if (audio) {
522 int32_t numChannels;
Andreas Huber516dacf2012-12-03 15:20:40 -0800523 CHECK(codecRequest->findInt32(
524 "channel-count", &numChannels));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800525
Andreas Huber31e25082011-01-10 10:38:31 -0800526 int32_t sampleRate;
527 CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800528
Steve Block3856b092011-10-20 11:56:00 +0100529 ALOGV("Audio output format changed to %d Hz, %d channels",
Andreas Huber31e25082011-01-10 10:38:31 -0800530 sampleRate, numChannels);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800531
Andreas Huber31e25082011-01-10 10:38:31 -0800532 mAudioSink->close();
Eric Laurent1948eb32012-04-13 16:50:19 -0700533
534 audio_output_flags_t flags;
535 int64_t durationUs;
Andreas Huber516dacf2012-12-03 15:20:40 -0800536 // FIXME: we should handle the case where the video decoder
537 // is created after we receive the format change indication.
538 // Current code will just make that we select deep buffer
539 // with video which should not be a problem as it should
Eric Laurent1948eb32012-04-13 16:50:19 -0700540 // not prevent from keeping A/V sync.
541 if (mVideoDecoder == NULL &&
542 mSource->getDuration(&durationUs) == OK &&
Andreas Huber516dacf2012-12-03 15:20:40 -0800543 durationUs
544 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
Eric Laurent1948eb32012-04-13 16:50:19 -0700545 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
546 } else {
547 flags = AUDIO_OUTPUT_FLAG_NONE;
548 }
549
Andreas Huber98065552012-05-03 11:33:01 -0700550 int32_t channelMask;
551 if (!codecRequest->findInt32("channel-mask", &channelMask)) {
552 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
553 }
554
Andreas Huber078cfcf2011-09-15 12:25:04 -0700555 CHECK_EQ(mAudioSink->open(
556 sampleRate,
557 numChannels,
Andreas Huber98065552012-05-03 11:33:01 -0700558 (audio_channel_mask_t)channelMask,
Andreas Huber078cfcf2011-09-15 12:25:04 -0700559 AUDIO_FORMAT_PCM_16_BIT,
Eric Laurent1948eb32012-04-13 16:50:19 -0700560 8 /* bufferCount */,
561 NULL,
562 NULL,
563 flags),
Andreas Huber078cfcf2011-09-15 12:25:04 -0700564 (status_t)OK);
Andreas Huber31e25082011-01-10 10:38:31 -0800565 mAudioSink->start();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800566
Andreas Huber31e25082011-01-10 10:38:31 -0800567 mRenderer->signalAudioSinkChanged();
568 } else {
569 // video
Andreas Huber3831a062010-12-21 10:22:33 -0800570
Andreas Huber31e25082011-01-10 10:38:31 -0800571 int32_t width, height;
572 CHECK(codecRequest->findInt32("width", &width));
573 CHECK(codecRequest->findInt32("height", &height));
574
575 int32_t cropLeft, cropTop, cropRight, cropBottom;
576 CHECK(codecRequest->findRect(
577 "crop",
578 &cropLeft, &cropTop, &cropRight, &cropBottom));
579
Andreas Huber516dacf2012-12-03 15:20:40 -0800580 int32_t displayWidth = cropRight - cropLeft + 1;
581 int32_t displayHeight = cropBottom - cropTop + 1;
582
Steve Block3856b092011-10-20 11:56:00 +0100583 ALOGV("Video output format changed to %d x %d "
Andreas Hubercb67cd12011-08-26 16:02:19 -0700584 "(crop: %d x %d @ (%d, %d))",
Andreas Huber31e25082011-01-10 10:38:31 -0800585 width, height,
Andreas Huber516dacf2012-12-03 15:20:40 -0800586 displayWidth,
587 displayHeight,
Andreas Hubercb67cd12011-08-26 16:02:19 -0700588 cropLeft, cropTop);
Andreas Huber31e25082011-01-10 10:38:31 -0800589
Andreas Huber516dacf2012-12-03 15:20:40 -0800590 sp<AMessage> videoInputFormat =
591 mSource->getFormat(false /* audio */);
592
593 // Take into account sample aspect ratio if necessary:
594 int32_t sarWidth, sarHeight;
595 if (videoInputFormat->findInt32("sar-width", &sarWidth)
596 && videoInputFormat->findInt32(
597 "sar-height", &sarHeight)) {
598 ALOGV("Sample aspect ratio %d : %d",
599 sarWidth, sarHeight);
600
601 displayWidth = (displayWidth * sarWidth) / sarHeight;
602
603 ALOGV("display dimensions %d x %d",
604 displayWidth, displayHeight);
605 }
606
Andreas Huber31e25082011-01-10 10:38:31 -0800607 notifyListener(
Andreas Huber516dacf2012-12-03 15:20:40 -0800608 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
Andreas Huber31e25082011-01-10 10:38:31 -0800609 }
Andreas Huber3831a062010-12-21 10:22:33 -0800610 } else if (what == ACodec::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100611 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800612 if (audio) {
613 mAudioDecoder.clear();
614
615 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
616 mFlushingAudio = SHUT_DOWN;
617 } else {
618 mVideoDecoder.clear();
619
620 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
621 mFlushingVideo = SHUT_DOWN;
622 }
623
624 finishFlushIfPossible();
Andreas Huberc92fd242011-08-16 13:48:44 -0700625 } else if (what == ACodec::kWhatError) {
Steve Block29357bc2012-01-06 19:20:56 +0000626 ALOGE("Received error from %s decoder, aborting playback.",
Andreas Huberc92fd242011-08-16 13:48:44 -0700627 audio ? "audio" : "video");
628
629 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
Andreas Huber57788222012-02-21 11:47:18 -0800630 } else if (what == ACodec::kWhatDrainThisBuffer) {
Andreas Huberf9334412010-12-15 15:17:42 -0800631 renderBuffer(audio, codecRequest);
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800632 } else if (what != ACodec::kWhatComponentAllocated
633 && what != ACodec::kWhatComponentConfigured
634 && what != ACodec::kWhatBuffersAllocated) {
635 ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
636 what,
637 what >> 24,
638 (what >> 16) & 0xff,
639 (what >> 8) & 0xff,
640 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800641 }
642
643 break;
644 }
645
646 case kWhatRendererNotify:
647 {
648 int32_t what;
649 CHECK(msg->findInt32("what", &what));
650
651 if (what == Renderer::kWhatEOS) {
652 int32_t audio;
653 CHECK(msg->findInt32("audio", &audio));
654
Andreas Huberc92fd242011-08-16 13:48:44 -0700655 int32_t finalResult;
656 CHECK(msg->findInt32("finalResult", &finalResult));
657
Andreas Huberf9334412010-12-15 15:17:42 -0800658 if (audio) {
659 mAudioEOS = true;
660 } else {
661 mVideoEOS = true;
662 }
663
Andreas Huberc92fd242011-08-16 13:48:44 -0700664 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100665 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700666 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000667 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700668 audio ? "audio" : "video", finalResult);
669
670 notifyListener(
671 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
672 }
Andreas Huberf9334412010-12-15 15:17:42 -0800673
674 if ((mAudioEOS || mAudioDecoder == NULL)
675 && (mVideoEOS || mVideoDecoder == NULL)) {
676 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
677 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800678 } else if (what == Renderer::kWhatPosition) {
679 int64_t positionUs;
680 CHECK(msg->findInt64("positionUs", &positionUs));
681
Andreas Huber3fe62152011-09-16 15:09:22 -0700682 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
683
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800684 if (mDriver != NULL) {
685 sp<NuPlayerDriver> driver = mDriver.promote();
686 if (driver != NULL) {
687 driver->notifyPosition(positionUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700688
689 driver->notifyFrameStats(
690 mNumFramesTotal, mNumFramesDropped);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800691 }
692 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700693 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800694 int32_t audio;
695 CHECK(msg->findInt32("audio", &audio));
696
Steve Block3856b092011-10-20 11:56:00 +0100697 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
James Dongf57b4ea2012-07-20 13:38:36 -0700698 } else if (what == Renderer::kWhatVideoRenderingStart) {
699 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Andreas Huberf9334412010-12-15 15:17:42 -0800700 }
701 break;
702 }
703
704 case kWhatMoreDataQueued:
705 {
706 break;
707 }
708
Andreas Huber1aef2112011-01-04 14:01:29 -0800709 case kWhatReset:
710 {
Steve Block3856b092011-10-20 11:56:00 +0100711 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800712
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800713 mDeferredActions.push_back(
714 new SimpleAction(&NuPlayer::performDecoderShutdown));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800715
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800716 mDeferredActions.push_back(
717 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800718
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800719 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800720 break;
721 }
722
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800723 case kWhatSeek:
724 {
725 int64_t seekTimeUs;
726 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
727
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800728 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800729
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800730 mDeferredActions.push_back(
731 new SimpleAction(&NuPlayer::performDecoderFlush));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800732
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800733 mDeferredActions.push_back(new SeekAction(seekTimeUs));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800734
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800735 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800736 break;
737 }
738
Andreas Huberb4082222011-01-20 15:23:04 -0800739 case kWhatPause:
740 {
741 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +0100742 mSource->pause();
Andreas Huberb4082222011-01-20 15:23:04 -0800743 mRenderer->pause();
744 break;
745 }
746
747 case kWhatResume:
748 {
749 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +0100750 mSource->resume();
Andreas Huberb4082222011-01-20 15:23:04 -0800751 mRenderer->resume();
752 break;
753 }
754
Andreas Huberb5f25f02013-02-05 10:14:26 -0800755 case kWhatSourceNotify:
756 {
Andreas Huber9575c962013-02-05 13:59:56 -0800757 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800758 break;
759 }
760
Andreas Huberf9334412010-12-15 15:17:42 -0800761 default:
762 TRESPASS();
763 break;
764 }
765}
766
Andreas Huber3831a062010-12-21 10:22:33 -0800767void NuPlayer::finishFlushIfPossible() {
768 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
769 return;
770 }
771
772 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
773 return;
774 }
775
Steve Block3856b092011-10-20 11:56:00 +0100776 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800777
Andreas Huber6e3d3112011-11-28 12:36:11 -0800778 if (mTimeDiscontinuityPending) {
779 mRenderer->signalTimeDiscontinuity();
780 mTimeDiscontinuityPending = false;
781 }
Andreas Huber3831a062010-12-21 10:22:33 -0800782
Andreas Huber22fc52f2011-01-05 16:24:27 -0800783 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800784 mAudioDecoder->signalResume();
785 }
786
Andreas Huber22fc52f2011-01-05 16:24:27 -0800787 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800788 mVideoDecoder->signalResume();
789 }
790
791 mFlushingAudio = NONE;
792 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800793
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800794 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800795}
796
797void NuPlayer::postScanSources() {
798 if (mScanSourcesPending) {
799 return;
800 }
801
802 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
803 msg->setInt32("generation", mScanSourcesGeneration);
804 msg->post();
805
806 mScanSourcesPending = true;
807}
808
Andreas Huber5bc087c2010-12-23 10:27:40 -0800809status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800810 if (*decoder != NULL) {
811 return OK;
812 }
813
Andreas Huber84066782011-08-16 09:34:26 -0700814 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800815
Andreas Huber84066782011-08-16 09:34:26 -0700816 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800817 return -EWOULDBLOCK;
818 }
819
Andreas Huber3fe62152011-09-16 15:09:22 -0700820 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -0700821 AString mime;
822 CHECK(format->findString("mime", &mime));
823 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Andreas Huber3fe62152011-09-16 15:09:22 -0700824 }
825
Andreas Huberf9334412010-12-15 15:17:42 -0800826 sp<AMessage> notify =
827 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
828 id());
829
Glenn Kasten11731182011-02-08 17:26:17 -0800830 *decoder = audio ? new Decoder(notify) :
831 new Decoder(notify, mNativeWindow);
Andreas Huberf9334412010-12-15 15:17:42 -0800832 looper()->registerHandler(*decoder);
833
Andreas Huber84066782011-08-16 09:34:26 -0700834 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -0800835
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800836 int64_t durationUs;
837 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
838 sp<NuPlayerDriver> driver = mDriver.promote();
839 if (driver != NULL) {
840 driver->notifyDuration(durationUs);
841 }
842 }
843
Andreas Huberf9334412010-12-15 15:17:42 -0800844 return OK;
845}
846
847status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
848 sp<AMessage> reply;
849 CHECK(msg->findMessage("reply", &reply));
850
Andreas Huber53df1a42010-12-22 10:03:04 -0800851 if ((audio && IsFlushingState(mFlushingAudio))
852 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800853 reply->setInt32("err", INFO_DISCONTINUITY);
854 reply->post();
855 return OK;
856 }
857
858 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -0800859
Andreas Huber3fe62152011-09-16 15:09:22 -0700860 bool dropAccessUnit;
861 do {
862 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800863
Andreas Huber3fe62152011-09-16 15:09:22 -0700864 if (err == -EWOULDBLOCK) {
865 return err;
866 } else if (err != OK) {
867 if (err == INFO_DISCONTINUITY) {
868 int32_t type;
869 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -0800870
Andreas Huber3fe62152011-09-16 15:09:22 -0700871 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -0800872 (audio &&
873 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
874 || (!audio &&
875 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -0800876
Andreas Huber6e3d3112011-11-28 12:36:11 -0800877 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
878
Steve Blockdf64d152012-01-04 20:05:49 +0000879 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800880 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -0800881
Andreas Huber3fe62152011-09-16 15:09:22 -0700882 if (audio) {
883 mSkipRenderingAudioUntilMediaTimeUs = -1;
884 } else {
885 mSkipRenderingVideoUntilMediaTimeUs = -1;
886 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800887
Andreas Huber6e3d3112011-11-28 12:36:11 -0800888 if (timeChange) {
889 sp<AMessage> extra;
890 if (accessUnit->meta()->findMessage("extra", &extra)
891 && extra != NULL) {
892 int64_t resumeAtMediaTimeUs;
893 if (extra->findInt64(
894 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +0000895 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800896 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700897
Andreas Huber6e3d3112011-11-28 12:36:11 -0800898 if (audio) {
899 mSkipRenderingAudioUntilMediaTimeUs =
900 resumeAtMediaTimeUs;
901 } else {
902 mSkipRenderingVideoUntilMediaTimeUs =
903 resumeAtMediaTimeUs;
904 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700905 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800906 }
907 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700908
Andreas Huber6e3d3112011-11-28 12:36:11 -0800909 mTimeDiscontinuityPending =
910 mTimeDiscontinuityPending || timeChange;
911
912 if (formatChange || timeChange) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800913 if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
914 // And we'll resume scanning sources once we're done
915 // flushing.
916 mDeferredActions.push_front(
917 new SimpleAction(
918 &NuPlayer::performScanSources));
919 }
920
Andreas Huber6e3d3112011-11-28 12:36:11 -0800921 flushDecoder(audio, formatChange);
922 } else {
923 // This stream is unaffected by the discontinuity
924
925 if (audio) {
926 mFlushingAudio = FLUSHED;
927 } else {
928 mFlushingVideo = FLUSHED;
929 }
930
931 finishFlushIfPossible();
932
933 return -EWOULDBLOCK;
934 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800935 }
936
Andreas Huber3fe62152011-09-16 15:09:22 -0700937 reply->setInt32("err", err);
938 reply->post();
939 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800940 }
941
Andreas Huber3fe62152011-09-16 15:09:22 -0700942 if (!audio) {
943 ++mNumFramesTotal;
944 }
945
946 dropAccessUnit = false;
947 if (!audio
948 && mVideoLateByUs > 100000ll
949 && mVideoIsAVC
950 && !IsAVCReferenceFrame(accessUnit)) {
951 dropAccessUnit = true;
952 ++mNumFramesDropped;
953 }
954 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800955
Steve Block3856b092011-10-20 11:56:00 +0100956 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800957
958#if 0
959 int64_t mediaTimeUs;
960 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +0100961 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800962 audio ? "audio" : "video",
963 mediaTimeUs / 1E6);
964#endif
965
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800966 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800967 reply->post();
968
969 return OK;
970}
971
972void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +0100973 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800974
975 sp<AMessage> reply;
976 CHECK(msg->findMessage("reply", &reply));
977
Andreas Huber18ac5402011-08-31 15:04:25 -0700978 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
979 // We're currently attempting to flush the decoder, in order
980 // to complete this, the decoder wants all its buffers back,
981 // so we don't want any output buffers it sent us (from before
982 // we initiated the flush) to be stuck in the renderer's queue.
983
Steve Block3856b092011-10-20 11:56:00 +0100984 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -0700985 " right back.", audio ? "audio" : "video");
986
987 reply->post();
988 return;
989 }
990
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800991 sp<ABuffer> buffer;
992 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -0800993
Andreas Huber32f3cef2011-03-02 15:34:46 -0800994 int64_t &skipUntilMediaTimeUs =
995 audio
996 ? mSkipRenderingAudioUntilMediaTimeUs
997 : mSkipRenderingVideoUntilMediaTimeUs;
998
999 if (skipUntilMediaTimeUs >= 0) {
1000 int64_t mediaTimeUs;
1001 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1002
1003 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +01001004 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -08001005 audio ? "audio" : "video",
1006 mediaTimeUs);
1007
1008 reply->post();
1009 return;
1010 }
1011
1012 skipUntilMediaTimeUs = -1;
1013 }
1014
Andreas Huberf9334412010-12-15 15:17:42 -08001015 mRenderer->queueBuffer(audio, buffer, reply);
1016}
1017
1018void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001019 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001020 return;
1021 }
1022
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001023 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001024
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001025 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001026 return;
1027 }
1028
Andreas Hubera4af2142011-10-26 15:23:31 -07001029 driver->notifyListener(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -08001030}
1031
Andreas Huber1aef2112011-01-04 14:01:29 -08001032void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001033 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001034 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001035 audio ? "audio" : "video");
1036 }
1037
Andreas Huber1aef2112011-01-04 14:01:29 -08001038 // Make sure we don't continue to scan sources until we finish flushing.
1039 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001040 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001041
1042 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1043 mRenderer->flush(audio);
1044
1045 FlushStatus newStatus =
1046 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1047
1048 if (audio) {
1049 CHECK(mFlushingAudio == NONE
1050 || mFlushingAudio == AWAITING_DISCONTINUITY);
1051
1052 mFlushingAudio = newStatus;
1053
1054 if (mFlushingVideo == NONE) {
1055 mFlushingVideo = (mVideoDecoder != NULL)
1056 ? AWAITING_DISCONTINUITY
1057 : FLUSHED;
1058 }
1059 } else {
1060 CHECK(mFlushingVideo == NONE
1061 || mFlushingVideo == AWAITING_DISCONTINUITY);
1062
1063 mFlushingVideo = newStatus;
1064
1065 if (mFlushingAudio == NONE) {
1066 mFlushingAudio = (mAudioDecoder != NULL)
1067 ? AWAITING_DISCONTINUITY
1068 : FLUSHED;
1069 }
1070 }
1071}
1072
Andreas Huber84066782011-08-16 09:34:26 -07001073sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1074 sp<MetaData> meta = getFormatMeta(audio);
1075
1076 if (meta == NULL) {
1077 return NULL;
1078 }
1079
1080 sp<AMessage> msg = new AMessage;
1081
1082 if(convertMetaDataToMessage(meta, &msg) == OK) {
1083 return msg;
1084 }
1085 return NULL;
1086}
1087
James Dong0d268a32012-08-31 12:18:27 -07001088status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1089 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001090 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001091 status_t ret = native_window_set_scaling_mode(
1092 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1093 if (ret != OK) {
1094 ALOGE("Failed to set scaling mode (%d): %s",
1095 -ret, strerror(-ret));
1096 return ret;
1097 }
1098 }
1099 return OK;
1100}
1101
Andreas Huberb7c8e912012-11-27 15:02:53 -08001102void NuPlayer::schedulePollDuration() {
1103 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1104 msg->setInt32("generation", mPollDurationGeneration);
1105 msg->post();
1106}
1107
1108void NuPlayer::cancelPollDuration() {
1109 ++mPollDurationGeneration;
1110}
1111
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001112void NuPlayer::processDeferredActions() {
1113 while (!mDeferredActions.empty()) {
1114 // We won't execute any deferred actions until we're no longer in
1115 // an intermediate state, i.e. one more more decoders are currently
1116 // flushing or shutting down.
1117
1118 if (mRenderer != NULL) {
1119 // There's an edge case where the renderer owns all output
1120 // buffers and is paused, therefore the decoder will not read
1121 // more input data and will never encounter the matching
1122 // discontinuity. To avoid this, we resume the renderer.
1123
1124 if (mFlushingAudio == AWAITING_DISCONTINUITY
1125 || mFlushingVideo == AWAITING_DISCONTINUITY) {
1126 mRenderer->resume();
1127 }
1128 }
1129
1130 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1131 // We're currently flushing, postpone the reset until that's
1132 // completed.
1133
1134 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1135 mFlushingAudio, mFlushingVideo);
1136
1137 break;
1138 }
1139
1140 sp<Action> action = *mDeferredActions.begin();
1141 mDeferredActions.erase(mDeferredActions.begin());
1142
1143 action->execute(this);
1144 }
1145}
1146
1147void NuPlayer::performSeek(int64_t seekTimeUs) {
1148 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1149 seekTimeUs,
1150 seekTimeUs / 1E6);
1151
1152 mSource->seekTo(seekTimeUs);
1153
1154 if (mDriver != NULL) {
1155 sp<NuPlayerDriver> driver = mDriver.promote();
1156 if (driver != NULL) {
1157 driver->notifyPosition(seekTimeUs);
1158 driver->notifySeekComplete();
1159 }
1160 }
1161
1162 // everything's flushed, continue playback.
1163}
1164
1165void NuPlayer::performDecoderFlush() {
1166 ALOGV("performDecoderFlush");
1167
1168 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1169 return;
1170 }
1171
1172 mTimeDiscontinuityPending = true;
1173
1174 if (mAudioDecoder != NULL) {
1175 flushDecoder(true /* audio */, false /* needShutdown */);
1176 }
1177
1178 if (mVideoDecoder != NULL) {
1179 flushDecoder(false /* audio */, false /* needShutdown */);
1180 }
1181}
1182
1183void NuPlayer::performDecoderShutdown() {
1184 ALOGV("performDecoderShutdown");
1185
1186 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1187 return;
1188 }
1189
1190 mTimeDiscontinuityPending = true;
1191
1192 if (mAudioDecoder != NULL) {
1193 flushDecoder(true /* audio */, true /* needShutdown */);
1194 }
1195
1196 if (mVideoDecoder != NULL) {
1197 flushDecoder(false /* audio */, true /* needShutdown */);
1198 }
1199}
1200
1201void NuPlayer::performReset() {
1202 ALOGV("performReset");
1203
1204 CHECK(mAudioDecoder == NULL);
1205 CHECK(mVideoDecoder == NULL);
1206
1207 cancelPollDuration();
1208
1209 ++mScanSourcesGeneration;
1210 mScanSourcesPending = false;
1211
1212 mRenderer.clear();
1213
1214 if (mSource != NULL) {
1215 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001216
1217 looper()->unregisterHandler(mSource->id());
1218
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001219 mSource.clear();
1220 }
1221
1222 if (mDriver != NULL) {
1223 sp<NuPlayerDriver> driver = mDriver.promote();
1224 if (driver != NULL) {
1225 driver->notifyResetComplete();
1226 }
1227 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001228
1229 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001230}
1231
1232void NuPlayer::performScanSources() {
1233 ALOGV("performScanSources");
1234
Andreas Huber57a339c2012-12-03 11:18:00 -08001235 if (!mStarted) {
1236 return;
1237 }
1238
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001239 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1240 postScanSources();
1241 }
1242}
1243
Andreas Huber57a339c2012-12-03 11:18:00 -08001244void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1245 ALOGV("performSetSurface");
1246
1247 mNativeWindow = wrapper;
1248
1249 // XXX - ignore error from setVideoScalingMode for now
1250 setVideoScalingMode(mVideoScalingMode);
1251
1252 if (mDriver != NULL) {
1253 sp<NuPlayerDriver> driver = mDriver.promote();
1254 if (driver != NULL) {
1255 driver->notifySetSurfaceComplete();
1256 }
1257 }
1258}
1259
Andreas Huber9575c962013-02-05 13:59:56 -08001260void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1261 int32_t what;
1262 CHECK(msg->findInt32("what", &what));
1263
1264 switch (what) {
1265 case Source::kWhatPrepared:
1266 {
Andreas Huberec0c5972013-02-05 14:47:13 -08001267 int32_t err;
1268 CHECK(msg->findInt32("err", &err));
1269
Andreas Huber9575c962013-02-05 13:59:56 -08001270 sp<NuPlayerDriver> driver = mDriver.promote();
1271 if (driver != NULL) {
Andreas Huberec0c5972013-02-05 14:47:13 -08001272 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08001273 }
1274 break;
1275 }
1276
1277 case Source::kWhatFlagsChanged:
1278 {
1279 uint32_t flags;
1280 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1281
1282 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1283 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1284 cancelPollDuration();
1285 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1286 && (flags & Source::FLAG_DYNAMIC_DURATION)
1287 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1288 schedulePollDuration();
1289 }
1290
1291 mSourceFlags = flags;
1292 break;
1293 }
1294
1295 case Source::kWhatVideoSizeChanged:
1296 {
1297 int32_t width, height;
1298 CHECK(msg->findInt32("width", &width));
1299 CHECK(msg->findInt32("height", &height));
1300
1301 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
1302 break;
1303 }
1304
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001305 case Source::kWhatBufferingStart:
1306 {
1307 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1308 break;
1309 }
1310
1311 case Source::kWhatBufferingEnd:
1312 {
1313 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1314 break;
1315 }
1316
Andreas Huber9575c962013-02-05 13:59:56 -08001317 default:
1318 TRESPASS();
1319 }
1320}
1321
Andreas Huberb5f25f02013-02-05 10:14:26 -08001322////////////////////////////////////////////////////////////////////////////////
1323
Andreas Huber9575c962013-02-05 13:59:56 -08001324void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1325 sp<AMessage> notify = dupNotify();
1326 notify->setInt32("what", kWhatFlagsChanged);
1327 notify->setInt32("flags", flags);
1328 notify->post();
1329}
1330
1331void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
1332 sp<AMessage> notify = dupNotify();
1333 notify->setInt32("what", kWhatVideoSizeChanged);
1334 notify->setInt32("width", width);
1335 notify->setInt32("height", height);
1336 notify->post();
1337}
1338
Andreas Huberec0c5972013-02-05 14:47:13 -08001339void NuPlayer::Source::notifyPrepared(status_t err) {
Andreas Huber9575c962013-02-05 13:59:56 -08001340 sp<AMessage> notify = dupNotify();
1341 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08001342 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08001343 notify->post();
1344}
1345
Andreas Huberb5f25f02013-02-05 10:14:26 -08001346void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1347 TRESPASS();
1348}
1349
Andreas Huberf9334412010-12-15 15:17:42 -08001350} // namespace android