blob: fa6b1e5ab4cbda4d6faa806e38ac2e1c5ffcb0f1 [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"
Wei Jiabc2fb722014-07-08 16:37:57 -070025#include "NuPlayerDecoderPassThrough.h"
Andreas Huber43c3e6c2011-01-05 12:17:08 -080026#include "NuPlayerDriver.h"
Andreas Huberf9334412010-12-15 15:17:42 -080027#include "NuPlayerRenderer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080028#include "NuPlayerSource.h"
Andreas Huber2bfdd422011-10-11 15:24:07 -070029#include "RTSPSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080030#include "StreamingSource.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070031#include "GenericSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080032
33#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080034
Andreas Huber3831a062010-12-21 10:22:33 -080035#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080036#include <media/stagefright/foundation/ABuffer.h>
37#include <media/stagefright/foundation/ADebug.h>
38#include <media/stagefright/foundation/AMessage.h>
Lajos Molnar09524832014-07-17 14:29:51 -070039#include <media/stagefright/MediaBuffer.h>
Andreas Huber3fe62152011-09-16 15:09:22 -070040#include <media/stagefright/MediaDefs.h>
Andreas Huberf9334412010-12-15 15:17:42 -080041#include <media/stagefright/MediaErrors.h>
42#include <media/stagefright/MetaData.h>
Andy McFadden8ba01022012-12-18 09:46:54 -080043#include <gui/IGraphicBufferProducer.h>
Andreas Huberf9334412010-12-15 15:17:42 -080044
Andreas Huber3fe62152011-09-16 15:09:22 -070045#include "avc_utils.h"
46
Andreas Huber84066782011-08-16 09:34:26 -070047#include "ESDS.h"
48#include <media/stagefright/Utils.h>
49
Andreas Huberf9334412010-12-15 15:17:42 -080050namespace android {
51
Andreas Hubera1f8ab02012-11-30 10:53:22 -080052struct NuPlayer::Action : public RefBase {
53 Action() {}
54
55 virtual void execute(NuPlayer *player) = 0;
56
57private:
58 DISALLOW_EVIL_CONSTRUCTORS(Action);
59};
60
61struct NuPlayer::SeekAction : public Action {
62 SeekAction(int64_t seekTimeUs)
63 : mSeekTimeUs(seekTimeUs) {
64 }
65
66 virtual void execute(NuPlayer *player) {
67 player->performSeek(mSeekTimeUs);
68 }
69
70private:
71 int64_t mSeekTimeUs;
72
73 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
74};
75
Andreas Huber57a339c2012-12-03 11:18:00 -080076struct NuPlayer::SetSurfaceAction : public Action {
77 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
78 : mWrapper(wrapper) {
79 }
80
81 virtual void execute(NuPlayer *player) {
82 player->performSetSurface(mWrapper);
83 }
84
85private:
86 sp<NativeWindowWrapper> mWrapper;
87
88 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
89};
90
Andreas Huber14f76722013-01-15 09:04:18 -080091struct NuPlayer::ShutdownDecoderAction : public Action {
92 ShutdownDecoderAction(bool audio, bool video)
93 : mAudio(audio),
94 mVideo(video) {
95 }
96
97 virtual void execute(NuPlayer *player) {
98 player->performDecoderShutdown(mAudio, mVideo);
99 }
100
101private:
102 bool mAudio;
103 bool mVideo;
104
105 DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction);
106};
107
108struct NuPlayer::PostMessageAction : public Action {
109 PostMessageAction(const sp<AMessage> &msg)
110 : mMessage(msg) {
111 }
112
113 virtual void execute(NuPlayer *) {
114 mMessage->post();
115 }
116
117private:
118 sp<AMessage> mMessage;
119
120 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
121};
122
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800123// Use this if there's no state necessary to save in order to execute
124// the action.
125struct NuPlayer::SimpleAction : public Action {
126 typedef void (NuPlayer::*ActionFunc)();
127
128 SimpleAction(ActionFunc func)
129 : mFunc(func) {
130 }
131
132 virtual void execute(NuPlayer *player) {
133 (player->*mFunc)();
134 }
135
136private:
137 ActionFunc mFunc;
138
139 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
140};
141
Andreas Huberf9334412010-12-15 15:17:42 -0800142////////////////////////////////////////////////////////////////////////////////
143
144NuPlayer::NuPlayer()
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700145 : mUIDValid(false),
Andreas Huber9575c962013-02-05 13:59:56 -0800146 mSourceFlags(0),
Andreas Huber3fe62152011-09-16 15:09:22 -0700147 mVideoIsAVC(false),
Wei Jiabc2fb722014-07-08 16:37:57 -0700148 mOffloadAudio(false),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700149 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800150 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800151 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800152 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800153 mPollDurationGeneration(0),
Andreas Huber6e3d3112011-11-28 12:36:11 -0800154 mTimeDiscontinuityPending(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800155 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800156 mFlushingVideo(NONE),
Andreas Huber3fe62152011-09-16 15:09:22 -0700157 mSkipRenderingAudioUntilMediaTimeUs(-1ll),
158 mSkipRenderingVideoUntilMediaTimeUs(-1ll),
159 mVideoLateByUs(0ll),
160 mNumFramesTotal(0ll),
James Dong0d268a32012-08-31 12:18:27 -0700161 mNumFramesDropped(0ll),
Andreas Huber57a339c2012-12-03 11:18:00 -0800162 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
163 mStarted(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800164}
165
166NuPlayer::~NuPlayer() {
167}
168
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700169void NuPlayer::setUID(uid_t uid) {
170 mUIDValid = true;
171 mUID = uid;
172}
173
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800174void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
175 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800176}
177
Andreas Huber9575c962013-02-05 13:59:56 -0800178void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Andreas Huberf9334412010-12-15 15:17:42 -0800179 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
180
Andreas Huberb5f25f02013-02-05 10:14:26 -0800181 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
182
Andreas Huber240abcc2014-02-13 13:32:37 -0800183 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber5bc087c2010-12-23 10:27:40 -0800184 msg->post();
185}
Andreas Huberf9334412010-12-15 15:17:42 -0800186
Andreas Huberafed0e12011-09-20 15:39:58 -0700187static bool IsHTTPLiveURL(const char *url) {
188 if (!strncasecmp("http://", url, 7)
Andreas Huber99759402013-04-01 14:28:31 -0700189 || !strncasecmp("https://", url, 8)
190 || !strncasecmp("file://", url, 7)) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700191 size_t len = strlen(url);
192 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
193 return true;
194 }
195
196 if (strstr(url,"m3u8")) {
197 return true;
198 }
199 }
200
201 return false;
202}
203
Andreas Huber9575c962013-02-05 13:59:56 -0800204void NuPlayer::setDataSourceAsync(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800205 const sp<IMediaHTTPService> &httpService,
206 const char *url,
207 const KeyedVector<String8, String8> *headers) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800208 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100209 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800210
Andreas Huberb5f25f02013-02-05 10:14:26 -0800211 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
212
Andreas Huberafed0e12011-09-20 15:39:58 -0700213 sp<Source> source;
214 if (IsHTTPLiveURL(url)) {
Andreas Huber81e68442014-02-05 11:52:33 -0800215 source = new HTTPLiveSource(notify, httpService, url, headers);
Andreas Huberafed0e12011-09-20 15:39:58 -0700216 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800217 source = new RTSPSource(
218 notify, httpService, url, headers, mUIDValid, mUID);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100219 } else if ((!strncasecmp(url, "http://", 7)
220 || !strncasecmp(url, "https://", 8))
221 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
222 || strstr(url, ".sdp?"))) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800223 source = new RTSPSource(
224 notify, httpService, url, headers, mUIDValid, mUID, true);
Lajos Molnar09524832014-07-17 14:29:51 -0700225 } else if ((!strncasecmp(url, "widevine://", 11))) {
226 source = new GenericSource(notify, httpService, url, headers,
227 true /* isWidevine */, mUIDValid, mUID);
228 mSourceFlags |= Source::FLAG_SECURE;
Andreas Huber2bfdd422011-10-11 15:24:07 -0700229 } else {
Andreas Huber81e68442014-02-05 11:52:33 -0800230 source = new GenericSource(notify, httpService, url, headers);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700231 }
232
Andreas Huberafed0e12011-09-20 15:39:58 -0700233 msg->setObject("source", source);
234 msg->post();
235}
236
Andreas Huber9575c962013-02-05 13:59:56 -0800237void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700238 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
239
Andreas Huberb5f25f02013-02-05 10:14:26 -0800240 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
241
242 sp<Source> source = new GenericSource(notify, fd, offset, length);
Andreas Huberafed0e12011-09-20 15:39:58 -0700243 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800244 msg->post();
245}
246
Andreas Huber9575c962013-02-05 13:59:56 -0800247void NuPlayer::prepareAsync() {
248 (new AMessage(kWhatPrepare, id()))->post();
249}
250
Andreas Huber57a339c2012-12-03 11:18:00 -0800251void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800252 const sp<IGraphicBufferProducer> &bufferProducer) {
Glenn Kasten11731182011-02-08 17:26:17 -0800253 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
Andreas Huber57a339c2012-12-03 11:18:00 -0800254
Andy McFadden8ba01022012-12-18 09:46:54 -0800255 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800256 msg->setObject("native-window", NULL);
257 } else {
258 msg->setObject(
259 "native-window",
260 new NativeWindowWrapper(
Mathias Agopian1a2952a2013-02-14 17:11:27 -0800261 new Surface(bufferProducer)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800262 }
263
Andreas Huberf9334412010-12-15 15:17:42 -0800264 msg->post();
265}
266
267void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
268 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
269 msg->setObject("sink", sink);
270 msg->post();
271}
272
273void NuPlayer::start() {
274 (new AMessage(kWhatStart, id()))->post();
275}
276
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800277void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800278 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800279}
280
281void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800282 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800283}
284
Andreas Huber1aef2112011-01-04 14:01:29 -0800285void NuPlayer::resetAsync() {
286 (new AMessage(kWhatReset, id()))->post();
287}
288
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800289void NuPlayer::seekToAsync(int64_t seekTimeUs) {
290 sp<AMessage> msg = new AMessage(kWhatSeek, id());
291 msg->setInt64("seekTimeUs", seekTimeUs);
292 msg->post();
293}
294
Andreas Huber53df1a42010-12-22 10:03:04 -0800295// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800296bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800297 switch (state) {
298 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800299 if (needShutdown != NULL) {
300 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800301 }
302 return true;
303
Andreas Huber1aef2112011-01-04 14:01:29 -0800304 case FLUSHING_DECODER_SHUTDOWN:
305 if (needShutdown != NULL) {
306 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800307 }
308 return true;
309
310 default:
311 return false;
312 }
313}
314
Chong Zhang404fced2014-06-11 14:45:31 -0700315void NuPlayer::writeTrackInfo(
316 Parcel* reply, const sp<AMessage> format) const {
317 int32_t trackType;
318 CHECK(format->findInt32("type", &trackType));
319
320 AString lang;
321 CHECK(format->findString("language", &lang));
322
323 reply->writeInt32(2); // write something non-zero
324 reply->writeInt32(trackType);
325 reply->writeString16(String16(lang.c_str()));
326
327 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
328 AString mime;
329 CHECK(format->findString("mime", &mime));
330
331 int32_t isAuto, isDefault, isForced;
332 CHECK(format->findInt32("auto", &isAuto));
333 CHECK(format->findInt32("default", &isDefault));
334 CHECK(format->findInt32("forced", &isForced));
335
336 reply->writeString16(String16(mime.c_str()));
337 reply->writeInt32(isAuto);
338 reply->writeInt32(isDefault);
339 reply->writeInt32(isForced);
340 }
341}
342
Andreas Huberf9334412010-12-15 15:17:42 -0800343void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
344 switch (msg->what()) {
345 case kWhatSetDataSource:
346 {
Steve Block3856b092011-10-20 11:56:00 +0100347 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800348
349 CHECK(mSource == NULL);
350
Andreas Huber5bc087c2010-12-23 10:27:40 -0800351 sp<RefBase> obj;
352 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800353
Andreas Huber5bc087c2010-12-23 10:27:40 -0800354 mSource = static_cast<Source *>(obj.get());
Andreas Huberb5f25f02013-02-05 10:14:26 -0800355
356 looper()->registerHandler(mSource);
Andreas Huber9575c962013-02-05 13:59:56 -0800357
358 CHECK(mDriver != NULL);
359 sp<NuPlayerDriver> driver = mDriver.promote();
360 if (driver != NULL) {
361 driver->notifySetDataSourceCompleted(OK);
362 }
363 break;
364 }
365
366 case kWhatPrepare:
367 {
368 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800369 break;
370 }
371
Chong Zhangdcb89b32013-08-06 09:44:47 -0700372 case kWhatGetTrackInfo:
373 {
374 uint32_t replyID;
375 CHECK(msg->senderAwaitsResponse(&replyID));
376
Chong Zhang404fced2014-06-11 14:45:31 -0700377 Parcel* reply;
378 CHECK(msg->findPointer("reply", (void**)&reply));
379
380 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700381 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700382 inbandTracks = mSource->getTrackCount();
383 }
384
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700385 size_t ccTracks = 0;
386 if (mCCDecoder != NULL) {
387 ccTracks = mCCDecoder->getTrackCount();
388 }
389
Chong Zhang404fced2014-06-11 14:45:31 -0700390 // total track count
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700391 reply->writeInt32(inbandTracks + ccTracks);
Chong Zhang404fced2014-06-11 14:45:31 -0700392
393 // write inband tracks
394 for (size_t i = 0; i < inbandTracks; ++i) {
395 writeTrackInfo(reply, mSource->getTrackInfo(i));
Chong Zhangdcb89b32013-08-06 09:44:47 -0700396 }
397
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700398 // write CC track
399 for (size_t i = 0; i < ccTracks; ++i) {
400 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
401 }
402
Chong Zhangdcb89b32013-08-06 09:44:47 -0700403 sp<AMessage> response = new AMessage;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700404 response->postReply(replyID);
405 break;
406 }
407
408 case kWhatSelectTrack:
409 {
410 uint32_t replyID;
411 CHECK(msg->senderAwaitsResponse(&replyID));
412
Chong Zhang404fced2014-06-11 14:45:31 -0700413 size_t trackIndex;
414 int32_t select;
415 CHECK(msg->findSize("trackIndex", &trackIndex));
416 CHECK(msg->findInt32("select", &select));
417
Chong Zhangdcb89b32013-08-06 09:44:47 -0700418 status_t err = INVALID_OPERATION;
Chong Zhang404fced2014-06-11 14:45:31 -0700419
420 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700421 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700422 inbandTracks = mSource->getTrackCount();
423 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700424 size_t ccTracks = 0;
425 if (mCCDecoder != NULL) {
426 ccTracks = mCCDecoder->getTrackCount();
427 }
Chong Zhang404fced2014-06-11 14:45:31 -0700428
429 if (trackIndex < inbandTracks) {
Chong Zhangdcb89b32013-08-06 09:44:47 -0700430 err = mSource->selectTrack(trackIndex, select);
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700431 } else {
432 trackIndex -= inbandTracks;
433
434 if (trackIndex < ccTracks) {
435 err = mCCDecoder->selectTrack(trackIndex, select);
436 }
Chong Zhangdcb89b32013-08-06 09:44:47 -0700437 }
438
439 sp<AMessage> response = new AMessage;
440 response->setInt32("err", err);
441
442 response->postReply(replyID);
443 break;
444 }
445
Andreas Huberb7c8e912012-11-27 15:02:53 -0800446 case kWhatPollDuration:
447 {
448 int32_t generation;
449 CHECK(msg->findInt32("generation", &generation));
450
451 if (generation != mPollDurationGeneration) {
452 // stale
453 break;
454 }
455
456 int64_t durationUs;
457 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
458 sp<NuPlayerDriver> driver = mDriver.promote();
459 if (driver != NULL) {
460 driver->notifyDuration(durationUs);
461 }
462 }
463
464 msg->post(1000000ll); // poll again in a second.
465 break;
466 }
467
Glenn Kasten11731182011-02-08 17:26:17 -0800468 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800469 {
Steve Block3856b092011-10-20 11:56:00 +0100470 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800471
Andreas Huber57a339c2012-12-03 11:18:00 -0800472 mDeferredActions.push_back(
Andreas Huber14f76722013-01-15 09:04:18 -0800473 new ShutdownDecoderAction(
474 false /* audio */, true /* video */));
Andreas Huber57a339c2012-12-03 11:18:00 -0800475
Andreas Huberf9334412010-12-15 15:17:42 -0800476 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800477 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800478
Andreas Huber57a339c2012-12-03 11:18:00 -0800479 mDeferredActions.push_back(
480 new SetSurfaceAction(
481 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700482
Andreas Huber57a339c2012-12-03 11:18:00 -0800483 if (obj != NULL) {
484 // If there is a new surface texture, instantiate decoders
485 // again if possible.
486 mDeferredActions.push_back(
487 new SimpleAction(&NuPlayer::performScanSources));
488 }
489
490 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800491 break;
492 }
493
494 case kWhatSetAudioSink:
495 {
Steve Block3856b092011-10-20 11:56:00 +0100496 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800497
498 sp<RefBase> obj;
499 CHECK(msg->findObject("sink", &obj));
500
501 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
502 break;
503 }
504
505 case kWhatStart:
506 {
Steve Block3856b092011-10-20 11:56:00 +0100507 ALOGV("kWhatStart");
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800508
Andreas Huber3fe62152011-09-16 15:09:22 -0700509 mVideoIsAVC = false;
Wei Jiabc2fb722014-07-08 16:37:57 -0700510 mOffloadAudio = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800511 mAudioEOS = false;
512 mVideoEOS = false;
Andreas Huber32f3cef2011-03-02 15:34:46 -0800513 mSkipRenderingAudioUntilMediaTimeUs = -1;
514 mSkipRenderingVideoUntilMediaTimeUs = -1;
Andreas Huber3fe62152011-09-16 15:09:22 -0700515 mVideoLateByUs = 0;
516 mNumFramesTotal = 0;
517 mNumFramesDropped = 0;
Andreas Huber57a339c2012-12-03 11:18:00 -0800518 mStarted = true;
Andreas Huber1aef2112011-01-04 14:01:29 -0800519
Lajos Molnar09524832014-07-17 14:29:51 -0700520 /* instantiate decoders now for secure playback */
521 if (mSourceFlags & Source::FLAG_SECURE) {
522 if (mNativeWindow != NULL) {
523 instantiateDecoder(false, &mVideoDecoder);
524 }
525
526 if (mAudioSink != NULL) {
527 instantiateDecoder(true, &mAudioDecoder);
528 }
529 }
530
Andreas Huber5bc087c2010-12-23 10:27:40 -0800531 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800532
Andreas Huberd5e56232013-03-12 11:01:43 -0700533 uint32_t flags = 0;
534
535 if (mSource->isRealTime()) {
536 flags |= Renderer::FLAG_REAL_TIME;
537 }
538
Wei Jiabc2fb722014-07-08 16:37:57 -0700539 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
540 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
541 if (mAudioSink != NULL) {
542 streamType = mAudioSink->getAudioStreamType();
543 }
544
545 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
546
547 mOffloadAudio =
548 canOffloadStream(audioMeta, (videoFormat != NULL),
549 true /* is_streaming */, streamType);
550 if (mOffloadAudio) {
551 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
552 }
553
Andreas Huberf9334412010-12-15 15:17:42 -0800554 mRenderer = new Renderer(
555 mAudioSink,
Andreas Huberd5e56232013-03-12 11:01:43 -0700556 new AMessage(kWhatRendererNotify, id()),
557 flags);
Andreas Huberf9334412010-12-15 15:17:42 -0800558
Lajos Molnar09524832014-07-17 14:29:51 -0700559 mRendererLooper = new ALooper;
560 mRendererLooper->setName("NuPlayerRenderer");
561 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
562 mRendererLooper->registerHandler(mRenderer);
Andreas Huberf9334412010-12-15 15:17:42 -0800563
Andreas Huber1aef2112011-01-04 14:01:29 -0800564 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800565 break;
566 }
567
568 case kWhatScanSources:
569 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800570 int32_t generation;
571 CHECK(msg->findInt32("generation", &generation));
572 if (generation != mScanSourcesGeneration) {
573 // Drop obsolete msg.
574 break;
575 }
576
Andreas Huber5bc087c2010-12-23 10:27:40 -0800577 mScanSourcesPending = false;
578
Steve Block3856b092011-10-20 11:56:00 +0100579 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800580 mAudioDecoder != NULL, mVideoDecoder != NULL);
581
Andreas Huberb7c8e912012-11-27 15:02:53 -0800582 bool mHadAnySourcesBefore =
583 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
584
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700585 if (mNativeWindow != NULL) {
586 instantiateDecoder(false, &mVideoDecoder);
587 }
Andreas Huberf9334412010-12-15 15:17:42 -0800588
589 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800590 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800591 }
592
Andreas Huberb7c8e912012-11-27 15:02:53 -0800593 if (!mHadAnySourcesBefore
594 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
595 // This is the first time we've found anything playable.
596
Andreas Huber9575c962013-02-05 13:59:56 -0800597 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800598 schedulePollDuration();
599 }
600 }
601
Andreas Hubereac68ba2011-09-27 12:12:25 -0700602 status_t err;
603 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800604 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
605 // We're not currently decoding anything (no audio or
606 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700607
608 if (err == ERROR_END_OF_STREAM) {
609 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
610 } else {
611 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
612 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800613 }
Andreas Huberf9334412010-12-15 15:17:42 -0800614 break;
615 }
616
Andreas Huberfbe9d812012-08-31 14:05:27 -0700617 if ((mAudioDecoder == NULL && mAudioSink != NULL)
618 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800619 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800620 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800621 }
622 break;
623 }
624
625 case kWhatVideoNotify:
626 case kWhatAudioNotify:
627 {
628 bool audio = msg->what() == kWhatAudioNotify;
629
Andreas Huberf9334412010-12-15 15:17:42 -0800630 int32_t what;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800631 CHECK(msg->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -0800632
Lajos Molnar1cd13982014-01-17 15:12:51 -0800633 if (what == Decoder::kWhatFillThisBuffer) {
Andreas Huberf9334412010-12-15 15:17:42 -0800634 status_t err = feedDecoderInputData(
Lajos Molnar1cd13982014-01-17 15:12:51 -0800635 audio, msg);
Andreas Huberf9334412010-12-15 15:17:42 -0800636
Andreas Huber5bc087c2010-12-23 10:27:40 -0800637 if (err == -EWOULDBLOCK) {
Andreas Hubereac68ba2011-09-27 12:12:25 -0700638 if (mSource->feedMoreTSData() == OK) {
Andreas Huber1183a4a2011-11-03 11:00:21 -0700639 msg->post(10000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800640 }
Andreas Huberf9334412010-12-15 15:17:42 -0800641 }
Lajos Molnar1cd13982014-01-17 15:12:51 -0800642 } else if (what == Decoder::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700643 int32_t err;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800644 CHECK(msg->findInt32("err", &err));
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700645
646 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100647 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700648 } else {
Steve Block3856b092011-10-20 11:56:00 +0100649 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700650 audio ? "audio" : "video",
651 err);
652 }
653
654 mRenderer->queueEOS(audio, err);
Lajos Molnar1cd13982014-01-17 15:12:51 -0800655 } else if (what == Decoder::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800656 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800657
Andreas Huberf9334412010-12-15 15:17:42 -0800658 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800659 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800660 mFlushingAudio = FLUSHED;
661 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800662 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800663 mFlushingVideo = FLUSHED;
Andreas Huber3fe62152011-09-16 15:09:22 -0700664
665 mVideoLateByUs = 0;
Andreas Huberf9334412010-12-15 15:17:42 -0800666 }
667
Steve Block3856b092011-10-20 11:56:00 +0100668 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800669
Andreas Huber1aef2112011-01-04 14:01:29 -0800670 if (needShutdown) {
Steve Block3856b092011-10-20 11:56:00 +0100671 ALOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800672 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800673
Andreas Huber53df1a42010-12-22 10:03:04 -0800674 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800675
Andreas Huber53df1a42010-12-22 10:03:04 -0800676 if (audio) {
677 mFlushingAudio = SHUTTING_DOWN_DECODER;
678 } else {
679 mFlushingVideo = SHUTTING_DOWN_DECODER;
680 }
Andreas Huberf9334412010-12-15 15:17:42 -0800681 }
Andreas Huber3831a062010-12-21 10:22:33 -0800682
683 finishFlushIfPossible();
Lajos Molnar1cd13982014-01-17 15:12:51 -0800684 } else if (what == Decoder::kWhatOutputFormatChanged) {
685 sp<AMessage> format;
686 CHECK(msg->findMessage("format", &format));
687
Andreas Huber31e25082011-01-10 10:38:31 -0800688 if (audio) {
689 int32_t numChannels;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800690 CHECK(format->findInt32(
Andreas Huber516dacf2012-12-03 15:20:40 -0800691 "channel-count", &numChannels));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800692
Andreas Huber31e25082011-01-10 10:38:31 -0800693 int32_t sampleRate;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800694 CHECK(format->findInt32("sample-rate", &sampleRate));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800695
Steve Block3856b092011-10-20 11:56:00 +0100696 ALOGV("Audio output format changed to %d Hz, %d channels",
Andreas Huber31e25082011-01-10 10:38:31 -0800697 sampleRate, numChannels);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800698
Andreas Huber31e25082011-01-10 10:38:31 -0800699 mAudioSink->close();
Eric Laurent1948eb32012-04-13 16:50:19 -0700700
Wei Jiabc2fb722014-07-08 16:37:57 -0700701 uint32_t flags;
Eric Laurent1948eb32012-04-13 16:50:19 -0700702 int64_t durationUs;
Andreas Huber516dacf2012-12-03 15:20:40 -0800703 // FIXME: we should handle the case where the video decoder
704 // is created after we receive the format change indication.
705 // Current code will just make that we select deep buffer
706 // with video which should not be a problem as it should
Eric Laurent1948eb32012-04-13 16:50:19 -0700707 // not prevent from keeping A/V sync.
708 if (mVideoDecoder == NULL &&
709 mSource->getDuration(&durationUs) == OK &&
Andreas Huber516dacf2012-12-03 15:20:40 -0800710 durationUs
711 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
Eric Laurent1948eb32012-04-13 16:50:19 -0700712 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
713 } else {
714 flags = AUDIO_OUTPUT_FLAG_NONE;
715 }
716
Andreas Huber98065552012-05-03 11:33:01 -0700717 int32_t channelMask;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800718 if (!format->findInt32("channel-mask", &channelMask)) {
Andreas Huber98065552012-05-03 11:33:01 -0700719 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
720 }
721
Wei Jiabc2fb722014-07-08 16:37:57 -0700722 if (mOffloadAudio) {
723 audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
724 audio_offload_info_t offloadInfo =
725 AUDIO_INFO_INITIALIZER;
726
727 AString mime;
728 CHECK(format->findString("mime", &mime));
729
730 status_t err =
731 mapMimeToAudioFormat(audioFormat, mime.c_str());
732 if (err != OK) {
733 ALOGE("Couldn't map mime \"%s\" to a valid "
734 "audio_format", mime.c_str());
735 mOffloadAudio = false;
736 } else {
737 ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
738 mime.c_str(), audioFormat);
739
740 flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
741
742 offloadInfo.duration_us = -1;
743 format->findInt64(
744 "durationUs", &offloadInfo.duration_us);
745
746 int avgBitRate = -1;
747 format->findInt32("bit-rate", &avgBitRate);
748
749 offloadInfo.sample_rate = sampleRate;
750 offloadInfo.channel_mask = channelMask;
751 offloadInfo.format = audioFormat;
752 offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
753 offloadInfo.bit_rate = avgBitRate;
754 offloadInfo.has_video = (mVideoDecoder != NULL);
755 offloadInfo.is_streaming = true;
756
Wei Jia3a2956d2014-07-22 16:01:33 -0700757 ALOGV("try to open AudioSink in offload mode");
Wei Jiabc2fb722014-07-08 16:37:57 -0700758 err = mAudioSink->open(
759 sampleRate,
760 numChannels,
761 (audio_channel_mask_t)channelMask,
762 audioFormat,
763 8 /* bufferCount */,
764 &NuPlayer::Renderer::AudioSinkCallback,
765 mRenderer.get(),
766 (audio_output_flags_t)flags,
767 &offloadInfo);
768
769 if (err == OK) {
770 // If the playback is offloaded to h/w, we pass
771 // the HAL some metadata information.
772 // We don't want to do this for PCM because it
773 // will be going through the AudioFlinger mixer
774 // before reaching the hardware.
775 sp<MetaData> audioMeta =
776 mSource->getFormatMeta(true /* audio */);
777 sendMetaDataToHal(mAudioSink, audioMeta);
778
779 err = mAudioSink->start();
780 }
781 }
782
783 if (err != OK) {
784 // Clean up, fall back to non offload mode.
785 mAudioSink->close();
786 mAudioDecoder.clear();
787 mRenderer->signalDisableOffloadAudio();
788 mOffloadAudio = false;
789
790 instantiateDecoder(
791 true /* audio */, &mAudioDecoder);
792 }
793 }
794
795 if (!mOffloadAudio) {
796 flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
Wei Jia3a2956d2014-07-22 16:01:33 -0700797 ALOGV("open AudioSink in NON-offload mode");
Wei Jiabc2fb722014-07-08 16:37:57 -0700798 CHECK_EQ(mAudioSink->open(
799 sampleRate,
800 numChannels,
801 (audio_channel_mask_t)channelMask,
802 AUDIO_FORMAT_PCM_16_BIT,
803 8 /* bufferCount */,
804 NULL,
805 NULL,
806 (audio_output_flags_t)flags),
807 (status_t)OK);
808 mAudioSink->start();
809 }
Andreas Huber2c2814b2010-12-15 17:18:20 -0800810
Andreas Huber31e25082011-01-10 10:38:31 -0800811 mRenderer->signalAudioSinkChanged();
812 } else {
813 // video
Andreas Huber3831a062010-12-21 10:22:33 -0800814
Andreas Huber31e25082011-01-10 10:38:31 -0800815 int32_t width, height;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800816 CHECK(format->findInt32("width", &width));
817 CHECK(format->findInt32("height", &height));
Andreas Huber31e25082011-01-10 10:38:31 -0800818
819 int32_t cropLeft, cropTop, cropRight, cropBottom;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800820 CHECK(format->findRect(
Andreas Huber31e25082011-01-10 10:38:31 -0800821 "crop",
822 &cropLeft, &cropTop, &cropRight, &cropBottom));
823
Andreas Huber516dacf2012-12-03 15:20:40 -0800824 int32_t displayWidth = cropRight - cropLeft + 1;
825 int32_t displayHeight = cropBottom - cropTop + 1;
826
Steve Block3856b092011-10-20 11:56:00 +0100827 ALOGV("Video output format changed to %d x %d "
Andreas Hubercb67cd12011-08-26 16:02:19 -0700828 "(crop: %d x %d @ (%d, %d))",
Andreas Huber31e25082011-01-10 10:38:31 -0800829 width, height,
Andreas Huber516dacf2012-12-03 15:20:40 -0800830 displayWidth,
831 displayHeight,
Andreas Hubercb67cd12011-08-26 16:02:19 -0700832 cropLeft, cropTop);
Andreas Huber31e25082011-01-10 10:38:31 -0800833
Andreas Huber516dacf2012-12-03 15:20:40 -0800834 sp<AMessage> videoInputFormat =
835 mSource->getFormat(false /* audio */);
836
837 // Take into account sample aspect ratio if necessary:
838 int32_t sarWidth, sarHeight;
839 if (videoInputFormat->findInt32("sar-width", &sarWidth)
840 && videoInputFormat->findInt32(
841 "sar-height", &sarHeight)) {
842 ALOGV("Sample aspect ratio %d : %d",
843 sarWidth, sarHeight);
844
845 displayWidth = (displayWidth * sarWidth) / sarHeight;
846
847 ALOGV("display dimensions %d x %d",
848 displayWidth, displayHeight);
849 }
850
Andreas Huber31e25082011-01-10 10:38:31 -0800851 notifyListener(
Andreas Huber516dacf2012-12-03 15:20:40 -0800852 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
Andreas Huber31e25082011-01-10 10:38:31 -0800853 }
Lajos Molnar1cd13982014-01-17 15:12:51 -0800854 } else if (what == Decoder::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100855 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800856 if (audio) {
857 mAudioDecoder.clear();
858
859 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
860 mFlushingAudio = SHUT_DOWN;
861 } else {
862 mVideoDecoder.clear();
863
864 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
865 mFlushingVideo = SHUT_DOWN;
866 }
867
868 finishFlushIfPossible();
Lajos Molnar1cd13982014-01-17 15:12:51 -0800869 } else if (what == Decoder::kWhatError) {
Steve Block29357bc2012-01-06 19:20:56 +0000870 ALOGE("Received error from %s decoder, aborting playback.",
Andreas Huberc92fd242011-08-16 13:48:44 -0700871 audio ? "audio" : "video");
872
873 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
Lajos Molnar1cd13982014-01-17 15:12:51 -0800874 } else if (what == Decoder::kWhatDrainThisBuffer) {
875 renderBuffer(audio, msg);
876 } else {
877 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800878 what,
879 what >> 24,
880 (what >> 16) & 0xff,
881 (what >> 8) & 0xff,
882 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800883 }
884
885 break;
886 }
887
888 case kWhatRendererNotify:
889 {
890 int32_t what;
891 CHECK(msg->findInt32("what", &what));
892
893 if (what == Renderer::kWhatEOS) {
894 int32_t audio;
895 CHECK(msg->findInt32("audio", &audio));
896
Andreas Huberc92fd242011-08-16 13:48:44 -0700897 int32_t finalResult;
898 CHECK(msg->findInt32("finalResult", &finalResult));
899
Andreas Huberf9334412010-12-15 15:17:42 -0800900 if (audio) {
901 mAudioEOS = true;
902 } else {
903 mVideoEOS = true;
904 }
905
Andreas Huberc92fd242011-08-16 13:48:44 -0700906 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100907 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700908 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000909 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700910 audio ? "audio" : "video", finalResult);
911
912 notifyListener(
913 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
914 }
Andreas Huberf9334412010-12-15 15:17:42 -0800915
916 if ((mAudioEOS || mAudioDecoder == NULL)
917 && (mVideoEOS || mVideoDecoder == NULL)) {
918 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
919 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800920 } else if (what == Renderer::kWhatPosition) {
921 int64_t positionUs;
922 CHECK(msg->findInt64("positionUs", &positionUs));
923
Andreas Huber3fe62152011-09-16 15:09:22 -0700924 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
925
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800926 if (mDriver != NULL) {
927 sp<NuPlayerDriver> driver = mDriver.promote();
928 if (driver != NULL) {
929 driver->notifyPosition(positionUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700930
931 driver->notifyFrameStats(
932 mNumFramesTotal, mNumFramesDropped);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800933 }
934 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700935 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800936 int32_t audio;
937 CHECK(msg->findInt32("audio", &audio));
938
Steve Block3856b092011-10-20 11:56:00 +0100939 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
James Dongf57b4ea2012-07-20 13:38:36 -0700940 } else if (what == Renderer::kWhatVideoRenderingStart) {
941 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Lajos Molnarcbaffcf2013-08-14 18:30:38 -0700942 } else if (what == Renderer::kWhatMediaRenderingStart) {
943 ALOGV("media rendering started");
944 notifyListener(MEDIA_STARTED, 0, 0);
Wei Jia3a2956d2014-07-22 16:01:33 -0700945 } else if (what == Renderer::kWhatAudioOffloadTearDown) {
946 ALOGV("Tear down audio offload, fall back to s/w path");
947 int64_t positionUs;
948 CHECK(msg->findInt64("positionUs", &positionUs));
949 mAudioSink->close();
950 mAudioDecoder.clear();
951 mRenderer->flush(true /* audio */);
952 if (mVideoDecoder != NULL) {
953 mRenderer->flush(false /* audio */);
954 }
955 mRenderer->signalDisableOffloadAudio();
956 mOffloadAudio = false;
957
958 performSeek(positionUs);
959 instantiateDecoder(true /* audio */, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800960 }
961 break;
962 }
963
964 case kWhatMoreDataQueued:
965 {
966 break;
967 }
968
Andreas Huber1aef2112011-01-04 14:01:29 -0800969 case kWhatReset:
970 {
Steve Block3856b092011-10-20 11:56:00 +0100971 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800972
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800973 mDeferredActions.push_back(
Andreas Huber14f76722013-01-15 09:04:18 -0800974 new ShutdownDecoderAction(
975 true /* audio */, true /* video */));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800976
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800977 mDeferredActions.push_back(
978 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800979
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800980 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800981 break;
982 }
983
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800984 case kWhatSeek:
985 {
986 int64_t seekTimeUs;
987 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
988
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800989 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800990
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800991 mDeferredActions.push_back(
992 new SimpleAction(&NuPlayer::performDecoderFlush));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800993
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800994 mDeferredActions.push_back(new SeekAction(seekTimeUs));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800995
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800996 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800997 break;
998 }
999
Andreas Huberb4082222011-01-20 15:23:04 -08001000 case kWhatPause:
1001 {
1002 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +01001003 mSource->pause();
Andreas Huberb4082222011-01-20 15:23:04 -08001004 mRenderer->pause();
1005 break;
1006 }
1007
1008 case kWhatResume:
1009 {
1010 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +01001011 mSource->resume();
Andreas Huberb4082222011-01-20 15:23:04 -08001012 mRenderer->resume();
1013 break;
1014 }
1015
Andreas Huberb5f25f02013-02-05 10:14:26 -08001016 case kWhatSourceNotify:
1017 {
Andreas Huber9575c962013-02-05 13:59:56 -08001018 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -08001019 break;
1020 }
1021
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001022 case kWhatClosedCaptionNotify:
1023 {
1024 onClosedCaptionNotify(msg);
1025 break;
1026 }
1027
Andreas Huberf9334412010-12-15 15:17:42 -08001028 default:
1029 TRESPASS();
1030 break;
1031 }
1032}
1033
Andreas Huber3831a062010-12-21 10:22:33 -08001034void NuPlayer::finishFlushIfPossible() {
1035 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
1036 return;
1037 }
1038
1039 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
1040 return;
1041 }
1042
Steve Block3856b092011-10-20 11:56:00 +01001043 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -08001044
Andreas Huber6e3d3112011-11-28 12:36:11 -08001045 if (mTimeDiscontinuityPending) {
1046 mRenderer->signalTimeDiscontinuity();
1047 mTimeDiscontinuityPending = false;
1048 }
Andreas Huber3831a062010-12-21 10:22:33 -08001049
Andreas Huber22fc52f2011-01-05 16:24:27 -08001050 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -08001051 mAudioDecoder->signalResume();
1052 }
1053
Andreas Huber22fc52f2011-01-05 16:24:27 -08001054 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -08001055 mVideoDecoder->signalResume();
1056 }
1057
1058 mFlushingAudio = NONE;
1059 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -08001060
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001061 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001062}
1063
1064void NuPlayer::postScanSources() {
1065 if (mScanSourcesPending) {
1066 return;
1067 }
1068
1069 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
1070 msg->setInt32("generation", mScanSourcesGeneration);
1071 msg->post();
1072
1073 mScanSourcesPending = true;
1074}
1075
Andreas Huber5bc087c2010-12-23 10:27:40 -08001076status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -08001077 if (*decoder != NULL) {
1078 return OK;
1079 }
1080
Andreas Huber84066782011-08-16 09:34:26 -07001081 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -08001082
Andreas Huber84066782011-08-16 09:34:26 -07001083 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001084 return -EWOULDBLOCK;
1085 }
1086
Andreas Huber3fe62152011-09-16 15:09:22 -07001087 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -07001088 AString mime;
1089 CHECK(format->findString("mime", &mime));
1090 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001091
1092 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
1093 mCCDecoder = new CCDecoder(ccNotify);
Lajos Molnar09524832014-07-17 14:29:51 -07001094
1095 if (mSourceFlags & Source::FLAG_SECURE) {
1096 format->setInt32("secure", true);
1097 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001098 }
1099
Andreas Huberf9334412010-12-15 15:17:42 -08001100 sp<AMessage> notify =
1101 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
1102 id());
1103
Wei Jiabc2fb722014-07-08 16:37:57 -07001104 if (audio) {
1105 if (mOffloadAudio) {
1106 *decoder = new DecoderPassThrough(notify);
1107 } else {
1108 *decoder = new Decoder(notify);
1109 }
1110 } else {
1111 *decoder = new Decoder(notify, mNativeWindow);
1112 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001113 (*decoder)->init();
Andreas Huber84066782011-08-16 09:34:26 -07001114 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -08001115
Lajos Molnar09524832014-07-17 14:29:51 -07001116 // allocate buffers to decrypt widevine source buffers
1117 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1118 Vector<sp<ABuffer> > inputBufs;
1119 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1120
1121 Vector<MediaBuffer *> mediaBufs;
1122 for (size_t i = 0; i < inputBufs.size(); i++) {
1123 const sp<ABuffer> &buffer = inputBufs[i];
1124 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1125 mediaBufs.push(mbuf);
1126 }
1127
1128 status_t err = mSource->setBuffers(audio, mediaBufs);
1129 if (err != OK) {
1130 for (size_t i = 0; i < mediaBufs.size(); ++i) {
1131 mediaBufs[i]->release();
1132 }
1133 mediaBufs.clear();
1134 ALOGE("Secure source didn't support secure mediaBufs.");
1135 return err;
1136 }
1137 }
Andreas Huberf9334412010-12-15 15:17:42 -08001138 return OK;
1139}
1140
1141status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
1142 sp<AMessage> reply;
1143 CHECK(msg->findMessage("reply", &reply));
1144
Andreas Huber53df1a42010-12-22 10:03:04 -08001145 if ((audio && IsFlushingState(mFlushingAudio))
1146 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -08001147 reply->setInt32("err", INFO_DISCONTINUITY);
1148 reply->post();
1149 return OK;
1150 }
1151
1152 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -08001153
Andreas Huber3fe62152011-09-16 15:09:22 -07001154 bool dropAccessUnit;
1155 do {
1156 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -08001157
Andreas Huber3fe62152011-09-16 15:09:22 -07001158 if (err == -EWOULDBLOCK) {
1159 return err;
1160 } else if (err != OK) {
1161 if (err == INFO_DISCONTINUITY) {
1162 int32_t type;
1163 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -08001164
Andreas Huber3fe62152011-09-16 15:09:22 -07001165 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -08001166 (audio &&
1167 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
1168 || (!audio &&
1169 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -08001170
Andreas Huber6e3d3112011-11-28 12:36:11 -08001171 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
1172
Steve Blockdf64d152012-01-04 20:05:49 +00001173 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001174 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -08001175
Andreas Huber3fe62152011-09-16 15:09:22 -07001176 if (audio) {
1177 mSkipRenderingAudioUntilMediaTimeUs = -1;
1178 } else {
1179 mSkipRenderingVideoUntilMediaTimeUs = -1;
1180 }
Andreas Huber32f3cef2011-03-02 15:34:46 -08001181
Andreas Huber6e3d3112011-11-28 12:36:11 -08001182 if (timeChange) {
1183 sp<AMessage> extra;
1184 if (accessUnit->meta()->findMessage("extra", &extra)
1185 && extra != NULL) {
1186 int64_t resumeAtMediaTimeUs;
1187 if (extra->findInt64(
1188 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001189 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001190 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -07001191
Andreas Huber6e3d3112011-11-28 12:36:11 -08001192 if (audio) {
1193 mSkipRenderingAudioUntilMediaTimeUs =
1194 resumeAtMediaTimeUs;
1195 } else {
1196 mSkipRenderingVideoUntilMediaTimeUs =
1197 resumeAtMediaTimeUs;
1198 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001199 }
Andreas Huber32f3cef2011-03-02 15:34:46 -08001200 }
1201 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001202
Andreas Huber6e3d3112011-11-28 12:36:11 -08001203 mTimeDiscontinuityPending =
1204 mTimeDiscontinuityPending || timeChange;
1205
1206 if (formatChange || timeChange) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001207 if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
1208 // And we'll resume scanning sources once we're done
1209 // flushing.
1210 mDeferredActions.push_front(
1211 new SimpleAction(
1212 &NuPlayer::performScanSources));
1213 }
1214
Robert Shih6d0a94e2014-01-23 16:18:22 -08001215 sp<AMessage> newFormat = mSource->getFormat(audio);
1216 sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder;
1217 if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) {
1218 flushDecoder(audio, /* needShutdown = */ true);
1219 } else {
1220 flushDecoder(audio, /* needShutdown = */ false);
1221 err = OK;
1222 }
Andreas Huber6e3d3112011-11-28 12:36:11 -08001223 } else {
1224 // This stream is unaffected by the discontinuity
1225
1226 if (audio) {
1227 mFlushingAudio = FLUSHED;
1228 } else {
1229 mFlushingVideo = FLUSHED;
1230 }
1231
1232 finishFlushIfPossible();
1233
1234 return -EWOULDBLOCK;
1235 }
Andreas Huber32f3cef2011-03-02 15:34:46 -08001236 }
1237
Andreas Huber3fe62152011-09-16 15:09:22 -07001238 reply->setInt32("err", err);
1239 reply->post();
1240 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -08001241 }
1242
Andreas Huber3fe62152011-09-16 15:09:22 -07001243 if (!audio) {
1244 ++mNumFramesTotal;
1245 }
1246
1247 dropAccessUnit = false;
1248 if (!audio
Lajos Molnar09524832014-07-17 14:29:51 -07001249 && !(mSourceFlags & Source::FLAG_SECURE)
Andreas Huber3fe62152011-09-16 15:09:22 -07001250 && mVideoLateByUs > 100000ll
1251 && mVideoIsAVC
1252 && !IsAVCReferenceFrame(accessUnit)) {
1253 dropAccessUnit = true;
1254 ++mNumFramesDropped;
1255 }
1256 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -08001257
Steve Block3856b092011-10-20 11:56:00 +01001258 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -08001259
1260#if 0
1261 int64_t mediaTimeUs;
1262 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +01001263 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -08001264 audio ? "audio" : "video",
1265 mediaTimeUs / 1E6);
1266#endif
1267
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001268 if (!audio) {
1269 mCCDecoder->decode(accessUnit);
1270 }
1271
Andreas Huber2d8bedd2012-02-21 14:38:23 -08001272 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -08001273 reply->post();
1274
1275 return OK;
1276}
1277
1278void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +01001279 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -08001280
1281 sp<AMessage> reply;
1282 CHECK(msg->findMessage("reply", &reply));
1283
Andreas Huber18ac5402011-08-31 15:04:25 -07001284 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
1285 // We're currently attempting to flush the decoder, in order
1286 // to complete this, the decoder wants all its buffers back,
1287 // so we don't want any output buffers it sent us (from before
1288 // we initiated the flush) to be stuck in the renderer's queue.
1289
Steve Block3856b092011-10-20 11:56:00 +01001290 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -07001291 " right back.", audio ? "audio" : "video");
1292
1293 reply->post();
1294 return;
1295 }
1296
Andreas Huber2d8bedd2012-02-21 14:38:23 -08001297 sp<ABuffer> buffer;
1298 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -08001299
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001300 int64_t mediaTimeUs;
1301 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1302
Andreas Huber32f3cef2011-03-02 15:34:46 -08001303 int64_t &skipUntilMediaTimeUs =
1304 audio
1305 ? mSkipRenderingAudioUntilMediaTimeUs
1306 : mSkipRenderingVideoUntilMediaTimeUs;
1307
1308 if (skipUntilMediaTimeUs >= 0) {
Andreas Huber32f3cef2011-03-02 15:34:46 -08001309
1310 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +01001311 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -08001312 audio ? "audio" : "video",
1313 mediaTimeUs);
1314
1315 reply->post();
1316 return;
1317 }
1318
1319 skipUntilMediaTimeUs = -1;
1320 }
1321
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001322 if (!audio && mCCDecoder->isSelected()) {
1323 mCCDecoder->display(mediaTimeUs);
1324 }
1325
Andreas Huberf9334412010-12-15 15:17:42 -08001326 mRenderer->queueBuffer(audio, buffer, reply);
1327}
1328
Chong Zhangdcb89b32013-08-06 09:44:47 -07001329void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001330 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001331 return;
1332 }
1333
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001334 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001335
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001336 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001337 return;
1338 }
1339
Chong Zhangdcb89b32013-08-06 09:44:47 -07001340 driver->notifyListener(msg, ext1, ext2, in);
Andreas Huberf9334412010-12-15 15:17:42 -08001341}
1342
Andreas Huber1aef2112011-01-04 14:01:29 -08001343void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber14f76722013-01-15 09:04:18 -08001344 ALOGV("[%s] flushDecoder needShutdown=%d",
1345 audio ? "audio" : "video", needShutdown);
1346
Andreas Huber6e3d3112011-11-28 12:36:11 -08001347 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001348 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001349 audio ? "audio" : "video");
1350 }
1351
Andreas Huber1aef2112011-01-04 14:01:29 -08001352 // Make sure we don't continue to scan sources until we finish flushing.
1353 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001354 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001355
1356 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1357 mRenderer->flush(audio);
1358
1359 FlushStatus newStatus =
1360 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1361
1362 if (audio) {
1363 CHECK(mFlushingAudio == NONE
1364 || mFlushingAudio == AWAITING_DISCONTINUITY);
1365
1366 mFlushingAudio = newStatus;
1367
1368 if (mFlushingVideo == NONE) {
1369 mFlushingVideo = (mVideoDecoder != NULL)
1370 ? AWAITING_DISCONTINUITY
1371 : FLUSHED;
1372 }
1373 } else {
1374 CHECK(mFlushingVideo == NONE
1375 || mFlushingVideo == AWAITING_DISCONTINUITY);
1376
1377 mFlushingVideo = newStatus;
1378
1379 if (mFlushingAudio == NONE) {
1380 mFlushingAudio = (mAudioDecoder != NULL)
1381 ? AWAITING_DISCONTINUITY
1382 : FLUSHED;
1383 }
1384 }
1385}
1386
Andreas Huber84066782011-08-16 09:34:26 -07001387sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1388 sp<MetaData> meta = getFormatMeta(audio);
1389
1390 if (meta == NULL) {
1391 return NULL;
1392 }
1393
1394 sp<AMessage> msg = new AMessage;
1395
1396 if(convertMetaDataToMessage(meta, &msg) == OK) {
1397 return msg;
1398 }
1399 return NULL;
1400}
1401
James Dong0d268a32012-08-31 12:18:27 -07001402status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1403 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001404 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001405 status_t ret = native_window_set_scaling_mode(
1406 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1407 if (ret != OK) {
1408 ALOGE("Failed to set scaling mode (%d): %s",
1409 -ret, strerror(-ret));
1410 return ret;
1411 }
1412 }
1413 return OK;
1414}
1415
Chong Zhangdcb89b32013-08-06 09:44:47 -07001416status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1417 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1418 msg->setPointer("reply", reply);
1419
1420 sp<AMessage> response;
1421 status_t err = msg->postAndAwaitResponse(&response);
1422 return err;
1423}
1424
1425status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
1426 sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1427 msg->setSize("trackIndex", trackIndex);
1428 msg->setInt32("select", select);
1429
1430 sp<AMessage> response;
1431 status_t err = msg->postAndAwaitResponse(&response);
1432
Chong Zhang404fced2014-06-11 14:45:31 -07001433 if (err != OK) {
1434 return err;
1435 }
1436
1437 if (!response->findInt32("err", &err)) {
1438 err = OK;
1439 }
1440
Chong Zhangdcb89b32013-08-06 09:44:47 -07001441 return err;
1442}
1443
Andreas Huberb7c8e912012-11-27 15:02:53 -08001444void NuPlayer::schedulePollDuration() {
1445 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1446 msg->setInt32("generation", mPollDurationGeneration);
1447 msg->post();
1448}
1449
1450void NuPlayer::cancelPollDuration() {
1451 ++mPollDurationGeneration;
1452}
1453
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001454void NuPlayer::processDeferredActions() {
1455 while (!mDeferredActions.empty()) {
1456 // We won't execute any deferred actions until we're no longer in
1457 // an intermediate state, i.e. one more more decoders are currently
1458 // flushing or shutting down.
1459
1460 if (mRenderer != NULL) {
1461 // There's an edge case where the renderer owns all output
1462 // buffers and is paused, therefore the decoder will not read
1463 // more input data and will never encounter the matching
1464 // discontinuity. To avoid this, we resume the renderer.
1465
1466 if (mFlushingAudio == AWAITING_DISCONTINUITY
1467 || mFlushingVideo == AWAITING_DISCONTINUITY) {
1468 mRenderer->resume();
1469 }
1470 }
1471
1472 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1473 // We're currently flushing, postpone the reset until that's
1474 // completed.
1475
1476 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1477 mFlushingAudio, mFlushingVideo);
1478
1479 break;
1480 }
1481
1482 sp<Action> action = *mDeferredActions.begin();
1483 mDeferredActions.erase(mDeferredActions.begin());
1484
1485 action->execute(this);
1486 }
1487}
1488
1489void NuPlayer::performSeek(int64_t seekTimeUs) {
1490 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1491 seekTimeUs,
1492 seekTimeUs / 1E6);
1493
1494 mSource->seekTo(seekTimeUs);
1495
1496 if (mDriver != NULL) {
1497 sp<NuPlayerDriver> driver = mDriver.promote();
1498 if (driver != NULL) {
1499 driver->notifyPosition(seekTimeUs);
1500 driver->notifySeekComplete();
1501 }
1502 }
1503
1504 // everything's flushed, continue playback.
1505}
1506
1507void NuPlayer::performDecoderFlush() {
1508 ALOGV("performDecoderFlush");
1509
Andreas Huberda9740e2013-04-16 10:54:03 -07001510 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001511 return;
1512 }
1513
1514 mTimeDiscontinuityPending = true;
1515
1516 if (mAudioDecoder != NULL) {
1517 flushDecoder(true /* audio */, false /* needShutdown */);
1518 }
1519
1520 if (mVideoDecoder != NULL) {
1521 flushDecoder(false /* audio */, false /* needShutdown */);
1522 }
1523}
1524
Andreas Huber14f76722013-01-15 09:04:18 -08001525void NuPlayer::performDecoderShutdown(bool audio, bool video) {
1526 ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001527
Andreas Huber14f76722013-01-15 09:04:18 -08001528 if ((!audio || mAudioDecoder == NULL)
1529 && (!video || mVideoDecoder == NULL)) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001530 return;
1531 }
1532
1533 mTimeDiscontinuityPending = true;
1534
Andreas Huber14f76722013-01-15 09:04:18 -08001535 if (mFlushingAudio == NONE && (!audio || mAudioDecoder == NULL)) {
1536 mFlushingAudio = FLUSHED;
1537 }
1538
1539 if (mFlushingVideo == NONE && (!video || mVideoDecoder == NULL)) {
1540 mFlushingVideo = FLUSHED;
1541 }
1542
1543 if (audio && mAudioDecoder != NULL) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001544 flushDecoder(true /* audio */, true /* needShutdown */);
1545 }
1546
Andreas Huber14f76722013-01-15 09:04:18 -08001547 if (video && mVideoDecoder != NULL) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001548 flushDecoder(false /* audio */, true /* needShutdown */);
1549 }
1550}
1551
1552void NuPlayer::performReset() {
1553 ALOGV("performReset");
1554
1555 CHECK(mAudioDecoder == NULL);
1556 CHECK(mVideoDecoder == NULL);
1557
1558 cancelPollDuration();
1559
1560 ++mScanSourcesGeneration;
1561 mScanSourcesPending = false;
1562
Lajos Molnar09524832014-07-17 14:29:51 -07001563 if (mRendererLooper != NULL) {
1564 if (mRenderer != NULL) {
1565 mRendererLooper->unregisterHandler(mRenderer->id());
1566 }
1567 mRendererLooper->stop();
1568 mRendererLooper.clear();
1569 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001570 mRenderer.clear();
1571
1572 if (mSource != NULL) {
1573 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001574
1575 looper()->unregisterHandler(mSource->id());
1576
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001577 mSource.clear();
1578 }
1579
1580 if (mDriver != NULL) {
1581 sp<NuPlayerDriver> driver = mDriver.promote();
1582 if (driver != NULL) {
1583 driver->notifyResetComplete();
1584 }
1585 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001586
1587 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001588}
1589
1590void NuPlayer::performScanSources() {
1591 ALOGV("performScanSources");
1592
Andreas Huber57a339c2012-12-03 11:18:00 -08001593 if (!mStarted) {
1594 return;
1595 }
1596
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001597 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1598 postScanSources();
1599 }
1600}
1601
Andreas Huber57a339c2012-12-03 11:18:00 -08001602void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1603 ALOGV("performSetSurface");
1604
1605 mNativeWindow = wrapper;
1606
1607 // XXX - ignore error from setVideoScalingMode for now
1608 setVideoScalingMode(mVideoScalingMode);
1609
1610 if (mDriver != NULL) {
1611 sp<NuPlayerDriver> driver = mDriver.promote();
1612 if (driver != NULL) {
1613 driver->notifySetSurfaceComplete();
1614 }
1615 }
1616}
1617
Andreas Huber9575c962013-02-05 13:59:56 -08001618void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1619 int32_t what;
1620 CHECK(msg->findInt32("what", &what));
1621
1622 switch (what) {
1623 case Source::kWhatPrepared:
1624 {
Andreas Huberb5f28d42013-04-25 15:11:19 -07001625 if (mSource == NULL) {
1626 // This is a stale notification from a source that was
1627 // asynchronously preparing when the client called reset().
1628 // We handled the reset, the source is gone.
1629 break;
1630 }
1631
Andreas Huberec0c5972013-02-05 14:47:13 -08001632 int32_t err;
1633 CHECK(msg->findInt32("err", &err));
1634
Andreas Huber9575c962013-02-05 13:59:56 -08001635 sp<NuPlayerDriver> driver = mDriver.promote();
1636 if (driver != NULL) {
Marco Nelissendd114d12014-05-28 15:23:14 -07001637 // notify duration first, so that it's definitely set when
1638 // the app received the "prepare complete" callback.
1639 int64_t durationUs;
1640 if (mSource->getDuration(&durationUs) == OK) {
1641 driver->notifyDuration(durationUs);
1642 }
Andreas Huberec0c5972013-02-05 14:47:13 -08001643 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08001644 }
Andreas Huber99759402013-04-01 14:28:31 -07001645
Andreas Huber9575c962013-02-05 13:59:56 -08001646 break;
1647 }
1648
1649 case Source::kWhatFlagsChanged:
1650 {
1651 uint32_t flags;
1652 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1653
Chong Zhang4b7069d2013-09-11 12:52:43 -07001654 sp<NuPlayerDriver> driver = mDriver.promote();
1655 if (driver != NULL) {
1656 driver->notifyFlagsChanged(flags);
1657 }
1658
Andreas Huber9575c962013-02-05 13:59:56 -08001659 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1660 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1661 cancelPollDuration();
1662 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1663 && (flags & Source::FLAG_DYNAMIC_DURATION)
1664 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1665 schedulePollDuration();
1666 }
1667
1668 mSourceFlags = flags;
1669 break;
1670 }
1671
1672 case Source::kWhatVideoSizeChanged:
1673 {
1674 int32_t width, height;
1675 CHECK(msg->findInt32("width", &width));
1676 CHECK(msg->findInt32("height", &height));
1677
1678 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
1679 break;
1680 }
1681
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001682 case Source::kWhatBufferingStart:
1683 {
1684 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1685 break;
1686 }
1687
1688 case Source::kWhatBufferingEnd:
1689 {
1690 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1691 break;
1692 }
1693
Chong Zhangdcb89b32013-08-06 09:44:47 -07001694 case Source::kWhatSubtitleData:
1695 {
1696 sp<ABuffer> buffer;
1697 CHECK(msg->findBuffer("buffer", &buffer));
1698
Chong Zhang404fced2014-06-11 14:45:31 -07001699 sendSubtitleData(buffer, 0 /* baseIndex */);
Chong Zhangdcb89b32013-08-06 09:44:47 -07001700 break;
1701 }
1702
Andreas Huber14f76722013-01-15 09:04:18 -08001703 case Source::kWhatQueueDecoderShutdown:
1704 {
1705 int32_t audio, video;
1706 CHECK(msg->findInt32("audio", &audio));
1707 CHECK(msg->findInt32("video", &video));
1708
1709 sp<AMessage> reply;
1710 CHECK(msg->findMessage("reply", &reply));
1711
1712 queueDecoderShutdown(audio, video, reply);
1713 break;
1714 }
1715
Andreas Huber9575c962013-02-05 13:59:56 -08001716 default:
1717 TRESPASS();
1718 }
1719}
1720
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001721void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
1722 int32_t what;
1723 CHECK(msg->findInt32("what", &what));
1724
1725 switch (what) {
1726 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
1727 {
1728 sp<ABuffer> buffer;
1729 CHECK(msg->findBuffer("buffer", &buffer));
1730
1731 size_t inbandTracks = 0;
1732 if (mSource != NULL) {
1733 inbandTracks = mSource->getTrackCount();
1734 }
1735
1736 sendSubtitleData(buffer, inbandTracks);
1737 break;
1738 }
1739
1740 case NuPlayer::CCDecoder::kWhatTrackAdded:
1741 {
1742 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
1743
1744 break;
1745 }
1746
1747 default:
1748 TRESPASS();
1749 }
1750
1751
1752}
1753
Chong Zhang404fced2014-06-11 14:45:31 -07001754void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
1755 int32_t trackIndex;
1756 int64_t timeUs, durationUs;
1757 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
1758 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1759 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
1760
1761 Parcel in;
1762 in.writeInt32(trackIndex + baseIndex);
1763 in.writeInt64(timeUs);
1764 in.writeInt64(durationUs);
1765 in.writeInt32(buffer->size());
1766 in.writeInt32(buffer->size());
1767 in.write(buffer->data(), buffer->size());
1768
1769 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
1770}
Andreas Huberb5f25f02013-02-05 10:14:26 -08001771////////////////////////////////////////////////////////////////////////////////
1772
Andreas Huber9575c962013-02-05 13:59:56 -08001773void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1774 sp<AMessage> notify = dupNotify();
1775 notify->setInt32("what", kWhatFlagsChanged);
1776 notify->setInt32("flags", flags);
1777 notify->post();
1778}
1779
1780void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
1781 sp<AMessage> notify = dupNotify();
1782 notify->setInt32("what", kWhatVideoSizeChanged);
1783 notify->setInt32("width", width);
1784 notify->setInt32("height", height);
1785 notify->post();
1786}
1787
Andreas Huberec0c5972013-02-05 14:47:13 -08001788void NuPlayer::Source::notifyPrepared(status_t err) {
Andreas Huber9575c962013-02-05 13:59:56 -08001789 sp<AMessage> notify = dupNotify();
1790 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08001791 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08001792 notify->post();
1793}
1794
Andreas Huber84333e02014-02-07 15:36:10 -08001795void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
Andreas Huberb5f25f02013-02-05 10:14:26 -08001796 TRESPASS();
1797}
1798
Andreas Huber14f76722013-01-15 09:04:18 -08001799void NuPlayer::queueDecoderShutdown(
1800 bool audio, bool video, const sp<AMessage> &reply) {
1801 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1802
1803 mDeferredActions.push_back(
1804 new ShutdownDecoderAction(audio, video));
1805
1806 mDeferredActions.push_back(
1807 new SimpleAction(&NuPlayer::performScanSources));
1808
1809 mDeferredActions.push_back(new PostMessageAction(reply));
1810
1811 processDeferredActions();
1812}
1813
Andreas Huberf9334412010-12-15 15:17:42 -08001814} // namespace android