blob: cfa525895b3f6ff24af789c26bf7aac8aae243ab [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"
Chong Zhang7137ec72014-11-12 16:41:05 -080024#include "NuPlayerCCDecoder.h"
Andreas Huberf9334412010-12-15 15:17:42 -080025#include "NuPlayerDecoder.h"
Chong Zhang7137ec72014-11-12 16:41:05 -080026#include "NuPlayerDecoderBase.h"
Wei Jiabc2fb722014-07-08 16:37:57 -070027#include "NuPlayerDecoderPassThrough.h"
Andreas Huber43c3e6c2011-01-05 12:17:08 -080028#include "NuPlayerDriver.h"
Andreas Huberf9334412010-12-15 15:17:42 -080029#include "NuPlayerRenderer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080030#include "NuPlayerSource.h"
Andreas Huber2bfdd422011-10-11 15:24:07 -070031#include "RTSPSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080032#include "StreamingSource.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070033#include "GenericSource.h"
Robert Shihd3b0bbb2014-07-23 15:00:25 -070034#include "TextDescriptions.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080035
36#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080037
Lajos Molnard9fd6312014-11-06 11:00:00 -080038#include <cutils/properties.h>
39
Andreas Huber3831a062010-12-21 10:22:33 -080040#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080041#include <media/stagefright/foundation/ABuffer.h>
42#include <media/stagefright/foundation/ADebug.h>
43#include <media/stagefright/foundation/AMessage.h>
Lajos Molnar09524832014-07-17 14:29:51 -070044#include <media/stagefright/MediaBuffer.h>
Andreas Huber3fe62152011-09-16 15:09:22 -070045#include <media/stagefright/MediaDefs.h>
Andreas Huberf9334412010-12-15 15:17:42 -080046#include <media/stagefright/MediaErrors.h>
47#include <media/stagefright/MetaData.h>
Andy McFadden8ba01022012-12-18 09:46:54 -080048#include <gui/IGraphicBufferProducer.h>
Andreas Huberf9334412010-12-15 15:17:42 -080049
Andreas Huber3fe62152011-09-16 15:09:22 -070050#include "avc_utils.h"
51
Andreas Huber84066782011-08-16 09:34:26 -070052#include "ESDS.h"
53#include <media/stagefright/Utils.h>
54
Andreas Huberf9334412010-12-15 15:17:42 -080055namespace android {
56
Andreas Hubera1f8ab02012-11-30 10:53:22 -080057struct NuPlayer::Action : public RefBase {
58 Action() {}
59
60 virtual void execute(NuPlayer *player) = 0;
61
62private:
63 DISALLOW_EVIL_CONSTRUCTORS(Action);
64};
65
66struct NuPlayer::SeekAction : public Action {
Wei Jiae427abf2014-09-22 15:21:11 -070067 SeekAction(int64_t seekTimeUs, bool needNotify)
68 : mSeekTimeUs(seekTimeUs),
69 mNeedNotify(needNotify) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -080070 }
71
72 virtual void execute(NuPlayer *player) {
Wei Jiae427abf2014-09-22 15:21:11 -070073 player->performSeek(mSeekTimeUs, mNeedNotify);
Andreas Hubera1f8ab02012-11-30 10:53:22 -080074 }
75
76private:
77 int64_t mSeekTimeUs;
Wei Jiae427abf2014-09-22 15:21:11 -070078 bool mNeedNotify;
Andreas Hubera1f8ab02012-11-30 10:53:22 -080079
80 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
81};
82
Chong Zhangf8d71772014-11-26 15:08:34 -080083struct NuPlayer::ResumeDecoderAction : public Action {
84 ResumeDecoderAction(bool needNotify)
85 : mNeedNotify(needNotify) {
86 }
87
88 virtual void execute(NuPlayer *player) {
89 player->performResumeDecoders(mNeedNotify);
90 }
91
92private:
93 bool mNeedNotify;
94
95 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
96};
97
Andreas Huber57a339c2012-12-03 11:18:00 -080098struct NuPlayer::SetSurfaceAction : public Action {
99 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
100 : mWrapper(wrapper) {
101 }
102
103 virtual void execute(NuPlayer *player) {
104 player->performSetSurface(mWrapper);
105 }
106
107private:
108 sp<NativeWindowWrapper> mWrapper;
109
110 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
111};
112
Wei Jiafef808d2014-10-31 17:57:05 -0700113struct NuPlayer::FlushDecoderAction : public Action {
114 FlushDecoderAction(FlushCommand audio, FlushCommand video)
Andreas Huber14f76722013-01-15 09:04:18 -0800115 : mAudio(audio),
116 mVideo(video) {
117 }
118
119 virtual void execute(NuPlayer *player) {
Wei Jiafef808d2014-10-31 17:57:05 -0700120 player->performDecoderFlush(mAudio, mVideo);
Andreas Huber14f76722013-01-15 09:04:18 -0800121 }
122
123private:
Wei Jiafef808d2014-10-31 17:57:05 -0700124 FlushCommand mAudio;
125 FlushCommand mVideo;
Andreas Huber14f76722013-01-15 09:04:18 -0800126
Wei Jiafef808d2014-10-31 17:57:05 -0700127 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
Andreas Huber14f76722013-01-15 09:04:18 -0800128};
129
130struct NuPlayer::PostMessageAction : public Action {
131 PostMessageAction(const sp<AMessage> &msg)
132 : mMessage(msg) {
133 }
134
135 virtual void execute(NuPlayer *) {
136 mMessage->post();
137 }
138
139private:
140 sp<AMessage> mMessage;
141
142 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
143};
144
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800145// Use this if there's no state necessary to save in order to execute
146// the action.
147struct NuPlayer::SimpleAction : public Action {
148 typedef void (NuPlayer::*ActionFunc)();
149
150 SimpleAction(ActionFunc func)
151 : mFunc(func) {
152 }
153
154 virtual void execute(NuPlayer *player) {
155 (player->*mFunc)();
156 }
157
158private:
159 ActionFunc mFunc;
160
161 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
162};
163
Andreas Huberf9334412010-12-15 15:17:42 -0800164////////////////////////////////////////////////////////////////////////////////
165
166NuPlayer::NuPlayer()
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700167 : mUIDValid(false),
Andreas Huber9575c962013-02-05 13:59:56 -0800168 mSourceFlags(0),
Wei Jiabc2fb722014-07-08 16:37:57 -0700169 mOffloadAudio(false),
Wei Jia88703c32014-08-06 11:24:07 -0700170 mAudioDecoderGeneration(0),
171 mVideoDecoderGeneration(0),
Wei Jia57568df2014-09-22 10:16:29 -0700172 mRendererGeneration(0),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700173 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800174 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800175 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800176 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800177 mPollDurationGeneration(0),
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700178 mTimedTextGeneration(0),
Andreas Huberf9334412010-12-15 15:17:42 -0800179 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800180 mFlushingVideo(NONE),
Chong Zhangf8d71772014-11-26 15:08:34 -0800181 mResumePending(false),
Andreas Huber57a339c2012-12-03 11:18:00 -0800182 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
Wei Jia98160162015-02-04 17:01:11 -0800183 mPlaybackRate(1.0),
Chong Zhangefbb6192015-01-30 17:13:27 -0800184 mStarted(false),
185 mPaused(false),
186 mPausedByClient(false) {
Andy Hung8d121d42014-10-03 09:53:53 -0700187 clearFlushComplete();
Andreas Huberf9334412010-12-15 15:17:42 -0800188}
189
190NuPlayer::~NuPlayer() {
191}
192
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700193void NuPlayer::setUID(uid_t uid) {
194 mUIDValid = true;
195 mUID = uid;
196}
197
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800198void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
199 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800200}
201
Andreas Huber9575c962013-02-05 13:59:56 -0800202void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800203 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Andreas Huberf9334412010-12-15 15:17:42 -0800204
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800205 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800206
Andreas Huber240abcc2014-02-13 13:32:37 -0800207 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber5bc087c2010-12-23 10:27:40 -0800208 msg->post();
209}
Andreas Huberf9334412010-12-15 15:17:42 -0800210
Andreas Huberafed0e12011-09-20 15:39:58 -0700211static bool IsHTTPLiveURL(const char *url) {
212 if (!strncasecmp("http://", url, 7)
Andreas Huber99759402013-04-01 14:28:31 -0700213 || !strncasecmp("https://", url, 8)
214 || !strncasecmp("file://", url, 7)) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700215 size_t len = strlen(url);
216 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
217 return true;
218 }
219
220 if (strstr(url,"m3u8")) {
221 return true;
222 }
223 }
224
225 return false;
226}
227
Andreas Huber9575c962013-02-05 13:59:56 -0800228void NuPlayer::setDataSourceAsync(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800229 const sp<IMediaHTTPService> &httpService,
230 const char *url,
231 const KeyedVector<String8, String8> *headers) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700232
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800233 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100234 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800235
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800236 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800237
Andreas Huberafed0e12011-09-20 15:39:58 -0700238 sp<Source> source;
239 if (IsHTTPLiveURL(url)) {
Andreas Huber81e68442014-02-05 11:52:33 -0800240 source = new HTTPLiveSource(notify, httpService, url, headers);
Andreas Huberafed0e12011-09-20 15:39:58 -0700241 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800242 source = new RTSPSource(
243 notify, httpService, url, headers, mUIDValid, mUID);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100244 } else if ((!strncasecmp(url, "http://", 7)
245 || !strncasecmp(url, "https://", 8))
246 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
247 || strstr(url, ".sdp?"))) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800248 source = new RTSPSource(
249 notify, httpService, url, headers, mUIDValid, mUID, true);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700250 } else {
Chong Zhang3de157d2014-08-05 20:54:44 -0700251 sp<GenericSource> genericSource =
252 new GenericSource(notify, mUIDValid, mUID);
253 // Don't set FLAG_SECURE on mSourceFlags here for widevine.
254 // The correct flags will be updated in Source::kWhatFlagsChanged
255 // handler when GenericSource is prepared.
Andreas Huber2bfdd422011-10-11 15:24:07 -0700256
Chong Zhanga19f33e2014-08-07 15:35:07 -0700257 status_t err = genericSource->setDataSource(httpService, url, headers);
Chong Zhang3de157d2014-08-05 20:54:44 -0700258
259 if (err == OK) {
260 source = genericSource;
261 } else {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700262 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700263 }
264 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700265 msg->setObject("source", source);
266 msg->post();
267}
268
Andreas Huber9575c962013-02-05 13:59:56 -0800269void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800270 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Andreas Huberafed0e12011-09-20 15:39:58 -0700271
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800272 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800273
Chong Zhang3de157d2014-08-05 20:54:44 -0700274 sp<GenericSource> source =
275 new GenericSource(notify, mUIDValid, mUID);
276
Chong Zhanga19f33e2014-08-07 15:35:07 -0700277 status_t err = source->setDataSource(fd, offset, length);
Chong Zhang3de157d2014-08-05 20:54:44 -0700278
279 if (err != OK) {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700280 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700281 source = NULL;
282 }
283
Andreas Huberafed0e12011-09-20 15:39:58 -0700284 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800285 msg->post();
286}
287
Andreas Huber9575c962013-02-05 13:59:56 -0800288void NuPlayer::prepareAsync() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800289 (new AMessage(kWhatPrepare, this))->post();
Andreas Huber9575c962013-02-05 13:59:56 -0800290}
291
Andreas Huber57a339c2012-12-03 11:18:00 -0800292void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800293 const sp<IGraphicBufferProducer> &bufferProducer) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800294 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, this);
Andreas Huber57a339c2012-12-03 11:18:00 -0800295
Andy McFadden8ba01022012-12-18 09:46:54 -0800296 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800297 msg->setObject("native-window", NULL);
298 } else {
299 msg->setObject(
300 "native-window",
301 new NativeWindowWrapper(
Wei Jia9c03a402014-08-26 15:24:43 -0700302 new Surface(bufferProducer, true /* controlledByApp */)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800303 }
304
Andreas Huberf9334412010-12-15 15:17:42 -0800305 msg->post();
306}
307
308void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800309 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
Andreas Huberf9334412010-12-15 15:17:42 -0800310 msg->setObject("sink", sink);
311 msg->post();
312}
313
314void NuPlayer::start() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800315 (new AMessage(kWhatStart, this))->post();
Andreas Huberf9334412010-12-15 15:17:42 -0800316}
317
Wei Jia98160162015-02-04 17:01:11 -0800318void NuPlayer::setPlaybackRate(float rate) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800319 sp<AMessage> msg = new AMessage(kWhatSetRate, this);
Wei Jia98160162015-02-04 17:01:11 -0800320 msg->setFloat("rate", rate);
321 msg->post();
322}
323
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800324void NuPlayer::pause() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800325 (new AMessage(kWhatPause, this))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800326}
327
Andreas Huber1aef2112011-01-04 14:01:29 -0800328void NuPlayer::resetAsync() {
Chong Zhang48296b72014-09-14 14:28:45 -0700329 if (mSource != NULL) {
330 // During a reset, the data source might be unresponsive already, we need to
331 // disconnect explicitly so that reads exit promptly.
332 // We can't queue the disconnect request to the looper, as it might be
333 // queued behind a stuck read and never gets processed.
334 // Doing a disconnect outside the looper to allows the pending reads to exit
335 // (either successfully or with error).
336 mSource->disconnect();
337 }
338
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800339 (new AMessage(kWhatReset, this))->post();
Andreas Huber1aef2112011-01-04 14:01:29 -0800340}
341
Wei Jiae427abf2014-09-22 15:21:11 -0700342void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800343 sp<AMessage> msg = new AMessage(kWhatSeek, this);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800344 msg->setInt64("seekTimeUs", seekTimeUs);
Wei Jiae427abf2014-09-22 15:21:11 -0700345 msg->setInt32("needNotify", needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800346 msg->post();
347}
348
Andreas Huber53df1a42010-12-22 10:03:04 -0800349
Chong Zhang404fced2014-06-11 14:45:31 -0700350void NuPlayer::writeTrackInfo(
351 Parcel* reply, const sp<AMessage> format) const {
352 int32_t trackType;
353 CHECK(format->findInt32("type", &trackType));
354
355 AString lang;
356 CHECK(format->findString("language", &lang));
357
358 reply->writeInt32(2); // write something non-zero
359 reply->writeInt32(trackType);
360 reply->writeString16(String16(lang.c_str()));
361
362 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
363 AString mime;
364 CHECK(format->findString("mime", &mime));
365
366 int32_t isAuto, isDefault, isForced;
367 CHECK(format->findInt32("auto", &isAuto));
368 CHECK(format->findInt32("default", &isDefault));
369 CHECK(format->findInt32("forced", &isForced));
370
371 reply->writeString16(String16(mime.c_str()));
372 reply->writeInt32(isAuto);
373 reply->writeInt32(isDefault);
374 reply->writeInt32(isForced);
375 }
376}
377
Andreas Huberf9334412010-12-15 15:17:42 -0800378void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
379 switch (msg->what()) {
380 case kWhatSetDataSource:
381 {
Steve Block3856b092011-10-20 11:56:00 +0100382 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800383
384 CHECK(mSource == NULL);
385
Chong Zhang3de157d2014-08-05 20:54:44 -0700386 status_t err = OK;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800387 sp<RefBase> obj;
388 CHECK(msg->findObject("source", &obj));
Chong Zhang3de157d2014-08-05 20:54:44 -0700389 if (obj != NULL) {
390 mSource = static_cast<Source *>(obj.get());
Chong Zhang3de157d2014-08-05 20:54:44 -0700391 } else {
392 err = UNKNOWN_ERROR;
393 }
Andreas Huber9575c962013-02-05 13:59:56 -0800394
395 CHECK(mDriver != NULL);
396 sp<NuPlayerDriver> driver = mDriver.promote();
397 if (driver != NULL) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700398 driver->notifySetDataSourceCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -0800399 }
400 break;
401 }
402
403 case kWhatPrepare:
404 {
405 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800406 break;
407 }
408
Chong Zhangdcb89b32013-08-06 09:44:47 -0700409 case kWhatGetTrackInfo:
410 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800411 sp<AReplyToken> replyID;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700412 CHECK(msg->senderAwaitsResponse(&replyID));
413
Chong Zhang404fced2014-06-11 14:45:31 -0700414 Parcel* reply;
415 CHECK(msg->findPointer("reply", (void**)&reply));
416
417 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700418 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700419 inbandTracks = mSource->getTrackCount();
420 }
421
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700422 size_t ccTracks = 0;
423 if (mCCDecoder != NULL) {
424 ccTracks = mCCDecoder->getTrackCount();
425 }
426
Chong Zhang404fced2014-06-11 14:45:31 -0700427 // total track count
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700428 reply->writeInt32(inbandTracks + ccTracks);
Chong Zhang404fced2014-06-11 14:45:31 -0700429
430 // write inband tracks
431 for (size_t i = 0; i < inbandTracks; ++i) {
432 writeTrackInfo(reply, mSource->getTrackInfo(i));
Chong Zhangdcb89b32013-08-06 09:44:47 -0700433 }
434
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700435 // write CC track
436 for (size_t i = 0; i < ccTracks; ++i) {
437 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
438 }
439
Chong Zhangdcb89b32013-08-06 09:44:47 -0700440 sp<AMessage> response = new AMessage;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700441 response->postReply(replyID);
442 break;
443 }
444
Robert Shih7c4f0d72014-07-09 18:53:31 -0700445 case kWhatGetSelectedTrack:
446 {
447 status_t err = INVALID_OPERATION;
448 if (mSource != NULL) {
449 err = OK;
450
451 int32_t type32;
452 CHECK(msg->findInt32("type", (int32_t*)&type32));
453 media_track_type type = (media_track_type)type32;
454 ssize_t selectedTrack = mSource->getSelectedTrack(type);
455
456 Parcel* reply;
457 CHECK(msg->findPointer("reply", (void**)&reply));
458 reply->writeInt32(selectedTrack);
459 }
460
461 sp<AMessage> response = new AMessage;
462 response->setInt32("err", err);
463
Lajos Molnar3f274362015-03-05 14:35:41 -0800464 sp<AReplyToken> replyID;
Robert Shih7c4f0d72014-07-09 18:53:31 -0700465 CHECK(msg->senderAwaitsResponse(&replyID));
466 response->postReply(replyID);
467 break;
468 }
469
Chong Zhangdcb89b32013-08-06 09:44:47 -0700470 case kWhatSelectTrack:
471 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800472 sp<AReplyToken> replyID;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700473 CHECK(msg->senderAwaitsResponse(&replyID));
474
Chong Zhang404fced2014-06-11 14:45:31 -0700475 size_t trackIndex;
476 int32_t select;
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700477 int64_t timeUs;
Chong Zhang404fced2014-06-11 14:45:31 -0700478 CHECK(msg->findSize("trackIndex", &trackIndex));
479 CHECK(msg->findInt32("select", &select));
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700480 CHECK(msg->findInt64("timeUs", &timeUs));
Chong Zhang404fced2014-06-11 14:45:31 -0700481
Chong Zhangdcb89b32013-08-06 09:44:47 -0700482 status_t err = INVALID_OPERATION;
Chong Zhang404fced2014-06-11 14:45:31 -0700483
484 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700485 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700486 inbandTracks = mSource->getTrackCount();
487 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700488 size_t ccTracks = 0;
489 if (mCCDecoder != NULL) {
490 ccTracks = mCCDecoder->getTrackCount();
491 }
Chong Zhang404fced2014-06-11 14:45:31 -0700492
493 if (trackIndex < inbandTracks) {
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700494 err = mSource->selectTrack(trackIndex, select, timeUs);
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700495
496 if (!select && err == OK) {
497 int32_t type;
498 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
499 if (info != NULL
500 && info->findInt32("type", &type)
501 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
502 ++mTimedTextGeneration;
503 }
504 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700505 } else {
506 trackIndex -= inbandTracks;
507
508 if (trackIndex < ccTracks) {
509 err = mCCDecoder->selectTrack(trackIndex, select);
510 }
Chong Zhangdcb89b32013-08-06 09:44:47 -0700511 }
512
513 sp<AMessage> response = new AMessage;
514 response->setInt32("err", err);
515
516 response->postReply(replyID);
517 break;
518 }
519
Andreas Huberb7c8e912012-11-27 15:02:53 -0800520 case kWhatPollDuration:
521 {
522 int32_t generation;
523 CHECK(msg->findInt32("generation", &generation));
524
525 if (generation != mPollDurationGeneration) {
526 // stale
527 break;
528 }
529
530 int64_t durationUs;
531 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
532 sp<NuPlayerDriver> driver = mDriver.promote();
533 if (driver != NULL) {
534 driver->notifyDuration(durationUs);
535 }
536 }
537
538 msg->post(1000000ll); // poll again in a second.
539 break;
540 }
541
Glenn Kasten11731182011-02-08 17:26:17 -0800542 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800543 {
Steve Block3856b092011-10-20 11:56:00 +0100544 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800545
546 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800547 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800548
Lajos Molnarf4849522014-12-10 16:58:57 -0800549 if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) {
Wei Jiafef808d2014-10-31 17:57:05 -0700550 performSetSurface(static_cast<NativeWindowWrapper *>(obj.get()));
551 break;
552 }
553
554 mDeferredActions.push_back(
555 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
556 FLUSH_CMD_SHUTDOWN /* video */));
557
Andreas Huber57a339c2012-12-03 11:18:00 -0800558 mDeferredActions.push_back(
559 new SetSurfaceAction(
560 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700561
Andreas Huber57a339c2012-12-03 11:18:00 -0800562 if (obj != NULL) {
Wei Jiafef808d2014-10-31 17:57:05 -0700563 if (mStarted) {
Andy Hung73535852014-09-05 11:42:58 -0700564 // Issue a seek to refresh the video screen only if started otherwise
565 // the extractor may not yet be started and will assert.
566 // If the video decoder is not set (perhaps audio only in this case)
567 // do not perform a seek as it is not needed.
Ronghua Wua73d9e02014-10-08 15:13:29 -0700568 int64_t currentPositionUs = 0;
569 if (getCurrentPosition(&currentPositionUs) == OK) {
570 mDeferredActions.push_back(
571 new SeekAction(currentPositionUs, false /* needNotify */));
572 }
Andy Hung73535852014-09-05 11:42:58 -0700573 }
Wei Jiaac428aa2014-09-02 19:01:34 -0700574
Andreas Huber57a339c2012-12-03 11:18:00 -0800575 // If there is a new surface texture, instantiate decoders
576 // again if possible.
577 mDeferredActions.push_back(
578 new SimpleAction(&NuPlayer::performScanSources));
579 }
580
Chong Zhangf8d71772014-11-26 15:08:34 -0800581 // After a flush without shutdown, decoder is paused.
582 // Don't resume it until source seek is done, otherwise it could
Chong Zhang7137ec72014-11-12 16:41:05 -0800583 // start pulling stale data too soon.
584 mDeferredActions.push_back(
Chong Zhangf8d71772014-11-26 15:08:34 -0800585 new ResumeDecoderAction(false /* needNotify */));
Chong Zhang7137ec72014-11-12 16:41:05 -0800586
Andreas Huber57a339c2012-12-03 11:18:00 -0800587 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800588 break;
589 }
590
591 case kWhatSetAudioSink:
592 {
Steve Block3856b092011-10-20 11:56:00 +0100593 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800594
595 sp<RefBase> obj;
596 CHECK(msg->findObject("sink", &obj));
597
598 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
599 break;
600 }
601
602 case kWhatStart:
603 {
Steve Block3856b092011-10-20 11:56:00 +0100604 ALOGV("kWhatStart");
Wei Jia94211742014-10-28 17:09:06 -0700605 if (mStarted) {
606 onResume();
607 } else {
608 onStart();
Lajos Molnar09524832014-07-17 14:29:51 -0700609 }
Chong Zhangefbb6192015-01-30 17:13:27 -0800610 mPausedByClient = false;
Andreas Huberf9334412010-12-15 15:17:42 -0800611 break;
612 }
613
Wei Jia98160162015-02-04 17:01:11 -0800614 case kWhatSetRate:
615 {
616 ALOGV("kWhatSetRate");
617 CHECK(msg->findFloat("rate", &mPlaybackRate));
618 if (mRenderer != NULL) {
619 mRenderer->setPlaybackRate(mPlaybackRate);
620 }
621 break;
622 }
623
Andreas Huberf9334412010-12-15 15:17:42 -0800624 case kWhatScanSources:
625 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800626 int32_t generation;
627 CHECK(msg->findInt32("generation", &generation));
628 if (generation != mScanSourcesGeneration) {
629 // Drop obsolete msg.
630 break;
631 }
632
Andreas Huber5bc087c2010-12-23 10:27:40 -0800633 mScanSourcesPending = false;
634
Steve Block3856b092011-10-20 11:56:00 +0100635 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800636 mAudioDecoder != NULL, mVideoDecoder != NULL);
637
Andreas Huberb7c8e912012-11-27 15:02:53 -0800638 bool mHadAnySourcesBefore =
639 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
640
Andy Hung282a7e32014-08-14 15:56:34 -0700641 // initialize video before audio because successful initialization of
642 // video may change deep buffer mode of audio.
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700643 if (mNativeWindow != NULL) {
644 instantiateDecoder(false, &mVideoDecoder);
645 }
Andreas Huberf9334412010-12-15 15:17:42 -0800646
Ronghua Wua10fd232014-11-06 16:15:20 -0800647 // Don't try to re-open audio sink if there's an existing decoder.
648 if (mAudioSink != NULL && mAudioDecoder == NULL) {
649 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
650 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
651 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
Andy Hung202bce12014-12-03 11:47:36 -0800652 const bool hasVideo = (videoFormat != NULL);
653 const bool canOffload = canOffloadStream(
654 audioMeta, hasVideo, true /* is_streaming */, streamType);
Ronghua Wua10fd232014-11-06 16:15:20 -0800655 if (canOffload) {
656 if (!mOffloadAudio) {
657 mRenderer->signalEnableOffloadAudio();
658 }
Andy Hung282a7e32014-08-14 15:56:34 -0700659 // open audio sink early under offload mode.
660 sp<AMessage> format = mSource->getFormat(true /*audio*/);
Andy Hung202bce12014-12-03 11:47:36 -0800661 tryOpenAudioSinkForOffload(format, hasVideo);
Andy Hung282a7e32014-08-14 15:56:34 -0700662 }
Andreas Huber5bc087c2010-12-23 10:27:40 -0800663 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800664 }
665
Andreas Huberb7c8e912012-11-27 15:02:53 -0800666 if (!mHadAnySourcesBefore
667 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
668 // This is the first time we've found anything playable.
669
Andreas Huber9575c962013-02-05 13:59:56 -0800670 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800671 schedulePollDuration();
672 }
673 }
674
Andreas Hubereac68ba2011-09-27 12:12:25 -0700675 status_t err;
676 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800677 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
678 // We're not currently decoding anything (no audio or
679 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700680
681 if (err == ERROR_END_OF_STREAM) {
682 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
683 } else {
684 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
685 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800686 }
Andreas Huberf9334412010-12-15 15:17:42 -0800687 break;
688 }
689
Andreas Huberfbe9d812012-08-31 14:05:27 -0700690 if ((mAudioDecoder == NULL && mAudioSink != NULL)
691 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800692 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800693 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800694 }
695 break;
696 }
697
698 case kWhatVideoNotify:
699 case kWhatAudioNotify:
700 {
701 bool audio = msg->what() == kWhatAudioNotify;
702
Wei Jia88703c32014-08-06 11:24:07 -0700703 int32_t currentDecoderGeneration =
704 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
705 int32_t requesterGeneration = currentDecoderGeneration - 1;
706 CHECK(msg->findInt32("generation", &requesterGeneration));
707
708 if (requesterGeneration != currentDecoderGeneration) {
709 ALOGV("got message from old %s decoder, generation(%d:%d)",
710 audio ? "audio" : "video", requesterGeneration,
711 currentDecoderGeneration);
712 sp<AMessage> reply;
713 if (!(msg->findMessage("reply", &reply))) {
714 return;
715 }
716
717 reply->setInt32("err", INFO_DISCONTINUITY);
718 reply->post();
719 return;
720 }
721
Andreas Huberf9334412010-12-15 15:17:42 -0800722 int32_t what;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800723 CHECK(msg->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -0800724
Chong Zhang7137ec72014-11-12 16:41:05 -0800725 if (what == DecoderBase::kWhatInputDiscontinuity) {
726 int32_t formatChange;
727 CHECK(msg->findInt32("formatChange", &formatChange));
Andreas Huberf9334412010-12-15 15:17:42 -0800728
Chong Zhang7137ec72014-11-12 16:41:05 -0800729 ALOGV("%s discontinuity: formatChange %d",
730 audio ? "audio" : "video", formatChange);
731
732 if (formatChange) {
733 mDeferredActions.push_back(
734 new FlushDecoderAction(
735 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
736 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
Andreas Huberf9334412010-12-15 15:17:42 -0800737 }
Chong Zhang7137ec72014-11-12 16:41:05 -0800738
739 mDeferredActions.push_back(
740 new SimpleAction(
741 &NuPlayer::performScanSources));
742
743 processDeferredActions();
744 } else if (what == DecoderBase::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700745 int32_t err;
Lajos Molnar1cd13982014-01-17 15:12:51 -0800746 CHECK(msg->findInt32("err", &err));
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700747
748 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100749 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700750 } else {
Steve Block3856b092011-10-20 11:56:00 +0100751 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700752 audio ? "audio" : "video",
753 err);
754 }
755
756 mRenderer->queueEOS(audio, err);
Chong Zhang7137ec72014-11-12 16:41:05 -0800757 } else if (what == DecoderBase::kWhatFlushCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100758 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800759
Andy Hung8d121d42014-10-03 09:53:53 -0700760 handleFlushComplete(audio, true /* isDecoder */);
Andreas Huber3831a062010-12-21 10:22:33 -0800761 finishFlushIfPossible();
Chong Zhang7137ec72014-11-12 16:41:05 -0800762 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
Lajos Molnar1cd13982014-01-17 15:12:51 -0800763 sp<AMessage> format;
764 CHECK(msg->findMessage("format", &format));
765
Wei Jiac6cfd702014-11-11 16:33:20 -0800766 sp<AMessage> inputFormat =
767 mSource->getFormat(false /* audio */);
Andreas Huber3831a062010-12-21 10:22:33 -0800768
Wei Jiac6cfd702014-11-11 16:33:20 -0800769 updateVideoSize(inputFormat, format);
Chong Zhang7137ec72014-11-12 16:41:05 -0800770 } else if (what == DecoderBase::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100771 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800772 if (audio) {
773 mAudioDecoder.clear();
Wei Jia57568df2014-09-22 10:16:29 -0700774 ++mAudioDecoderGeneration;
Andreas Huber3831a062010-12-21 10:22:33 -0800775
776 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
777 mFlushingAudio = SHUT_DOWN;
778 } else {
779 mVideoDecoder.clear();
Wei Jia57568df2014-09-22 10:16:29 -0700780 ++mVideoDecoderGeneration;
Andreas Huber3831a062010-12-21 10:22:33 -0800781
782 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
783 mFlushingVideo = SHUT_DOWN;
784 }
785
786 finishFlushIfPossible();
Chong Zhangf8d71772014-11-26 15:08:34 -0800787 } else if (what == DecoderBase::kWhatResumeCompleted) {
788 finishResume();
Chong Zhang7137ec72014-11-12 16:41:05 -0800789 } else if (what == DecoderBase::kWhatError) {
Chong Zhangf4c0a942014-08-11 15:14:10 -0700790 status_t err;
Andy Hung2abde2c2014-09-30 14:40:32 -0700791 if (!msg->findInt32("err", &err) || err == OK) {
Chong Zhangf4c0a942014-08-11 15:14:10 -0700792 err = UNKNOWN_ERROR;
793 }
Andy Hungcf31f1e2014-09-23 14:59:01 -0700794
Andy Hung2abde2c2014-09-30 14:40:32 -0700795 // Decoder errors can be due to Source (e.g. from streaming),
796 // or from decoding corrupted bitstreams, or from other decoder
797 // MediaCodec operations (e.g. from an ongoing reset or seek).
Andy Hung202bce12014-12-03 11:47:36 -0800798 // They may also be due to openAudioSink failure at
799 // decoder start or after a format change.
Andy Hung2abde2c2014-09-30 14:40:32 -0700800 //
801 // We try to gracefully shut down the affected decoder if possible,
802 // rather than trying to force the shutdown with something
803 // similar to performReset(). This method can lead to a hang
804 // if MediaCodec functions block after an error, but they should
805 // typically return INVALID_OPERATION instead of blocking.
806
807 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
808 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
809 err, audio ? "audio" : "video", *flushing);
810
811 switch (*flushing) {
812 case NONE:
813 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -0700814 new FlushDecoderAction(
815 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
816 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
Andy Hung2abde2c2014-09-30 14:40:32 -0700817 processDeferredActions();
818 break;
819 case FLUSHING_DECODER:
820 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
821 break; // Wait for flush to complete.
822 case FLUSHING_DECODER_SHUTDOWN:
823 break; // Wait for flush to complete.
824 case SHUTTING_DOWN_DECODER:
825 break; // Wait for shutdown to complete.
826 case FLUSHED:
827 // Widevine source reads must stop before releasing the video decoder.
828 if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
829 mSource->stop();
830 }
831 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
832 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
833 break;
834 case SHUT_DOWN:
835 finishFlushIfPossible(); // Should not occur.
836 break; // Finish anyways.
Marco Nelissen9e2b7912014-08-18 16:13:03 -0700837 }
Andy Hung2abde2c2014-09-30 14:40:32 -0700838 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
Lajos Molnar1cd13982014-01-17 15:12:51 -0800839 } else {
840 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800841 what,
842 what >> 24,
843 (what >> 16) & 0xff,
844 (what >> 8) & 0xff,
845 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800846 }
847
848 break;
849 }
850
851 case kWhatRendererNotify:
852 {
Wei Jia57568df2014-09-22 10:16:29 -0700853 int32_t requesterGeneration = mRendererGeneration - 1;
854 CHECK(msg->findInt32("generation", &requesterGeneration));
855 if (requesterGeneration != mRendererGeneration) {
856 ALOGV("got message from old renderer, generation(%d:%d)",
857 requesterGeneration, mRendererGeneration);
858 return;
859 }
860
Andreas Huberf9334412010-12-15 15:17:42 -0800861 int32_t what;
862 CHECK(msg->findInt32("what", &what));
863
864 if (what == Renderer::kWhatEOS) {
865 int32_t audio;
866 CHECK(msg->findInt32("audio", &audio));
867
Andreas Huberc92fd242011-08-16 13:48:44 -0700868 int32_t finalResult;
869 CHECK(msg->findInt32("finalResult", &finalResult));
870
Andreas Huberf9334412010-12-15 15:17:42 -0800871 if (audio) {
872 mAudioEOS = true;
873 } else {
874 mVideoEOS = true;
875 }
876
Andreas Huberc92fd242011-08-16 13:48:44 -0700877 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100878 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700879 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000880 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700881 audio ? "audio" : "video", finalResult);
882
883 notifyListener(
884 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
885 }
Andreas Huberf9334412010-12-15 15:17:42 -0800886
887 if ((mAudioEOS || mAudioDecoder == NULL)
888 && (mVideoEOS || mVideoDecoder == NULL)) {
889 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
890 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700891 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800892 int32_t audio;
893 CHECK(msg->findInt32("audio", &audio));
894
Steve Block3856b092011-10-20 11:56:00 +0100895 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
Andy Hung8d121d42014-10-03 09:53:53 -0700896 handleFlushComplete(audio, false /* isDecoder */);
897 finishFlushIfPossible();
James Dongf57b4ea2012-07-20 13:38:36 -0700898 } else if (what == Renderer::kWhatVideoRenderingStart) {
899 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Lajos Molnarcbaffcf2013-08-14 18:30:38 -0700900 } else if (what == Renderer::kWhatMediaRenderingStart) {
901 ALOGV("media rendering started");
902 notifyListener(MEDIA_STARTED, 0, 0);
Wei Jia3a2956d2014-07-22 16:01:33 -0700903 } else if (what == Renderer::kWhatAudioOffloadTearDown) {
Ronghua Wua10fd232014-11-06 16:15:20 -0800904 ALOGV("Tear down audio offload, fall back to s/w path if due to error.");
Wei Jia3a2956d2014-07-22 16:01:33 -0700905 int64_t positionUs;
906 CHECK(msg->findInt64("positionUs", &positionUs));
Ronghua Wu08529172014-10-02 16:55:52 -0700907 int32_t reason;
908 CHECK(msg->findInt32("reason", &reason));
Andy Hung282a7e32014-08-14 15:56:34 -0700909 closeAudioSink();
Wei Jia3a2956d2014-07-22 16:01:33 -0700910 mAudioDecoder.clear();
Wei Jia57568df2014-09-22 10:16:29 -0700911 ++mAudioDecoderGeneration;
Chong Zhang7137ec72014-11-12 16:41:05 -0800912 mRenderer->flush(
913 true /* audio */, false /* notifyComplete */);
Wei Jia3a2956d2014-07-22 16:01:33 -0700914 if (mVideoDecoder != NULL) {
Chong Zhang7137ec72014-11-12 16:41:05 -0800915 mRenderer->flush(
916 false /* audio */, false /* notifyComplete */);
Wei Jia3a2956d2014-07-22 16:01:33 -0700917 }
Wei Jia3a2956d2014-07-22 16:01:33 -0700918
Wei Jiae427abf2014-09-22 15:21:11 -0700919 performSeek(positionUs, false /* needNotify */);
Ronghua Wu08529172014-10-02 16:55:52 -0700920 if (reason == Renderer::kDueToError) {
Ronghua Wua10fd232014-11-06 16:15:20 -0800921 mRenderer->signalDisableOffloadAudio();
922 mOffloadAudio = false;
Ronghua Wu08529172014-10-02 16:55:52 -0700923 instantiateDecoder(true /* audio */, &mAudioDecoder);
924 }
Andreas Huberf9334412010-12-15 15:17:42 -0800925 }
926 break;
927 }
928
929 case kWhatMoreDataQueued:
930 {
931 break;
932 }
933
Andreas Huber1aef2112011-01-04 14:01:29 -0800934 case kWhatReset:
935 {
Steve Block3856b092011-10-20 11:56:00 +0100936 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800937
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800938 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -0700939 new FlushDecoderAction(
940 FLUSH_CMD_SHUTDOWN /* audio */,
941 FLUSH_CMD_SHUTDOWN /* video */));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800942
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800943 mDeferredActions.push_back(
944 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800945
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800946 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800947 break;
948 }
949
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800950 case kWhatSeek:
951 {
952 int64_t seekTimeUs;
Wei Jiae427abf2014-09-22 15:21:11 -0700953 int32_t needNotify;
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800954 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
Wei Jiae427abf2014-09-22 15:21:11 -0700955 CHECK(msg->findInt32("needNotify", &needNotify));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800956
Wei Jiae427abf2014-09-22 15:21:11 -0700957 ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d",
958 seekTimeUs, needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800959
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800960 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -0700961 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
962 FLUSH_CMD_FLUSH /* video */));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800963
Wei Jiae427abf2014-09-22 15:21:11 -0700964 mDeferredActions.push_back(
965 new SeekAction(seekTimeUs, needNotify));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800966
Chong Zhangf8d71772014-11-26 15:08:34 -0800967 // After a flush without shutdown, decoder is paused.
968 // Don't resume it until source seek is done, otherwise it could
Chong Zhang7137ec72014-11-12 16:41:05 -0800969 // start pulling stale data too soon.
970 mDeferredActions.push_back(
Chong Zhangf8d71772014-11-26 15:08:34 -0800971 new ResumeDecoderAction(needNotify));
Chong Zhang7137ec72014-11-12 16:41:05 -0800972
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800973 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800974 break;
975 }
976
Andreas Huberb4082222011-01-20 15:23:04 -0800977 case kWhatPause:
978 {
Chong Zhangefbb6192015-01-30 17:13:27 -0800979 onPause();
980 mPausedByClient = true;
Andreas Huberb4082222011-01-20 15:23:04 -0800981 break;
982 }
983
Andreas Huberb5f25f02013-02-05 10:14:26 -0800984 case kWhatSourceNotify:
985 {
Andreas Huber9575c962013-02-05 13:59:56 -0800986 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800987 break;
988 }
989
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700990 case kWhatClosedCaptionNotify:
991 {
992 onClosedCaptionNotify(msg);
993 break;
994 }
995
Andreas Huberf9334412010-12-15 15:17:42 -0800996 default:
997 TRESPASS();
998 break;
999 }
1000}
1001
Wei Jia94211742014-10-28 17:09:06 -07001002void NuPlayer::onResume() {
Chong Zhangefbb6192015-01-30 17:13:27 -08001003 if (!mPaused) {
1004 return;
1005 }
1006 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001007 if (mSource != NULL) {
1008 mSource->resume();
1009 } else {
1010 ALOGW("resume called when source is gone or not set");
1011 }
1012 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1013 // needed.
1014 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1015 instantiateDecoder(true /* audio */, &mAudioDecoder);
1016 }
1017 if (mRenderer != NULL) {
1018 mRenderer->resume();
1019 } else {
1020 ALOGW("resume called when renderer is gone or not set");
1021 }
1022}
1023
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001024status_t NuPlayer::onInstantiateSecureDecoders() {
1025 status_t err;
1026 if (!(mSourceFlags & Source::FLAG_SECURE)) {
1027 return BAD_TYPE;
1028 }
1029
1030 if (mRenderer != NULL) {
1031 ALOGE("renderer should not be set when instantiating secure decoders");
1032 return UNKNOWN_ERROR;
1033 }
1034
1035 // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
1036 // data on instantiation.
1037 if (mNativeWindow != NULL) {
1038 err = instantiateDecoder(false, &mVideoDecoder);
1039 if (err != OK) {
1040 return err;
1041 }
1042 }
1043
1044 if (mAudioSink != NULL) {
1045 err = instantiateDecoder(true, &mAudioDecoder);
1046 if (err != OK) {
1047 return err;
1048 }
1049 }
1050 return OK;
1051}
1052
Wei Jia94211742014-10-28 17:09:06 -07001053void NuPlayer::onStart() {
Wei Jia94211742014-10-28 17:09:06 -07001054 mOffloadAudio = false;
1055 mAudioEOS = false;
1056 mVideoEOS = false;
Wei Jia94211742014-10-28 17:09:06 -07001057 mStarted = true;
1058
Wei Jia94211742014-10-28 17:09:06 -07001059 mSource->start();
1060
1061 uint32_t flags = 0;
1062
1063 if (mSource->isRealTime()) {
1064 flags |= Renderer::FLAG_REAL_TIME;
1065 }
1066
1067 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1068 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1069 if (mAudioSink != NULL) {
1070 streamType = mAudioSink->getAudioStreamType();
1071 }
1072
1073 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1074
1075 mOffloadAudio =
1076 canOffloadStream(audioMeta, (videoFormat != NULL),
1077 true /* is_streaming */, streamType);
1078 if (mOffloadAudio) {
1079 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1080 }
1081
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001082 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
Wei Jia94211742014-10-28 17:09:06 -07001083 ++mRendererGeneration;
1084 notify->setInt32("generation", mRendererGeneration);
1085 mRenderer = new Renderer(mAudioSink, notify, flags);
Wei Jia94211742014-10-28 17:09:06 -07001086 mRendererLooper = new ALooper;
1087 mRendererLooper->setName("NuPlayerRenderer");
1088 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1089 mRendererLooper->registerHandler(mRenderer);
Wei Jiac8206ff2015-03-04 13:59:37 -08001090 if (mPlaybackRate != 1.0) {
1091 mRenderer->setPlaybackRate(mPlaybackRate);
1092 }
Wei Jia94211742014-10-28 17:09:06 -07001093
1094 sp<MetaData> meta = getFileMeta();
1095 int32_t rate;
1096 if (meta != NULL
1097 && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
1098 mRenderer->setVideoFrameRate(rate);
1099 }
1100
Wei Jiac6cfd702014-11-11 16:33:20 -08001101 if (mVideoDecoder != NULL) {
1102 mVideoDecoder->setRenderer(mRenderer);
1103 }
1104 if (mAudioDecoder != NULL) {
1105 mAudioDecoder->setRenderer(mRenderer);
1106 }
1107
Wei Jia94211742014-10-28 17:09:06 -07001108 postScanSources();
1109}
1110
Chong Zhangefbb6192015-01-30 17:13:27 -08001111void NuPlayer::onPause() {
1112 if (mPaused) {
1113 return;
1114 }
1115 mPaused = true;
1116 if (mSource != NULL) {
1117 mSource->pause();
1118 } else {
1119 ALOGW("pause called when source is gone or not set");
1120 }
1121 if (mRenderer != NULL) {
1122 mRenderer->pause();
1123 } else {
1124 ALOGW("pause called when renderer is gone or not set");
1125 }
1126}
1127
Ronghua Wud7988b12014-10-03 15:19:10 -07001128bool NuPlayer::audioDecoderStillNeeded() {
1129 // Audio decoder is no longer needed if it's in shut/shutting down status.
1130 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1131}
1132
Andy Hung8d121d42014-10-03 09:53:53 -07001133void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1134 // We wait for both the decoder flush and the renderer flush to complete
1135 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1136
1137 mFlushComplete[audio][isDecoder] = true;
1138 if (!mFlushComplete[audio][!isDecoder]) {
1139 return;
1140 }
1141
1142 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1143 switch (*state) {
1144 case FLUSHING_DECODER:
1145 {
1146 *state = FLUSHED;
Andy Hung8d121d42014-10-03 09:53:53 -07001147 break;
1148 }
1149
1150 case FLUSHING_DECODER_SHUTDOWN:
1151 {
1152 *state = SHUTTING_DOWN_DECODER;
1153
1154 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1155 if (!audio) {
Andy Hung8d121d42014-10-03 09:53:53 -07001156 // Widevine source reads must stop before releasing the video decoder.
1157 if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
1158 mSource->stop();
1159 }
1160 }
1161 getDecoder(audio)->initiateShutdown();
1162 break;
1163 }
1164
1165 default:
1166 // decoder flush completes only occur in a flushing state.
1167 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1168 break;
1169 }
1170}
1171
Andreas Huber3831a062010-12-21 10:22:33 -08001172void NuPlayer::finishFlushIfPossible() {
Wei Jia53904f32014-07-29 10:22:53 -07001173 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1174 && mFlushingAudio != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001175 return;
1176 }
1177
Wei Jia53904f32014-07-29 10:22:53 -07001178 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1179 && mFlushingVideo != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001180 return;
1181 }
1182
Steve Block3856b092011-10-20 11:56:00 +01001183 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -08001184
Andreas Huber3831a062010-12-21 10:22:33 -08001185 mFlushingAudio = NONE;
1186 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -08001187
Andy Hung8d121d42014-10-03 09:53:53 -07001188 clearFlushComplete();
1189
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001190 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001191}
1192
1193void NuPlayer::postScanSources() {
1194 if (mScanSourcesPending) {
1195 return;
1196 }
1197
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001198 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
Andreas Huber1aef2112011-01-04 14:01:29 -08001199 msg->setInt32("generation", mScanSourcesGeneration);
1200 msg->post();
1201
1202 mScanSourcesPending = true;
1203}
1204
Andy Hung202bce12014-12-03 11:47:36 -08001205void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) {
1206 // Note: This is called early in NuPlayer to determine whether offloading
1207 // is possible; otherwise the decoders call the renderer openAudioSink directly.
Andy Hung282a7e32014-08-14 15:56:34 -07001208
Andy Hung202bce12014-12-03 11:47:36 -08001209 status_t err = mRenderer->openAudioSink(
1210 format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);
1211 if (err != OK) {
1212 // Any failure we turn off mOffloadAudio.
1213 mOffloadAudio = false;
1214 } else if (mOffloadAudio) {
Chong Zhang3b9eb1f2014-10-15 17:05:08 -07001215 sp<MetaData> audioMeta =
1216 mSource->getFormatMeta(true /* audio */);
1217 sendMetaDataToHal(mAudioSink, audioMeta);
Andy Hung282a7e32014-08-14 15:56:34 -07001218 }
1219}
1220
1221void NuPlayer::closeAudioSink() {
Chong Zhang3b9eb1f2014-10-15 17:05:08 -07001222 mRenderer->closeAudioSink();
Andy Hung282a7e32014-08-14 15:56:34 -07001223}
1224
Chong Zhang7137ec72014-11-12 16:41:05 -08001225status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -08001226 if (*decoder != NULL) {
1227 return OK;
1228 }
1229
Andreas Huber84066782011-08-16 09:34:26 -07001230 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -08001231
Andreas Huber84066782011-08-16 09:34:26 -07001232 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001233 return -EWOULDBLOCK;
1234 }
1235
Andreas Huber3fe62152011-09-16 15:09:22 -07001236 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -07001237 AString mime;
1238 CHECK(format->findString("mime", &mime));
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001239
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001240 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
Chong Zhang341ab6e2015-02-04 13:37:18 -08001241 if (mCCDecoder == NULL) {
1242 mCCDecoder = new CCDecoder(ccNotify);
1243 }
Lajos Molnar09524832014-07-17 14:29:51 -07001244
1245 if (mSourceFlags & Source::FLAG_SECURE) {
1246 format->setInt32("secure", true);
1247 }
Chong Zhang17134602015-01-07 16:14:34 -08001248
1249 if (mSourceFlags & Source::FLAG_PROTECTED) {
1250 format->setInt32("protected", true);
1251 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001252 }
1253
Wei Jiabc2fb722014-07-08 16:37:57 -07001254 if (audio) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001255 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07001256 ++mAudioDecoderGeneration;
1257 notify->setInt32("generation", mAudioDecoderGeneration);
1258
Wei Jiabc2fb722014-07-08 16:37:57 -07001259 if (mOffloadAudio) {
Wei Jiac6cfd702014-11-11 16:33:20 -08001260 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
Wei Jiabc2fb722014-07-08 16:37:57 -07001261 } else {
Wei Jiac6cfd702014-11-11 16:33:20 -08001262 *decoder = new Decoder(notify, mSource, mRenderer);
Wei Jiabc2fb722014-07-08 16:37:57 -07001263 }
1264 } else {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001265 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07001266 ++mVideoDecoderGeneration;
1267 notify->setInt32("generation", mVideoDecoderGeneration);
1268
Chong Zhang7137ec72014-11-12 16:41:05 -08001269 *decoder = new Decoder(
1270 notify, mSource, mRenderer, mNativeWindow, mCCDecoder);
Lajos Molnard9fd6312014-11-06 11:00:00 -08001271
1272 // enable FRC if high-quality AV sync is requested, even if not
1273 // queuing to native window, as this will even improve textureview
1274 // playback.
1275 {
1276 char value[PROPERTY_VALUE_MAX];
1277 if (property_get("persist.sys.media.avsync", value, NULL) &&
1278 (!strcmp("1", value) || !strcasecmp("true", value))) {
1279 format->setInt32("auto-frc", 1);
1280 }
1281 }
Wei Jiabc2fb722014-07-08 16:37:57 -07001282 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001283 (*decoder)->init();
Andreas Huber84066782011-08-16 09:34:26 -07001284 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -08001285
Lajos Molnar09524832014-07-17 14:29:51 -07001286 // allocate buffers to decrypt widevine source buffers
1287 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1288 Vector<sp<ABuffer> > inputBufs;
1289 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1290
1291 Vector<MediaBuffer *> mediaBufs;
1292 for (size_t i = 0; i < inputBufs.size(); i++) {
1293 const sp<ABuffer> &buffer = inputBufs[i];
1294 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1295 mediaBufs.push(mbuf);
1296 }
1297
1298 status_t err = mSource->setBuffers(audio, mediaBufs);
1299 if (err != OK) {
1300 for (size_t i = 0; i < mediaBufs.size(); ++i) {
1301 mediaBufs[i]->release();
1302 }
1303 mediaBufs.clear();
1304 ALOGE("Secure source didn't support secure mediaBufs.");
1305 return err;
1306 }
1307 }
Andreas Huberf9334412010-12-15 15:17:42 -08001308 return OK;
1309}
1310
Chong Zhangced1c2f2014-08-08 15:22:35 -07001311void NuPlayer::updateVideoSize(
1312 const sp<AMessage> &inputFormat,
1313 const sp<AMessage> &outputFormat) {
1314 if (inputFormat == NULL) {
1315 ALOGW("Unknown video size, reporting 0x0!");
1316 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1317 return;
1318 }
1319
1320 int32_t displayWidth, displayHeight;
1321 int32_t cropLeft, cropTop, cropRight, cropBottom;
1322
1323 if (outputFormat != NULL) {
1324 int32_t width, height;
1325 CHECK(outputFormat->findInt32("width", &width));
1326 CHECK(outputFormat->findInt32("height", &height));
1327
1328 int32_t cropLeft, cropTop, cropRight, cropBottom;
1329 CHECK(outputFormat->findRect(
1330 "crop",
1331 &cropLeft, &cropTop, &cropRight, &cropBottom));
1332
1333 displayWidth = cropRight - cropLeft + 1;
1334 displayHeight = cropBottom - cropTop + 1;
1335
1336 ALOGV("Video output format changed to %d x %d "
1337 "(crop: %d x %d @ (%d, %d))",
1338 width, height,
1339 displayWidth,
1340 displayHeight,
1341 cropLeft, cropTop);
1342 } else {
1343 CHECK(inputFormat->findInt32("width", &displayWidth));
1344 CHECK(inputFormat->findInt32("height", &displayHeight));
1345
1346 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1347 }
1348
1349 // Take into account sample aspect ratio if necessary:
1350 int32_t sarWidth, sarHeight;
1351 if (inputFormat->findInt32("sar-width", &sarWidth)
1352 && inputFormat->findInt32("sar-height", &sarHeight)) {
1353 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1354
1355 displayWidth = (displayWidth * sarWidth) / sarHeight;
1356
1357 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1358 }
1359
1360 int32_t rotationDegrees;
1361 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1362 rotationDegrees = 0;
1363 }
1364
1365 if (rotationDegrees == 90 || rotationDegrees == 270) {
1366 int32_t tmp = displayWidth;
1367 displayWidth = displayHeight;
1368 displayHeight = tmp;
1369 }
1370
1371 notifyListener(
1372 MEDIA_SET_VIDEO_SIZE,
1373 displayWidth,
1374 displayHeight);
1375}
1376
Chong Zhangdcb89b32013-08-06 09:44:47 -07001377void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001378 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001379 return;
1380 }
1381
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001382 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001383
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001384 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001385 return;
1386 }
1387
Chong Zhangdcb89b32013-08-06 09:44:47 -07001388 driver->notifyListener(msg, ext1, ext2, in);
Andreas Huberf9334412010-12-15 15:17:42 -08001389}
1390
Chong Zhang7137ec72014-11-12 16:41:05 -08001391void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber14f76722013-01-15 09:04:18 -08001392 ALOGV("[%s] flushDecoder needShutdown=%d",
1393 audio ? "audio" : "video", needShutdown);
1394
Chong Zhang7137ec72014-11-12 16:41:05 -08001395 const sp<DecoderBase> &decoder = getDecoder(audio);
Lajos Molnar87603c02014-08-20 19:25:30 -07001396 if (decoder == NULL) {
Steve Blockdf64d152012-01-04 20:05:49 +00001397 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001398 audio ? "audio" : "video");
Lajos Molnar87603c02014-08-20 19:25:30 -07001399 return;
Andreas Huber6e3d3112011-11-28 12:36:11 -08001400 }
1401
Andreas Huber1aef2112011-01-04 14:01:29 -08001402 // Make sure we don't continue to scan sources until we finish flushing.
1403 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001404 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001405
Chong Zhang7137ec72014-11-12 16:41:05 -08001406 decoder->signalFlush();
Andreas Huber1aef2112011-01-04 14:01:29 -08001407
1408 FlushStatus newStatus =
1409 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1410
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001411 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
Andy Hung8d121d42014-10-03 09:53:53 -07001412 mFlushComplete[audio][true /* isDecoder */] = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001413 if (audio) {
Wei Jia53904f32014-07-29 10:22:53 -07001414 ALOGE_IF(mFlushingAudio != NONE,
1415 "audio flushDecoder() is called in state %d", mFlushingAudio);
Andreas Huber1aef2112011-01-04 14:01:29 -08001416 mFlushingAudio = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08001417 } else {
Wei Jia53904f32014-07-29 10:22:53 -07001418 ALOGE_IF(mFlushingVideo != NONE,
1419 "video flushDecoder() is called in state %d", mFlushingVideo);
Andreas Huber1aef2112011-01-04 14:01:29 -08001420 mFlushingVideo = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08001421 }
1422}
1423
Chong Zhangced1c2f2014-08-08 15:22:35 -07001424void NuPlayer::queueDecoderShutdown(
1425 bool audio, bool video, const sp<AMessage> &reply) {
1426 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Huber84066782011-08-16 09:34:26 -07001427
Chong Zhangced1c2f2014-08-08 15:22:35 -07001428 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001429 new FlushDecoderAction(
1430 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1431 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
Andreas Huber84066782011-08-16 09:34:26 -07001432
Chong Zhangced1c2f2014-08-08 15:22:35 -07001433 mDeferredActions.push_back(
1434 new SimpleAction(&NuPlayer::performScanSources));
Andreas Huber84066782011-08-16 09:34:26 -07001435
Chong Zhangced1c2f2014-08-08 15:22:35 -07001436 mDeferredActions.push_back(new PostMessageAction(reply));
1437
1438 processDeferredActions();
Andreas Huber84066782011-08-16 09:34:26 -07001439}
1440
James Dong0d268a32012-08-31 12:18:27 -07001441status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1442 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001443 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001444 status_t ret = native_window_set_scaling_mode(
1445 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1446 if (ret != OK) {
1447 ALOGE("Failed to set scaling mode (%d): %s",
1448 -ret, strerror(-ret));
1449 return ret;
1450 }
1451 }
1452 return OK;
1453}
1454
Chong Zhangdcb89b32013-08-06 09:44:47 -07001455status_t NuPlayer::getTrackInfo(Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001456 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07001457 msg->setPointer("reply", reply);
1458
1459 sp<AMessage> response;
1460 status_t err = msg->postAndAwaitResponse(&response);
1461 return err;
1462}
1463
Robert Shih7c4f0d72014-07-09 18:53:31 -07001464status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001465 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
Robert Shih7c4f0d72014-07-09 18:53:31 -07001466 msg->setPointer("reply", reply);
1467 msg->setInt32("type", type);
1468
1469 sp<AMessage> response;
1470 status_t err = msg->postAndAwaitResponse(&response);
1471 if (err == OK && response != NULL) {
1472 CHECK(response->findInt32("err", &err));
1473 }
1474 return err;
1475}
1476
Robert Shih6ffb1fd2014-10-29 16:24:32 -07001477status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001478 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07001479 msg->setSize("trackIndex", trackIndex);
1480 msg->setInt32("select", select);
Robert Shih6ffb1fd2014-10-29 16:24:32 -07001481 msg->setInt64("timeUs", timeUs);
Chong Zhangdcb89b32013-08-06 09:44:47 -07001482
1483 sp<AMessage> response;
1484 status_t err = msg->postAndAwaitResponse(&response);
1485
Chong Zhang404fced2014-06-11 14:45:31 -07001486 if (err != OK) {
1487 return err;
1488 }
1489
1490 if (!response->findInt32("err", &err)) {
1491 err = OK;
1492 }
1493
Chong Zhangdcb89b32013-08-06 09:44:47 -07001494 return err;
1495}
1496
Ronghua Wua73d9e02014-10-08 15:13:29 -07001497status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
1498 sp<Renderer> renderer = mRenderer;
1499 if (renderer == NULL) {
1500 return NO_INIT;
1501 }
1502
1503 return renderer->getCurrentPosition(mediaUs);
1504}
1505
1506void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) {
Chong Zhang7137ec72014-11-12 16:41:05 -08001507 sp<DecoderBase> decoder = getDecoder(false /* audio */);
1508 if (decoder != NULL) {
1509 decoder->getStats(numFramesTotal, numFramesDropped);
1510 } else {
1511 *numFramesTotal = 0;
1512 *numFramesDropped = 0;
1513 }
Ronghua Wua73d9e02014-10-08 15:13:29 -07001514}
1515
Marco Nelissenf0b72b52014-09-16 15:43:44 -07001516sp<MetaData> NuPlayer::getFileMeta() {
1517 return mSource->getFileFormatMeta();
1518}
1519
Andreas Huberb7c8e912012-11-27 15:02:53 -08001520void NuPlayer::schedulePollDuration() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001521 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
Andreas Huberb7c8e912012-11-27 15:02:53 -08001522 msg->setInt32("generation", mPollDurationGeneration);
1523 msg->post();
1524}
1525
1526void NuPlayer::cancelPollDuration() {
1527 ++mPollDurationGeneration;
1528}
1529
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001530void NuPlayer::processDeferredActions() {
1531 while (!mDeferredActions.empty()) {
1532 // We won't execute any deferred actions until we're no longer in
1533 // an intermediate state, i.e. one more more decoders are currently
1534 // flushing or shutting down.
1535
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001536 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1537 // We're currently flushing, postpone the reset until that's
1538 // completed.
1539
1540 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1541 mFlushingAudio, mFlushingVideo);
1542
1543 break;
1544 }
1545
1546 sp<Action> action = *mDeferredActions.begin();
1547 mDeferredActions.erase(mDeferredActions.begin());
1548
1549 action->execute(this);
1550 }
1551}
1552
Wei Jiae427abf2014-09-22 15:21:11 -07001553void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
1554 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)",
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001555 seekTimeUs,
Wei Jiae427abf2014-09-22 15:21:11 -07001556 seekTimeUs / 1E6,
1557 needNotify);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001558
Andy Hungadf34bf2014-09-03 18:22:22 -07001559 if (mSource == NULL) {
1560 // This happens when reset occurs right before the loop mode
1561 // asynchronously seeks to the start of the stream.
1562 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
1563 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
1564 mAudioDecoder.get(), mVideoDecoder.get());
1565 return;
1566 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001567 mSource->seekTo(seekTimeUs);
Robert Shihd3b0bbb2014-07-23 15:00:25 -07001568 ++mTimedTextGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001569
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001570 // everything's flushed, continue playback.
1571}
1572
Wei Jiafef808d2014-10-31 17:57:05 -07001573void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
1574 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001575
Wei Jiafef808d2014-10-31 17:57:05 -07001576 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
1577 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001578 return;
1579 }
1580
Wei Jiafef808d2014-10-31 17:57:05 -07001581 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
1582 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001583 }
1584
Wei Jiafef808d2014-10-31 17:57:05 -07001585 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
1586 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001587 }
1588}
1589
1590void NuPlayer::performReset() {
1591 ALOGV("performReset");
1592
1593 CHECK(mAudioDecoder == NULL);
1594 CHECK(mVideoDecoder == NULL);
1595
1596 cancelPollDuration();
1597
1598 ++mScanSourcesGeneration;
1599 mScanSourcesPending = false;
1600
Lajos Molnar09524832014-07-17 14:29:51 -07001601 if (mRendererLooper != NULL) {
1602 if (mRenderer != NULL) {
1603 mRendererLooper->unregisterHandler(mRenderer->id());
1604 }
1605 mRendererLooper->stop();
1606 mRendererLooper.clear();
1607 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001608 mRenderer.clear();
Wei Jia57568df2014-09-22 10:16:29 -07001609 ++mRendererGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001610
1611 if (mSource != NULL) {
1612 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001613
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001614 mSource.clear();
1615 }
1616
1617 if (mDriver != NULL) {
1618 sp<NuPlayerDriver> driver = mDriver.promote();
1619 if (driver != NULL) {
1620 driver->notifyResetComplete();
1621 }
1622 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001623
1624 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001625}
1626
1627void NuPlayer::performScanSources() {
1628 ALOGV("performScanSources");
1629
Andreas Huber57a339c2012-12-03 11:18:00 -08001630 if (!mStarted) {
1631 return;
1632 }
1633
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001634 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1635 postScanSources();
1636 }
1637}
1638
Andreas Huber57a339c2012-12-03 11:18:00 -08001639void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1640 ALOGV("performSetSurface");
1641
1642 mNativeWindow = wrapper;
1643
1644 // XXX - ignore error from setVideoScalingMode for now
1645 setVideoScalingMode(mVideoScalingMode);
Chong Zhang13d6faa2014-08-22 15:35:28 -07001646
1647 if (mDriver != NULL) {
1648 sp<NuPlayerDriver> driver = mDriver.promote();
1649 if (driver != NULL) {
1650 driver->notifySetSurfaceComplete();
1651 }
1652 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001653}
1654
Chong Zhangf8d71772014-11-26 15:08:34 -08001655void NuPlayer::performResumeDecoders(bool needNotify) {
1656 if (needNotify) {
1657 mResumePending = true;
1658 if (mVideoDecoder == NULL) {
1659 // if audio-only, we can notify seek complete now,
1660 // as the resume operation will be relatively fast.
1661 finishResume();
1662 }
1663 }
1664
Chong Zhang7137ec72014-11-12 16:41:05 -08001665 if (mVideoDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08001666 // When there is continuous seek, MediaPlayer will cache the seek
1667 // position, and send down new seek request when previous seek is
1668 // complete. Let's wait for at least one video output frame before
1669 // notifying seek complete, so that the video thumbnail gets updated
1670 // when seekbar is dragged.
1671 mVideoDecoder->signalResume(needNotify);
Chong Zhang7137ec72014-11-12 16:41:05 -08001672 }
1673
1674 if (mAudioDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08001675 mAudioDecoder->signalResume(false /* needNotify */);
1676 }
1677}
1678
1679void NuPlayer::finishResume() {
1680 if (mResumePending) {
1681 mResumePending = false;
1682 if (mDriver != NULL) {
1683 sp<NuPlayerDriver> driver = mDriver.promote();
1684 if (driver != NULL) {
1685 driver->notifySeekComplete();
1686 }
1687 }
Chong Zhang7137ec72014-11-12 16:41:05 -08001688 }
1689}
1690
Andreas Huber9575c962013-02-05 13:59:56 -08001691void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1692 int32_t what;
1693 CHECK(msg->findInt32("what", &what));
1694
1695 switch (what) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001696 case Source::kWhatInstantiateSecureDecoders:
1697 {
1698 if (mSource == NULL) {
1699 // This is a stale notification from a source that was
1700 // asynchronously preparing when the client called reset().
1701 // We handled the reset, the source is gone.
1702 break;
1703 }
1704
1705 sp<AMessage> reply;
1706 CHECK(msg->findMessage("reply", &reply));
1707 status_t err = onInstantiateSecureDecoders();
1708 reply->setInt32("err", err);
1709 reply->post();
1710 break;
1711 }
1712
Andreas Huber9575c962013-02-05 13:59:56 -08001713 case Source::kWhatPrepared:
1714 {
Andreas Huberb5f28d42013-04-25 15:11:19 -07001715 if (mSource == NULL) {
1716 // This is a stale notification from a source that was
1717 // asynchronously preparing when the client called reset().
1718 // We handled the reset, the source is gone.
1719 break;
1720 }
1721
Andreas Huberec0c5972013-02-05 14:47:13 -08001722 int32_t err;
1723 CHECK(msg->findInt32("err", &err));
1724
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001725 if (err != OK) {
1726 // shut down potential secure codecs in case client never calls reset
1727 mDeferredActions.push_back(
1728 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
1729 FLUSH_CMD_SHUTDOWN /* video */));
1730 processDeferredActions();
1731 }
1732
Andreas Huber9575c962013-02-05 13:59:56 -08001733 sp<NuPlayerDriver> driver = mDriver.promote();
1734 if (driver != NULL) {
Marco Nelissendd114d12014-05-28 15:23:14 -07001735 // notify duration first, so that it's definitely set when
1736 // the app received the "prepare complete" callback.
1737 int64_t durationUs;
1738 if (mSource->getDuration(&durationUs) == OK) {
1739 driver->notifyDuration(durationUs);
1740 }
Andreas Huberec0c5972013-02-05 14:47:13 -08001741 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08001742 }
Andreas Huber99759402013-04-01 14:28:31 -07001743
Andreas Huber9575c962013-02-05 13:59:56 -08001744 break;
1745 }
1746
1747 case Source::kWhatFlagsChanged:
1748 {
1749 uint32_t flags;
1750 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1751
Chong Zhang4b7069d2013-09-11 12:52:43 -07001752 sp<NuPlayerDriver> driver = mDriver.promote();
1753 if (driver != NULL) {
Wei Jia895651b2014-12-10 17:31:52 -08001754 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
1755 driver->notifyListener(
1756 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
1757 }
Chong Zhang4b7069d2013-09-11 12:52:43 -07001758 driver->notifyFlagsChanged(flags);
1759 }
1760
Andreas Huber9575c962013-02-05 13:59:56 -08001761 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1762 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1763 cancelPollDuration();
1764 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1765 && (flags & Source::FLAG_DYNAMIC_DURATION)
1766 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1767 schedulePollDuration();
1768 }
1769
1770 mSourceFlags = flags;
1771 break;
1772 }
1773
1774 case Source::kWhatVideoSizeChanged:
1775 {
Chong Zhangced1c2f2014-08-08 15:22:35 -07001776 sp<AMessage> format;
1777 CHECK(msg->findMessage("format", &format));
Andreas Huber9575c962013-02-05 13:59:56 -08001778
Chong Zhangced1c2f2014-08-08 15:22:35 -07001779 updateVideoSize(format);
Andreas Huber9575c962013-02-05 13:59:56 -08001780 break;
1781 }
1782
Chong Zhang2a3cc9a2014-08-21 17:48:26 -07001783 case Source::kWhatBufferingUpdate:
1784 {
1785 int32_t percentage;
1786 CHECK(msg->findInt32("percentage", &percentage));
1787
1788 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
1789 break;
1790 }
1791
Chong Zhangefbb6192015-01-30 17:13:27 -08001792 case Source::kWhatPauseOnBufferingStart:
1793 {
1794 // ignore if not playing
1795 if (mStarted && !mPausedByClient) {
1796 ALOGI("buffer low, pausing...");
1797
1798 onPause();
1799 }
1800 // fall-thru
1801 }
1802
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001803 case Source::kWhatBufferingStart:
1804 {
1805 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1806 break;
1807 }
1808
Chong Zhangefbb6192015-01-30 17:13:27 -08001809 case Source::kWhatResumeOnBufferingEnd:
1810 {
1811 // ignore if not playing
1812 if (mStarted && !mPausedByClient) {
1813 ALOGI("buffer ready, resuming...");
1814
1815 onResume();
1816 }
1817 // fall-thru
1818 }
1819
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001820 case Source::kWhatBufferingEnd:
1821 {
1822 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1823 break;
1824 }
1825
Chong Zhangefbb6192015-01-30 17:13:27 -08001826 case Source::kWhatCacheStats:
1827 {
1828 int32_t kbps;
1829 CHECK(msg->findInt32("bandwidth", &kbps));
1830
1831 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
1832 break;
1833 }
1834
Chong Zhangdcb89b32013-08-06 09:44:47 -07001835 case Source::kWhatSubtitleData:
1836 {
1837 sp<ABuffer> buffer;
1838 CHECK(msg->findBuffer("buffer", &buffer));
1839
Chong Zhang404fced2014-06-11 14:45:31 -07001840 sendSubtitleData(buffer, 0 /* baseIndex */);
Chong Zhangdcb89b32013-08-06 09:44:47 -07001841 break;
1842 }
1843
Robert Shihd3b0bbb2014-07-23 15:00:25 -07001844 case Source::kWhatTimedTextData:
1845 {
1846 int32_t generation;
1847 if (msg->findInt32("generation", &generation)
1848 && generation != mTimedTextGeneration) {
1849 break;
1850 }
1851
1852 sp<ABuffer> buffer;
1853 CHECK(msg->findBuffer("buffer", &buffer));
1854
1855 sp<NuPlayerDriver> driver = mDriver.promote();
1856 if (driver == NULL) {
1857 break;
1858 }
1859
1860 int posMs;
1861 int64_t timeUs, posUs;
1862 driver->getCurrentPosition(&posMs);
1863 posUs = posMs * 1000;
1864 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1865
1866 if (posUs < timeUs) {
1867 if (!msg->findInt32("generation", &generation)) {
1868 msg->setInt32("generation", mTimedTextGeneration);
1869 }
1870 msg->post(timeUs - posUs);
1871 } else {
1872 sendTimedTextData(buffer);
1873 }
1874 break;
1875 }
1876
Andreas Huber14f76722013-01-15 09:04:18 -08001877 case Source::kWhatQueueDecoderShutdown:
1878 {
1879 int32_t audio, video;
1880 CHECK(msg->findInt32("audio", &audio));
1881 CHECK(msg->findInt32("video", &video));
1882
1883 sp<AMessage> reply;
1884 CHECK(msg->findMessage("reply", &reply));
1885
1886 queueDecoderShutdown(audio, video, reply);
1887 break;
1888 }
1889
Ronghua Wu80276872014-08-28 15:50:29 -07001890 case Source::kWhatDrmNoLicense:
1891 {
1892 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
1893 break;
1894 }
1895
Andreas Huber9575c962013-02-05 13:59:56 -08001896 default:
1897 TRESPASS();
1898 }
1899}
1900
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001901void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
1902 int32_t what;
1903 CHECK(msg->findInt32("what", &what));
1904
1905 switch (what) {
1906 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
1907 {
1908 sp<ABuffer> buffer;
1909 CHECK(msg->findBuffer("buffer", &buffer));
1910
1911 size_t inbandTracks = 0;
1912 if (mSource != NULL) {
1913 inbandTracks = mSource->getTrackCount();
1914 }
1915
1916 sendSubtitleData(buffer, inbandTracks);
1917 break;
1918 }
1919
1920 case NuPlayer::CCDecoder::kWhatTrackAdded:
1921 {
1922 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
1923
1924 break;
1925 }
1926
1927 default:
1928 TRESPASS();
1929 }
1930
1931
1932}
1933
Chong Zhang404fced2014-06-11 14:45:31 -07001934void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
1935 int32_t trackIndex;
1936 int64_t timeUs, durationUs;
1937 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
1938 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1939 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
1940
1941 Parcel in;
1942 in.writeInt32(trackIndex + baseIndex);
1943 in.writeInt64(timeUs);
1944 in.writeInt64(durationUs);
1945 in.writeInt32(buffer->size());
1946 in.writeInt32(buffer->size());
1947 in.write(buffer->data(), buffer->size());
1948
1949 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
1950}
Robert Shihd3b0bbb2014-07-23 15:00:25 -07001951
1952void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
1953 const void *data;
1954 size_t size = 0;
1955 int64_t timeUs;
1956 int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
1957
1958 AString mime;
1959 CHECK(buffer->meta()->findString("mime", &mime));
1960 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
1961
1962 data = buffer->data();
1963 size = buffer->size();
1964
1965 Parcel parcel;
1966 if (size > 0) {
1967 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1968 flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
1969 TextDescriptions::getParcelOfDescriptions(
1970 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
1971 }
1972
1973 if ((parcel.dataSize() > 0)) {
1974 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
1975 } else { // send an empty timed text
1976 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
1977 }
1978}
Andreas Huberb5f25f02013-02-05 10:14:26 -08001979////////////////////////////////////////////////////////////////////////////////
1980
Chong Zhangced1c2f2014-08-08 15:22:35 -07001981sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1982 sp<MetaData> meta = getFormatMeta(audio);
1983
1984 if (meta == NULL) {
1985 return NULL;
1986 }
1987
1988 sp<AMessage> msg = new AMessage;
1989
1990 if(convertMetaDataToMessage(meta, &msg) == OK) {
1991 return msg;
1992 }
1993 return NULL;
1994}
1995
Andreas Huber9575c962013-02-05 13:59:56 -08001996void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1997 sp<AMessage> notify = dupNotify();
1998 notify->setInt32("what", kWhatFlagsChanged);
1999 notify->setInt32("flags", flags);
2000 notify->post();
2001}
2002
Chong Zhangced1c2f2014-08-08 15:22:35 -07002003void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
Andreas Huber9575c962013-02-05 13:59:56 -08002004 sp<AMessage> notify = dupNotify();
2005 notify->setInt32("what", kWhatVideoSizeChanged);
Chong Zhangced1c2f2014-08-08 15:22:35 -07002006 notify->setMessage("format", format);
Andreas Huber9575c962013-02-05 13:59:56 -08002007 notify->post();
2008}
2009
Andreas Huberec0c5972013-02-05 14:47:13 -08002010void NuPlayer::Source::notifyPrepared(status_t err) {
Andreas Huber9575c962013-02-05 13:59:56 -08002011 sp<AMessage> notify = dupNotify();
2012 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08002013 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08002014 notify->post();
2015}
2016
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002017void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
2018 sp<AMessage> notify = dupNotify();
2019 notify->setInt32("what", kWhatInstantiateSecureDecoders);
2020 notify->setMessage("reply", reply);
2021 notify->post();
2022}
2023
Andreas Huber84333e02014-02-07 15:36:10 -08002024void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
Andreas Huberb5f25f02013-02-05 10:14:26 -08002025 TRESPASS();
2026}
2027
Andreas Huberf9334412010-12-15 15:17:42 -08002028} // namespace android