blob: 5c6c5fdc4473706cb0931ef185078fe1423148ab [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
Ray Essick5814d4e2022-09-08 13:19:39 -050063#include <media/esds/ESDS.h>
Andreas Huber84066782011-08-16 09:34:26 -070064#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.
Jonathan Kim2a012642023-01-04 11:14:05 +09001230 if (mVideoEOS) {
1231 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1232 } else {
1233 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_AUDIO_ERROR, err);
1234 }
Wei Jia686e8e52017-04-03 14:08:01 -07001235 }
1236 mAudioDecoderError = true;
1237 } else {
Wei Jia2f6d8c52017-04-11 09:50:31 -07001238 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
Wei Jiaf86731d2017-07-11 17:24:34 -07001239 || mAudioSink == NULL || mAudioDecoder == NULL) {
Wei Jia686e8e52017-04-03 14:08:01 -07001240 // When both audio and video have error, or this stream has only video
1241 // which has error, notify client of error.
1242 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1243 } else {
1244 // Only video track has error. Audio track could be still good to play.
Jonathan Kim2a012642023-01-04 11:14:05 +09001245 if (mAudioEOS) {
1246 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1247 } else {
1248 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_VIDEO_ERROR, err);
1249 }
Wei Jia686e8e52017-04-03 14:08:01 -07001250 }
1251 mVideoDecoderError = true;
1252 }
1253 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08001254 } else {
1255 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001256 what,
1257 what >> 24,
1258 (what >> 16) & 0xff,
1259 (what >> 8) & 0xff,
1260 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -08001261 }
1262
1263 break;
1264 }
1265
1266 case kWhatRendererNotify:
1267 {
Wei Jia57568df2014-09-22 10:16:29 -07001268 int32_t requesterGeneration = mRendererGeneration - 1;
1269 CHECK(msg->findInt32("generation", &requesterGeneration));
1270 if (requesterGeneration != mRendererGeneration) {
1271 ALOGV("got message from old renderer, generation(%d:%d)",
1272 requesterGeneration, mRendererGeneration);
1273 return;
1274 }
1275
Andreas Huberf9334412010-12-15 15:17:42 -08001276 int32_t what;
1277 CHECK(msg->findInt32("what", &what));
1278
1279 if (what == Renderer::kWhatEOS) {
1280 int32_t audio;
1281 CHECK(msg->findInt32("audio", &audio));
1282
Andreas Huberc92fd242011-08-16 13:48:44 -07001283 int32_t finalResult;
1284 CHECK(msg->findInt32("finalResult", &finalResult));
1285
Andreas Huberf9334412010-12-15 15:17:42 -08001286 if (audio) {
1287 mAudioEOS = true;
1288 } else {
1289 mVideoEOS = true;
1290 }
1291
Andreas Huberc92fd242011-08-16 13:48:44 -07001292 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +01001293 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -07001294 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001295 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -07001296 audio ? "audio" : "video", finalResult);
1297
1298 notifyListener(
1299 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
1300 }
Andreas Huberf9334412010-12-15 15:17:42 -08001301
1302 if ((mAudioEOS || mAudioDecoder == NULL)
1303 && (mVideoEOS || mVideoDecoder == NULL)) {
1304 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1305 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001306 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -08001307 int32_t audio;
1308 CHECK(msg->findInt32("audio", &audio));
1309
Wei Jia3261f0d2015-10-08 13:58:33 -07001310 if (audio) {
1311 mAudioEOS = false;
1312 } else {
1313 mVideoEOS = false;
1314 }
1315
Steve Block3856b092011-10-20 11:56:00 +01001316 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
Wei Jiada4252f2015-07-14 18:15:28 -07001317 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1318 || mFlushingAudio == SHUT_DOWN)) {
1319 // Flush has been handled by tear down.
1320 break;
1321 }
Andy Hung8d121d42014-10-03 09:53:53 -07001322 handleFlushComplete(audio, false /* isDecoder */);
1323 finishFlushIfPossible();
James Dongf57b4ea2012-07-20 13:38:36 -07001324 } else if (what == Renderer::kWhatVideoRenderingStart) {
1325 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Lajos Molnarcbaffcf2013-08-14 18:30:38 -07001326 } else if (what == Renderer::kWhatMediaRenderingStart) {
1327 ALOGV("media rendering started");
1328 notifyListener(MEDIA_STARTED, 0, 0);
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001329 } else if (what == Renderer::kWhatAudioTearDown) {
Ronghua Wu08529172014-10-02 16:55:52 -07001330 int32_t reason;
1331 CHECK(msg->findInt32("reason", &reason));
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001332 ALOGV("Tear down audio with reason %d.", reason);
Wei Jia8456ddd2016-04-22 14:46:43 -07001333 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1334 // TimeoutWhenPaused is only for offload mode.
Wei Jia355b2bb2018-04-09 16:36:23 -07001335 ALOGW("Received a stale message for teardown, mPaused(%d), mOffloadAudio(%d)",
1336 mPaused, mOffloadAudio);
Wei Jia8456ddd2016-04-22 14:46:43 -07001337 break;
1338 }
Wei Jiada4252f2015-07-14 18:15:28 -07001339 int64_t positionUs;
Robert Shih1a5c8592015-08-04 18:07:44 -07001340 if (!msg->findInt64("positionUs", &positionUs)) {
1341 positionUs = mPreviousSeekTimeUs;
1342 }
Ronghua Wufaeb0f22015-05-21 12:20:21 -07001343
Wei Jia5031b2f2016-02-25 11:19:31 -08001344 restartAudio(
Wei Jiaa05f1e32016-03-25 16:31:22 -07001345 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1346 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
Andreas Huberf9334412010-12-15 15:17:42 -08001347 }
1348 break;
1349 }
1350
1351 case kWhatMoreDataQueued:
1352 {
1353 break;
1354 }
1355
Andreas Huber1aef2112011-01-04 14:01:29 -08001356 case kWhatReset:
1357 {
Steve Block3856b092011-10-20 11:56:00 +01001358 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -08001359
Ronghua Wu64c2d172015-10-07 16:52:19 -07001360 mResetting = true;
Ray Essickeda32522018-02-28 12:08:28 -08001361 updatePlaybackTimer(true /* stopping */, "kWhatReset");
1362 updateRebufferingTimer(true /* stopping */, true /* exiting */);
Ronghua Wu64c2d172015-10-07 16:52:19 -07001363
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001364 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001365 new FlushDecoderAction(
1366 FLUSH_CMD_SHUTDOWN /* audio */,
1367 FLUSH_CMD_SHUTDOWN /* video */));
Andreas Huberb7c8e912012-11-27 15:02:53 -08001368
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001369 mDeferredActions.push_back(
1370 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -08001371
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001372 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001373 break;
1374 }
1375
Wei Jia52c28512017-09-13 18:17:51 -07001376 case kWhatNotifyTime:
1377 {
1378 ALOGV("kWhatNotifyTime");
1379 int64_t timerUs;
1380 CHECK(msg->findInt64("timerUs", &timerUs));
1381
1382 notifyListener(MEDIA_NOTIFY_TIME, timerUs, 0);
1383 break;
1384 }
1385
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001386 case kWhatSeek:
1387 {
1388 int64_t seekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -08001389 int32_t mode;
Wei Jiae427abf2014-09-22 15:21:11 -07001390 int32_t needNotify;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001391 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
Wei Jiac5de0912016-11-18 10:22:14 -08001392 CHECK(msg->findInt32("mode", &mode));
Wei Jiae427abf2014-09-22 15:21:11 -07001393 CHECK(msg->findInt32("needNotify", &needNotify));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001394
Wei Jiac5de0912016-11-18 10:22:14 -08001395 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1396 (long long)seekTimeUs, mode, needNotify);
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001397
Wei Jia1061c9c2015-05-19 16:02:17 -07001398 if (!mStarted) {
1399 // Seek before the player is started. In order to preview video,
1400 // need to start the player and pause it. This branch is called
1401 // only once if needed. After the player is started, any seek
1402 // operation will go through normal path.
Robert Shih0c61a0d2015-07-06 15:09:10 -07001403 // Audio-only cases are handled separately.
Wei Jiac5de0912016-11-18 10:22:14 -08001404 onStart(seekTimeUs, (MediaPlayerSeekMode)mode);
Robert Shih0c61a0d2015-07-06 15:09:10 -07001405 if (mStarted) {
1406 onPause();
1407 mPausedByClient = true;
1408 }
Wei Jia1061c9c2015-05-19 16:02:17 -07001409 if (needNotify) {
1410 notifyDriverSeekComplete();
1411 }
1412 break;
1413 }
1414
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001415 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07001416 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1417 FLUSH_CMD_FLUSH /* video */));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001418
Wei Jiae427abf2014-09-22 15:21:11 -07001419 mDeferredActions.push_back(
Wei Jiac5de0912016-11-18 10:22:14 -08001420 new SeekAction(seekTimeUs, (MediaPlayerSeekMode)mode));
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001421
Chong Zhangf8d71772014-11-26 15:08:34 -08001422 // After a flush without shutdown, decoder is paused.
1423 // Don't resume it until source seek is done, otherwise it could
Chong Zhang7137ec72014-11-12 16:41:05 -08001424 // start pulling stale data too soon.
1425 mDeferredActions.push_back(
Chong Zhangf8d71772014-11-26 15:08:34 -08001426 new ResumeDecoderAction(needNotify));
Chong Zhang7137ec72014-11-12 16:41:05 -08001427
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001428 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001429 break;
1430 }
1431
Andreas Huberb4082222011-01-20 15:23:04 -08001432 case kWhatPause:
1433 {
Chong Zhangefbb6192015-01-30 17:13:27 -08001434 onPause();
1435 mPausedByClient = true;
Andreas Huberb4082222011-01-20 15:23:04 -08001436 break;
1437 }
1438
Andreas Huberb5f25f02013-02-05 10:14:26 -08001439 case kWhatSourceNotify:
1440 {
Andreas Huber9575c962013-02-05 13:59:56 -08001441 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -08001442 break;
1443 }
1444
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001445 case kWhatClosedCaptionNotify:
1446 {
1447 onClosedCaptionNotify(msg);
1448 break;
1449 }
1450
Hassan Shojaniacefac142017-02-06 21:02:02 -08001451 case kWhatPrepareDrm:
1452 {
1453 status_t status = onPrepareDrm(msg);
1454
1455 sp<AMessage> response = new AMessage;
1456 response->setInt32("status", status);
1457 sp<AReplyToken> replyID;
1458 CHECK(msg->senderAwaitsResponse(&replyID));
1459 response->postReply(replyID);
1460 break;
1461 }
1462
1463 case kWhatReleaseDrm:
1464 {
1465 status_t status = onReleaseDrm();
1466
1467 sp<AMessage> response = new AMessage;
1468 response->setInt32("status", status);
1469 sp<AReplyToken> replyID;
1470 CHECK(msg->senderAwaitsResponse(&replyID));
1471 response->postReply(replyID);
1472 break;
1473 }
1474
Dongwon Kang47afe0a2018-03-27 15:15:30 -07001475 case kWhatMediaClockNotify:
1476 {
1477 ALOGV("kWhatMediaClockNotify");
1478 int64_t anchorMediaUs, anchorRealUs;
1479 float playbackRate;
1480 CHECK(msg->findInt64("anchor-media-us", &anchorMediaUs));
1481 CHECK(msg->findInt64("anchor-real-us", &anchorRealUs));
1482 CHECK(msg->findFloat("playback-rate", &playbackRate));
1483
1484 Parcel in;
1485 in.writeInt64(anchorMediaUs);
1486 in.writeInt64(anchorRealUs);
1487 in.writeFloat(playbackRate);
1488
1489 notifyListener(MEDIA_TIME_DISCONTINUITY, 0, 0, &in);
1490 break;
1491 }
1492
Andreas Huberf9334412010-12-15 15:17:42 -08001493 default:
1494 TRESPASS();
1495 break;
1496 }
1497}
1498
Wei Jia94211742014-10-28 17:09:06 -07001499void NuPlayer::onResume() {
Ronghua Wu64c2d172015-10-07 16:52:19 -07001500 if (!mPaused || mResetting) {
1501 ALOGD_IF(mResetting, "resetting, onResume discarded");
Chong Zhangefbb6192015-01-30 17:13:27 -08001502 return;
1503 }
1504 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001505 if (mSource != NULL) {
1506 mSource->resume();
1507 } else {
1508 ALOGW("resume called when source is gone or not set");
1509 }
1510 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1511 // needed.
1512 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1513 instantiateDecoder(true /* audio */, &mAudioDecoder);
1514 }
1515 if (mRenderer != NULL) {
1516 mRenderer->resume();
1517 } else {
1518 ALOGW("resume called when renderer is gone or not set");
1519 }
Ray Essickd4d00612017-01-03 09:36:27 -08001520
Ray Essick0d98c182017-11-09 13:42:42 -08001521 startPlaybackTimer("onresume");
Wei Jia94211742014-10-28 17:09:06 -07001522}
1523
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001524status_t NuPlayer::onInstantiateSecureDecoders() {
1525 status_t err;
1526 if (!(mSourceFlags & Source::FLAG_SECURE)) {
1527 return BAD_TYPE;
1528 }
1529
1530 if (mRenderer != NULL) {
1531 ALOGE("renderer should not be set when instantiating secure decoders");
1532 return UNKNOWN_ERROR;
1533 }
1534
1535 // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
1536 // data on instantiation.
Lajos Molnar1de1e252015-04-30 18:18:34 -07001537 if (mSurface != NULL) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07001538 err = instantiateDecoder(false, &mVideoDecoder);
1539 if (err != OK) {
1540 return err;
1541 }
1542 }
1543
1544 if (mAudioSink != NULL) {
1545 err = instantiateDecoder(true, &mAudioDecoder);
1546 if (err != OK) {
1547 return err;
1548 }
1549 }
1550 return OK;
1551}
1552
Wei Jiac5de0912016-11-18 10:22:14 -08001553void NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08001554 ALOGV("onStart: mCrypto: %p (%d)", mCrypto.get(),
1555 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
1556
Robert Shih0c61a0d2015-07-06 15:09:10 -07001557 if (!mSourceStarted) {
1558 mSourceStarted = true;
1559 mSource->start();
1560 }
1561 if (startPositionUs > 0) {
Wei Jiac5de0912016-11-18 10:22:14 -08001562 performSeek(startPositionUs, mode);
Robert Shih0c61a0d2015-07-06 15:09:10 -07001563 if (mSource->getFormat(false /* audio */) == NULL) {
1564 return;
1565 }
1566 }
1567
Wei Jia94211742014-10-28 17:09:06 -07001568 mOffloadAudio = false;
1569 mAudioEOS = false;
1570 mVideoEOS = false;
Wei Jia94211742014-10-28 17:09:06 -07001571 mStarted = true;
Wei Jiafe8fe7d2016-06-08 10:29:25 -07001572 mPaused = false;
Wei Jia94211742014-10-28 17:09:06 -07001573
Wei Jia94211742014-10-28 17:09:06 -07001574 uint32_t flags = 0;
1575
1576 if (mSource->isRealTime()) {
1577 flags |= Renderer::FLAG_REAL_TIME;
1578 }
1579
Wei Jia9737d342016-12-28 14:59:59 -08001580 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1581 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1582 if (!hasAudio && !hasVideo) {
Wei Jia1de83d52016-10-10 10:15:03 -07001583 ALOGE("no metadata for either audio or video source");
1584 mSource->stop();
1585 mSourceStarted = false;
1586 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_MALFORMED);
1587 return;
1588 }
Wei Jia9737d342016-12-28 14:59:59 -08001589 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1590
1591 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
Wei Jia1de83d52016-10-10 10:15:03 -07001592
Wei Jia94211742014-10-28 17:09:06 -07001593 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1594 if (mAudioSink != NULL) {
1595 streamType = mAudioSink->getAudioStreamType();
1596 }
1597
Wei Jia94211742014-10-28 17:09:06 -07001598 mOffloadAudio =
Wei Jia9737d342016-12-28 14:59:59 -08001599 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
Wei Jiabf70feb2016-02-19 15:47:16 -08001600 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001601
1602 // Modular DRM: Disabling audio offload if the source is protected
1603 if (mOffloadAudio && mIsDrmProtected) {
1604 mOffloadAudio = false;
1605 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1606 }
1607
Wei Jia94211742014-10-28 17:09:06 -07001608 if (mOffloadAudio) {
1609 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1610 }
1611
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001612 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
Wei Jia94211742014-10-28 17:09:06 -07001613 ++mRendererGeneration;
1614 notify->setInt32("generation", mRendererGeneration);
Wei Jia0a68f662017-08-30 18:01:26 -07001615 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
Wei Jia94211742014-10-28 17:09:06 -07001616 mRendererLooper = new ALooper;
1617 mRendererLooper->setName("NuPlayerRenderer");
1618 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1619 mRendererLooper->registerHandler(mRenderer);
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001620
1621 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1622 if (err != OK) {
1623 mSource->stop();
Robert Shih0c61a0d2015-07-06 15:09:10 -07001624 mSourceStarted = false;
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001625 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1626 return;
Wei Jiac8206ff2015-03-04 13:59:37 -08001627 }
Wei Jia94211742014-10-28 17:09:06 -07001628
Ronghua Wuc8a70d32015-04-29 16:26:34 -07001629 float rate = getFrameRate();
1630 if (rate > 0) {
Wei Jia94211742014-10-28 17:09:06 -07001631 mRenderer->setVideoFrameRate(rate);
1632 }
1633
Wei Jiac6cfd702014-11-11 16:33:20 -08001634 if (mVideoDecoder != NULL) {
1635 mVideoDecoder->setRenderer(mRenderer);
1636 }
1637 if (mAudioDecoder != NULL) {
1638 mAudioDecoder->setRenderer(mRenderer);
1639 }
1640
Ray Essick0d98c182017-11-09 13:42:42 -08001641 startPlaybackTimer("onstart");
Ray Essickd4d00612017-01-03 09:36:27 -08001642
Wei Jia94211742014-10-28 17:09:06 -07001643 postScanSources();
1644}
1645
Ray Essick0d98c182017-11-09 13:42:42 -08001646void NuPlayer::startPlaybackTimer(const char *where) {
1647 Mutex::Autolock autoLock(mPlayingTimeLock);
1648 if (mLastStartedPlayingTimeNs == 0) {
1649 mLastStartedPlayingTimeNs = systemTime();
1650 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1651 }
1652}
1653
Ray Essickeda32522018-02-28 12:08:28 -08001654void NuPlayer::updatePlaybackTimer(bool stopping, const char *where) {
Ray Essick0d98c182017-11-09 13:42:42 -08001655 Mutex::Autolock autoLock(mPlayingTimeLock);
1656
Ray Essickeda32522018-02-28 12:08:28 -08001657 ALOGV("updatePlaybackTimer(%s) time %20" PRId64 " (%s)",
1658 stopping ? "stop" : "snap", mLastStartedPlayingTimeNs, where);
Ray Essick0d98c182017-11-09 13:42:42 -08001659
1660 if (mLastStartedPlayingTimeNs != 0) {
1661 sp<NuPlayerDriver> driver = mDriver.promote();
Ray Essickeda32522018-02-28 12:08:28 -08001662 int64_t now = systemTime();
Ray Essick0d98c182017-11-09 13:42:42 -08001663 if (driver != NULL) {
Ray Essick0d98c182017-11-09 13:42:42 -08001664 int64_t played = now - mLastStartedPlayingTimeNs;
Ray Essickeda32522018-02-28 12:08:28 -08001665 ALOGV("updatePlaybackTimer() log %20" PRId64 "", played);
Ray Essick0d98c182017-11-09 13:42:42 -08001666
1667 if (played > 0) {
1668 driver->notifyMorePlayingTimeUs((played+500)/1000);
1669 }
1670 }
Ray Essickeda32522018-02-28 12:08:28 -08001671 if (stopping) {
1672 mLastStartedPlayingTimeNs = 0;
1673 } else {
1674 mLastStartedPlayingTimeNs = now;
1675 }
Ray Essick0d98c182017-11-09 13:42:42 -08001676 }
1677}
1678
Ray Essick58e0f7a2017-11-21 10:59:38 -08001679void NuPlayer::startRebufferingTimer() {
1680 Mutex::Autolock autoLock(mPlayingTimeLock);
1681 if (mLastStartedRebufferingTimeNs == 0) {
1682 mLastStartedRebufferingTimeNs = systemTime();
1683 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1684 }
1685}
1686
Ray Essickeda32522018-02-28 12:08:28 -08001687void NuPlayer::updateRebufferingTimer(bool stopping, bool exitingPlayback) {
Ray Essick58e0f7a2017-11-21 10:59:38 -08001688 Mutex::Autolock autoLock(mPlayingTimeLock);
1689
Ray Essickeda32522018-02-28 12:08:28 -08001690 ALOGV("updateRebufferingTimer(%s) time %20" PRId64 " (exiting %d)",
1691 stopping ? "stop" : "snap", mLastStartedRebufferingTimeNs, exitingPlayback);
Ray Essick58e0f7a2017-11-21 10:59:38 -08001692
1693 if (mLastStartedRebufferingTimeNs != 0) {
1694 sp<NuPlayerDriver> driver = mDriver.promote();
Ray Essickeda32522018-02-28 12:08:28 -08001695 int64_t now = systemTime();
Ray Essick58e0f7a2017-11-21 10:59:38 -08001696 if (driver != NULL) {
Ray Essick58e0f7a2017-11-21 10:59:38 -08001697 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
Ray Essickeda32522018-02-28 12:08:28 -08001698 ALOGV("updateRebufferingTimer() log %20" PRId64 "", rebuffered);
Ray Essick58e0f7a2017-11-21 10:59:38 -08001699
1700 if (rebuffered > 0) {
1701 driver->notifyMoreRebufferingTimeUs((rebuffered+500)/1000);
1702 if (exitingPlayback) {
1703 driver->notifyRebufferingWhenExit(true);
1704 }
1705 }
1706 }
Ray Essickeda32522018-02-28 12:08:28 -08001707 if (stopping) {
1708 mLastStartedRebufferingTimeNs = 0;
1709 } else {
1710 mLastStartedRebufferingTimeNs = now;
1711 }
Ray Essick58e0f7a2017-11-21 10:59:38 -08001712 }
1713}
1714
Ray Essickeda32522018-02-28 12:08:28 -08001715void NuPlayer::updateInternalTimers() {
1716 // update values, but ticking clocks keep ticking
1717 ALOGV("updateInternalTimers()");
1718 updatePlaybackTimer(false /* stopping */, "updateInternalTimers");
1719 updateRebufferingTimer(false /* stopping */, false /* exiting */);
1720}
1721
Kim Sungyeon23b23932019-07-18 17:48:32 +09001722void NuPlayer::setTargetBitrate(int bitrate) {
Lajos Molnared809da2020-08-17 16:53:02 -07001723 if (mSource != NULL) {
Kim Sungyeon23b23932019-07-18 17:48:32 +09001724 mSource->setTargetBitrate(bitrate);
Lajos Molnared809da2020-08-17 16:53:02 -07001725 }
Kim Sungyeon23b23932019-07-18 17:48:32 +09001726}
1727
Chong Zhangefbb6192015-01-30 17:13:27 -08001728void NuPlayer::onPause() {
Ray Essick0d98c182017-11-09 13:42:42 -08001729
Ray Essickeda32522018-02-28 12:08:28 -08001730 updatePlaybackTimer(true /* stopping */, "onPause");
Ray Essick0d98c182017-11-09 13:42:42 -08001731
Chong Zhangefbb6192015-01-30 17:13:27 -08001732 if (mPaused) {
1733 return;
1734 }
1735 mPaused = true;
1736 if (mSource != NULL) {
1737 mSource->pause();
1738 } else {
1739 ALOGW("pause called when source is gone or not set");
1740 }
1741 if (mRenderer != NULL) {
1742 mRenderer->pause();
1743 } else {
1744 ALOGW("pause called when renderer is gone or not set");
1745 }
Ray Essickd4d00612017-01-03 09:36:27 -08001746
Chong Zhangefbb6192015-01-30 17:13:27 -08001747}
1748
Ronghua Wud7988b12014-10-03 15:19:10 -07001749bool NuPlayer::audioDecoderStillNeeded() {
1750 // Audio decoder is no longer needed if it's in shut/shutting down status.
1751 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1752}
1753
Andy Hung8d121d42014-10-03 09:53:53 -07001754void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1755 // We wait for both the decoder flush and the renderer flush to complete
1756 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1757
1758 mFlushComplete[audio][isDecoder] = true;
1759 if (!mFlushComplete[audio][!isDecoder]) {
1760 return;
1761 }
1762
1763 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1764 switch (*state) {
1765 case FLUSHING_DECODER:
1766 {
1767 *state = FLUSHED;
Andy Hung8d121d42014-10-03 09:53:53 -07001768 break;
1769 }
1770
1771 case FLUSHING_DECODER_SHUTDOWN:
1772 {
1773 *state = SHUTTING_DOWN_DECODER;
1774
1775 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
Andy Hung8d121d42014-10-03 09:53:53 -07001776 getDecoder(audio)->initiateShutdown();
1777 break;
1778 }
1779
1780 default:
1781 // decoder flush completes only occur in a flushing state.
1782 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1783 break;
1784 }
1785}
1786
Andreas Huber3831a062010-12-21 10:22:33 -08001787void NuPlayer::finishFlushIfPossible() {
Wei Jia53904f32014-07-29 10:22:53 -07001788 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1789 && mFlushingAudio != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001790 return;
1791 }
1792
Wei Jia53904f32014-07-29 10:22:53 -07001793 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1794 && mFlushingVideo != SHUT_DOWN) {
Andreas Huber3831a062010-12-21 10:22:33 -08001795 return;
1796 }
1797
Steve Block3856b092011-10-20 11:56:00 +01001798 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -08001799
Andreas Huber3831a062010-12-21 10:22:33 -08001800 mFlushingAudio = NONE;
1801 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -08001802
Andy Hung8d121d42014-10-03 09:53:53 -07001803 clearFlushComplete();
1804
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001805 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -08001806}
1807
1808void NuPlayer::postScanSources() {
1809 if (mScanSourcesPending) {
1810 return;
1811 }
1812
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001813 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
Andreas Huber1aef2112011-01-04 14:01:29 -08001814 msg->setInt32("generation", mScanSourcesGeneration);
1815 msg->post();
1816
1817 mScanSourcesPending = true;
1818}
1819
Wei Jia41cd4632016-05-13 10:53:30 -07001820void NuPlayer::tryOpenAudioSinkForOffload(
1821 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
Andy Hung202bce12014-12-03 11:47:36 -08001822 // Note: This is called early in NuPlayer to determine whether offloading
1823 // is possible; otherwise the decoders call the renderer openAudioSink directly.
Andy Hung282a7e32014-08-14 15:56:34 -07001824
Andy Hung202bce12014-12-03 11:47:36 -08001825 status_t err = mRenderer->openAudioSink(
Dhananjay Kumarc387f2b2015-08-06 10:43:16 +05301826 format, true /* offloadOnly */, hasVideo,
1827 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
Andy Hung202bce12014-12-03 11:47:36 -08001828 if (err != OK) {
1829 // Any failure we turn off mOffloadAudio.
1830 mOffloadAudio = false;
1831 } else if (mOffloadAudio) {
Chong Zhang3b9eb1f2014-10-15 17:05:08 -07001832 sendMetaDataToHal(mAudioSink, audioMeta);
Andy Hung282a7e32014-08-14 15:56:34 -07001833 }
1834}
1835
1836void NuPlayer::closeAudioSink() {
Daniel Norman1e0d88b2020-01-07 15:02:54 -08001837 if (mRenderer != NULL) {
1838 mRenderer->closeAudioSink();
1839 }
Andy Hung282a7e32014-08-14 15:56:34 -07001840}
1841
Wei Jia5031b2f2016-02-25 11:19:31 -08001842void NuPlayer::restartAudio(
Wei Jiabf70feb2016-02-19 15:47:16 -08001843 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
Wei Jia355b2bb2018-04-09 16:36:23 -07001844 ALOGD("restartAudio timeUs(%lld), dontOffload(%d), createDecoder(%d)",
1845 (long long)currentPositionUs, forceNonOffload, needsToCreateAudioDecoder);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001846 if (mAudioDecoder != NULL) {
1847 mAudioDecoder->pause();
Ray Essickfcb8fd32018-08-07 09:39:38 -07001848 Mutex::Autolock autoLock(mDecoderLock);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001849 mAudioDecoder.clear();
Wei Jia686e8e52017-04-03 14:08:01 -07001850 mAudioDecoderError = false;
Wei Jiaa05f1e32016-03-25 16:31:22 -07001851 ++mAudioDecoderGeneration;
1852 }
Wei Jiabf70feb2016-02-19 15:47:16 -08001853 if (mFlushingAudio == FLUSHING_DECODER) {
1854 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1855 mFlushingAudio = FLUSHED;
1856 finishFlushIfPossible();
1857 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1858 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1859 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1860 mFlushingAudio = SHUT_DOWN;
1861 finishFlushIfPossible();
1862 needsToCreateAudioDecoder = false;
1863 }
1864 if (mRenderer == NULL) {
1865 return;
1866 }
1867 closeAudioSink();
1868 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1869 if (mVideoDecoder != NULL) {
Praveen Chavaneca08fb2019-01-21 11:00:38 -08001870 mDeferredActions.push_back(
1871 new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
1872 FLUSH_CMD_FLUSH /* video */));
1873 mDeferredActions.push_back(
1874 new SeekAction(currentPositionUs,
1875 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
1876 // After a flush without shutdown, decoder is paused.
1877 // Don't resume it until source seek is done, otherwise it could
1878 // start pulling stale data too soon.
1879 mDeferredActions.push_back(new ResumeDecoderAction(false));
1880 processDeferredActions();
1881 } else {
1882 performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
Wei Jiabf70feb2016-02-19 15:47:16 -08001883 }
1884
Wei Jiabf70feb2016-02-19 15:47:16 -08001885 if (forceNonOffload) {
1886 mRenderer->signalDisableOffloadAudio();
1887 mOffloadAudio = false;
1888 }
1889 if (needsToCreateAudioDecoder) {
Wei Jiaa05f1e32016-03-25 16:31:22 -07001890 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
Wei Jiabf70feb2016-02-19 15:47:16 -08001891 }
1892}
1893
Wei Jia41cd4632016-05-13 10:53:30 -07001894void NuPlayer::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiae4d18c72015-07-13 17:58:11 -07001895 if (mSource == NULL || mAudioSink == NULL) {
1896 return;
1897 }
1898
1899 if (mRenderer == NULL) {
1900 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1901 mOffloadAudio = false;
1902 return;
1903 }
1904
1905 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1906 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1907 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1908 const bool hasVideo = (videoFormat != NULL);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001909 bool canOffload = canOffloadStream(
Wei Jiabf70feb2016-02-19 15:47:16 -08001910 audioMeta, hasVideo, mSource->isStreaming(), streamType)
1911 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001912
1913 // Modular DRM: Disabling audio offload if the source is protected
1914 if (canOffload && mIsDrmProtected) {
1915 canOffload = false;
1916 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1917 }
1918
Wei Jiae4d18c72015-07-13 17:58:11 -07001919 if (canOffload) {
1920 if (!mOffloadAudio) {
1921 mRenderer->signalEnableOffloadAudio();
1922 }
1923 // open audio sink early under offload mode.
Wei Jia41cd4632016-05-13 10:53:30 -07001924 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
Wei Jiae4d18c72015-07-13 17:58:11 -07001925 } else {
Robert Shihe1d70192015-07-23 17:54:13 -07001926 if (mOffloadAudio) {
1927 mRenderer->signalDisableOffloadAudio();
1928 mOffloadAudio = false;
1929 }
Wei Jiae4d18c72015-07-13 17:58:11 -07001930 }
1931}
1932
Wei Jiaa05f1e32016-03-25 16:31:22 -07001933status_t NuPlayer::instantiateDecoder(
1934 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
Wei Jia566da802015-08-27 13:59:30 -07001935 // The audio decoder could be cleared by tear down. If still in shut down
1936 // process, no need to create a new audio decoder.
1937 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
Andreas Huberf9334412010-12-15 15:17:42 -08001938 return OK;
1939 }
1940
Andreas Huber84066782011-08-16 09:34:26 -07001941 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -08001942
Andreas Huber84066782011-08-16 09:34:26 -07001943 if (format == NULL) {
Robert Shih7350b052015-10-01 15:50:14 -07001944 return UNKNOWN_ERROR;
1945 } else {
1946 status_t err;
1947 if (format->findInt32("err", &err) && err) {
1948 return err;
1949 }
Andreas Huberf9334412010-12-15 15:17:42 -08001950 }
1951
Ronghua Wu8db88132015-04-22 13:51:35 -07001952 format->setInt32("priority", 0 /* realtime */);
1953
Byeongjo Park5e27b1b2018-07-12 15:36:03 +09001954 if (mDataSourceType == DATA_SOURCE_TYPE_RTP) {
1955 ALOGV("instantiateDecoder: set decoder error free on stream corrupt.");
1956 format->setInt32("corrupt-free", true);
1957 }
1958
Andreas Huber3fe62152011-09-16 15:09:22 -07001959 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -07001960 AString mime;
1961 CHECK(format->findString("mime", &mime));
Chong Zhanga7fa1d92014-06-11 14:49:23 -07001962
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001963 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
Chong Zhang341ab6e2015-02-04 13:37:18 -08001964 if (mCCDecoder == NULL) {
1965 mCCDecoder = new CCDecoder(ccNotify);
1966 }
Lajos Molnar09524832014-07-17 14:29:51 -07001967
1968 if (mSourceFlags & Source::FLAG_SECURE) {
1969 format->setInt32("secure", true);
1970 }
Chong Zhang17134602015-01-07 16:14:34 -08001971
1972 if (mSourceFlags & Source::FLAG_PROTECTED) {
1973 format->setInt32("protected", true);
1974 }
Ronghua Wu8db88132015-04-22 13:51:35 -07001975
Ronghua Wuc8a70d32015-04-29 16:26:34 -07001976 float rate = getFrameRate();
1977 if (rate > 0) {
Lajos Molnar3a474aa2015-04-24 17:10:07 -07001978 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
Ronghua Wu8db88132015-04-22 13:51:35 -07001979 }
Andreas Huber3fe62152011-09-16 15:09:22 -07001980 }
1981
Ray Essickfcb8fd32018-08-07 09:39:38 -07001982 Mutex::Autolock autoLock(mDecoderLock);
1983
Wei Jiabc2fb722014-07-08 16:37:57 -07001984 if (audio) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08001985 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07001986 ++mAudioDecoderGeneration;
1987 notify->setInt32("generation", mAudioDecoderGeneration);
1988
Wei Jiaa05f1e32016-03-25 16:31:22 -07001989 if (checkAudioModeChange) {
Wei Jia41cd4632016-05-13 10:53:30 -07001990 determineAudioModeChange(format);
Wei Jiaa05f1e32016-03-25 16:31:22 -07001991 }
Wei Jiabc2fb722014-07-08 16:37:57 -07001992 if (mOffloadAudio) {
Wei Jia14532f22015-12-29 11:28:15 -08001993 mSource->setOffloadAudio(true /* offload */);
1994
Haynes Mathew George8b635332015-03-30 17:59:47 -07001995 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1996 format->setInt32("has-video", hasVideo);
Wei Jiac6cfd702014-11-11 16:33:20 -08001997 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001998 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
Wei Jiabc2fb722014-07-08 16:37:57 -07001999 } else {
Wei Jia14532f22015-12-29 11:28:15 -08002000 mSource->setOffloadAudio(false /* offload */);
2001
Wei Jiaf2ae3e12016-10-27 17:10:59 -07002002 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
Hassan Shojaniacefac142017-02-06 21:02:02 -08002003 ALOGV("instantiateDecoder audio Decoder");
Wei Jiabc2fb722014-07-08 16:37:57 -07002004 }
Wei Jia686e8e52017-04-03 14:08:01 -07002005 mAudioDecoderError = false;
Wei Jiabc2fb722014-07-08 16:37:57 -07002006 } else {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002007 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
Wei Jia88703c32014-08-06 11:24:07 -07002008 ++mVideoDecoderGeneration;
2009 notify->setInt32("generation", mVideoDecoderGeneration);
2010
Chong Zhang7137ec72014-11-12 16:41:05 -08002011 *decoder = new Decoder(
Wei Jiaf2ae3e12016-10-27 17:10:59 -07002012 notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
Wei Jia686e8e52017-04-03 14:08:01 -07002013 mVideoDecoderError = false;
Lajos Molnard9fd6312014-11-06 11:00:00 -08002014
2015 // enable FRC if high-quality AV sync is requested, even if not
Lajos Molnar1de1e252015-04-30 18:18:34 -07002016 // directly queuing to display, as this will even improve textureview
Lajos Molnard9fd6312014-11-06 11:00:00 -08002017 // playback.
2018 {
Marco Nelissen96626b72016-12-01 13:58:59 -08002019 if (property_get_bool("persist.sys.media.avsync", false)) {
Lajos Molnard9fd6312014-11-06 11:00:00 -08002020 format->setInt32("auto-frc", 1);
2021 }
2022 }
Wei Jiabc2fb722014-07-08 16:37:57 -07002023 }
Lajos Molnar1cd13982014-01-17 15:12:51 -08002024 (*decoder)->init();
Hassan Shojaniacefac142017-02-06 21:02:02 -08002025
2026 // Modular DRM
2027 if (mIsDrmProtected) {
2028 format->setPointer("crypto", mCrypto.get());
2029 ALOGV("instantiateDecoder: mCrypto: %p (%d) isSecure: %d", mCrypto.get(),
2030 (mCrypto != NULL ? mCrypto->getStrongCount() : 0),
2031 (mSourceFlags & Source::FLAG_SECURE) != 0);
2032 }
2033
Andreas Huber84066782011-08-16 09:34:26 -07002034 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -08002035
Praveen Chavanbbaa1442016-04-08 13:33:49 -07002036 if (!audio) {
2037 sp<AMessage> params = new AMessage();
2038 float rate = getFrameRate();
2039 if (rate > 0) {
2040 params->setFloat("frame-rate-total", rate);
2041 }
2042
2043 sp<MetaData> fileMeta = getFileMeta();
2044 if (fileMeta != NULL) {
2045 int32_t videoTemporalLayerCount;
2046 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2047 && videoTemporalLayerCount > 0) {
2048 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2049 }
2050 }
2051
2052 if (params->countEntries() > 0) {
2053 (*decoder)->setParameters(params);
2054 }
2055 }
Andreas Huberf9334412010-12-15 15:17:42 -08002056 return OK;
2057}
2058
Chong Zhangced1c2f2014-08-08 15:22:35 -07002059void NuPlayer::updateVideoSize(
2060 const sp<AMessage> &inputFormat,
2061 const sp<AMessage> &outputFormat) {
2062 if (inputFormat == NULL) {
2063 ALOGW("Unknown video size, reporting 0x0!");
2064 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
2065 return;
2066 }
Wei Jia9737d342016-12-28 14:59:59 -08002067 int32_t err = OK;
2068 inputFormat->findInt32("err", &err);
2069 if (err == -EWOULDBLOCK) {
2070 ALOGW("Video meta is not available yet!");
2071 return;
2072 }
2073 if (err != OK) {
2074 ALOGW("Something is wrong with video meta!");
2075 return;
2076 }
Chong Zhangced1c2f2014-08-08 15:22:35 -07002077
2078 int32_t displayWidth, displayHeight;
Chong Zhangced1c2f2014-08-08 15:22:35 -07002079 if (outputFormat != NULL) {
2080 int32_t width, height;
2081 CHECK(outputFormat->findInt32("width", &width));
2082 CHECK(outputFormat->findInt32("height", &height));
2083
2084 int32_t cropLeft, cropTop, cropRight, cropBottom;
2085 CHECK(outputFormat->findRect(
2086 "crop",
2087 &cropLeft, &cropTop, &cropRight, &cropBottom));
2088
2089 displayWidth = cropRight - cropLeft + 1;
2090 displayHeight = cropBottom - cropTop + 1;
2091
2092 ALOGV("Video output format changed to %d x %d "
2093 "(crop: %d x %d @ (%d, %d))",
2094 width, height,
2095 displayWidth,
2096 displayHeight,
2097 cropLeft, cropTop);
2098 } else {
2099 CHECK(inputFormat->findInt32("width", &displayWidth));
2100 CHECK(inputFormat->findInt32("height", &displayHeight));
2101
2102 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2103 }
2104
2105 // Take into account sample aspect ratio if necessary:
2106 int32_t sarWidth, sarHeight;
2107 if (inputFormat->findInt32("sar-width", &sarWidth)
Wei Jia095bc252017-01-27 10:16:16 -08002108 && inputFormat->findInt32("sar-height", &sarHeight)
2109 && sarWidth > 0 && sarHeight > 0) {
Chong Zhangced1c2f2014-08-08 15:22:35 -07002110 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2111
2112 displayWidth = (displayWidth * sarWidth) / sarHeight;
2113
2114 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
Wei Jiadf6c6af2016-09-29 11:27:15 -07002115 } else {
2116 int32_t width, height;
2117 if (inputFormat->findInt32("display-width", &width)
2118 && inputFormat->findInt32("display-height", &height)
2119 && width > 0 && height > 0
2120 && displayWidth > 0 && displayHeight > 0) {
2121 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2122 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2123 } else {
2124 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2125 }
2126 ALOGV("Video display width and height are overridden to %d x %d",
2127 displayWidth, displayHeight);
2128 }
Chong Zhangced1c2f2014-08-08 15:22:35 -07002129 }
2130
2131 int32_t rotationDegrees;
2132 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2133 rotationDegrees = 0;
2134 }
2135
2136 if (rotationDegrees == 90 || rotationDegrees == 270) {
2137 int32_t tmp = displayWidth;
2138 displayWidth = displayHeight;
2139 displayHeight = tmp;
2140 }
2141
2142 notifyListener(
2143 MEDIA_SET_VIDEO_SIZE,
2144 displayWidth,
2145 displayHeight);
2146}
2147
Chong Zhangdcb89b32013-08-06 09:44:47 -07002148void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002149 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08002150 return;
2151 }
2152
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002153 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08002154
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002155 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08002156 return;
2157 }
2158
Chong Zhangdcb89b32013-08-06 09:44:47 -07002159 driver->notifyListener(msg, ext1, ext2, in);
Andreas Huberf9334412010-12-15 15:17:42 -08002160}
2161
Chong Zhang7137ec72014-11-12 16:41:05 -08002162void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber14f76722013-01-15 09:04:18 -08002163 ALOGV("[%s] flushDecoder needShutdown=%d",
2164 audio ? "audio" : "video", needShutdown);
2165
Chong Zhang7137ec72014-11-12 16:41:05 -08002166 const sp<DecoderBase> &decoder = getDecoder(audio);
Lajos Molnar87603c02014-08-20 19:25:30 -07002167 if (decoder == NULL) {
Steve Blockdf64d152012-01-04 20:05:49 +00002168 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08002169 audio ? "audio" : "video");
Lajos Molnar87603c02014-08-20 19:25:30 -07002170 return;
Andreas Huber6e3d3112011-11-28 12:36:11 -08002171 }
2172
Andreas Huber1aef2112011-01-04 14:01:29 -08002173 // Make sure we don't continue to scan sources until we finish flushing.
2174 ++mScanSourcesGeneration;
Chong Zhang3b032b32015-04-17 15:49:06 -07002175 if (mScanSourcesPending) {
Toshikazu Saitocbcbb792015-09-15 14:53:01 +09002176 if (!needShutdown) {
2177 mDeferredActions.push_back(
2178 new SimpleAction(&NuPlayer::performScanSources));
2179 }
Chong Zhang3b032b32015-04-17 15:49:06 -07002180 mScanSourcesPending = false;
2181 }
Andreas Huber1aef2112011-01-04 14:01:29 -08002182
Chong Zhang7137ec72014-11-12 16:41:05 -08002183 decoder->signalFlush();
Andreas Huber1aef2112011-01-04 14:01:29 -08002184
2185 FlushStatus newStatus =
2186 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2187
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002188 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
Andy Hung8d121d42014-10-03 09:53:53 -07002189 mFlushComplete[audio][true /* isDecoder */] = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08002190 if (audio) {
Wei Jia53904f32014-07-29 10:22:53 -07002191 ALOGE_IF(mFlushingAudio != NONE,
2192 "audio flushDecoder() is called in state %d", mFlushingAudio);
Andreas Huber1aef2112011-01-04 14:01:29 -08002193 mFlushingAudio = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08002194 } else {
Wei Jia53904f32014-07-29 10:22:53 -07002195 ALOGE_IF(mFlushingVideo != NONE,
2196 "video flushDecoder() is called in state %d", mFlushingVideo);
Andreas Huber1aef2112011-01-04 14:01:29 -08002197 mFlushingVideo = newStatus;
Andreas Huber1aef2112011-01-04 14:01:29 -08002198 }
2199}
2200
Chong Zhangced1c2f2014-08-08 15:22:35 -07002201void NuPlayer::queueDecoderShutdown(
2202 bool audio, bool video, const sp<AMessage> &reply) {
2203 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
Andreas Huber84066782011-08-16 09:34:26 -07002204
Chong Zhangced1c2f2014-08-08 15:22:35 -07002205 mDeferredActions.push_back(
Wei Jiafef808d2014-10-31 17:57:05 -07002206 new FlushDecoderAction(
2207 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2208 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
Andreas Huber84066782011-08-16 09:34:26 -07002209
Chong Zhangced1c2f2014-08-08 15:22:35 -07002210 mDeferredActions.push_back(
2211 new SimpleAction(&NuPlayer::performScanSources));
Andreas Huber84066782011-08-16 09:34:26 -07002212
Chong Zhangced1c2f2014-08-08 15:22:35 -07002213 mDeferredActions.push_back(new PostMessageAction(reply));
2214
2215 processDeferredActions();
Andreas Huber84066782011-08-16 09:34:26 -07002216}
2217
James Dong0d268a32012-08-31 12:18:27 -07002218status_t NuPlayer::setVideoScalingMode(int32_t mode) {
2219 mVideoScalingMode = mode;
Lajos Molnar1de1e252015-04-30 18:18:34 -07002220 if (mSurface != NULL) {
2221 status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
James Dong0d268a32012-08-31 12:18:27 -07002222 if (ret != OK) {
2223 ALOGE("Failed to set scaling mode (%d): %s",
2224 -ret, strerror(-ret));
2225 return ret;
2226 }
2227 }
2228 return OK;
2229}
2230
Chong Zhangdcb89b32013-08-06 09:44:47 -07002231status_t NuPlayer::getTrackInfo(Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002232 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002233 msg->setPointer("reply", reply);
2234
2235 sp<AMessage> response;
2236 status_t err = msg->postAndAwaitResponse(&response);
2237 return err;
2238}
2239
Robert Shih7c4f0d72014-07-09 18:53:31 -07002240status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002241 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
Robert Shih7c4f0d72014-07-09 18:53:31 -07002242 msg->setPointer("reply", reply);
2243 msg->setInt32("type", type);
2244
2245 sp<AMessage> response;
2246 status_t err = msg->postAndAwaitResponse(&response);
2247 if (err == OK && response != NULL) {
2248 CHECK(response->findInt32("err", &err));
2249 }
2250 return err;
2251}
2252
Robert Shih6ffb1fd2014-10-29 16:24:32 -07002253status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002254 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002255 msg->setSize("trackIndex", trackIndex);
2256 msg->setInt32("select", select);
Robert Shih6ffb1fd2014-10-29 16:24:32 -07002257 msg->setInt64("timeUs", timeUs);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002258
2259 sp<AMessage> response;
2260 status_t err = msg->postAndAwaitResponse(&response);
2261
Chong Zhang404fced2014-06-11 14:45:31 -07002262 if (err != OK) {
2263 return err;
2264 }
2265
2266 if (!response->findInt32("err", &err)) {
2267 err = OK;
2268 }
2269
Chong Zhangdcb89b32013-08-06 09:44:47 -07002270 return err;
2271}
2272
Ronghua Wua73d9e02014-10-08 15:13:29 -07002273status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
2274 sp<Renderer> renderer = mRenderer;
2275 if (renderer == NULL) {
2276 return NO_INIT;
2277 }
2278
2279 return renderer->getCurrentPosition(mediaUs);
2280}
2281
Ray Essickffc941f2018-05-18 11:08:37 -07002282void NuPlayer::getStats(Vector<sp<AMessage> > *trackStats) {
2283 CHECK(trackStats != NULL);
Praveen Chavane1e5d7a2015-05-19 19:09:48 -07002284
Ray Essickfcb8fd32018-08-07 09:39:38 -07002285 trackStats->clear();
Ray Essickffc941f2018-05-18 11:08:37 -07002286
Ray Essickfcb8fd32018-08-07 09:39:38 -07002287 Mutex::Autolock autoLock(mDecoderLock);
2288 if (mVideoDecoder != NULL) {
2289 trackStats->push_back(mVideoDecoder->getStats());
2290 }
2291 if (mAudioDecoder != NULL) {
2292 trackStats->push_back(mAudioDecoder->getStats());
2293 }
Ronghua Wua73d9e02014-10-08 15:13:29 -07002294}
2295
Marco Nelissenf0b72b52014-09-16 15:43:44 -07002296sp<MetaData> NuPlayer::getFileMeta() {
2297 return mSource->getFileFormatMeta();
2298}
2299
Ronghua Wuc8a70d32015-04-29 16:26:34 -07002300float NuPlayer::getFrameRate() {
2301 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2302 if (meta == NULL) {
2303 return 0;
2304 }
2305 int32_t rate;
2306 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2307 // fall back to try file meta
2308 sp<MetaData> fileMeta = getFileMeta();
2309 if (fileMeta == NULL) {
2310 ALOGW("source has video meta but not file meta");
2311 return -1;
2312 }
2313 int32_t fileMetaRate;
2314 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2315 return -1;
2316 }
2317 return fileMetaRate;
2318 }
2319 return rate;
2320}
2321
Andreas Huberb7c8e912012-11-27 15:02:53 -08002322void NuPlayer::schedulePollDuration() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -08002323 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
Andreas Huberb7c8e912012-11-27 15:02:53 -08002324 msg->setInt32("generation", mPollDurationGeneration);
2325 msg->post();
2326}
2327
2328void NuPlayer::cancelPollDuration() {
2329 ++mPollDurationGeneration;
2330}
2331
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002332void NuPlayer::processDeferredActions() {
2333 while (!mDeferredActions.empty()) {
2334 // We won't execute any deferred actions until we're no longer in
2335 // an intermediate state, i.e. one more more decoders are currently
2336 // flushing or shutting down.
2337
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002338 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2339 // We're currently flushing, postpone the reset until that's
2340 // completed.
2341
2342 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2343 mFlushingAudio, mFlushingVideo);
2344
2345 break;
2346 }
2347
2348 sp<Action> action = *mDeferredActions.begin();
2349 mDeferredActions.erase(mDeferredActions.begin());
2350
2351 action->execute(this);
2352 }
2353}
2354
Wei Jiac5de0912016-11-18 10:22:14 -08002355void NuPlayer::performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
2356 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2357 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002358
Andy Hungadf34bf2014-09-03 18:22:22 -07002359 if (mSource == NULL) {
2360 // This happens when reset occurs right before the loop mode
2361 // asynchronously seeks to the start of the stream.
2362 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2363 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2364 mAudioDecoder.get(), mVideoDecoder.get());
2365 return;
2366 }
Robert Shih1a5c8592015-08-04 18:07:44 -07002367 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiac5de0912016-11-18 10:22:14 -08002368 mSource->seekTo(seekTimeUs, mode);
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002369 ++mTimedTextGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002370
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002371 // everything's flushed, continue playback.
2372}
2373
Wei Jiafef808d2014-10-31 17:57:05 -07002374void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2375 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002376
Wei Jiafef808d2014-10-31 17:57:05 -07002377 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2378 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002379 return;
2380 }
2381
Wei Jiafef808d2014-10-31 17:57:05 -07002382 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2383 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002384 }
2385
Wei Jiafef808d2014-10-31 17:57:05 -07002386 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2387 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002388 }
2389}
2390
2391void NuPlayer::performReset() {
2392 ALOGV("performReset");
2393
2394 CHECK(mAudioDecoder == NULL);
2395 CHECK(mVideoDecoder == NULL);
2396
Ray Essickeda32522018-02-28 12:08:28 -08002397 updatePlaybackTimer(true /* stopping */, "performReset");
2398 updateRebufferingTimer(true /* stopping */, true /* exiting */);
Ray Essick0d98c182017-11-09 13:42:42 -08002399
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002400 cancelPollDuration();
2401
2402 ++mScanSourcesGeneration;
2403 mScanSourcesPending = false;
2404
Lajos Molnar09524832014-07-17 14:29:51 -07002405 if (mRendererLooper != NULL) {
2406 if (mRenderer != NULL) {
2407 mRendererLooper->unregisterHandler(mRenderer->id());
2408 }
2409 mRendererLooper->stop();
2410 mRendererLooper.clear();
2411 }
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002412 mRenderer.clear();
Wei Jia57568df2014-09-22 10:16:29 -07002413 ++mRendererGeneration;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002414
2415 if (mSource != NULL) {
2416 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08002417
Wei Jiac45a4b22016-04-15 15:30:23 -07002418 Mutex::Autolock autoLock(mSourceLock);
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002419 mSource.clear();
2420 }
2421
2422 if (mDriver != NULL) {
2423 sp<NuPlayerDriver> driver = mDriver.promote();
2424 if (driver != NULL) {
2425 driver->notifyResetComplete();
2426 }
2427 }
Andreas Huber57a339c2012-12-03 11:18:00 -08002428
2429 mStarted = false;
Wei Jia8a092d32016-06-03 14:57:24 -07002430 mPrepared = false;
Ronghua Wu64c2d172015-10-07 16:52:19 -07002431 mResetting = false;
Robert Shih0c61a0d2015-07-06 15:09:10 -07002432 mSourceStarted = false;
Hassan Shojaniacefac142017-02-06 21:02:02 -08002433
2434 // Modular DRM
2435 if (mCrypto != NULL) {
2436 // decoders will be flushed before this so their mCrypto would go away on their own
2437 // TODO change to ALOGV
2438 ALOGD("performReset mCrypto: %p (%d)", mCrypto.get(),
2439 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2440 mCrypto.clear();
2441 }
2442 mIsDrmProtected = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002443}
2444
2445void NuPlayer::performScanSources() {
2446 ALOGV("performScanSources");
2447
Andreas Huber57a339c2012-12-03 11:18:00 -08002448 if (!mStarted) {
2449 return;
2450 }
2451
Andreas Hubera1f8ab02012-11-30 10:53:22 -08002452 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2453 postScanSources();
2454 }
2455}
2456
Lajos Molnar1de1e252015-04-30 18:18:34 -07002457void NuPlayer::performSetSurface(const sp<Surface> &surface) {
Andreas Huber57a339c2012-12-03 11:18:00 -08002458 ALOGV("performSetSurface");
2459
Lajos Molnar1de1e252015-04-30 18:18:34 -07002460 mSurface = surface;
Andreas Huber57a339c2012-12-03 11:18:00 -08002461
2462 // XXX - ignore error from setVideoScalingMode for now
2463 setVideoScalingMode(mVideoScalingMode);
Chong Zhang13d6faa2014-08-22 15:35:28 -07002464
2465 if (mDriver != NULL) {
2466 sp<NuPlayerDriver> driver = mDriver.promote();
2467 if (driver != NULL) {
2468 driver->notifySetSurfaceComplete();
2469 }
2470 }
Andreas Huber57a339c2012-12-03 11:18:00 -08002471}
2472
Chong Zhangf8d71772014-11-26 15:08:34 -08002473void NuPlayer::performResumeDecoders(bool needNotify) {
2474 if (needNotify) {
2475 mResumePending = true;
2476 if (mVideoDecoder == NULL) {
2477 // if audio-only, we can notify seek complete now,
2478 // as the resume operation will be relatively fast.
2479 finishResume();
2480 }
2481 }
2482
Chong Zhang7137ec72014-11-12 16:41:05 -08002483 if (mVideoDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08002484 // When there is continuous seek, MediaPlayer will cache the seek
2485 // position, and send down new seek request when previous seek is
2486 // complete. Let's wait for at least one video output frame before
2487 // notifying seek complete, so that the video thumbnail gets updated
2488 // when seekbar is dragged.
2489 mVideoDecoder->signalResume(needNotify);
Chong Zhang7137ec72014-11-12 16:41:05 -08002490 }
2491
2492 if (mAudioDecoder != NULL) {
Chong Zhangf8d71772014-11-26 15:08:34 -08002493 mAudioDecoder->signalResume(false /* needNotify */);
2494 }
2495}
2496
2497void NuPlayer::finishResume() {
2498 if (mResumePending) {
2499 mResumePending = false;
Wei Jia1061c9c2015-05-19 16:02:17 -07002500 notifyDriverSeekComplete();
2501 }
2502}
2503
2504void NuPlayer::notifyDriverSeekComplete() {
2505 if (mDriver != NULL) {
2506 sp<NuPlayerDriver> driver = mDriver.promote();
2507 if (driver != NULL) {
2508 driver->notifySeekComplete();
Chong Zhangf8d71772014-11-26 15:08:34 -08002509 }
Chong Zhang7137ec72014-11-12 16:41:05 -08002510 }
2511}
2512
Andreas Huber9575c962013-02-05 13:59:56 -08002513void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
2514 int32_t what;
2515 CHECK(msg->findInt32("what", &what));
2516
2517 switch (what) {
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002518 case Source::kWhatInstantiateSecureDecoders:
2519 {
2520 if (mSource == NULL) {
2521 // This is a stale notification from a source that was
2522 // asynchronously preparing when the client called reset().
2523 // We handled the reset, the source is gone.
2524 break;
2525 }
2526
2527 sp<AMessage> reply;
2528 CHECK(msg->findMessage("reply", &reply));
2529 status_t err = onInstantiateSecureDecoders();
2530 reply->setInt32("err", err);
2531 reply->post();
2532 break;
2533 }
2534
Andreas Huber9575c962013-02-05 13:59:56 -08002535 case Source::kWhatPrepared:
2536 {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002537 ALOGV("NuPlayer::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
Andreas Huberb5f28d42013-04-25 15:11:19 -07002538 if (mSource == NULL) {
2539 // This is a stale notification from a source that was
2540 // asynchronously preparing when the client called reset().
2541 // We handled the reset, the source is gone.
2542 break;
2543 }
2544
Andreas Huberec0c5972013-02-05 14:47:13 -08002545 int32_t err;
2546 CHECK(msg->findInt32("err", &err));
2547
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002548 if (err != OK) {
2549 // shut down potential secure codecs in case client never calls reset
2550 mDeferredActions.push_back(
2551 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2552 FLUSH_CMD_SHUTDOWN /* video */));
2553 processDeferredActions();
Wei Jia8a092d32016-06-03 14:57:24 -07002554 } else {
2555 mPrepared = true;
Lajos Molnarfcd3e942015-03-31 10:06:48 -07002556 }
2557
Andreas Huber9575c962013-02-05 13:59:56 -08002558 sp<NuPlayerDriver> driver = mDriver.promote();
2559 if (driver != NULL) {
Marco Nelissendd114d12014-05-28 15:23:14 -07002560 // notify duration first, so that it's definitely set when
2561 // the app received the "prepare complete" callback.
2562 int64_t durationUs;
2563 if (mSource->getDuration(&durationUs) == OK) {
2564 driver->notifyDuration(durationUs);
2565 }
Andreas Huberec0c5972013-02-05 14:47:13 -08002566 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08002567 }
Andreas Huber99759402013-04-01 14:28:31 -07002568
Andreas Huber9575c962013-02-05 13:59:56 -08002569 break;
2570 }
2571
Hassan Shojaniacefac142017-02-06 21:02:02 -08002572 // Modular DRM
2573 case Source::kWhatDrmInfo:
2574 {
2575 Parcel parcel;
2576 sp<ABuffer> drmInfo;
2577 CHECK(msg->findBuffer("drmInfo", &drmInfo));
2578 parcel.setData(drmInfo->data(), drmInfo->size());
2579
2580 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA_DRM_INFO drmInfo: %p parcel size: %zu",
2581 drmInfo.get(), parcel.dataSize());
2582
2583 notifyListener(MEDIA_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
2584
2585 break;
2586 }
2587
Andreas Huber9575c962013-02-05 13:59:56 -08002588 case Source::kWhatFlagsChanged:
2589 {
2590 uint32_t flags;
2591 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2592
Chong Zhang4b7069d2013-09-11 12:52:43 -07002593 sp<NuPlayerDriver> driver = mDriver.promote();
2594 if (driver != NULL) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08002595
2596 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2597 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2598 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2599 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2600 (flags & Source::FLAG_CAN_PAUSE) != 0,
2601 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2602 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2603 (flags & Source::FLAG_CAN_SEEK) != 0,
2604 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2605 (flags & Source::FLAG_SECURE) != 0,
2606 (flags & Source::FLAG_PROTECTED) != 0);
2607
Wei Jia895651b2014-12-10 17:31:52 -08002608 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
2609 driver->notifyListener(
2610 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
2611 }
Chong Zhang4b7069d2013-09-11 12:52:43 -07002612 driver->notifyFlagsChanged(flags);
2613 }
2614
Andreas Huber9575c962013-02-05 13:59:56 -08002615 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2616 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2617 cancelPollDuration();
2618 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2619 && (flags & Source::FLAG_DYNAMIC_DURATION)
2620 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2621 schedulePollDuration();
2622 }
2623
2624 mSourceFlags = flags;
2625 break;
2626 }
2627
2628 case Source::kWhatVideoSizeChanged:
2629 {
Chong Zhangced1c2f2014-08-08 15:22:35 -07002630 sp<AMessage> format;
2631 CHECK(msg->findMessage("format", &format));
Andreas Huber9575c962013-02-05 13:59:56 -08002632
Chong Zhangced1c2f2014-08-08 15:22:35 -07002633 updateVideoSize(format);
Andreas Huber9575c962013-02-05 13:59:56 -08002634 break;
2635 }
2636
Chong Zhang2a3cc9a2014-08-21 17:48:26 -07002637 case Source::kWhatBufferingUpdate:
2638 {
2639 int32_t percentage;
2640 CHECK(msg->findInt32("percentage", &percentage));
2641
2642 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
2643 break;
2644 }
2645
Chong Zhangefbb6192015-01-30 17:13:27 -08002646 case Source::kWhatPauseOnBufferingStart:
2647 {
2648 // ignore if not playing
Chong Zhang8a048332015-05-06 15:16:28 -07002649 if (mStarted) {
Chong Zhangefbb6192015-01-30 17:13:27 -08002650 ALOGI("buffer low, pausing...");
2651
Ray Essick58e0f7a2017-11-21 10:59:38 -08002652 startRebufferingTimer();
Chong Zhang8a048332015-05-06 15:16:28 -07002653 mPausedForBuffering = true;
Chong Zhangefbb6192015-01-30 17:13:27 -08002654 onPause();
2655 }
Wei Jiabfe82072016-05-20 09:21:50 -07002656 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
Roger Jönssonb50e83e2013-01-21 16:26:41 +01002657 break;
2658 }
2659
Chong Zhangefbb6192015-01-30 17:13:27 -08002660 case Source::kWhatResumeOnBufferingEnd:
2661 {
2662 // ignore if not playing
Chong Zhang8a048332015-05-06 15:16:28 -07002663 if (mStarted) {
Chong Zhangefbb6192015-01-30 17:13:27 -08002664 ALOGI("buffer ready, resuming...");
2665
Ray Essickeda32522018-02-28 12:08:28 -08002666 updateRebufferingTimer(true /* stopping */, false /* exiting */);
Chong Zhang8a048332015-05-06 15:16:28 -07002667 mPausedForBuffering = false;
2668
2669 // do not resume yet if client didn't unpause
2670 if (!mPausedByClient) {
2671 onResume();
2672 }
Chong Zhangefbb6192015-01-30 17:13:27 -08002673 }
Wei Jia3bed45a2016-02-17 11:06:47 -08002674 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
Roger Jönssonb50e83e2013-01-21 16:26:41 +01002675 break;
2676 }
2677
Chong Zhangefbb6192015-01-30 17:13:27 -08002678 case Source::kWhatCacheStats:
2679 {
2680 int32_t kbps;
2681 CHECK(msg->findInt32("bandwidth", &kbps));
2682
2683 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
2684 break;
2685 }
2686
Chong Zhangdcb89b32013-08-06 09:44:47 -07002687 case Source::kWhatSubtitleData:
2688 {
2689 sp<ABuffer> buffer;
2690 CHECK(msg->findBuffer("buffer", &buffer));
2691
Chong Zhang404fced2014-06-11 14:45:31 -07002692 sendSubtitleData(buffer, 0 /* baseIndex */);
Chong Zhangdcb89b32013-08-06 09:44:47 -07002693 break;
2694 }
2695
Robert Shih08528432015-04-08 09:06:54 -07002696 case Source::kWhatTimedMetaData:
2697 {
2698 sp<ABuffer> buffer;
2699 if (!msg->findBuffer("buffer", &buffer)) {
2700 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2701 } else {
2702 sendTimedMetaData(buffer);
2703 }
2704 break;
2705 }
2706
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002707 case Source::kWhatTimedTextData:
2708 {
2709 int32_t generation;
2710 if (msg->findInt32("generation", &generation)
2711 && generation != mTimedTextGeneration) {
2712 break;
2713 }
2714
2715 sp<ABuffer> buffer;
2716 CHECK(msg->findBuffer("buffer", &buffer));
2717
2718 sp<NuPlayerDriver> driver = mDriver.promote();
2719 if (driver == NULL) {
2720 break;
2721 }
2722
2723 int posMs;
2724 int64_t timeUs, posUs;
2725 driver->getCurrentPosition(&posMs);
Chih-Hung Hsieh62309d52018-12-11 13:54:02 -08002726 posUs = (int64_t) posMs * 1000LL;
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002727 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2728
2729 if (posUs < timeUs) {
2730 if (!msg->findInt32("generation", &generation)) {
2731 msg->setInt32("generation", mTimedTextGeneration);
2732 }
2733 msg->post(timeUs - posUs);
2734 } else {
2735 sendTimedTextData(buffer);
2736 }
2737 break;
2738 }
2739
Andreas Huber14f76722013-01-15 09:04:18 -08002740 case Source::kWhatQueueDecoderShutdown:
2741 {
2742 int32_t audio, video;
2743 CHECK(msg->findInt32("audio", &audio));
2744 CHECK(msg->findInt32("video", &video));
2745
2746 sp<AMessage> reply;
2747 CHECK(msg->findMessage("reply", &reply));
2748
2749 queueDecoderShutdown(audio, video, reply);
2750 break;
2751 }
2752
Ronghua Wu80276872014-08-28 15:50:29 -07002753 case Source::kWhatDrmNoLicense:
2754 {
2755 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2756 break;
2757 }
2758
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002759 case Source::kWhatIMSRxNotice:
2760 {
2761 sp<AMessage> IMSRxNotice;
2762 CHECK(msg->findMessage("message", &IMSRxNotice));
2763 sendIMSRxNotice(IMSRxNotice);
2764 break;
2765 }
2766
Andreas Huber9575c962013-02-05 13:59:56 -08002767 default:
2768 TRESPASS();
2769 }
2770}
2771
Chong Zhanga7fa1d92014-06-11 14:49:23 -07002772void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2773 int32_t what;
2774 CHECK(msg->findInt32("what", &what));
2775
2776 switch (what) {
2777 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2778 {
2779 sp<ABuffer> buffer;
2780 CHECK(msg->findBuffer("buffer", &buffer));
2781
2782 size_t inbandTracks = 0;
2783 if (mSource != NULL) {
2784 inbandTracks = mSource->getTrackCount();
2785 }
2786
2787 sendSubtitleData(buffer, inbandTracks);
2788 break;
2789 }
2790
2791 case NuPlayer::CCDecoder::kWhatTrackAdded:
2792 {
2793 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2794
2795 break;
2796 }
2797
2798 default:
2799 TRESPASS();
2800 }
2801
2802
2803}
2804
Chong Zhang404fced2014-06-11 14:45:31 -07002805void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2806 int32_t trackIndex;
2807 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002808 CHECK(buffer->meta()->findInt32("track-index", &trackIndex));
Chong Zhang404fced2014-06-11 14:45:31 -07002809 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2810 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2811
2812 Parcel in;
2813 in.writeInt32(trackIndex + baseIndex);
2814 in.writeInt64(timeUs);
2815 in.writeInt64(durationUs);
2816 in.writeInt32(buffer->size());
2817 in.writeInt32(buffer->size());
2818 in.write(buffer->data(), buffer->size());
2819
2820 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2821}
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002822
Robert Shih08528432015-04-08 09:06:54 -07002823void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
2824 int64_t timeUs;
2825 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2826
2827 Parcel in;
2828 in.writeInt64(timeUs);
2829 in.writeInt32(buffer->size());
2830 in.writeInt32(buffer->size());
2831 in.write(buffer->data(), buffer->size());
2832
2833 notifyListener(MEDIA_META_DATA, 0, 0, &in);
2834}
2835
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002836void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2837 const void *data;
2838 size_t size = 0;
2839 int64_t timeUs;
Marco Nelissen55e2f4c2015-09-04 15:57:15 -07002840 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002841
2842 AString mime;
2843 CHECK(buffer->meta()->findString("mime", &mime));
2844 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2845
2846 data = buffer->data();
2847 size = buffer->size();
2848
2849 Parcel parcel;
2850 if (size > 0) {
2851 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
Marco Nelissen55e2f4c2015-09-04 15:57:15 -07002852 int32_t global = 0;
2853 if (buffer->meta()->findInt32("global", &global) && global) {
2854 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2855 } else {
2856 flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2857 }
Robert Shihd3b0bbb2014-07-23 15:00:25 -07002858 TextDescriptions::getParcelOfDescriptions(
2859 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2860 }
2861
2862 if ((parcel.dataSize() > 0)) {
2863 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2864 } else { // send an empty timed text
2865 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2866 }
2867}
Hassan Shojaniacefac142017-02-06 21:02:02 -08002868
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002869void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002870 int32_t payloadType;
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002871
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002872 CHECK(msg->findInt32("payload-type", &payloadType));
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002873
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002874 int32_t rtpSeq = 0, rtpTime = 0;
2875 int64_t ntpTime = 0, recvTimeUs = 0;
2876
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002877 Parcel in;
2878 in.writeInt32(payloadType);
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002879
2880 switch (payloadType) {
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002881 case ARTPSource::RTP_FIRST_PACKET:
2882 {
2883 CHECK(msg->findInt32("rtp-time", &rtpTime));
2884 CHECK(msg->findInt32("rtp-seq-num", &rtpSeq));
2885 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2886 in.writeInt32(rtpTime);
2887 in.writeInt32(rtpSeq);
2888 in.writeInt32(recvTimeUs >> 32);
2889 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2890 break;
2891 }
2892 case ARTPSource::RTCP_FIRST_PACKET:
2893 {
2894 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2895 in.writeInt32(recvTimeUs >> 32);
2896 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2897 break;
2898 }
2899 case ARTPSource::RTCP_SR:
2900 {
2901 CHECK(msg->findInt32("rtp-time", &rtpTime));
2902 CHECK(msg->findInt64("ntp-time", &ntpTime));
2903 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2904 in.writeInt32(rtpTime);
2905 in.writeInt32(ntpTime >> 32);
2906 in.writeInt32(ntpTime & 0xFFFFFFFF);
2907 in.writeInt32(recvTimeUs >> 32);
2908 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2909 break;
2910 }
Byeongjo Park195d6142021-11-12 19:27:09 +09002911 case ARTPSource::RTCP_RR:
2912 {
2913 int64_t recvTimeUs;
2914 int32_t senderId;
2915 int32_t ssrc;
2916 int32_t fraction;
2917 int32_t lost;
2918 int32_t lastSeq;
2919 int32_t jitter;
2920 int32_t lsr;
2921 int32_t dlsr;
2922 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2923 CHECK(msg->findInt32("rtcp-rr-ssrc", &senderId));
2924 CHECK(msg->findInt32("rtcp-rrb-ssrc", &ssrc));
2925 CHECK(msg->findInt32("rtcp-rrb-fraction", &fraction));
2926 CHECK(msg->findInt32("rtcp-rrb-lost", &lost));
2927 CHECK(msg->findInt32("rtcp-rrb-lastSeq", &lastSeq));
2928 CHECK(msg->findInt32("rtcp-rrb-jitter", &jitter));
2929 CHECK(msg->findInt32("rtcp-rrb-lsr", &lsr));
2930 CHECK(msg->findInt32("rtcp-rrb-dlsr", &dlsr));
2931 in.writeInt32(recvTimeUs >> 32);
2932 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2933 in.writeInt32(senderId);
2934 in.writeInt32(ssrc);
2935 in.writeInt32(fraction);
2936 in.writeInt32(lost);
2937 in.writeInt32(lastSeq);
2938 in.writeInt32(jitter);
2939 in.writeInt32(lsr);
2940 in.writeInt32(dlsr);
2941 break;
2942 }
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002943 case ARTPSource::RTCP_TSFB: // RTCP TSFB
2944 case ARTPSource::RTCP_PSFB: // RTCP PSFB
2945 case ARTPSource::RTP_AUTODOWN:
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002946 {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002947 int32_t feedbackType, id;
2948 CHECK(msg->findInt32("feedback-type", &feedbackType));
2949 CHECK(msg->findInt32("sender", &id));
2950 in.writeInt32(feedbackType);
2951 in.writeInt32(id);
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002952 if (payloadType == ARTPSource::RTCP_TSFB) {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002953 int32_t bitrate;
2954 CHECK(msg->findInt32("bit-rate", &bitrate));
2955 in.writeInt32(bitrate);
2956 }
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002957 break;
2958 }
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002959 case ARTPSource::RTP_QUALITY:
2960 case ARTPSource::RTP_QUALITY_EMC:
Kim Sungyeon23b23932019-07-18 17:48:32 +09002961 {
2962 int32_t feedbackType, bitrate;
2963 int32_t highestSeqNum, baseSeqNum, prevExpected;
2964 int32_t numBufRecv, prevNumBufRecv;
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002965 int32_t latestRtpTime, jbTimeMs, rtpRtcpSrTimeGapMs;
2966 int64_t recvTimeUs;
Kim Sungyeon23b23932019-07-18 17:48:32 +09002967 CHECK(msg->findInt32("feedback-type", &feedbackType));
2968 CHECK(msg->findInt32("bit-rate", &bitrate));
2969 CHECK(msg->findInt32("highest-seq-num", &highestSeqNum));
2970 CHECK(msg->findInt32("base-seq-num", &baseSeqNum));
2971 CHECK(msg->findInt32("prev-expected", &prevExpected));
2972 CHECK(msg->findInt32("num-buf-recv", &numBufRecv));
2973 CHECK(msg->findInt32("prev-num-buf-recv", &prevNumBufRecv));
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002974 CHECK(msg->findInt32("latest-rtp-time", &latestRtpTime));
2975 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2976 CHECK(msg->findInt32("rtp-jitter-time-ms", &jbTimeMs));
2977 CHECK(msg->findInt32("rtp-rtcpsr-time-gap-ms", &rtpRtcpSrTimeGapMs));
Kim Sungyeon23b23932019-07-18 17:48:32 +09002978 in.writeInt32(feedbackType);
2979 in.writeInt32(bitrate);
2980 in.writeInt32(highestSeqNum);
2981 in.writeInt32(baseSeqNum);
2982 in.writeInt32(prevExpected);
2983 in.writeInt32(numBufRecv);
2984 in.writeInt32(prevNumBufRecv);
Kim Sungyeonbf5d9322021-07-16 16:36:37 +09002985 in.writeInt32(latestRtpTime);
2986 in.writeInt32(recvTimeUs >> 32);
2987 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2988 in.writeInt32(jbTimeMs);
2989 in.writeInt32(rtpRtcpSrTimeGapMs);
Kim Sungyeon23b23932019-07-18 17:48:32 +09002990 break;
2991 }
Kim Sungyeon89d5bc62020-03-17 21:39:33 +09002992 case ARTPSource::RTP_CVO:
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002993 {
Byeongjo Parkb0225aa2018-04-20 14:00:15 +09002994 int32_t cvo;
2995 CHECK(msg->findInt32("cvo", &cvo));
2996 in.writeInt32(cvo);
Kim Sungyeond3c6b322018-03-02 14:41:19 +09002997 break;
2998 }
2999 default:
3000 break;
3001 }
3002
3003 notifyListener(MEDIA_IMS_RX_NOTICE, 0, 0, &in);
3004}
3005
Hassan Shojaniaff63de72017-04-26 15:10:42 -07003006const char *NuPlayer::getDataSourceType() {
3007 switch (mDataSourceType) {
3008 case DATA_SOURCE_TYPE_HTTP_LIVE:
3009 return "HTTPLive";
3010
Byeongjo Park5e27b1b2018-07-12 15:36:03 +09003011 case DATA_SOURCE_TYPE_RTP:
3012 return "RTP";
3013
Hassan Shojaniaff63de72017-04-26 15:10:42 -07003014 case DATA_SOURCE_TYPE_RTSP:
3015 return "RTSP";
3016
3017 case DATA_SOURCE_TYPE_GENERIC_URL:
3018 return "GenURL";
3019
3020 case DATA_SOURCE_TYPE_GENERIC_FD:
3021 return "GenFD";
3022
3023 case DATA_SOURCE_TYPE_MEDIA:
3024 return "Media";
3025
3026 case DATA_SOURCE_TYPE_STREAM:
3027 return "Stream";
3028
3029 case DATA_SOURCE_TYPE_NONE:
3030 default:
3031 return "None";
3032 }
3033 }
3034
Hassan Shojaniacefac142017-02-06 21:02:02 -08003035// Modular DRM begin
3036status_t NuPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3037{
3038 ALOGV("prepareDrm ");
3039
3040 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3041 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3042 // synchronous call so just passing the address but with local copies of "const" args
3043 uint8_t UUID[16];
3044 memcpy(UUID, uuid, sizeof(UUID));
3045 Vector<uint8_t> sessionId = drmSessionId;
3046 msg->setPointer("uuid", (void*)UUID);
3047 msg->setPointer("drmSessionId", (void*)&sessionId);
3048
3049 sp<AMessage> response;
3050 status_t status = msg->postAndAwaitResponse(&response);
3051
3052 if (status == OK && response != NULL) {
3053 CHECK(response->findInt32("status", &status));
3054 ALOGV("prepareDrm ret: %d ", status);
3055 } else {
3056 ALOGE("prepareDrm err: %d", status);
3057 }
3058
3059 return status;
3060}
3061
3062status_t NuPlayer::releaseDrm()
3063{
3064 ALOGV("releaseDrm ");
3065
3066 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3067
3068 sp<AMessage> response;
3069 status_t status = msg->postAndAwaitResponse(&response);
3070
3071 if (status == OK && response != NULL) {
3072 CHECK(response->findInt32("status", &status));
3073 ALOGV("releaseDrm ret: %d ", status);
3074 } else {
3075 ALOGE("releaseDrm err: %d", status);
3076 }
3077
3078 return status;
3079}
3080
3081status_t NuPlayer::onPrepareDrm(const sp<AMessage> &msg)
3082{
3083 // TODO change to ALOGV
3084 ALOGD("onPrepareDrm ");
3085
3086 status_t status = INVALID_OPERATION;
3087 if (mSource == NULL) {
3088 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3089 return status;
3090 }
3091
3092 uint8_t *uuid;
3093 Vector<uint8_t> *drmSessionId;
3094 CHECK(msg->findPointer("uuid", (void**)&uuid));
3095 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3096
3097 status = OK;
3098 sp<ICrypto> crypto = NULL;
3099
3100 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
3101 if (crypto == NULL) {
3102 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
3103 return status;
3104 }
3105 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
3106
3107 if (mCrypto != NULL) {
3108 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p (%d)",
3109 mCrypto.get(), mCrypto->getStrongCount());
3110 mCrypto.clear();
3111 }
3112
3113 mCrypto = crypto;
3114 mIsDrmProtected = true;
3115 // TODO change to ALOGV
3116 ALOGD("onPrepareDrm: mCrypto: %p (%d)", mCrypto.get(),
3117 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3118
3119 return status;
3120}
3121
3122status_t NuPlayer::onReleaseDrm()
3123{
3124 // TODO change to ALOGV
3125 ALOGD("onReleaseDrm ");
3126
Hassan Shojania50b20c92017-02-16 18:28:58 -08003127 if (!mIsDrmProtected) {
3128 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3129 }
3130
3131 mIsDrmProtected = false;
Hassan Shojaniacefac142017-02-06 21:02:02 -08003132
3133 status_t status;
3134 if (mCrypto != NULL) {
Hassan Shojania355e8472017-05-12 10:33:16 -07003135 // notifying the source first before removing crypto from codec
3136 if (mSource != NULL) {
3137 mSource->releaseDrm();
3138 }
3139
Hassan Shojaniacefac142017-02-06 21:02:02 -08003140 status=OK;
3141 // first making sure the codecs have released their crypto reference
3142 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3143 if (videoDecoder != NULL) {
3144 status = videoDecoder->releaseCrypto();
3145 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3146 }
3147
3148 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3149 if (audioDecoder != NULL) {
3150 status_t status_audio = audioDecoder->releaseCrypto();
3151 if (status == OK) { // otherwise, returning the first error
3152 status = status_audio;
3153 }
3154 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3155 }
3156
3157 // TODO change to ALOGV
3158 ALOGD("onReleaseDrm: mCrypto: %p (%d)", mCrypto.get(),
3159 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3160 mCrypto.clear();
3161 } else { // mCrypto == NULL
3162 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3163 status = INVALID_OPERATION;
3164 }
3165
3166 return status;
3167}
3168// Modular DRM end
Andreas Huberb5f25f02013-02-05 10:14:26 -08003169////////////////////////////////////////////////////////////////////////////////
3170
Chong Zhangced1c2f2014-08-08 15:22:35 -07003171sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
3172 sp<MetaData> meta = getFormatMeta(audio);
3173
3174 if (meta == NULL) {
3175 return NULL;
3176 }
3177
3178 sp<AMessage> msg = new AMessage;
3179
3180 if(convertMetaDataToMessage(meta, &msg) == OK) {
3181 return msg;
3182 }
3183 return NULL;
3184}
3185
Andreas Huber9575c962013-02-05 13:59:56 -08003186void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
3187 sp<AMessage> notify = dupNotify();
3188 notify->setInt32("what", kWhatFlagsChanged);
3189 notify->setInt32("flags", flags);
3190 notify->post();
3191}
3192
Chong Zhangced1c2f2014-08-08 15:22:35 -07003193void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
Andreas Huber9575c962013-02-05 13:59:56 -08003194 sp<AMessage> notify = dupNotify();
3195 notify->setInt32("what", kWhatVideoSizeChanged);
Chong Zhangced1c2f2014-08-08 15:22:35 -07003196 notify->setMessage("format", format);
Andreas Huber9575c962013-02-05 13:59:56 -08003197 notify->post();
3198}
3199
Andreas Huberec0c5972013-02-05 14:47:13 -08003200void NuPlayer::Source::notifyPrepared(status_t err) {
Hassan Shojaniacefac142017-02-06 21:02:02 -08003201 ALOGV("Source::notifyPrepared %d", err);
Andreas Huber9575c962013-02-05 13:59:56 -08003202 sp<AMessage> notify = dupNotify();
3203 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08003204 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08003205 notify->post();
3206}
3207
Hassan Shojaniacefac142017-02-06 21:02:02 -08003208void NuPlayer::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3209{
3210 ALOGV("Source::notifyDrmInfo");
3211
3212 sp<AMessage> notify = dupNotify();
3213 notify->setInt32("what", kWhatDrmInfo);
3214 notify->setBuffer("drmInfo", drmInfoBuffer);
3215
3216 notify->post();
3217}
3218
Lajos Molnarfcd3e942015-03-31 10:06:48 -07003219void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
3220 sp<AMessage> notify = dupNotify();
3221 notify->setInt32("what", kWhatInstantiateSecureDecoders);
3222 notify->setMessage("reply", reply);
3223 notify->post();
3224}
3225
Andreas Huber84333e02014-02-07 15:36:10 -08003226void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
Andreas Huberb5f25f02013-02-05 10:14:26 -08003227 TRESPASS();
3228}
3229
Andreas Huberf9334412010-12-15 15:17:42 -08003230} // namespace android