blob: c07e34c10e5e4f1983f209710ae64b5162caa650 [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"
Byeongjo Park28225ab2019-01-24 20:31:19 +090034#include "RTPSource.h"
Andreas Huber2bfdd422011-10-11 15:24:07 -070035#include "RTSPSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080036#include "StreamingSource.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070037#include "GenericSource.h"
Ray Essick64050722022-01-14 13:46:33 -080038#include <timedtext/TextDescriptions.h>
Andreas Huberf9334412010-12-15 15:17:42 -080039
Lajos Molnard9fd6312014-11-06 11:00:00 -080040#include <cutils/properties.h>
41
Lajos Molnar3a474aa2015-04-24 17:10:07 -070042#include <media/AudioResamplerPublic.h>
43#include <media/AVSyncSettings.h>
Wonsik Kim7e34bf52016-08-23 00:09:18 +090044#include <media/MediaCodecBuffer.h>
Lajos Molnar3a474aa2015-04-24 17:10:07 -070045
Andreas Huber3831a062010-12-21 10:22:33 -080046#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080047#include <media/stagefright/foundation/ABuffer.h>
48#include <media/stagefright/foundation/ADebug.h>
49#include <media/stagefright/foundation/AMessage.h>
Dongwon Kangd91dc5a2017-10-10 00:07:09 -070050#include <media/stagefright/foundation/avc_utils.h>
Lajos Molnar09524832014-07-17 14:29:51 -070051#include <media/stagefright/MediaBuffer.h>
Wei Jia0a68f662017-08-30 18:01:26 -070052#include <media/stagefright/MediaClock.h>
Andreas Huber3fe62152011-09-16 15:09:22 -070053#include <media/stagefright/MediaDefs.h>
Andreas Huberf9334412010-12-15 15:17:42 -080054#include <media/stagefright/MediaErrors.h>
55#include <media/stagefright/MetaData.h>
Lajos Molnar1de1e252015-04-30 18:18:34 -070056
Ray Essick64050722022-01-14 13:46:33 -080057#include <mpeg2ts/ATSParser.h>
58
Andy McFadden8ba01022012-12-18 09:46:54 -080059#include <gui/IGraphicBufferProducer.h>
Lajos Molnar1de1e252015-04-30 18:18:34 -070060#include <gui/Surface.h>
Andreas Huberf9334412010-12-15 15:17:42 -080061
Andreas Huber3fe62152011-09-16 15:09:22 -070062
Andreas Huber84066782011-08-16 09:34:26 -070063#include "ESDS.h"
64#include <media/stagefright/Utils.h>
65
Andreas Huberf9334412010-12-15 15:17:42 -080066namespace android {
67
Andreas Hubera1f8ab02012-11-30 10:53:22 -080068struct NuPlayer::Action : public RefBase {
69 Action() {}
70
71 virtual void execute(NuPlayer *player) = 0;
72
73private:
74 DISALLOW_EVIL_CONSTRUCTORS(Action);
75};
76
77struct NuPlayer::SeekAction : public Action {
Wei Jiac5de0912016-11-18 10:22:14 -080078 explicit SeekAction(int64_t seekTimeUs, MediaPlayerSeekMode mode)
Wei Jia14486822016-11-02 17:51:30 -070079 : mSeekTimeUs(seekTimeUs),
Wei Jiac5de0912016-11-18 10:22:14 -080080 mMode(mode) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -080081 }
82
83 virtual void execute(NuPlayer *player) {
Wei Jiac5de0912016-11-18 10:22:14 -080084 player->performSeek(mSeekTimeUs, mMode);
Andreas Hubera1f8ab02012-11-30 10:53:22 -080085 }
86
87private:
88 int64_t mSeekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -080089 MediaPlayerSeekMode mMode;
Andreas Hubera1f8ab02012-11-30 10:53:22 -080090
91 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
92};
93
Chong Zhangf8d71772014-11-26 15:08:34 -080094struct NuPlayer::ResumeDecoderAction : public Action {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070095 explicit ResumeDecoderAction(bool needNotify)
Chong Zhangf8d71772014-11-26 15:08:34 -080096 : mNeedNotify(needNotify) {
97 }
98
99 virtual void execute(NuPlayer *player) {
100 player->performResumeDecoders(mNeedNotify);
101 }
102
103private:
104 bool mNeedNotify;
105
106 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
107};
108
Andreas Huber57a339c2012-12-03 11:18:00 -0800109struct NuPlayer::SetSurfaceAction : public Action {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700110 explicit SetSurfaceAction(const sp<Surface> &surface)
Lajos Molnar1de1e252015-04-30 18:18:34 -0700111 : mSurface(surface) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800112 }
113
114 virtual void execute(NuPlayer *player) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700115 player->performSetSurface(mSurface);
Andreas Huber57a339c2012-12-03 11:18:00 -0800116 }
117
118private:
Lajos Molnar1de1e252015-04-30 18:18:34 -0700119 sp<Surface> mSurface;
Andreas Huber57a339c2012-12-03 11:18:00 -0800120
121 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
122};
123
Wei Jiafef808d2014-10-31 17:57:05 -0700124struct NuPlayer::FlushDecoderAction : public Action {
125 FlushDecoderAction(FlushCommand audio, FlushCommand video)
Andreas Huber14f76722013-01-15 09:04:18 -0800126 : mAudio(audio),
127 mVideo(video) {
128 }
129
130 virtual void execute(NuPlayer *player) {
Wei Jiafef808d2014-10-31 17:57:05 -0700131 player->performDecoderFlush(mAudio, mVideo);
Andreas Huber14f76722013-01-15 09:04:18 -0800132 }
133
134private:
Wei Jiafef808d2014-10-31 17:57:05 -0700135 FlushCommand mAudio;
136 FlushCommand mVideo;
Andreas Huber14f76722013-01-15 09:04:18 -0800137
Wei Jiafef808d2014-10-31 17:57:05 -0700138 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
Andreas Huber14f76722013-01-15 09:04:18 -0800139};
140
141struct NuPlayer::PostMessageAction : public Action {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700142 explicit PostMessageAction(const sp<AMessage> &msg)
Andreas Huber14f76722013-01-15 09:04:18 -0800143 : mMessage(msg) {
144 }
145
146 virtual void execute(NuPlayer *) {
147 mMessage->post();
148 }
149
150private:
151 sp<AMessage> mMessage;
152
153 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
154};
155
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800156// Use this if there's no state necessary to save in order to execute
157// the action.
158struct NuPlayer::SimpleAction : public Action {
159 typedef void (NuPlayer::*ActionFunc)();
160
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700161 explicit SimpleAction(ActionFunc func)
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800162 : mFunc(func) {
163 }
164
165 virtual void execute(NuPlayer *player) {
166 (player->*mFunc)();
167 }
168
169private:
170 ActionFunc mFunc;
171
172 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
173};
174
Andreas Huberf9334412010-12-15 15:17:42 -0800175////////////////////////////////////////////////////////////////////////////////
176
Wei Jia0a68f662017-08-30 18:01:26 -0700177NuPlayer::NuPlayer(pid_t pid, const sp<MediaClock> &mediaClock)
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700178 : mUIDValid(false),
Ronghua Wu68845c12015-07-21 09:50:48 -0700179 mPID(pid),
Wei Jia0a68f662017-08-30 18:01:26 -0700180 mMediaClock(mediaClock),
Andreas Huber9575c962013-02-05 13:59:56 -0800181 mSourceFlags(0),
Wei Jiabc2fb722014-07-08 16:37:57 -0700182 mOffloadAudio(false),
Wei Jia88703c32014-08-06 11:24:07 -0700183 mAudioDecoderGeneration(0),
184 mVideoDecoderGeneration(0),
Wei Jia57568df2014-09-22 10:16:29 -0700185 mRendererGeneration(0),
Ray Essick0d98c182017-11-09 13:42:42 -0800186 mLastStartedPlayingTimeNs(0),
Ray Essickeda32522018-02-28 12:08:28 -0800187 mLastStartedRebufferingTimeNs(0),
Robert Shih1a5c8592015-08-04 18:07:44 -0700188 mPreviousSeekTimeUs(0),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700189 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800190 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800191 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800192 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800193 mPollDurationGeneration(0),
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700194 mTimedTextGeneration(0),
Andreas Huberf9334412010-12-15 15:17:42 -0800195 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800196 mFlushingVideo(NONE),
Chong Zhangf8d71772014-11-26 15:08:34 -0800197 mResumePending(false),
Andreas Huber57a339c2012-12-03 11:18:00 -0800198 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700199 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
200 mVideoFpsHint(-1.f),
Chong Zhangefbb6192015-01-30 17:13:27 -0800201 mStarted(false),
Wei Jia8a092d32016-06-03 14:57:24 -0700202 mPrepared(false),
Ronghua Wu64c2d172015-10-07 16:52:19 -0700203 mResetting(false),
Robert Shih0c61a0d2015-07-06 15:09:10 -0700204 mSourceStarted(false),
Wei Jia686e8e52017-04-03 14:08:01 -0700205 mAudioDecoderError(false),
206 mVideoDecoderError(false),
Chong Zhangefbb6192015-01-30 17:13:27 -0800207 mPaused(false),
Wei Jia71c75e02016-02-04 09:40:47 -0800208 mPausedByClient(true),
Hassan Shojania50b20c92017-02-16 18:28:58 -0800209 mPausedForBuffering(false),
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700210 mIsDrmProtected(false),
211 mDataSourceType(DATA_SOURCE_TYPE_NONE) {
Wei Jia0a68f662017-08-30 18:01:26 -0700212 CHECK(mediaClock != NULL);
Andy Hung8d121d42014-10-03 09:53:53 -0700213 clearFlushComplete();
Andreas Huberf9334412010-12-15 15:17:42 -0800214}
215
216NuPlayer::~NuPlayer() {
217}
218
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700219void NuPlayer::setUID(uid_t uid) {
220 mUIDValid = true;
221 mUID = uid;
222}
223
Dongwon Kang47afe0a2018-03-27 15:15:30 -0700224void NuPlayer::init(const wp<NuPlayerDriver> &driver) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800225 mDriver = driver;
Dongwon Kang47afe0a2018-03-27 15:15:30 -0700226
227 sp<AMessage> notify = new AMessage(kWhatMediaClockNotify, this);
228 mMediaClock->setNotificationMessage(notify);
Andreas Huberf9334412010-12-15 15:17:42 -0800229}
230
Andreas Huber9575c962013-02-05 13:59:56 -0800231void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800232 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Andreas Huberf9334412010-12-15 15:17:42 -0800233
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800234 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800235
Andreas Huber240abcc2014-02-13 13:32:37 -0800236 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber5bc087c2010-12-23 10:27:40 -0800237 msg->post();
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700238 mDataSourceType = DATA_SOURCE_TYPE_STREAM;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800239}
Andreas Huberf9334412010-12-15 15:17:42 -0800240
Andreas Huberafed0e12011-09-20 15:39:58 -0700241static bool IsHTTPLiveURL(const char *url) {
242 if (!strncasecmp("http://", url, 7)
Andreas Huber99759402013-04-01 14:28:31 -0700243 || !strncasecmp("https://", url, 8)
244 || !strncasecmp("file://", url, 7)) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700245 size_t len = strlen(url);
246 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
247 return true;
248 }
249
250 if (strstr(url,"m3u8")) {
251 return true;
252 }
253 }
254
255 return false;
256}
257
Andreas Huber9575c962013-02-05 13:59:56 -0800258void NuPlayer::setDataSourceAsync(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800259 const sp<IMediaHTTPService> &httpService,
260 const char *url,
261 const KeyedVector<String8, String8> *headers) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700262
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800263 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100264 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800265
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800266 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800267
Andreas Huberafed0e12011-09-20 15:39:58 -0700268 sp<Source> source;
269 if (IsHTTPLiveURL(url)) {
Andreas Huber81e68442014-02-05 11:52:33 -0800270 source = new HTTPLiveSource(notify, httpService, url, headers);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800271 ALOGV("setDataSourceAsync HTTPLiveSource %s", url);
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700272 mDataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Andreas Huberafed0e12011-09-20 15:39:58 -0700273 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800274 source = new RTSPSource(
275 notify, httpService, url, headers, mUIDValid, mUID);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800276 ALOGV("setDataSourceAsync RTSPSource %s", url);
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700277 mDataSourceType = DATA_SOURCE_TYPE_RTSP;
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100278 } else if ((!strncasecmp(url, "http://", 7)
279 || !strncasecmp(url, "https://", 8))
280 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
281 || strstr(url, ".sdp?"))) {
Andreas Huber1b86fe02014-01-29 11:13:26 -0800282 source = new RTSPSource(
283 notify, httpService, url, headers, mUIDValid, mUID, true);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800284 ALOGV("setDataSourceAsync RTSPSource http/https/.sdp %s", url);
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700285 mDataSourceType = DATA_SOURCE_TYPE_RTSP;
Andreas Huber2bfdd422011-10-11 15:24:07 -0700286 } else {
Hassan Shojaniacefac142017-02-06 21:02:02 -0800287 ALOGV("setDataSourceAsync GenericSource %s", url);
288
Chong Zhang3de157d2014-08-05 20:54:44 -0700289 sp<GenericSource> genericSource =
Wei Jia992c5592017-09-01 14:20:23 -0700290 new GenericSource(notify, mUIDValid, mUID, mMediaClock);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700291
Chong Zhanga19f33e2014-08-07 15:35:07 -0700292 status_t err = genericSource->setDataSource(httpService, url, headers);
Chong Zhang3de157d2014-08-05 20:54:44 -0700293
294 if (err == OK) {
295 source = genericSource;
296 } else {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700297 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700298 }
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700299
300 // regardless of success/failure
301 mDataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Chong Zhang3de157d2014-08-05 20:54:44 -0700302 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700303 msg->setObject("source", source);
304 msg->post();
305}
306
Andreas Huber9575c962013-02-05 13:59:56 -0800307void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800308 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Andreas Huberafed0e12011-09-20 15:39:58 -0700309
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800310 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800311
Chong Zhang3de157d2014-08-05 20:54:44 -0700312 sp<GenericSource> source =
Wei Jia992c5592017-09-01 14:20:23 -0700313 new GenericSource(notify, mUIDValid, mUID, mMediaClock);
Chong Zhang3de157d2014-08-05 20:54:44 -0700314
Hassan Shojaniacefac142017-02-06 21:02:02 -0800315 ALOGV("setDataSourceAsync fd %d/%lld/%lld source: %p",
316 fd, (long long)offset, (long long)length, source.get());
317
Chong Zhanga19f33e2014-08-07 15:35:07 -0700318 status_t err = source->setDataSource(fd, offset, length);
Chong Zhang3de157d2014-08-05 20:54:44 -0700319
320 if (err != OK) {
Chong Zhanga19f33e2014-08-07 15:35:07 -0700321 ALOGE("Failed to set data source!");
Chong Zhang3de157d2014-08-05 20:54:44 -0700322 source = NULL;
323 }
324
Andreas Huberafed0e12011-09-20 15:39:58 -0700325 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800326 msg->post();
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700327 mDataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Andreas Huberf9334412010-12-15 15:17:42 -0800328}
329
Chris Watkins99f31602015-03-20 13:06:33 -0700330void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) {
331 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
332 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
333
Wei Jia992c5592017-09-01 14:20:23 -0700334 sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID, mMediaClock);
Chris Watkins99f31602015-03-20 13:06:33 -0700335 status_t err = source->setDataSource(dataSource);
336
337 if (err != OK) {
338 ALOGE("Failed to set data source!");
339 source = NULL;
340 }
341
342 msg->setObject("source", source);
343 msg->post();
Hassan Shojaniaff63de72017-04-26 15:10:42 -0700344 mDataSourceType = DATA_SOURCE_TYPE_MEDIA;
Chris Watkins99f31602015-03-20 13:06:33 -0700345}
346
Wei Jia9bb38032017-03-23 18:00:38 -0700347status_t NuPlayer::getBufferingSettings(
Wei Jia48fa06d2016-12-20 15:30:49 -0800348 BufferingSettings *buffering /* nonnull */) {
Wei Jia9bb38032017-03-23 18:00:38 -0700349 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
Wei Jia48fa06d2016-12-20 15:30:49 -0800350 sp<AMessage> response;
351 status_t err = msg->postAndAwaitResponse(&response);
352 if (err == OK && response != NULL) {
353 CHECK(response->findInt32("err", &err));
354 if (err == OK) {
355 readFromAMessage(response, buffering);
356 }
357 }
358 return err;
359}
360
361status_t NuPlayer::setBufferingSettings(const BufferingSettings& buffering) {
362 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
363 writeToAMessage(msg, buffering);
364 sp<AMessage> response;
365 status_t err = msg->postAndAwaitResponse(&response);
366 if (err == OK && response != NULL) {
367 CHECK(response->findInt32("err", &err));
368 }
369 return err;
370}
371
Byeongjo Park28225ab2019-01-24 20:31:19 +0900372void NuPlayer::setDataSourceAsync(const String8& rtpParams) {
373 ALOGD("setDataSourceAsync for RTP = %s", rtpParams.string());
374 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
375
376 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
377 sp<Source> source = new RTPSource(notify, rtpParams);
378
379 msg->setObject("source", source);
380 msg->post();
Byeongjo Park5e27b1b2018-07-12 15:36:03 +0900381 mDataSourceType = DATA_SOURCE_TYPE_RTP;
Byeongjo Park28225ab2019-01-24 20:31:19 +0900382}
383
Andreas Huber9575c962013-02-05 13:59:56 -0800384void NuPlayer::prepareAsync() {
Hassan Shojaniacefac142017-02-06 21:02:02 -0800385 ALOGV("prepareAsync");
386
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800387 (new AMessage(kWhatPrepare, this))->post();
Andreas Huber9575c962013-02-05 13:59:56 -0800388}
389
Andreas Huber57a339c2012-12-03 11:18:00 -0800390void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800391 const sp<IGraphicBufferProducer> &bufferProducer) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700392 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
Andreas Huber57a339c2012-12-03 11:18:00 -0800393
Andy McFadden8ba01022012-12-18 09:46:54 -0800394 if (bufferProducer == NULL) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700395 msg->setObject("surface", NULL);
Andreas Huber57a339c2012-12-03 11:18:00 -0800396 } else {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700397 msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */));
Andreas Huber57a339c2012-12-03 11:18:00 -0800398 }
399
Andreas Huberf9334412010-12-15 15:17:42 -0800400 msg->post();
401}
402
403void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800404 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
Andreas Huberf9334412010-12-15 15:17:42 -0800405 msg->setObject("sink", sink);
406 msg->post();
407}
408
409void NuPlayer::start() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800410 (new AMessage(kWhatStart, this))->post();
Andreas Huberf9334412010-12-15 15:17:42 -0800411}
412
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700413status_t NuPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) {
414 // do some cursory validation of the settings here. audio modes are
415 // only validated when set on the audiosink.
416 if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
417 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
418 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
419 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
420 return BAD_VALUE;
421 }
422 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
423 writeToAMessage(msg, rate);
424 sp<AMessage> response;
425 status_t err = msg->postAndAwaitResponse(&response);
426 if (err == OK && response != NULL) {
427 CHECK(response->findInt32("err", &err));
428 }
429 return err;
430}
431
432status_t NuPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
433 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
434 sp<AMessage> response;
435 status_t err = msg->postAndAwaitResponse(&response);
436 if (err == OK && response != NULL) {
437 CHECK(response->findInt32("err", &err));
438 if (err == OK) {
439 readFromAMessage(response, rate);
440 }
441 }
442 return err;
443}
444
445status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
446 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
447 writeToAMessage(msg, sync, videoFpsHint);
448 sp<AMessage> response;
449 status_t err = msg->postAndAwaitResponse(&response);
450 if (err == OK && response != NULL) {
451 CHECK(response->findInt32("err", &err));
452 }
453 return err;
454}
455
456status_t NuPlayer::getSyncSettings(
457 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
458 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
459 sp<AMessage> response;
460 status_t err = msg->postAndAwaitResponse(&response);
461 if (err == OK && response != NULL) {
462 CHECK(response->findInt32("err", &err));
463 if (err == OK) {
464 readFromAMessage(response, sync, videoFps);
465 }
466 }
467 return err;
Wei Jia98160162015-02-04 17:01:11 -0800468}
469
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800470void NuPlayer::pause() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800471 (new AMessage(kWhatPause, this))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800472}
473
Andreas Huber1aef2112011-01-04 14:01:29 -0800474void NuPlayer::resetAsync() {
Wei Jiac45a4b22016-04-15 15:30:23 -0700475 sp<Source> source;
476 {
477 Mutex::Autolock autoLock(mSourceLock);
478 source = mSource;
479 }
480
481 if (source != NULL) {
Chong Zhang48296b72014-09-14 14:28:45 -0700482 // During a reset, the data source might be unresponsive already, we need to
483 // disconnect explicitly so that reads exit promptly.
484 // We can't queue the disconnect request to the looper, as it might be
485 // queued behind a stuck read and never gets processed.
486 // Doing a disconnect outside the looper to allows the pending reads to exit
487 // (either successfully or with error).
Wei Jiac45a4b22016-04-15 15:30:23 -0700488 source->disconnect();
Chong Zhang48296b72014-09-14 14:28:45 -0700489 }
490
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800491 (new AMessage(kWhatReset, this))->post();
Andreas Huber1aef2112011-01-04 14:01:29 -0800492}
493
Wei Jia52c28512017-09-13 18:17:51 -0700494status_t NuPlayer::notifyAt(int64_t mediaTimeUs) {
495 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
496 notify->setInt64("timerUs", mediaTimeUs);
497 mMediaClock->addTimer(notify, mediaTimeUs);
498 return OK;
499}
500
Wei Jiac5de0912016-11-18 10:22:14 -0800501void NuPlayer::seekToAsync(int64_t seekTimeUs, MediaPlayerSeekMode mode, bool needNotify) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800502 sp<AMessage> msg = new AMessage(kWhatSeek, this);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800503 msg->setInt64("seekTimeUs", seekTimeUs);
Wei Jiac5de0912016-11-18 10:22:14 -0800504 msg->setInt32("mode", mode);
Wei Jiae427abf2014-09-22 15:21:11 -0700505 msg->setInt32("needNotify", needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800506 msg->post();
507}
508
Andreas Huber53df1a42010-12-22 10:03:04 -0800509
Chong Zhang404fced2014-06-11 14:45:31 -0700510void NuPlayer::writeTrackInfo(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700511 Parcel* reply, const sp<AMessage>& format) const {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700512 if (format == NULL) {
513 ALOGE("NULL format");
514 return;
515 }
Chong Zhang404fced2014-06-11 14:45:31 -0700516 int32_t trackType;
Marco Nelissen9436e482015-09-15 10:21:53 -0700517 if (!format->findInt32("type", &trackType)) {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700518 ALOGE("no track type");
519 return;
520 }
Chong Zhang404fced2014-06-11 14:45:31 -0700521
Robert Shih755106e2015-04-30 14:36:45 -0700522 AString mime;
Robert Shih2e3a4252015-05-06 10:21:15 -0700523 if (!format->findString("mime", &mime)) {
524 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
525 // If we can't find the mimetype here it means that we wouldn't be needing
526 // the mimetype on the Java end. We still write a placeholder mime to keep the
527 // (de)serialization logic simple.
528 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
529 mime = "audio/";
530 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
531 mime = "video/";
532 } else {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700533 ALOGE("unknown track type: %d", trackType);
534 return;
Robert Shih2e3a4252015-05-06 10:21:15 -0700535 }
536 }
Robert Shih755106e2015-04-30 14:36:45 -0700537
Chong Zhang404fced2014-06-11 14:45:31 -0700538 AString lang;
Marco Nelissen9436e482015-09-15 10:21:53 -0700539 if (!format->findString("language", &lang)) {
Marco Nelissenc367ca12015-09-15 09:51:59 -0700540 ALOGE("no language");
541 return;
542 }
Chong Zhang404fced2014-06-11 14:45:31 -0700543
544 reply->writeInt32(2); // write something non-zero
545 reply->writeInt32(trackType);
Robert Shih755106e2015-04-30 14:36:45 -0700546 reply->writeString16(String16(mime.c_str()));
Chong Zhang404fced2014-06-11 14:45:31 -0700547 reply->writeString16(String16(lang.c_str()));
548
549 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
Chong Zhang404fced2014-06-11 14:45:31 -0700550 int32_t isAuto, isDefault, isForced;
551 CHECK(format->findInt32("auto", &isAuto));
552 CHECK(format->findInt32("default", &isDefault));
553 CHECK(format->findInt32("forced", &isForced));
554
Chong Zhang404fced2014-06-11 14:45:31 -0700555 reply->writeInt32(isAuto);
556 reply->writeInt32(isDefault);
557 reply->writeInt32(isForced);
Simon Bowdenb3de2072022-10-05 13:46:20 +0000558 } else if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
559 int32_t hapticChannelCount;
560 bool hasHapticChannels = format->findInt32("haptic-channel-count", &hapticChannelCount);
561 reply->writeInt32(hasHapticChannels);
562 if (hasHapticChannels) {
563 reply->writeInt32(hapticChannelCount);
564 }
Chong Zhang404fced2014-06-11 14:45:31 -0700565 }
566}
567
Andreas Huberf9334412010-12-15 15:17:42 -0800568void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
569 switch (msg->what()) {
570 case kWhatSetDataSource:
571 {
Steve Block3856b092011-10-20 11:56:00 +0100572 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800573
574 CHECK(mSource == NULL);
575
Chong Zhang3de157d2014-08-05 20:54:44 -0700576 status_t err = OK;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800577 sp<RefBase> obj;
578 CHECK(msg->findObject("source", &obj));
Chong Zhang3de157d2014-08-05 20:54:44 -0700579 if (obj != NULL) {
Wei Jiac45a4b22016-04-15 15:30:23 -0700580 Mutex::Autolock autoLock(mSourceLock);
Chong Zhang3de157d2014-08-05 20:54:44 -0700581 mSource = static_cast<Source *>(obj.get());
Chong Zhang3de157d2014-08-05 20:54:44 -0700582 } else {
583 err = UNKNOWN_ERROR;
584 }
Andreas Huber9575c962013-02-05 13:59:56 -0800585
586 CHECK(mDriver != NULL);
587 sp<NuPlayerDriver> driver = mDriver.promote();
588 if (driver != NULL) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700589 driver->notifySetDataSourceCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -0800590 }
591 break;
592 }
593
Wei Jia9bb38032017-03-23 18:00:38 -0700594 case kWhatGetBufferingSettings:
Wei Jia48fa06d2016-12-20 15:30:49 -0800595 {
596 sp<AReplyToken> replyID;
597 CHECK(msg->senderAwaitsResponse(&replyID));
598
Wei Jia9bb38032017-03-23 18:00:38 -0700599 ALOGV("kWhatGetBufferingSettings");
Wei Jia48fa06d2016-12-20 15:30:49 -0800600 BufferingSettings buffering;
601 status_t err = OK;
602 if (mSource != NULL) {
Wei Jia9bb38032017-03-23 18:00:38 -0700603 err = mSource->getBufferingSettings(&buffering);
Wei Jia48fa06d2016-12-20 15:30:49 -0800604 } else {
605 err = INVALID_OPERATION;
606 }
607 sp<AMessage> response = new AMessage;
608 if (err == OK) {
609 writeToAMessage(response, buffering);
610 }
611 response->setInt32("err", err);
612 response->postReply(replyID);
613 break;
614 }
615
616 case kWhatSetBufferingSettings:
617 {
618 sp<AReplyToken> replyID;
619 CHECK(msg->senderAwaitsResponse(&replyID));
620
621 ALOGV("kWhatSetBufferingSettings");
622 BufferingSettings buffering;
623 readFromAMessage(msg, &buffering);
624 status_t err = OK;
625 if (mSource != NULL) {
626 err = mSource->setBufferingSettings(buffering);
627 } else {
628 err = INVALID_OPERATION;
629 }
630 sp<AMessage> response = new AMessage;
631 response->setInt32("err", err);
632 response->postReply(replyID);
633 break;
634 }
635
Andreas Huber9575c962013-02-05 13:59:56 -0800636 case kWhatPrepare:
637 {
Hassan Shojaniacefac142017-02-06 21:02:02 -0800638 ALOGV("onMessageReceived kWhatPrepare");
639
Andreas Huber9575c962013-02-05 13:59:56 -0800640 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800641 break;
642 }
643
Chong Zhangdcb89b32013-08-06 09:44:47 -0700644 case kWhatGetTrackInfo:
645 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800646 sp<AReplyToken> replyID;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700647 CHECK(msg->senderAwaitsResponse(&replyID));
648
Chong Zhang404fced2014-06-11 14:45:31 -0700649 Parcel* reply;
650 CHECK(msg->findPointer("reply", (void**)&reply));
651
652 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700653 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700654 inbandTracks = mSource->getTrackCount();
655 }
656
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700657 size_t ccTracks = 0;
658 if (mCCDecoder != NULL) {
659 ccTracks = mCCDecoder->getTrackCount();
660 }
661
Chong Zhang404fced2014-06-11 14:45:31 -0700662 // total track count
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700663 reply->writeInt32(inbandTracks + ccTracks);
Chong Zhang404fced2014-06-11 14:45:31 -0700664
665 // write inband tracks
666 for (size_t i = 0; i < inbandTracks; ++i) {
667 writeTrackInfo(reply, mSource->getTrackInfo(i));
Chong Zhangdcb89b32013-08-06 09:44:47 -0700668 }
669
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700670 // write CC track
671 for (size_t i = 0; i < ccTracks; ++i) {
672 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
673 }
674
Chong Zhangdcb89b32013-08-06 09:44:47 -0700675 sp<AMessage> response = new AMessage;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700676 response->postReply(replyID);
677 break;
678 }
679
Robert Shih7c4f0d72014-07-09 18:53:31 -0700680 case kWhatGetSelectedTrack:
681 {
Wei Jia039224f2018-11-29 17:25:17 -0800682 int32_t type32;
683 CHECK(msg->findInt32("type", (int32_t*)&type32));
684 media_track_type type = (media_track_type)type32;
685
686 size_t inbandTracks = 0;
Robert Shih7c4f0d72014-07-09 18:53:31 -0700687 status_t err = INVALID_OPERATION;
Wei Jia039224f2018-11-29 17:25:17 -0800688 ssize_t selectedTrack = -1;
Robert Shih7c4f0d72014-07-09 18:53:31 -0700689 if (mSource != NULL) {
690 err = OK;
Wei Jia039224f2018-11-29 17:25:17 -0800691 inbandTracks = mSource->getTrackCount();
692 selectedTrack = mSource->getSelectedTrack(type);
Robert Shih7c4f0d72014-07-09 18:53:31 -0700693 }
694
Wei Jia039224f2018-11-29 17:25:17 -0800695 if (selectedTrack == -1 && mCCDecoder != NULL) {
696 err = OK;
697 selectedTrack = mCCDecoder->getSelectedTrack(type);
698 if (selectedTrack != -1) {
699 selectedTrack += inbandTracks;
700 }
701 }
702
703 Parcel* reply;
704 CHECK(msg->findPointer("reply", (void**)&reply));
705 reply->writeInt32(selectedTrack);
706
Robert Shih7c4f0d72014-07-09 18:53:31 -0700707 sp<AMessage> response = new AMessage;
708 response->setInt32("err", err);
709
Lajos Molnar3f274362015-03-05 14:35:41 -0800710 sp<AReplyToken> replyID;
Robert Shih7c4f0d72014-07-09 18:53:31 -0700711 CHECK(msg->senderAwaitsResponse(&replyID));
712 response->postReply(replyID);
713 break;
714 }
715
Chong Zhangdcb89b32013-08-06 09:44:47 -0700716 case kWhatSelectTrack:
717 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800718 sp<AReplyToken> replyID;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700719 CHECK(msg->senderAwaitsResponse(&replyID));
720
Chong Zhang404fced2014-06-11 14:45:31 -0700721 size_t trackIndex;
722 int32_t select;
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700723 int64_t timeUs;
Chong Zhang404fced2014-06-11 14:45:31 -0700724 CHECK(msg->findSize("trackIndex", &trackIndex));
725 CHECK(msg->findInt32("select", &select));
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700726 CHECK(msg->findInt64("timeUs", &timeUs));
Chong Zhang404fced2014-06-11 14:45:31 -0700727
Chong Zhangdcb89b32013-08-06 09:44:47 -0700728 status_t err = INVALID_OPERATION;
Chong Zhang404fced2014-06-11 14:45:31 -0700729
730 size_t inbandTracks = 0;
Chong Zhangdcb89b32013-08-06 09:44:47 -0700731 if (mSource != NULL) {
Chong Zhang404fced2014-06-11 14:45:31 -0700732 inbandTracks = mSource->getTrackCount();
733 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700734 size_t ccTracks = 0;
735 if (mCCDecoder != NULL) {
736 ccTracks = mCCDecoder->getTrackCount();
737 }
Chong Zhang404fced2014-06-11 14:45:31 -0700738
739 if (trackIndex < inbandTracks) {
Robert Shih6ffb1fd2014-10-29 16:24:32 -0700740 err = mSource->selectTrack(trackIndex, select, timeUs);
Robert Shihd3b0bbb2014-07-23 15:00:25 -0700741
742 if (!select && err == OK) {
743 int32_t type;
744 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
745 if (info != NULL
746 && info->findInt32("type", &type)
747 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
748 ++mTimedTextGeneration;
749 }
750 }
Chong Zhanga7fa1d92014-06-11 14:49:23 -0700751 } else {
752 trackIndex -= inbandTracks;
753
754 if (trackIndex < ccTracks) {
755 err = mCCDecoder->selectTrack(trackIndex, select);
756 }
Chong Zhangdcb89b32013-08-06 09:44:47 -0700757 }
758
759 sp<AMessage> response = new AMessage;
760 response->setInt32("err", err);
761
762 response->postReply(replyID);
763 break;
764 }
765
Andreas Huberb7c8e912012-11-27 15:02:53 -0800766 case kWhatPollDuration:
767 {
768 int32_t generation;
769 CHECK(msg->findInt32("generation", &generation));
770
771 if (generation != mPollDurationGeneration) {
772 // stale
773 break;
774 }
775
776 int64_t durationUs;
777 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
778 sp<NuPlayerDriver> driver = mDriver.promote();
779 if (driver != NULL) {
780 driver->notifyDuration(durationUs);
781 }
782 }
783
Chih-Hung Hsieh62309d52018-12-11 13:54:02 -0800784 msg->post(1000000LL); // poll again in a second.
Andreas Huberb7c8e912012-11-27 15:02:53 -0800785 break;
786 }
787
Lajos Molnar1de1e252015-04-30 18:18:34 -0700788 case kWhatSetVideoSurface:
Andreas Huberf9334412010-12-15 15:17:42 -0800789 {
Andreas Huberf9334412010-12-15 15:17:42 -0800790
791 sp<RefBase> obj;
Lajos Molnar1de1e252015-04-30 18:18:34 -0700792 CHECK(msg->findObject("surface", &obj));
793 sp<Surface> surface = static_cast<Surface *>(obj.get());
Lajos Molnara81c6222015-07-10 19:17:45 -0700794
795 ALOGD("onSetVideoSurface(%p, %s video decoder)",
796 surface.get(),
Wei Jia6b7d2ed2015-08-10 15:11:54 -0700797 (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
Lajos Molnara81c6222015-07-10 19:17:45 -0700798 && mVideoDecoder != NULL) ? "have" : "no");
799
Wei Jia6b7d2ed2015-08-10 15:11:54 -0700800 // Need to check mStarted before calling mSource->getFormat because NuPlayer might
801 // be in preparing state and it could take long time.
802 // When mStarted is true, mSource must have been set.
803 if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
Lajos Molnara81c6222015-07-10 19:17:45 -0700804 // NOTE: mVideoDecoder's mSurface is always non-null
805 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
Lajos Molnar1de1e252015-04-30 18:18:34 -0700806 performSetSurface(surface);
Wei Jiafef808d2014-10-31 17:57:05 -0700807 break;
808 }
809
810 mDeferredActions.push_back(
Krystian Turczyn687a5892016-01-20 14:20:35 +0100811 new FlushDecoderAction(
812 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
Wei Jiafef808d2014-10-31 17:57:05 -0700813 FLUSH_CMD_SHUTDOWN /* video */));
814
Lajos Molnar1de1e252015-04-30 18:18:34 -0700815 mDeferredActions.push_back(new SetSurfaceAction(surface));
James Dong0d268a32012-08-31 12:18:27 -0700816
Krystian Turczyn687a5892016-01-20 14:20:35 +0100817 if (obj != NULL) {
Wei Jiafef808d2014-10-31 17:57:05 -0700818 if (mStarted) {
Andy Hung73535852014-09-05 11:42:58 -0700819 // Issue a seek to refresh the video screen only if started otherwise
820 // the extractor may not yet be started and will assert.
821 // If the video decoder is not set (perhaps audio only in this case)
822 // do not perform a seek as it is not needed.
Ronghua Wua73d9e02014-10-08 15:13:29 -0700823 int64_t currentPositionUs = 0;
824 if (getCurrentPosition(&currentPositionUs) == OK) {
825 mDeferredActions.push_back(
Wei Jiac5de0912016-11-18 10:22:14 -0800826 new SeekAction(currentPositionUs,
827 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
Ronghua Wua73d9e02014-10-08 15:13:29 -0700828 }
Andy Hung73535852014-09-05 11:42:58 -0700829 }
Wei Jiaac428aa2014-09-02 19:01:34 -0700830
Andreas Huber57a339c2012-12-03 11:18:00 -0800831 // If there is a new surface texture, instantiate decoders
832 // again if possible.
833 mDeferredActions.push_back(
834 new SimpleAction(&NuPlayer::performScanSources));
Andreas Huber57a339c2012-12-03 11:18:00 -0800835
Krystian Turczyn687a5892016-01-20 14:20:35 +0100836 // After a flush without shutdown, decoder is paused.
837 // Don't resume it until source seek is done, otherwise it could
838 // start pulling stale data too soon.
839 mDeferredActions.push_back(
840 new ResumeDecoderAction(false /* needNotify */));
841 }
Chong Zhang7137ec72014-11-12 16:41:05 -0800842
Andreas Huber57a339c2012-12-03 11:18:00 -0800843 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800844 break;
845 }
846
847 case kWhatSetAudioSink:
848 {
Steve Block3856b092011-10-20 11:56:00 +0100849 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800850
851 sp<RefBase> obj;
852 CHECK(msg->findObject("sink", &obj));
853
854 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
855 break;
856 }
857
858 case kWhatStart:
859 {
Steve Block3856b092011-10-20 11:56:00 +0100860 ALOGV("kWhatStart");
Wei Jia94211742014-10-28 17:09:06 -0700861 if (mStarted) {
Chong Zhang8a048332015-05-06 15:16:28 -0700862 // do not resume yet if the source is still buffering
863 if (!mPausedForBuffering) {
864 onResume();
865 }
Wei Jia94211742014-10-28 17:09:06 -0700866 } else {
867 onStart();
Lajos Molnar09524832014-07-17 14:29:51 -0700868 }
Chong Zhangefbb6192015-01-30 17:13:27 -0800869 mPausedByClient = false;
Andreas Huberf9334412010-12-15 15:17:42 -0800870 break;
871 }
872
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700873 case kWhatConfigPlayback:
Wei Jia98160162015-02-04 17:01:11 -0800874 {
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700875 sp<AReplyToken> replyID;
876 CHECK(msg->senderAwaitsResponse(&replyID));
877 AudioPlaybackRate rate /* sanitized */;
878 readFromAMessage(msg, &rate);
879 status_t err = OK;
Wei Jia98160162015-02-04 17:01:11 -0800880 if (mRenderer != NULL) {
Jaideep Sharma18a79122020-11-04 16:30:05 +0530881 // AudioSink allows only 1.f and 0.f for offload and direct modes.
882 // For other speeds, restart audio to fallback to supported paths
883 bool audioDirectOutput = (mAudioSink->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0;
884 if ((mOffloadAudio || audioDirectOutput) &&
885 ((rate.mSpeed != 0.f && rate.mSpeed != 1.f) || rate.mPitch != 1.f)) {
886
Wei Jiabf70feb2016-02-19 15:47:16 -0800887 int64_t currentPositionUs;
888 if (getCurrentPosition(&currentPositionUs) != OK) {
889 currentPositionUs = mPreviousSeekTimeUs;
890 }
891
892 // Set mPlaybackSettings so that the new audio decoder can
893 // be created correctly.
894 mPlaybackSettings = rate;
895 if (!mPaused) {
896 mRenderer->pause();
897 }
Wei Jia5031b2f2016-02-25 11:19:31 -0800898 restartAudio(
Wei Jiabf70feb2016-02-19 15:47:16 -0800899 currentPositionUs, true /* forceNonOffload */,
900 true /* needsToCreateAudioDecoder */);
901 if (!mPaused) {
902 mRenderer->resume();
903 }
904 }
905
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700906 err = mRenderer->setPlaybackSettings(rate);
907 }
908 if (err == OK) {
909 if (rate.mSpeed == 0.f) {
910 onPause();
Wei Jia351ce872016-02-10 13:21:59 -0800911 mPausedByClient = true;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700912 // save all other settings (using non-paused speed)
913 // so we can restore them on start
914 AudioPlaybackRate newRate = rate;
915 newRate.mSpeed = mPlaybackSettings.mSpeed;
916 mPlaybackSettings = newRate;
917 } else { /* rate.mSpeed != 0.f */
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700918 mPlaybackSettings = rate;
Wei Jia8a092d32016-06-03 14:57:24 -0700919 if (mStarted) {
920 // do not resume yet if the source is still buffering
921 if (!mPausedForBuffering) {
922 onResume();
923 }
924 } else if (mPrepared) {
925 onStart();
926 }
927
928 mPausedByClient = false;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700929 }
Wei Jia98160162015-02-04 17:01:11 -0800930 }
Ronghua Wu8db88132015-04-22 13:51:35 -0700931
932 if (mVideoDecoder != NULL) {
Praveen Chavanbbaa1442016-04-08 13:33:49 -0700933 sp<AMessage> params = new AMessage();
934 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
935 mVideoDecoder->setParameters(params);
Ronghua Wu8db88132015-04-22 13:51:35 -0700936 }
937
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700938 sp<AMessage> response = new AMessage;
939 response->setInt32("err", err);
940 response->postReply(replyID);
941 break;
942 }
943
944 case kWhatGetPlaybackSettings:
945 {
946 sp<AReplyToken> replyID;
947 CHECK(msg->senderAwaitsResponse(&replyID));
948 AudioPlaybackRate rate = mPlaybackSettings;
949 status_t err = OK;
950 if (mRenderer != NULL) {
951 err = mRenderer->getPlaybackSettings(&rate);
952 }
953 if (err == OK) {
954 // get playback settings used by renderer, as it may be
955 // slightly off due to audiosink not taking small changes.
956 mPlaybackSettings = rate;
957 if (mPaused) {
958 rate.mSpeed = 0.f;
959 }
960 }
961 sp<AMessage> response = new AMessage;
962 if (err == OK) {
963 writeToAMessage(response, rate);
964 }
965 response->setInt32("err", err);
966 response->postReply(replyID);
967 break;
968 }
969
970 case kWhatConfigSync:
971 {
972 sp<AReplyToken> replyID;
973 CHECK(msg->senderAwaitsResponse(&replyID));
974
975 ALOGV("kWhatConfigSync");
976 AVSyncSettings sync;
977 float videoFpsHint;
978 readFromAMessage(msg, &sync, &videoFpsHint);
979 status_t err = OK;
980 if (mRenderer != NULL) {
981 err = mRenderer->setSyncSettings(sync, videoFpsHint);
982 }
983 if (err == OK) {
984 mSyncSettings = sync;
985 mVideoFpsHint = videoFpsHint;
986 }
987 sp<AMessage> response = new AMessage;
988 response->setInt32("err", err);
989 response->postReply(replyID);
990 break;
991 }
992
993 case kWhatGetSyncSettings:
994 {
995 sp<AReplyToken> replyID;
996 CHECK(msg->senderAwaitsResponse(&replyID));
997 AVSyncSettings sync = mSyncSettings;
998 float videoFps = mVideoFpsHint;
999 status_t err = OK;
1000 if (mRenderer != NULL) {
1001 err = mRenderer->getSyncSettings(&sync, &videoFps);
1002 if (err == OK) {
1003 mSyncSettings = sync;
1004 mVideoFpsHint = videoFps;
1005 }
1006 }
1007 sp<AMessage> response = new AMessage;
1008 if (err == OK) {
1009 writeToAMessage(response, sync, videoFps);
1010 }
1011 response->setInt32("err", err);
1012 response->postReply(replyID);
Wei Jia98160162015-02-04 17:01:11 -08001013 break;
1014 }
1015
Andreas Huberf9334412010-12-15 15:17:42 -08001016 case kWhatScanSources:
1017 {
Andreas Huber1aef2112011-01-04 14:01:29 -08001018 int32_t generation;
1019 CHECK(msg->findInt32("generation", &generation));
1020 if (generation != mScanSourcesGeneration) {
1021 // Drop obsolete msg.
1022 break;
1023 }
1024
Andreas Huber5bc087c2010-12-23 10:27:40 -08001025 mScanSourcesPending = false;
1026
Steve Block3856b092011-10-20 11:56:00 +01001027 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001028 mAudioDecoder != NULL, mVideoDecoder != NULL);
1029
Andreas Huberb7c8e912012-11-27 15:02:53 -08001030 bool mHadAnySourcesBefore =
1031 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
Robert Shih7350b052015-10-01 15:50:14 -07001032 bool rescan = false;
Andreas Huberb7c8e912012-11-27 15:02:53 -08001033
Andy Hung282a7e32014-08-14 15:56:34 -07001034 // initialize video before audio because successful initialization of
1035 // video may change deep buffer mode of audio.
Lajos Molnar1de1e252015-04-30 18:18:34 -07001036 if (mSurface != NULL) {
Robert Shih7350b052015-10-01 15:50:14 -07001037 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1038 rescan = true;
1039 }
Haynes Mathew George5d246ef2012-07-09 10:36:57 -07001040 }
Andreas Huberf9334412010-12-15 15:17:42 -08001041
Ronghua Wua10fd232014-11-06 16:15:20 -08001042 // Don't try to re-open audio sink if there's an existing decoder.
1043 if (mAudioSink != NULL && mAudioDecoder == NULL) {
Robert Shih7350b052015-10-01 15:50:14 -07001044 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1045 rescan = true;
1046 }
Andreas Huberf9334412010-12-15 15:17:42 -08001047 }
1048
Andreas Huberb7c8e912012-11-27 15:02:53 -08001049 if (!mHadAnySourcesBefore
1050 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1051 // This is the first time we've found anything playable.
1052
Andreas Huber9575c962013-02-05 13:59:56 -08001053 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -08001054 schedulePollDuration();
1055 }
1056 }
1057
Andreas Hubereac68ba2011-09-27 12:12:25 -07001058 status_t err;
1059 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -08001060 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1061 // We're not currently decoding anything (no audio or
1062 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -07001063
1064 if (err == ERROR_END_OF_STREAM) {
1065 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1066 } else {
1067 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1068 }
Andreas Huber1aef2112011-01-04 14:01:29 -08001069 }
Andreas Huberf9334412010-12-15 15:17:42 -08001070 break;
1071 }
1072
Robert Shih7350b052015-10-01 15:50:14 -07001073 if (rescan) {
Chih-Hung Hsieh62309d52018-12-11 13:54:02 -08001074 msg->post(100000LL);
Andreas Huber5bc087c2010-12-23 10:27:40 -08001075 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -08001076 }
1077 break;
1078 }
1079
1080 case kWhatVideoNotify:
1081 case kWhatAudioNotify:
1082 {
1083 bool audio = msg->what() == kWhatAudioNotify;
1084
Wei Jia88703c32014-08-06 11:24:07 -07001085 int32_t currentDecoderGeneration =
1086 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1087 int32_t requesterGeneration = currentDecoderGeneration - 1;
1088 CHECK(msg->findInt32("generation", &requesterGeneration));
1089
1090 if (requesterGeneration != currentDecoderGeneration) {
1091 ALOGV("got message from old %s decoder, generation(%d:%d)",
1092 audio ? "audio" : "video", requesterGeneration,
1093 currentDecoderGeneration);
1094 sp<AMessage> reply;
1095 if (!(msg->findMessage("reply", &reply))) {
1096 return;
1097 }
1098
1099 reply->setInt32("err", INFO_DISCONTINUITY);
1100 reply->post();
1101 return;
1102 }
1103
Andreas Huberf9334412010-12-15 15:17:42 -08001104 int32_t what;
Lajos Molnar1cd13982014-01-17 15:12:51 -08001105 CHECK(msg->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -08001106
Chong Zhang7137ec72014-11-12 16:41:05 -08001107 if (what == DecoderBase::kWhatInputDiscontinuity) {
1108 int32_t formatChange;
1109 CHECK(msg->findInt32("formatChange", &formatChange));
Andreas Huberf9334412010-12-15 15:17:42 -08001110
Chong Zhang7137ec72014-11-12 16:41:05 -08001111 ALOGV("%s discontinuity: formatChange %d",
1112 audio ? "audio" : "video", formatChange);
1113
1114 if (formatChange) {
1115 mDeferredActions.push_back(
1116 new FlushDecoderAction(
1117 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1118 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
Andreas Huberf9334412010-12-15 15:17:42 -08001119 }
Chong Zhang7137ec72014-11-12 16:41:05 -08001120
1121 mDeferredActions.push_back(
1122 new SimpleAction(
1123 &NuPlayer::performScanSources));
1124
1125 processDeferredActions();
1126 } else if (what == DecoderBase::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001127 int32_t err;
Lajos Molnar1cd13982014-01-17 15:12:51 -08001128 CHECK(msg->findInt32("err", &err));
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001129
1130 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +01001131 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001132 } else {
Steve Block3856b092011-10-20 11:56:00 +01001133 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -07001134 audio ? "audio" : "video",
1135 err);
1136 }
1137
1138 mRenderer->queueEOS(audio, err);
Chong Zhang7137ec72014-11-12 16:41:05 -08001139 } else if (what == DecoderBase::kWhatFlushCompleted) {
Steve Block3856b092011-10-20 11:56:00 +01001140 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -08001141
Andy Hung8d121d42014-10-03 09:53:53 -07001142 handleFlushComplete(audio, true /* isDecoder */);
Andreas Huber3831a062010-12-21 10:22:33 -08001143 finishFlushIfPossible();
Chong Zhang7137ec72014-11-12 16:41:05 -08001144 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
Lajos Molnar1cd13982014-01-17 15:12:51 -08001145 sp<AMessage> format;
1146 CHECK(msg->findMessage("format", &format));
1147
Wei Jiac6cfd702014-11-11 16:33:20 -08001148 sp<AMessage> inputFormat =
1149 mSource->getFormat(false /* audio */);
Andreas Huber3831a062010-12-21 10:22:33 -08001150
Bartosz Dolewski26936f72014-12-11 12:47:08 +01001151 setVideoScalingMode(mVideoScalingMode);
Wei Jiac6cfd702014-11-11 16:33:20 -08001152 updateVideoSize(inputFormat, format);
Chong Zhang7137ec72014-11-12 16:41:05 -08001153 } else if (what == DecoderBase::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +01001154 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -08001155 if (audio) {
Ray Essickfcb8fd32018-08-07 09:39:38 -07001156 Mutex::Autolock autoLock(mDecoderLock);
Andreas Huber3831a062010-12-21 10:22:33 -08001157 mAudioDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001158 mAudioDecoderError = false;
Wei Jia57568df2014-09-22 10:16:29 -07001159 ++mAudioDecoderGeneration;
Andreas Huber3831a062010-12-21 10:22:33 -08001160
1161 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1162 mFlushingAudio = SHUT_DOWN;
1163 } else {
Ray Essickfcb8fd32018-08-07 09:39:38 -07001164 Mutex::Autolock autoLock(mDecoderLock);
Andreas Huber3831a062010-12-21 10:22:33 -08001165 mVideoDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001166 mVideoDecoderError = false;
Wei Jia57568df2014-09-22 10:16:29 -07001167 ++mVideoDecoderGeneration;
Andreas Huber3831a062010-12-21 10:22:33 -08001168
1169 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1170 mFlushingVideo = SHUT_DOWN;
1171 }
1172
1173 finishFlushIfPossible();
Chong Zhangf8d71772014-11-26 15:08:34 -08001174 } else if (what == DecoderBase::kWhatResumeCompleted) {
1175 finishResume();
Chong Zhang7137ec72014-11-12 16:41:05 -08001176 } else if (what == DecoderBase::kWhatError) {
Chong Zhangf4c0a942014-08-11 15:14:10 -07001177 status_t err;
Andy Hung2abde2c2014-09-30 14:40:32 -07001178 if (!msg->findInt32("err", &err) || err == OK) {
Chong Zhangf4c0a942014-08-11 15:14:10 -07001179 err = UNKNOWN_ERROR;
1180 }
Andy Hungcf31f1e2014-09-23 14:59:01 -07001181
Andy Hung2abde2c2014-09-30 14:40:32 -07001182 // Decoder errors can be due to Source (e.g. from streaming),
1183 // or from decoding corrupted bitstreams, or from other decoder
1184 // MediaCodec operations (e.g. from an ongoing reset or seek).
Andy Hung202bce12014-12-03 11:47:36 -08001185 // They may also be due to openAudioSink failure at
1186 // decoder start or after a format change.
Andy Hung2abde2c2014-09-30 14:40:32 -07001187 //
1188 // We try to gracefully shut down the affected decoder if possible,
1189 // rather than trying to force the shutdown with something
1190 // similar to performReset(). This method can lead to a hang
1191 // if MediaCodec functions block after an error, but they should
1192 // typically return INVALID_OPERATION instead of blocking.
1193
1194 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1195 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1196 err, audio ? "audio" : "video", *flushing);
1197
1198 switch (*flushing) {
1199 case NONE:
1200 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001201 new FlushDecoderAction(
1202 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1203 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
Andy Hung2abde2c2014-09-30 14:40:32 -07001204 processDeferredActions();
1205 break;
1206 case FLUSHING_DECODER:
1207 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1208 break; // Wait for flush to complete.
1209 case FLUSHING_DECODER_SHUTDOWN:
1210 break; // Wait for flush to complete.
1211 case SHUTTING_DOWN_DECODER:
1212 break; // Wait for shutdown to complete.
1213 case FLUSHED:
Andy Hung2abde2c2014-09-30 14:40:32 -07001214 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1215 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1216 break;
1217 case SHUT_DOWN:
1218 finishFlushIfPossible(); // Should not occur.
1219 break; // Finish anyways.
Marco Nelissen9e2b7912014-08-18 16:13:03 -07001220 }
Wei Jia686e8e52017-04-03 14:08:01 -07001221 if (mSource != nullptr) {
1222 if (audio) {
Wei Jia2f6d8c52017-04-11 09:50:31 -07001223 if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
Wei Jiaf86731d2017-07-11 17:24:34 -07001224 || mSurface == NULL || mVideoDecoder == NULL) {
Wei Jia686e8e52017-04-03 14:08:01 -07001225 // When both audio and video have error, or this stream has only audio
1226 // which has error, notify client of error.
1227 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1228 } else {
1229 // Only audio track has error. Video track could be still good to play.
1230 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_AUDIO_ERROR, err);
1231 }
1232 mAudioDecoderError = true;
1233 } else {
Wei Jia2f6d8c52017-04-11 09:50:31 -07001234 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
Wei Jiaf86731d2017-07-11 17:24:34 -07001235 || mAudioSink == NULL || mAudioDecoder == NULL) {
Wei Jia686e8e52017-04-03 14:08:01 -07001236 // When both audio and video have error, or this stream has only video
1237 // which has error, notify client of error.
1238 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1239 } else {
1240 // Only video track has error. Audio track could be still good to play.
1241 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_VIDEO_ERROR, err);
1242 }
1243 mVideoDecoderError = true;
1244 }
1245 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001246 } else {
1247 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001248 what,
1249 what >> 24,
1250 (what >> 16) & 0xff,
1251 (what >> 8) & 0xff,
1252 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -08001253 }
1254
1255 break;
1256 }
1257
1258 case kWhatRendererNotify:
1259 {
Wei Jia57568df2014-09-22 10:16:29 -07001260 int32_t requesterGeneration = mRendererGeneration - 1;
1261 CHECK(msg->findInt32("generation", &requesterGeneration));
1262 if (requesterGeneration != mRendererGeneration) {
1263 ALOGV("got message from old renderer, generation(%d:%d)",
1264 requesterGeneration, mRendererGeneration);
1265 return;
1266 }
1267
Andreas Huberf9334412010-12-15 15:17:42 -08001268 int32_t what;
1269 CHECK(msg->findInt32("what", &what));
1270
1271 if (what == Renderer::kWhatEOS) {
1272 int32_t audio;
1273 CHECK(msg->findInt32("audio", &audio));
1274
Andreas Huberc92fd242011-08-16 13:48:44 -07001275 int32_t finalResult;
1276 CHECK(msg->findInt32("finalResult", &finalResult));
1277
Andreas Huberf9334412010-12-15 15:17:42 -08001278 if (audio) {
1279 mAudioEOS = true;
1280 } else {
1281 mVideoEOS = true;
1282 }
1283
Andreas Huberc92fd242011-08-16 13:48:44 -07001284 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +01001285 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -07001286 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001287 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -07001288 audio ? "audio" : "video", finalResult);
1289
1290 notifyListener(
1291 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
1292 }
Andreas Huberf9334412010-12-15 15:17:42 -08001293
1294 if ((mAudioEOS || mAudioDecoder == NULL)
1295 && (mVideoEOS || mVideoDecoder == NULL)) {
1296 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1297 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001298 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -08001299 int32_t audio;
1300 CHECK(msg->findInt32("audio", &audio));
1301
Wei Jia3261f0d2015-10-08 13:58:33 -07001302 if (audio) {
1303 mAudioEOS = false;
1304 } else {
1305 mVideoEOS = false;
1306 }
1307
Steve Block3856b092011-10-20 11:56:00 +01001308 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
Wei Jiada4252f2015-07-14 18:15:28 -07001309 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1310 || mFlushingAudio == SHUT_DOWN)) {
1311 // Flush has been handled by tear down.
1312 break;
1313 }
Andy Hung8d121d42014-10-03 09:53:53 -07001314 handleFlushComplete(audio, false /* isDecoder */);
1315 finishFlushIfPossible();
James Dongf57b4ea2012-07-20 13:38:36 -07001316 } else if (what == Renderer::kWhatVideoRenderingStart) {
1317 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Lajos Molnarcbaffcf2013-08-14 18:30:38 -07001318 } else if (what == Renderer::kWhatMediaRenderingStart) {
1319 ALOGV("media rendering started");
1320 notifyListener(MEDIA_STARTED, 0, 0);
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001321 } else if (what == Renderer::kWhatAudioTearDown) {
Ronghua Wu08529172014-10-02 16:55:52 -07001322 int32_t reason;
1323 CHECK(msg->findInt32("reason", &reason));
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001324 ALOGV("Tear down audio with reason %d.", reason);
Wei Jia8456ddd2016-04-22 14:46:43 -07001325 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1326 // TimeoutWhenPaused is only for offload mode.
Wei Jia355b2bb2018-04-09 16:36:23 -07001327 ALOGW("Received a stale message for teardown, mPaused(%d), mOffloadAudio(%d)",
1328 mPaused, mOffloadAudio);
Wei Jia8456ddd2016-04-22 14:46:43 -07001329 break;
1330 }
Wei Jiada4252f2015-07-14 18:15:28 -07001331 int64_t positionUs;
Robert Shih1a5c8592015-08-04 18:07:44 -07001332 if (!msg->findInt64("positionUs", &positionUs)) {
1333 positionUs = mPreviousSeekTimeUs;
1334 }
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001335
Wei Jia5031b2f2016-02-25 11:19:31 -08001336 restartAudio(
Wei Jiaa05f1e32016-03-25 16:31:22 -07001337 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1338 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
Andreas Huberf9334412010-12-15 15:17:42 -08001339 }
1340 break;
1341 }
1342
1343 case kWhatMoreDataQueued:
1344 {
1345 break;
1346 }
1347
Andreas Huber1aef2112011-01-04 14:01:29 -08001348 case kWhatReset:
1349 {
Steve Block3856b092011-10-20 11:56:00 +01001350 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -08001351
Ronghua Wu64c2d172015-10-07 16:52:19 -07001352 mResetting = true;
Ray Essickeda32522018-02-28 12:08:28 -08001353 updatePlaybackTimer(true /* stopping */, "kWhatReset");
1354 updateRebufferingTimer(true /* stopping */, true /* exiting */);
Ronghua Wu64c2d172015-10-07 16:52:19 -07001355
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001356 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001357 new FlushDecoderAction(
1358 FLUSH_CMD_SHUTDOWN /* audio */,
1359 FLUSH_CMD_SHUTDOWN /* video */));
Andreas Huberb7c8e912012-11-27 15:02:53 -08001360
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001361 mDeferredActions.push_back(
1362 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -08001363
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001364 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001365 break;
1366 }
1367
Wei Jia52c28512017-09-13 18:17:51 -07001368 case kWhatNotifyTime:
1369 {
1370 ALOGV("kWhatNotifyTime");
1371 int64_t timerUs;
1372 CHECK(msg->findInt64("timerUs", &timerUs));
1373
1374 notifyListener(MEDIA_NOTIFY_TIME, timerUs, 0);
1375 break;
1376 }
1377
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001378 case kWhatSeek:
1379 {
1380 int64_t seekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -08001381 int32_t mode;
Wei Jiae427abf2014-09-22 15:21:11 -07001382 int32_t needNotify;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001383 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
Wei Jiac5de0912016-11-18 10:22:14 -08001384 CHECK(msg->findInt32("mode", &mode));
Wei Jiae427abf2014-09-22 15:21:11 -07001385 CHECK(msg->findInt32("needNotify", &needNotify));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001386
Wei Jiac5de0912016-11-18 10:22:14 -08001387 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1388 (long long)seekTimeUs, mode, needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001389
Wei Jia1061c9c2015-05-19 16:02:17 -07001390 if (!mStarted) {
1391 // Seek before the player is started. In order to preview video,
1392 // need to start the player and pause it. This branch is called
1393 // only once if needed. After the player is started, any seek
1394 // operation will go through normal path.
Robert Shih0c61a0d2015-07-06 15:09:10 -07001395 // Audio-only cases are handled separately.
Wei Jiac5de0912016-11-18 10:22:14 -08001396 onStart(seekTimeUs, (MediaPlayerSeekMode)mode);
Robert Shih0c61a0d2015-07-06 15:09:10 -07001397 if (mStarted) {
1398 onPause();
1399 mPausedByClient = true;
1400 }
Wei Jia1061c9c2015-05-19 16:02:17 -07001401 if (needNotify) {
1402 notifyDriverSeekComplete();
1403 }
1404 break;
1405 }
1406
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001407 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001408 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1409 FLUSH_CMD_FLUSH /* video */));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001410
Wei Jiae427abf2014-09-22 15:21:11 -07001411 mDeferredActions.push_back(
Wei Jiac5de0912016-11-18 10:22:14 -08001412 new SeekAction(seekTimeUs, (MediaPlayerSeekMode)mode));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001413
Chong Zhangf8d71772014-11-26 15:08:34 -08001414 // After a flush without shutdown, decoder is paused.
1415 // Don't resume it until source seek is done, otherwise it could
Chong Zhang7137ec72014-11-12 16:41:05 -08001416 // start pulling stale data too soon.
1417 mDeferredActions.push_back(
Chong Zhangf8d71772014-11-26 15:08:34 -08001418 new ResumeDecoderAction(needNotify));
Chong Zhang7137ec72014-11-12 16:41:05 -08001419
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001420 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001421 break;
1422 }
1423
Andreas Huberb4082222011-01-20 15:23:04 -08001424 case kWhatPause:
1425 {
Chong Zhangefbb6192015-01-30 17:13:27 -08001426 onPause();
1427 mPausedByClient = true;
Andreas Huberb4082222011-01-20 15:23:04 -08001428 break;
1429 }
1430
Andreas Huberb5f25f02013-02-05 10:14:26 -08001431 case kWhatSourceNotify:
1432 {
Andreas Huber9575c962013-02-05 13:59:56 -08001433 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -08001434 break;
1435 }
1436
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001437 case kWhatClosedCaptionNotify:
1438 {
1439 onClosedCaptionNotify(msg);
1440 break;
1441 }
1442
Hassan Shojaniacefac142017-02-06 21:02:02 -08001443 case kWhatPrepareDrm:
1444 {
1445 status_t status = onPrepareDrm(msg);
1446
1447 sp<AMessage> response = new AMessage;
1448 response->setInt32("status", status);
1449 sp<AReplyToken> replyID;
1450 CHECK(msg->senderAwaitsResponse(&replyID));
1451 response->postReply(replyID);
1452 break;
1453 }
1454
1455 case kWhatReleaseDrm:
1456 {
1457 status_t status = onReleaseDrm();
1458
1459 sp<AMessage> response = new AMessage;
1460 response->setInt32("status", status);
1461 sp<AReplyToken> replyID;
1462 CHECK(msg->senderAwaitsResponse(&replyID));
1463 response->postReply(replyID);
1464 break;
1465 }
1466
Dongwon Kang47afe0a2018-03-27 15:15:30 -07001467 case kWhatMediaClockNotify:
1468 {
1469 ALOGV("kWhatMediaClockNotify");
1470 int64_t anchorMediaUs, anchorRealUs;
1471 float playbackRate;
1472 CHECK(msg->findInt64("anchor-media-us", &anchorMediaUs));
1473 CHECK(msg->findInt64("anchor-real-us", &anchorRealUs));
1474 CHECK(msg->findFloat("playback-rate", &playbackRate));
1475
1476 Parcel in;
1477 in.writeInt64(anchorMediaUs);
1478 in.writeInt64(anchorRealUs);
1479 in.writeFloat(playbackRate);
1480
1481 notifyListener(MEDIA_TIME_DISCONTINUITY, 0, 0, &in);
1482 break;
1483 }
1484
Andreas Huberf9334412010-12-15 15:17:42 -08001485 default:
1486 TRESPASS();
1487 break;
1488 }
1489}
1490
Wei Jia94211742014-10-28 17:09:06 -07001491void NuPlayer::onResume() {
Ronghua Wu64c2d172015-10-07 16:52:19 -07001492 if (!mPaused || mResetting) {
1493 ALOGD_IF(mResetting, "resetting, onResume discarded");
Chong Zhangefbb6192015-01-30 17:13:27 -08001494 return;
1495 }
1496 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001497 if (mSource != NULL) {
1498 mSource->resume();
1499 } else {
1500 ALOGW("resume called when source is gone or not set");
1501 }
1502 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1503 // needed.
1504 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1505 instantiateDecoder(true /* audio */, &mAudioDecoder);
1506 }
1507 if (mRenderer != NULL) {
1508 mRenderer->resume();
1509 } else {
1510 ALOGW("resume called when renderer is gone or not set");
1511 }
Ray Essickd4d00612017-01-03 09:36:27 -08001512
Ray Essick0d98c182017-11-09 13:42:42 -08001513 startPlaybackTimer("onresume");
Wei Jia94211742014-10-28 17:09:06 -07001514}
1515
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001516status_t NuPlayer::onInstantiateSecureDecoders() {
1517 status_t err;
1518 if (!(mSourceFlags & Source::FLAG_SECURE)) {
1519 return BAD_TYPE;
1520 }
1521
1522 if (mRenderer != NULL) {
1523 ALOGE("renderer should not be set when instantiating secure decoders");
1524 return UNKNOWN_ERROR;
1525 }
1526
1527 // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
1528 // data on instantiation.
Lajos Molnar1de1e252015-04-30 18:18:34 -07001529 if (mSurface != NULL) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001530 err = instantiateDecoder(false, &mVideoDecoder);
1531 if (err != OK) {
1532 return err;
1533 }
1534 }
1535
1536 if (mAudioSink != NULL) {
1537 err = instantiateDecoder(true, &mAudioDecoder);
1538 if (err != OK) {
1539 return err;
1540 }
1541 }
1542 return OK;
1543}
1544
Wei Jiac5de0912016-11-18 10:22:14 -08001545void NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08001546 ALOGV("onStart: mCrypto: %p (%d)", mCrypto.get(),
1547 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
1548
Robert Shih0c61a0d2015-07-06 15:09:10 -07001549 if (!mSourceStarted) {
1550 mSourceStarted = true;
1551 mSource->start();
1552 }
1553 if (startPositionUs > 0) {
Wei Jiac5de0912016-11-18 10:22:14 -08001554 performSeek(startPositionUs, mode);
Robert Shih0c61a0d2015-07-06 15:09:10 -07001555 if (mSource->getFormat(false /* audio */) == NULL) {
1556 return;
1557 }
1558 }
1559
Wei Jia94211742014-10-28 17:09:06 -07001560 mOffloadAudio = false;
1561 mAudioEOS = false;
1562 mVideoEOS = false;
Wei Jia94211742014-10-28 17:09:06 -07001563 mStarted = true;
Wei Jiafe8fe7d2016-06-08 10:29:25 -07001564 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001565
Wei Jia94211742014-10-28 17:09:06 -07001566 uint32_t flags = 0;
1567
1568 if (mSource->isRealTime()) {
1569 flags |= Renderer::FLAG_REAL_TIME;
1570 }
1571
Wei Jia9737d342016-12-28 14:59:59 -08001572 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1573 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1574 if (!hasAudio && !hasVideo) {
Wei Jia1de83d52016-10-10 10:15:03 -07001575 ALOGE("no metadata for either audio or video source");
1576 mSource->stop();
1577 mSourceStarted = false;
1578 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_MALFORMED);
1579 return;
1580 }
Wei Jia9737d342016-12-28 14:59:59 -08001581 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1582
1583 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
Wei Jia1de83d52016-10-10 10:15:03 -07001584
Wei Jia94211742014-10-28 17:09:06 -07001585 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1586 if (mAudioSink != NULL) {
1587 streamType = mAudioSink->getAudioStreamType();
1588 }
1589
Wei Jia94211742014-10-28 17:09:06 -07001590 mOffloadAudio =
Wei Jia9737d342016-12-28 14:59:59 -08001591 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
Wei Jiabf70feb2016-02-19 15:47:16 -08001592 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001593
1594 // Modular DRM: Disabling audio offload if the source is protected
1595 if (mOffloadAudio && mIsDrmProtected) {
1596 mOffloadAudio = false;
1597 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1598 }
1599
Wei Jia94211742014-10-28 17:09:06 -07001600 if (mOffloadAudio) {
1601 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1602 }
1603
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001604 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
Wei Jia94211742014-10-28 17:09:06 -07001605 ++mRendererGeneration;
1606 notify->setInt32("generation", mRendererGeneration);
Wei Jia0a68f662017-08-30 18:01:26 -07001607 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
Wei Jia94211742014-10-28 17:09:06 -07001608 mRendererLooper = new ALooper;
1609 mRendererLooper->setName("NuPlayerRenderer");
1610 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1611 mRendererLooper->registerHandler(mRenderer);
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001612
1613 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1614 if (err != OK) {
1615 mSource->stop();
Robert Shih0c61a0d2015-07-06 15:09:10 -07001616 mSourceStarted = false;
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001617 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1618 return;
Wei Jiac8206ff2015-03-04 13:59:37 -08001619 }
Wei Jia94211742014-10-28 17:09:06 -07001620
Ronghua Wuc8a70d32015-04-29 16:26:34 -07001621 float rate = getFrameRate();
1622 if (rate > 0) {
Wei Jia94211742014-10-28 17:09:06 -07001623 mRenderer->setVideoFrameRate(rate);
1624 }
1625
Wei Jiac6cfd702014-11-11 16:33:20 -08001626 if (mVideoDecoder != NULL) {
1627 mVideoDecoder->setRenderer(mRenderer);
1628 }
1629 if (mAudioDecoder != NULL) {
1630 mAudioDecoder->setRenderer(mRenderer);
1631 }
1632
Ray Essick0d98c182017-11-09 13:42:42 -08001633 startPlaybackTimer("onstart");
Ray Essickd4d00612017-01-03 09:36:27 -08001634
Wei Jia94211742014-10-28 17:09:06 -07001635 postScanSources();
1636}
1637
Ray Essick0d98c182017-11-09 13:42:42 -08001638void NuPlayer::startPlaybackTimer(const char *where) {
1639 Mutex::Autolock autoLock(mPlayingTimeLock);
1640 if (mLastStartedPlayingTimeNs == 0) {
1641 mLastStartedPlayingTimeNs = systemTime();
1642 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1643 }
1644}
1645
Ray Essickeda32522018-02-28 12:08:28 -08001646void NuPlayer::updatePlaybackTimer(bool stopping, const char *where) {
Ray Essick0d98c182017-11-09 13:42:42 -08001647 Mutex::Autolock autoLock(mPlayingTimeLock);
1648
Ray Essickeda32522018-02-28 12:08:28 -08001649 ALOGV("updatePlaybackTimer(%s) time %20" PRId64 " (%s)",
1650 stopping ? "stop" : "snap", mLastStartedPlayingTimeNs, where);
Ray Essick0d98c182017-11-09 13:42:42 -08001651
1652 if (mLastStartedPlayingTimeNs != 0) {
1653 sp<NuPlayerDriver> driver = mDriver.promote();
Ray Essickeda32522018-02-28 12:08:28 -08001654 int64_t now = systemTime();
Ray Essick0d98c182017-11-09 13:42:42 -08001655 if (driver != NULL) {
Ray Essick0d98c182017-11-09 13:42:42 -08001656 int64_t played = now - mLastStartedPlayingTimeNs;
Ray Essickeda32522018-02-28 12:08:28 -08001657 ALOGV("updatePlaybackTimer() log %20" PRId64 "", played);
Ray Essick0d98c182017-11-09 13:42:42 -08001658
1659 if (played > 0) {
1660 driver->notifyMorePlayingTimeUs((played+500)/1000);
1661 }
1662 }
Ray Essickeda32522018-02-28 12:08:28 -08001663 if (stopping) {
1664 mLastStartedPlayingTimeNs = 0;
1665 } else {
1666 mLastStartedPlayingTimeNs = now;
1667 }
Ray Essick0d98c182017-11-09 13:42:42 -08001668 }
1669}
1670
Ray Essick58e0f7a2017-11-21 10:59:38 -08001671void NuPlayer::startRebufferingTimer() {
1672 Mutex::Autolock autoLock(mPlayingTimeLock);
1673 if (mLastStartedRebufferingTimeNs == 0) {
1674 mLastStartedRebufferingTimeNs = systemTime();
1675 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1676 }
1677}
1678
Ray Essickeda32522018-02-28 12:08:28 -08001679void NuPlayer::updateRebufferingTimer(bool stopping, bool exitingPlayback) {
Ray Essick58e0f7a2017-11-21 10:59:38 -08001680 Mutex::Autolock autoLock(mPlayingTimeLock);
1681
Ray Essickeda32522018-02-28 12:08:28 -08001682 ALOGV("updateRebufferingTimer(%s) time %20" PRId64 " (exiting %d)",
1683 stopping ? "stop" : "snap", mLastStartedRebufferingTimeNs, exitingPlayback);
Ray Essick58e0f7a2017-11-21 10:59:38 -08001684
1685 if (mLastStartedRebufferingTimeNs != 0) {
1686 sp<NuPlayerDriver> driver = mDriver.promote();
Ray Essickeda32522018-02-28 12:08:28 -08001687 int64_t now = systemTime();
Ray Essick58e0f7a2017-11-21 10:59:38 -08001688 if (driver != NULL) {
Ray Essick58e0f7a2017-11-21 10:59:38 -08001689 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
Ray Essickeda32522018-02-28 12:08:28 -08001690 ALOGV("updateRebufferingTimer() log %20" PRId64 "", rebuffered);
Ray Essick58e0f7a2017-11-21 10:59:38 -08001691
1692 if (rebuffered > 0) {
1693 driver->notifyMoreRebufferingTimeUs((rebuffered+500)/1000);
1694 if (exitingPlayback) {
1695 driver->notifyRebufferingWhenExit(true);
1696 }
1697 }
1698 }
Ray Essickeda32522018-02-28 12:08:28 -08001699 if (stopping) {
1700 mLastStartedRebufferingTimeNs = 0;
1701 } else {
1702 mLastStartedRebufferingTimeNs = now;
1703 }
Ray Essick58e0f7a2017-11-21 10:59:38 -08001704 }
1705}
1706
Ray Essickeda32522018-02-28 12:08:28 -08001707void NuPlayer::updateInternalTimers() {
1708 // update values, but ticking clocks keep ticking
1709 ALOGV("updateInternalTimers()");
1710 updatePlaybackTimer(false /* stopping */, "updateInternalTimers");
1711 updateRebufferingTimer(false /* stopping */, false /* exiting */);
1712}
1713
Kim Sungyeon23b23932019-07-18 17:48:32 +09001714void NuPlayer::setTargetBitrate(int bitrate) {
Lajos Molnared809da2020-08-17 16:53:02 -07001715 if (mSource != NULL) {
Kim Sungyeon23b23932019-07-18 17:48:32 +09001716 mSource->setTargetBitrate(bitrate);
Lajos Molnared809da2020-08-17 16:53:02 -07001717 }
Kim Sungyeon23b23932019-07-18 17:48:32 +09001718}
1719
Chong Zhangefbb6192015-01-30 17:13:27 -08001720void NuPlayer::onPause() {
Ray Essick0d98c182017-11-09 13:42:42 -08001721
Ray Essickeda32522018-02-28 12:08:28 -08001722 updatePlaybackTimer(true /* stopping */, "onPause");
Ray Essick0d98c182017-11-09 13:42:42 -08001723
Chong Zhangefbb6192015-01-30 17:13:27 -08001724 if (mPaused) {
1725 return;
1726 }
1727 mPaused = true;
1728 if (mSource != NULL) {
1729 mSource->pause();
1730 } else {
1731 ALOGW("pause called when source is gone or not set");
1732 }
1733 if (mRenderer != NULL) {
1734 mRenderer->pause();
1735 } else {
1736 ALOGW("pause called when renderer is gone or not set");
1737 }
Ray Essickd4d00612017-01-03 09:36:27 -08001738
Chong Zhangefbb6192015-01-30 17:13:27 -08001739}
1740
Ronghua Wud7988b12014-10-03 15:19:10 -07001741bool NuPlayer::audioDecoderStillNeeded() {
1742 // Audio decoder is no longer needed if it's in shut/shutting down status.
1743 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1744}
1745
Andy Hung8d121d42014-10-03 09:53:53 -07001746void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1747 // We wait for both the decoder flush and the renderer flush to complete
1748 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1749
1750 mFlushComplete[audio][isDecoder] = true;
1751 if (!mFlushComplete[audio][!isDecoder]) {
1752 return;
1753 }
1754
1755 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1756 switch (*state) {
1757 case FLUSHING_DECODER:
1758 {
1759 *state = FLUSHED;
Andy Hung8d121d42014-10-03 09:53:53 -07001760 break;
1761 }
1762
1763 case FLUSHING_DECODER_SHUTDOWN:
1764 {
1765 *state = SHUTTING_DOWN_DECODER;
1766
1767 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
Andy Hung8d121d42014-10-03 09:53:53 -07001768 getDecoder(audio)->initiateShutdown();
1769 break;
1770 }
1771
1772 default:
1773 // decoder flush completes only occur in a flushing state.
1774 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1775 break;
1776 }
1777}
1778
Andreas Huber3831a062010-12-21 10:22:33 -08001779void NuPlayer::finishFlushIfPossible() {
Wei Jia53904f32014-07-29 10:22:53 -07001780 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1781 && mFlushingAudio != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001782 return;
1783 }
1784
Wei Jia53904f32014-07-29 10:22:53 -07001785 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1786 && mFlushingVideo != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001787 return;
1788 }
1789
Steve Block3856b092011-10-20 11:56:00 +01001790 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -08001791
Andreas Huber3831a062010-12-21 10:22:33 -08001792 mFlushingAudio = NONE;
1793 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -08001794
Andy Hung8d121d42014-10-03 09:53:53 -07001795 clearFlushComplete();
1796
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001797 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001798}
1799
1800void NuPlayer::postScanSources() {
1801 if (mScanSourcesPending) {
1802 return;
1803 }
1804
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001805 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
Andreas Huber1aef2112011-01-04 14:01:29 -08001806 msg->setInt32("generation", mScanSourcesGeneration);
1807 msg->post();
1808
1809 mScanSourcesPending = true;
1810}
1811
Wei Jia41cd4632016-05-13 10:53:30 -07001812void NuPlayer::tryOpenAudioSinkForOffload(
1813 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
Andy Hung202bce12014-12-03 11:47:36 -08001814 // Note: This is called early in NuPlayer to determine whether offloading
1815 // is possible; otherwise the decoders call the renderer openAudioSink directly.
Andy Hung282a7e32014-08-14 15:56:34 -07001816
Andy Hung202bce12014-12-03 11:47:36 -08001817 status_t err = mRenderer->openAudioSink(
Dhananjay Kumarc387f2b2015-08-06 10:43:16 +05301818 format, true /* offloadOnly */, hasVideo,
1819 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
Andy Hung202bce12014-12-03 11:47:36 -08001820 if (err != OK) {
1821 // Any failure we turn off mOffloadAudio.
1822 mOffloadAudio = false;
1823 } else if (mOffloadAudio) {
Chong Zhang3b9eb1f2014-10-15 17:05:08 -07001824 sendMetaDataToHal(mAudioSink, audioMeta);
Andy Hung282a7e32014-08-14 15:56:34 -07001825 }
1826}
1827
1828void NuPlayer::closeAudioSink() {
Daniel Norman1e0d88b2020-01-07 15:02:54 -08001829 if (mRenderer != NULL) {
1830 mRenderer->closeAudioSink();
1831 }
Andy Hung282a7e32014-08-14 15:56:34 -07001832}
1833
Wei Jia5031b2f2016-02-25 11:19:31 -08001834void NuPlayer::restartAudio(
Wei Jiabf70feb2016-02-19 15:47:16 -08001835 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
Wei Jia355b2bb2018-04-09 16:36:23 -07001836 ALOGD("restartAudio timeUs(%lld), dontOffload(%d), createDecoder(%d)",
1837 (long long)currentPositionUs, forceNonOffload, needsToCreateAudioDecoder);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001838 if (mAudioDecoder != NULL) {
1839 mAudioDecoder->pause();
Ray Essickfcb8fd32018-08-07 09:39:38 -07001840 Mutex::Autolock autoLock(mDecoderLock);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001841 mAudioDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001842 mAudioDecoderError = false;
Wei Jiaa05f1e32016-03-25 16:31:22 -07001843 ++mAudioDecoderGeneration;
1844 }
Wei Jiabf70feb2016-02-19 15:47:16 -08001845 if (mFlushingAudio == FLUSHING_DECODER) {
1846 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1847 mFlushingAudio = FLUSHED;
1848 finishFlushIfPossible();
1849 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1850 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1851 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1852 mFlushingAudio = SHUT_DOWN;
1853 finishFlushIfPossible();
1854 needsToCreateAudioDecoder = false;
1855 }
1856 if (mRenderer == NULL) {
1857 return;
1858 }
1859 closeAudioSink();
1860 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1861 if (mVideoDecoder != NULL) {
Praveen Chavaneca08fb2019-01-21 11:00:38 -08001862 mDeferredActions.push_back(
1863 new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
1864 FLUSH_CMD_FLUSH /* video */));
1865 mDeferredActions.push_back(
1866 new SeekAction(currentPositionUs,
1867 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
1868 // After a flush without shutdown, decoder is paused.
1869 // Don't resume it until source seek is done, otherwise it could
1870 // start pulling stale data too soon.
1871 mDeferredActions.push_back(new ResumeDecoderAction(false));
1872 processDeferredActions();
1873 } else {
1874 performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
Wei Jiabf70feb2016-02-19 15:47:16 -08001875 }
1876
Wei Jiabf70feb2016-02-19 15:47:16 -08001877 if (forceNonOffload) {
1878 mRenderer->signalDisableOffloadAudio();
1879 mOffloadAudio = false;
1880 }
1881 if (needsToCreateAudioDecoder) {
Wei Jiaa05f1e32016-03-25 16:31:22 -07001882 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
Wei Jiabf70feb2016-02-19 15:47:16 -08001883 }
1884}
1885
Wei Jia41cd4632016-05-13 10:53:30 -07001886void NuPlayer::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiae4d18c72015-07-13 17:58:11 -07001887 if (mSource == NULL || mAudioSink == NULL) {
1888 return;
1889 }
1890
1891 if (mRenderer == NULL) {
1892 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1893 mOffloadAudio = false;
1894 return;
1895 }
1896
1897 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1898 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1899 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1900 const bool hasVideo = (videoFormat != NULL);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001901 bool canOffload = canOffloadStream(
Wei Jiabf70feb2016-02-19 15:47:16 -08001902 audioMeta, hasVideo, mSource->isStreaming(), streamType)
1903 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001904
1905 // Modular DRM: Disabling audio offload if the source is protected
1906 if (canOffload && mIsDrmProtected) {
1907 canOffload = false;
1908 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1909 }
1910
Wei Jiae4d18c72015-07-13 17:58:11 -07001911 if (canOffload) {
1912 if (!mOffloadAudio) {
1913 mRenderer->signalEnableOffloadAudio();
1914 }
1915 // open audio sink early under offload mode.
Wei Jia41cd4632016-05-13 10:53:30 -07001916 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
Wei Jiae4d18c72015-07-13 17:58:11 -07001917 } else {
Robert Shihe1d70192015-07-23 17:54:13 -07001918 if (mOffloadAudio) {
1919 mRenderer->signalDisableOffloadAudio();
1920 mOffloadAudio = false;
1921 }
Wei Jiae4d18c72015-07-13 17:58:11 -07001922 }
1923}
1924
Wei Jiaa05f1e32016-03-25 16:31:22 -07001925status_t NuPlayer::instantiateDecoder(
1926 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
Wei Jia566da802015-08-27 13:59:30 -07001927 // The audio decoder could be cleared by tear down. If still in shut down
1928 // process, no need to create a new audio decoder.
1929 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
Andreas Huberf9334412010-12-15 15:17:42 -08001930 return OK;
1931 }
1932
Andreas Huber84066782011-08-16 09:34:26 -07001933 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -08001934
Andreas Huber84066782011-08-16 09:34:26 -07001935 if (format == NULL) {
Robert Shih7350b052015-10-01 15:50:14 -07001936 return UNKNOWN_ERROR;
1937 } else {
1938 status_t err;
1939 if (format->findInt32("err", &err) && err) {
1940 return err;
1941 }
Andreas Huberf9334412010-12-15 15:17:42 -08001942 }
1943
Ronghua Wu8db88132015-04-22 13:51:35 -07001944 format->setInt32("priority", 0 /* realtime */);
1945
Byeongjo Park5e27b1b2018-07-12 15:36:03 +09001946 if (mDataSourceType == DATA_SOURCE_TYPE_RTP) {
1947 ALOGV("instantiateDecoder: set decoder error free on stream corrupt.");
1948 format->setInt32("corrupt-free", true);
1949 }
1950
Andreas Huber3fe62152011-09-16 15:09:22 -07001951 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -07001952 AString mime;
1953 CHECK(format->findString("mime", &mime));
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001954
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001955 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
Chong Zhang341ab6e2015-02-04 13:37:18 -08001956 if (mCCDecoder == NULL) {
1957 mCCDecoder = new CCDecoder(ccNotify);
1958 }
Lajos Molnar09524832014-07-17 14:29:51 -07001959
1960 if (mSourceFlags & Source::FLAG_SECURE) {
1961 format->setInt32("secure", true);
1962 }
Chong Zhang17134602015-01-07 16:14:34 -08001963
1964 if (mSourceFlags & Source::FLAG_PROTECTED) {
1965 format->setInt32("protected", true);
1966 }
Ronghua Wu8db88132015-04-22 13:51:35 -07001967
Ronghua Wuc8a70d32015-04-29 16:26:34 -07001968 float rate = getFrameRate();
1969 if (rate > 0) {
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001970 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
Ronghua Wu8db88132015-04-22 13:51:35 -07001971 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001972 }
1973
Ray Essickfcb8fd32018-08-07 09:39:38 -07001974 Mutex::Autolock autoLock(mDecoderLock);
1975
Wei Jiabc2fb722014-07-08 16:37:57 -07001976 if (audio) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001977 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07001978 ++mAudioDecoderGeneration;
1979 notify->setInt32("generation", mAudioDecoderGeneration);
1980
Wei Jiaa05f1e32016-03-25 16:31:22 -07001981 if (checkAudioModeChange) {
Wei Jia41cd4632016-05-13 10:53:30 -07001982 determineAudioModeChange(format);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001983 }
Wei Jiabc2fb722014-07-08 16:37:57 -07001984 if (mOffloadAudio) {
Wei Jia14532f22015-12-29 11:28:15 -08001985 mSource->setOffloadAudio(true /* offload */);
1986
Haynes Mathew George8b635332015-03-30 17:59:47 -07001987 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1988 format->setInt32("has-video", hasVideo);
Wei Jiac6cfd702014-11-11 16:33:20 -08001989 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001990 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
Wei Jiabc2fb722014-07-08 16:37:57 -07001991 } else {
Wei Jia14532f22015-12-29 11:28:15 -08001992 mSource->setOffloadAudio(false /* offload */);
1993
Wei Jiaf2ae3e12016-10-27 17:10:59 -07001994 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001995 ALOGV("instantiateDecoder audio Decoder");
Wei Jiabc2fb722014-07-08 16:37:57 -07001996 }
Wei Jia686e8e52017-04-03 14:08:01 -07001997 mAudioDecoderError = false;
Wei Jiabc2fb722014-07-08 16:37:57 -07001998 } else {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001999 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07002000 ++mVideoDecoderGeneration;
2001 notify->setInt32("generation", mVideoDecoderGeneration);
2002
Chong Zhang7137ec72014-11-12 16:41:05 -08002003 *decoder = new Decoder(
Wei Jiaf2ae3e12016-10-27 17:10:59 -07002004 notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
Wei Jia686e8e52017-04-03 14:08:01 -07002005 mVideoDecoderError = false;
Lajos Molnard9fd6312014-11-06 11:00:00 -08002006
2007 // enable FRC if high-quality AV sync is requested, even if not
Lajos Molnar1de1e252015-04-30 18:18:34 -07002008 // directly queuing to display, as this will even improve textureview
Lajos Molnard9fd6312014-11-06 11:00:00 -08002009 // playback.
2010 {
Marco Nelissen96626b72016-12-01 13:58:59 -08002011 if (property_get_bool("persist.sys.media.avsync", false)) {
Lajos Molnard9fd6312014-11-06 11:00:00 -08002012 format->setInt32("auto-frc", 1);
2013 }
2014 }
Wei Jiabc2fb722014-07-08 16:37:57 -07002015 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08002016 (*decoder)->init();
Hassan Shojaniacefac142017-02-06 21:02:02 -08002017
2018 // Modular DRM
2019 if (mIsDrmProtected) {
2020 format->setPointer("crypto", mCrypto.get());
2021 ALOGV("instantiateDecoder: mCrypto: %p (%d) isSecure: %d", mCrypto.get(),
2022 (mCrypto != NULL ? mCrypto->getStrongCount() : 0),
2023 (mSourceFlags & Source::FLAG_SECURE) != 0);
2024 }
2025
Andreas Huber84066782011-08-16 09:34:26 -07002026 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -08002027
Praveen Chavanbbaa1442016-04-08 13:33:49 -07002028 if (!audio) {
2029 sp<AMessage> params = new AMessage();
2030 float rate = getFrameRate();
2031 if (rate > 0) {
2032 params->setFloat("frame-rate-total", rate);
2033 }
2034
2035 sp<MetaData> fileMeta = getFileMeta();
2036 if (fileMeta != NULL) {
2037 int32_t videoTemporalLayerCount;
2038 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2039 && videoTemporalLayerCount > 0) {
2040 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2041 }
2042 }
2043
2044 if (params->countEntries() > 0) {
2045 (*decoder)->setParameters(params);
2046 }
2047 }
Andreas Huberf9334412010-12-15 15:17:42 -08002048 return OK;
2049}
2050
Chong Zhangced1c2f2014-08-08 15:22:35 -07002051void NuPlayer::updateVideoSize(
2052 const sp<AMessage> &inputFormat,
2053 const sp<AMessage> &outputFormat) {
2054 if (inputFormat == NULL) {
2055 ALOGW("Unknown video size, reporting 0x0!");
2056 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
2057 return;
2058 }
Wei Jia9737d342016-12-28 14:59:59 -08002059 int32_t err = OK;
2060 inputFormat->findInt32("err", &err);
2061 if (err == -EWOULDBLOCK) {
2062 ALOGW("Video meta is not available yet!");
2063 return;
2064 }
2065 if (err != OK) {
2066 ALOGW("Something is wrong with video meta!");
2067 return;
2068 }
Chong Zhangced1c2f2014-08-08 15:22:35 -07002069
2070 int32_t displayWidth, displayHeight;
Chong Zhangced1c2f2014-08-08 15:22:35 -07002071 if (outputFormat != NULL) {
2072 int32_t width, height;
2073 CHECK(outputFormat->findInt32("width", &width));
2074 CHECK(outputFormat->findInt32("height", &height));
2075
2076 int32_t cropLeft, cropTop, cropRight, cropBottom;
2077 CHECK(outputFormat->findRect(
2078 "crop",
2079 &cropLeft, &cropTop, &cropRight, &cropBottom));
2080
2081 displayWidth = cropRight - cropLeft + 1;
2082 displayHeight = cropBottom - cropTop + 1;
2083
2084 ALOGV("Video output format changed to %d x %d "
2085 "(crop: %d x %d @ (%d, %d))",
2086 width, height,
2087 displayWidth,
2088 displayHeight,
2089 cropLeft, cropTop);
2090 } else {
2091 CHECK(inputFormat->findInt32("width", &displayWidth));
2092 CHECK(inputFormat->findInt32("height", &displayHeight));
2093
2094 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2095 }
2096
2097 // Take into account sample aspect ratio if necessary:
2098 int32_t sarWidth, sarHeight;
2099 if (inputFormat->findInt32("sar-width", &sarWidth)
Wei Jia095bc252017-01-27 10:16:16 -08002100 && inputFormat->findInt32("sar-height", &sarHeight)
2101 && sarWidth > 0 && sarHeight > 0) {
Chong Zhangced1c2f2014-08-08 15:22:35 -07002102 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2103
2104 displayWidth = (displayWidth * sarWidth) / sarHeight;
2105
2106 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
Wei Jiadf6c6af2016-09-29 11:27:15 -07002107 } else {
2108 int32_t width, height;
2109 if (inputFormat->findInt32("display-width", &width)
2110 && inputFormat->findInt32("display-height", &height)
2111 && width > 0 && height > 0
2112 && displayWidth > 0 && displayHeight > 0) {
2113 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2114 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2115 } else {
2116 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2117 }
2118 ALOGV("Video display width and height are overridden to %d x %d",
2119 displayWidth, displayHeight);
2120 }
Chong Zhangced1c2f2014-08-08 15:22:35 -07002121 }
2122
2123 int32_t rotationDegrees;
2124 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2125 rotationDegrees = 0;
2126 }
2127
2128 if (rotationDegrees == 90 || rotationDegrees == 270) {
2129 int32_t tmp = displayWidth;
2130 displayWidth = displayHeight;
2131 displayHeight = tmp;
2132 }
2133
2134 notifyListener(
2135 MEDIA_SET_VIDEO_SIZE,
2136 displayWidth,
2137 displayHeight);
2138}
2139
Chong Zhangdcb89b32013-08-06 09:44:47 -07002140void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002141 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08002142 return;
2143 }
2144
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002145 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08002146
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002147 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08002148 return;
2149 }
2150
Chong Zhangdcb89b32013-08-06 09:44:47 -07002151 driver->notifyListener(msg, ext1, ext2, in);
Andreas Huberf9334412010-12-15 15:17:42 -08002152}
2153
Chong Zhang7137ec72014-11-12 16:41:05 -08002154void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber14f76722013-01-15 09:04:18 -08002155 ALOGV("[%s] flushDecoder needShutdown=%d",
2156 audio ? "audio" : "video", needShutdown);
2157
Chong Zhang7137ec72014-11-12 16:41:05 -08002158 const sp<DecoderBase> &decoder = getDecoder(audio);
Lajos Molnar87603c02014-08-20 19:25:30 -07002159 if (decoder == NULL) {
Steve Blockdf64d152012-01-04 20:05:49 +00002160 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08002161 audio ? "audio" : "video");
Lajos Molnar87603c02014-08-20 19:25:30 -07002162 return;
Andreas Huber6e3d3112011-11-28 12:36:11 -08002163 }
2164
Andreas Huber1aef2112011-01-04 14:01:29 -08002165 // Make sure we don't continue to scan sources until we finish flushing.
2166 ++mScanSourcesGeneration;
Chong Zhang3b032b32015-04-17 15:49:06 -07002167 if (mScanSourcesPending) {
Toshikazu Saitocbcbb792015-09-15 14:53:01 +09002168 if (!needShutdown) {
2169 mDeferredActions.push_back(
2170 new SimpleAction(&NuPlayer::performScanSources));
2171 }
Chong Zhang3b032b32015-04-17 15:49:06 -07002172 mScanSourcesPending = false;
2173 }
Andreas Huber1aef2112011-01-04 14:01:29 -08002174
Chong Zhang7137ec72014-11-12 16:41:05 -08002175 decoder->signalFlush();
Andreas Huber1aef2112011-01-04 14:01:29 -08002176
2177 FlushStatus newStatus =
2178 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2179
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002180 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
Andy Hung8d121d42014-10-03 09:53:53 -07002181 mFlushComplete[audio][true /* isDecoder */] = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08002182 if (audio) {
Wei Jia53904f32014-07-29 10:22:53 -07002183 ALOGE_IF(mFlushingAudio != NONE,
2184 "audio flushDecoder() is called in state %d", mFlushingAudio);
Andreas Huber1aef2112011-01-04 14:01:29 -08002185 mFlushingAudio = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08002186 } else {
Wei Jia53904f32014-07-29 10:22:53 -07002187 ALOGE_IF(mFlushingVideo != NONE,
2188 "video flushDecoder() is called in state %d", mFlushingVideo);
Andreas Huber1aef2112011-01-04 14:01:29 -08002189 mFlushingVideo = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08002190 }
2191}
2192
Chong Zhangced1c2f2014-08-08 15:22:35 -07002193void NuPlayer::queueDecoderShutdown(
2194 bool audio, bool video, const sp<AMessage> &reply) {
2195 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Huber84066782011-08-16 09:34:26 -07002196
Chong Zhangced1c2f2014-08-08 15:22:35 -07002197 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07002198 new FlushDecoderAction(
2199 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2200 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
Andreas Huber84066782011-08-16 09:34:26 -07002201
Chong Zhangced1c2f2014-08-08 15:22:35 -07002202 mDeferredActions.push_back(
2203 new SimpleAction(&NuPlayer::performScanSources));
Andreas Huber84066782011-08-16 09:34:26 -07002204
Chong Zhangced1c2f2014-08-08 15:22:35 -07002205 mDeferredActions.push_back(new PostMessageAction(reply));
2206
2207 processDeferredActions();
Andreas Huber84066782011-08-16 09:34:26 -07002208}
2209
James Dong0d268a32012-08-31 12:18:27 -07002210status_t NuPlayer::setVideoScalingMode(int32_t mode) {
2211 mVideoScalingMode = mode;
Lajos Molnar1de1e252015-04-30 18:18:34 -07002212 if (mSurface != NULL) {
2213 status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
James Dong0d268a32012-08-31 12:18:27 -07002214 if (ret != OK) {
2215 ALOGE("Failed to set scaling mode (%d): %s",
2216 -ret, strerror(-ret));
2217 return ret;
2218 }
2219 }
2220 return OK;
2221}
2222
Chong Zhangdcb89b32013-08-06 09:44:47 -07002223status_t NuPlayer::getTrackInfo(Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002224 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002225 msg->setPointer("reply", reply);
2226
2227 sp<AMessage> response;
2228 status_t err = msg->postAndAwaitResponse(&response);
2229 return err;
2230}
2231
Robert Shih7c4f0d72014-07-09 18:53:31 -07002232status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002233 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
Robert Shih7c4f0d72014-07-09 18:53:31 -07002234 msg->setPointer("reply", reply);
2235 msg->setInt32("type", type);
2236
2237 sp<AMessage> response;
2238 status_t err = msg->postAndAwaitResponse(&response);
2239 if (err == OK && response != NULL) {
2240 CHECK(response->findInt32("err", &err));
2241 }
2242 return err;
2243}
2244
Robert Shih6ffb1fd2014-10-29 16:24:32 -07002245status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002246 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002247 msg->setSize("trackIndex", trackIndex);
2248 msg->setInt32("select", select);
Robert Shih6ffb1fd2014-10-29 16:24:32 -07002249 msg->setInt64("timeUs", timeUs);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002250
2251 sp<AMessage> response;
2252 status_t err = msg->postAndAwaitResponse(&response);
2253
Chong Zhang404fced2014-06-11 14:45:31 -07002254 if (err != OK) {
2255 return err;
2256 }
2257
2258 if (!response->findInt32("err", &err)) {
2259 err = OK;
2260 }
2261
Chong Zhangdcb89b32013-08-06 09:44:47 -07002262 return err;
2263}
2264
Ronghua Wua73d9e02014-10-08 15:13:29 -07002265status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
2266 sp<Renderer> renderer = mRenderer;
2267 if (renderer == NULL) {
2268 return NO_INIT;
2269 }
2270
2271 return renderer->getCurrentPosition(mediaUs);
2272}
2273
Ray Essickffc941f2018-05-18 11:08:37 -07002274void NuPlayer::getStats(Vector<sp<AMessage> > *trackStats) {
2275 CHECK(trackStats != NULL);
Praveen Chavane1e5d7a2015-05-19 19:09:48 -07002276
Ray Essickfcb8fd32018-08-07 09:39:38 -07002277 trackStats->clear();
Ray Essickffc941f2018-05-18 11:08:37 -07002278
Ray Essickfcb8fd32018-08-07 09:39:38 -07002279 Mutex::Autolock autoLock(mDecoderLock);
2280 if (mVideoDecoder != NULL) {
2281 trackStats->push_back(mVideoDecoder->getStats());
2282 }
2283 if (mAudioDecoder != NULL) {
2284 trackStats->push_back(mAudioDecoder->getStats());
2285 }
Ronghua Wua73d9e02014-10-08 15:13:29 -07002286}
2287
Marco Nelissenf0b72b52014-09-16 15:43:44 -07002288sp<MetaData> NuPlayer::getFileMeta() {
2289 return mSource->getFileFormatMeta();
2290}
2291
Ronghua Wuc8a70d32015-04-29 16:26:34 -07002292float NuPlayer::getFrameRate() {
2293 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2294 if (meta == NULL) {
2295 return 0;
2296 }
2297 int32_t rate;
2298 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2299 // fall back to try file meta
2300 sp<MetaData> fileMeta = getFileMeta();
2301 if (fileMeta == NULL) {
2302 ALOGW("source has video meta but not file meta");
2303 return -1;
2304 }
2305 int32_t fileMetaRate;
2306 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2307 return -1;
2308 }
2309 return fileMetaRate;
2310 }
2311 return rate;
2312}
2313
Andreas Huberb7c8e912012-11-27 15:02:53 -08002314void NuPlayer::schedulePollDuration() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002315 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
Andreas Huberb7c8e912012-11-27 15:02:53 -08002316 msg->setInt32("generation", mPollDurationGeneration);
2317 msg->post();
2318}
2319
2320void NuPlayer::cancelPollDuration() {
2321 ++mPollDurationGeneration;
2322}
2323
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002324void NuPlayer::processDeferredActions() {
2325 while (!mDeferredActions.empty()) {
2326 // We won't execute any deferred actions until we're no longer in
2327 // an intermediate state, i.e. one more more decoders are currently
2328 // flushing or shutting down.
2329
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002330 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2331 // We're currently flushing, postpone the reset until that's
2332 // completed.
2333
2334 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2335 mFlushingAudio, mFlushingVideo);
2336
2337 break;
2338 }
2339
2340 sp<Action> action = *mDeferredActions.begin();
2341 mDeferredActions.erase(mDeferredActions.begin());
2342
2343 action->execute(this);
2344 }
2345}
2346
Wei Jiac5de0912016-11-18 10:22:14 -08002347void NuPlayer::performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
2348 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2349 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002350
Andy Hungadf34bf2014-09-03 18:22:22 -07002351 if (mSource == NULL) {
2352 // This happens when reset occurs right before the loop mode
2353 // asynchronously seeks to the start of the stream.
2354 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2355 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2356 mAudioDecoder.get(), mVideoDecoder.get());
2357 return;
2358 }
Robert Shih1a5c8592015-08-04 18:07:44 -07002359 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -08002360 mSource->seekTo(seekTimeUs, mode);
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002361 ++mTimedTextGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002362
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002363 // everything's flushed, continue playback.
2364}
2365
Wei Jiafef808d2014-10-31 17:57:05 -07002366void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2367 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002368
Wei Jiafef808d2014-10-31 17:57:05 -07002369 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2370 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002371 return;
2372 }
2373
Wei Jiafef808d2014-10-31 17:57:05 -07002374 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2375 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002376 }
2377
Wei Jiafef808d2014-10-31 17:57:05 -07002378 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2379 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002380 }
2381}
2382
2383void NuPlayer::performReset() {
2384 ALOGV("performReset");
2385
2386 CHECK(mAudioDecoder == NULL);
2387 CHECK(mVideoDecoder == NULL);
2388
Ray Essickeda32522018-02-28 12:08:28 -08002389 updatePlaybackTimer(true /* stopping */, "performReset");
2390 updateRebufferingTimer(true /* stopping */, true /* exiting */);
Ray Essick0d98c182017-11-09 13:42:42 -08002391
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002392 cancelPollDuration();
2393
2394 ++mScanSourcesGeneration;
2395 mScanSourcesPending = false;
2396
Lajos Molnar09524832014-07-17 14:29:51 -07002397 if (mRendererLooper != NULL) {
2398 if (mRenderer != NULL) {
2399 mRendererLooper->unregisterHandler(mRenderer->id());
2400 }
2401 mRendererLooper->stop();
2402 mRendererLooper.clear();
2403 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002404 mRenderer.clear();
Wei Jia57568df2014-09-22 10:16:29 -07002405 ++mRendererGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002406
2407 if (mSource != NULL) {
2408 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08002409
Wei Jiac45a4b22016-04-15 15:30:23 -07002410 Mutex::Autolock autoLock(mSourceLock);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002411 mSource.clear();
2412 }
2413
2414 if (mDriver != NULL) {
2415 sp<NuPlayerDriver> driver = mDriver.promote();
2416 if (driver != NULL) {
2417 driver->notifyResetComplete();
2418 }
2419 }
Andreas Huber57a339c2012-12-03 11:18:00 -08002420
2421 mStarted = false;
Wei Jia8a092d32016-06-03 14:57:24 -07002422 mPrepared = false;
Ronghua Wu64c2d172015-10-07 16:52:19 -07002423 mResetting = false;
Robert Shih0c61a0d2015-07-06 15:09:10 -07002424 mSourceStarted = false;
Hassan Shojaniacefac142017-02-06 21:02:02 -08002425
2426 // Modular DRM
2427 if (mCrypto != NULL) {
2428 // decoders will be flushed before this so their mCrypto would go away on their own
2429 // TODO change to ALOGV
2430 ALOGD("performReset mCrypto: %p (%d)", mCrypto.get(),
2431 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2432 mCrypto.clear();
2433 }
2434 mIsDrmProtected = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002435}
2436
2437void NuPlayer::performScanSources() {
2438 ALOGV("performScanSources");
2439
Andreas Huber57a339c2012-12-03 11:18:00 -08002440 if (!mStarted) {
2441 return;
2442 }
2443
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002444 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2445 postScanSources();
2446 }
2447}
2448
Lajos Molnar1de1e252015-04-30 18:18:34 -07002449void NuPlayer::performSetSurface(const sp<Surface> &surface) {
Andreas Huber57a339c2012-12-03 11:18:00 -08002450 ALOGV("performSetSurface");
2451
Lajos Molnar1de1e252015-04-30 18:18:34 -07002452 mSurface = surface;
Andreas Huber57a339c2012-12-03 11:18:00 -08002453
2454 // XXX - ignore error from setVideoScalingMode for now
2455 setVideoScalingMode(mVideoScalingMode);
Chong Zhang13d6faa2014-08-22 15:35:28 -07002456
2457 if (mDriver != NULL) {
2458 sp<NuPlayerDriver> driver = mDriver.promote();
2459 if (driver != NULL) {
2460 driver->notifySetSurfaceComplete();
2461 }
2462 }
Andreas Huber57a339c2012-12-03 11:18:00 -08002463}
2464
Chong Zhangf8d71772014-11-26 15:08:34 -08002465void NuPlayer::performResumeDecoders(bool needNotify) {
2466 if (needNotify) {
2467 mResumePending = true;
2468 if (mVideoDecoder == NULL) {
2469 // if audio-only, we can notify seek complete now,
2470 // as the resume operation will be relatively fast.
2471 finishResume();
2472 }
2473 }
2474
Chong Zhang7137ec72014-11-12 16:41:05 -08002475 if (mVideoDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08002476 // When there is continuous seek, MediaPlayer will cache the seek
2477 // position, and send down new seek request when previous seek is
2478 // complete. Let's wait for at least one video output frame before
2479 // notifying seek complete, so that the video thumbnail gets updated
2480 // when seekbar is dragged.
2481 mVideoDecoder->signalResume(needNotify);
Chong Zhang7137ec72014-11-12 16:41:05 -08002482 }
2483
2484 if (mAudioDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08002485 mAudioDecoder->signalResume(false /* needNotify */);
2486 }
2487}
2488
2489void NuPlayer::finishResume() {
2490 if (mResumePending) {
2491 mResumePending = false;
Wei Jia1061c9c2015-05-19 16:02:17 -07002492 notifyDriverSeekComplete();
2493 }
2494}
2495
2496void NuPlayer::notifyDriverSeekComplete() {
2497 if (mDriver != NULL) {
2498 sp<NuPlayerDriver> driver = mDriver.promote();
2499 if (driver != NULL) {
2500 driver->notifySeekComplete();
Chong Zhangf8d71772014-11-26 15:08:34 -08002501 }
Chong Zhang7137ec72014-11-12 16:41:05 -08002502 }
2503}
2504
Andreas Huber9575c962013-02-05 13:59:56 -08002505void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
2506 int32_t what;
2507 CHECK(msg->findInt32("what", &what));
2508
2509 switch (what) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002510 case Source::kWhatInstantiateSecureDecoders:
2511 {
2512 if (mSource == NULL) {
2513 // This is a stale notification from a source that was
2514 // asynchronously preparing when the client called reset().
2515 // We handled the reset, the source is gone.
2516 break;
2517 }
2518
2519 sp<AMessage> reply;
2520 CHECK(msg->findMessage("reply", &reply));
2521 status_t err = onInstantiateSecureDecoders();
2522 reply->setInt32("err", err);
2523 reply->post();
2524 break;
2525 }
2526
Andreas Huber9575c962013-02-05 13:59:56 -08002527 case Source::kWhatPrepared:
2528 {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002529 ALOGV("NuPlayer::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
Andreas Huberb5f28d42013-04-25 15:11:19 -07002530 if (mSource == NULL) {
2531 // This is a stale notification from a source that was
2532 // asynchronously preparing when the client called reset().
2533 // We handled the reset, the source is gone.
2534 break;
2535 }
2536
Andreas Huberec0c5972013-02-05 14:47:13 -08002537 int32_t err;
2538 CHECK(msg->findInt32("err", &err));
2539
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002540 if (err != OK) {
2541 // shut down potential secure codecs in case client never calls reset
2542 mDeferredActions.push_back(
2543 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2544 FLUSH_CMD_SHUTDOWN /* video */));
2545 processDeferredActions();
Wei Jia8a092d32016-06-03 14:57:24 -07002546 } else {
2547 mPrepared = true;
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002548 }
2549
Andreas Huber9575c962013-02-05 13:59:56 -08002550 sp<NuPlayerDriver> driver = mDriver.promote();
2551 if (driver != NULL) {
Marco Nelissendd114d12014-05-28 15:23:14 -07002552 // notify duration first, so that it's definitely set when
2553 // the app received the "prepare complete" callback.
2554 int64_t durationUs;
2555 if (mSource->getDuration(&durationUs) == OK) {
2556 driver->notifyDuration(durationUs);
2557 }
Andreas Huberec0c5972013-02-05 14:47:13 -08002558 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08002559 }
Andreas Huber99759402013-04-01 14:28:31 -07002560
Andreas Huber9575c962013-02-05 13:59:56 -08002561 break;
2562 }
2563
Hassan Shojaniacefac142017-02-06 21:02:02 -08002564 // Modular DRM
2565 case Source::kWhatDrmInfo:
2566 {
2567 Parcel parcel;
2568 sp<ABuffer> drmInfo;
2569 CHECK(msg->findBuffer("drmInfo", &drmInfo));
2570 parcel.setData(drmInfo->data(), drmInfo->size());
2571
2572 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA_DRM_INFO drmInfo: %p parcel size: %zu",
2573 drmInfo.get(), parcel.dataSize());
2574
2575 notifyListener(MEDIA_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
2576
2577 break;
2578 }
2579
Andreas Huber9575c962013-02-05 13:59:56 -08002580 case Source::kWhatFlagsChanged:
2581 {
2582 uint32_t flags;
2583 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2584
Chong Zhang4b7069d2013-09-11 12:52:43 -07002585 sp<NuPlayerDriver> driver = mDriver.promote();
2586 if (driver != NULL) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002587
2588 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2589 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2590 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2591 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2592 (flags & Source::FLAG_CAN_PAUSE) != 0,
2593 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2594 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2595 (flags & Source::FLAG_CAN_SEEK) != 0,
2596 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2597 (flags & Source::FLAG_SECURE) != 0,
2598 (flags & Source::FLAG_PROTECTED) != 0);
2599
Wei Jia895651b2014-12-10 17:31:52 -08002600 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
2601 driver->notifyListener(
2602 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
2603 }
Chong Zhang4b7069d2013-09-11 12:52:43 -07002604 driver->notifyFlagsChanged(flags);
2605 }
2606
Andreas Huber9575c962013-02-05 13:59:56 -08002607 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2608 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2609 cancelPollDuration();
2610 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2611 && (flags & Source::FLAG_DYNAMIC_DURATION)
2612 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2613 schedulePollDuration();
2614 }
2615
2616 mSourceFlags = flags;
2617 break;
2618 }
2619
2620 case Source::kWhatVideoSizeChanged:
2621 {
Chong Zhangced1c2f2014-08-08 15:22:35 -07002622 sp<AMessage> format;
2623 CHECK(msg->findMessage("format", &format));
Andreas Huber9575c962013-02-05 13:59:56 -08002624
Chong Zhangced1c2f2014-08-08 15:22:35 -07002625 updateVideoSize(format);
Andreas Huber9575c962013-02-05 13:59:56 -08002626 break;
2627 }
2628
Chong Zhang2a3cc9a2014-08-21 17:48:26 -07002629 case Source::kWhatBufferingUpdate:
2630 {
2631 int32_t percentage;
2632 CHECK(msg->findInt32("percentage", &percentage));
2633
2634 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
2635 break;
2636 }
2637
Chong Zhangefbb6192015-01-30 17:13:27 -08002638 case Source::kWhatPauseOnBufferingStart:
2639 {
2640 // ignore if not playing
Chong Zhang8a048332015-05-06 15:16:28 -07002641 if (mStarted) {
Chong Zhangefbb6192015-01-30 17:13:27 -08002642 ALOGI("buffer low, pausing...");
2643
Ray Essick58e0f7a2017-11-21 10:59:38 -08002644 startRebufferingTimer();
Chong Zhang8a048332015-05-06 15:16:28 -07002645 mPausedForBuffering = true;
Chong Zhangefbb6192015-01-30 17:13:27 -08002646 onPause();
2647 }
Wei Jiabfe82072016-05-20 09:21:50 -07002648 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
Roger Jönssonb50e83e2013-01-21 16:26:41 +01002649 break;
2650 }
2651
Chong Zhangefbb6192015-01-30 17:13:27 -08002652 case Source::kWhatResumeOnBufferingEnd:
2653 {
2654 // ignore if not playing
Chong Zhang8a048332015-05-06 15:16:28 -07002655 if (mStarted) {
Chong Zhangefbb6192015-01-30 17:13:27 -08002656 ALOGI("buffer ready, resuming...");
2657
Ray Essickeda32522018-02-28 12:08:28 -08002658 updateRebufferingTimer(true /* stopping */, false /* exiting */);
Chong Zhang8a048332015-05-06 15:16:28 -07002659 mPausedForBuffering = false;
2660
2661 // do not resume yet if client didn't unpause
2662 if (!mPausedByClient) {
2663 onResume();
2664 }
Chong Zhangefbb6192015-01-30 17:13:27 -08002665 }
Wei Jia3bed45a2016-02-17 11:06:47 -08002666 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
Roger Jönssonb50e83e2013-01-21 16:26:41 +01002667 break;
2668 }
2669
Chong Zhangefbb6192015-01-30 17:13:27 -08002670 case Source::kWhatCacheStats:
2671 {
2672 int32_t kbps;
2673 CHECK(msg->findInt32("bandwidth", &kbps));
2674
2675 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
2676 break;
2677 }
2678
Chong Zhangdcb89b32013-08-06 09:44:47 -07002679 case Source::kWhatSubtitleData:
2680 {
2681 sp<ABuffer> buffer;
2682 CHECK(msg->findBuffer("buffer", &buffer));
2683
Chong Zhang404fced2014-06-11 14:45:31 -07002684 sendSubtitleData(buffer, 0 /* baseIndex */);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002685 break;
2686 }
2687
Robert Shih08528432015-04-08 09:06:54 -07002688 case Source::kWhatTimedMetaData:
2689 {
2690 sp<ABuffer> buffer;
2691 if (!msg->findBuffer("buffer", &buffer)) {
2692 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2693 } else {
2694 sendTimedMetaData(buffer);
2695 }
2696 break;
2697 }
2698
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002699 case Source::kWhatTimedTextData:
2700 {
2701 int32_t generation;
2702 if (msg->findInt32("generation", &generation)
2703 && generation != mTimedTextGeneration) {
2704 break;
2705 }
2706
2707 sp<ABuffer> buffer;
2708 CHECK(msg->findBuffer("buffer", &buffer));
2709
2710 sp<NuPlayerDriver> driver = mDriver.promote();
2711 if (driver == NULL) {
2712 break;
2713 }
2714
2715 int posMs;
2716 int64_t timeUs, posUs;
2717 driver->getCurrentPosition(&posMs);
Chih-Hung Hsieh62309d52018-12-11 13:54:02 -08002718 posUs = (int64_t) posMs * 1000LL;
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002719 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2720
2721 if (posUs < timeUs) {
2722 if (!msg->findInt32("generation", &generation)) {
2723 msg->setInt32("generation", mTimedTextGeneration);
2724 }
2725 msg->post(timeUs - posUs);
2726 } else {
2727 sendTimedTextData(buffer);
2728 }
2729 break;
2730 }
2731
Andreas Huber14f76722013-01-15 09:04:18 -08002732 case Source::kWhatQueueDecoderShutdown:
2733 {
2734 int32_t audio, video;
2735 CHECK(msg->findInt32("audio", &audio));
2736 CHECK(msg->findInt32("video", &video));
2737
2738 sp<AMessage> reply;
2739 CHECK(msg->findMessage("reply", &reply));
2740
2741 queueDecoderShutdown(audio, video, reply);
2742 break;
2743 }
2744
Ronghua Wu80276872014-08-28 15:50:29 -07002745 case Source::kWhatDrmNoLicense:
2746 {
2747 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2748 break;
2749 }
2750
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002751 case Source::kWhatIMSRxNotice:
2752 {
2753 sp<AMessage> IMSRxNotice;
2754 CHECK(msg->findMessage("message", &IMSRxNotice));
2755 sendIMSRxNotice(IMSRxNotice);
2756 break;
2757 }
2758
Andreas Huber9575c962013-02-05 13:59:56 -08002759 default:
2760 TRESPASS();
2761 }
2762}
2763
Chong Zhanga7fa1d92014-06-11 14:49:23 -07002764void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2765 int32_t what;
2766 CHECK(msg->findInt32("what", &what));
2767
2768 switch (what) {
2769 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2770 {
2771 sp<ABuffer> buffer;
2772 CHECK(msg->findBuffer("buffer", &buffer));
2773
2774 size_t inbandTracks = 0;
2775 if (mSource != NULL) {
2776 inbandTracks = mSource->getTrackCount();
2777 }
2778
2779 sendSubtitleData(buffer, inbandTracks);
2780 break;
2781 }
2782
2783 case NuPlayer::CCDecoder::kWhatTrackAdded:
2784 {
2785 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2786
2787 break;
2788 }
2789
2790 default:
2791 TRESPASS();
2792 }
2793
2794
2795}
2796
Chong Zhang404fced2014-06-11 14:45:31 -07002797void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2798 int32_t trackIndex;
2799 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002800 CHECK(buffer->meta()->findInt32("track-index", &trackIndex));
Chong Zhang404fced2014-06-11 14:45:31 -07002801 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2802 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2803
2804 Parcel in;
2805 in.writeInt32(trackIndex + baseIndex);
2806 in.writeInt64(timeUs);
2807 in.writeInt64(durationUs);
2808 in.writeInt32(buffer->size());
2809 in.writeInt32(buffer->size());
2810 in.write(buffer->data(), buffer->size());
2811
2812 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2813}
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002814
Robert Shih08528432015-04-08 09:06:54 -07002815void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
2816 int64_t timeUs;
2817 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2818
2819 Parcel in;
2820 in.writeInt64(timeUs);
2821 in.writeInt32(buffer->size());
2822 in.writeInt32(buffer->size());
2823 in.write(buffer->data(), buffer->size());
2824
2825 notifyListener(MEDIA_META_DATA, 0, 0, &in);
2826}
2827
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002828void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2829 const void *data;
2830 size_t size = 0;
2831 int64_t timeUs;
Marco Nelissen55e2f4c2015-09-04 15:57:15 -07002832 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002833
2834 AString mime;
2835 CHECK(buffer->meta()->findString("mime", &mime));
2836 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2837
2838 data = buffer->data();
2839 size = buffer->size();
2840
2841 Parcel parcel;
2842 if (size > 0) {
2843 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
Marco Nelissen55e2f4c2015-09-04 15:57:15 -07002844 int32_t global = 0;
2845 if (buffer->meta()->findInt32("global", &global) && global) {
2846 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2847 } else {
2848 flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2849 }
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002850 TextDescriptions::getParcelOfDescriptions(
2851 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2852 }
2853
2854 if ((parcel.dataSize() > 0)) {
2855 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2856 } else { // send an empty timed text
2857 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2858 }
2859}
Hassan Shojaniacefac142017-02-06 21:02:02 -08002860
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002861void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002862 int32_t payloadType;
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002863
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002864 CHECK(msg->findInt32("payload-type", &payloadType));
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002865
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002866 int32_t rtpSeq = 0, rtpTime = 0;
2867 int64_t ntpTime = 0, recvTimeUs = 0;
2868
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002869 Parcel in;
2870 in.writeInt32(payloadType);
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002871
2872 switch (payloadType) {
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002873 case ARTPSource::RTP_FIRST_PACKET:
2874 {
2875 CHECK(msg->findInt32("rtp-time", &rtpTime));
2876 CHECK(msg->findInt32("rtp-seq-num", &rtpSeq));
2877 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2878 in.writeInt32(rtpTime);
2879 in.writeInt32(rtpSeq);
2880 in.writeInt32(recvTimeUs >> 32);
2881 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2882 break;
2883 }
2884 case ARTPSource::RTCP_FIRST_PACKET:
2885 {
2886 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2887 in.writeInt32(recvTimeUs >> 32);
2888 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2889 break;
2890 }
2891 case ARTPSource::RTCP_SR:
2892 {
2893 CHECK(msg->findInt32("rtp-time", &rtpTime));
2894 CHECK(msg->findInt64("ntp-time", &ntpTime));
2895 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2896 in.writeInt32(rtpTime);
2897 in.writeInt32(ntpTime >> 32);
2898 in.writeInt32(ntpTime & 0xFFFFFFFF);
2899 in.writeInt32(recvTimeUs >> 32);
2900 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2901 break;
2902 }
Byeongjo Park195d6142021-11-12 19:27:09 +09002903 case ARTPSource::RTCP_RR:
2904 {
2905 int64_t recvTimeUs;
2906 int32_t senderId;
2907 int32_t ssrc;
2908 int32_t fraction;
2909 int32_t lost;
2910 int32_t lastSeq;
2911 int32_t jitter;
2912 int32_t lsr;
2913 int32_t dlsr;
2914 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2915 CHECK(msg->findInt32("rtcp-rr-ssrc", &senderId));
2916 CHECK(msg->findInt32("rtcp-rrb-ssrc", &ssrc));
2917 CHECK(msg->findInt32("rtcp-rrb-fraction", &fraction));
2918 CHECK(msg->findInt32("rtcp-rrb-lost", &lost));
2919 CHECK(msg->findInt32("rtcp-rrb-lastSeq", &lastSeq));
2920 CHECK(msg->findInt32("rtcp-rrb-jitter", &jitter));
2921 CHECK(msg->findInt32("rtcp-rrb-lsr", &lsr));
2922 CHECK(msg->findInt32("rtcp-rrb-dlsr", &dlsr));
2923 in.writeInt32(recvTimeUs >> 32);
2924 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2925 in.writeInt32(senderId);
2926 in.writeInt32(ssrc);
2927 in.writeInt32(fraction);
2928 in.writeInt32(lost);
2929 in.writeInt32(lastSeq);
2930 in.writeInt32(jitter);
2931 in.writeInt32(lsr);
2932 in.writeInt32(dlsr);
2933 break;
2934 }
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002935 case ARTPSource::RTCP_TSFB: // RTCP TSFB
2936 case ARTPSource::RTCP_PSFB: // RTCP PSFB
2937 case ARTPSource::RTP_AUTODOWN:
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002938 {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002939 int32_t feedbackType, id;
2940 CHECK(msg->findInt32("feedback-type", &feedbackType));
2941 CHECK(msg->findInt32("sender", &id));
2942 in.writeInt32(feedbackType);
2943 in.writeInt32(id);
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002944 if (payloadType == ARTPSource::RTCP_TSFB) {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002945 int32_t bitrate;
2946 CHECK(msg->findInt32("bit-rate", &bitrate));
2947 in.writeInt32(bitrate);
2948 }
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002949 break;
2950 }
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002951 case ARTPSource::RTP_QUALITY:
2952 case ARTPSource::RTP_QUALITY_EMC:
Kim Sungyeon23b23932019-07-18 17:48:32 +09002953 {
2954 int32_t feedbackType, bitrate;
2955 int32_t highestSeqNum, baseSeqNum, prevExpected;
2956 int32_t numBufRecv, prevNumBufRecv;
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002957 int32_t latestRtpTime, jbTimeMs, rtpRtcpSrTimeGapMs;
2958 int64_t recvTimeUs;
Kim Sungyeon23b23932019-07-18 17:48:32 +09002959 CHECK(msg->findInt32("feedback-type", &feedbackType));
2960 CHECK(msg->findInt32("bit-rate", &bitrate));
2961 CHECK(msg->findInt32("highest-seq-num", &highestSeqNum));
2962 CHECK(msg->findInt32("base-seq-num", &baseSeqNum));
2963 CHECK(msg->findInt32("prev-expected", &prevExpected));
2964 CHECK(msg->findInt32("num-buf-recv", &numBufRecv));
2965 CHECK(msg->findInt32("prev-num-buf-recv", &prevNumBufRecv));
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002966 CHECK(msg->findInt32("latest-rtp-time", &latestRtpTime));
2967 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2968 CHECK(msg->findInt32("rtp-jitter-time-ms", &jbTimeMs));
2969 CHECK(msg->findInt32("rtp-rtcpsr-time-gap-ms", &rtpRtcpSrTimeGapMs));
Kim Sungyeon23b23932019-07-18 17:48:32 +09002970 in.writeInt32(feedbackType);
2971 in.writeInt32(bitrate);
2972 in.writeInt32(highestSeqNum);
2973 in.writeInt32(baseSeqNum);
2974 in.writeInt32(prevExpected);
2975 in.writeInt32(numBufRecv);
2976 in.writeInt32(prevNumBufRecv);
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002977 in.writeInt32(latestRtpTime);
2978 in.writeInt32(recvTimeUs >> 32);
2979 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2980 in.writeInt32(jbTimeMs);
2981 in.writeInt32(rtpRtcpSrTimeGapMs);
Kim Sungyeon23b23932019-07-18 17:48:32 +09002982 break;
2983 }
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002984 case ARTPSource::RTP_CVO:
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002985 {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002986 int32_t cvo;
2987 CHECK(msg->findInt32("cvo", &cvo));
2988 in.writeInt32(cvo);
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002989 break;
2990 }
2991 default:
2992 break;
2993 }
2994
2995 notifyListener(MEDIA_IMS_RX_NOTICE, 0, 0, &in);
2996}
2997
Hassan Shojaniaff63de72017-04-26 15:10:42 -07002998const char *NuPlayer::getDataSourceType() {
2999 switch (mDataSourceType) {
3000 case DATA_SOURCE_TYPE_HTTP_LIVE:
3001 return "HTTPLive";
3002
Byeongjo Park5e27b1b2018-07-12 15:36:03 +09003003 case DATA_SOURCE_TYPE_RTP:
3004 return "RTP";
3005
Hassan Shojaniaff63de72017-04-26 15:10:42 -07003006 case DATA_SOURCE_TYPE_RTSP:
3007 return "RTSP";
3008
3009 case DATA_SOURCE_TYPE_GENERIC_URL:
3010 return "GenURL";
3011
3012 case DATA_SOURCE_TYPE_GENERIC_FD:
3013 return "GenFD";
3014
3015 case DATA_SOURCE_TYPE_MEDIA:
3016 return "Media";
3017
3018 case DATA_SOURCE_TYPE_STREAM:
3019 return "Stream";
3020
3021 case DATA_SOURCE_TYPE_NONE:
3022 default:
3023 return "None";
3024 }
3025 }
3026
Hassan Shojaniacefac142017-02-06 21:02:02 -08003027// Modular DRM begin
3028status_t NuPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3029{
3030 ALOGV("prepareDrm ");
3031
3032 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3033 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3034 // synchronous call so just passing the address but with local copies of "const" args
3035 uint8_t UUID[16];
3036 memcpy(UUID, uuid, sizeof(UUID));
3037 Vector<uint8_t> sessionId = drmSessionId;
3038 msg->setPointer("uuid", (void*)UUID);
3039 msg->setPointer("drmSessionId", (void*)&sessionId);
3040
3041 sp<AMessage> response;
3042 status_t status = msg->postAndAwaitResponse(&response);
3043
3044 if (status == OK && response != NULL) {
3045 CHECK(response->findInt32("status", &status));
3046 ALOGV("prepareDrm ret: %d ", status);
3047 } else {
3048 ALOGE("prepareDrm err: %d", status);
3049 }
3050
3051 return status;
3052}
3053
3054status_t NuPlayer::releaseDrm()
3055{
3056 ALOGV("releaseDrm ");
3057
3058 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3059
3060 sp<AMessage> response;
3061 status_t status = msg->postAndAwaitResponse(&response);
3062
3063 if (status == OK && response != NULL) {
3064 CHECK(response->findInt32("status", &status));
3065 ALOGV("releaseDrm ret: %d ", status);
3066 } else {
3067 ALOGE("releaseDrm err: %d", status);
3068 }
3069
3070 return status;
3071}
3072
3073status_t NuPlayer::onPrepareDrm(const sp<AMessage> &msg)
3074{
3075 // TODO change to ALOGV
3076 ALOGD("onPrepareDrm ");
3077
3078 status_t status = INVALID_OPERATION;
3079 if (mSource == NULL) {
3080 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3081 return status;
3082 }
3083
3084 uint8_t *uuid;
3085 Vector<uint8_t> *drmSessionId;
3086 CHECK(msg->findPointer("uuid", (void**)&uuid));
3087 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3088
3089 status = OK;
3090 sp<ICrypto> crypto = NULL;
3091
3092 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
3093 if (crypto == NULL) {
3094 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
3095 return status;
3096 }
3097 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
3098
3099 if (mCrypto != NULL) {
3100 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p (%d)",
3101 mCrypto.get(), mCrypto->getStrongCount());
3102 mCrypto.clear();
3103 }
3104
3105 mCrypto = crypto;
3106 mIsDrmProtected = true;
3107 // TODO change to ALOGV
3108 ALOGD("onPrepareDrm: mCrypto: %p (%d)", mCrypto.get(),
3109 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3110
3111 return status;
3112}
3113
3114status_t NuPlayer::onReleaseDrm()
3115{
3116 // TODO change to ALOGV
3117 ALOGD("onReleaseDrm ");
3118
Hassan Shojania50b20c92017-02-16 18:28:58 -08003119 if (!mIsDrmProtected) {
3120 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3121 }
3122
3123 mIsDrmProtected = false;
Hassan Shojaniacefac142017-02-06 21:02:02 -08003124
3125 status_t status;
3126 if (mCrypto != NULL) {
Hassan Shojania355e8472017-05-12 10:33:16 -07003127 // notifying the source first before removing crypto from codec
3128 if (mSource != NULL) {
3129 mSource->releaseDrm();
3130 }
3131
Hassan Shojaniacefac142017-02-06 21:02:02 -08003132 status=OK;
3133 // first making sure the codecs have released their crypto reference
3134 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3135 if (videoDecoder != NULL) {
3136 status = videoDecoder->releaseCrypto();
3137 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3138 }
3139
3140 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3141 if (audioDecoder != NULL) {
3142 status_t status_audio = audioDecoder->releaseCrypto();
3143 if (status == OK) { // otherwise, returning the first error
3144 status = status_audio;
3145 }
3146 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3147 }
3148
3149 // TODO change to ALOGV
3150 ALOGD("onReleaseDrm: mCrypto: %p (%d)", mCrypto.get(),
3151 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3152 mCrypto.clear();
3153 } else { // mCrypto == NULL
3154 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3155 status = INVALID_OPERATION;
3156 }
3157
3158 return status;
3159}
3160// Modular DRM end
Andreas Huberb5f25f02013-02-05 10:14:26 -08003161////////////////////////////////////////////////////////////////////////////////
3162
Chong Zhangced1c2f2014-08-08 15:22:35 -07003163sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
3164 sp<MetaData> meta = getFormatMeta(audio);
3165
3166 if (meta == NULL) {
3167 return NULL;
3168 }
3169
3170 sp<AMessage> msg = new AMessage;
3171
3172 if(convertMetaDataToMessage(meta, &msg) == OK) {
3173 return msg;
3174 }
3175 return NULL;
3176}
3177
Andreas Huber9575c962013-02-05 13:59:56 -08003178void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
3179 sp<AMessage> notify = dupNotify();
3180 notify->setInt32("what", kWhatFlagsChanged);
3181 notify->setInt32("flags", flags);
3182 notify->post();
3183}
3184
Chong Zhangced1c2f2014-08-08 15:22:35 -07003185void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
Andreas Huber9575c962013-02-05 13:59:56 -08003186 sp<AMessage> notify = dupNotify();
3187 notify->setInt32("what", kWhatVideoSizeChanged);
Chong Zhangced1c2f2014-08-08 15:22:35 -07003188 notify->setMessage("format", format);
Andreas Huber9575c962013-02-05 13:59:56 -08003189 notify->post();
3190}
3191
Andreas Huberec0c5972013-02-05 14:47:13 -08003192void NuPlayer::Source::notifyPrepared(status_t err) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08003193 ALOGV("Source::notifyPrepared %d", err);
Andreas Huber9575c962013-02-05 13:59:56 -08003194 sp<AMessage> notify = dupNotify();
3195 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08003196 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08003197 notify->post();
3198}
3199
Hassan Shojaniacefac142017-02-06 21:02:02 -08003200void NuPlayer::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3201{
3202 ALOGV("Source::notifyDrmInfo");
3203
3204 sp<AMessage> notify = dupNotify();
3205 notify->setInt32("what", kWhatDrmInfo);
3206 notify->setBuffer("drmInfo", drmInfoBuffer);
3207
3208 notify->post();
3209}
3210
Lajos Molnarfcd3e942015-03-31 10:06:48 -07003211void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
3212 sp<AMessage> notify = dupNotify();
3213 notify->setInt32("what", kWhatInstantiateSecureDecoders);
3214 notify->setMessage("reply", reply);
3215 notify->post();
3216}
3217
Andreas Huber84333e02014-02-07 15:36:10 -08003218void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
Andreas Huberb5f25f02013-02-05 10:14:26 -08003219 TRESPASS();
3220}
3221
Andreas Huberf9334412010-12-15 15:17:42 -08003222} // namespace android