blob: 0d4c7304abab062e036ad3dd047e3dc39019244e [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"
Ray Essickd4d00612017-01-03 09:36:27 -080019
20#include <inttypes.h>
21
Andreas Huberf9334412010-12-15 15:17:42 -080022#include <utils/Log.h>
23
24#include "NuPlayer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080025
26#include "HTTPLiveSource.h"
Chong Zhang7137ec72014-11-12 16:41:05 -080027#include "NuPlayerCCDecoder.h"
Andreas Huberf9334412010-12-15 15:17:42 -080028#include "NuPlayerDecoder.h"
Chong Zhang7137ec72014-11-12 16:41:05 -080029#include "NuPlayerDecoderBase.h"
Wei Jiabc2fb722014-07-08 16:37:57 -070030#include "NuPlayerDecoderPassThrough.h"
Andreas Huber43c3e6c2011-01-05 12:17:08 -080031#include "NuPlayerDriver.h"
Andreas Huberf9334412010-12-15 15:17:42 -080032#include "NuPlayerRenderer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080033#include "NuPlayerSource.h"
Andreas Huber2bfdd422011-10-11 15:24:07 -070034#include "RTSPSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080035#include "StreamingSource.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070036#include "GenericSource.h"
Robert Shihd3b0bbb2014-07-23 15:00:25 -070037#include "TextDescriptions.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080038
39#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080040
Lajos Molnard9fd6312014-11-06 11:00:00 -080041#include <cutils/properties.h>
42
Lajos Molnar3a474aa2015-04-24 17:10:07 -070043#include <media/AudioResamplerPublic.h>
44#include <media/AVSyncSettings.h>
Wonsik Kim7e34bf52016-08-23 00:09:18 +090045#include <media/MediaCodecBuffer.h>
Lajos Molnar3a474aa2015-04-24 17:10:07 -070046
Andreas Huber3831a062010-12-21 10:22:33 -080047#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080048#include <media/stagefright/foundation/ABuffer.h>
49#include <media/stagefright/foundation/ADebug.h>
50#include <media/stagefright/foundation/AMessage.h>
Lajos Molnar09524832014-07-17 14:29:51 -070051#include <media/stagefright/MediaBuffer.h>
Andreas Huber3fe62152011-09-16 15:09:22 -070052#include <media/stagefright/MediaDefs.h>
Andreas Huberf9334412010-12-15 15:17:42 -080053#include <media/stagefright/MediaErrors.h>
54#include <media/stagefright/MetaData.h>
Lajos Molnar1de1e252015-04-30 18:18:34 -070055
Andy McFadden8ba01022012-12-18 09:46:54 -080056#include <gui/IGraphicBufferProducer.h>
Lajos Molnar1de1e252015-04-30 18:18:34 -070057#include <gui/Surface.h>
Andreas Huberf9334412010-12-15 15:17:42 -080058
Andreas Huber3fe62152011-09-16 15:09:22 -070059#include "avc_utils.h"
60
Andreas Huber84066782011-08-16 09:34:26 -070061#include "ESDS.h"
62#include <media/stagefright/Utils.h>
63
Andreas Huberf9334412010-12-15 15:17:42 -080064namespace android {
65
Andreas Hubera1f8ab02012-11-30 10:53:22 -080066struct NuPlayer::Action : public RefBase {
67 Action() {}
68
69 virtual void execute(NuPlayer *player) = 0;
70
71private:
72 DISALLOW_EVIL_CONSTRUCTORS(Action);
73};
74
75struct NuPlayer::SeekAction : public Action {
Wei Jiac5de0912016-11-18 10:22:14 -080076 explicit SeekAction(int64_t seekTimeUs, MediaPlayerSeekMode mode)
Wei Jia14486822016-11-02 17:51:30 -070077 : mSeekTimeUs(seekTimeUs),
Wei Jiac5de0912016-11-18 10:22:14 -080078 mMode(mode) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -080079 }
80
81 virtual void execute(NuPlayer *player) {
Wei Jiac5de0912016-11-18 10:22:14 -080082 player->performSeek(mSeekTimeUs, mMode);
Andreas Hubera1f8ab02012-11-30 10:53:22 -080083 }
84
85private:
86 int64_t mSeekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -080087 MediaPlayerSeekMode mMode;
Andreas Hubera1f8ab02012-11-30 10:53:22 -080088
89 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
90};
91
Chong Zhangf8d71772014-11-26 15:08:34 -080092struct NuPlayer::ResumeDecoderAction : public Action {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070093 explicit ResumeDecoderAction(bool needNotify)
Chong Zhangf8d71772014-11-26 15:08:34 -080094 : mNeedNotify(needNotify) {
95 }
96
97 virtual void execute(NuPlayer *player) {
98 player->performResumeDecoders(mNeedNotify);
99 }
100
101private:
102 bool mNeedNotify;
103
104 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
105};
106
Andreas Huber57a339c2012-12-03 11:18:00 -0800107struct NuPlayer::SetSurfaceAction : public Action {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700108 explicit SetSurfaceAction(const sp<Surface> &surface)
Lajos Molnar1de1e252015-04-30 18:18:34 -0700109 : mSurface(surface) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800110 }
111
112 virtual void execute(NuPlayer *player) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700113 player->performSetSurface(mSurface);
Andreas Huber57a339c2012-12-03 11:18:00 -0800114 }
115
116private:
Lajos Molnar1de1e252015-04-30 18:18:34 -0700117 sp<Surface> mSurface;
Andreas Huber57a339c2012-12-03 11:18:00 -0800118
119 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
120};
121
Wei Jiafef808d2014-10-31 17:57:05 -0700122struct NuPlayer::FlushDecoderAction : public Action {
123 FlushDecoderAction(FlushCommand audio, FlushCommand video)
Andreas Huber14f76722013-01-15 09:04:18 -0800124 : mAudio(audio),
125 mVideo(video) {
126 }
127
128 virtual void execute(NuPlayer *player) {
Wei Jiafef808d2014-10-31 17:57:05 -0700129 player->performDecoderFlush(mAudio, mVideo);
Andreas Huber14f76722013-01-15 09:04:18 -0800130 }
131
132private:
Wei Jiafef808d2014-10-31 17:57:05 -0700133 FlushCommand mAudio;
134 FlushCommand mVideo;
Andreas Huber14f76722013-01-15 09:04:18 -0800135
Wei Jiafef808d2014-10-31 17:57:05 -0700136 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
Andreas Huber14f76722013-01-15 09:04:18 -0800137};
138
139struct NuPlayer::PostMessageAction : public Action {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700140 explicit PostMessageAction(const sp<AMessage> &msg)
Andreas Huber14f76722013-01-15 09:04:18 -0800141 : mMessage(msg) {
142 }
143
144 virtual void execute(NuPlayer *) {
145 mMessage->post();
146 }
147
148private:
149 sp<AMessage> mMessage;
150
151 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
152};
153
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800154// Use this if there's no state necessary to save in order to execute
155// the action.
156struct NuPlayer::SimpleAction : public Action {
157 typedef void (NuPlayer::*ActionFunc)();
158
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700159 explicit SimpleAction(ActionFunc func)
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800160 : mFunc(func) {
161 }
162
163 virtual void execute(NuPlayer *player) {
164 (player->*mFunc)();
165 }
166
167private:
168 ActionFunc mFunc;
169
170 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
171};
172
Andreas Huberf9334412010-12-15 15:17:42 -0800173////////////////////////////////////////////////////////////////////////////////
174
Ronghua Wu68845c12015-07-21 09:50:48 -0700175NuPlayer::NuPlayer(pid_t pid)
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700176 : mUIDValid(false),
Ronghua Wu68845c12015-07-21 09:50:48 -0700177 mPID(pid),
Andreas Huber9575c962013-02-05 13:59:56 -0800178 mSourceFlags(0),
Wei Jiabc2fb722014-07-08 16:37:57 -0700179 mOffloadAudio(false),
Wei Jia88703c32014-08-06 11:24:07 -0700180 mAudioDecoderGeneration(0),
181 mVideoDecoderGeneration(0),
Wei Jia57568df2014-09-22 10:16:29 -0700182 mRendererGeneration(0),
Robert Shih1a5c8592015-08-04 18:07:44 -0700183 mPreviousSeekTimeUs(0),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700184 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800185 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800186 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800187 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800188 mPollDurationGeneration(0),
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700189 mTimedTextGeneration(0),
Andreas Huberf9334412010-12-15 15:17:42 -0800190 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800191 mFlushingVideo(NONE),
Chong Zhangf8d71772014-11-26 15:08:34 -0800192 mResumePending(false),
Andreas Huber57a339c2012-12-03 11:18:00 -0800193 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700194 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
195 mVideoFpsHint(-1.f),
Chong Zhangefbb6192015-01-30 17:13:27 -0800196 mStarted(false),
Wei Jia8a092d32016-06-03 14:57:24 -0700197 mPrepared(false),
Ronghua Wu64c2d172015-10-07 16:52:19 -0700198 mResetting(false),
Robert Shih0c61a0d2015-07-06 15:09:10 -0700199 mSourceStarted(false),
Wei Jia686e8e52017-04-03 14:08:01 -0700200 mAudioDecoderError(false),
201 mVideoDecoderError(false),
Chong Zhangefbb6192015-01-30 17:13:27 -0800202 mPaused(false),
Wei Jia71c75e02016-02-04 09:40:47 -0800203 mPausedByClient(true),
Hassan Shojania50b20c92017-02-16 18:28:58 -0800204 mPausedForBuffering(false),
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700205 mIsDrmProtected(false),
206 mDataSourceType(DATA_SOURCE_TYPE_NONE) {
Andy Hung8d121d42014-10-03 09:53:53 -0700207 clearFlushComplete();
Andreas Huberf9334412010-12-15 15:17:42 -0800208}
209
210NuPlayer::~NuPlayer() {
211}
212
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700213void NuPlayer::setUID(uid_t uid) {
214 mUIDValid = true;
215 mUID = uid;
216}
217
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800218void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
219 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800220}
221
Andreas Huber9575c962013-02-05 13:59:56 -0800222void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800223 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Andreas Huberf9334412010-12-15 15:17:42 -0800224
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800225 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800226
Andreas Huber240abcc2014-02-13 13:32:37 -0800227 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber5bc087c2010-12-23 10:27:40 -0800228 msg->post();
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700229 mDataSourceType = DATA_SOURCE_TYPE_STREAM;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800230}
Andreas Huberf9334412010-12-15 15:17:42 -0800231
Andreas Huberafed0e12011-09-20 15:39:58 -0700232static bool IsHTTPLiveURL(const char *url) {
233 if (!strncasecmp("http://", url, 7)
Andreas Huber99759402013-04-01 14:28:31 -0700234 || !strncasecmp("https://", url, 8)
235 || !strncasecmp("file://", url, 7)) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700236 size_t len = strlen(url);
237 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
238 return true;
239 }
240
241 if (strstr(url,"m3u8")) {
242 return true;
243 }
244 }
245
246 return false;
247}
248
Andreas Huber9575c962013-02-05 13:59:56 -0800249void NuPlayer::setDataSourceAsync(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800250 const sp<IMediaHTTPService> &httpService,
251 const char *url,
252 const KeyedVector<String8, String8> *headers) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700253
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800254 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100255 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800256
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800257 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800258
Andreas Huberafed0e12011-09-20 15:39:58 -0700259 sp<Source> source;
260 if (IsHTTPLiveURL(url)) {
Andreas Huber81e68442014-02-05 11:52:33 -0800261 source = new HTTPLiveSource(notify, httpService, url, headers);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800262 ALOGV("setDataSourceAsync HTTPLiveSource %s", url);
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700263 mDataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Andreas Huberafed0e12011-09-20 15:39:58 -0700264 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800265 source = new RTSPSource(
266 notify, httpService, url, headers, mUIDValid, mUID);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800267 ALOGV("setDataSourceAsync RTSPSource %s", url);
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700268 mDataSourceType = DATA_SOURCE_TYPE_RTSP;
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100269 } else if ((!strncasecmp(url, "http://", 7)
270 || !strncasecmp(url, "https://", 8))
271 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
272 || strstr(url, ".sdp?"))) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800273 source = new RTSPSource(
274 notify, httpService, url, headers, mUIDValid, mUID, true);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800275 ALOGV("setDataSourceAsync RTSPSource http/https/.sdp %s", url);
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700276 mDataSourceType = DATA_SOURCE_TYPE_RTSP;
Andreas Huber2bfdd422011-10-11 15:24:07 -0700277 } else {
Hassan Shojaniacefac142017-02-06 21:02:02 -0800278 ALOGV("setDataSourceAsync GenericSource %s", url);
279
Chong Zhang3de157d2014-08-05 20:54:44 -0700280 sp<GenericSource> genericSource =
281 new GenericSource(notify, mUIDValid, mUID);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700282
Chong Zhanga19f33e2014-08-07 15:35:07 -0700283 status_t err = genericSource->setDataSource(httpService, url, headers);
Chong Zhang3de157d2014-08-05 20:54:44 -0700284
285 if (err == OK) {
286 source = genericSource;
287 } else {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700288 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700289 }
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700290
291 // regardless of success/failure
292 mDataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Chong Zhang3de157d2014-08-05 20:54:44 -0700293 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700294 msg->setObject("source", source);
295 msg->post();
296}
297
Andreas Huber9575c962013-02-05 13:59:56 -0800298void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800299 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Andreas Huberafed0e12011-09-20 15:39:58 -0700300
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800301 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800302
Chong Zhang3de157d2014-08-05 20:54:44 -0700303 sp<GenericSource> source =
304 new GenericSource(notify, mUIDValid, mUID);
305
Hassan Shojaniacefac142017-02-06 21:02:02 -0800306 ALOGV("setDataSourceAsync fd %d/%lld/%lld source: %p",
307 fd, (long long)offset, (long long)length, source.get());
308
Chong Zhanga19f33e2014-08-07 15:35:07 -0700309 status_t err = source->setDataSource(fd, offset, length);
Chong Zhang3de157d2014-08-05 20:54:44 -0700310
311 if (err != OK) {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700312 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700313 source = NULL;
314 }
315
Andreas Huberafed0e12011-09-20 15:39:58 -0700316 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800317 msg->post();
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700318 mDataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Andreas Huberf9334412010-12-15 15:17:42 -0800319}
320
Chris Watkins99f31602015-03-20 13:06:33 -0700321void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) {
322 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
323 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
324
325 sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID);
326 status_t err = source->setDataSource(dataSource);
327
328 if (err != OK) {
329 ALOGE("Failed to set data source!");
330 source = NULL;
331 }
332
333 msg->setObject("source", source);
334 msg->post();
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700335 mDataSourceType = DATA_SOURCE_TYPE_MEDIA;
Chris Watkins99f31602015-03-20 13:06:33 -0700336}
337
Wei Jia48fa06d2016-12-20 15:30:49 -0800338status_t NuPlayer::getDefaultBufferingSettings(
339 BufferingSettings *buffering /* nonnull */) {
340 sp<AMessage> msg = new AMessage(kWhatGetDefaultBufferingSettings, this);
341 sp<AMessage> response;
342 status_t err = msg->postAndAwaitResponse(&response);
343 if (err == OK && response != NULL) {
344 CHECK(response->findInt32("err", &err));
345 if (err == OK) {
346 readFromAMessage(response, buffering);
347 }
348 }
349 return err;
350}
351
352status_t NuPlayer::setBufferingSettings(const BufferingSettings& buffering) {
353 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
354 writeToAMessage(msg, buffering);
355 sp<AMessage> response;
356 status_t err = msg->postAndAwaitResponse(&response);
357 if (err == OK && response != NULL) {
358 CHECK(response->findInt32("err", &err));
359 }
360 return err;
361}
362
Andreas Huber9575c962013-02-05 13:59:56 -0800363void NuPlayer::prepareAsync() {
Hassan Shojaniacefac142017-02-06 21:02:02 -0800364 ALOGV("prepareAsync");
365
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800366 (new AMessage(kWhatPrepare, this))->post();
Andreas Huber9575c962013-02-05 13:59:56 -0800367}
368
Andreas Huber57a339c2012-12-03 11:18:00 -0800369void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800370 const sp<IGraphicBufferProducer> &bufferProducer) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700371 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
Andreas Huber57a339c2012-12-03 11:18:00 -0800372
Andy McFadden8ba01022012-12-18 09:46:54 -0800373 if (bufferProducer == NULL) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700374 msg->setObject("surface", NULL);
Andreas Huber57a339c2012-12-03 11:18:00 -0800375 } else {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700376 msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */));
Andreas Huber57a339c2012-12-03 11:18:00 -0800377 }
378
Andreas Huberf9334412010-12-15 15:17:42 -0800379 msg->post();
380}
381
382void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800383 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
Andreas Huberf9334412010-12-15 15:17:42 -0800384 msg->setObject("sink", sink);
385 msg->post();
386}
387
388void NuPlayer::start() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800389 (new AMessage(kWhatStart, this))->post();
Andreas Huberf9334412010-12-15 15:17:42 -0800390}
391
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700392status_t NuPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) {
393 // do some cursory validation of the settings here. audio modes are
394 // only validated when set on the audiosink.
395 if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
396 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
397 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
398 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
399 return BAD_VALUE;
400 }
401 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
402 writeToAMessage(msg, rate);
403 sp<AMessage> response;
404 status_t err = msg->postAndAwaitResponse(&response);
405 if (err == OK && response != NULL) {
406 CHECK(response->findInt32("err", &err));
407 }
408 return err;
409}
410
411status_t NuPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
412 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
413 sp<AMessage> response;
414 status_t err = msg->postAndAwaitResponse(&response);
415 if (err == OK && response != NULL) {
416 CHECK(response->findInt32("err", &err));
417 if (err == OK) {
418 readFromAMessage(response, rate);
419 }
420 }
421 return err;
422}
423
424status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
425 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
426 writeToAMessage(msg, sync, videoFpsHint);
427 sp<AMessage> response;
428 status_t err = msg->postAndAwaitResponse(&response);
429 if (err == OK && response != NULL) {
430 CHECK(response->findInt32("err", &err));
431 }
432 return err;
433}
434
435status_t NuPlayer::getSyncSettings(
436 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
437 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
438 sp<AMessage> response;
439 status_t err = msg->postAndAwaitResponse(&response);
440 if (err == OK && response != NULL) {
441 CHECK(response->findInt32("err", &err));
442 if (err == OK) {
443 readFromAMessage(response, sync, videoFps);
444 }
445 }
446 return err;
Wei Jia98160162015-02-04 17:01:11 -0800447}
448
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800449void NuPlayer::pause() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800450 (new AMessage(kWhatPause, this))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800451}
452
Andreas Huber1aef2112011-01-04 14:01:29 -0800453void NuPlayer::resetAsync() {
Wei Jiac45a4b22016-04-15 15:30:23 -0700454 sp<Source> source;
455 {
456 Mutex::Autolock autoLock(mSourceLock);
457 source = mSource;
458 }
459
460 if (source != NULL) {
Chong Zhang48296b72014-09-14 14:28:45 -0700461 // During a reset, the data source might be unresponsive already, we need to
462 // disconnect explicitly so that reads exit promptly.
463 // We can't queue the disconnect request to the looper, as it might be
464 // queued behind a stuck read and never gets processed.
465 // Doing a disconnect outside the looper to allows the pending reads to exit
466 // (either successfully or with error).
Wei Jiac45a4b22016-04-15 15:30:23 -0700467 source->disconnect();
Chong Zhang48296b72014-09-14 14:28:45 -0700468 }
469
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800470 (new AMessage(kWhatReset, this))->post();
Andreas Huber1aef2112011-01-04 14:01:29 -0800471}
472
Wei Jiac5de0912016-11-18 10:22:14 -0800473void NuPlayer::seekToAsync(int64_t seekTimeUs, MediaPlayerSeekMode mode, bool needNotify) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800474 sp<AMessage> msg = new AMessage(kWhatSeek, this);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800475 msg->setInt64("seekTimeUs", seekTimeUs);
Wei Jiac5de0912016-11-18 10:22:14 -0800476 msg->setInt32("mode", mode);
Wei Jiae427abf2014-09-22 15:21:11 -0700477 msg->setInt32("needNotify", needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800478 msg->post();
479}
480
Andreas Huber53df1a42010-12-22 10:03:04 -0800481
Chong Zhang404fced2014-06-11 14:45:31 -0700482void NuPlayer::writeTrackInfo(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700483 Parcel* reply, const sp<AMessage>& format) const {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700484 if (format == NULL) {
485 ALOGE("NULL format");
486 return;
487 }
Chong Zhang404fced2014-06-11 14:45:31 -0700488 int32_t trackType;
Marco Nelissen9436e482015-09-15 10:21:53 -0700489 if (!format->findInt32("type", &trackType)) {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700490 ALOGE("no track type");
491 return;
492 }
Chong Zhang404fced2014-06-11 14:45:31 -0700493
Robert Shih755106e2015-04-30 14:36:45 -0700494 AString mime;
Robert Shih2e3a4252015-05-06 10:21:15 -0700495 if (!format->findString("mime", &mime)) {
496 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
497 // If we can't find the mimetype here it means that we wouldn't be needing
498 // the mimetype on the Java end. We still write a placeholder mime to keep the
499 // (de)serialization logic simple.
500 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
501 mime = "audio/";
502 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
503 mime = "video/";
504 } else {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700505 ALOGE("unknown track type: %d", trackType);
506 return;
Robert Shih2e3a4252015-05-06 10:21:15 -0700507 }
508 }
Robert Shih755106e2015-04-30 14:36:45 -0700509
Chong Zhang404fced2014-06-11 14:45:31 -0700510 AString lang;
Marco Nelissen9436e482015-09-15 10:21:53 -0700511 if (!format->findString("language", &lang)) {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700512 ALOGE("no language");
513 return;
514 }
Chong Zhang404fced2014-06-11 14:45:31 -0700515
516 reply->writeInt32(2); // write something non-zero
517 reply->writeInt32(trackType);
Robert Shih755106e2015-04-30 14:36:45 -0700518 reply->writeString16(String16(mime.c_str()));
Chong Zhang404fced2014-06-11 14:45:31 -0700519 reply->writeString16(String16(lang.c_str()));
520
521 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
Chong Zhang404fced2014-06-11 14:45:31 -0700522 int32_t isAuto, isDefault, isForced;
523 CHECK(format->findInt32("auto", &isAuto));
524 CHECK(format->findInt32("default", &isDefault));
525 CHECK(format->findInt32("forced", &isForced));
526
Chong Zhang404fced2014-06-11 14:45:31 -0700527 reply->writeInt32(isAuto);
528 reply->writeInt32(isDefault);
529 reply->writeInt32(isForced);
530 }
531}
532
Andreas Huberf9334412010-12-15 15:17:42 -0800533void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
534 switch (msg->what()) {
535 case kWhatSetDataSource:
536 {
Steve Block3856b092011-10-20 11:56:00 +0100537 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800538
539 CHECK(mSource == NULL);
540
Chong Zhang3de157d2014-08-05 20:54:44 -0700541 status_t err = OK;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800542 sp<RefBase> obj;
543 CHECK(msg->findObject("source", &obj));
Chong Zhang3de157d2014-08-05 20:54:44 -0700544 if (obj != NULL) {
Wei Jiac45a4b22016-04-15 15:30:23 -0700545 Mutex::Autolock autoLock(mSourceLock);
Chong Zhang3de157d2014-08-05 20:54:44 -0700546 mSource = static_cast<Source *>(obj.get());
Chong Zhang3de157d2014-08-05 20:54:44 -0700547 } else {
548 err = UNKNOWN_ERROR;
549 }
Andreas Huber9575c962013-02-05 13:59:56 -0800550
551 CHECK(mDriver != NULL);
552 sp<NuPlayerDriver> driver = mDriver.promote();
553 if (driver != NULL) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700554 driver->notifySetDataSourceCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -0800555 }
556 break;
557 }
558
Wei Jia48fa06d2016-12-20 15:30:49 -0800559 case kWhatGetDefaultBufferingSettings:
560 {
561 sp<AReplyToken> replyID;
562 CHECK(msg->senderAwaitsResponse(&replyID));
563
564 ALOGV("kWhatGetDefaultBufferingSettings");
565 BufferingSettings buffering;
566 status_t err = OK;
567 if (mSource != NULL) {
568 err = mSource->getDefaultBufferingSettings(&buffering);
569 } else {
570 err = INVALID_OPERATION;
571 }
572 sp<AMessage> response = new AMessage;
573 if (err == OK) {
574 writeToAMessage(response, buffering);
575 }
576 response->setInt32("err", err);
577 response->postReply(replyID);
578 break;
579 }
580
581 case kWhatSetBufferingSettings:
582 {
583 sp<AReplyToken> replyID;
584 CHECK(msg->senderAwaitsResponse(&replyID));
585
586 ALOGV("kWhatSetBufferingSettings");
587 BufferingSettings buffering;
588 readFromAMessage(msg, &buffering);
589 status_t err = OK;
590 if (mSource != NULL) {
591 err = mSource->setBufferingSettings(buffering);
592 } else {
593 err = INVALID_OPERATION;
594 }
595 sp<AMessage> response = new AMessage;
596 response->setInt32("err", err);
597 response->postReply(replyID);
598 break;
599 }
600
Andreas Huber9575c962013-02-05 13:59:56 -0800601 case kWhatPrepare:
602 {
Hassan Shojaniacefac142017-02-06 21:02:02 -0800603 ALOGV("onMessageReceived kWhatPrepare");
604
Andreas Huber9575c962013-02-05 13:59:56 -0800605 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800606 break;
607 }
608
Chong Zhangdcb89b32013-08-06 09:44:47 -0700609 case kWhatGetTrackInfo:
610 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800611 sp<AReplyToken> replyID;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700612 CHECK(msg->senderAwaitsResponse(&replyID));
613
Chong Zhang404fced2014-06-11 14:45:31 -0700614 Parcel* reply;
615 CHECK(msg->findPointer("reply", (void**)&reply));
616
617 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700618 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700619 inbandTracks = mSource->getTrackCount();
620 }
621
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700622 size_t ccTracks = 0;
623 if (mCCDecoder != NULL) {
624 ccTracks = mCCDecoder->getTrackCount();
625 }
626
Chong Zhang404fced2014-06-11 14:45:31 -0700627 // total track count
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700628 reply->writeInt32(inbandTracks + ccTracks);
Chong Zhang404fced2014-06-11 14:45:31 -0700629
630 // write inband tracks
631 for (size_t i = 0; i < inbandTracks; ++i) {
632 writeTrackInfo(reply, mSource->getTrackInfo(i));
Chong Zhangdcb89b32013-08-06 09:44:47 -0700633 }
634
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700635 // write CC track
636 for (size_t i = 0; i < ccTracks; ++i) {
637 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
638 }
639
Chong Zhangdcb89b32013-08-06 09:44:47 -0700640 sp<AMessage> response = new AMessage;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700641 response->postReply(replyID);
642 break;
643 }
644
Robert Shih7c4f0d72014-07-09 18:53:31 -0700645 case kWhatGetSelectedTrack:
646 {
647 status_t err = INVALID_OPERATION;
648 if (mSource != NULL) {
649 err = OK;
650
651 int32_t type32;
652 CHECK(msg->findInt32("type", (int32_t*)&type32));
653 media_track_type type = (media_track_type)type32;
654 ssize_t selectedTrack = mSource->getSelectedTrack(type);
655
656 Parcel* reply;
657 CHECK(msg->findPointer("reply", (void**)&reply));
658 reply->writeInt32(selectedTrack);
659 }
660
661 sp<AMessage> response = new AMessage;
662 response->setInt32("err", err);
663
Lajos Molnar3f274362015-03-05 14:35:41 -0800664 sp<AReplyToken> replyID;
Robert Shih7c4f0d72014-07-09 18:53:31 -0700665 CHECK(msg->senderAwaitsResponse(&replyID));
666 response->postReply(replyID);
667 break;
668 }
669
Chong Zhangdcb89b32013-08-06 09:44:47 -0700670 case kWhatSelectTrack:
671 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800672 sp<AReplyToken> replyID;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700673 CHECK(msg->senderAwaitsResponse(&replyID));
674
Chong Zhang404fced2014-06-11 14:45:31 -0700675 size_t trackIndex;
676 int32_t select;
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700677 int64_t timeUs;
Chong Zhang404fced2014-06-11 14:45:31 -0700678 CHECK(msg->findSize("trackIndex", &trackIndex));
679 CHECK(msg->findInt32("select", &select));
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700680 CHECK(msg->findInt64("timeUs", &timeUs));
Chong Zhang404fced2014-06-11 14:45:31 -0700681
Chong Zhangdcb89b32013-08-06 09:44:47 -0700682 status_t err = INVALID_OPERATION;
Chong Zhang404fced2014-06-11 14:45:31 -0700683
684 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700685 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700686 inbandTracks = mSource->getTrackCount();
687 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700688 size_t ccTracks = 0;
689 if (mCCDecoder != NULL) {
690 ccTracks = mCCDecoder->getTrackCount();
691 }
Chong Zhang404fced2014-06-11 14:45:31 -0700692
693 if (trackIndex < inbandTracks) {
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700694 err = mSource->selectTrack(trackIndex, select, timeUs);
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700695
696 if (!select && err == OK) {
697 int32_t type;
698 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
699 if (info != NULL
700 && info->findInt32("type", &type)
701 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
702 ++mTimedTextGeneration;
703 }
704 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700705 } else {
706 trackIndex -= inbandTracks;
707
708 if (trackIndex < ccTracks) {
709 err = mCCDecoder->selectTrack(trackIndex, select);
710 }
Chong Zhangdcb89b32013-08-06 09:44:47 -0700711 }
712
713 sp<AMessage> response = new AMessage;
714 response->setInt32("err", err);
715
716 response->postReply(replyID);
717 break;
718 }
719
Andreas Huberb7c8e912012-11-27 15:02:53 -0800720 case kWhatPollDuration:
721 {
722 int32_t generation;
723 CHECK(msg->findInt32("generation", &generation));
724
725 if (generation != mPollDurationGeneration) {
726 // stale
727 break;
728 }
729
730 int64_t durationUs;
731 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
732 sp<NuPlayerDriver> driver = mDriver.promote();
733 if (driver != NULL) {
734 driver->notifyDuration(durationUs);
735 }
736 }
737
738 msg->post(1000000ll); // poll again in a second.
739 break;
740 }
741
Lajos Molnar1de1e252015-04-30 18:18:34 -0700742 case kWhatSetVideoSurface:
Andreas Huberf9334412010-12-15 15:17:42 -0800743 {
Andreas Huberf9334412010-12-15 15:17:42 -0800744
745 sp<RefBase> obj;
Lajos Molnar1de1e252015-04-30 18:18:34 -0700746 CHECK(msg->findObject("surface", &obj));
747 sp<Surface> surface = static_cast<Surface *>(obj.get());
Lajos Molnara81c6222015-07-10 19:17:45 -0700748
749 ALOGD("onSetVideoSurface(%p, %s video decoder)",
750 surface.get(),
Wei Jia6b7d2ed2015-08-10 15:11:54 -0700751 (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
Lajos Molnara81c6222015-07-10 19:17:45 -0700752 && mVideoDecoder != NULL) ? "have" : "no");
753
Wei Jia6b7d2ed2015-08-10 15:11:54 -0700754 // Need to check mStarted before calling mSource->getFormat because NuPlayer might
755 // be in preparing state and it could take long time.
756 // When mStarted is true, mSource must have been set.
757 if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
Lajos Molnara81c6222015-07-10 19:17:45 -0700758 // NOTE: mVideoDecoder's mSurface is always non-null
759 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700760 performSetSurface(surface);
Wei Jiafef808d2014-10-31 17:57:05 -0700761 break;
762 }
763
764 mDeferredActions.push_back(
765 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
766 FLUSH_CMD_SHUTDOWN /* video */));
767
Lajos Molnar1de1e252015-04-30 18:18:34 -0700768 mDeferredActions.push_back(new SetSurfaceAction(surface));
James Dong0d268a32012-08-31 12:18:27 -0700769
Wei Jiac6e58412015-07-10 18:04:55 -0700770 if (obj != NULL || mAudioDecoder != NULL) {
Wei Jiafef808d2014-10-31 17:57:05 -0700771 if (mStarted) {
Andy Hung73535852014-09-05 11:42:58 -0700772 // Issue a seek to refresh the video screen only if started otherwise
773 // the extractor may not yet be started and will assert.
774 // If the video decoder is not set (perhaps audio only in this case)
775 // do not perform a seek as it is not needed.
Ronghua Wua73d9e02014-10-08 15:13:29 -0700776 int64_t currentPositionUs = 0;
777 if (getCurrentPosition(&currentPositionUs) == OK) {
778 mDeferredActions.push_back(
Wei Jiac5de0912016-11-18 10:22:14 -0800779 new SeekAction(currentPositionUs,
780 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
Ronghua Wua73d9e02014-10-08 15:13:29 -0700781 }
Andy Hung73535852014-09-05 11:42:58 -0700782 }
Wei Jiaac428aa2014-09-02 19:01:34 -0700783
Andreas Huber57a339c2012-12-03 11:18:00 -0800784 // If there is a new surface texture, instantiate decoders
785 // again if possible.
786 mDeferredActions.push_back(
787 new SimpleAction(&NuPlayer::performScanSources));
788 }
789
Chong Zhangf8d71772014-11-26 15:08:34 -0800790 // After a flush without shutdown, decoder is paused.
791 // Don't resume it until source seek is done, otherwise it could
Chong Zhang7137ec72014-11-12 16:41:05 -0800792 // start pulling stale data too soon.
793 mDeferredActions.push_back(
Chong Zhangf8d71772014-11-26 15:08:34 -0800794 new ResumeDecoderAction(false /* needNotify */));
Chong Zhang7137ec72014-11-12 16:41:05 -0800795
Andreas Huber57a339c2012-12-03 11:18:00 -0800796 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800797 break;
798 }
799
800 case kWhatSetAudioSink:
801 {
Steve Block3856b092011-10-20 11:56:00 +0100802 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800803
804 sp<RefBase> obj;
805 CHECK(msg->findObject("sink", &obj));
806
807 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
808 break;
809 }
810
811 case kWhatStart:
812 {
Steve Block3856b092011-10-20 11:56:00 +0100813 ALOGV("kWhatStart");
Wei Jia94211742014-10-28 17:09:06 -0700814 if (mStarted) {
Chong Zhang8a048332015-05-06 15:16:28 -0700815 // do not resume yet if the source is still buffering
816 if (!mPausedForBuffering) {
817 onResume();
818 }
Wei Jia94211742014-10-28 17:09:06 -0700819 } else {
820 onStart();
Lajos Molnar09524832014-07-17 14:29:51 -0700821 }
Chong Zhangefbb6192015-01-30 17:13:27 -0800822 mPausedByClient = false;
Andreas Huberf9334412010-12-15 15:17:42 -0800823 break;
824 }
825
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700826 case kWhatConfigPlayback:
Wei Jia98160162015-02-04 17:01:11 -0800827 {
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700828 sp<AReplyToken> replyID;
829 CHECK(msg->senderAwaitsResponse(&replyID));
830 AudioPlaybackRate rate /* sanitized */;
831 readFromAMessage(msg, &rate);
832 status_t err = OK;
Wei Jia98160162015-02-04 17:01:11 -0800833 if (mRenderer != NULL) {
Wei Jiabf70feb2016-02-19 15:47:16 -0800834 // AudioSink allows only 1.f and 0.f for offload mode.
835 // For other speed, switch to non-offload mode.
836 if (mOffloadAudio && ((rate.mSpeed != 0.f && rate.mSpeed != 1.f)
837 || rate.mPitch != 1.f)) {
838 int64_t currentPositionUs;
839 if (getCurrentPosition(&currentPositionUs) != OK) {
840 currentPositionUs = mPreviousSeekTimeUs;
841 }
842
843 // Set mPlaybackSettings so that the new audio decoder can
844 // be created correctly.
845 mPlaybackSettings = rate;
846 if (!mPaused) {
847 mRenderer->pause();
848 }
Wei Jia5031b2f2016-02-25 11:19:31 -0800849 restartAudio(
Wei Jiabf70feb2016-02-19 15:47:16 -0800850 currentPositionUs, true /* forceNonOffload */,
851 true /* needsToCreateAudioDecoder */);
852 if (!mPaused) {
853 mRenderer->resume();
854 }
855 }
856
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700857 err = mRenderer->setPlaybackSettings(rate);
858 }
859 if (err == OK) {
860 if (rate.mSpeed == 0.f) {
861 onPause();
Wei Jia351ce872016-02-10 13:21:59 -0800862 mPausedByClient = true;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700863 // save all other settings (using non-paused speed)
864 // so we can restore them on start
865 AudioPlaybackRate newRate = rate;
866 newRate.mSpeed = mPlaybackSettings.mSpeed;
867 mPlaybackSettings = newRate;
868 } else { /* rate.mSpeed != 0.f */
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700869 mPlaybackSettings = rate;
Wei Jia8a092d32016-06-03 14:57:24 -0700870 if (mStarted) {
871 // do not resume yet if the source is still buffering
872 if (!mPausedForBuffering) {
873 onResume();
874 }
875 } else if (mPrepared) {
876 onStart();
877 }
878
879 mPausedByClient = false;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700880 }
Wei Jia98160162015-02-04 17:01:11 -0800881 }
Ronghua Wu8db88132015-04-22 13:51:35 -0700882
883 if (mVideoDecoder != NULL) {
Praveen Chavanbbaa1442016-04-08 13:33:49 -0700884 sp<AMessage> params = new AMessage();
885 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
886 mVideoDecoder->setParameters(params);
Ronghua Wu8db88132015-04-22 13:51:35 -0700887 }
888
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700889 sp<AMessage> response = new AMessage;
890 response->setInt32("err", err);
891 response->postReply(replyID);
892 break;
893 }
894
895 case kWhatGetPlaybackSettings:
896 {
897 sp<AReplyToken> replyID;
898 CHECK(msg->senderAwaitsResponse(&replyID));
899 AudioPlaybackRate rate = mPlaybackSettings;
900 status_t err = OK;
901 if (mRenderer != NULL) {
902 err = mRenderer->getPlaybackSettings(&rate);
903 }
904 if (err == OK) {
905 // get playback settings used by renderer, as it may be
906 // slightly off due to audiosink not taking small changes.
907 mPlaybackSettings = rate;
908 if (mPaused) {
909 rate.mSpeed = 0.f;
910 }
911 }
912 sp<AMessage> response = new AMessage;
913 if (err == OK) {
914 writeToAMessage(response, rate);
915 }
916 response->setInt32("err", err);
917 response->postReply(replyID);
918 break;
919 }
920
921 case kWhatConfigSync:
922 {
923 sp<AReplyToken> replyID;
924 CHECK(msg->senderAwaitsResponse(&replyID));
925
926 ALOGV("kWhatConfigSync");
927 AVSyncSettings sync;
928 float videoFpsHint;
929 readFromAMessage(msg, &sync, &videoFpsHint);
930 status_t err = OK;
931 if (mRenderer != NULL) {
932 err = mRenderer->setSyncSettings(sync, videoFpsHint);
933 }
934 if (err == OK) {
935 mSyncSettings = sync;
936 mVideoFpsHint = videoFpsHint;
937 }
938 sp<AMessage> response = new AMessage;
939 response->setInt32("err", err);
940 response->postReply(replyID);
941 break;
942 }
943
944 case kWhatGetSyncSettings:
945 {
946 sp<AReplyToken> replyID;
947 CHECK(msg->senderAwaitsResponse(&replyID));
948 AVSyncSettings sync = mSyncSettings;
949 float videoFps = mVideoFpsHint;
950 status_t err = OK;
951 if (mRenderer != NULL) {
952 err = mRenderer->getSyncSettings(&sync, &videoFps);
953 if (err == OK) {
954 mSyncSettings = sync;
955 mVideoFpsHint = videoFps;
956 }
957 }
958 sp<AMessage> response = new AMessage;
959 if (err == OK) {
960 writeToAMessage(response, sync, videoFps);
961 }
962 response->setInt32("err", err);
963 response->postReply(replyID);
Wei Jia98160162015-02-04 17:01:11 -0800964 break;
965 }
966
Andreas Huberf9334412010-12-15 15:17:42 -0800967 case kWhatScanSources:
968 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800969 int32_t generation;
970 CHECK(msg->findInt32("generation", &generation));
971 if (generation != mScanSourcesGeneration) {
972 // Drop obsolete msg.
973 break;
974 }
975
Andreas Huber5bc087c2010-12-23 10:27:40 -0800976 mScanSourcesPending = false;
977
Steve Block3856b092011-10-20 11:56:00 +0100978 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800979 mAudioDecoder != NULL, mVideoDecoder != NULL);
980
Andreas Huberb7c8e912012-11-27 15:02:53 -0800981 bool mHadAnySourcesBefore =
982 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
Robert Shih7350b052015-10-01 15:50:14 -0700983 bool rescan = false;
Andreas Huberb7c8e912012-11-27 15:02:53 -0800984
Andy Hung282a7e32014-08-14 15:56:34 -0700985 // initialize video before audio because successful initialization of
986 // video may change deep buffer mode of audio.
Lajos Molnar1de1e252015-04-30 18:18:34 -0700987 if (mSurface != NULL) {
Robert Shih7350b052015-10-01 15:50:14 -0700988 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
989 rescan = true;
990 }
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700991 }
Andreas Huberf9334412010-12-15 15:17:42 -0800992
Ronghua Wua10fd232014-11-06 16:15:20 -0800993 // Don't try to re-open audio sink if there's an existing decoder.
994 if (mAudioSink != NULL && mAudioDecoder == NULL) {
Robert Shih7350b052015-10-01 15:50:14 -0700995 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
996 rescan = true;
997 }
Andreas Huberf9334412010-12-15 15:17:42 -0800998 }
999
Andreas Huberb7c8e912012-11-27 15:02:53 -08001000 if (!mHadAnySourcesBefore
1001 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1002 // This is the first time we've found anything playable.
1003
Andreas Huber9575c962013-02-05 13:59:56 -08001004 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -08001005 schedulePollDuration();
1006 }
1007 }
1008
Andreas Hubereac68ba2011-09-27 12:12:25 -07001009 status_t err;
1010 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -08001011 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1012 // We're not currently decoding anything (no audio or
1013 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -07001014
1015 if (err == ERROR_END_OF_STREAM) {
1016 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1017 } else {
1018 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1019 }
Andreas Huber1aef2112011-01-04 14:01:29 -08001020 }
Andreas Huberf9334412010-12-15 15:17:42 -08001021 break;
1022 }
1023
Robert Shih7350b052015-10-01 15:50:14 -07001024 if (rescan) {
Andreas Huberf9334412010-12-15 15:17:42 -08001025 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -08001026 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -08001027 }
1028 break;
1029 }
1030
1031 case kWhatVideoNotify:
1032 case kWhatAudioNotify:
1033 {
1034 bool audio = msg->what() == kWhatAudioNotify;
1035
Wei Jia88703c32014-08-06 11:24:07 -07001036 int32_t currentDecoderGeneration =
1037 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1038 int32_t requesterGeneration = currentDecoderGeneration - 1;
1039 CHECK(msg->findInt32("generation", &requesterGeneration));
1040
1041 if (requesterGeneration != currentDecoderGeneration) {
1042 ALOGV("got message from old %s decoder, generation(%d:%d)",
1043 audio ? "audio" : "video", requesterGeneration,
1044 currentDecoderGeneration);
1045 sp<AMessage> reply;
1046 if (!(msg->findMessage("reply", &reply))) {
1047 return;
1048 }
1049
1050 reply->setInt32("err", INFO_DISCONTINUITY);
1051 reply->post();
1052 return;
1053 }
1054
Andreas Huberf9334412010-12-15 15:17:42 -08001055 int32_t what;
Lajos Molnar1cd13982014-01-17 15:12:51 -08001056 CHECK(msg->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -08001057
Chong Zhang7137ec72014-11-12 16:41:05 -08001058 if (what == DecoderBase::kWhatInputDiscontinuity) {
1059 int32_t formatChange;
1060 CHECK(msg->findInt32("formatChange", &formatChange));
Andreas Huberf9334412010-12-15 15:17:42 -08001061
Chong Zhang7137ec72014-11-12 16:41:05 -08001062 ALOGV("%s discontinuity: formatChange %d",
1063 audio ? "audio" : "video", formatChange);
1064
1065 if (formatChange) {
1066 mDeferredActions.push_back(
1067 new FlushDecoderAction(
1068 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1069 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
Andreas Huberf9334412010-12-15 15:17:42 -08001070 }
Chong Zhang7137ec72014-11-12 16:41:05 -08001071
1072 mDeferredActions.push_back(
1073 new SimpleAction(
1074 &NuPlayer::performScanSources));
1075
1076 processDeferredActions();
1077 } else if (what == DecoderBase::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001078 int32_t err;
Lajos Molnar1cd13982014-01-17 15:12:51 -08001079 CHECK(msg->findInt32("err", &err));
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001080
1081 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +01001082 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001083 } else {
Steve Block3856b092011-10-20 11:56:00 +01001084 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001085 audio ? "audio" : "video",
1086 err);
1087 }
1088
1089 mRenderer->queueEOS(audio, err);
Chong Zhang7137ec72014-11-12 16:41:05 -08001090 } else if (what == DecoderBase::kWhatFlushCompleted) {
Steve Block3856b092011-10-20 11:56:00 +01001091 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -08001092
Andy Hung8d121d42014-10-03 09:53:53 -07001093 handleFlushComplete(audio, true /* isDecoder */);
Andreas Huber3831a062010-12-21 10:22:33 -08001094 finishFlushIfPossible();
Chong Zhang7137ec72014-11-12 16:41:05 -08001095 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
Lajos Molnar1cd13982014-01-17 15:12:51 -08001096 sp<AMessage> format;
1097 CHECK(msg->findMessage("format", &format));
1098
Wei Jiac6cfd702014-11-11 16:33:20 -08001099 sp<AMessage> inputFormat =
1100 mSource->getFormat(false /* audio */);
Andreas Huber3831a062010-12-21 10:22:33 -08001101
Bartosz Dolewski26936f72014-12-11 12:47:08 +01001102 setVideoScalingMode(mVideoScalingMode);
Wei Jiac6cfd702014-11-11 16:33:20 -08001103 updateVideoSize(inputFormat, format);
Chong Zhang7137ec72014-11-12 16:41:05 -08001104 } else if (what == DecoderBase::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +01001105 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -08001106 if (audio) {
1107 mAudioDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001108 mAudioDecoderError = false;
Wei Jia57568df2014-09-22 10:16:29 -07001109 ++mAudioDecoderGeneration;
Andreas Huber3831a062010-12-21 10:22:33 -08001110
1111 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1112 mFlushingAudio = SHUT_DOWN;
1113 } else {
1114 mVideoDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001115 mVideoDecoderError = false;
Wei Jia57568df2014-09-22 10:16:29 -07001116 ++mVideoDecoderGeneration;
Andreas Huber3831a062010-12-21 10:22:33 -08001117
1118 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1119 mFlushingVideo = SHUT_DOWN;
1120 }
1121
1122 finishFlushIfPossible();
Chong Zhangf8d71772014-11-26 15:08:34 -08001123 } else if (what == DecoderBase::kWhatResumeCompleted) {
1124 finishResume();
Chong Zhang7137ec72014-11-12 16:41:05 -08001125 } else if (what == DecoderBase::kWhatError) {
Chong Zhangf4c0a942014-08-11 15:14:10 -07001126 status_t err;
Andy Hung2abde2c2014-09-30 14:40:32 -07001127 if (!msg->findInt32("err", &err) || err == OK) {
Chong Zhangf4c0a942014-08-11 15:14:10 -07001128 err = UNKNOWN_ERROR;
1129 }
Andy Hungcf31f1e2014-09-23 14:59:01 -07001130
Andy Hung2abde2c2014-09-30 14:40:32 -07001131 // Decoder errors can be due to Source (e.g. from streaming),
1132 // or from decoding corrupted bitstreams, or from other decoder
1133 // MediaCodec operations (e.g. from an ongoing reset or seek).
Andy Hung202bce12014-12-03 11:47:36 -08001134 // They may also be due to openAudioSink failure at
1135 // decoder start or after a format change.
Andy Hung2abde2c2014-09-30 14:40:32 -07001136 //
1137 // We try to gracefully shut down the affected decoder if possible,
1138 // rather than trying to force the shutdown with something
1139 // similar to performReset(). This method can lead to a hang
1140 // if MediaCodec functions block after an error, but they should
1141 // typically return INVALID_OPERATION instead of blocking.
1142
1143 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1144 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1145 err, audio ? "audio" : "video", *flushing);
1146
1147 switch (*flushing) {
1148 case NONE:
1149 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001150 new FlushDecoderAction(
1151 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1152 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
Andy Hung2abde2c2014-09-30 14:40:32 -07001153 processDeferredActions();
1154 break;
1155 case FLUSHING_DECODER:
1156 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1157 break; // Wait for flush to complete.
1158 case FLUSHING_DECODER_SHUTDOWN:
1159 break; // Wait for flush to complete.
1160 case SHUTTING_DOWN_DECODER:
1161 break; // Wait for shutdown to complete.
1162 case FLUSHED:
Andy Hung2abde2c2014-09-30 14:40:32 -07001163 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1164 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1165 break;
1166 case SHUT_DOWN:
1167 finishFlushIfPossible(); // Should not occur.
1168 break; // Finish anyways.
Marco Nelissen9e2b7912014-08-18 16:13:03 -07001169 }
Wei Jia686e8e52017-04-03 14:08:01 -07001170 if (mSource != nullptr) {
1171 if (audio) {
Wei Jia2f6d8c52017-04-11 09:50:31 -07001172 if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
1173 || mSurface == NULL) {
Wei Jia686e8e52017-04-03 14:08:01 -07001174 // When both audio and video have error, or this stream has only audio
1175 // which has error, notify client of error.
1176 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1177 } else {
1178 // Only audio track has error. Video track could be still good to play.
1179 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_AUDIO_ERROR, err);
1180 }
1181 mAudioDecoderError = true;
1182 } else {
Wei Jia2f6d8c52017-04-11 09:50:31 -07001183 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
1184 || mAudioSink == NULL) {
Wei Jia686e8e52017-04-03 14:08:01 -07001185 // When both audio and video have error, or this stream has only video
1186 // which has error, notify client of error.
1187 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1188 } else {
1189 // Only video track has error. Audio track could be still good to play.
1190 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_VIDEO_ERROR, err);
1191 }
1192 mVideoDecoderError = true;
1193 }
1194 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001195 } else {
1196 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001197 what,
1198 what >> 24,
1199 (what >> 16) & 0xff,
1200 (what >> 8) & 0xff,
1201 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -08001202 }
1203
1204 break;
1205 }
1206
1207 case kWhatRendererNotify:
1208 {
Wei Jia57568df2014-09-22 10:16:29 -07001209 int32_t requesterGeneration = mRendererGeneration - 1;
1210 CHECK(msg->findInt32("generation", &requesterGeneration));
1211 if (requesterGeneration != mRendererGeneration) {
1212 ALOGV("got message from old renderer, generation(%d:%d)",
1213 requesterGeneration, mRendererGeneration);
1214 return;
1215 }
1216
Andreas Huberf9334412010-12-15 15:17:42 -08001217 int32_t what;
1218 CHECK(msg->findInt32("what", &what));
1219
1220 if (what == Renderer::kWhatEOS) {
1221 int32_t audio;
1222 CHECK(msg->findInt32("audio", &audio));
1223
Andreas Huberc92fd242011-08-16 13:48:44 -07001224 int32_t finalResult;
1225 CHECK(msg->findInt32("finalResult", &finalResult));
1226
Andreas Huberf9334412010-12-15 15:17:42 -08001227 if (audio) {
1228 mAudioEOS = true;
1229 } else {
1230 mVideoEOS = true;
1231 }
1232
Andreas Huberc92fd242011-08-16 13:48:44 -07001233 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +01001234 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -07001235 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001236 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -07001237 audio ? "audio" : "video", finalResult);
1238
1239 notifyListener(
1240 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
1241 }
Andreas Huberf9334412010-12-15 15:17:42 -08001242
1243 if ((mAudioEOS || mAudioDecoder == NULL)
1244 && (mVideoEOS || mVideoDecoder == NULL)) {
1245 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1246 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001247 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -08001248 int32_t audio;
1249 CHECK(msg->findInt32("audio", &audio));
1250
Wei Jia3261f0d2015-10-08 13:58:33 -07001251 if (audio) {
1252 mAudioEOS = false;
1253 } else {
1254 mVideoEOS = false;
1255 }
1256
Steve Block3856b092011-10-20 11:56:00 +01001257 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
Wei Jiada4252f2015-07-14 18:15:28 -07001258 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1259 || mFlushingAudio == SHUT_DOWN)) {
1260 // Flush has been handled by tear down.
1261 break;
1262 }
Andy Hung8d121d42014-10-03 09:53:53 -07001263 handleFlushComplete(audio, false /* isDecoder */);
1264 finishFlushIfPossible();
James Dongf57b4ea2012-07-20 13:38:36 -07001265 } else if (what == Renderer::kWhatVideoRenderingStart) {
1266 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Lajos Molnarcbaffcf2013-08-14 18:30:38 -07001267 } else if (what == Renderer::kWhatMediaRenderingStart) {
1268 ALOGV("media rendering started");
1269 notifyListener(MEDIA_STARTED, 0, 0);
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001270 } else if (what == Renderer::kWhatAudioTearDown) {
Ronghua Wu08529172014-10-02 16:55:52 -07001271 int32_t reason;
1272 CHECK(msg->findInt32("reason", &reason));
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001273 ALOGV("Tear down audio with reason %d.", reason);
Wei Jia8456ddd2016-04-22 14:46:43 -07001274 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1275 // TimeoutWhenPaused is only for offload mode.
1276 ALOGW("Receive a stale message for teardown.");
1277 break;
1278 }
Wei Jiada4252f2015-07-14 18:15:28 -07001279 int64_t positionUs;
Robert Shih1a5c8592015-08-04 18:07:44 -07001280 if (!msg->findInt64("positionUs", &positionUs)) {
1281 positionUs = mPreviousSeekTimeUs;
1282 }
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001283
Wei Jia5031b2f2016-02-25 11:19:31 -08001284 restartAudio(
Wei Jiaa05f1e32016-03-25 16:31:22 -07001285 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1286 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
Andreas Huberf9334412010-12-15 15:17:42 -08001287 }
1288 break;
1289 }
1290
1291 case kWhatMoreDataQueued:
1292 {
1293 break;
1294 }
1295
Andreas Huber1aef2112011-01-04 14:01:29 -08001296 case kWhatReset:
1297 {
Steve Block3856b092011-10-20 11:56:00 +01001298 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -08001299
Ronghua Wu64c2d172015-10-07 16:52:19 -07001300 mResetting = true;
1301
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001302 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001303 new FlushDecoderAction(
1304 FLUSH_CMD_SHUTDOWN /* audio */,
1305 FLUSH_CMD_SHUTDOWN /* video */));
Andreas Huberb7c8e912012-11-27 15:02:53 -08001306
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001307 mDeferredActions.push_back(
1308 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -08001309
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001310 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001311 break;
1312 }
1313
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001314 case kWhatSeek:
1315 {
1316 int64_t seekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -08001317 int32_t mode;
Wei Jiae427abf2014-09-22 15:21:11 -07001318 int32_t needNotify;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001319 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
Wei Jiac5de0912016-11-18 10:22:14 -08001320 CHECK(msg->findInt32("mode", &mode));
Wei Jiae427abf2014-09-22 15:21:11 -07001321 CHECK(msg->findInt32("needNotify", &needNotify));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001322
Wei Jiac5de0912016-11-18 10:22:14 -08001323 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1324 (long long)seekTimeUs, mode, needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001325
Wei Jia1061c9c2015-05-19 16:02:17 -07001326 if (!mStarted) {
1327 // Seek before the player is started. In order to preview video,
1328 // need to start the player and pause it. This branch is called
1329 // only once if needed. After the player is started, any seek
1330 // operation will go through normal path.
Robert Shih0c61a0d2015-07-06 15:09:10 -07001331 // Audio-only cases are handled separately.
Wei Jiac5de0912016-11-18 10:22:14 -08001332 onStart(seekTimeUs, (MediaPlayerSeekMode)mode);
Robert Shih0c61a0d2015-07-06 15:09:10 -07001333 if (mStarted) {
1334 onPause();
1335 mPausedByClient = true;
1336 }
Wei Jia1061c9c2015-05-19 16:02:17 -07001337 if (needNotify) {
1338 notifyDriverSeekComplete();
1339 }
1340 break;
1341 }
1342
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001343 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001344 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1345 FLUSH_CMD_FLUSH /* video */));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001346
Wei Jiae427abf2014-09-22 15:21:11 -07001347 mDeferredActions.push_back(
Wei Jiac5de0912016-11-18 10:22:14 -08001348 new SeekAction(seekTimeUs, (MediaPlayerSeekMode)mode));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001349
Chong Zhangf8d71772014-11-26 15:08:34 -08001350 // After a flush without shutdown, decoder is paused.
1351 // Don't resume it until source seek is done, otherwise it could
Chong Zhang7137ec72014-11-12 16:41:05 -08001352 // start pulling stale data too soon.
1353 mDeferredActions.push_back(
Chong Zhangf8d71772014-11-26 15:08:34 -08001354 new ResumeDecoderAction(needNotify));
Chong Zhang7137ec72014-11-12 16:41:05 -08001355
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001356 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001357 break;
1358 }
1359
Andreas Huberb4082222011-01-20 15:23:04 -08001360 case kWhatPause:
1361 {
Chong Zhangefbb6192015-01-30 17:13:27 -08001362 onPause();
1363 mPausedByClient = true;
Andreas Huberb4082222011-01-20 15:23:04 -08001364 break;
1365 }
1366
Andreas Huberb5f25f02013-02-05 10:14:26 -08001367 case kWhatSourceNotify:
1368 {
Andreas Huber9575c962013-02-05 13:59:56 -08001369 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -08001370 break;
1371 }
1372
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001373 case kWhatClosedCaptionNotify:
1374 {
1375 onClosedCaptionNotify(msg);
1376 break;
1377 }
1378
Hassan Shojaniacefac142017-02-06 21:02:02 -08001379 case kWhatPrepareDrm:
1380 {
1381 status_t status = onPrepareDrm(msg);
1382
1383 sp<AMessage> response = new AMessage;
1384 response->setInt32("status", status);
1385 sp<AReplyToken> replyID;
1386 CHECK(msg->senderAwaitsResponse(&replyID));
1387 response->postReply(replyID);
1388 break;
1389 }
1390
1391 case kWhatReleaseDrm:
1392 {
1393 status_t status = onReleaseDrm();
1394
1395 sp<AMessage> response = new AMessage;
1396 response->setInt32("status", status);
1397 sp<AReplyToken> replyID;
1398 CHECK(msg->senderAwaitsResponse(&replyID));
1399 response->postReply(replyID);
1400 break;
1401 }
1402
Andreas Huberf9334412010-12-15 15:17:42 -08001403 default:
1404 TRESPASS();
1405 break;
1406 }
1407}
1408
Wei Jia94211742014-10-28 17:09:06 -07001409void NuPlayer::onResume() {
Ronghua Wu64c2d172015-10-07 16:52:19 -07001410 if (!mPaused || mResetting) {
1411 ALOGD_IF(mResetting, "resetting, onResume discarded");
Chong Zhangefbb6192015-01-30 17:13:27 -08001412 return;
1413 }
1414 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001415 if (mSource != NULL) {
1416 mSource->resume();
1417 } else {
1418 ALOGW("resume called when source is gone or not set");
1419 }
1420 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1421 // needed.
1422 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1423 instantiateDecoder(true /* audio */, &mAudioDecoder);
1424 }
1425 if (mRenderer != NULL) {
1426 mRenderer->resume();
1427 } else {
1428 ALOGW("resume called when renderer is gone or not set");
1429 }
Ray Essickd4d00612017-01-03 09:36:27 -08001430
1431 mLastStartedPlayingTimeNs = systemTime();
Wei Jia94211742014-10-28 17:09:06 -07001432}
1433
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001434status_t NuPlayer::onInstantiateSecureDecoders() {
1435 status_t err;
1436 if (!(mSourceFlags & Source::FLAG_SECURE)) {
1437 return BAD_TYPE;
1438 }
1439
1440 if (mRenderer != NULL) {
1441 ALOGE("renderer should not be set when instantiating secure decoders");
1442 return UNKNOWN_ERROR;
1443 }
1444
1445 // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
1446 // data on instantiation.
Lajos Molnar1de1e252015-04-30 18:18:34 -07001447 if (mSurface != NULL) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001448 err = instantiateDecoder(false, &mVideoDecoder);
1449 if (err != OK) {
1450 return err;
1451 }
1452 }
1453
1454 if (mAudioSink != NULL) {
1455 err = instantiateDecoder(true, &mAudioDecoder);
1456 if (err != OK) {
1457 return err;
1458 }
1459 }
1460 return OK;
1461}
1462
Wei Jiac5de0912016-11-18 10:22:14 -08001463void NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08001464 ALOGV("onStart: mCrypto: %p (%d)", mCrypto.get(),
1465 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
1466
Robert Shih0c61a0d2015-07-06 15:09:10 -07001467 if (!mSourceStarted) {
1468 mSourceStarted = true;
1469 mSource->start();
1470 }
1471 if (startPositionUs > 0) {
Wei Jiac5de0912016-11-18 10:22:14 -08001472 performSeek(startPositionUs, mode);
Robert Shih0c61a0d2015-07-06 15:09:10 -07001473 if (mSource->getFormat(false /* audio */) == NULL) {
1474 return;
1475 }
1476 }
1477
Wei Jia94211742014-10-28 17:09:06 -07001478 mOffloadAudio = false;
1479 mAudioEOS = false;
1480 mVideoEOS = false;
Wei Jia94211742014-10-28 17:09:06 -07001481 mStarted = true;
Wei Jiafe8fe7d2016-06-08 10:29:25 -07001482 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001483
Wei Jia94211742014-10-28 17:09:06 -07001484 uint32_t flags = 0;
1485
1486 if (mSource->isRealTime()) {
1487 flags |= Renderer::FLAG_REAL_TIME;
1488 }
1489
Wei Jia9737d342016-12-28 14:59:59 -08001490 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1491 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1492 if (!hasAudio && !hasVideo) {
Wei Jia1de83d52016-10-10 10:15:03 -07001493 ALOGE("no metadata for either audio or video source");
1494 mSource->stop();
1495 mSourceStarted = false;
1496 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_MALFORMED);
1497 return;
1498 }
Wei Jia9737d342016-12-28 14:59:59 -08001499 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1500
1501 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
Wei Jia1de83d52016-10-10 10:15:03 -07001502
Wei Jia94211742014-10-28 17:09:06 -07001503 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1504 if (mAudioSink != NULL) {
1505 streamType = mAudioSink->getAudioStreamType();
1506 }
1507
Wei Jia94211742014-10-28 17:09:06 -07001508 mOffloadAudio =
Wei Jia9737d342016-12-28 14:59:59 -08001509 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
Wei Jiabf70feb2016-02-19 15:47:16 -08001510 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001511
1512 // Modular DRM: Disabling audio offload if the source is protected
1513 if (mOffloadAudio && mIsDrmProtected) {
1514 mOffloadAudio = false;
1515 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1516 }
1517
Wei Jia94211742014-10-28 17:09:06 -07001518 if (mOffloadAudio) {
1519 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1520 }
1521
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001522 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
Wei Jia94211742014-10-28 17:09:06 -07001523 ++mRendererGeneration;
1524 notify->setInt32("generation", mRendererGeneration);
1525 mRenderer = new Renderer(mAudioSink, notify, flags);
Wei Jia94211742014-10-28 17:09:06 -07001526 mRendererLooper = new ALooper;
1527 mRendererLooper->setName("NuPlayerRenderer");
1528 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1529 mRendererLooper->registerHandler(mRenderer);
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001530
1531 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1532 if (err != OK) {
1533 mSource->stop();
Robert Shih0c61a0d2015-07-06 15:09:10 -07001534 mSourceStarted = false;
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001535 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1536 return;
Wei Jiac8206ff2015-03-04 13:59:37 -08001537 }
Wei Jia94211742014-10-28 17:09:06 -07001538
Ronghua Wuc8a70d32015-04-29 16:26:34 -07001539 float rate = getFrameRate();
1540 if (rate > 0) {
Wei Jia94211742014-10-28 17:09:06 -07001541 mRenderer->setVideoFrameRate(rate);
1542 }
1543
Wei Jiac6cfd702014-11-11 16:33:20 -08001544 if (mVideoDecoder != NULL) {
1545 mVideoDecoder->setRenderer(mRenderer);
1546 }
1547 if (mAudioDecoder != NULL) {
1548 mAudioDecoder->setRenderer(mRenderer);
1549 }
1550
Ray Essickd4d00612017-01-03 09:36:27 -08001551 mLastStartedPlayingTimeNs = systemTime();
1552
Wei Jia94211742014-10-28 17:09:06 -07001553 postScanSources();
1554}
1555
Chong Zhangefbb6192015-01-30 17:13:27 -08001556void NuPlayer::onPause() {
1557 if (mPaused) {
1558 return;
1559 }
1560 mPaused = true;
1561 if (mSource != NULL) {
1562 mSource->pause();
1563 } else {
1564 ALOGW("pause called when source is gone or not set");
1565 }
1566 if (mRenderer != NULL) {
1567 mRenderer->pause();
1568 } else {
1569 ALOGW("pause called when renderer is gone or not set");
1570 }
Ray Essickd4d00612017-01-03 09:36:27 -08001571
1572 sp<NuPlayerDriver> driver = mDriver.promote();
1573 if (driver != NULL) {
1574 int64_t now = systemTime();
1575 int64_t played = now - mLastStartedPlayingTimeNs;
Ray Essickd4d00612017-01-03 09:36:27 -08001576
1577 driver->notifyMorePlayingTimeUs((played+500)/1000);
1578 }
Chong Zhangefbb6192015-01-30 17:13:27 -08001579}
1580
Ronghua Wud7988b12014-10-03 15:19:10 -07001581bool NuPlayer::audioDecoderStillNeeded() {
1582 // Audio decoder is no longer needed if it's in shut/shutting down status.
1583 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1584}
1585
Andy Hung8d121d42014-10-03 09:53:53 -07001586void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1587 // We wait for both the decoder flush and the renderer flush to complete
1588 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1589
1590 mFlushComplete[audio][isDecoder] = true;
1591 if (!mFlushComplete[audio][!isDecoder]) {
1592 return;
1593 }
1594
1595 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1596 switch (*state) {
1597 case FLUSHING_DECODER:
1598 {
1599 *state = FLUSHED;
Andy Hung8d121d42014-10-03 09:53:53 -07001600 break;
1601 }
1602
1603 case FLUSHING_DECODER_SHUTDOWN:
1604 {
1605 *state = SHUTTING_DOWN_DECODER;
1606
1607 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
Andy Hung8d121d42014-10-03 09:53:53 -07001608 getDecoder(audio)->initiateShutdown();
1609 break;
1610 }
1611
1612 default:
1613 // decoder flush completes only occur in a flushing state.
1614 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1615 break;
1616 }
1617}
1618
Andreas Huber3831a062010-12-21 10:22:33 -08001619void NuPlayer::finishFlushIfPossible() {
Wei Jia53904f32014-07-29 10:22:53 -07001620 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1621 && mFlushingAudio != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001622 return;
1623 }
1624
Wei Jia53904f32014-07-29 10:22:53 -07001625 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1626 && mFlushingVideo != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001627 return;
1628 }
1629
Steve Block3856b092011-10-20 11:56:00 +01001630 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -08001631
Andreas Huber3831a062010-12-21 10:22:33 -08001632 mFlushingAudio = NONE;
1633 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -08001634
Andy Hung8d121d42014-10-03 09:53:53 -07001635 clearFlushComplete();
1636
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001637 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001638}
1639
1640void NuPlayer::postScanSources() {
1641 if (mScanSourcesPending) {
1642 return;
1643 }
1644
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001645 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
Andreas Huber1aef2112011-01-04 14:01:29 -08001646 msg->setInt32("generation", mScanSourcesGeneration);
1647 msg->post();
1648
1649 mScanSourcesPending = true;
1650}
1651
Wei Jia41cd4632016-05-13 10:53:30 -07001652void NuPlayer::tryOpenAudioSinkForOffload(
1653 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
Andy Hung202bce12014-12-03 11:47:36 -08001654 // Note: This is called early in NuPlayer to determine whether offloading
1655 // is possible; otherwise the decoders call the renderer openAudioSink directly.
Andy Hung282a7e32014-08-14 15:56:34 -07001656
Andy Hung202bce12014-12-03 11:47:36 -08001657 status_t err = mRenderer->openAudioSink(
Dhananjay Kumarc387f2b2015-08-06 10:43:16 +05301658 format, true /* offloadOnly */, hasVideo,
1659 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
Andy Hung202bce12014-12-03 11:47:36 -08001660 if (err != OK) {
1661 // Any failure we turn off mOffloadAudio.
1662 mOffloadAudio = false;
1663 } else if (mOffloadAudio) {
Chong Zhang3b9eb1f2014-10-15 17:05:08 -07001664 sendMetaDataToHal(mAudioSink, audioMeta);
Andy Hung282a7e32014-08-14 15:56:34 -07001665 }
1666}
1667
1668void NuPlayer::closeAudioSink() {
Chong Zhang3b9eb1f2014-10-15 17:05:08 -07001669 mRenderer->closeAudioSink();
Andy Hung282a7e32014-08-14 15:56:34 -07001670}
1671
Wei Jia5031b2f2016-02-25 11:19:31 -08001672void NuPlayer::restartAudio(
Wei Jiabf70feb2016-02-19 15:47:16 -08001673 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
Wei Jiaa05f1e32016-03-25 16:31:22 -07001674 if (mAudioDecoder != NULL) {
1675 mAudioDecoder->pause();
1676 mAudioDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001677 mAudioDecoderError = false;
Wei Jiaa05f1e32016-03-25 16:31:22 -07001678 ++mAudioDecoderGeneration;
1679 }
Wei Jiabf70feb2016-02-19 15:47:16 -08001680 if (mFlushingAudio == FLUSHING_DECODER) {
1681 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1682 mFlushingAudio = FLUSHED;
1683 finishFlushIfPossible();
1684 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1685 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1686 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1687 mFlushingAudio = SHUT_DOWN;
1688 finishFlushIfPossible();
1689 needsToCreateAudioDecoder = false;
1690 }
1691 if (mRenderer == NULL) {
1692 return;
1693 }
1694 closeAudioSink();
1695 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1696 if (mVideoDecoder != NULL) {
1697 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1698 }
1699
Wei Jiac5de0912016-11-18 10:22:14 -08001700 performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
Wei Jiabf70feb2016-02-19 15:47:16 -08001701
1702 if (forceNonOffload) {
1703 mRenderer->signalDisableOffloadAudio();
1704 mOffloadAudio = false;
1705 }
1706 if (needsToCreateAudioDecoder) {
Wei Jiaa05f1e32016-03-25 16:31:22 -07001707 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
Wei Jiabf70feb2016-02-19 15:47:16 -08001708 }
1709}
1710
Wei Jia41cd4632016-05-13 10:53:30 -07001711void NuPlayer::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiae4d18c72015-07-13 17:58:11 -07001712 if (mSource == NULL || mAudioSink == NULL) {
1713 return;
1714 }
1715
1716 if (mRenderer == NULL) {
1717 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1718 mOffloadAudio = false;
1719 return;
1720 }
1721
1722 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1723 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1724 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1725 const bool hasVideo = (videoFormat != NULL);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001726 bool canOffload = canOffloadStream(
Wei Jiabf70feb2016-02-19 15:47:16 -08001727 audioMeta, hasVideo, mSource->isStreaming(), streamType)
1728 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001729
1730 // Modular DRM: Disabling audio offload if the source is protected
1731 if (canOffload && mIsDrmProtected) {
1732 canOffload = false;
1733 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1734 }
1735
Wei Jiae4d18c72015-07-13 17:58:11 -07001736 if (canOffload) {
1737 if (!mOffloadAudio) {
1738 mRenderer->signalEnableOffloadAudio();
1739 }
1740 // open audio sink early under offload mode.
Wei Jia41cd4632016-05-13 10:53:30 -07001741 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
Wei Jiae4d18c72015-07-13 17:58:11 -07001742 } else {
Robert Shihe1d70192015-07-23 17:54:13 -07001743 if (mOffloadAudio) {
1744 mRenderer->signalDisableOffloadAudio();
1745 mOffloadAudio = false;
1746 }
Wei Jiae4d18c72015-07-13 17:58:11 -07001747 }
1748}
1749
Wei Jiaa05f1e32016-03-25 16:31:22 -07001750status_t NuPlayer::instantiateDecoder(
1751 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
Wei Jia566da802015-08-27 13:59:30 -07001752 // The audio decoder could be cleared by tear down. If still in shut down
1753 // process, no need to create a new audio decoder.
1754 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
Andreas Huberf9334412010-12-15 15:17:42 -08001755 return OK;
1756 }
1757
Andreas Huber84066782011-08-16 09:34:26 -07001758 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -08001759
Andreas Huber84066782011-08-16 09:34:26 -07001760 if (format == NULL) {
Robert Shih7350b052015-10-01 15:50:14 -07001761 return UNKNOWN_ERROR;
1762 } else {
1763 status_t err;
1764 if (format->findInt32("err", &err) && err) {
1765 return err;
1766 }
Andreas Huberf9334412010-12-15 15:17:42 -08001767 }
1768
Ronghua Wu8db88132015-04-22 13:51:35 -07001769 format->setInt32("priority", 0 /* realtime */);
1770
Andreas Huber3fe62152011-09-16 15:09:22 -07001771 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -07001772 AString mime;
1773 CHECK(format->findString("mime", &mime));
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001774
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001775 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
Chong Zhang341ab6e2015-02-04 13:37:18 -08001776 if (mCCDecoder == NULL) {
1777 mCCDecoder = new CCDecoder(ccNotify);
1778 }
Lajos Molnar09524832014-07-17 14:29:51 -07001779
1780 if (mSourceFlags & Source::FLAG_SECURE) {
1781 format->setInt32("secure", true);
1782 }
Chong Zhang17134602015-01-07 16:14:34 -08001783
1784 if (mSourceFlags & Source::FLAG_PROTECTED) {
1785 format->setInt32("protected", true);
1786 }
Ronghua Wu8db88132015-04-22 13:51:35 -07001787
Ronghua Wuc8a70d32015-04-29 16:26:34 -07001788 float rate = getFrameRate();
1789 if (rate > 0) {
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001790 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
Ronghua Wu8db88132015-04-22 13:51:35 -07001791 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001792 }
1793
Wei Jiabc2fb722014-07-08 16:37:57 -07001794 if (audio) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001795 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07001796 ++mAudioDecoderGeneration;
1797 notify->setInt32("generation", mAudioDecoderGeneration);
1798
Wei Jiaa05f1e32016-03-25 16:31:22 -07001799 if (checkAudioModeChange) {
Wei Jia41cd4632016-05-13 10:53:30 -07001800 determineAudioModeChange(format);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001801 }
Wei Jiabc2fb722014-07-08 16:37:57 -07001802 if (mOffloadAudio) {
Wei Jia14532f22015-12-29 11:28:15 -08001803 mSource->setOffloadAudio(true /* offload */);
1804
Haynes Mathew George8b635332015-03-30 17:59:47 -07001805 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1806 format->setInt32("has-video", hasVideo);
Wei Jiac6cfd702014-11-11 16:33:20 -08001807 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001808 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
Wei Jiabc2fb722014-07-08 16:37:57 -07001809 } else {
Wei Jia14532f22015-12-29 11:28:15 -08001810 mSource->setOffloadAudio(false /* offload */);
1811
Wei Jiaf2ae3e12016-10-27 17:10:59 -07001812 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001813 ALOGV("instantiateDecoder audio Decoder");
Wei Jiabc2fb722014-07-08 16:37:57 -07001814 }
Wei Jia686e8e52017-04-03 14:08:01 -07001815 mAudioDecoderError = false;
Wei Jiabc2fb722014-07-08 16:37:57 -07001816 } else {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001817 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07001818 ++mVideoDecoderGeneration;
1819 notify->setInt32("generation", mVideoDecoderGeneration);
1820
Chong Zhang7137ec72014-11-12 16:41:05 -08001821 *decoder = new Decoder(
Wei Jiaf2ae3e12016-10-27 17:10:59 -07001822 notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
Wei Jia686e8e52017-04-03 14:08:01 -07001823 mVideoDecoderError = false;
Lajos Molnard9fd6312014-11-06 11:00:00 -08001824
1825 // enable FRC if high-quality AV sync is requested, even if not
Lajos Molnar1de1e252015-04-30 18:18:34 -07001826 // directly queuing to display, as this will even improve textureview
Lajos Molnard9fd6312014-11-06 11:00:00 -08001827 // playback.
1828 {
Marco Nelissen96626b72016-12-01 13:58:59 -08001829 if (property_get_bool("persist.sys.media.avsync", false)) {
Lajos Molnard9fd6312014-11-06 11:00:00 -08001830 format->setInt32("auto-frc", 1);
1831 }
1832 }
Wei Jiabc2fb722014-07-08 16:37:57 -07001833 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001834 (*decoder)->init();
Hassan Shojaniacefac142017-02-06 21:02:02 -08001835
1836 // Modular DRM
1837 if (mIsDrmProtected) {
1838 format->setPointer("crypto", mCrypto.get());
1839 ALOGV("instantiateDecoder: mCrypto: %p (%d) isSecure: %d", mCrypto.get(),
1840 (mCrypto != NULL ? mCrypto->getStrongCount() : 0),
1841 (mSourceFlags & Source::FLAG_SECURE) != 0);
1842 }
1843
Andreas Huber84066782011-08-16 09:34:26 -07001844 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -08001845
Praveen Chavanbbaa1442016-04-08 13:33:49 -07001846 if (!audio) {
1847 sp<AMessage> params = new AMessage();
1848 float rate = getFrameRate();
1849 if (rate > 0) {
1850 params->setFloat("frame-rate-total", rate);
1851 }
1852
1853 sp<MetaData> fileMeta = getFileMeta();
1854 if (fileMeta != NULL) {
1855 int32_t videoTemporalLayerCount;
1856 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
1857 && videoTemporalLayerCount > 0) {
1858 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
1859 }
1860 }
1861
1862 if (params->countEntries() > 0) {
1863 (*decoder)->setParameters(params);
1864 }
1865 }
Andreas Huberf9334412010-12-15 15:17:42 -08001866 return OK;
1867}
1868
Chong Zhangced1c2f2014-08-08 15:22:35 -07001869void NuPlayer::updateVideoSize(
1870 const sp<AMessage> &inputFormat,
1871 const sp<AMessage> &outputFormat) {
1872 if (inputFormat == NULL) {
1873 ALOGW("Unknown video size, reporting 0x0!");
1874 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1875 return;
1876 }
Wei Jia9737d342016-12-28 14:59:59 -08001877 int32_t err = OK;
1878 inputFormat->findInt32("err", &err);
1879 if (err == -EWOULDBLOCK) {
1880 ALOGW("Video meta is not available yet!");
1881 return;
1882 }
1883 if (err != OK) {
1884 ALOGW("Something is wrong with video meta!");
1885 return;
1886 }
Chong Zhangced1c2f2014-08-08 15:22:35 -07001887
1888 int32_t displayWidth, displayHeight;
Chong Zhangced1c2f2014-08-08 15:22:35 -07001889 if (outputFormat != NULL) {
1890 int32_t width, height;
1891 CHECK(outputFormat->findInt32("width", &width));
1892 CHECK(outputFormat->findInt32("height", &height));
1893
1894 int32_t cropLeft, cropTop, cropRight, cropBottom;
1895 CHECK(outputFormat->findRect(
1896 "crop",
1897 &cropLeft, &cropTop, &cropRight, &cropBottom));
1898
1899 displayWidth = cropRight - cropLeft + 1;
1900 displayHeight = cropBottom - cropTop + 1;
1901
1902 ALOGV("Video output format changed to %d x %d "
1903 "(crop: %d x %d @ (%d, %d))",
1904 width, height,
1905 displayWidth,
1906 displayHeight,
1907 cropLeft, cropTop);
1908 } else {
1909 CHECK(inputFormat->findInt32("width", &displayWidth));
1910 CHECK(inputFormat->findInt32("height", &displayHeight));
1911
1912 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1913 }
1914
1915 // Take into account sample aspect ratio if necessary:
1916 int32_t sarWidth, sarHeight;
1917 if (inputFormat->findInt32("sar-width", &sarWidth)
Wei Jia095bc252017-01-27 10:16:16 -08001918 && inputFormat->findInt32("sar-height", &sarHeight)
1919 && sarWidth > 0 && sarHeight > 0) {
Chong Zhangced1c2f2014-08-08 15:22:35 -07001920 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1921
1922 displayWidth = (displayWidth * sarWidth) / sarHeight;
1923
1924 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
Wei Jiadf6c6af2016-09-29 11:27:15 -07001925 } else {
1926 int32_t width, height;
1927 if (inputFormat->findInt32("display-width", &width)
1928 && inputFormat->findInt32("display-height", &height)
1929 && width > 0 && height > 0
1930 && displayWidth > 0 && displayHeight > 0) {
1931 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
1932 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
1933 } else {
1934 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
1935 }
1936 ALOGV("Video display width and height are overridden to %d x %d",
1937 displayWidth, displayHeight);
1938 }
Chong Zhangced1c2f2014-08-08 15:22:35 -07001939 }
1940
1941 int32_t rotationDegrees;
1942 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1943 rotationDegrees = 0;
1944 }
1945
1946 if (rotationDegrees == 90 || rotationDegrees == 270) {
1947 int32_t tmp = displayWidth;
1948 displayWidth = displayHeight;
1949 displayHeight = tmp;
1950 }
1951
1952 notifyListener(
1953 MEDIA_SET_VIDEO_SIZE,
1954 displayWidth,
1955 displayHeight);
1956}
1957
Chong Zhangdcb89b32013-08-06 09:44:47 -07001958void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001959 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001960 return;
1961 }
1962
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001963 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001964
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001965 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001966 return;
1967 }
1968
Chong Zhangdcb89b32013-08-06 09:44:47 -07001969 driver->notifyListener(msg, ext1, ext2, in);
Andreas Huberf9334412010-12-15 15:17:42 -08001970}
1971
Chong Zhang7137ec72014-11-12 16:41:05 -08001972void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber14f76722013-01-15 09:04:18 -08001973 ALOGV("[%s] flushDecoder needShutdown=%d",
1974 audio ? "audio" : "video", needShutdown);
1975
Chong Zhang7137ec72014-11-12 16:41:05 -08001976 const sp<DecoderBase> &decoder = getDecoder(audio);
Lajos Molnar87603c02014-08-20 19:25:30 -07001977 if (decoder == NULL) {
Steve Blockdf64d152012-01-04 20:05:49 +00001978 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001979 audio ? "audio" : "video");
Lajos Molnar87603c02014-08-20 19:25:30 -07001980 return;
Andreas Huber6e3d3112011-11-28 12:36:11 -08001981 }
1982
Andreas Huber1aef2112011-01-04 14:01:29 -08001983 // Make sure we don't continue to scan sources until we finish flushing.
1984 ++mScanSourcesGeneration;
Chong Zhang3b032b32015-04-17 15:49:06 -07001985 if (mScanSourcesPending) {
Toshikazu Saitocbcbb792015-09-15 14:53:01 +09001986 if (!needShutdown) {
1987 mDeferredActions.push_back(
1988 new SimpleAction(&NuPlayer::performScanSources));
1989 }
Chong Zhang3b032b32015-04-17 15:49:06 -07001990 mScanSourcesPending = false;
1991 }
Andreas Huber1aef2112011-01-04 14:01:29 -08001992
Chong Zhang7137ec72014-11-12 16:41:05 -08001993 decoder->signalFlush();
Andreas Huber1aef2112011-01-04 14:01:29 -08001994
1995 FlushStatus newStatus =
1996 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1997
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001998 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
Andy Hung8d121d42014-10-03 09:53:53 -07001999 mFlushComplete[audio][true /* isDecoder */] = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08002000 if (audio) {
Wei Jia53904f32014-07-29 10:22:53 -07002001 ALOGE_IF(mFlushingAudio != NONE,
2002 "audio flushDecoder() is called in state %d", mFlushingAudio);
Andreas Huber1aef2112011-01-04 14:01:29 -08002003 mFlushingAudio = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08002004 } else {
Wei Jia53904f32014-07-29 10:22:53 -07002005 ALOGE_IF(mFlushingVideo != NONE,
2006 "video flushDecoder() is called in state %d", mFlushingVideo);
Andreas Huber1aef2112011-01-04 14:01:29 -08002007 mFlushingVideo = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08002008 }
2009}
2010
Chong Zhangced1c2f2014-08-08 15:22:35 -07002011void NuPlayer::queueDecoderShutdown(
2012 bool audio, bool video, const sp<AMessage> &reply) {
2013 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Huber84066782011-08-16 09:34:26 -07002014
Chong Zhangced1c2f2014-08-08 15:22:35 -07002015 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07002016 new FlushDecoderAction(
2017 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2018 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
Andreas Huber84066782011-08-16 09:34:26 -07002019
Chong Zhangced1c2f2014-08-08 15:22:35 -07002020 mDeferredActions.push_back(
2021 new SimpleAction(&NuPlayer::performScanSources));
Andreas Huber84066782011-08-16 09:34:26 -07002022
Chong Zhangced1c2f2014-08-08 15:22:35 -07002023 mDeferredActions.push_back(new PostMessageAction(reply));
2024
2025 processDeferredActions();
Andreas Huber84066782011-08-16 09:34:26 -07002026}
2027
James Dong0d268a32012-08-31 12:18:27 -07002028status_t NuPlayer::setVideoScalingMode(int32_t mode) {
2029 mVideoScalingMode = mode;
Lajos Molnar1de1e252015-04-30 18:18:34 -07002030 if (mSurface != NULL) {
2031 status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
James Dong0d268a32012-08-31 12:18:27 -07002032 if (ret != OK) {
2033 ALOGE("Failed to set scaling mode (%d): %s",
2034 -ret, strerror(-ret));
2035 return ret;
2036 }
2037 }
2038 return OK;
2039}
2040
Chong Zhangdcb89b32013-08-06 09:44:47 -07002041status_t NuPlayer::getTrackInfo(Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002042 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002043 msg->setPointer("reply", reply);
2044
2045 sp<AMessage> response;
2046 status_t err = msg->postAndAwaitResponse(&response);
2047 return err;
2048}
2049
Robert Shih7c4f0d72014-07-09 18:53:31 -07002050status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002051 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
Robert Shih7c4f0d72014-07-09 18:53:31 -07002052 msg->setPointer("reply", reply);
2053 msg->setInt32("type", type);
2054
2055 sp<AMessage> response;
2056 status_t err = msg->postAndAwaitResponse(&response);
2057 if (err == OK && response != NULL) {
2058 CHECK(response->findInt32("err", &err));
2059 }
2060 return err;
2061}
2062
Robert Shih6ffb1fd2014-10-29 16:24:32 -07002063status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002064 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002065 msg->setSize("trackIndex", trackIndex);
2066 msg->setInt32("select", select);
Robert Shih6ffb1fd2014-10-29 16:24:32 -07002067 msg->setInt64("timeUs", timeUs);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002068
2069 sp<AMessage> response;
2070 status_t err = msg->postAndAwaitResponse(&response);
2071
Chong Zhang404fced2014-06-11 14:45:31 -07002072 if (err != OK) {
2073 return err;
2074 }
2075
2076 if (!response->findInt32("err", &err)) {
2077 err = OK;
2078 }
2079
Chong Zhangdcb89b32013-08-06 09:44:47 -07002080 return err;
2081}
2082
Ronghua Wua73d9e02014-10-08 15:13:29 -07002083status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
2084 sp<Renderer> renderer = mRenderer;
2085 if (renderer == NULL) {
2086 return NO_INIT;
2087 }
2088
2089 return renderer->getCurrentPosition(mediaUs);
2090}
2091
Praveen Chavane1e5d7a2015-05-19 19:09:48 -07002092void NuPlayer::getStats(Vector<sp<AMessage> > *mTrackStats) {
2093 CHECK(mTrackStats != NULL);
2094
2095 mTrackStats->clear();
2096 if (mVideoDecoder != NULL) {
2097 mTrackStats->push_back(mVideoDecoder->getStats());
2098 }
2099 if (mAudioDecoder != NULL) {
2100 mTrackStats->push_back(mAudioDecoder->getStats());
Chong Zhang7137ec72014-11-12 16:41:05 -08002101 }
Ronghua Wua73d9e02014-10-08 15:13:29 -07002102}
2103
Marco Nelissenf0b72b52014-09-16 15:43:44 -07002104sp<MetaData> NuPlayer::getFileMeta() {
2105 return mSource->getFileFormatMeta();
2106}
2107
Ronghua Wuc8a70d32015-04-29 16:26:34 -07002108float NuPlayer::getFrameRate() {
2109 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2110 if (meta == NULL) {
2111 return 0;
2112 }
2113 int32_t rate;
2114 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2115 // fall back to try file meta
2116 sp<MetaData> fileMeta = getFileMeta();
2117 if (fileMeta == NULL) {
2118 ALOGW("source has video meta but not file meta");
2119 return -1;
2120 }
2121 int32_t fileMetaRate;
2122 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2123 return -1;
2124 }
2125 return fileMetaRate;
2126 }
2127 return rate;
2128}
2129
Andreas Huberb7c8e912012-11-27 15:02:53 -08002130void NuPlayer::schedulePollDuration() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002131 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
Andreas Huberb7c8e912012-11-27 15:02:53 -08002132 msg->setInt32("generation", mPollDurationGeneration);
2133 msg->post();
2134}
2135
2136void NuPlayer::cancelPollDuration() {
2137 ++mPollDurationGeneration;
2138}
2139
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002140void NuPlayer::processDeferredActions() {
2141 while (!mDeferredActions.empty()) {
2142 // We won't execute any deferred actions until we're no longer in
2143 // an intermediate state, i.e. one more more decoders are currently
2144 // flushing or shutting down.
2145
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002146 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2147 // We're currently flushing, postpone the reset until that's
2148 // completed.
2149
2150 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2151 mFlushingAudio, mFlushingVideo);
2152
2153 break;
2154 }
2155
2156 sp<Action> action = *mDeferredActions.begin();
2157 mDeferredActions.erase(mDeferredActions.begin());
2158
2159 action->execute(this);
2160 }
2161}
2162
Wei Jiac5de0912016-11-18 10:22:14 -08002163void NuPlayer::performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
2164 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2165 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002166
Andy Hungadf34bf2014-09-03 18:22:22 -07002167 if (mSource == NULL) {
2168 // This happens when reset occurs right before the loop mode
2169 // asynchronously seeks to the start of the stream.
2170 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2171 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2172 mAudioDecoder.get(), mVideoDecoder.get());
2173 return;
2174 }
Robert Shih1a5c8592015-08-04 18:07:44 -07002175 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -08002176 mSource->seekTo(seekTimeUs, mode);
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002177 ++mTimedTextGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002178
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002179 // everything's flushed, continue playback.
2180}
2181
Wei Jiafef808d2014-10-31 17:57:05 -07002182void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2183 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002184
Wei Jiafef808d2014-10-31 17:57:05 -07002185 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2186 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002187 return;
2188 }
2189
Wei Jiafef808d2014-10-31 17:57:05 -07002190 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2191 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002192 }
2193
Wei Jiafef808d2014-10-31 17:57:05 -07002194 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2195 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002196 }
2197}
2198
2199void NuPlayer::performReset() {
2200 ALOGV("performReset");
2201
2202 CHECK(mAudioDecoder == NULL);
2203 CHECK(mVideoDecoder == NULL);
2204
2205 cancelPollDuration();
2206
2207 ++mScanSourcesGeneration;
2208 mScanSourcesPending = false;
2209
Lajos Molnar09524832014-07-17 14:29:51 -07002210 if (mRendererLooper != NULL) {
2211 if (mRenderer != NULL) {
2212 mRendererLooper->unregisterHandler(mRenderer->id());
2213 }
2214 mRendererLooper->stop();
2215 mRendererLooper.clear();
2216 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002217 mRenderer.clear();
Wei Jia57568df2014-09-22 10:16:29 -07002218 ++mRendererGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002219
2220 if (mSource != NULL) {
2221 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08002222
Wei Jiac45a4b22016-04-15 15:30:23 -07002223 Mutex::Autolock autoLock(mSourceLock);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002224 mSource.clear();
2225 }
2226
2227 if (mDriver != NULL) {
2228 sp<NuPlayerDriver> driver = mDriver.promote();
2229 if (driver != NULL) {
2230 driver->notifyResetComplete();
2231 }
2232 }
Andreas Huber57a339c2012-12-03 11:18:00 -08002233
2234 mStarted = false;
Wei Jia8a092d32016-06-03 14:57:24 -07002235 mPrepared = false;
Ronghua Wu64c2d172015-10-07 16:52:19 -07002236 mResetting = false;
Robert Shih0c61a0d2015-07-06 15:09:10 -07002237 mSourceStarted = false;
Hassan Shojaniacefac142017-02-06 21:02:02 -08002238
2239 // Modular DRM
2240 if (mCrypto != NULL) {
2241 // decoders will be flushed before this so their mCrypto would go away on their own
2242 // TODO change to ALOGV
2243 ALOGD("performReset mCrypto: %p (%d)", mCrypto.get(),
2244 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2245 mCrypto.clear();
2246 }
2247 mIsDrmProtected = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002248}
2249
2250void NuPlayer::performScanSources() {
2251 ALOGV("performScanSources");
2252
Andreas Huber57a339c2012-12-03 11:18:00 -08002253 if (!mStarted) {
2254 return;
2255 }
2256
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002257 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2258 postScanSources();
2259 }
2260}
2261
Lajos Molnar1de1e252015-04-30 18:18:34 -07002262void NuPlayer::performSetSurface(const sp<Surface> &surface) {
Andreas Huber57a339c2012-12-03 11:18:00 -08002263 ALOGV("performSetSurface");
2264
Lajos Molnar1de1e252015-04-30 18:18:34 -07002265 mSurface = surface;
Andreas Huber57a339c2012-12-03 11:18:00 -08002266
2267 // XXX - ignore error from setVideoScalingMode for now
2268 setVideoScalingMode(mVideoScalingMode);
Chong Zhang13d6faa2014-08-22 15:35:28 -07002269
2270 if (mDriver != NULL) {
2271 sp<NuPlayerDriver> driver = mDriver.promote();
2272 if (driver != NULL) {
2273 driver->notifySetSurfaceComplete();
2274 }
2275 }
Andreas Huber57a339c2012-12-03 11:18:00 -08002276}
2277
Chong Zhangf8d71772014-11-26 15:08:34 -08002278void NuPlayer::performResumeDecoders(bool needNotify) {
2279 if (needNotify) {
2280 mResumePending = true;
2281 if (mVideoDecoder == NULL) {
2282 // if audio-only, we can notify seek complete now,
2283 // as the resume operation will be relatively fast.
2284 finishResume();
2285 }
2286 }
2287
Chong Zhang7137ec72014-11-12 16:41:05 -08002288 if (mVideoDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08002289 // When there is continuous seek, MediaPlayer will cache the seek
2290 // position, and send down new seek request when previous seek is
2291 // complete. Let's wait for at least one video output frame before
2292 // notifying seek complete, so that the video thumbnail gets updated
2293 // when seekbar is dragged.
2294 mVideoDecoder->signalResume(needNotify);
Chong Zhang7137ec72014-11-12 16:41:05 -08002295 }
2296
2297 if (mAudioDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08002298 mAudioDecoder->signalResume(false /* needNotify */);
2299 }
2300}
2301
2302void NuPlayer::finishResume() {
2303 if (mResumePending) {
2304 mResumePending = false;
Wei Jia1061c9c2015-05-19 16:02:17 -07002305 notifyDriverSeekComplete();
2306 }
2307}
2308
2309void NuPlayer::notifyDriverSeekComplete() {
2310 if (mDriver != NULL) {
2311 sp<NuPlayerDriver> driver = mDriver.promote();
2312 if (driver != NULL) {
2313 driver->notifySeekComplete();
Chong Zhangf8d71772014-11-26 15:08:34 -08002314 }
Chong Zhang7137ec72014-11-12 16:41:05 -08002315 }
2316}
2317
Andreas Huber9575c962013-02-05 13:59:56 -08002318void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
2319 int32_t what;
2320 CHECK(msg->findInt32("what", &what));
2321
2322 switch (what) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002323 case Source::kWhatInstantiateSecureDecoders:
2324 {
2325 if (mSource == NULL) {
2326 // This is a stale notification from a source that was
2327 // asynchronously preparing when the client called reset().
2328 // We handled the reset, the source is gone.
2329 break;
2330 }
2331
2332 sp<AMessage> reply;
2333 CHECK(msg->findMessage("reply", &reply));
2334 status_t err = onInstantiateSecureDecoders();
2335 reply->setInt32("err", err);
2336 reply->post();
2337 break;
2338 }
2339
Andreas Huber9575c962013-02-05 13:59:56 -08002340 case Source::kWhatPrepared:
2341 {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002342 ALOGV("NuPlayer::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
Andreas Huberb5f28d42013-04-25 15:11:19 -07002343 if (mSource == NULL) {
2344 // This is a stale notification from a source that was
2345 // asynchronously preparing when the client called reset().
2346 // We handled the reset, the source is gone.
2347 break;
2348 }
2349
Andreas Huberec0c5972013-02-05 14:47:13 -08002350 int32_t err;
2351 CHECK(msg->findInt32("err", &err));
2352
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002353 if (err != OK) {
2354 // shut down potential secure codecs in case client never calls reset
2355 mDeferredActions.push_back(
2356 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2357 FLUSH_CMD_SHUTDOWN /* video */));
2358 processDeferredActions();
Wei Jia8a092d32016-06-03 14:57:24 -07002359 } else {
2360 mPrepared = true;
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002361 }
2362
Andreas Huber9575c962013-02-05 13:59:56 -08002363 sp<NuPlayerDriver> driver = mDriver.promote();
2364 if (driver != NULL) {
Marco Nelissendd114d12014-05-28 15:23:14 -07002365 // notify duration first, so that it's definitely set when
2366 // the app received the "prepare complete" callback.
2367 int64_t durationUs;
2368 if (mSource->getDuration(&durationUs) == OK) {
2369 driver->notifyDuration(durationUs);
2370 }
Andreas Huberec0c5972013-02-05 14:47:13 -08002371 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08002372 }
Andreas Huber99759402013-04-01 14:28:31 -07002373
Andreas Huber9575c962013-02-05 13:59:56 -08002374 break;
2375 }
2376
Hassan Shojaniacefac142017-02-06 21:02:02 -08002377 // Modular DRM
2378 case Source::kWhatDrmInfo:
2379 {
2380 Parcel parcel;
2381 sp<ABuffer> drmInfo;
2382 CHECK(msg->findBuffer("drmInfo", &drmInfo));
2383 parcel.setData(drmInfo->data(), drmInfo->size());
2384
2385 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA_DRM_INFO drmInfo: %p parcel size: %zu",
2386 drmInfo.get(), parcel.dataSize());
2387
2388 notifyListener(MEDIA_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
2389
2390 break;
2391 }
2392
Andreas Huber9575c962013-02-05 13:59:56 -08002393 case Source::kWhatFlagsChanged:
2394 {
2395 uint32_t flags;
2396 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2397
Chong Zhang4b7069d2013-09-11 12:52:43 -07002398 sp<NuPlayerDriver> driver = mDriver.promote();
2399 if (driver != NULL) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002400
2401 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2402 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2403 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2404 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2405 (flags & Source::FLAG_CAN_PAUSE) != 0,
2406 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2407 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2408 (flags & Source::FLAG_CAN_SEEK) != 0,
2409 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2410 (flags & Source::FLAG_SECURE) != 0,
2411 (flags & Source::FLAG_PROTECTED) != 0);
2412
Wei Jia895651b2014-12-10 17:31:52 -08002413 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
2414 driver->notifyListener(
2415 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
2416 }
Chong Zhang4b7069d2013-09-11 12:52:43 -07002417 driver->notifyFlagsChanged(flags);
2418 }
2419
Andreas Huber9575c962013-02-05 13:59:56 -08002420 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2421 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2422 cancelPollDuration();
2423 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2424 && (flags & Source::FLAG_DYNAMIC_DURATION)
2425 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2426 schedulePollDuration();
2427 }
2428
2429 mSourceFlags = flags;
2430 break;
2431 }
2432
2433 case Source::kWhatVideoSizeChanged:
2434 {
Chong Zhangced1c2f2014-08-08 15:22:35 -07002435 sp<AMessage> format;
2436 CHECK(msg->findMessage("format", &format));
Andreas Huber9575c962013-02-05 13:59:56 -08002437
Chong Zhangced1c2f2014-08-08 15:22:35 -07002438 updateVideoSize(format);
Andreas Huber9575c962013-02-05 13:59:56 -08002439 break;
2440 }
2441
Chong Zhang2a3cc9a2014-08-21 17:48:26 -07002442 case Source::kWhatBufferingUpdate:
2443 {
2444 int32_t percentage;
2445 CHECK(msg->findInt32("percentage", &percentage));
2446
2447 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
2448 break;
2449 }
2450
Chong Zhangefbb6192015-01-30 17:13:27 -08002451 case Source::kWhatPauseOnBufferingStart:
2452 {
2453 // ignore if not playing
Chong Zhang8a048332015-05-06 15:16:28 -07002454 if (mStarted) {
Chong Zhangefbb6192015-01-30 17:13:27 -08002455 ALOGI("buffer low, pausing...");
2456
Chong Zhang8a048332015-05-06 15:16:28 -07002457 mPausedForBuffering = true;
Chong Zhangefbb6192015-01-30 17:13:27 -08002458 onPause();
2459 }
Wei Jiabfe82072016-05-20 09:21:50 -07002460 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
Roger Jönssonb50e83e2013-01-21 16:26:41 +01002461 break;
2462 }
2463
Chong Zhangefbb6192015-01-30 17:13:27 -08002464 case Source::kWhatResumeOnBufferingEnd:
2465 {
2466 // ignore if not playing
Chong Zhang8a048332015-05-06 15:16:28 -07002467 if (mStarted) {
Chong Zhangefbb6192015-01-30 17:13:27 -08002468 ALOGI("buffer ready, resuming...");
2469
Chong Zhang8a048332015-05-06 15:16:28 -07002470 mPausedForBuffering = false;
2471
2472 // do not resume yet if client didn't unpause
2473 if (!mPausedByClient) {
2474 onResume();
2475 }
Chong Zhangefbb6192015-01-30 17:13:27 -08002476 }
Wei Jia3bed45a2016-02-17 11:06:47 -08002477 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
Roger Jönssonb50e83e2013-01-21 16:26:41 +01002478 break;
2479 }
2480
Chong Zhangefbb6192015-01-30 17:13:27 -08002481 case Source::kWhatCacheStats:
2482 {
2483 int32_t kbps;
2484 CHECK(msg->findInt32("bandwidth", &kbps));
2485
2486 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
2487 break;
2488 }
2489
Chong Zhangdcb89b32013-08-06 09:44:47 -07002490 case Source::kWhatSubtitleData:
2491 {
2492 sp<ABuffer> buffer;
2493 CHECK(msg->findBuffer("buffer", &buffer));
2494
Chong Zhang404fced2014-06-11 14:45:31 -07002495 sendSubtitleData(buffer, 0 /* baseIndex */);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002496 break;
2497 }
2498
Robert Shih08528432015-04-08 09:06:54 -07002499 case Source::kWhatTimedMetaData:
2500 {
2501 sp<ABuffer> buffer;
2502 if (!msg->findBuffer("buffer", &buffer)) {
2503 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2504 } else {
2505 sendTimedMetaData(buffer);
2506 }
2507 break;
2508 }
2509
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002510 case Source::kWhatTimedTextData:
2511 {
2512 int32_t generation;
2513 if (msg->findInt32("generation", &generation)
2514 && generation != mTimedTextGeneration) {
2515 break;
2516 }
2517
2518 sp<ABuffer> buffer;
2519 CHECK(msg->findBuffer("buffer", &buffer));
2520
2521 sp<NuPlayerDriver> driver = mDriver.promote();
2522 if (driver == NULL) {
2523 break;
2524 }
2525
2526 int posMs;
2527 int64_t timeUs, posUs;
2528 driver->getCurrentPosition(&posMs);
Patrik2 Carlsson24d484b2015-01-27 16:49:45 +01002529 posUs = (int64_t) posMs * 1000ll;
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002530 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2531
2532 if (posUs < timeUs) {
2533 if (!msg->findInt32("generation", &generation)) {
2534 msg->setInt32("generation", mTimedTextGeneration);
2535 }
2536 msg->post(timeUs - posUs);
2537 } else {
2538 sendTimedTextData(buffer);
2539 }
2540 break;
2541 }
2542
Andreas Huber14f76722013-01-15 09:04:18 -08002543 case Source::kWhatQueueDecoderShutdown:
2544 {
2545 int32_t audio, video;
2546 CHECK(msg->findInt32("audio", &audio));
2547 CHECK(msg->findInt32("video", &video));
2548
2549 sp<AMessage> reply;
2550 CHECK(msg->findMessage("reply", &reply));
2551
2552 queueDecoderShutdown(audio, video, reply);
2553 break;
2554 }
2555
Ronghua Wu80276872014-08-28 15:50:29 -07002556 case Source::kWhatDrmNoLicense:
2557 {
2558 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2559 break;
2560 }
2561
Andreas Huber9575c962013-02-05 13:59:56 -08002562 default:
2563 TRESPASS();
2564 }
2565}
2566
Chong Zhanga7fa1d92014-06-11 14:49:23 -07002567void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2568 int32_t what;
2569 CHECK(msg->findInt32("what", &what));
2570
2571 switch (what) {
2572 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2573 {
2574 sp<ABuffer> buffer;
2575 CHECK(msg->findBuffer("buffer", &buffer));
2576
2577 size_t inbandTracks = 0;
2578 if (mSource != NULL) {
2579 inbandTracks = mSource->getTrackCount();
2580 }
2581
2582 sendSubtitleData(buffer, inbandTracks);
2583 break;
2584 }
2585
2586 case NuPlayer::CCDecoder::kWhatTrackAdded:
2587 {
2588 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2589
2590 break;
2591 }
2592
2593 default:
2594 TRESPASS();
2595 }
2596
2597
2598}
2599
Chong Zhang404fced2014-06-11 14:45:31 -07002600void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2601 int32_t trackIndex;
2602 int64_t timeUs, durationUs;
2603 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
2604 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2605 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2606
2607 Parcel in;
2608 in.writeInt32(trackIndex + baseIndex);
2609 in.writeInt64(timeUs);
2610 in.writeInt64(durationUs);
2611 in.writeInt32(buffer->size());
2612 in.writeInt32(buffer->size());
2613 in.write(buffer->data(), buffer->size());
2614
2615 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2616}
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002617
Robert Shih08528432015-04-08 09:06:54 -07002618void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
2619 int64_t timeUs;
2620 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2621
2622 Parcel in;
2623 in.writeInt64(timeUs);
2624 in.writeInt32(buffer->size());
2625 in.writeInt32(buffer->size());
2626 in.write(buffer->data(), buffer->size());
2627
2628 notifyListener(MEDIA_META_DATA, 0, 0, &in);
2629}
2630
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002631void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2632 const void *data;
2633 size_t size = 0;
2634 int64_t timeUs;
Marco Nelissen55e2f4c2015-09-04 15:57:15 -07002635 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002636
2637 AString mime;
2638 CHECK(buffer->meta()->findString("mime", &mime));
2639 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2640
2641 data = buffer->data();
2642 size = buffer->size();
2643
2644 Parcel parcel;
2645 if (size > 0) {
2646 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
Marco Nelissen55e2f4c2015-09-04 15:57:15 -07002647 int32_t global = 0;
2648 if (buffer->meta()->findInt32("global", &global) && global) {
2649 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2650 } else {
2651 flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2652 }
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002653 TextDescriptions::getParcelOfDescriptions(
2654 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2655 }
2656
2657 if ((parcel.dataSize() > 0)) {
2658 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2659 } else { // send an empty timed text
2660 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2661 }
2662}
Hassan Shojaniacefac142017-02-06 21:02:02 -08002663
Hassan Shojaniaff63de72017-04-26 15:10:42 -07002664const char *NuPlayer::getDataSourceType() {
2665 switch (mDataSourceType) {
2666 case DATA_SOURCE_TYPE_HTTP_LIVE:
2667 return "HTTPLive";
2668
2669 case DATA_SOURCE_TYPE_RTSP:
2670 return "RTSP";
2671
2672 case DATA_SOURCE_TYPE_GENERIC_URL:
2673 return "GenURL";
2674
2675 case DATA_SOURCE_TYPE_GENERIC_FD:
2676 return "GenFD";
2677
2678 case DATA_SOURCE_TYPE_MEDIA:
2679 return "Media";
2680
2681 case DATA_SOURCE_TYPE_STREAM:
2682 return "Stream";
2683
2684 case DATA_SOURCE_TYPE_NONE:
2685 default:
2686 return "None";
2687 }
2688 }
2689
Hassan Shojaniacefac142017-02-06 21:02:02 -08002690// Modular DRM begin
2691status_t NuPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
2692{
2693 ALOGV("prepareDrm ");
2694
2695 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
2696 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
2697 // synchronous call so just passing the address but with local copies of "const" args
2698 uint8_t UUID[16];
2699 memcpy(UUID, uuid, sizeof(UUID));
2700 Vector<uint8_t> sessionId = drmSessionId;
2701 msg->setPointer("uuid", (void*)UUID);
2702 msg->setPointer("drmSessionId", (void*)&sessionId);
2703
2704 sp<AMessage> response;
2705 status_t status = msg->postAndAwaitResponse(&response);
2706
2707 if (status == OK && response != NULL) {
2708 CHECK(response->findInt32("status", &status));
2709 ALOGV("prepareDrm ret: %d ", status);
2710 } else {
2711 ALOGE("prepareDrm err: %d", status);
2712 }
2713
2714 return status;
2715}
2716
2717status_t NuPlayer::releaseDrm()
2718{
2719 ALOGV("releaseDrm ");
2720
2721 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
2722
2723 sp<AMessage> response;
2724 status_t status = msg->postAndAwaitResponse(&response);
2725
2726 if (status == OK && response != NULL) {
2727 CHECK(response->findInt32("status", &status));
2728 ALOGV("releaseDrm ret: %d ", status);
2729 } else {
2730 ALOGE("releaseDrm err: %d", status);
2731 }
2732
2733 return status;
2734}
2735
2736status_t NuPlayer::onPrepareDrm(const sp<AMessage> &msg)
2737{
2738 // TODO change to ALOGV
2739 ALOGD("onPrepareDrm ");
2740
2741 status_t status = INVALID_OPERATION;
2742 if (mSource == NULL) {
2743 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
2744 return status;
2745 }
2746
2747 uint8_t *uuid;
2748 Vector<uint8_t> *drmSessionId;
2749 CHECK(msg->findPointer("uuid", (void**)&uuid));
2750 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
2751
2752 status = OK;
2753 sp<ICrypto> crypto = NULL;
2754
2755 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
2756 if (crypto == NULL) {
2757 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
2758 return status;
2759 }
2760 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
2761
2762 if (mCrypto != NULL) {
2763 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p (%d)",
2764 mCrypto.get(), mCrypto->getStrongCount());
2765 mCrypto.clear();
2766 }
2767
2768 mCrypto = crypto;
2769 mIsDrmProtected = true;
2770 // TODO change to ALOGV
2771 ALOGD("onPrepareDrm: mCrypto: %p (%d)", mCrypto.get(),
2772 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2773
2774 return status;
2775}
2776
2777status_t NuPlayer::onReleaseDrm()
2778{
2779 // TODO change to ALOGV
2780 ALOGD("onReleaseDrm ");
2781
Hassan Shojania50b20c92017-02-16 18:28:58 -08002782 if (!mIsDrmProtected) {
2783 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
2784 }
2785
2786 mIsDrmProtected = false;
Hassan Shojaniacefac142017-02-06 21:02:02 -08002787
2788 status_t status;
2789 if (mCrypto != NULL) {
2790 status=OK;
2791 // first making sure the codecs have released their crypto reference
2792 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
2793 if (videoDecoder != NULL) {
2794 status = videoDecoder->releaseCrypto();
2795 ALOGV("onReleaseDrm: video decoder ret: %d", status);
2796 }
2797
2798 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
2799 if (audioDecoder != NULL) {
2800 status_t status_audio = audioDecoder->releaseCrypto();
2801 if (status == OK) { // otherwise, returning the first error
2802 status = status_audio;
2803 }
2804 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
2805 }
2806
2807 // TODO change to ALOGV
2808 ALOGD("onReleaseDrm: mCrypto: %p (%d)", mCrypto.get(),
2809 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2810 mCrypto.clear();
2811 } else { // mCrypto == NULL
2812 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
2813 status = INVALID_OPERATION;
2814 }
2815
2816 return status;
2817}
2818// Modular DRM end
Andreas Huberb5f25f02013-02-05 10:14:26 -08002819////////////////////////////////////////////////////////////////////////////////
2820
Chong Zhangced1c2f2014-08-08 15:22:35 -07002821sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
2822 sp<MetaData> meta = getFormatMeta(audio);
2823
2824 if (meta == NULL) {
2825 return NULL;
2826 }
2827
2828 sp<AMessage> msg = new AMessage;
2829
2830 if(convertMetaDataToMessage(meta, &msg) == OK) {
2831 return msg;
2832 }
2833 return NULL;
2834}
2835
Andreas Huber9575c962013-02-05 13:59:56 -08002836void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
2837 sp<AMessage> notify = dupNotify();
2838 notify->setInt32("what", kWhatFlagsChanged);
2839 notify->setInt32("flags", flags);
2840 notify->post();
2841}
2842
Chong Zhangced1c2f2014-08-08 15:22:35 -07002843void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
Andreas Huber9575c962013-02-05 13:59:56 -08002844 sp<AMessage> notify = dupNotify();
2845 notify->setInt32("what", kWhatVideoSizeChanged);
Chong Zhangced1c2f2014-08-08 15:22:35 -07002846 notify->setMessage("format", format);
Andreas Huber9575c962013-02-05 13:59:56 -08002847 notify->post();
2848}
2849
Andreas Huberec0c5972013-02-05 14:47:13 -08002850void NuPlayer::Source::notifyPrepared(status_t err) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002851 ALOGV("Source::notifyPrepared %d", err);
Andreas Huber9575c962013-02-05 13:59:56 -08002852 sp<AMessage> notify = dupNotify();
2853 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08002854 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08002855 notify->post();
2856}
2857
Hassan Shojaniacefac142017-02-06 21:02:02 -08002858void NuPlayer::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
2859{
2860 ALOGV("Source::notifyDrmInfo");
2861
2862 sp<AMessage> notify = dupNotify();
2863 notify->setInt32("what", kWhatDrmInfo);
2864 notify->setBuffer("drmInfo", drmInfoBuffer);
2865
2866 notify->post();
2867}
2868
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002869void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
2870 sp<AMessage> notify = dupNotify();
2871 notify->setInt32("what", kWhatInstantiateSecureDecoders);
2872 notify->setMessage("reply", reply);
2873 notify->post();
2874}
2875
Andreas Huber84333e02014-02-07 15:36:10 -08002876void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
Andreas Huberb5f25f02013-02-05 10:14:26 -08002877 TRESPASS();
2878}
2879
Andreas Huberf9334412010-12-15 15:17:42 -08002880} // namespace android