blob: d4ffdfeb4fd80f65f4378042a19847122226643b [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2 * Copyright 2017 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 "NuPlayer2"
19
20#include <inttypes.h>
21
22#include <utils/Log.h>
23
24#include "NuPlayer2.h"
25
Wei Jia2409c872018-02-02 10:34:33 -080026#include "HTTPLiveSource2.h"
Dongwon Kang946bdb32018-11-14 10:12:00 -080027#include "JMediaPlayer2Utils.h"
Wei Jia53692fa2017-12-11 10:33:46 -080028#include "NuPlayer2CCDecoder.h"
29#include "NuPlayer2Decoder.h"
30#include "NuPlayer2DecoderBase.h"
31#include "NuPlayer2DecoderPassThrough.h"
32#include "NuPlayer2Driver.h"
33#include "NuPlayer2Renderer.h"
34#include "NuPlayer2Source.h"
Wei Jia2409c872018-02-02 10:34:33 -080035#include "RTSPSource2.h"
36#include "GenericSource2.h"
Dongwon Kanga0e816a2018-09-10 19:46:49 -070037#include "TextDescriptions2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080038
39#include "ATSParser.h"
40
41#include <cutils/properties.h>
42
43#include <media/AudioParameter.h>
44#include <media/AudioResamplerPublic.h>
45#include <media/AVSyncSettings.h>
Wei Jiac2636032018-02-01 09:15:25 -080046#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080047#include <media/MediaCodecBuffer.h>
Wei Jia28288fb2017-12-15 13:45:29 -080048#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080049
50#include <media/stagefright/foundation/hexdump.h>
51#include <media/stagefright/foundation/ABuffer.h>
52#include <media/stagefright/foundation/ADebug.h>
53#include <media/stagefright/foundation/AMessage.h>
54#include <media/stagefright/foundation/avc_utils.h>
55#include <media/stagefright/MediaBuffer.h>
56#include <media/stagefright/MediaClock.h>
57#include <media/stagefright/MediaDefs.h>
58#include <media/stagefright/MediaErrors.h>
59#include <media/stagefright/MetaData.h>
60
Wei Jia53692fa2017-12-11 10:33:46 -080061#include "ESDS.h"
62#include <media/stagefright/Utils.h>
63
Wei Jia28288fb2017-12-15 13:45:29 -080064#include <system/window.h>
65
Wei Jia53692fa2017-12-11 10:33:46 -080066namespace android {
67
Wei Jia33abcc72018-01-30 09:47:38 -080068static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
Wei Jia53692fa2017-12-11 10:33:46 -080069 const sp<MetaData>& meta) {
70 int32_t sampleRate = 0;
71 int32_t bitRate = 0;
72 int32_t channelMask = 0;
73 int32_t delaySamples = 0;
74 int32_t paddingSamples = 0;
75
76 AudioParameter param = AudioParameter();
77
78 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
79 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
80 }
81 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
82 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
83 }
84 if (meta->findInt32(kKeyBitRate, &bitRate)) {
85 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
86 }
87 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
88 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
89 }
90 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
91 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
92 }
93
94 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
95 "delaySample %d, paddingSample %d", bitRate, sampleRate,
96 channelMask, delaySamples, paddingSamples);
97
98 sink->setParameters(param.toString());
99 return OK;
100}
101
102
103struct NuPlayer2::Action : public RefBase {
104 Action() {}
105
106 virtual void execute(NuPlayer2 *player) = 0;
107
108private:
109 DISALLOW_EVIL_CONSTRUCTORS(Action);
110};
111
112struct NuPlayer2::SeekAction : public Action {
113 explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
114 : mSeekTimeUs(seekTimeUs),
115 mMode(mode) {
116 }
117
118 virtual void execute(NuPlayer2 *player) {
119 player->performSeek(mSeekTimeUs, mMode);
120 }
121
122private:
123 int64_t mSeekTimeUs;
124 MediaPlayer2SeekMode mMode;
125
126 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
127};
128
129struct NuPlayer2::ResumeDecoderAction : public Action {
130 explicit ResumeDecoderAction(bool needNotify)
131 : mNeedNotify(needNotify) {
132 }
133
134 virtual void execute(NuPlayer2 *player) {
135 player->performResumeDecoders(mNeedNotify);
136 }
137
138private:
139 bool mNeedNotify;
140
141 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
142};
143
144struct NuPlayer2::SetSurfaceAction : public Action {
Wei Jia28288fb2017-12-15 13:45:29 -0800145 explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
146 : mNativeWindow(nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800147 }
148
149 virtual void execute(NuPlayer2 *player) {
Wei Jia28288fb2017-12-15 13:45:29 -0800150 player->performSetSurface(mNativeWindow);
Wei Jia53692fa2017-12-11 10:33:46 -0800151 }
152
153private:
Wei Jia28288fb2017-12-15 13:45:29 -0800154 sp<ANativeWindowWrapper> mNativeWindow;
Wei Jia53692fa2017-12-11 10:33:46 -0800155
156 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
157};
158
159struct NuPlayer2::FlushDecoderAction : public Action {
160 FlushDecoderAction(FlushCommand audio, FlushCommand video)
161 : mAudio(audio),
162 mVideo(video) {
163 }
164
165 virtual void execute(NuPlayer2 *player) {
166 player->performDecoderFlush(mAudio, mVideo);
167 }
168
169private:
170 FlushCommand mAudio;
171 FlushCommand mVideo;
172
173 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
174};
175
176struct NuPlayer2::PostMessageAction : public Action {
177 explicit PostMessageAction(const sp<AMessage> &msg)
178 : mMessage(msg) {
179 }
180
181 virtual void execute(NuPlayer2 *) {
182 mMessage->post();
183 }
184
185private:
186 sp<AMessage> mMessage;
187
188 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
189};
190
191// Use this if there's no state necessary to save in order to execute
192// the action.
193struct NuPlayer2::SimpleAction : public Action {
194 typedef void (NuPlayer2::*ActionFunc)();
195
196 explicit SimpleAction(ActionFunc func)
197 : mFunc(func) {
198 }
199
200 virtual void execute(NuPlayer2 *player) {
201 (player->*mFunc)();
202 }
203
204private:
205 ActionFunc mFunc;
206
207 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
208};
209
210////////////////////////////////////////////////////////////////////////////////
211
Wei Jia003fdb52018-02-06 14:44:32 -0800212NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
213 : mPID(pid),
214 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800215 mMediaClock(mediaClock),
Wei Jia53692fa2017-12-11 10:33:46 -0800216 mOffloadAudio(false),
217 mAudioDecoderGeneration(0),
218 mVideoDecoderGeneration(0),
219 mRendererGeneration(0),
Wei Jiad1864f92018-10-19 12:34:56 -0700220 mEOSMonitorGeneration(0),
Wei Jia53692fa2017-12-11 10:33:46 -0800221 mLastStartedPlayingTimeNs(0),
222 mPreviousSeekTimeUs(0),
223 mAudioEOS(false),
224 mVideoEOS(false),
225 mScanSourcesPending(false),
226 mScanSourcesGeneration(0),
227 mPollDurationGeneration(0),
228 mTimedTextGeneration(0),
229 mFlushingAudio(NONE),
230 mFlushingVideo(NONE),
231 mResumePending(false),
232 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
233 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
234 mVideoFpsHint(-1.f),
235 mStarted(false),
236 mPrepared(false),
237 mResetting(false),
238 mSourceStarted(false),
239 mAudioDecoderError(false),
240 mVideoDecoderError(false),
241 mPaused(false),
242 mPausedByClient(true),
243 mPausedForBuffering(false),
Wei Jiaf01e3122018-10-18 11:49:44 -0700244 mIsDrmProtected(false) {
Wei Jia53692fa2017-12-11 10:33:46 -0800245 CHECK(mediaClock != NULL);
246 clearFlushComplete();
247}
248
249NuPlayer2::~NuPlayer2() {
250}
251
Wei Jia53692fa2017-12-11 10:33:46 -0800252void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
253 mDriver = driver;
254}
255
Wei Jia53692fa2017-12-11 10:33:46 -0800256static bool IsHTTPLiveURL(const char *url) {
257 if (!strncasecmp("http://", url, 7)
258 || !strncasecmp("https://", url, 8)
259 || !strncasecmp("file://", url, 7)) {
260 size_t len = strlen(url);
261 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
262 return true;
263 }
264
265 if (strstr(url,"m3u8")) {
266 return true;
267 }
268 }
269
270 return false;
271}
272
Wei Jia72bf2a02018-02-06 15:29:23 -0800273status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
274 sp<Source> *source,
275 DATA_SOURCE_TYPE *dataSourceType) {
276 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800277 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800278 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800279
Wei Jiac2636032018-02-01 09:15:25 -0800280 switch (dsd->mType) {
281 case DataSourceDesc::TYPE_URL:
282 {
283 const char *url = dsd->mUrl.c_str();
284 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800285
Wei Jiac2636032018-02-01 09:15:25 -0800286 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
287 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800288
Wei Jiac2636032018-02-01 09:15:25 -0800289 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800290 *source = new HTTPLiveSource2(notify, httpService, url, headers);
291 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
292 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800293 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800294 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800295 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800296 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
297 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800298 } else if ((!strncasecmp(url, "http://", 7)
299 || !strncasecmp(url, "https://", 8))
300 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
301 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800302 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800303 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800304 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
305 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800306 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800307 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800308
Wei Jia2409c872018-02-02 10:34:33 -0800309 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800310 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800311
Robert Shih49fb89d2018-01-31 17:53:19 -0800312 err = genericSource->setDataSource(url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800313
314 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800315 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800316 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800317 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800318 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800319 }
320
321 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800322 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800323 }
324 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800325 }
326
Wei Jiac2636032018-02-01 09:15:25 -0800327 case DataSourceDesc::TYPE_FD:
328 {
Wei Jia2409c872018-02-02 10:34:33 -0800329 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800330 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800331
Wei Jia72bf2a02018-02-06 15:29:23 -0800332 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
333 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
334 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800335
Wei Jia72bf2a02018-02-06 15:29:23 -0800336 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800337
Wei Jiac2636032018-02-01 09:15:25 -0800338 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800339 ALOGE("Failed to create NuPlayer2Source!");
340 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800341 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800342 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800343 }
Wei Jia53692fa2017-12-11 10:33:46 -0800344
Wei Jia72bf2a02018-02-06 15:29:23 -0800345 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800346 break;
347 }
Wei Jia53692fa2017-12-11 10:33:46 -0800348
Wei Jiac2636032018-02-01 09:15:25 -0800349 case DataSourceDesc::TYPE_CALLBACK:
350 {
Wei Jia2409c872018-02-02 10:34:33 -0800351 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800352 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800353 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800354
Wei Jiac2636032018-02-01 09:15:25 -0800355 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800356 ALOGE("Failed to create NuPlayer2Source!");
357 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800358 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800359 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800360 }
361
Wei Jia72bf2a02018-02-06 15:29:23 -0800362 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800363 break;
364 }
365
366 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800367 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800368 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800369 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800370 ALOGE("invalid data source type!");
371 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800372 }
373
Wei Jia72bf2a02018-02-06 15:29:23 -0800374 return err;
375}
376
377void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
378 DATA_SOURCE_TYPE dataSourceType;
379 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800380 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800381
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800382 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
383 // and expects notifySetDataSourceCompleted regardless of success or failure.
384 // This will be changed since setDataSource should be asynchronous at JAVA level.
385 // When it succeeds, app will get onInfo notification. Otherwise, onError
386 // will be called.
387 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800388 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800389 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800390 return;
391 }
392
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800393 // Now, source != NULL.
394 */
395
Wei Jiaf01e3122018-10-18 11:49:44 -0700396 mCurrentSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800397
398 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800399 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800400 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700401 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
402 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia72bf2a02018-02-06 15:29:23 -0800403 msg->post();
404}
405
406void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
407 DATA_SOURCE_TYPE dataSourceType;
408 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800409 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800410
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800411 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800412 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800413 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800414 return;
415 }
416
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800417 // Now, source != NULL.
418 */
419
Wei Jiaf01e3122018-10-18 11:49:44 -0700420 mNextSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800421
422 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
423 msg->setObject("source", source);
424 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700425 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
426 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia53692fa2017-12-11 10:33:46 -0800427 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800428}
429
Wei Jia57aeffd2018-02-15 16:01:14 -0800430void NuPlayer2::playNextDataSource(int64_t srcId) {
431 disconnectSource();
432
433 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
434 msg->setInt64("srcId", srcId);
435 msg->post();
436}
437
Wei Jia53692fa2017-12-11 10:33:46 -0800438status_t NuPlayer2::getBufferingSettings(
439 BufferingSettings *buffering /* nonnull */) {
440 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
441 sp<AMessage> response;
442 status_t err = msg->postAndAwaitResponse(&response);
443 if (err == OK && response != NULL) {
444 CHECK(response->findInt32("err", &err));
445 if (err == OK) {
446 readFromAMessage(response, buffering);
447 }
448 }
449 return err;
450}
451
452status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
453 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
454 writeToAMessage(msg, buffering);
455 sp<AMessage> response;
456 status_t err = msg->postAndAwaitResponse(&response);
457 if (err == OK && response != NULL) {
458 CHECK(response->findInt32("err", &err));
459 }
460 return err;
461}
462
463void NuPlayer2::prepareAsync() {
464 ALOGV("prepareAsync");
465
466 (new AMessage(kWhatPrepare, this))->post();
467}
468
Wei Jia28288fb2017-12-15 13:45:29 -0800469void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800470 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
471
Wei Jia28288fb2017-12-15 13:45:29 -0800472 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800473 msg->setObject("surface", NULL);
474 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800475 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800476 }
477
478 msg->post();
479}
480
Wei Jia33abcc72018-01-30 09:47:38 -0800481void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800482 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
483 msg->setObject("sink", sink);
484 msg->post();
485}
486
487void NuPlayer2::start() {
488 (new AMessage(kWhatStart, this))->post();
489}
490
491status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
492 // do some cursory validation of the settings here. audio modes are
493 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700494 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800495 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
496 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
497 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
498 return BAD_VALUE;
499 }
500 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
501 writeToAMessage(msg, rate);
502 sp<AMessage> response;
503 status_t err = msg->postAndAwaitResponse(&response);
504 if (err == OK && response != NULL) {
505 CHECK(response->findInt32("err", &err));
506 }
507 return err;
508}
509
510status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
511 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
512 sp<AMessage> response;
513 status_t err = msg->postAndAwaitResponse(&response);
514 if (err == OK && response != NULL) {
515 CHECK(response->findInt32("err", &err));
516 if (err == OK) {
517 readFromAMessage(response, rate);
518 }
519 }
520 return err;
521}
522
523status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
524 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
525 writeToAMessage(msg, sync, videoFpsHint);
526 sp<AMessage> response;
527 status_t err = msg->postAndAwaitResponse(&response);
528 if (err == OK && response != NULL) {
529 CHECK(response->findInt32("err", &err));
530 }
531 return err;
532}
533
534status_t NuPlayer2::getSyncSettings(
535 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
536 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
537 sp<AMessage> response;
538 status_t err = msg->postAndAwaitResponse(&response);
539 if (err == OK && response != NULL) {
540 CHECK(response->findInt32("err", &err));
541 if (err == OK) {
542 readFromAMessage(response, sync, videoFps);
543 }
544 }
545 return err;
546}
547
548void NuPlayer2::pause() {
549 (new AMessage(kWhatPause, this))->post();
550}
551
552void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800553 disconnectSource();
554 (new AMessage(kWhatReset, this))->post();
555}
556
557void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800558 sp<Source> source;
559 {
560 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700561 source = mCurrentSourceInfo.mSource;
Wei Jia53692fa2017-12-11 10:33:46 -0800562 }
563
564 if (source != NULL) {
565 // During a reset, the data source might be unresponsive already, we need to
566 // disconnect explicitly so that reads exit promptly.
567 // We can't queue the disconnect request to the looper, as it might be
568 // queued behind a stuck read and never gets processed.
569 // Doing a disconnect outside the looper to allows the pending reads to exit
570 // (either successfully or with error).
571 source->disconnect();
572 }
573
Wei Jia53692fa2017-12-11 10:33:46 -0800574}
575
576status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
577 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
578 notify->setInt64("timerUs", mediaTimeUs);
579 mMediaClock->addTimer(notify, mediaTimeUs);
580 return OK;
581}
582
583void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
584 sp<AMessage> msg = new AMessage(kWhatSeek, this);
585 msg->setInt64("seekTimeUs", seekTimeUs);
586 msg->setInt32("mode", mode);
587 msg->setInt32("needNotify", needNotify);
588 msg->post();
589}
590
Wei Jiad1864f92018-10-19 12:34:56 -0700591void NuPlayer2::rewind() {
592 sp<AMessage> msg = new AMessage(kWhatRewind, this);
593 msg->post();
594}
595
Wei Jia53692fa2017-12-11 10:33:46 -0800596void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700597 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800598 if (format == NULL) {
599 ALOGE("NULL format");
600 return;
601 }
602 int32_t trackType;
603 if (!format->findInt32("type", &trackType)) {
604 ALOGE("no track type");
605 return;
606 }
607
608 AString mime;
609 if (!format->findString("mime", &mime)) {
610 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
611 // If we can't find the mimetype here it means that we wouldn't be needing
612 // the mimetype on the Java end. We still write a placeholder mime to keep the
613 // (de)serialization logic simple.
614 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
615 mime = "audio/";
616 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
617 mime = "video/";
618 } else {
619 ALOGE("unknown track type: %d", trackType);
620 return;
621 }
622 }
623
624 AString lang;
625 if (!format->findString("language", &lang)) {
626 ALOGE("no language");
627 return;
628 }
629
Dongwon Kang9f631982018-07-10 12:34:41 -0700630 reply->add_values()->set_int32_value(trackType);
631 reply->add_values()->set_string_value(mime.c_str());
632 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800633
634 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
635 int32_t isAuto, isDefault, isForced;
636 CHECK(format->findInt32("auto", &isAuto));
637 CHECK(format->findInt32("default", &isDefault));
638 CHECK(format->findInt32("forced", &isForced));
639
Dongwon Kang9f631982018-07-10 12:34:41 -0700640 reply->add_values()->set_int32_value(isAuto);
641 reply->add_values()->set_int32_value(isDefault);
642 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800643 }
644}
645
646void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
Dichen Zhangf8726912018-10-17 13:31:26 -0700647
Wei Jia53692fa2017-12-11 10:33:46 -0800648 switch (msg->what()) {
649 case kWhatSetDataSource:
650 {
651 ALOGV("kWhatSetDataSource");
652
Wei Jiaf01e3122018-10-18 11:49:44 -0700653 CHECK(mCurrentSourceInfo.mSource == NULL);
Wei Jia53692fa2017-12-11 10:33:46 -0800654
655 status_t err = OK;
656 sp<RefBase> obj;
657 CHECK(msg->findObject("source", &obj));
658 if (obj != NULL) {
659 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700660 CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
661 CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
662 CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
663 mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800664 } else {
665 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800666 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800667 }
668
669 CHECK(mDriver != NULL);
670 sp<NuPlayer2Driver> driver = mDriver.promote();
671 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700672 driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800673 }
674 break;
675 }
676
Wei Jia72bf2a02018-02-06 15:29:23 -0800677 case kWhatPrepareNextDataSource:
678 {
679 ALOGV("kWhatPrepareNextDataSource");
680
681 status_t err = OK;
682 sp<RefBase> obj;
683 CHECK(msg->findObject("source", &obj));
684 if (obj != NULL) {
685 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700686 CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
687 CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
688 CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
689 mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
690 mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
Wei Jia72bf2a02018-02-06 15:29:23 -0800691 } else {
692 err = UNKNOWN_ERROR;
693 }
694
695 break;
696 }
697
Wei Jia57aeffd2018-02-15 16:01:14 -0800698 case kWhatPlayNextDataSource:
699 {
700 ALOGV("kWhatPlayNextDataSource");
701 int64_t srcId;
702 CHECK(msg->findInt64("srcId", &srcId));
Wei Jiaf01e3122018-10-18 11:49:44 -0700703 if (srcId != mNextSourceInfo.mSrcId) {
Wei Jia57aeffd2018-02-15 16:01:14 -0800704 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
705 return;
706 }
707
708 mResetting = true;
709 stopPlaybackTimer("kWhatPlayNextDataSource");
710 stopRebufferingTimer(true);
711
712 mDeferredActions.push_back(
713 new FlushDecoderAction(
714 FLUSH_CMD_SHUTDOWN /* audio */,
715 FLUSH_CMD_SHUTDOWN /* video */));
716
717 mDeferredActions.push_back(
718 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
719
720 processDeferredActions();
721 break;
722 }
723
Wei Jiad1864f92018-10-19 12:34:56 -0700724 case kWhatEOSMonitor:
725 {
726 int32_t generation;
727 CHECK(msg->findInt32("generation", &generation));
728 int32_t reason;
729 CHECK(msg->findInt32("reason", &reason));
730
731 if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
732 break; // stale or reset
733 }
734
735 ALOGV("kWhatEOSMonitor");
736 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
737 break;
738 }
739
Wei Jia53692fa2017-12-11 10:33:46 -0800740 case kWhatGetBufferingSettings:
741 {
742 sp<AReplyToken> replyID;
743 CHECK(msg->senderAwaitsResponse(&replyID));
744
745 ALOGV("kWhatGetBufferingSettings");
746 BufferingSettings buffering;
747 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700748 if (mCurrentSourceInfo.mSource != NULL) {
749 err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800750 } else {
751 err = INVALID_OPERATION;
752 }
753 sp<AMessage> response = new AMessage;
754 if (err == OK) {
755 writeToAMessage(response, buffering);
756 }
757 response->setInt32("err", err);
758 response->postReply(replyID);
759 break;
760 }
761
762 case kWhatSetBufferingSettings:
763 {
764 sp<AReplyToken> replyID;
765 CHECK(msg->senderAwaitsResponse(&replyID));
766
767 ALOGV("kWhatSetBufferingSettings");
768 BufferingSettings buffering;
769 readFromAMessage(msg, &buffering);
770 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700771 if (mCurrentSourceInfo.mSource != NULL) {
772 err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800773 } else {
774 err = INVALID_OPERATION;
775 }
776 sp<AMessage> response = new AMessage;
777 response->setInt32("err", err);
778 response->postReply(replyID);
779 break;
780 }
781
782 case kWhatPrepare:
783 {
784 ALOGV("onMessageReceived kWhatPrepare");
785
Wei Jiaf01e3122018-10-18 11:49:44 -0700786 mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800787 break;
788 }
789
790 case kWhatGetTrackInfo:
791 {
792 sp<AReplyToken> replyID;
793 CHECK(msg->senderAwaitsResponse(&replyID));
794
Dongwon Kang9f631982018-07-10 12:34:41 -0700795 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800796 CHECK(msg->findPointer("reply", (void**)&reply));
797
798 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700799 if (mCurrentSourceInfo.mSource != NULL) {
800 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800801 }
802
803 size_t ccTracks = 0;
804 if (mCCDecoder != NULL) {
805 ccTracks = mCCDecoder->getTrackCount();
806 }
807
808 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700809 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800810
811 // write inband tracks
812 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700813 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800814 }
815
816 // write CC track
817 for (size_t i = 0; i < ccTracks; ++i) {
818 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
819 }
820
821 sp<AMessage> response = new AMessage;
822 response->postReply(replyID);
823 break;
824 }
825
826 case kWhatGetSelectedTrack:
827 {
Wei Jia039224f2018-11-29 17:25:17 -0800828 int32_t type32;
829 CHECK(msg->findInt32("type", (int32_t*)&type32));
830 media_track_type type = (media_track_type)type32;
831
832 size_t inbandTracks = 0;
Wei Jia53692fa2017-12-11 10:33:46 -0800833 status_t err = INVALID_OPERATION;
Wei Jia039224f2018-11-29 17:25:17 -0800834 ssize_t selectedTrack = -1;
Wei Jiaf01e3122018-10-18 11:49:44 -0700835 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800836 err = OK;
Wei Jia039224f2018-11-29 17:25:17 -0800837 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
838 selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800839 }
840
Wei Jia039224f2018-11-29 17:25:17 -0800841 if (selectedTrack == -1 && mCCDecoder != NULL) {
842 err = OK;
843 selectedTrack = mCCDecoder->getSelectedTrack(type);
844 if (selectedTrack != -1) {
845 selectedTrack += inbandTracks;
846 }
847 }
848
849 PlayerMessage* reply;
850 CHECK(msg->findPointer("reply", (void**)&reply));
851 reply->add_values()->set_int32_value(selectedTrack);
852
Wei Jia53692fa2017-12-11 10:33:46 -0800853 sp<AMessage> response = new AMessage;
854 response->setInt32("err", err);
855
856 sp<AReplyToken> replyID;
857 CHECK(msg->senderAwaitsResponse(&replyID));
858 response->postReply(replyID);
859 break;
860 }
861
862 case kWhatSelectTrack:
863 {
864 sp<AReplyToken> replyID;
865 CHECK(msg->senderAwaitsResponse(&replyID));
866
867 size_t trackIndex;
868 int32_t select;
869 int64_t timeUs;
870 CHECK(msg->findSize("trackIndex", &trackIndex));
871 CHECK(msg->findInt32("select", &select));
872 CHECK(msg->findInt64("timeUs", &timeUs));
873
874 status_t err = INVALID_OPERATION;
875
876 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700877 if (mCurrentSourceInfo.mSource != NULL) {
878 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800879 }
880 size_t ccTracks = 0;
881 if (mCCDecoder != NULL) {
882 ccTracks = mCCDecoder->getTrackCount();
883 }
884
885 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700886 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800887
888 if (!select && err == OK) {
889 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700890 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800891 if (info != NULL
892 && info->findInt32("type", &type)
893 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
894 ++mTimedTextGeneration;
895 }
896 }
897 } else {
898 trackIndex -= inbandTracks;
899
900 if (trackIndex < ccTracks) {
901 err = mCCDecoder->selectTrack(trackIndex, select);
902 }
903 }
904
905 sp<AMessage> response = new AMessage;
906 response->setInt32("err", err);
907
908 response->postReply(replyID);
909 break;
910 }
911
912 case kWhatPollDuration:
913 {
914 int32_t generation;
915 CHECK(msg->findInt32("generation", &generation));
916
917 if (generation != mPollDurationGeneration) {
918 // stale
919 break;
920 }
921
922 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700923 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800924 sp<NuPlayer2Driver> driver = mDriver.promote();
925 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700926 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800927 }
928 }
929
930 msg->post(1000000ll); // poll again in a second.
931 break;
932 }
933
934 case kWhatSetVideoSurface:
935 {
936
937 sp<RefBase> obj;
938 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800939 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800940
941 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800942 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700943 (mCurrentSourceInfo.mSource != NULL && mStarted
944 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800945 && mVideoDecoder != NULL) ? "have" : "no");
946
Wei Jiaf01e3122018-10-18 11:49:44 -0700947 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
948 // because NuPlayer2 might be in preparing state and it could take long time.
949 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
950 if (mCurrentSourceInfo.mSource == NULL || !mStarted
951 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800952 // NOTE: mVideoDecoder's mNativeWindow is always non-null
953 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
954 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800955 break;
956 }
957
958 mDeferredActions.push_back(
959 new FlushDecoderAction(
960 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
961 FLUSH_CMD_SHUTDOWN /* video */));
962
Wei Jia28288fb2017-12-15 13:45:29 -0800963 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800964
965 if (obj != NULL) {
966 if (mStarted) {
967 // Issue a seek to refresh the video screen only if started otherwise
968 // the extractor may not yet be started and will assert.
969 // If the video decoder is not set (perhaps audio only in this case)
970 // do not perform a seek as it is not needed.
971 int64_t currentPositionUs = 0;
972 if (getCurrentPosition(&currentPositionUs) == OK) {
973 mDeferredActions.push_back(
974 new SeekAction(currentPositionUs,
975 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
976 }
977 }
978
979 // If there is a new surface texture, instantiate decoders
980 // again if possible.
981 mDeferredActions.push_back(
982 new SimpleAction(&NuPlayer2::performScanSources));
983
984 // After a flush without shutdown, decoder is paused.
985 // Don't resume it until source seek is done, otherwise it could
986 // start pulling stale data too soon.
987 mDeferredActions.push_back(
988 new ResumeDecoderAction(false /* needNotify */));
989 }
990
991 processDeferredActions();
992 break;
993 }
994
995 case kWhatSetAudioSink:
996 {
997 ALOGV("kWhatSetAudioSink");
998
999 sp<RefBase> obj;
1000 CHECK(msg->findObject("sink", &obj));
1001
Wei Jia33abcc72018-01-30 09:47:38 -08001002 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001003 break;
1004 }
1005
1006 case kWhatStart:
1007 {
1008 ALOGV("kWhatStart");
1009 if (mStarted) {
1010 // do not resume yet if the source is still buffering
1011 if (!mPausedForBuffering) {
1012 onResume();
1013 }
1014 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001015 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001016 }
1017 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001018 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001019 break;
1020 }
1021
1022 case kWhatConfigPlayback:
1023 {
1024 sp<AReplyToken> replyID;
1025 CHECK(msg->senderAwaitsResponse(&replyID));
1026 AudioPlaybackRate rate /* sanitized */;
1027 readFromAMessage(msg, &rate);
1028 status_t err = OK;
1029 if (mRenderer != NULL) {
1030 // AudioSink allows only 1.f and 0.f for offload mode.
1031 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001032 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001033 int64_t currentPositionUs;
1034 if (getCurrentPosition(&currentPositionUs) != OK) {
1035 currentPositionUs = mPreviousSeekTimeUs;
1036 }
1037
1038 // Set mPlaybackSettings so that the new audio decoder can
1039 // be created correctly.
1040 mPlaybackSettings = rate;
1041 if (!mPaused) {
1042 mRenderer->pause();
1043 }
1044 restartAudio(
1045 currentPositionUs, true /* forceNonOffload */,
1046 true /* needsToCreateAudioDecoder */);
1047 if (!mPaused) {
1048 mRenderer->resume();
1049 }
1050 }
1051
1052 err = mRenderer->setPlaybackSettings(rate);
1053 }
1054 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001055 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001056
Wei Jia700a7c22018-09-14 18:04:35 -07001057 if (mVideoDecoder != NULL) {
1058 sp<AMessage> params = new AMessage();
1059 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1060 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001061 }
1062 }
1063
Wei Jia53692fa2017-12-11 10:33:46 -08001064 sp<AMessage> response = new AMessage;
1065 response->setInt32("err", err);
1066 response->postReply(replyID);
1067 break;
1068 }
1069
1070 case kWhatGetPlaybackSettings:
1071 {
1072 sp<AReplyToken> replyID;
1073 CHECK(msg->senderAwaitsResponse(&replyID));
1074 AudioPlaybackRate rate = mPlaybackSettings;
1075 status_t err = OK;
1076 if (mRenderer != NULL) {
1077 err = mRenderer->getPlaybackSettings(&rate);
1078 }
1079 if (err == OK) {
1080 // get playback settings used by renderer, as it may be
1081 // slightly off due to audiosink not taking small changes.
1082 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001083 }
1084 sp<AMessage> response = new AMessage;
1085 if (err == OK) {
1086 writeToAMessage(response, rate);
1087 }
1088 response->setInt32("err", err);
1089 response->postReply(replyID);
1090 break;
1091 }
1092
1093 case kWhatConfigSync:
1094 {
1095 sp<AReplyToken> replyID;
1096 CHECK(msg->senderAwaitsResponse(&replyID));
1097
1098 ALOGV("kWhatConfigSync");
1099 AVSyncSettings sync;
1100 float videoFpsHint;
1101 readFromAMessage(msg, &sync, &videoFpsHint);
1102 status_t err = OK;
1103 if (mRenderer != NULL) {
1104 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1105 }
1106 if (err == OK) {
1107 mSyncSettings = sync;
1108 mVideoFpsHint = videoFpsHint;
1109 }
1110 sp<AMessage> response = new AMessage;
1111 response->setInt32("err", err);
1112 response->postReply(replyID);
1113 break;
1114 }
1115
1116 case kWhatGetSyncSettings:
1117 {
1118 sp<AReplyToken> replyID;
1119 CHECK(msg->senderAwaitsResponse(&replyID));
1120 AVSyncSettings sync = mSyncSettings;
1121 float videoFps = mVideoFpsHint;
1122 status_t err = OK;
1123 if (mRenderer != NULL) {
1124 err = mRenderer->getSyncSettings(&sync, &videoFps);
1125 if (err == OK) {
1126 mSyncSettings = sync;
1127 mVideoFpsHint = videoFps;
1128 }
1129 }
1130 sp<AMessage> response = new AMessage;
1131 if (err == OK) {
1132 writeToAMessage(response, sync, videoFps);
1133 }
1134 response->setInt32("err", err);
1135 response->postReply(replyID);
1136 break;
1137 }
1138
1139 case kWhatScanSources:
1140 {
1141 int32_t generation;
1142 CHECK(msg->findInt32("generation", &generation));
1143 if (generation != mScanSourcesGeneration) {
1144 // Drop obsolete msg.
1145 break;
1146 }
1147
1148 mScanSourcesPending = false;
1149
1150 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1151 mAudioDecoder != NULL, mVideoDecoder != NULL);
1152
1153 bool mHadAnySourcesBefore =
1154 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1155 bool rescan = false;
1156
1157 // initialize video before audio because successful initialization of
1158 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001159 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001160 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1161 rescan = true;
1162 }
1163 }
1164
1165 // Don't try to re-open audio sink if there's an existing decoder.
1166 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1167 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1168 rescan = true;
1169 }
1170 }
1171
1172 if (!mHadAnySourcesBefore
1173 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1174 // This is the first time we've found anything playable.
1175
Wei Jiaf01e3122018-10-18 11:49:44 -07001176 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001177 schedulePollDuration();
1178 }
1179 }
1180
1181 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001182 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001183 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1184 // We're not currently decoding anything (no audio or
1185 // video tracks found) and we just ran out of input data.
1186
1187 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001188 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001189 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001190 notifyListener(
1191 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001192 }
1193 }
1194 break;
1195 }
1196
1197 if (rescan) {
1198 msg->post(100000ll);
1199 mScanSourcesPending = true;
1200 }
1201 break;
1202 }
1203
1204 case kWhatVideoNotify:
1205 case kWhatAudioNotify:
1206 {
1207 bool audio = msg->what() == kWhatAudioNotify;
1208
1209 int32_t currentDecoderGeneration =
1210 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1211 int32_t requesterGeneration = currentDecoderGeneration - 1;
1212 CHECK(msg->findInt32("generation", &requesterGeneration));
1213
1214 if (requesterGeneration != currentDecoderGeneration) {
1215 ALOGV("got message from old %s decoder, generation(%d:%d)",
1216 audio ? "audio" : "video", requesterGeneration,
1217 currentDecoderGeneration);
1218 sp<AMessage> reply;
1219 if (!(msg->findMessage("reply", &reply))) {
1220 return;
1221 }
1222
1223 reply->setInt32("err", INFO_DISCONTINUITY);
1224 reply->post();
1225 return;
1226 }
1227
1228 int32_t what;
1229 CHECK(msg->findInt32("what", &what));
1230
1231 if (what == DecoderBase::kWhatInputDiscontinuity) {
1232 int32_t formatChange;
1233 CHECK(msg->findInt32("formatChange", &formatChange));
1234
1235 ALOGV("%s discontinuity: formatChange %d",
1236 audio ? "audio" : "video", formatChange);
1237
1238 if (formatChange) {
1239 mDeferredActions.push_back(
1240 new FlushDecoderAction(
1241 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1242 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1243 }
1244
1245 mDeferredActions.push_back(
1246 new SimpleAction(
1247 &NuPlayer2::performScanSources));
1248
1249 processDeferredActions();
1250 } else if (what == DecoderBase::kWhatEOS) {
1251 int32_t err;
1252 CHECK(msg->findInt32("err", &err));
1253
1254 if (err == ERROR_END_OF_STREAM) {
1255 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1256 } else {
1257 ALOGV("got %s decoder EOS w/ error %d",
1258 audio ? "audio" : "video",
1259 err);
1260 }
1261
1262 mRenderer->queueEOS(audio, err);
1263 } else if (what == DecoderBase::kWhatFlushCompleted) {
1264 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1265
1266 handleFlushComplete(audio, true /* isDecoder */);
1267 finishFlushIfPossible();
1268 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1269 sp<AMessage> format;
1270 CHECK(msg->findMessage("format", &format));
1271
1272 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001273 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001274
1275 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001276 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001277 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1278 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1279 if (audio) {
1280 mAudioDecoder.clear();
1281 mAudioDecoderError = false;
1282 ++mAudioDecoderGeneration;
1283
1284 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1285 mFlushingAudio = SHUT_DOWN;
1286 } else {
1287 mVideoDecoder.clear();
1288 mVideoDecoderError = false;
1289 ++mVideoDecoderGeneration;
1290
1291 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1292 mFlushingVideo = SHUT_DOWN;
1293 }
1294
1295 finishFlushIfPossible();
1296 } else if (what == DecoderBase::kWhatResumeCompleted) {
1297 finishResume();
1298 } else if (what == DecoderBase::kWhatError) {
1299 status_t err;
1300 if (!msg->findInt32("err", &err) || err == OK) {
1301 err = UNKNOWN_ERROR;
1302 }
1303
1304 // Decoder errors can be due to Source (e.g. from streaming),
1305 // or from decoding corrupted bitstreams, or from other decoder
1306 // MediaCodec operations (e.g. from an ongoing reset or seek).
1307 // They may also be due to openAudioSink failure at
1308 // decoder start or after a format change.
1309 //
1310 // We try to gracefully shut down the affected decoder if possible,
1311 // rather than trying to force the shutdown with something
1312 // similar to performReset(). This method can lead to a hang
1313 // if MediaCodec functions block after an error, but they should
1314 // typically return INVALID_OPERATION instead of blocking.
1315
1316 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1317 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1318 err, audio ? "audio" : "video", *flushing);
1319
1320 switch (*flushing) {
1321 case NONE:
1322 mDeferredActions.push_back(
1323 new FlushDecoderAction(
1324 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1325 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1326 processDeferredActions();
1327 break;
1328 case FLUSHING_DECODER:
1329 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1330 break; // Wait for flush to complete.
1331 case FLUSHING_DECODER_SHUTDOWN:
1332 break; // Wait for flush to complete.
1333 case SHUTTING_DOWN_DECODER:
1334 break; // Wait for shutdown to complete.
1335 case FLUSHED:
1336 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1337 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1338 break;
1339 case SHUT_DOWN:
1340 finishFlushIfPossible(); // Should not occur.
1341 break; // Finish anyways.
1342 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001343 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001344 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001345 if (mVideoDecoderError
1346 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1347 || mNativeWindow == NULL
1348 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001349 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001350 // When both audio and video have error, or this stream has only audio
1351 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001352 notifyListener(
1353 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1354 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001355 } else {
1356 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001357 notifyListener(
1358 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1359 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001360 }
1361 mAudioDecoderError = true;
1362 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001363 if (mAudioDecoderError
1364 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001365 || mAudioSink == NULL || mAudioDecoder == NULL) {
1366 // When both audio and video have error, or this stream has only video
1367 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001368 notifyListener(
1369 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1370 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001371 } else {
1372 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001373 notifyListener(
1374 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1375 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001376 }
1377 mVideoDecoderError = true;
1378 }
1379 }
1380 } else {
1381 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1382 what,
1383 what >> 24,
1384 (what >> 16) & 0xff,
1385 (what >> 8) & 0xff,
1386 what & 0xff);
1387 }
1388
1389 break;
1390 }
1391
1392 case kWhatRendererNotify:
1393 {
1394 int32_t requesterGeneration = mRendererGeneration - 1;
1395 CHECK(msg->findInt32("generation", &requesterGeneration));
1396 if (requesterGeneration != mRendererGeneration) {
1397 ALOGV("got message from old renderer, generation(%d:%d)",
1398 requesterGeneration, mRendererGeneration);
1399 return;
1400 }
1401
1402 int32_t what;
1403 CHECK(msg->findInt32("what", &what));
1404
1405 if (what == Renderer::kWhatEOS) {
1406 int32_t audio;
1407 CHECK(msg->findInt32("audio", &audio));
1408
1409 int32_t finalResult;
1410 CHECK(msg->findInt32("finalResult", &finalResult));
1411
1412 if (audio) {
1413 mAudioEOS = true;
1414 } else {
1415 mVideoEOS = true;
1416 }
1417
1418 if (finalResult == ERROR_END_OF_STREAM) {
1419 ALOGV("reached %s EOS", audio ? "audio" : "video");
1420 } else {
1421 ALOGE("%s track encountered an error (%d)",
1422 audio ? "audio" : "video", finalResult);
1423
1424 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001425 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1426 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001427 }
1428
1429 if ((mAudioEOS || mAudioDecoder == NULL)
1430 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001431 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001432 }
1433 } else if (what == Renderer::kWhatFlushComplete) {
1434 int32_t audio;
1435 CHECK(msg->findInt32("audio", &audio));
1436
1437 if (audio) {
1438 mAudioEOS = false;
1439 } else {
1440 mVideoEOS = false;
1441 }
1442
1443 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1444 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1445 || mFlushingAudio == SHUT_DOWN)) {
1446 // Flush has been handled by tear down.
1447 break;
1448 }
1449 handleFlushComplete(audio, false /* isDecoder */);
1450 finishFlushIfPossible();
1451 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001452 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1453 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001454 } else if (what == Renderer::kWhatMediaRenderingStart) {
1455 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001456 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001457 } else if (what == Renderer::kWhatAudioTearDown) {
1458 int32_t reason;
1459 CHECK(msg->findInt32("reason", &reason));
1460 ALOGV("Tear down audio with reason %d.", reason);
1461 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1462 // TimeoutWhenPaused is only for offload mode.
1463 ALOGW("Receive a stale message for teardown.");
1464 break;
1465 }
1466 int64_t positionUs;
1467 if (!msg->findInt64("positionUs", &positionUs)) {
1468 positionUs = mPreviousSeekTimeUs;
1469 }
1470
1471 restartAudio(
1472 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1473 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1474 }
1475 break;
1476 }
1477
1478 case kWhatMoreDataQueued:
1479 {
1480 break;
1481 }
1482
1483 case kWhatReset:
1484 {
1485 ALOGV("kWhatReset");
1486
1487 mResetting = true;
1488 stopPlaybackTimer("kWhatReset");
1489 stopRebufferingTimer(true);
1490
1491 mDeferredActions.push_back(
1492 new FlushDecoderAction(
1493 FLUSH_CMD_SHUTDOWN /* audio */,
1494 FLUSH_CMD_SHUTDOWN /* video */));
1495
1496 mDeferredActions.push_back(
1497 new SimpleAction(&NuPlayer2::performReset));
1498
1499 processDeferredActions();
1500 break;
1501 }
1502
1503 case kWhatNotifyTime:
1504 {
1505 ALOGV("kWhatNotifyTime");
1506 int64_t timerUs;
1507 CHECK(msg->findInt64("timerUs", &timerUs));
1508
Wei Jiaf01e3122018-10-18 11:49:44 -07001509 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001510 break;
1511 }
1512
1513 case kWhatSeek:
1514 {
1515 int64_t seekTimeUs;
1516 int32_t mode;
1517 int32_t needNotify;
1518 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1519 CHECK(msg->findInt32("mode", &mode));
1520 CHECK(msg->findInt32("needNotify", &needNotify));
1521
1522 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1523 (long long)seekTimeUs, mode, needNotify);
1524
1525 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001526 if (!mSourceStarted) {
1527 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001528 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001529 }
Wei Jia083e9092018-02-12 11:46:04 -08001530 if (seekTimeUs > 0) {
1531 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1532 }
1533
Wei Jia53692fa2017-12-11 10:33:46 -08001534 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001535 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001536 }
1537 break;
1538 }
1539
Wei Jia083e9092018-02-12 11:46:04 -08001540 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001541 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001542
Wei Jia53692fa2017-12-11 10:33:46 -08001543 mDeferredActions.push_back(
1544 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1545 FLUSH_CMD_FLUSH /* video */));
1546
1547 mDeferredActions.push_back(
1548 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1549
1550 // After a flush without shutdown, decoder is paused.
1551 // Don't resume it until source seek is done, otherwise it could
1552 // start pulling stale data too soon.
1553 mDeferredActions.push_back(
1554 new ResumeDecoderAction(needNotify));
1555
1556 processDeferredActions();
1557 break;
1558 }
1559
Wei Jiad1864f92018-10-19 12:34:56 -07001560 case kWhatRewind:
1561 {
1562 ALOGV("kWhatRewind");
1563
1564 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1565 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1566
1567 if (!mStarted) {
1568 if (!mSourceStarted) {
1569 mSourceStarted = true;
1570 mCurrentSourceInfo.mSource->start();
1571 }
1572 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1573 break;
1574 }
1575
1576 // seeks can take a while, so we essentially paused
1577 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1578
1579 mDeferredActions.push_back(
1580 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1581 FLUSH_CMD_FLUSH /* video */));
1582
1583 mDeferredActions.push_back(
1584 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1585
1586 // After a flush without shutdown, decoder is paused.
1587 // Don't resume it until source seek is done, otherwise it could
1588 // start pulling stale data too soon.
1589 mDeferredActions.push_back(
1590 new ResumeDecoderAction(false /* needNotify */));
1591
1592 processDeferredActions();
1593 break;
1594 }
1595
Wei Jia53692fa2017-12-11 10:33:46 -08001596 case kWhatPause:
1597 {
Wei Jia6376cd52018-09-26 11:42:55 -07001598 if (!mStarted) {
1599 onStart(false /* play */);
1600 }
Wei Jia53692fa2017-12-11 10:33:46 -08001601 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001602 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001603 mPausedByClient = true;
1604 break;
1605 }
1606
1607 case kWhatSourceNotify:
1608 {
1609 onSourceNotify(msg);
1610 break;
1611 }
1612
1613 case kWhatClosedCaptionNotify:
1614 {
1615 onClosedCaptionNotify(msg);
1616 break;
1617 }
1618
1619 case kWhatPrepareDrm:
1620 {
1621 status_t status = onPrepareDrm(msg);
1622
1623 sp<AMessage> response = new AMessage;
1624 response->setInt32("status", status);
1625 sp<AReplyToken> replyID;
1626 CHECK(msg->senderAwaitsResponse(&replyID));
1627 response->postReply(replyID);
1628 break;
1629 }
1630
1631 case kWhatReleaseDrm:
1632 {
1633 status_t status = onReleaseDrm();
1634
1635 sp<AMessage> response = new AMessage;
1636 response->setInt32("status", status);
1637 sp<AReplyToken> replyID;
1638 CHECK(msg->senderAwaitsResponse(&replyID));
1639 response->postReply(replyID);
1640 break;
1641 }
1642
1643 default:
1644 TRESPASS();
1645 break;
1646 }
1647}
1648
1649void NuPlayer2::onResume() {
1650 if (!mPaused || mResetting) {
1651 ALOGD_IF(mResetting, "resetting, onResume discarded");
1652 return;
1653 }
1654 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001655 if (mCurrentSourceInfo.mSource != NULL) {
1656 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001657 } else {
1658 ALOGW("resume called when source is gone or not set");
1659 }
1660 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1661 // needed.
1662 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1663 instantiateDecoder(true /* audio */, &mAudioDecoder);
1664 }
1665 if (mRenderer != NULL) {
1666 mRenderer->resume();
1667 } else {
1668 ALOGW("resume called when renderer is gone or not set");
1669 }
1670
1671 startPlaybackTimer("onresume");
1672}
1673
Wei Jia6376cd52018-09-26 11:42:55 -07001674void NuPlayer2::onStart(bool play) {
Wei Jia53692fa2017-12-11 10:33:46 -08001675 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1676
1677 if (!mSourceStarted) {
1678 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001679 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001680 }
Wei Jia53692fa2017-12-11 10:33:46 -08001681
1682 mOffloadAudio = false;
1683 mAudioEOS = false;
1684 mVideoEOS = false;
1685 mStarted = true;
1686 mPaused = false;
1687
1688 uint32_t flags = 0;
1689
Wei Jiaf01e3122018-10-18 11:49:44 -07001690 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001691 flags |= Renderer::FLAG_REAL_TIME;
1692 }
1693
Wei Jiaf01e3122018-10-18 11:49:44 -07001694 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1695 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001696 if (!hasAudio && !hasVideo) {
1697 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001698 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001699 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001700 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1701 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001702 return;
1703 }
1704 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1705
Wei Jiaf01e3122018-10-18 11:49:44 -07001706 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001707
1708 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1709 if (mAudioSink != NULL) {
1710 streamType = mAudioSink->getAudioStreamType();
1711 }
1712
1713 mOffloadAudio =
Dongwon Kang946bdb32018-11-14 10:12:00 -08001714 JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
1715 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001716 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1717
1718 // Modular DRM: Disabling audio offload if the source is protected
1719 if (mOffloadAudio && mIsDrmProtected) {
1720 mOffloadAudio = false;
1721 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1722 }
1723
1724 if (mOffloadAudio) {
1725 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1726 }
1727
1728 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1729 ++mRendererGeneration;
1730 notify->setInt32("generation", mRendererGeneration);
1731 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1732 mRendererLooper = new ALooper;
Wei Jia8c8b57a2018-11-28 11:09:50 -08001733 mRendererLooper->setName("NuPlayer2Renderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001734 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001735 mRendererLooper->registerHandler(mRenderer);
1736
1737 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1738 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001739 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001740 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001741 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001742 return;
1743 }
1744
1745 float rate = getFrameRate();
1746 if (rate > 0) {
1747 mRenderer->setVideoFrameRate(rate);
1748 }
1749
Wei Jiad1864f92018-10-19 12:34:56 -07001750 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001751 // Renderer is created in paused state.
1752 if (play) {
1753 mRenderer->resume();
1754 }
1755
Wei Jia53692fa2017-12-11 10:33:46 -08001756 if (mVideoDecoder != NULL) {
1757 mVideoDecoder->setRenderer(mRenderer);
1758 }
1759 if (mAudioDecoder != NULL) {
1760 mAudioDecoder->setRenderer(mRenderer);
1761 }
1762
1763 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001764 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001765
1766 postScanSources();
1767}
1768
Wei Jiad1864f92018-10-19 12:34:56 -07001769void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001770 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001771
1772 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1773 return;
1774 }
1775
1776 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001777 msg->setInt32("generation", mEOSMonitorGeneration);
1778 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1779}
1780
Wei Jia53692fa2017-12-11 10:33:46 -08001781void NuPlayer2::startPlaybackTimer(const char *where) {
1782 Mutex::Autolock autoLock(mPlayingTimeLock);
1783 if (mLastStartedPlayingTimeNs == 0) {
1784 mLastStartedPlayingTimeNs = systemTime();
1785 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1786 }
1787}
1788
1789void NuPlayer2::stopPlaybackTimer(const char *where) {
1790 Mutex::Autolock autoLock(mPlayingTimeLock);
1791
1792 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1793
1794 if (mLastStartedPlayingTimeNs != 0) {
1795 sp<NuPlayer2Driver> driver = mDriver.promote();
1796 if (driver != NULL) {
1797 int64_t now = systemTime();
1798 int64_t played = now - mLastStartedPlayingTimeNs;
1799 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1800
1801 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001802 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001803 }
1804 }
1805 mLastStartedPlayingTimeNs = 0;
1806 }
1807}
1808
1809void NuPlayer2::startRebufferingTimer() {
1810 Mutex::Autolock autoLock(mPlayingTimeLock);
1811 if (mLastStartedRebufferingTimeNs == 0) {
1812 mLastStartedRebufferingTimeNs = systemTime();
1813 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1814 }
1815}
1816
1817void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1818 Mutex::Autolock autoLock(mPlayingTimeLock);
1819
Wei Jiaf01e3122018-10-18 11:49:44 -07001820 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1821 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001822
1823 if (mLastStartedRebufferingTimeNs != 0) {
1824 sp<NuPlayer2Driver> driver = mDriver.promote();
1825 if (driver != NULL) {
1826 int64_t now = systemTime();
1827 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1828 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1829
1830 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001831 driver->notifyMoreRebufferingTimeUs(
1832 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001833 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001834 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001835 }
1836 }
1837 }
1838 mLastStartedRebufferingTimeNs = 0;
1839 }
1840}
1841
1842void NuPlayer2::onPause() {
1843
1844 stopPlaybackTimer("onPause");
1845
1846 if (mPaused) {
1847 return;
1848 }
1849 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001850 if (mCurrentSourceInfo.mSource != NULL) {
1851 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001852 } else {
1853 ALOGW("pause called when source is gone or not set");
1854 }
1855 if (mRenderer != NULL) {
1856 mRenderer->pause();
1857 } else {
1858 ALOGW("pause called when renderer is gone or not set");
1859 }
1860
1861}
1862
1863bool NuPlayer2::audioDecoderStillNeeded() {
1864 // Audio decoder is no longer needed if it's in shut/shutting down status.
1865 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1866}
1867
1868void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1869 // We wait for both the decoder flush and the renderer flush to complete
1870 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1871
1872 mFlushComplete[audio][isDecoder] = true;
1873 if (!mFlushComplete[audio][!isDecoder]) {
1874 return;
1875 }
1876
1877 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1878 switch (*state) {
1879 case FLUSHING_DECODER:
1880 {
1881 *state = FLUSHED;
1882 break;
1883 }
1884
1885 case FLUSHING_DECODER_SHUTDOWN:
1886 {
1887 *state = SHUTTING_DOWN_DECODER;
1888
1889 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1890 getDecoder(audio)->initiateShutdown();
1891 break;
1892 }
1893
1894 default:
1895 // decoder flush completes only occur in a flushing state.
1896 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1897 break;
1898 }
1899}
1900
1901void NuPlayer2::finishFlushIfPossible() {
1902 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1903 && mFlushingAudio != SHUT_DOWN) {
1904 return;
1905 }
1906
1907 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1908 && mFlushingVideo != SHUT_DOWN) {
1909 return;
1910 }
1911
1912 ALOGV("both audio and video are flushed now.");
1913
1914 mFlushingAudio = NONE;
1915 mFlushingVideo = NONE;
1916
1917 clearFlushComplete();
1918
1919 processDeferredActions();
1920}
1921
1922void NuPlayer2::postScanSources() {
1923 if (mScanSourcesPending) {
1924 return;
1925 }
1926
1927 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1928 msg->setInt32("generation", mScanSourcesGeneration);
1929 msg->post();
1930
1931 mScanSourcesPending = true;
1932}
1933
1934void NuPlayer2::tryOpenAudioSinkForOffload(
1935 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1936 // Note: This is called early in NuPlayer2 to determine whether offloading
1937 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1938
1939 status_t err = mRenderer->openAudioSink(
1940 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001941 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001942 if (err != OK) {
1943 // Any failure we turn off mOffloadAudio.
1944 mOffloadAudio = false;
1945 } else if (mOffloadAudio) {
1946 sendMetaDataToHal(mAudioSink, audioMeta);
1947 }
1948}
1949
1950void NuPlayer2::closeAudioSink() {
1951 mRenderer->closeAudioSink();
1952}
1953
1954void NuPlayer2::restartAudio(
1955 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1956 if (mAudioDecoder != NULL) {
1957 mAudioDecoder->pause();
1958 mAudioDecoder.clear();
1959 mAudioDecoderError = false;
1960 ++mAudioDecoderGeneration;
1961 }
1962 if (mFlushingAudio == FLUSHING_DECODER) {
1963 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1964 mFlushingAudio = FLUSHED;
1965 finishFlushIfPossible();
1966 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1967 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1968 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1969 mFlushingAudio = SHUT_DOWN;
1970 finishFlushIfPossible();
1971 needsToCreateAudioDecoder = false;
1972 }
1973 if (mRenderer == NULL) {
1974 return;
1975 }
1976 closeAudioSink();
1977 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1978 if (mVideoDecoder != NULL) {
1979 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1980 }
1981
1982 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1983
1984 if (forceNonOffload) {
1985 mRenderer->signalDisableOffloadAudio();
1986 mOffloadAudio = false;
1987 }
1988 if (needsToCreateAudioDecoder) {
1989 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1990 }
1991}
1992
1993void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001994 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001995 return;
1996 }
1997
1998 if (mRenderer == NULL) {
1999 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
2000 mOffloadAudio = false;
2001 return;
2002 }
2003
Wei Jiaf01e3122018-10-18 11:49:44 -07002004 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
2005 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002006 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
2007 const bool hasVideo = (videoFormat != NULL);
Dongwon Kangcd0e4272018-11-15 10:49:14 -08002008 bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
Wei Jiaf01e3122018-10-18 11:49:44 -07002009 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08002010 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2011
2012 // Modular DRM: Disabling audio offload if the source is protected
2013 if (canOffload && mIsDrmProtected) {
2014 canOffload = false;
2015 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2016 }
2017
2018 if (canOffload) {
2019 if (!mOffloadAudio) {
2020 mRenderer->signalEnableOffloadAudio();
2021 }
2022 // open audio sink early under offload mode.
2023 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2024 } else {
2025 if (mOffloadAudio) {
2026 mRenderer->signalDisableOffloadAudio();
2027 mOffloadAudio = false;
2028 }
2029 }
2030}
2031
2032status_t NuPlayer2::instantiateDecoder(
2033 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2034 // The audio decoder could be cleared by tear down. If still in shut down
2035 // process, no need to create a new audio decoder.
2036 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2037 return OK;
2038 }
2039
Wei Jiaf01e3122018-10-18 11:49:44 -07002040 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002041
2042 if (format == NULL) {
2043 return UNKNOWN_ERROR;
2044 } else {
2045 status_t err;
2046 if (format->findInt32("err", &err) && err) {
2047 return err;
2048 }
2049 }
2050
2051 format->setInt32("priority", 0 /* realtime */);
2052
2053 if (!audio) {
2054 AString mime;
2055 CHECK(format->findString("mime", &mime));
2056
2057 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2058 if (mCCDecoder == NULL) {
2059 mCCDecoder = new CCDecoder(ccNotify);
2060 }
2061
Wei Jiaf01e3122018-10-18 11:49:44 -07002062 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002063 format->setInt32("secure", true);
2064 }
2065
Wei Jiaf01e3122018-10-18 11:49:44 -07002066 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002067 format->setInt32("protected", true);
2068 }
2069
2070 float rate = getFrameRate();
2071 if (rate > 0) {
2072 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2073 }
2074 }
2075
2076 if (audio) {
2077 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2078 ++mAudioDecoderGeneration;
2079 notify->setInt32("generation", mAudioDecoderGeneration);
2080
2081 if (checkAudioModeChange) {
2082 determineAudioModeChange(format);
2083 }
2084 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002085 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002086
Wei Jiaf01e3122018-10-18 11:49:44 -07002087 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002088 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002089 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002090 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2091 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002092 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002093
Wei Jiaf01e3122018-10-18 11:49:44 -07002094 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002095 ALOGV("instantiateDecoder audio Decoder");
2096 }
2097 mAudioDecoderError = false;
2098 } else {
2099 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2100 ++mVideoDecoderGeneration;
2101 notify->setInt32("generation", mVideoDecoderGeneration);
2102
2103 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002104 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2105 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002106 mVideoDecoderError = false;
2107
2108 // enable FRC if high-quality AV sync is requested, even if not
2109 // directly queuing to display, as this will even improve textureview
2110 // playback.
2111 {
2112 if (property_get_bool("persist.sys.media.avsync", false)) {
2113 format->setInt32("auto-frc", 1);
2114 }
2115 }
2116 }
2117 (*decoder)->init();
2118
2119 // Modular DRM
2120 if (mIsDrmProtected) {
2121 format->setObject("crypto", mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002122 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
2123 mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002124 }
2125
2126 (*decoder)->configure(format);
2127
2128 if (!audio) {
2129 sp<AMessage> params = new AMessage();
2130 float rate = getFrameRate();
2131 if (rate > 0) {
2132 params->setFloat("frame-rate-total", rate);
2133 }
2134
2135 sp<MetaData> fileMeta = getFileMeta();
2136 if (fileMeta != NULL) {
2137 int32_t videoTemporalLayerCount;
2138 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2139 && videoTemporalLayerCount > 0) {
2140 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2141 }
2142 }
2143
2144 if (params->countEntries() > 0) {
2145 (*decoder)->setParameters(params);
2146 }
2147 }
2148 return OK;
2149}
2150
2151void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002152 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002153 const sp<AMessage> &inputFormat,
2154 const sp<AMessage> &outputFormat) {
2155 if (inputFormat == NULL) {
2156 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002157 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002158 return;
2159 }
2160 int32_t err = OK;
2161 inputFormat->findInt32("err", &err);
2162 if (err == -EWOULDBLOCK) {
2163 ALOGW("Video meta is not available yet!");
2164 return;
2165 }
2166 if (err != OK) {
2167 ALOGW("Something is wrong with video meta!");
2168 return;
2169 }
2170
2171 int32_t displayWidth, displayHeight;
2172 if (outputFormat != NULL) {
2173 int32_t width, height;
2174 CHECK(outputFormat->findInt32("width", &width));
2175 CHECK(outputFormat->findInt32("height", &height));
2176
2177 int32_t cropLeft, cropTop, cropRight, cropBottom;
2178 CHECK(outputFormat->findRect(
2179 "crop",
2180 &cropLeft, &cropTop, &cropRight, &cropBottom));
2181
2182 displayWidth = cropRight - cropLeft + 1;
2183 displayHeight = cropBottom - cropTop + 1;
2184
2185 ALOGV("Video output format changed to %d x %d "
2186 "(crop: %d x %d @ (%d, %d))",
2187 width, height,
2188 displayWidth,
2189 displayHeight,
2190 cropLeft, cropTop);
2191 } else {
2192 CHECK(inputFormat->findInt32("width", &displayWidth));
2193 CHECK(inputFormat->findInt32("height", &displayHeight));
2194
2195 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2196 }
2197
2198 // Take into account sample aspect ratio if necessary:
2199 int32_t sarWidth, sarHeight;
2200 if (inputFormat->findInt32("sar-width", &sarWidth)
2201 && inputFormat->findInt32("sar-height", &sarHeight)
2202 && sarWidth > 0 && sarHeight > 0) {
2203 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2204
2205 displayWidth = (displayWidth * sarWidth) / sarHeight;
2206
2207 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2208 } else {
2209 int32_t width, height;
2210 if (inputFormat->findInt32("display-width", &width)
2211 && inputFormat->findInt32("display-height", &height)
2212 && width > 0 && height > 0
2213 && displayWidth > 0 && displayHeight > 0) {
2214 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2215 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2216 } else {
2217 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2218 }
2219 ALOGV("Video display width and height are overridden to %d x %d",
2220 displayWidth, displayHeight);
2221 }
2222 }
2223
2224 int32_t rotationDegrees;
2225 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2226 rotationDegrees = 0;
2227 }
2228
2229 if (rotationDegrees == 90 || rotationDegrees == 270) {
2230 int32_t tmp = displayWidth;
2231 displayWidth = displayHeight;
2232 displayHeight = tmp;
2233 }
2234
2235 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002236 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002237 MEDIA2_SET_VIDEO_SIZE,
2238 displayWidth,
2239 displayHeight);
2240}
2241
Dongwon Kang41929fb2018-09-09 08:29:56 -07002242void NuPlayer2::notifyListener(
2243 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002244 if (mDriver == NULL) {
2245 return;
2246 }
2247
2248 sp<NuPlayer2Driver> driver = mDriver.promote();
2249
2250 if (driver == NULL) {
2251 return;
2252 }
2253
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002254 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002255}
2256
2257void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2258 ALOGV("[%s] flushDecoder needShutdown=%d",
2259 audio ? "audio" : "video", needShutdown);
2260
2261 const sp<DecoderBase> &decoder = getDecoder(audio);
2262 if (decoder == NULL) {
2263 ALOGI("flushDecoder %s without decoder present",
2264 audio ? "audio" : "video");
2265 return;
2266 }
2267
2268 // Make sure we don't continue to scan sources until we finish flushing.
2269 ++mScanSourcesGeneration;
2270 if (mScanSourcesPending) {
2271 if (!needShutdown) {
2272 mDeferredActions.push_back(
2273 new SimpleAction(&NuPlayer2::performScanSources));
2274 }
2275 mScanSourcesPending = false;
2276 }
2277
2278 decoder->signalFlush();
2279
2280 FlushStatus newStatus =
2281 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2282
2283 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2284 mFlushComplete[audio][true /* isDecoder */] = false;
2285 if (audio) {
2286 ALOGE_IF(mFlushingAudio != NONE,
2287 "audio flushDecoder() is called in state %d", mFlushingAudio);
2288 mFlushingAudio = newStatus;
2289 } else {
2290 ALOGE_IF(mFlushingVideo != NONE,
2291 "video flushDecoder() is called in state %d", mFlushingVideo);
2292 mFlushingVideo = newStatus;
2293 }
2294}
2295
2296void NuPlayer2::queueDecoderShutdown(
2297 bool audio, bool video, const sp<AMessage> &reply) {
2298 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2299
2300 mDeferredActions.push_back(
2301 new FlushDecoderAction(
2302 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2303 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2304
2305 mDeferredActions.push_back(
2306 new SimpleAction(&NuPlayer2::performScanSources));
2307
2308 mDeferredActions.push_back(new PostMessageAction(reply));
2309
2310 processDeferredActions();
2311}
2312
2313status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2314 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002315 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2316 status_t ret = native_window_set_scaling_mode(
2317 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002318 if (ret != OK) {
2319 ALOGE("Failed to set scaling mode (%d): %s",
2320 -ret, strerror(-ret));
2321 return ret;
2322 }
2323 }
2324 return OK;
2325}
2326
Dongwon Kang9f631982018-07-10 12:34:41 -07002327status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002328 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2329 msg->setPointer("reply", reply);
2330
2331 sp<AMessage> response;
2332 status_t err = msg->postAndAwaitResponse(&response);
2333 return err;
2334}
2335
Dongwon Kang9f631982018-07-10 12:34:41 -07002336status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002337 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2338 msg->setPointer("reply", reply);
2339 msg->setInt32("type", type);
2340
2341 sp<AMessage> response;
2342 status_t err = msg->postAndAwaitResponse(&response);
2343 if (err == OK && response != NULL) {
2344 CHECK(response->findInt32("err", &err));
2345 }
2346 return err;
2347}
2348
2349status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2350 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2351 msg->setSize("trackIndex", trackIndex);
2352 msg->setInt32("select", select);
2353 msg->setInt64("timeUs", timeUs);
2354
2355 sp<AMessage> response;
2356 status_t err = msg->postAndAwaitResponse(&response);
2357
2358 if (err != OK) {
2359 return err;
2360 }
2361
2362 if (!response->findInt32("err", &err)) {
2363 err = OK;
2364 }
2365
2366 return err;
2367}
2368
2369status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2370 sp<Renderer> renderer = mRenderer;
2371 if (renderer == NULL) {
2372 return NO_INIT;
2373 }
2374
2375 return renderer->getCurrentPosition(mediaUs);
2376}
2377
2378void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2379 CHECK(mTrackStats != NULL);
2380
2381 mTrackStats->clear();
2382 if (mVideoDecoder != NULL) {
2383 mTrackStats->push_back(mVideoDecoder->getStats());
2384 }
2385 if (mAudioDecoder != NULL) {
2386 mTrackStats->push_back(mAudioDecoder->getStats());
2387 }
2388}
2389
2390sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002391 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002392}
2393
2394float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002395 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002396 if (meta == NULL) {
2397 return 0;
2398 }
2399 int32_t rate;
2400 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2401 // fall back to try file meta
2402 sp<MetaData> fileMeta = getFileMeta();
2403 if (fileMeta == NULL) {
2404 ALOGW("source has video meta but not file meta");
2405 return -1;
2406 }
2407 int32_t fileMetaRate;
2408 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2409 return -1;
2410 }
2411 return fileMetaRate;
2412 }
2413 return rate;
2414}
2415
2416void NuPlayer2::schedulePollDuration() {
2417 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2418 msg->setInt32("generation", mPollDurationGeneration);
2419 msg->post();
2420}
2421
2422void NuPlayer2::cancelPollDuration() {
2423 ++mPollDurationGeneration;
2424}
2425
2426void NuPlayer2::processDeferredActions() {
2427 while (!mDeferredActions.empty()) {
2428 // We won't execute any deferred actions until we're no longer in
2429 // an intermediate state, i.e. one more more decoders are currently
2430 // flushing or shutting down.
2431
2432 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2433 // We're currently flushing, postpone the reset until that's
2434 // completed.
2435
2436 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2437 mFlushingAudio, mFlushingVideo);
2438
2439 break;
2440 }
2441
2442 sp<Action> action = *mDeferredActions.begin();
2443 mDeferredActions.erase(mDeferredActions.begin());
2444
2445 action->execute(this);
2446 }
2447}
2448
2449void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2450 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2451 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2452
Wei Jiaf01e3122018-10-18 11:49:44 -07002453 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002454 // This happens when reset occurs right before the loop mode
2455 // asynchronously seeks to the start of the stream.
2456 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002457 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002458 mAudioDecoder.get(), mVideoDecoder.get());
2459 return;
2460 }
2461 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002462 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002463 ++mTimedTextGeneration;
2464
2465 // everything's flushed, continue playback.
2466}
2467
2468void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2469 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2470
2471 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2472 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2473 return;
2474 }
2475
2476 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2477 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2478 }
2479
2480 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2481 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2482 }
2483}
2484
2485void NuPlayer2::performReset() {
2486 ALOGV("performReset");
2487
2488 CHECK(mAudioDecoder == NULL);
2489 CHECK(mVideoDecoder == NULL);
2490
2491 stopPlaybackTimer("performReset");
2492 stopRebufferingTimer(true);
2493
2494 cancelPollDuration();
2495
2496 ++mScanSourcesGeneration;
2497 mScanSourcesPending = false;
2498
2499 if (mRendererLooper != NULL) {
2500 if (mRenderer != NULL) {
2501 mRendererLooper->unregisterHandler(mRenderer->id());
2502 }
2503 mRendererLooper->stop();
2504 mRendererLooper.clear();
2505 }
2506 mRenderer.clear();
2507 ++mRendererGeneration;
2508
Wei Jiaf01e3122018-10-18 11:49:44 -07002509 if (mCurrentSourceInfo.mSource != NULL) {
2510 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08002511
2512 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002513 mCurrentSourceInfo.mSource.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08002514 }
2515
2516 if (mDriver != NULL) {
2517 sp<NuPlayer2Driver> driver = mDriver.promote();
2518 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002519 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002520 }
2521 }
2522
2523 mStarted = false;
2524 mPrepared = false;
2525 mResetting = false;
2526 mSourceStarted = false;
2527
2528 // Modular DRM
2529 if (mCrypto != NULL) {
2530 // decoders will be flushed before this so their mCrypto would go away on their own
2531 // TODO change to ALOGV
2532 ALOGD("performReset mCrypto: %p", mCrypto.get());
2533 mCrypto.clear();
2534 }
2535 mIsDrmProtected = false;
2536}
2537
Wei Jia57aeffd2018-02-15 16:01:14 -08002538void NuPlayer2::performPlayNextDataSource() {
2539 ALOGV("performPlayNextDataSource");
2540
2541 CHECK(mAudioDecoder == NULL);
2542 CHECK(mVideoDecoder == NULL);
2543
2544 stopPlaybackTimer("performPlayNextDataSource");
2545 stopRebufferingTimer(true);
2546
2547 cancelPollDuration();
2548
2549 ++mScanSourcesGeneration;
2550 mScanSourcesPending = false;
2551
2552 ++mRendererGeneration;
2553
Wei Jiaf01e3122018-10-18 11:49:44 -07002554 if (mCurrentSourceInfo.mSource != NULL) {
2555 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002556 }
2557
2558 long previousSrcId;
2559 {
2560 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002561 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002562
2563 mCurrentSourceInfo = mNextSourceInfo;
2564 mNextSourceInfo = SourceInfo();
2565 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002566 }
2567
2568 if (mDriver != NULL) {
2569 sp<NuPlayer2Driver> driver = mDriver.promote();
2570 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002571 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002572
2573 int64_t durationUs;
2574 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2575 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2576 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002577 notifyListener(
2578 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002579 }
2580 }
2581
2582 mStarted = false;
2583 mPrepared = true; // TODO: what if it's not prepared
2584 mResetting = false;
2585 mSourceStarted = false;
2586
Wei Jiad1864f92018-10-19 12:34:56 -07002587 addEndTimeMonitor();
2588
Wei Jia57aeffd2018-02-15 16:01:14 -08002589 // Modular DRM
2590 if (mCrypto != NULL) {
2591 // decoders will be flushed before this so their mCrypto would go away on their own
2592 // TODO change to ALOGV
2593 ALOGD("performReset mCrypto: %p", mCrypto.get());
2594 mCrypto.clear();
2595 }
2596 mIsDrmProtected = false;
2597
2598 if (mRenderer != NULL) {
2599 mRenderer->resume();
2600 }
2601
Wei Jia6376cd52018-09-26 11:42:55 -07002602 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002603 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002604 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002605}
2606
Wei Jia53692fa2017-12-11 10:33:46 -08002607void NuPlayer2::performScanSources() {
2608 ALOGV("performScanSources");
2609
2610 if (!mStarted) {
2611 return;
2612 }
2613
2614 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2615 postScanSources();
2616 }
2617}
2618
Wei Jia28288fb2017-12-15 13:45:29 -08002619void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002620 ALOGV("performSetSurface");
2621
Wei Jia28288fb2017-12-15 13:45:29 -08002622 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002623
2624 // XXX - ignore error from setVideoScalingMode for now
2625 setVideoScalingMode(mVideoScalingMode);
2626
2627 if (mDriver != NULL) {
2628 sp<NuPlayer2Driver> driver = mDriver.promote();
2629 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002630 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002631 }
2632 }
2633}
2634
2635void NuPlayer2::performResumeDecoders(bool needNotify) {
2636 if (needNotify) {
2637 mResumePending = true;
2638 if (mVideoDecoder == NULL) {
2639 // if audio-only, we can notify seek complete now,
2640 // as the resume operation will be relatively fast.
2641 finishResume();
2642 }
2643 }
2644
2645 if (mVideoDecoder != NULL) {
2646 // When there is continuous seek, MediaPlayer will cache the seek
2647 // position, and send down new seek request when previous seek is
2648 // complete. Let's wait for at least one video output frame before
2649 // notifying seek complete, so that the video thumbnail gets updated
2650 // when seekbar is dragged.
2651 mVideoDecoder->signalResume(needNotify);
2652 }
2653
2654 if (mAudioDecoder != NULL) {
2655 mAudioDecoder->signalResume(false /* needNotify */);
2656 }
2657}
2658
2659void NuPlayer2::finishResume() {
2660 if (mResumePending) {
2661 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002662 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002663 }
2664}
2665
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002666void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002667 if (mDriver != NULL) {
2668 sp<NuPlayer2Driver> driver = mDriver.promote();
2669 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002670 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002671 }
2672 }
2673}
2674
2675void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2676 int32_t what;
2677 CHECK(msg->findInt32("what", &what));
2678
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002679 int64_t srcId;
2680 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002681 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002682 case Source::kWhatPrepared:
2683 {
Wei Jiad1864f92018-10-19 12:34:56 -07002684 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2685 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2686 if (srcId == mCurrentSourceInfo.mSrcId) {
2687 if (mCurrentSourceInfo.mSource == NULL) {
2688 // This is a stale notification from a source that was
2689 // asynchronously preparing when the client called reset().
2690 // We handled the reset, the source is gone.
2691 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002692 }
Wei Jiad1864f92018-10-19 12:34:56 -07002693
2694 int32_t err;
2695 CHECK(msg->findInt32("err", &err));
2696
2697 if (err != OK) {
2698 // shut down potential secure codecs in case client never calls reset
2699 mDeferredActions.push_back(
2700 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2701 FLUSH_CMD_SHUTDOWN /* video */));
2702 processDeferredActions();
2703 } else {
2704 mPrepared = true;
2705 }
2706
2707 sp<NuPlayer2Driver> driver = mDriver.promote();
2708 if (driver != NULL) {
2709 // notify duration first, so that it's definitely set when
2710 // the app received the "prepare complete" callback.
2711 int64_t durationUs;
2712 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2713 driver->notifyDuration(srcId, durationUs);
2714 }
2715 driver->notifyPrepareCompleted(srcId, err);
2716 }
2717 } else if (srcId == mNextSourceInfo.mSrcId) {
2718 if (mNextSourceInfo.mSource == NULL) {
2719 break; // stale
2720 }
2721
2722 sp<NuPlayer2Driver> driver = mDriver.promote();
2723 if (driver != NULL) {
2724 int32_t err;
2725 CHECK(msg->findInt32("err", &err));
2726 driver->notifyPrepareCompleted(srcId, err);
2727 }
Wei Jia53692fa2017-12-11 10:33:46 -08002728 }
2729
2730 break;
2731 }
2732
2733 // Modular DRM
2734 case Source::kWhatDrmInfo:
2735 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002736 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002737 sp<ABuffer> drmInfo;
2738 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002739 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002740
Dongwon Kang41929fb2018-09-09 08:29:56 -07002741 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2742 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002743
Dongwon Kang41929fb2018-09-09 08:29:56 -07002744 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002745
2746 break;
2747 }
2748
2749 case Source::kWhatFlagsChanged:
2750 {
2751 uint32_t flags;
2752 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2753
2754 sp<NuPlayer2Driver> driver = mDriver.promote();
2755 if (driver != NULL) {
2756
2757 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2758 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2759 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2760 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2761 (flags & Source::FLAG_CAN_PAUSE) != 0,
2762 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2763 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2764 (flags & Source::FLAG_CAN_SEEK) != 0,
2765 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2766 (flags & Source::FLAG_SECURE) != 0,
2767 (flags & Source::FLAG_PROTECTED) != 0);
2768
2769 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2770 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002771 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002772 }
Wei Jiad1864f92018-10-19 12:34:56 -07002773 if (srcId == mCurrentSourceInfo.mSrcId) {
2774 driver->notifyFlagsChanged(srcId, flags);
2775 }
Wei Jia53692fa2017-12-11 10:33:46 -08002776 }
2777
Wei Jiaf01e3122018-10-18 11:49:44 -07002778 if (srcId == mCurrentSourceInfo.mSrcId) {
2779 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2780 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2781 cancelPollDuration();
2782 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2783 && (flags & Source::FLAG_DYNAMIC_DURATION)
2784 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2785 schedulePollDuration();
2786 }
Wei Jia53692fa2017-12-11 10:33:46 -08002787
Wei Jiaf01e3122018-10-18 11:49:44 -07002788 mCurrentSourceInfo.mSourceFlags = flags;
2789 } else if (srcId == mNextSourceInfo.mSrcId) {
2790 // TODO: handle duration polling for next source.
2791 mNextSourceInfo.mSourceFlags = flags;
2792 }
Wei Jia53692fa2017-12-11 10:33:46 -08002793 break;
2794 }
2795
2796 case Source::kWhatVideoSizeChanged:
2797 {
2798 sp<AMessage> format;
2799 CHECK(msg->findMessage("format", &format));
2800
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002801 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002802 break;
2803 }
2804
2805 case Source::kWhatBufferingUpdate:
2806 {
2807 int32_t percentage;
2808 CHECK(msg->findInt32("percentage", &percentage));
2809
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002810 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002811 break;
2812 }
2813
2814 case Source::kWhatPauseOnBufferingStart:
2815 {
2816 // ignore if not playing
2817 if (mStarted) {
2818 ALOGI("buffer low, pausing...");
2819
2820 startRebufferingTimer();
2821 mPausedForBuffering = true;
2822 onPause();
2823 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002824 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002825 break;
2826 }
2827
2828 case Source::kWhatResumeOnBufferingEnd:
2829 {
2830 // ignore if not playing
2831 if (mStarted) {
2832 ALOGI("buffer ready, resuming...");
2833
2834 stopRebufferingTimer(false);
2835 mPausedForBuffering = false;
2836
2837 // do not resume yet if client didn't unpause
2838 if (!mPausedByClient) {
2839 onResume();
2840 }
2841 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002842 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002843 break;
2844 }
2845
2846 case Source::kWhatCacheStats:
2847 {
2848 int32_t kbps;
2849 CHECK(msg->findInt32("bandwidth", &kbps));
2850
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002851 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002852 break;
2853 }
2854
2855 case Source::kWhatSubtitleData:
2856 {
2857 sp<ABuffer> buffer;
2858 CHECK(msg->findBuffer("buffer", &buffer));
2859
2860 sendSubtitleData(buffer, 0 /* baseIndex */);
2861 break;
2862 }
2863
2864 case Source::kWhatTimedMetaData:
2865 {
2866 sp<ABuffer> buffer;
2867 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002868 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002869 } else {
2870 sendTimedMetaData(buffer);
2871 }
2872 break;
2873 }
2874
2875 case Source::kWhatTimedTextData:
2876 {
2877 int32_t generation;
2878 if (msg->findInt32("generation", &generation)
2879 && generation != mTimedTextGeneration) {
2880 break;
2881 }
2882
2883 sp<ABuffer> buffer;
2884 CHECK(msg->findBuffer("buffer", &buffer));
2885
2886 sp<NuPlayer2Driver> driver = mDriver.promote();
2887 if (driver == NULL) {
2888 break;
2889 }
2890
Wei Jia800fe372018-02-20 15:00:45 -08002891 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002892 int64_t timeUs, posUs;
2893 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002894 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002895 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2896
2897 if (posUs < timeUs) {
2898 if (!msg->findInt32("generation", &generation)) {
2899 msg->setInt32("generation", mTimedTextGeneration);
2900 }
2901 msg->post(timeUs - posUs);
2902 } else {
2903 sendTimedTextData(buffer);
2904 }
2905 break;
2906 }
2907
2908 case Source::kWhatQueueDecoderShutdown:
2909 {
2910 int32_t audio, video;
2911 CHECK(msg->findInt32("audio", &audio));
2912 CHECK(msg->findInt32("video", &video));
2913
2914 sp<AMessage> reply;
2915 CHECK(msg->findMessage("reply", &reply));
2916
2917 queueDecoderShutdown(audio, video, reply);
2918 break;
2919 }
2920
2921 case Source::kWhatDrmNoLicense:
2922 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002923 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002924 break;
2925 }
2926
2927 default:
2928 TRESPASS();
2929 }
2930}
2931
2932void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2933 int32_t what;
2934 CHECK(msg->findInt32("what", &what));
2935
2936 switch (what) {
2937 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2938 {
2939 sp<ABuffer> buffer;
2940 CHECK(msg->findBuffer("buffer", &buffer));
2941
2942 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002943 if (mCurrentSourceInfo.mSource != NULL) {
2944 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002945 }
2946
2947 sendSubtitleData(buffer, inbandTracks);
2948 break;
2949 }
2950
2951 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2952 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002953 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002954
2955 break;
2956 }
2957
2958 default:
2959 TRESPASS();
2960 }
2961
2962
2963}
2964
2965void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2966 int32_t trackIndex;
2967 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002968 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002969 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2970 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2971
Dongwon Kang41929fb2018-09-09 08:29:56 -07002972 PlayerMessage playerMsg;
2973 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2974 playerMsg.add_values()->set_int64_value(timeUs);
2975 playerMsg.add_values()->set_int64_value(durationUs);
2976 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002977
Wei Jiaf01e3122018-10-18 11:49:44 -07002978 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002979}
2980
2981void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2982 int64_t timeUs;
2983 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2984
Dongwon Kang41929fb2018-09-09 08:29:56 -07002985 PlayerMessage playerMsg;
2986 playerMsg.add_values()->set_int64_value(timeUs);
2987 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002988
Wei Jiaf01e3122018-10-18 11:49:44 -07002989 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002990}
2991
2992void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2993 const void *data;
2994 size_t size = 0;
2995 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002996 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002997
2998 AString mime;
2999 CHECK(buffer->meta()->findString("mime", &mime));
3000 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
3001
3002 data = buffer->data();
3003 size = buffer->size();
3004
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003005 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08003006 if (size > 0) {
3007 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3008 int32_t global = 0;
3009 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003010 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003011 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003012 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003013 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003014 TextDescriptions2::getPlayerMessageOfDescriptions(
3015 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003016 }
3017
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003018 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003019 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003020 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003021 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003022 }
3023}
3024
3025const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003026 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003027 case DATA_SOURCE_TYPE_HTTP_LIVE:
3028 return "HTTPLive";
3029
3030 case DATA_SOURCE_TYPE_RTSP:
3031 return "RTSP";
3032
3033 case DATA_SOURCE_TYPE_GENERIC_URL:
3034 return "GenURL";
3035
3036 case DATA_SOURCE_TYPE_GENERIC_FD:
3037 return "GenFD";
3038
3039 case DATA_SOURCE_TYPE_MEDIA:
3040 return "Media";
3041
Wei Jia53692fa2017-12-11 10:33:46 -08003042 case DATA_SOURCE_TYPE_NONE:
3043 default:
3044 return "None";
3045 }
3046 }
3047
3048// Modular DRM begin
Robert Shih3c3728d2018-12-04 17:06:36 -08003049status_t NuPlayer2::prepareDrm(
3050 int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
Wei Jia53692fa2017-12-11 10:33:46 -08003051{
3052 ALOGV("prepareDrm ");
3053
3054 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3055 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3056 // synchronous call so just passing the address but with local copies of "const" args
3057 uint8_t UUID[16];
3058 memcpy(UUID, uuid, sizeof(UUID));
3059 Vector<uint8_t> sessionId = drmSessionId;
Robert Shih3c3728d2018-12-04 17:06:36 -08003060 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003061 msg->setPointer("uuid", (void*)UUID);
3062 msg->setPointer("drmSessionId", (void*)&sessionId);
3063
3064 sp<AMessage> response;
3065 status_t status = msg->postAndAwaitResponse(&response);
3066
3067 if (status == OK && response != NULL) {
3068 CHECK(response->findInt32("status", &status));
3069 ALOGV("prepareDrm ret: %d ", status);
3070 } else {
3071 ALOGE("prepareDrm err: %d", status);
3072 }
3073
3074 return status;
3075}
3076
Robert Shih3c3728d2018-12-04 17:06:36 -08003077status_t NuPlayer2::releaseDrm(int64_t srcId)
Wei Jia53692fa2017-12-11 10:33:46 -08003078{
3079 ALOGV("releaseDrm ");
3080
3081 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
Robert Shih3c3728d2018-12-04 17:06:36 -08003082 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003083
3084 sp<AMessage> response;
3085 status_t status = msg->postAndAwaitResponse(&response);
3086
3087 if (status == OK && response != NULL) {
3088 CHECK(response->findInt32("status", &status));
3089 ALOGV("releaseDrm ret: %d ", status);
3090 } else {
3091 ALOGE("releaseDrm err: %d", status);
3092 }
3093
3094 return status;
3095}
3096
3097status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3098{
3099 // TODO change to ALOGV
3100 ALOGD("onPrepareDrm ");
3101
3102 status_t status = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -07003103 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003104 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3105 return status;
3106 }
3107
3108 uint8_t *uuid;
3109 Vector<uint8_t> *drmSessionId;
3110 CHECK(msg->findPointer("uuid", (void**)&uuid));
3111 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3112
3113 status = OK;
3114 sp<AMediaCryptoWrapper> crypto = NULL;
3115
Wei Jiaf01e3122018-10-18 11:49:44 -07003116 status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003117 if (crypto == NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003118 ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
Wei Jia53692fa2017-12-11 10:33:46 -08003119 return status;
3120 }
Wei Jiaf01e3122018-10-18 11:49:44 -07003121 ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
Wei Jia53692fa2017-12-11 10:33:46 -08003122
3123 if (mCrypto != NULL) {
3124 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3125 mCrypto.clear();
3126 }
3127
3128 mCrypto = crypto;
3129 mIsDrmProtected = true;
3130 // TODO change to ALOGV
3131 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3132
3133 return status;
3134}
3135
3136status_t NuPlayer2::onReleaseDrm()
3137{
3138 // TODO change to ALOGV
3139 ALOGD("onReleaseDrm ");
3140
3141 if (!mIsDrmProtected) {
3142 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3143 }
3144
3145 mIsDrmProtected = false;
3146
3147 status_t status;
3148 if (mCrypto != NULL) {
3149 // notifying the source first before removing crypto from codec
Wei Jiaf01e3122018-10-18 11:49:44 -07003150 if (mCurrentSourceInfo.mSource != NULL) {
3151 mCurrentSourceInfo.mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003152 }
3153
3154 status=OK;
3155 // first making sure the codecs have released their crypto reference
3156 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3157 if (videoDecoder != NULL) {
3158 status = videoDecoder->releaseCrypto();
3159 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3160 }
3161
3162 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3163 if (audioDecoder != NULL) {
3164 status_t status_audio = audioDecoder->releaseCrypto();
3165 if (status == OK) { // otherwise, returning the first error
3166 status = status_audio;
3167 }
3168 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3169 }
3170
3171 // TODO change to ALOGV
3172 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3173 mCrypto.clear();
3174 } else { // mCrypto == NULL
3175 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3176 status = INVALID_OPERATION;
3177 }
3178
3179 return status;
3180}
3181// Modular DRM end
3182////////////////////////////////////////////////////////////////////////////////
3183
3184sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3185 sp<MetaData> meta = getFormatMeta(audio);
3186
3187 if (meta == NULL) {
3188 return NULL;
3189 }
3190
3191 sp<AMessage> msg = new AMessage;
3192
3193 if(convertMetaDataToMessage(meta, &msg) == OK) {
3194 return msg;
3195 }
3196 return NULL;
3197}
3198
3199void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3200 sp<AMessage> notify = dupNotify();
3201 notify->setInt32("what", kWhatFlagsChanged);
3202 notify->setInt32("flags", flags);
3203 notify->post();
3204}
3205
3206void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3207 sp<AMessage> notify = dupNotify();
3208 notify->setInt32("what", kWhatVideoSizeChanged);
3209 notify->setMessage("format", format);
3210 notify->post();
3211}
3212
3213void NuPlayer2::Source::notifyPrepared(status_t err) {
3214 ALOGV("Source::notifyPrepared %d", err);
3215 sp<AMessage> notify = dupNotify();
3216 notify->setInt32("what", kWhatPrepared);
3217 notify->setInt32("err", err);
3218 notify->post();
3219}
3220
3221void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3222{
3223 ALOGV("Source::notifyDrmInfo");
3224
3225 sp<AMessage> notify = dupNotify();
3226 notify->setInt32("what", kWhatDrmInfo);
3227 notify->setBuffer("drmInfo", drmInfoBuffer);
3228
3229 notify->post();
3230}
3231
Wei Jia53692fa2017-12-11 10:33:46 -08003232void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3233 TRESPASS();
3234}
3235
Wei Jiaf01e3122018-10-18 11:49:44 -07003236NuPlayer2::SourceInfo::SourceInfo()
3237 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3238 mSrcId(0),
3239 mSourceFlags(0),
3240 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003241 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003242}
3243
Wei Jiad1864f92018-10-19 12:34:56 -07003244NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3245 mSource = other.mSource;
3246 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3247 mSrcId = other.mSrcId;
3248 mSourceFlags = other.mSourceFlags;
3249 mStartTimeUs = other.mStartTimeUs;
3250 mEndTimeUs = other.mEndTimeUs;
3251 return *this;
3252}
3253
Wei Jia53692fa2017-12-11 10:33:46 -08003254} // namespace android