blob: ae221231efb4f28b96be5e549a6277d8f1f6c7d7 [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"
Robert Shihd3b0bbb2014-07-23 15:00:25 -070032#include "TextDescriptions.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080033
34#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080035
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>
Lajos Molnar09524832014-07-17 14:29:51 -070040#include <media/stagefright/MediaBuffer.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 Huber14f76722013-01-15 09:04:18 -080092struct NuPlayer::ShutdownDecoderAction : public Action {
93 ShutdownDecoderAction(bool audio, bool video)
94 : mAudio(audio),
95 mVideo(video) {
96 }
97
98 virtual void execute(NuPlayer *player) {
99 player->performDecoderShutdown(mAudio, mVideo);
100 }
101
102private:
103 bool mAudio;
104 bool mVideo;
105
106 DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction);
107};
108
109struct NuPlayer::PostMessageAction : public Action {
110 PostMessageAction(const sp<AMessage> &msg)
111 : mMessage(msg) {
112 }
113
114 virtual void execute(NuPlayer *) {
115 mMessage->post();
116 }
117
118private:
119 sp<AMessage> mMessage;
120
121 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
122};
123
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800124// Use this if there's no state necessary to save in order to execute
125// the action.
126struct NuPlayer::SimpleAction : public Action {
127 typedef void (NuPlayer::*ActionFunc)();
128
129 SimpleAction(ActionFunc func)
130 : mFunc(func) {
131 }
132
133 virtual void execute(NuPlayer *player) {
134 (player->*mFunc)();
135 }
136
137private:
138 ActionFunc mFunc;
139
140 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
141};
142
Andreas Huberf9334412010-12-15 15:17:42 -0800143////////////////////////////////////////////////////////////////////////////////
144
145NuPlayer::NuPlayer()
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700146 : mUIDValid(false),
Andreas Huber9575c962013-02-05 13:59:56 -0800147 mSourceFlags(0),
Wei Jiaac428aa2014-09-02 19:01:34 -0700148 mCurrentPositionUs(0),
Andreas Huber3fe62152011-09-16 15:09:22 -0700149 mVideoIsAVC(false),
Wei Jiabc2fb722014-07-08 16:37:57 -0700150 mOffloadAudio(false),
Andy Hung282a7e32014-08-14 15:56:34 -0700151 mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
Wei Jia88703c32014-08-06 11:24:07 -0700152 mAudioDecoderGeneration(0),
153 mVideoDecoderGeneration(0),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700154 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800155 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800156 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800157 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800158 mPollDurationGeneration(0),
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700159 mTimedTextGeneration(0),
Andreas Huber6e3d3112011-11-28 12:36:11 -0800160 mTimeDiscontinuityPending(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800161 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800162 mFlushingVideo(NONE),
Andreas Huber3fe62152011-09-16 15:09:22 -0700163 mSkipRenderingAudioUntilMediaTimeUs(-1ll),
164 mSkipRenderingVideoUntilMediaTimeUs(-1ll),
165 mVideoLateByUs(0ll),
166 mNumFramesTotal(0ll),
James Dong0d268a32012-08-31 12:18:27 -0700167 mNumFramesDropped(0ll),
Andreas Huber57a339c2012-12-03 11:18:00 -0800168 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
169 mStarted(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800170}
171
172NuPlayer::~NuPlayer() {
173}
174
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700175void NuPlayer::setUID(uid_t uid) {
176 mUIDValid = true;
177 mUID = uid;
178}
179
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800180void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
181 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800182}
183
Andreas Huber9575c962013-02-05 13:59:56 -0800184void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Andreas Huberf9334412010-12-15 15:17:42 -0800185 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
186
Andreas Huberb5f25f02013-02-05 10:14:26 -0800187 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
188
Andreas Huber240abcc2014-02-13 13:32:37 -0800189 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber5bc087c2010-12-23 10:27:40 -0800190 msg->post();
191}
Andreas Huberf9334412010-12-15 15:17:42 -0800192
Andreas Huberafed0e12011-09-20 15:39:58 -0700193static bool IsHTTPLiveURL(const char *url) {
194 if (!strncasecmp("http://", url, 7)
Andreas Huber99759402013-04-01 14:28:31 -0700195 || !strncasecmp("https://", url, 8)
196 || !strncasecmp("file://", url, 7)) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700197 size_t len = strlen(url);
198 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
199 return true;
200 }
201
202 if (strstr(url,"m3u8")) {
203 return true;
204 }
205 }
206
207 return false;
208}
209
Andreas Huber9575c962013-02-05 13:59:56 -0800210void NuPlayer::setDataSourceAsync(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800211 const sp<IMediaHTTPService> &httpService,
212 const char *url,
213 const KeyedVector<String8, String8> *headers) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700214
Andreas Huber5bc087c2010-12-23 10:27:40 -0800215 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100216 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800217
Andreas Huberb5f25f02013-02-05 10:14:26 -0800218 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
219
Andreas Huberafed0e12011-09-20 15:39:58 -0700220 sp<Source> source;
221 if (IsHTTPLiveURL(url)) {
Andreas Huber81e68442014-02-05 11:52:33 -0800222 source = new HTTPLiveSource(notify, httpService, url, headers);
Andreas Huberafed0e12011-09-20 15:39:58 -0700223 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800224 source = new RTSPSource(
225 notify, httpService, url, headers, mUIDValid, mUID);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100226 } else if ((!strncasecmp(url, "http://", 7)
227 || !strncasecmp(url, "https://", 8))
228 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
229 || strstr(url, ".sdp?"))) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800230 source = new RTSPSource(
231 notify, httpService, url, headers, mUIDValid, mUID, true);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700232 } else {
Chong Zhang3de157d2014-08-05 20:54:44 -0700233 sp<GenericSource> genericSource =
234 new GenericSource(notify, mUIDValid, mUID);
235 // Don't set FLAG_SECURE on mSourceFlags here for widevine.
236 // The correct flags will be updated in Source::kWhatFlagsChanged
237 // handler when GenericSource is prepared.
Andreas Huber2bfdd422011-10-11 15:24:07 -0700238
Chong Zhanga19f33e2014-08-07 15:35:07 -0700239 status_t err = genericSource->setDataSource(httpService, url, headers);
Chong Zhang3de157d2014-08-05 20:54:44 -0700240
241 if (err == OK) {
242 source = genericSource;
243 } else {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700244 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700245 }
246 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700247 msg->setObject("source", source);
248 msg->post();
249}
250
Andreas Huber9575c962013-02-05 13:59:56 -0800251void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700252 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
253
Andreas Huberb5f25f02013-02-05 10:14:26 -0800254 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
255
Chong Zhang3de157d2014-08-05 20:54:44 -0700256 sp<GenericSource> source =
257 new GenericSource(notify, mUIDValid, mUID);
258
Chong Zhanga19f33e2014-08-07 15:35:07 -0700259 status_t err = source->setDataSource(fd, offset, length);
Chong Zhang3de157d2014-08-05 20:54:44 -0700260
261 if (err != OK) {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700262 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700263 source = NULL;
264 }
265
Andreas Huberafed0e12011-09-20 15:39:58 -0700266 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800267 msg->post();
268}
269
Andreas Huber9575c962013-02-05 13:59:56 -0800270void NuPlayer::prepareAsync() {
271 (new AMessage(kWhatPrepare, id()))->post();
272}
273
Andreas Huber57a339c2012-12-03 11:18:00 -0800274void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800275 const sp<IGraphicBufferProducer> &bufferProducer) {
Glenn Kasten11731182011-02-08 17:26:17 -0800276 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
Andreas Huber57a339c2012-12-03 11:18:00 -0800277
Andy McFadden8ba01022012-12-18 09:46:54 -0800278 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800279 msg->setObject("native-window", NULL);
280 } else {
281 msg->setObject(
282 "native-window",
283 new NativeWindowWrapper(
Wei Jia9c03a402014-08-26 15:24:43 -0700284 new Surface(bufferProducer, true /* controlledByApp */)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800285 }
286
Andreas Huberf9334412010-12-15 15:17:42 -0800287 msg->post();
288}
289
290void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
291 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
292 msg->setObject("sink", sink);
293 msg->post();
294}
295
296void NuPlayer::start() {
297 (new AMessage(kWhatStart, id()))->post();
298}
299
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800300void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800301 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800302}
303
304void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800305 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800306}
307
Andreas Huber1aef2112011-01-04 14:01:29 -0800308void NuPlayer::resetAsync() {
309 (new AMessage(kWhatReset, id()))->post();
310}
311
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800312void NuPlayer::seekToAsync(int64_t seekTimeUs) {
313 sp<AMessage> msg = new AMessage(kWhatSeek, id());
314 msg->setInt64("seekTimeUs", seekTimeUs);
315 msg->post();
316}
317
Andreas Huber53df1a42010-12-22 10:03:04 -0800318// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800319bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800320 switch (state) {
321 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800322 if (needShutdown != NULL) {
323 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800324 }
325 return true;
326
Andreas Huber1aef2112011-01-04 14:01:29 -0800327 case FLUSHING_DECODER_SHUTDOWN:
328 if (needShutdown != NULL) {
329 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800330 }
331 return true;
332
333 default:
334 return false;
335 }
336}
337
Chong Zhang404fced2014-06-11 14:45:31 -0700338void NuPlayer::writeTrackInfo(
339 Parcel* reply, const sp<AMessage> format) const {
340 int32_t trackType;
341 CHECK(format->findInt32("type", &trackType));
342
343 AString lang;
344 CHECK(format->findString("language", &lang));
345
346 reply->writeInt32(2); // write something non-zero
347 reply->writeInt32(trackType);
348 reply->writeString16(String16(lang.c_str()));
349
350 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
351 AString mime;
352 CHECK(format->findString("mime", &mime));
353
354 int32_t isAuto, isDefault, isForced;
355 CHECK(format->findInt32("auto", &isAuto));
356 CHECK(format->findInt32("default", &isDefault));
357 CHECK(format->findInt32("forced", &isForced));
358
359 reply->writeString16(String16(mime.c_str()));
360 reply->writeInt32(isAuto);
361 reply->writeInt32(isDefault);
362 reply->writeInt32(isForced);
363 }
364}
365
Andreas Huberf9334412010-12-15 15:17:42 -0800366void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
367 switch (msg->what()) {
368 case kWhatSetDataSource:
369 {
Steve Block3856b092011-10-20 11:56:00 +0100370 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800371
372 CHECK(mSource == NULL);
373
Chong Zhang3de157d2014-08-05 20:54:44 -0700374 status_t err = OK;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800375 sp<RefBase> obj;
376 CHECK(msg->findObject("source", &obj));
Chong Zhang3de157d2014-08-05 20:54:44 -0700377 if (obj != NULL) {
378 mSource = static_cast<Source *>(obj.get());
Chong Zhang3de157d2014-08-05 20:54:44 -0700379 } else {
380 err = UNKNOWN_ERROR;
381 }
Andreas Huber9575c962013-02-05 13:59:56 -0800382
383 CHECK(mDriver != NULL);
384 sp<NuPlayerDriver> driver = mDriver.promote();
385 if (driver != NULL) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700386 driver->notifySetDataSourceCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -0800387 }
388 break;
389 }
390
391 case kWhatPrepare:
392 {
393 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800394 break;
395 }
396
Chong Zhangdcb89b32013-08-06 09:44:47 -0700397 case kWhatGetTrackInfo:
398 {
399 uint32_t replyID;
400 CHECK(msg->senderAwaitsResponse(&replyID));
401
Chong Zhang404fced2014-06-11 14:45:31 -0700402 Parcel* reply;
403 CHECK(msg->findPointer("reply", (void**)&reply));
404
405 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700406 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700407 inbandTracks = mSource->getTrackCount();
408 }
409
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700410 size_t ccTracks = 0;
411 if (mCCDecoder != NULL) {
412 ccTracks = mCCDecoder->getTrackCount();
413 }
414
Chong Zhang404fced2014-06-11 14:45:31 -0700415 // total track count
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700416 reply->writeInt32(inbandTracks + ccTracks);
Chong Zhang404fced2014-06-11 14:45:31 -0700417
418 // write inband tracks
419 for (size_t i = 0; i < inbandTracks; ++i) {
420 writeTrackInfo(reply, mSource->getTrackInfo(i));
Chong Zhangdcb89b32013-08-06 09:44:47 -0700421 }
422
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700423 // write CC track
424 for (size_t i = 0; i < ccTracks; ++i) {
425 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
426 }
427
Chong Zhangdcb89b32013-08-06 09:44:47 -0700428 sp<AMessage> response = new AMessage;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700429 response->postReply(replyID);
430 break;
431 }
432
Robert Shih7c4f0d72014-07-09 18:53:31 -0700433 case kWhatGetSelectedTrack:
434 {
435 status_t err = INVALID_OPERATION;
436 if (mSource != NULL) {
437 err = OK;
438
439 int32_t type32;
440 CHECK(msg->findInt32("type", (int32_t*)&type32));
441 media_track_type type = (media_track_type)type32;
442 ssize_t selectedTrack = mSource->getSelectedTrack(type);
443
444 Parcel* reply;
445 CHECK(msg->findPointer("reply", (void**)&reply));
446 reply->writeInt32(selectedTrack);
447 }
448
449 sp<AMessage> response = new AMessage;
450 response->setInt32("err", err);
451
452 uint32_t replyID;
453 CHECK(msg->senderAwaitsResponse(&replyID));
454 response->postReply(replyID);
455 break;
456 }
457
Chong Zhangdcb89b32013-08-06 09:44:47 -0700458 case kWhatSelectTrack:
459 {
460 uint32_t replyID;
461 CHECK(msg->senderAwaitsResponse(&replyID));
462
Chong Zhang404fced2014-06-11 14:45:31 -0700463 size_t trackIndex;
464 int32_t select;
465 CHECK(msg->findSize("trackIndex", &trackIndex));
466 CHECK(msg->findInt32("select", &select));
467
Chong Zhangdcb89b32013-08-06 09:44:47 -0700468 status_t err = INVALID_OPERATION;
Chong Zhang404fced2014-06-11 14:45:31 -0700469
470 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700471 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700472 inbandTracks = mSource->getTrackCount();
473 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700474 size_t ccTracks = 0;
475 if (mCCDecoder != NULL) {
476 ccTracks = mCCDecoder->getTrackCount();
477 }
Chong Zhang404fced2014-06-11 14:45:31 -0700478
479 if (trackIndex < inbandTracks) {
Chong Zhangdcb89b32013-08-06 09:44:47 -0700480 err = mSource->selectTrack(trackIndex, select);
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700481
482 if (!select && err == OK) {
483 int32_t type;
484 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
485 if (info != NULL
486 && info->findInt32("type", &type)
487 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
488 ++mTimedTextGeneration;
489 }
490 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700491 } else {
492 trackIndex -= inbandTracks;
493
494 if (trackIndex < ccTracks) {
495 err = mCCDecoder->selectTrack(trackIndex, select);
496 }
Chong Zhangdcb89b32013-08-06 09:44:47 -0700497 }
498
499 sp<AMessage> response = new AMessage;
500 response->setInt32("err", err);
501
502 response->postReply(replyID);
503 break;
504 }
505
Andreas Huberb7c8e912012-11-27 15:02:53 -0800506 case kWhatPollDuration:
507 {
508 int32_t generation;
509 CHECK(msg->findInt32("generation", &generation));
510
511 if (generation != mPollDurationGeneration) {
512 // stale
513 break;
514 }
515
516 int64_t durationUs;
517 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
518 sp<NuPlayerDriver> driver = mDriver.promote();
519 if (driver != NULL) {
520 driver->notifyDuration(durationUs);
521 }
522 }
523
524 msg->post(1000000ll); // poll again in a second.
525 break;
526 }
527
Glenn Kasten11731182011-02-08 17:26:17 -0800528 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800529 {
Steve Block3856b092011-10-20 11:56:00 +0100530 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800531
Andreas Huber57a339c2012-12-03 11:18:00 -0800532 mDeferredActions.push_back(
Andreas Huber14f76722013-01-15 09:04:18 -0800533 new ShutdownDecoderAction(
534 false /* audio */, true /* video */));
Andreas Huber57a339c2012-12-03 11:18:00 -0800535
Andreas Huberf9334412010-12-15 15:17:42 -0800536 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800537 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800538
Andreas Huber57a339c2012-12-03 11:18:00 -0800539 mDeferredActions.push_back(
540 new SetSurfaceAction(
541 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700542
Andreas Huber57a339c2012-12-03 11:18:00 -0800543 if (obj != NULL) {
Wei Jiaac428aa2014-09-02 19:01:34 -0700544 mDeferredActions.push_back(new SeekAction(mCurrentPositionUs));
545
Andreas Huber57a339c2012-12-03 11:18:00 -0800546 // If there is a new surface texture, instantiate decoders
547 // again if possible.
548 mDeferredActions.push_back(
549 new SimpleAction(&NuPlayer::performScanSources));
550 }
551
552 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800553 break;
554 }
555
556 case kWhatSetAudioSink:
557 {
Steve Block3856b092011-10-20 11:56:00 +0100558 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800559
560 sp<RefBase> obj;
561 CHECK(msg->findObject("sink", &obj));
562
563 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
564 break;
565 }
566
567 case kWhatStart:
568 {
Steve Block3856b092011-10-20 11:56:00 +0100569 ALOGV("kWhatStart");
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800570
Andreas Huber3fe62152011-09-16 15:09:22 -0700571 mVideoIsAVC = false;
Wei Jiabc2fb722014-07-08 16:37:57 -0700572 mOffloadAudio = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800573 mAudioEOS = false;
574 mVideoEOS = false;
Andreas Huber32f3cef2011-03-02 15:34:46 -0800575 mSkipRenderingAudioUntilMediaTimeUs = -1;
576 mSkipRenderingVideoUntilMediaTimeUs = -1;
Andreas Huber3fe62152011-09-16 15:09:22 -0700577 mVideoLateByUs = 0;
578 mNumFramesTotal = 0;
579 mNumFramesDropped = 0;
Andreas Huber57a339c2012-12-03 11:18:00 -0800580 mStarted = true;
Andreas Huber1aef2112011-01-04 14:01:29 -0800581
Lajos Molnar09524832014-07-17 14:29:51 -0700582 /* instantiate decoders now for secure playback */
583 if (mSourceFlags & Source::FLAG_SECURE) {
584 if (mNativeWindow != NULL) {
585 instantiateDecoder(false, &mVideoDecoder);
586 }
587
588 if (mAudioSink != NULL) {
589 instantiateDecoder(true, &mAudioDecoder);
590 }
591 }
592
Andreas Huber5bc087c2010-12-23 10:27:40 -0800593 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800594
Andreas Huberd5e56232013-03-12 11:01:43 -0700595 uint32_t flags = 0;
596
597 if (mSource->isRealTime()) {
598 flags |= Renderer::FLAG_REAL_TIME;
599 }
600
Wei Jiabc2fb722014-07-08 16:37:57 -0700601 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
602 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
603 if (mAudioSink != NULL) {
604 streamType = mAudioSink->getAudioStreamType();
605 }
606
607 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
608
609 mOffloadAudio =
610 canOffloadStream(audioMeta, (videoFormat != NULL),
611 true /* is_streaming */, streamType);
612 if (mOffloadAudio) {
613 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
614 }
615
Andreas Huberf9334412010-12-15 15:17:42 -0800616 mRenderer = new Renderer(
617 mAudioSink,
Andreas Huberd5e56232013-03-12 11:01:43 -0700618 new AMessage(kWhatRendererNotify, id()),
619 flags);
Andreas Huberf9334412010-12-15 15:17:42 -0800620
Lajos Molnar09524832014-07-17 14:29:51 -0700621 mRendererLooper = new ALooper;
622 mRendererLooper->setName("NuPlayerRenderer");
623 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
624 mRendererLooper->registerHandler(mRenderer);
Andreas Huberf9334412010-12-15 15:17:42 -0800625
Andreas Huber1aef2112011-01-04 14:01:29 -0800626 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800627 break;
628 }
629
630 case kWhatScanSources:
631 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800632 int32_t generation;
633 CHECK(msg->findInt32("generation", &generation));
634 if (generation != mScanSourcesGeneration) {
635 // Drop obsolete msg.
636 break;
637 }
638
Andreas Huber5bc087c2010-12-23 10:27:40 -0800639 mScanSourcesPending = false;
640
Steve Block3856b092011-10-20 11:56:00 +0100641 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800642 mAudioDecoder != NULL, mVideoDecoder != NULL);
643
Andreas Huberb7c8e912012-11-27 15:02:53 -0800644 bool mHadAnySourcesBefore =
645 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
646
Andy Hung282a7e32014-08-14 15:56:34 -0700647 // initialize video before audio because successful initialization of
648 // video may change deep buffer mode of audio.
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700649 if (mNativeWindow != NULL) {
650 instantiateDecoder(false, &mVideoDecoder);
651 }
Andreas Huberf9334412010-12-15 15:17:42 -0800652
653 if (mAudioSink != NULL) {
Andy Hung282a7e32014-08-14 15:56:34 -0700654 if (mOffloadAudio) {
655 // open audio sink early under offload mode.
656 sp<AMessage> format = mSource->getFormat(true /*audio*/);
657 openAudioSink(format, true /*offloadOnly*/);
658 }
Andreas Huber5bc087c2010-12-23 10:27:40 -0800659 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800660 }
661
Andreas Huberb7c8e912012-11-27 15:02:53 -0800662 if (!mHadAnySourcesBefore
663 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
664 // This is the first time we've found anything playable.
665
Andreas Huber9575c962013-02-05 13:59:56 -0800666 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800667 schedulePollDuration();
668 }
669 }
670
Andreas Hubereac68ba2011-09-27 12:12:25 -0700671 status_t err;
672 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800673 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
674 // We're not currently decoding anything (no audio or
675 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700676
677 if (err == ERROR_END_OF_STREAM) {
678 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
679 } else {
680 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
681 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800682 }
Andreas Huberf9334412010-12-15 15:17:42 -0800683 break;
684 }
685
Andreas Huberfbe9d812012-08-31 14:05:27 -0700686 if ((mAudioDecoder == NULL && mAudioSink != NULL)
687 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800688 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800689 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800690 }
691 break;
692 }
693
694 case kWhatVideoNotify:
695 case kWhatAudioNotify:
696 {
697 bool audio = msg->what() == kWhatAudioNotify;
698
Wei Jia88703c32014-08-06 11:24:07 -0700699 int32_t currentDecoderGeneration =
700 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
701 int32_t requesterGeneration = currentDecoderGeneration - 1;
702 CHECK(msg->findInt32("generation", &requesterGeneration));
703
704 if (requesterGeneration != currentDecoderGeneration) {
705 ALOGV("got message from old %s decoder, generation(%d:%d)",
706 audio ? "audio" : "video", requesterGeneration,
707 currentDecoderGeneration);
708 sp<AMessage> reply;
709 if (!(msg->findMessage("reply", &reply))) {
710 return;
711 }
712
713 reply->setInt32("err", INFO_DISCONTINUITY);
714 reply->post();
715 return;
716 }
717
Andreas Huberf9334412010-12-15 15:17:42 -0800718 int32_t what;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800719 CHECK(msg->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -0800720
Lajos Molnar1cd13982014-01-17 15:12:51 -0800721 if (what == Decoder::kWhatFillThisBuffer) {
Andreas Huberf9334412010-12-15 15:17:42 -0800722 status_t err = feedDecoderInputData(
Lajos Molnar1cd13982014-01-17 15:12:51 -0800723 audio, msg);
Andreas Huberf9334412010-12-15 15:17:42 -0800724
Andreas Huber5bc087c2010-12-23 10:27:40 -0800725 if (err == -EWOULDBLOCK) {
Andreas Hubereac68ba2011-09-27 12:12:25 -0700726 if (mSource->feedMoreTSData() == OK) {
Andreas Huber1183a4a2011-11-03 11:00:21 -0700727 msg->post(10000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800728 }
Andreas Huberf9334412010-12-15 15:17:42 -0800729 }
Lajos Molnar1cd13982014-01-17 15:12:51 -0800730 } else if (what == Decoder::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700731 int32_t err;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800732 CHECK(msg->findInt32("err", &err));
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700733
734 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100735 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700736 } else {
Steve Block3856b092011-10-20 11:56:00 +0100737 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700738 audio ? "audio" : "video",
739 err);
740 }
741
742 mRenderer->queueEOS(audio, err);
Lajos Molnar1cd13982014-01-17 15:12:51 -0800743 } else if (what == Decoder::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800744 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800745
Andreas Huberf9334412010-12-15 15:17:42 -0800746 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800747 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800748 mFlushingAudio = FLUSHED;
749 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800750 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800751 mFlushingVideo = FLUSHED;
Andreas Huber3fe62152011-09-16 15:09:22 -0700752
753 mVideoLateByUs = 0;
Andreas Huberf9334412010-12-15 15:17:42 -0800754 }
755
Steve Block3856b092011-10-20 11:56:00 +0100756 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800757
Andreas Huber1aef2112011-01-04 14:01:29 -0800758 if (needShutdown) {
Steve Block3856b092011-10-20 11:56:00 +0100759 ALOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800760 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800761
Lajos Molnar87603c02014-08-20 19:25:30 -0700762 getDecoder(audio)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800763
Andreas Huber53df1a42010-12-22 10:03:04 -0800764 if (audio) {
765 mFlushingAudio = SHUTTING_DOWN_DECODER;
766 } else {
767 mFlushingVideo = SHUTTING_DOWN_DECODER;
768 }
Andreas Huberf9334412010-12-15 15:17:42 -0800769 }
Andreas Huber3831a062010-12-21 10:22:33 -0800770
771 finishFlushIfPossible();
Lajos Molnar1cd13982014-01-17 15:12:51 -0800772 } else if (what == Decoder::kWhatOutputFormatChanged) {
773 sp<AMessage> format;
774 CHECK(msg->findMessage("format", &format));
775
Andreas Huber31e25082011-01-10 10:38:31 -0800776 if (audio) {
Andy Hung282a7e32014-08-14 15:56:34 -0700777 openAudioSink(format, false /*offloadOnly*/);
Andreas Huber31e25082011-01-10 10:38:31 -0800778 } else {
779 // video
Chong Zhangced1c2f2014-08-08 15:22:35 -0700780 sp<AMessage> inputFormat =
781 mSource->getFormat(false /* audio */);
Andreas Huber3831a062010-12-21 10:22:33 -0800782
Chong Zhangced1c2f2014-08-08 15:22:35 -0700783 updateVideoSize(inputFormat, format);
Andreas Huber31e25082011-01-10 10:38:31 -0800784 }
Lajos Molnar1cd13982014-01-17 15:12:51 -0800785 } else if (what == Decoder::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100786 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800787 if (audio) {
788 mAudioDecoder.clear();
789
790 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
791 mFlushingAudio = SHUT_DOWN;
792 } else {
793 mVideoDecoder.clear();
794
795 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
796 mFlushingVideo = SHUT_DOWN;
797 }
798
799 finishFlushIfPossible();
Lajos Molnar1cd13982014-01-17 15:12:51 -0800800 } else if (what == Decoder::kWhatError) {
Steve Block29357bc2012-01-06 19:20:56 +0000801 ALOGE("Received error from %s decoder, aborting playback.",
Andreas Huberc92fd242011-08-16 13:48:44 -0700802 audio ? "audio" : "video");
803
Chong Zhangf4c0a942014-08-11 15:14:10 -0700804 status_t err;
805 if (!msg->findInt32("err", &err)) {
806 err = UNKNOWN_ERROR;
807 }
808 mRenderer->queueEOS(audio, err);
Marco Nelissen9e2b7912014-08-18 16:13:03 -0700809 if (audio && mFlushingAudio != NONE) {
810 mAudioDecoder.clear();
811 mFlushingAudio = SHUT_DOWN;
812 } else if (!audio && mFlushingVideo != NONE){
813 mVideoDecoder.clear();
814 mFlushingVideo = SHUT_DOWN;
815 }
816 finishFlushIfPossible();
Lajos Molnar1cd13982014-01-17 15:12:51 -0800817 } else if (what == Decoder::kWhatDrainThisBuffer) {
818 renderBuffer(audio, msg);
819 } else {
820 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800821 what,
822 what >> 24,
823 (what >> 16) & 0xff,
824 (what >> 8) & 0xff,
825 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800826 }
827
828 break;
829 }
830
831 case kWhatRendererNotify:
832 {
833 int32_t what;
834 CHECK(msg->findInt32("what", &what));
835
836 if (what == Renderer::kWhatEOS) {
837 int32_t audio;
838 CHECK(msg->findInt32("audio", &audio));
839
Andreas Huberc92fd242011-08-16 13:48:44 -0700840 int32_t finalResult;
841 CHECK(msg->findInt32("finalResult", &finalResult));
842
Andreas Huberf9334412010-12-15 15:17:42 -0800843 if (audio) {
844 mAudioEOS = true;
845 } else {
846 mVideoEOS = true;
847 }
848
Andreas Huberc92fd242011-08-16 13:48:44 -0700849 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100850 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700851 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000852 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700853 audio ? "audio" : "video", finalResult);
854
855 notifyListener(
856 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
857 }
Andreas Huberf9334412010-12-15 15:17:42 -0800858
859 if ((mAudioEOS || mAudioDecoder == NULL)
860 && (mVideoEOS || mVideoDecoder == NULL)) {
861 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
862 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800863 } else if (what == Renderer::kWhatPosition) {
864 int64_t positionUs;
865 CHECK(msg->findInt64("positionUs", &positionUs));
Wei Jiaac428aa2014-09-02 19:01:34 -0700866 mCurrentPositionUs = positionUs;
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800867
Andreas Huber3fe62152011-09-16 15:09:22 -0700868 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
869
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800870 if (mDriver != NULL) {
871 sp<NuPlayerDriver> driver = mDriver.promote();
872 if (driver != NULL) {
873 driver->notifyPosition(positionUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700874
875 driver->notifyFrameStats(
876 mNumFramesTotal, mNumFramesDropped);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800877 }
878 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700879 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800880 int32_t audio;
881 CHECK(msg->findInt32("audio", &audio));
882
Steve Block3856b092011-10-20 11:56:00 +0100883 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
James Dongf57b4ea2012-07-20 13:38:36 -0700884 } else if (what == Renderer::kWhatVideoRenderingStart) {
885 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Lajos Molnarcbaffcf2013-08-14 18:30:38 -0700886 } else if (what == Renderer::kWhatMediaRenderingStart) {
887 ALOGV("media rendering started");
888 notifyListener(MEDIA_STARTED, 0, 0);
Wei Jia3a2956d2014-07-22 16:01:33 -0700889 } else if (what == Renderer::kWhatAudioOffloadTearDown) {
890 ALOGV("Tear down audio offload, fall back to s/w path");
891 int64_t positionUs;
892 CHECK(msg->findInt64("positionUs", &positionUs));
Andy Hung282a7e32014-08-14 15:56:34 -0700893 closeAudioSink();
Wei Jia3a2956d2014-07-22 16:01:33 -0700894 mAudioDecoder.clear();
895 mRenderer->flush(true /* audio */);
896 if (mVideoDecoder != NULL) {
897 mRenderer->flush(false /* audio */);
898 }
899 mRenderer->signalDisableOffloadAudio();
900 mOffloadAudio = false;
901
902 performSeek(positionUs);
903 instantiateDecoder(true /* audio */, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800904 }
905 break;
906 }
907
908 case kWhatMoreDataQueued:
909 {
910 break;
911 }
912
Andreas Huber1aef2112011-01-04 14:01:29 -0800913 case kWhatReset:
914 {
Steve Block3856b092011-10-20 11:56:00 +0100915 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800916
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800917 mDeferredActions.push_back(
Andreas Huber14f76722013-01-15 09:04:18 -0800918 new ShutdownDecoderAction(
919 true /* audio */, true /* video */));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800920
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800921 mDeferredActions.push_back(
922 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800923
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800924 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800925 break;
926 }
927
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800928 case kWhatSeek:
929 {
930 int64_t seekTimeUs;
931 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
932
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800933 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800934
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800935 mDeferredActions.push_back(
936 new SimpleAction(&NuPlayer::performDecoderFlush));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800937
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800938 mDeferredActions.push_back(new SeekAction(seekTimeUs));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800939
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800940 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800941 break;
942 }
943
Andreas Huberb4082222011-01-20 15:23:04 -0800944 case kWhatPause:
945 {
946 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +0100947 mSource->pause();
Andreas Huberb4082222011-01-20 15:23:04 -0800948 mRenderer->pause();
949 break;
950 }
951
952 case kWhatResume:
953 {
954 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +0100955 mSource->resume();
Andreas Huberb4082222011-01-20 15:23:04 -0800956 mRenderer->resume();
957 break;
958 }
959
Andreas Huberb5f25f02013-02-05 10:14:26 -0800960 case kWhatSourceNotify:
961 {
Andreas Huber9575c962013-02-05 13:59:56 -0800962 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800963 break;
964 }
965
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700966 case kWhatClosedCaptionNotify:
967 {
968 onClosedCaptionNotify(msg);
969 break;
970 }
971
Andreas Huberf9334412010-12-15 15:17:42 -0800972 default:
973 TRESPASS();
974 break;
975 }
976}
977
Andreas Huber3831a062010-12-21 10:22:33 -0800978void NuPlayer::finishFlushIfPossible() {
Wei Jia53904f32014-07-29 10:22:53 -0700979 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
980 && mFlushingAudio != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -0800981 return;
982 }
983
Wei Jia53904f32014-07-29 10:22:53 -0700984 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
985 && mFlushingVideo != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -0800986 return;
987 }
988
Steve Block3856b092011-10-20 11:56:00 +0100989 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800990
Andreas Huber6e3d3112011-11-28 12:36:11 -0800991 if (mTimeDiscontinuityPending) {
992 mRenderer->signalTimeDiscontinuity();
993 mTimeDiscontinuityPending = false;
994 }
Andreas Huber3831a062010-12-21 10:22:33 -0800995
Wei Jia53904f32014-07-29 10:22:53 -0700996 if (mAudioDecoder != NULL && mFlushingAudio == FLUSHED) {
Andreas Huber3831a062010-12-21 10:22:33 -0800997 mAudioDecoder->signalResume();
998 }
999
Wei Jia53904f32014-07-29 10:22:53 -07001000 if (mVideoDecoder != NULL && mFlushingVideo == FLUSHED) {
Andreas Huber3831a062010-12-21 10:22:33 -08001001 mVideoDecoder->signalResume();
1002 }
1003
1004 mFlushingAudio = NONE;
1005 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -08001006
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001007 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001008}
1009
1010void NuPlayer::postScanSources() {
1011 if (mScanSourcesPending) {
1012 return;
1013 }
1014
1015 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
1016 msg->setInt32("generation", mScanSourcesGeneration);
1017 msg->post();
1018
1019 mScanSourcesPending = true;
1020}
1021
Andy Hung282a7e32014-08-14 15:56:34 -07001022void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
1023 ALOGV("openAudioSink: offloadOnly(%d) mOffloadAudio(%d)",
1024 offloadOnly, mOffloadAudio);
1025 bool audioSinkChanged = false;
1026
1027 int32_t numChannels;
1028 CHECK(format->findInt32("channel-count", &numChannels));
1029
1030 int32_t channelMask;
1031 if (!format->findInt32("channel-mask", &channelMask)) {
1032 // signal to the AudioSink to derive the mask from count.
1033 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
1034 }
1035
1036 int32_t sampleRate;
1037 CHECK(format->findInt32("sample-rate", &sampleRate));
1038
1039 uint32_t flags;
1040 int64_t durationUs;
1041 // FIXME: we should handle the case where the video decoder
1042 // is created after we receive the format change indication.
1043 // Current code will just make that we select deep buffer
1044 // with video which should not be a problem as it should
1045 // not prevent from keeping A/V sync.
1046 if (mVideoDecoder == NULL &&
1047 mSource->getDuration(&durationUs) == OK &&
1048 durationUs
1049 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
1050 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1051 } else {
1052 flags = AUDIO_OUTPUT_FLAG_NONE;
1053 }
1054
1055 if (mOffloadAudio) {
1056 audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
1057 AString mime;
1058 CHECK(format->findString("mime", &mime));
1059 status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
1060
1061 if (err != OK) {
1062 ALOGE("Couldn't map mime \"%s\" to a valid "
1063 "audio_format", mime.c_str());
1064 mOffloadAudio = false;
1065 } else {
1066 ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
1067 mime.c_str(), audioFormat);
1068
1069 int avgBitRate = -1;
1070 format->findInt32("bit-rate", &avgBitRate);
1071
1072 int32_t aacProfile = -1;
1073 if (audioFormat == AUDIO_FORMAT_AAC
1074 && format->findInt32("aac-profile", &aacProfile)) {
1075 // Redefine AAC format as per aac profile
1076 mapAACProfileToAudioFormat(
1077 audioFormat,
1078 aacProfile);
1079 }
1080
1081 audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
1082 offloadInfo.duration_us = -1;
1083 format->findInt64(
1084 "durationUs", &offloadInfo.duration_us);
1085 offloadInfo.sample_rate = sampleRate;
1086 offloadInfo.channel_mask = channelMask;
1087 offloadInfo.format = audioFormat;
1088 offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
1089 offloadInfo.bit_rate = avgBitRate;
1090 offloadInfo.has_video = (mVideoDecoder != NULL);
1091 offloadInfo.is_streaming = true;
1092
1093 if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
1094 ALOGV("openAudioSink: no change in offload mode");
1095 return; // no change from previous configuration, everything ok.
1096 }
1097 ALOGV("openAudioSink: try to open AudioSink in offload mode");
1098 flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
Ronghua Wu1ffb5382014-08-18 15:57:03 -07001099 flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
Andy Hung282a7e32014-08-14 15:56:34 -07001100 audioSinkChanged = true;
1101 mAudioSink->close();
1102 err = mAudioSink->open(
1103 sampleRate,
1104 numChannels,
1105 (audio_channel_mask_t)channelMask,
1106 audioFormat,
1107 8 /* bufferCount */,
1108 &NuPlayer::Renderer::AudioSinkCallback,
1109 mRenderer.get(),
1110 (audio_output_flags_t)flags,
1111 &offloadInfo);
1112
1113 if (err == OK) {
1114 // If the playback is offloaded to h/w, we pass
1115 // the HAL some metadata information.
1116 // We don't want to do this for PCM because it
1117 // will be going through the AudioFlinger mixer
1118 // before reaching the hardware.
1119 sp<MetaData> audioMeta =
1120 mSource->getFormatMeta(true /* audio */);
1121 sendMetaDataToHal(mAudioSink, audioMeta);
1122 mCurrentOffloadInfo = offloadInfo;
1123 err = mAudioSink->start();
1124 ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
1125 }
1126 if (err != OK) {
1127 // Clean up, fall back to non offload mode.
1128 mAudioSink->close();
1129 mRenderer->signalDisableOffloadAudio();
1130 mOffloadAudio = false;
1131 mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1132 ALOGV("openAudioSink: offload failed");
1133 }
1134 }
1135 }
1136 if (!offloadOnly && !mOffloadAudio) {
1137 flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
1138 ALOGV("openAudioSink: open AudioSink in NON-offload mode");
1139
1140 audioSinkChanged = true;
1141 mAudioSink->close();
1142 mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1143 CHECK_EQ(mAudioSink->open(
1144 sampleRate,
1145 numChannels,
1146 (audio_channel_mask_t)channelMask,
1147 AUDIO_FORMAT_PCM_16_BIT,
1148 8 /* bufferCount */,
1149 NULL,
1150 NULL,
1151 (audio_output_flags_t)flags),
1152 (status_t)OK);
1153 mAudioSink->start();
1154 }
1155 if (audioSinkChanged) {
1156 mRenderer->signalAudioSinkChanged();
1157 }
1158}
1159
1160void NuPlayer::closeAudioSink() {
1161 mAudioSink->close();
1162 mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1163}
1164
Andreas Huber5bc087c2010-12-23 10:27:40 -08001165status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -08001166 if (*decoder != NULL) {
1167 return OK;
1168 }
1169
Andreas Huber84066782011-08-16 09:34:26 -07001170 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -08001171
Andreas Huber84066782011-08-16 09:34:26 -07001172 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001173 return -EWOULDBLOCK;
1174 }
1175
Andreas Huber3fe62152011-09-16 15:09:22 -07001176 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -07001177 AString mime;
1178 CHECK(format->findString("mime", &mime));
1179 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001180
1181 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
1182 mCCDecoder = new CCDecoder(ccNotify);
Lajos Molnar09524832014-07-17 14:29:51 -07001183
1184 if (mSourceFlags & Source::FLAG_SECURE) {
1185 format->setInt32("secure", true);
1186 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001187 }
1188
Wei Jiabc2fb722014-07-08 16:37:57 -07001189 if (audio) {
Wei Jia88703c32014-08-06 11:24:07 -07001190 sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
1191 ++mAudioDecoderGeneration;
1192 notify->setInt32("generation", mAudioDecoderGeneration);
1193
Wei Jiabc2fb722014-07-08 16:37:57 -07001194 if (mOffloadAudio) {
1195 *decoder = new DecoderPassThrough(notify);
1196 } else {
1197 *decoder = new Decoder(notify);
1198 }
1199 } else {
Wei Jia88703c32014-08-06 11:24:07 -07001200 sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
1201 ++mVideoDecoderGeneration;
1202 notify->setInt32("generation", mVideoDecoderGeneration);
1203
Wei Jiabc2fb722014-07-08 16:37:57 -07001204 *decoder = new Decoder(notify, mNativeWindow);
1205 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001206 (*decoder)->init();
Andreas Huber84066782011-08-16 09:34:26 -07001207 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -08001208
Lajos Molnar09524832014-07-17 14:29:51 -07001209 // allocate buffers to decrypt widevine source buffers
1210 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1211 Vector<sp<ABuffer> > inputBufs;
1212 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1213
1214 Vector<MediaBuffer *> mediaBufs;
1215 for (size_t i = 0; i < inputBufs.size(); i++) {
1216 const sp<ABuffer> &buffer = inputBufs[i];
1217 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1218 mediaBufs.push(mbuf);
1219 }
1220
1221 status_t err = mSource->setBuffers(audio, mediaBufs);
1222 if (err != OK) {
1223 for (size_t i = 0; i < mediaBufs.size(); ++i) {
1224 mediaBufs[i]->release();
1225 }
1226 mediaBufs.clear();
1227 ALOGE("Secure source didn't support secure mediaBufs.");
1228 return err;
1229 }
1230 }
Andreas Huberf9334412010-12-15 15:17:42 -08001231 return OK;
1232}
1233
1234status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
1235 sp<AMessage> reply;
1236 CHECK(msg->findMessage("reply", &reply));
1237
Wei Jia53904f32014-07-29 10:22:53 -07001238 if ((audio && mFlushingAudio != NONE)
1239 || (!audio && mFlushingVideo != NONE)) {
Wei Jiab189a5b2014-08-07 06:11:39 +00001240 reply->setInt32("err", INFO_DISCONTINUITY);
1241 reply->post();
1242 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -08001243 }
1244
1245 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -08001246
Andreas Huber3fe62152011-09-16 15:09:22 -07001247 bool dropAccessUnit;
1248 do {
1249 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -08001250
Andreas Huber3fe62152011-09-16 15:09:22 -07001251 if (err == -EWOULDBLOCK) {
1252 return err;
1253 } else if (err != OK) {
1254 if (err == INFO_DISCONTINUITY) {
1255 int32_t type;
1256 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -08001257
Andreas Huber3fe62152011-09-16 15:09:22 -07001258 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -08001259 (audio &&
1260 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
1261 || (!audio &&
1262 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -08001263
Andreas Huber6e3d3112011-11-28 12:36:11 -08001264 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
1265
Steve Blockdf64d152012-01-04 20:05:49 +00001266 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001267 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -08001268
Andreas Huber3fe62152011-09-16 15:09:22 -07001269 if (audio) {
1270 mSkipRenderingAudioUntilMediaTimeUs = -1;
1271 } else {
1272 mSkipRenderingVideoUntilMediaTimeUs = -1;
1273 }
Andreas Huber32f3cef2011-03-02 15:34:46 -08001274
Andreas Huber6e3d3112011-11-28 12:36:11 -08001275 if (timeChange) {
1276 sp<AMessage> extra;
1277 if (accessUnit->meta()->findMessage("extra", &extra)
1278 && extra != NULL) {
1279 int64_t resumeAtMediaTimeUs;
1280 if (extra->findInt64(
1281 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001282 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001283 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -07001284
Andreas Huber6e3d3112011-11-28 12:36:11 -08001285 if (audio) {
1286 mSkipRenderingAudioUntilMediaTimeUs =
1287 resumeAtMediaTimeUs;
1288 } else {
1289 mSkipRenderingVideoUntilMediaTimeUs =
1290 resumeAtMediaTimeUs;
1291 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001292 }
Andreas Huber32f3cef2011-03-02 15:34:46 -08001293 }
1294 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001295
Andreas Huber6e3d3112011-11-28 12:36:11 -08001296 mTimeDiscontinuityPending =
1297 mTimeDiscontinuityPending || timeChange;
1298
Lajos Molnar87603c02014-08-20 19:25:30 -07001299 bool seamlessFormatChange = false;
1300 sp<AMessage> newFormat = mSource->getFormat(audio);
1301 if (formatChange) {
1302 seamlessFormatChange =
1303 getDecoder(audio)->supportsSeamlessFormatChange(newFormat);
1304 // treat seamless format change separately
1305 formatChange = !seamlessFormatChange;
1306 }
1307 bool shutdownOrFlush = formatChange || timeChange;
1308
1309 // We want to queue up scan-sources only once per discontinuity.
1310 // We control this by doing it only if neither audio nor video are
1311 // flushing or shutting down. (After handling 1st discontinuity, one
1312 // of the flushing states will not be NONE.)
1313 // No need to scan sources if this discontinuity does not result
1314 // in a flush or shutdown, as the flushing state will stay NONE.
1315 if (mFlushingAudio == NONE && mFlushingVideo == NONE &&
1316 shutdownOrFlush) {
Robert Shiha2981012014-07-30 17:41:24 -07001317 // And we'll resume scanning sources once we're done
1318 // flushing.
1319 mDeferredActions.push_front(
1320 new SimpleAction(
1321 &NuPlayer::performScanSources));
1322 }
1323
Lajos Molnar87603c02014-08-20 19:25:30 -07001324 if (formatChange /* not seamless */) {
1325 // must change decoder
1326 flushDecoder(audio, /* needShutdown = */ true);
1327 } else if (timeChange) {
1328 // need to flush
1329 flushDecoder(audio, /* needShutdown = */ false, newFormat);
1330 err = OK;
1331 } else if (seamlessFormatChange) {
1332 // reuse existing decoder and don't flush
1333 updateDecoderFormatWithoutFlush(audio, newFormat);
1334 err = OK;
Andreas Huber6e3d3112011-11-28 12:36:11 -08001335 } else {
1336 // This stream is unaffected by the discontinuity
Andreas Huber6e3d3112011-11-28 12:36:11 -08001337 return -EWOULDBLOCK;
1338 }
Andreas Huber32f3cef2011-03-02 15:34:46 -08001339 }
1340
Andreas Huber3fe62152011-09-16 15:09:22 -07001341 reply->setInt32("err", err);
1342 reply->post();
1343 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -08001344 }
1345
Andreas Huber3fe62152011-09-16 15:09:22 -07001346 if (!audio) {
1347 ++mNumFramesTotal;
1348 }
1349
1350 dropAccessUnit = false;
1351 if (!audio
Lajos Molnar09524832014-07-17 14:29:51 -07001352 && !(mSourceFlags & Source::FLAG_SECURE)
Andreas Huber3fe62152011-09-16 15:09:22 -07001353 && mVideoLateByUs > 100000ll
1354 && mVideoIsAVC
1355 && !IsAVCReferenceFrame(accessUnit)) {
1356 dropAccessUnit = true;
1357 ++mNumFramesDropped;
1358 }
1359 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -08001360
Steve Block3856b092011-10-20 11:56:00 +01001361 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -08001362
1363#if 0
1364 int64_t mediaTimeUs;
1365 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +01001366 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -08001367 audio ? "audio" : "video",
1368 mediaTimeUs / 1E6);
1369#endif
1370
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001371 if (!audio) {
1372 mCCDecoder->decode(accessUnit);
1373 }
1374
Andreas Huber2d8bedd2012-02-21 14:38:23 -08001375 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -08001376 reply->post();
1377
1378 return OK;
1379}
1380
1381void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +01001382 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -08001383
1384 sp<AMessage> reply;
1385 CHECK(msg->findMessage("reply", &reply));
1386
Wei Jia53904f32014-07-29 10:22:53 -07001387 if ((audio && mFlushingAudio != NONE)
1388 || (!audio && mFlushingVideo != NONE)) {
Andreas Huber18ac5402011-08-31 15:04:25 -07001389 // We're currently attempting to flush the decoder, in order
1390 // to complete this, the decoder wants all its buffers back,
1391 // so we don't want any output buffers it sent us (from before
1392 // we initiated the flush) to be stuck in the renderer's queue.
1393
Steve Block3856b092011-10-20 11:56:00 +01001394 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -07001395 " right back.", audio ? "audio" : "video");
1396
1397 reply->post();
1398 return;
1399 }
1400
Andreas Huber2d8bedd2012-02-21 14:38:23 -08001401 sp<ABuffer> buffer;
1402 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -08001403
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001404 int64_t mediaTimeUs;
1405 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1406
Andreas Huber32f3cef2011-03-02 15:34:46 -08001407 int64_t &skipUntilMediaTimeUs =
1408 audio
1409 ? mSkipRenderingAudioUntilMediaTimeUs
1410 : mSkipRenderingVideoUntilMediaTimeUs;
1411
1412 if (skipUntilMediaTimeUs >= 0) {
Andreas Huber32f3cef2011-03-02 15:34:46 -08001413
1414 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +01001415 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -08001416 audio ? "audio" : "video",
1417 mediaTimeUs);
1418
1419 reply->post();
1420 return;
1421 }
1422
1423 skipUntilMediaTimeUs = -1;
1424 }
1425
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001426 if (!audio && mCCDecoder->isSelected()) {
1427 mCCDecoder->display(mediaTimeUs);
1428 }
1429
Andreas Huberf9334412010-12-15 15:17:42 -08001430 mRenderer->queueBuffer(audio, buffer, reply);
1431}
1432
Chong Zhangced1c2f2014-08-08 15:22:35 -07001433void NuPlayer::updateVideoSize(
1434 const sp<AMessage> &inputFormat,
1435 const sp<AMessage> &outputFormat) {
1436 if (inputFormat == NULL) {
1437 ALOGW("Unknown video size, reporting 0x0!");
1438 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1439 return;
1440 }
1441
1442 int32_t displayWidth, displayHeight;
1443 int32_t cropLeft, cropTop, cropRight, cropBottom;
1444
1445 if (outputFormat != NULL) {
1446 int32_t width, height;
1447 CHECK(outputFormat->findInt32("width", &width));
1448 CHECK(outputFormat->findInt32("height", &height));
1449
1450 int32_t cropLeft, cropTop, cropRight, cropBottom;
1451 CHECK(outputFormat->findRect(
1452 "crop",
1453 &cropLeft, &cropTop, &cropRight, &cropBottom));
1454
1455 displayWidth = cropRight - cropLeft + 1;
1456 displayHeight = cropBottom - cropTop + 1;
1457
1458 ALOGV("Video output format changed to %d x %d "
1459 "(crop: %d x %d @ (%d, %d))",
1460 width, height,
1461 displayWidth,
1462 displayHeight,
1463 cropLeft, cropTop);
1464 } else {
1465 CHECK(inputFormat->findInt32("width", &displayWidth));
1466 CHECK(inputFormat->findInt32("height", &displayHeight));
1467
1468 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1469 }
1470
1471 // Take into account sample aspect ratio if necessary:
1472 int32_t sarWidth, sarHeight;
1473 if (inputFormat->findInt32("sar-width", &sarWidth)
1474 && inputFormat->findInt32("sar-height", &sarHeight)) {
1475 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1476
1477 displayWidth = (displayWidth * sarWidth) / sarHeight;
1478
1479 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1480 }
1481
1482 int32_t rotationDegrees;
1483 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1484 rotationDegrees = 0;
1485 }
1486
1487 if (rotationDegrees == 90 || rotationDegrees == 270) {
1488 int32_t tmp = displayWidth;
1489 displayWidth = displayHeight;
1490 displayHeight = tmp;
1491 }
1492
1493 notifyListener(
1494 MEDIA_SET_VIDEO_SIZE,
1495 displayWidth,
1496 displayHeight);
1497}
1498
Chong Zhangdcb89b32013-08-06 09:44:47 -07001499void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001500 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001501 return;
1502 }
1503
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001504 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001505
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001506 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001507 return;
1508 }
1509
Chong Zhangdcb89b32013-08-06 09:44:47 -07001510 driver->notifyListener(msg, ext1, ext2, in);
Andreas Huberf9334412010-12-15 15:17:42 -08001511}
1512
Lajos Molnar87603c02014-08-20 19:25:30 -07001513void NuPlayer::flushDecoder(
1514 bool audio, bool needShutdown, const sp<AMessage> &newFormat) {
Andreas Huber14f76722013-01-15 09:04:18 -08001515 ALOGV("[%s] flushDecoder needShutdown=%d",
1516 audio ? "audio" : "video", needShutdown);
1517
Lajos Molnar87603c02014-08-20 19:25:30 -07001518 const sp<Decoder> &decoder = getDecoder(audio);
1519 if (decoder == NULL) {
Steve Blockdf64d152012-01-04 20:05:49 +00001520 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001521 audio ? "audio" : "video");
Lajos Molnar87603c02014-08-20 19:25:30 -07001522 return;
Andreas Huber6e3d3112011-11-28 12:36:11 -08001523 }
1524
Andreas Huber1aef2112011-01-04 14:01:29 -08001525 // Make sure we don't continue to scan sources until we finish flushing.
1526 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001527 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001528
Lajos Molnar87603c02014-08-20 19:25:30 -07001529 decoder->signalFlush(newFormat);
Andreas Huber1aef2112011-01-04 14:01:29 -08001530 mRenderer->flush(audio);
1531
1532 FlushStatus newStatus =
1533 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1534
1535 if (audio) {
Wei Jia53904f32014-07-29 10:22:53 -07001536 ALOGE_IF(mFlushingAudio != NONE,
1537 "audio flushDecoder() is called in state %d", mFlushingAudio);
Andreas Huber1aef2112011-01-04 14:01:29 -08001538 mFlushingAudio = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08001539 } else {
Wei Jia53904f32014-07-29 10:22:53 -07001540 ALOGE_IF(mFlushingVideo != NONE,
1541 "video flushDecoder() is called in state %d", mFlushingVideo);
Andreas Huber1aef2112011-01-04 14:01:29 -08001542 mFlushingVideo = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08001543 }
1544}
1545
Lajos Molnar87603c02014-08-20 19:25:30 -07001546void NuPlayer::updateDecoderFormatWithoutFlush(
1547 bool audio, const sp<AMessage> &format) {
1548 ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video");
1549
1550 const sp<Decoder> &decoder = getDecoder(audio);
1551 if (decoder == NULL) {
1552 ALOGI("updateDecoderFormatWithoutFlush %s without decoder present",
1553 audio ? "audio" : "video");
1554 return;
1555 }
1556
1557 decoder->signalUpdateFormat(format);
1558}
1559
Chong Zhangced1c2f2014-08-08 15:22:35 -07001560void NuPlayer::queueDecoderShutdown(
1561 bool audio, bool video, const sp<AMessage> &reply) {
1562 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Huber84066782011-08-16 09:34:26 -07001563
Chong Zhangced1c2f2014-08-08 15:22:35 -07001564 mDeferredActions.push_back(
1565 new ShutdownDecoderAction(audio, video));
Andreas Huber84066782011-08-16 09:34:26 -07001566
Chong Zhangced1c2f2014-08-08 15:22:35 -07001567 mDeferredActions.push_back(
1568 new SimpleAction(&NuPlayer::performScanSources));
Andreas Huber84066782011-08-16 09:34:26 -07001569
Chong Zhangced1c2f2014-08-08 15:22:35 -07001570 mDeferredActions.push_back(new PostMessageAction(reply));
1571
1572 processDeferredActions();
Andreas Huber84066782011-08-16 09:34:26 -07001573}
1574
James Dong0d268a32012-08-31 12:18:27 -07001575status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1576 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001577 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001578 status_t ret = native_window_set_scaling_mode(
1579 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1580 if (ret != OK) {
1581 ALOGE("Failed to set scaling mode (%d): %s",
1582 -ret, strerror(-ret));
1583 return ret;
1584 }
1585 }
1586 return OK;
1587}
1588
Chong Zhangdcb89b32013-08-06 09:44:47 -07001589status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1590 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1591 msg->setPointer("reply", reply);
1592
1593 sp<AMessage> response;
1594 status_t err = msg->postAndAwaitResponse(&response);
1595 return err;
1596}
1597
Robert Shih7c4f0d72014-07-09 18:53:31 -07001598status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
1599 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
1600 msg->setPointer("reply", reply);
1601 msg->setInt32("type", type);
1602
1603 sp<AMessage> response;
1604 status_t err = msg->postAndAwaitResponse(&response);
1605 if (err == OK && response != NULL) {
1606 CHECK(response->findInt32("err", &err));
1607 }
1608 return err;
1609}
1610
Chong Zhangdcb89b32013-08-06 09:44:47 -07001611status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
1612 sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1613 msg->setSize("trackIndex", trackIndex);
1614 msg->setInt32("select", select);
1615
1616 sp<AMessage> response;
1617 status_t err = msg->postAndAwaitResponse(&response);
1618
Chong Zhang404fced2014-06-11 14:45:31 -07001619 if (err != OK) {
1620 return err;
1621 }
1622
1623 if (!response->findInt32("err", &err)) {
1624 err = OK;
1625 }
1626
Chong Zhangdcb89b32013-08-06 09:44:47 -07001627 return err;
1628}
1629
Andreas Huberb7c8e912012-11-27 15:02:53 -08001630void NuPlayer::schedulePollDuration() {
1631 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1632 msg->setInt32("generation", mPollDurationGeneration);
1633 msg->post();
1634}
1635
1636void NuPlayer::cancelPollDuration() {
1637 ++mPollDurationGeneration;
1638}
1639
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001640void NuPlayer::processDeferredActions() {
1641 while (!mDeferredActions.empty()) {
1642 // We won't execute any deferred actions until we're no longer in
1643 // an intermediate state, i.e. one more more decoders are currently
1644 // flushing or shutting down.
1645
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001646 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1647 // We're currently flushing, postpone the reset until that's
1648 // completed.
1649
1650 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1651 mFlushingAudio, mFlushingVideo);
1652
1653 break;
1654 }
1655
1656 sp<Action> action = *mDeferredActions.begin();
1657 mDeferredActions.erase(mDeferredActions.begin());
1658
1659 action->execute(this);
1660 }
1661}
1662
1663void NuPlayer::performSeek(int64_t seekTimeUs) {
1664 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1665 seekTimeUs,
1666 seekTimeUs / 1E6);
1667
1668 mSource->seekTo(seekTimeUs);
Robert Shihd3b0bbb2014-07-23 15:00:25 -07001669 ++mTimedTextGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001670
1671 if (mDriver != NULL) {
1672 sp<NuPlayerDriver> driver = mDriver.promote();
1673 if (driver != NULL) {
1674 driver->notifyPosition(seekTimeUs);
1675 driver->notifySeekComplete();
1676 }
1677 }
1678
1679 // everything's flushed, continue playback.
1680}
1681
1682void NuPlayer::performDecoderFlush() {
1683 ALOGV("performDecoderFlush");
1684
Andreas Huberda9740e2013-04-16 10:54:03 -07001685 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001686 return;
1687 }
1688
1689 mTimeDiscontinuityPending = true;
1690
1691 if (mAudioDecoder != NULL) {
1692 flushDecoder(true /* audio */, false /* needShutdown */);
1693 }
1694
1695 if (mVideoDecoder != NULL) {
1696 flushDecoder(false /* audio */, false /* needShutdown */);
1697 }
1698}
1699
Andreas Huber14f76722013-01-15 09:04:18 -08001700void NuPlayer::performDecoderShutdown(bool audio, bool video) {
1701 ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001702
Andreas Huber14f76722013-01-15 09:04:18 -08001703 if ((!audio || mAudioDecoder == NULL)
1704 && (!video || mVideoDecoder == NULL)) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001705 return;
1706 }
1707
1708 mTimeDiscontinuityPending = true;
1709
Andreas Huber14f76722013-01-15 09:04:18 -08001710 if (audio && mAudioDecoder != NULL) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001711 flushDecoder(true /* audio */, true /* needShutdown */);
1712 }
1713
Andreas Huber14f76722013-01-15 09:04:18 -08001714 if (video && mVideoDecoder != NULL) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001715 flushDecoder(false /* audio */, true /* needShutdown */);
1716 }
1717}
1718
1719void NuPlayer::performReset() {
1720 ALOGV("performReset");
1721
1722 CHECK(mAudioDecoder == NULL);
1723 CHECK(mVideoDecoder == NULL);
1724
1725 cancelPollDuration();
1726
1727 ++mScanSourcesGeneration;
1728 mScanSourcesPending = false;
1729
Lajos Molnar09524832014-07-17 14:29:51 -07001730 if (mRendererLooper != NULL) {
1731 if (mRenderer != NULL) {
1732 mRendererLooper->unregisterHandler(mRenderer->id());
1733 }
1734 mRendererLooper->stop();
1735 mRendererLooper.clear();
1736 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001737 mRenderer.clear();
1738
1739 if (mSource != NULL) {
1740 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001741
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001742 mSource.clear();
1743 }
1744
1745 if (mDriver != NULL) {
1746 sp<NuPlayerDriver> driver = mDriver.promote();
1747 if (driver != NULL) {
1748 driver->notifyResetComplete();
1749 }
1750 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001751
1752 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001753}
1754
1755void NuPlayer::performScanSources() {
1756 ALOGV("performScanSources");
1757
Andreas Huber57a339c2012-12-03 11:18:00 -08001758 if (!mStarted) {
1759 return;
1760 }
1761
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001762 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1763 postScanSources();
1764 }
1765}
1766
Andreas Huber57a339c2012-12-03 11:18:00 -08001767void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1768 ALOGV("performSetSurface");
1769
1770 mNativeWindow = wrapper;
1771
1772 // XXX - ignore error from setVideoScalingMode for now
1773 setVideoScalingMode(mVideoScalingMode);
Chong Zhang13d6faa2014-08-22 15:35:28 -07001774
1775 if (mDriver != NULL) {
1776 sp<NuPlayerDriver> driver = mDriver.promote();
1777 if (driver != NULL) {
1778 driver->notifySetSurfaceComplete();
1779 }
1780 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001781}
1782
Andreas Huber9575c962013-02-05 13:59:56 -08001783void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1784 int32_t what;
1785 CHECK(msg->findInt32("what", &what));
1786
1787 switch (what) {
1788 case Source::kWhatPrepared:
1789 {
Andreas Huberb5f28d42013-04-25 15:11:19 -07001790 if (mSource == NULL) {
1791 // This is a stale notification from a source that was
1792 // asynchronously preparing when the client called reset().
1793 // We handled the reset, the source is gone.
1794 break;
1795 }
1796
Andreas Huberec0c5972013-02-05 14:47:13 -08001797 int32_t err;
1798 CHECK(msg->findInt32("err", &err));
1799
Andreas Huber9575c962013-02-05 13:59:56 -08001800 sp<NuPlayerDriver> driver = mDriver.promote();
1801 if (driver != NULL) {
Marco Nelissendd114d12014-05-28 15:23:14 -07001802 // notify duration first, so that it's definitely set when
1803 // the app received the "prepare complete" callback.
1804 int64_t durationUs;
1805 if (mSource->getDuration(&durationUs) == OK) {
1806 driver->notifyDuration(durationUs);
1807 }
Andreas Huberec0c5972013-02-05 14:47:13 -08001808 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08001809 }
Andreas Huber99759402013-04-01 14:28:31 -07001810
Andreas Huber9575c962013-02-05 13:59:56 -08001811 break;
1812 }
1813
1814 case Source::kWhatFlagsChanged:
1815 {
1816 uint32_t flags;
1817 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1818
Chong Zhang4b7069d2013-09-11 12:52:43 -07001819 sp<NuPlayerDriver> driver = mDriver.promote();
1820 if (driver != NULL) {
1821 driver->notifyFlagsChanged(flags);
1822 }
1823
Andreas Huber9575c962013-02-05 13:59:56 -08001824 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1825 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1826 cancelPollDuration();
1827 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1828 && (flags & Source::FLAG_DYNAMIC_DURATION)
1829 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1830 schedulePollDuration();
1831 }
1832
1833 mSourceFlags = flags;
1834 break;
1835 }
1836
1837 case Source::kWhatVideoSizeChanged:
1838 {
Chong Zhangced1c2f2014-08-08 15:22:35 -07001839 sp<AMessage> format;
1840 CHECK(msg->findMessage("format", &format));
Andreas Huber9575c962013-02-05 13:59:56 -08001841
Chong Zhangced1c2f2014-08-08 15:22:35 -07001842 updateVideoSize(format);
Andreas Huber9575c962013-02-05 13:59:56 -08001843 break;
1844 }
1845
Chong Zhang2a3cc9a2014-08-21 17:48:26 -07001846 case Source::kWhatBufferingUpdate:
1847 {
1848 int32_t percentage;
1849 CHECK(msg->findInt32("percentage", &percentage));
1850
1851 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
1852 break;
1853 }
1854
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001855 case Source::kWhatBufferingStart:
1856 {
1857 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1858 break;
1859 }
1860
1861 case Source::kWhatBufferingEnd:
1862 {
1863 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1864 break;
1865 }
1866
Chong Zhangdcb89b32013-08-06 09:44:47 -07001867 case Source::kWhatSubtitleData:
1868 {
1869 sp<ABuffer> buffer;
1870 CHECK(msg->findBuffer("buffer", &buffer));
1871
Chong Zhang404fced2014-06-11 14:45:31 -07001872 sendSubtitleData(buffer, 0 /* baseIndex */);
Chong Zhangdcb89b32013-08-06 09:44:47 -07001873 break;
1874 }
1875
Robert Shihd3b0bbb2014-07-23 15:00:25 -07001876 case Source::kWhatTimedTextData:
1877 {
1878 int32_t generation;
1879 if (msg->findInt32("generation", &generation)
1880 && generation != mTimedTextGeneration) {
1881 break;
1882 }
1883
1884 sp<ABuffer> buffer;
1885 CHECK(msg->findBuffer("buffer", &buffer));
1886
1887 sp<NuPlayerDriver> driver = mDriver.promote();
1888 if (driver == NULL) {
1889 break;
1890 }
1891
1892 int posMs;
1893 int64_t timeUs, posUs;
1894 driver->getCurrentPosition(&posMs);
1895 posUs = posMs * 1000;
1896 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1897
1898 if (posUs < timeUs) {
1899 if (!msg->findInt32("generation", &generation)) {
1900 msg->setInt32("generation", mTimedTextGeneration);
1901 }
1902 msg->post(timeUs - posUs);
1903 } else {
1904 sendTimedTextData(buffer);
1905 }
1906 break;
1907 }
1908
Andreas Huber14f76722013-01-15 09:04:18 -08001909 case Source::kWhatQueueDecoderShutdown:
1910 {
1911 int32_t audio, video;
1912 CHECK(msg->findInt32("audio", &audio));
1913 CHECK(msg->findInt32("video", &video));
1914
1915 sp<AMessage> reply;
1916 CHECK(msg->findMessage("reply", &reply));
1917
1918 queueDecoderShutdown(audio, video, reply);
1919 break;
1920 }
1921
Ronghua Wu80276872014-08-28 15:50:29 -07001922 case Source::kWhatDrmNoLicense:
1923 {
1924 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
1925 break;
1926 }
1927
Andreas Huber9575c962013-02-05 13:59:56 -08001928 default:
1929 TRESPASS();
1930 }
1931}
1932
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001933void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
1934 int32_t what;
1935 CHECK(msg->findInt32("what", &what));
1936
1937 switch (what) {
1938 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
1939 {
1940 sp<ABuffer> buffer;
1941 CHECK(msg->findBuffer("buffer", &buffer));
1942
1943 size_t inbandTracks = 0;
1944 if (mSource != NULL) {
1945 inbandTracks = mSource->getTrackCount();
1946 }
1947
1948 sendSubtitleData(buffer, inbandTracks);
1949 break;
1950 }
1951
1952 case NuPlayer::CCDecoder::kWhatTrackAdded:
1953 {
1954 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
1955
1956 break;
1957 }
1958
1959 default:
1960 TRESPASS();
1961 }
1962
1963
1964}
1965
Chong Zhang404fced2014-06-11 14:45:31 -07001966void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
1967 int32_t trackIndex;
1968 int64_t timeUs, durationUs;
1969 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
1970 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1971 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
1972
1973 Parcel in;
1974 in.writeInt32(trackIndex + baseIndex);
1975 in.writeInt64(timeUs);
1976 in.writeInt64(durationUs);
1977 in.writeInt32(buffer->size());
1978 in.writeInt32(buffer->size());
1979 in.write(buffer->data(), buffer->size());
1980
1981 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
1982}
Robert Shihd3b0bbb2014-07-23 15:00:25 -07001983
1984void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
1985 const void *data;
1986 size_t size = 0;
1987 int64_t timeUs;
1988 int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
1989
1990 AString mime;
1991 CHECK(buffer->meta()->findString("mime", &mime));
1992 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
1993
1994 data = buffer->data();
1995 size = buffer->size();
1996
1997 Parcel parcel;
1998 if (size > 0) {
1999 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2000 flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
2001 TextDescriptions::getParcelOfDescriptions(
2002 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2003 }
2004
2005 if ((parcel.dataSize() > 0)) {
2006 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2007 } else { // send an empty timed text
2008 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2009 }
2010}
Andreas Huberb5f25f02013-02-05 10:14:26 -08002011////////////////////////////////////////////////////////////////////////////////
2012
Chong Zhangced1c2f2014-08-08 15:22:35 -07002013sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
2014 sp<MetaData> meta = getFormatMeta(audio);
2015
2016 if (meta == NULL) {
2017 return NULL;
2018 }
2019
2020 sp<AMessage> msg = new AMessage;
2021
2022 if(convertMetaDataToMessage(meta, &msg) == OK) {
2023 return msg;
2024 }
2025 return NULL;
2026}
2027
Andreas Huber9575c962013-02-05 13:59:56 -08002028void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
2029 sp<AMessage> notify = dupNotify();
2030 notify->setInt32("what", kWhatFlagsChanged);
2031 notify->setInt32("flags", flags);
2032 notify->post();
2033}
2034
Chong Zhangced1c2f2014-08-08 15:22:35 -07002035void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
Andreas Huber9575c962013-02-05 13:59:56 -08002036 sp<AMessage> notify = dupNotify();
2037 notify->setInt32("what", kWhatVideoSizeChanged);
Chong Zhangced1c2f2014-08-08 15:22:35 -07002038 notify->setMessage("format", format);
Andreas Huber9575c962013-02-05 13:59:56 -08002039 notify->post();
2040}
2041
Andreas Huberec0c5972013-02-05 14:47:13 -08002042void NuPlayer::Source::notifyPrepared(status_t err) {
Andreas Huber9575c962013-02-05 13:59:56 -08002043 sp<AMessage> notify = dupNotify();
2044 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08002045 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08002046 notify->post();
2047}
2048
Andreas Huber84333e02014-02-07 15:36:10 -08002049void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
Andreas Huberb5f25f02013-02-05 10:14:26 -08002050 TRESPASS();
2051}
2052
Andreas Huberf9334412010-12-15 15:17:42 -08002053} // namespace android