blob: fef9faecad533b09db15b3b087a282d16a579695 [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 {
828 status_t err = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -0700829 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800830 err = OK;
831
832 int32_t type32;
833 CHECK(msg->findInt32("type", (int32_t*)&type32));
834 media_track_type type = (media_track_type)type32;
Wei Jiaf01e3122018-10-18 11:49:44 -0700835 ssize_t selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800836
Dongwon Kang9f631982018-07-10 12:34:41 -0700837 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800838 CHECK(msg->findPointer("reply", (void**)&reply));
Dongwon Kang9f631982018-07-10 12:34:41 -0700839 reply->add_values()->set_int32_value(selectedTrack);
Wei Jia53692fa2017-12-11 10:33:46 -0800840 }
841
842 sp<AMessage> response = new AMessage;
843 response->setInt32("err", err);
844
845 sp<AReplyToken> replyID;
846 CHECK(msg->senderAwaitsResponse(&replyID));
847 response->postReply(replyID);
848 break;
849 }
850
851 case kWhatSelectTrack:
852 {
853 sp<AReplyToken> replyID;
854 CHECK(msg->senderAwaitsResponse(&replyID));
855
856 size_t trackIndex;
857 int32_t select;
858 int64_t timeUs;
859 CHECK(msg->findSize("trackIndex", &trackIndex));
860 CHECK(msg->findInt32("select", &select));
861 CHECK(msg->findInt64("timeUs", &timeUs));
862
863 status_t err = INVALID_OPERATION;
864
865 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700866 if (mCurrentSourceInfo.mSource != NULL) {
867 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800868 }
869 size_t ccTracks = 0;
870 if (mCCDecoder != NULL) {
871 ccTracks = mCCDecoder->getTrackCount();
872 }
873
874 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700875 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800876
877 if (!select && err == OK) {
878 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700879 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800880 if (info != NULL
881 && info->findInt32("type", &type)
882 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
883 ++mTimedTextGeneration;
884 }
885 }
886 } else {
887 trackIndex -= inbandTracks;
888
889 if (trackIndex < ccTracks) {
890 err = mCCDecoder->selectTrack(trackIndex, select);
891 }
892 }
893
894 sp<AMessage> response = new AMessage;
895 response->setInt32("err", err);
896
897 response->postReply(replyID);
898 break;
899 }
900
901 case kWhatPollDuration:
902 {
903 int32_t generation;
904 CHECK(msg->findInt32("generation", &generation));
905
906 if (generation != mPollDurationGeneration) {
907 // stale
908 break;
909 }
910
911 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700912 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800913 sp<NuPlayer2Driver> driver = mDriver.promote();
914 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700915 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800916 }
917 }
918
919 msg->post(1000000ll); // poll again in a second.
920 break;
921 }
922
923 case kWhatSetVideoSurface:
924 {
925
926 sp<RefBase> obj;
927 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800928 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800929
930 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800931 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700932 (mCurrentSourceInfo.mSource != NULL && mStarted
933 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800934 && mVideoDecoder != NULL) ? "have" : "no");
935
Wei Jiaf01e3122018-10-18 11:49:44 -0700936 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
937 // because NuPlayer2 might be in preparing state and it could take long time.
938 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
939 if (mCurrentSourceInfo.mSource == NULL || !mStarted
940 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800941 // NOTE: mVideoDecoder's mNativeWindow is always non-null
942 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
943 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800944 break;
945 }
946
947 mDeferredActions.push_back(
948 new FlushDecoderAction(
949 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
950 FLUSH_CMD_SHUTDOWN /* video */));
951
Wei Jia28288fb2017-12-15 13:45:29 -0800952 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800953
954 if (obj != NULL) {
955 if (mStarted) {
956 // Issue a seek to refresh the video screen only if started otherwise
957 // the extractor may not yet be started and will assert.
958 // If the video decoder is not set (perhaps audio only in this case)
959 // do not perform a seek as it is not needed.
960 int64_t currentPositionUs = 0;
961 if (getCurrentPosition(&currentPositionUs) == OK) {
962 mDeferredActions.push_back(
963 new SeekAction(currentPositionUs,
964 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
965 }
966 }
967
968 // If there is a new surface texture, instantiate decoders
969 // again if possible.
970 mDeferredActions.push_back(
971 new SimpleAction(&NuPlayer2::performScanSources));
972
973 // After a flush without shutdown, decoder is paused.
974 // Don't resume it until source seek is done, otherwise it could
975 // start pulling stale data too soon.
976 mDeferredActions.push_back(
977 new ResumeDecoderAction(false /* needNotify */));
978 }
979
980 processDeferredActions();
981 break;
982 }
983
984 case kWhatSetAudioSink:
985 {
986 ALOGV("kWhatSetAudioSink");
987
988 sp<RefBase> obj;
989 CHECK(msg->findObject("sink", &obj));
990
Wei Jia33abcc72018-01-30 09:47:38 -0800991 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800992 break;
993 }
994
995 case kWhatStart:
996 {
997 ALOGV("kWhatStart");
998 if (mStarted) {
999 // do not resume yet if the source is still buffering
1000 if (!mPausedForBuffering) {
1001 onResume();
1002 }
1003 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001004 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001005 }
1006 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001007 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001008 break;
1009 }
1010
1011 case kWhatConfigPlayback:
1012 {
1013 sp<AReplyToken> replyID;
1014 CHECK(msg->senderAwaitsResponse(&replyID));
1015 AudioPlaybackRate rate /* sanitized */;
1016 readFromAMessage(msg, &rate);
1017 status_t err = OK;
1018 if (mRenderer != NULL) {
1019 // AudioSink allows only 1.f and 0.f for offload mode.
1020 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001021 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001022 int64_t currentPositionUs;
1023 if (getCurrentPosition(&currentPositionUs) != OK) {
1024 currentPositionUs = mPreviousSeekTimeUs;
1025 }
1026
1027 // Set mPlaybackSettings so that the new audio decoder can
1028 // be created correctly.
1029 mPlaybackSettings = rate;
1030 if (!mPaused) {
1031 mRenderer->pause();
1032 }
1033 restartAudio(
1034 currentPositionUs, true /* forceNonOffload */,
1035 true /* needsToCreateAudioDecoder */);
1036 if (!mPaused) {
1037 mRenderer->resume();
1038 }
1039 }
1040
1041 err = mRenderer->setPlaybackSettings(rate);
1042 }
1043 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001044 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001045
Wei Jia700a7c22018-09-14 18:04:35 -07001046 if (mVideoDecoder != NULL) {
1047 sp<AMessage> params = new AMessage();
1048 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1049 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001050 }
1051 }
1052
Wei Jia53692fa2017-12-11 10:33:46 -08001053 sp<AMessage> response = new AMessage;
1054 response->setInt32("err", err);
1055 response->postReply(replyID);
1056 break;
1057 }
1058
1059 case kWhatGetPlaybackSettings:
1060 {
1061 sp<AReplyToken> replyID;
1062 CHECK(msg->senderAwaitsResponse(&replyID));
1063 AudioPlaybackRate rate = mPlaybackSettings;
1064 status_t err = OK;
1065 if (mRenderer != NULL) {
1066 err = mRenderer->getPlaybackSettings(&rate);
1067 }
1068 if (err == OK) {
1069 // get playback settings used by renderer, as it may be
1070 // slightly off due to audiosink not taking small changes.
1071 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001072 }
1073 sp<AMessage> response = new AMessage;
1074 if (err == OK) {
1075 writeToAMessage(response, rate);
1076 }
1077 response->setInt32("err", err);
1078 response->postReply(replyID);
1079 break;
1080 }
1081
1082 case kWhatConfigSync:
1083 {
1084 sp<AReplyToken> replyID;
1085 CHECK(msg->senderAwaitsResponse(&replyID));
1086
1087 ALOGV("kWhatConfigSync");
1088 AVSyncSettings sync;
1089 float videoFpsHint;
1090 readFromAMessage(msg, &sync, &videoFpsHint);
1091 status_t err = OK;
1092 if (mRenderer != NULL) {
1093 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1094 }
1095 if (err == OK) {
1096 mSyncSettings = sync;
1097 mVideoFpsHint = videoFpsHint;
1098 }
1099 sp<AMessage> response = new AMessage;
1100 response->setInt32("err", err);
1101 response->postReply(replyID);
1102 break;
1103 }
1104
1105 case kWhatGetSyncSettings:
1106 {
1107 sp<AReplyToken> replyID;
1108 CHECK(msg->senderAwaitsResponse(&replyID));
1109 AVSyncSettings sync = mSyncSettings;
1110 float videoFps = mVideoFpsHint;
1111 status_t err = OK;
1112 if (mRenderer != NULL) {
1113 err = mRenderer->getSyncSettings(&sync, &videoFps);
1114 if (err == OK) {
1115 mSyncSettings = sync;
1116 mVideoFpsHint = videoFps;
1117 }
1118 }
1119 sp<AMessage> response = new AMessage;
1120 if (err == OK) {
1121 writeToAMessage(response, sync, videoFps);
1122 }
1123 response->setInt32("err", err);
1124 response->postReply(replyID);
1125 break;
1126 }
1127
1128 case kWhatScanSources:
1129 {
1130 int32_t generation;
1131 CHECK(msg->findInt32("generation", &generation));
1132 if (generation != mScanSourcesGeneration) {
1133 // Drop obsolete msg.
1134 break;
1135 }
1136
1137 mScanSourcesPending = false;
1138
1139 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1140 mAudioDecoder != NULL, mVideoDecoder != NULL);
1141
1142 bool mHadAnySourcesBefore =
1143 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1144 bool rescan = false;
1145
1146 // initialize video before audio because successful initialization of
1147 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001148 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001149 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1150 rescan = true;
1151 }
1152 }
1153
1154 // Don't try to re-open audio sink if there's an existing decoder.
1155 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1156 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1157 rescan = true;
1158 }
1159 }
1160
1161 if (!mHadAnySourcesBefore
1162 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1163 // This is the first time we've found anything playable.
1164
Wei Jiaf01e3122018-10-18 11:49:44 -07001165 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001166 schedulePollDuration();
1167 }
1168 }
1169
1170 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001171 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001172 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1173 // We're not currently decoding anything (no audio or
1174 // video tracks found) and we just ran out of input data.
1175
1176 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001177 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001178 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001179 notifyListener(
1180 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001181 }
1182 }
1183 break;
1184 }
1185
1186 if (rescan) {
1187 msg->post(100000ll);
1188 mScanSourcesPending = true;
1189 }
1190 break;
1191 }
1192
1193 case kWhatVideoNotify:
1194 case kWhatAudioNotify:
1195 {
1196 bool audio = msg->what() == kWhatAudioNotify;
1197
1198 int32_t currentDecoderGeneration =
1199 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1200 int32_t requesterGeneration = currentDecoderGeneration - 1;
1201 CHECK(msg->findInt32("generation", &requesterGeneration));
1202
1203 if (requesterGeneration != currentDecoderGeneration) {
1204 ALOGV("got message from old %s decoder, generation(%d:%d)",
1205 audio ? "audio" : "video", requesterGeneration,
1206 currentDecoderGeneration);
1207 sp<AMessage> reply;
1208 if (!(msg->findMessage("reply", &reply))) {
1209 return;
1210 }
1211
1212 reply->setInt32("err", INFO_DISCONTINUITY);
1213 reply->post();
1214 return;
1215 }
1216
1217 int32_t what;
1218 CHECK(msg->findInt32("what", &what));
1219
1220 if (what == DecoderBase::kWhatInputDiscontinuity) {
1221 int32_t formatChange;
1222 CHECK(msg->findInt32("formatChange", &formatChange));
1223
1224 ALOGV("%s discontinuity: formatChange %d",
1225 audio ? "audio" : "video", formatChange);
1226
1227 if (formatChange) {
1228 mDeferredActions.push_back(
1229 new FlushDecoderAction(
1230 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1231 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1232 }
1233
1234 mDeferredActions.push_back(
1235 new SimpleAction(
1236 &NuPlayer2::performScanSources));
1237
1238 processDeferredActions();
1239 } else if (what == DecoderBase::kWhatEOS) {
1240 int32_t err;
1241 CHECK(msg->findInt32("err", &err));
1242
1243 if (err == ERROR_END_OF_STREAM) {
1244 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1245 } else {
1246 ALOGV("got %s decoder EOS w/ error %d",
1247 audio ? "audio" : "video",
1248 err);
1249 }
1250
1251 mRenderer->queueEOS(audio, err);
1252 } else if (what == DecoderBase::kWhatFlushCompleted) {
1253 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1254
1255 handleFlushComplete(audio, true /* isDecoder */);
1256 finishFlushIfPossible();
1257 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1258 sp<AMessage> format;
1259 CHECK(msg->findMessage("format", &format));
1260
1261 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001262 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001263
1264 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001265 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001266 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1267 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1268 if (audio) {
1269 mAudioDecoder.clear();
1270 mAudioDecoderError = false;
1271 ++mAudioDecoderGeneration;
1272
1273 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1274 mFlushingAudio = SHUT_DOWN;
1275 } else {
1276 mVideoDecoder.clear();
1277 mVideoDecoderError = false;
1278 ++mVideoDecoderGeneration;
1279
1280 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1281 mFlushingVideo = SHUT_DOWN;
1282 }
1283
1284 finishFlushIfPossible();
1285 } else if (what == DecoderBase::kWhatResumeCompleted) {
1286 finishResume();
1287 } else if (what == DecoderBase::kWhatError) {
1288 status_t err;
1289 if (!msg->findInt32("err", &err) || err == OK) {
1290 err = UNKNOWN_ERROR;
1291 }
1292
1293 // Decoder errors can be due to Source (e.g. from streaming),
1294 // or from decoding corrupted bitstreams, or from other decoder
1295 // MediaCodec operations (e.g. from an ongoing reset or seek).
1296 // They may also be due to openAudioSink failure at
1297 // decoder start or after a format change.
1298 //
1299 // We try to gracefully shut down the affected decoder if possible,
1300 // rather than trying to force the shutdown with something
1301 // similar to performReset(). This method can lead to a hang
1302 // if MediaCodec functions block after an error, but they should
1303 // typically return INVALID_OPERATION instead of blocking.
1304
1305 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1306 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1307 err, audio ? "audio" : "video", *flushing);
1308
1309 switch (*flushing) {
1310 case NONE:
1311 mDeferredActions.push_back(
1312 new FlushDecoderAction(
1313 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1314 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1315 processDeferredActions();
1316 break;
1317 case FLUSHING_DECODER:
1318 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1319 break; // Wait for flush to complete.
1320 case FLUSHING_DECODER_SHUTDOWN:
1321 break; // Wait for flush to complete.
1322 case SHUTTING_DOWN_DECODER:
1323 break; // Wait for shutdown to complete.
1324 case FLUSHED:
1325 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1326 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1327 break;
1328 case SHUT_DOWN:
1329 finishFlushIfPossible(); // Should not occur.
1330 break; // Finish anyways.
1331 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001332 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001333 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001334 if (mVideoDecoderError
1335 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1336 || mNativeWindow == NULL
1337 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001338 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001339 // When both audio and video have error, or this stream has only audio
1340 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001341 notifyListener(
1342 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1343 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001344 } else {
1345 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001346 notifyListener(
1347 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1348 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001349 }
1350 mAudioDecoderError = true;
1351 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001352 if (mAudioDecoderError
1353 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001354 || mAudioSink == NULL || mAudioDecoder == NULL) {
1355 // When both audio and video have error, or this stream has only video
1356 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001357 notifyListener(
1358 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1359 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001360 } else {
1361 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001362 notifyListener(
1363 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1364 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001365 }
1366 mVideoDecoderError = true;
1367 }
1368 }
1369 } else {
1370 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1371 what,
1372 what >> 24,
1373 (what >> 16) & 0xff,
1374 (what >> 8) & 0xff,
1375 what & 0xff);
1376 }
1377
1378 break;
1379 }
1380
1381 case kWhatRendererNotify:
1382 {
1383 int32_t requesterGeneration = mRendererGeneration - 1;
1384 CHECK(msg->findInt32("generation", &requesterGeneration));
1385 if (requesterGeneration != mRendererGeneration) {
1386 ALOGV("got message from old renderer, generation(%d:%d)",
1387 requesterGeneration, mRendererGeneration);
1388 return;
1389 }
1390
1391 int32_t what;
1392 CHECK(msg->findInt32("what", &what));
1393
1394 if (what == Renderer::kWhatEOS) {
1395 int32_t audio;
1396 CHECK(msg->findInt32("audio", &audio));
1397
1398 int32_t finalResult;
1399 CHECK(msg->findInt32("finalResult", &finalResult));
1400
1401 if (audio) {
1402 mAudioEOS = true;
1403 } else {
1404 mVideoEOS = true;
1405 }
1406
1407 if (finalResult == ERROR_END_OF_STREAM) {
1408 ALOGV("reached %s EOS", audio ? "audio" : "video");
1409 } else {
1410 ALOGE("%s track encountered an error (%d)",
1411 audio ? "audio" : "video", finalResult);
1412
1413 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001414 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1415 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001416 }
1417
1418 if ((mAudioEOS || mAudioDecoder == NULL)
1419 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001420 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001421 }
1422 } else if (what == Renderer::kWhatFlushComplete) {
1423 int32_t audio;
1424 CHECK(msg->findInt32("audio", &audio));
1425
1426 if (audio) {
1427 mAudioEOS = false;
1428 } else {
1429 mVideoEOS = false;
1430 }
1431
1432 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1433 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1434 || mFlushingAudio == SHUT_DOWN)) {
1435 // Flush has been handled by tear down.
1436 break;
1437 }
1438 handleFlushComplete(audio, false /* isDecoder */);
1439 finishFlushIfPossible();
1440 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001441 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1442 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001443 } else if (what == Renderer::kWhatMediaRenderingStart) {
1444 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001445 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001446 } else if (what == Renderer::kWhatAudioTearDown) {
1447 int32_t reason;
1448 CHECK(msg->findInt32("reason", &reason));
1449 ALOGV("Tear down audio with reason %d.", reason);
1450 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1451 // TimeoutWhenPaused is only for offload mode.
1452 ALOGW("Receive a stale message for teardown.");
1453 break;
1454 }
1455 int64_t positionUs;
1456 if (!msg->findInt64("positionUs", &positionUs)) {
1457 positionUs = mPreviousSeekTimeUs;
1458 }
1459
1460 restartAudio(
1461 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1462 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1463 }
1464 break;
1465 }
1466
1467 case kWhatMoreDataQueued:
1468 {
1469 break;
1470 }
1471
1472 case kWhatReset:
1473 {
1474 ALOGV("kWhatReset");
1475
1476 mResetting = true;
1477 stopPlaybackTimer("kWhatReset");
1478 stopRebufferingTimer(true);
1479
1480 mDeferredActions.push_back(
1481 new FlushDecoderAction(
1482 FLUSH_CMD_SHUTDOWN /* audio */,
1483 FLUSH_CMD_SHUTDOWN /* video */));
1484
1485 mDeferredActions.push_back(
1486 new SimpleAction(&NuPlayer2::performReset));
1487
1488 processDeferredActions();
1489 break;
1490 }
1491
1492 case kWhatNotifyTime:
1493 {
1494 ALOGV("kWhatNotifyTime");
1495 int64_t timerUs;
1496 CHECK(msg->findInt64("timerUs", &timerUs));
1497
Wei Jiaf01e3122018-10-18 11:49:44 -07001498 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001499 break;
1500 }
1501
1502 case kWhatSeek:
1503 {
1504 int64_t seekTimeUs;
1505 int32_t mode;
1506 int32_t needNotify;
1507 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1508 CHECK(msg->findInt32("mode", &mode));
1509 CHECK(msg->findInt32("needNotify", &needNotify));
1510
1511 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1512 (long long)seekTimeUs, mode, needNotify);
1513
1514 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001515 if (!mSourceStarted) {
1516 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001517 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001518 }
Wei Jia083e9092018-02-12 11:46:04 -08001519 if (seekTimeUs > 0) {
1520 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1521 }
1522
Wei Jia53692fa2017-12-11 10:33:46 -08001523 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001524 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001525 }
1526 break;
1527 }
1528
Wei Jia083e9092018-02-12 11:46:04 -08001529 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001530 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001531
Wei Jia53692fa2017-12-11 10:33:46 -08001532 mDeferredActions.push_back(
1533 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1534 FLUSH_CMD_FLUSH /* video */));
1535
1536 mDeferredActions.push_back(
1537 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1538
1539 // After a flush without shutdown, decoder is paused.
1540 // Don't resume it until source seek is done, otherwise it could
1541 // start pulling stale data too soon.
1542 mDeferredActions.push_back(
1543 new ResumeDecoderAction(needNotify));
1544
1545 processDeferredActions();
1546 break;
1547 }
1548
Wei Jiad1864f92018-10-19 12:34:56 -07001549 case kWhatRewind:
1550 {
1551 ALOGV("kWhatRewind");
1552
1553 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1554 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1555
1556 if (!mStarted) {
1557 if (!mSourceStarted) {
1558 mSourceStarted = true;
1559 mCurrentSourceInfo.mSource->start();
1560 }
1561 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1562 break;
1563 }
1564
1565 // seeks can take a while, so we essentially paused
1566 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1567
1568 mDeferredActions.push_back(
1569 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1570 FLUSH_CMD_FLUSH /* video */));
1571
1572 mDeferredActions.push_back(
1573 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1574
1575 // After a flush without shutdown, decoder is paused.
1576 // Don't resume it until source seek is done, otherwise it could
1577 // start pulling stale data too soon.
1578 mDeferredActions.push_back(
1579 new ResumeDecoderAction(false /* needNotify */));
1580
1581 processDeferredActions();
1582 break;
1583 }
1584
Wei Jia53692fa2017-12-11 10:33:46 -08001585 case kWhatPause:
1586 {
Wei Jia6376cd52018-09-26 11:42:55 -07001587 if (!mStarted) {
1588 onStart(false /* play */);
1589 }
Wei Jia53692fa2017-12-11 10:33:46 -08001590 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001591 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001592 mPausedByClient = true;
1593 break;
1594 }
1595
1596 case kWhatSourceNotify:
1597 {
1598 onSourceNotify(msg);
1599 break;
1600 }
1601
1602 case kWhatClosedCaptionNotify:
1603 {
1604 onClosedCaptionNotify(msg);
1605 break;
1606 }
1607
1608 case kWhatPrepareDrm:
1609 {
1610 status_t status = onPrepareDrm(msg);
1611
1612 sp<AMessage> response = new AMessage;
1613 response->setInt32("status", status);
1614 sp<AReplyToken> replyID;
1615 CHECK(msg->senderAwaitsResponse(&replyID));
1616 response->postReply(replyID);
1617 break;
1618 }
1619
1620 case kWhatReleaseDrm:
1621 {
1622 status_t status = onReleaseDrm();
1623
1624 sp<AMessage> response = new AMessage;
1625 response->setInt32("status", status);
1626 sp<AReplyToken> replyID;
1627 CHECK(msg->senderAwaitsResponse(&replyID));
1628 response->postReply(replyID);
1629 break;
1630 }
1631
1632 default:
1633 TRESPASS();
1634 break;
1635 }
1636}
1637
1638void NuPlayer2::onResume() {
1639 if (!mPaused || mResetting) {
1640 ALOGD_IF(mResetting, "resetting, onResume discarded");
1641 return;
1642 }
1643 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001644 if (mCurrentSourceInfo.mSource != NULL) {
1645 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001646 } else {
1647 ALOGW("resume called when source is gone or not set");
1648 }
1649 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1650 // needed.
1651 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1652 instantiateDecoder(true /* audio */, &mAudioDecoder);
1653 }
1654 if (mRenderer != NULL) {
1655 mRenderer->resume();
1656 } else {
1657 ALOGW("resume called when renderer is gone or not set");
1658 }
1659
1660 startPlaybackTimer("onresume");
1661}
1662
Wei Jia6376cd52018-09-26 11:42:55 -07001663void NuPlayer2::onStart(bool play) {
Wei Jia53692fa2017-12-11 10:33:46 -08001664 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1665
1666 if (!mSourceStarted) {
1667 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001668 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001669 }
Wei Jia53692fa2017-12-11 10:33:46 -08001670
1671 mOffloadAudio = false;
1672 mAudioEOS = false;
1673 mVideoEOS = false;
1674 mStarted = true;
1675 mPaused = false;
1676
1677 uint32_t flags = 0;
1678
Wei Jiaf01e3122018-10-18 11:49:44 -07001679 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001680 flags |= Renderer::FLAG_REAL_TIME;
1681 }
1682
Wei Jiaf01e3122018-10-18 11:49:44 -07001683 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1684 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001685 if (!hasAudio && !hasVideo) {
1686 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001687 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001688 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001689 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1690 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001691 return;
1692 }
1693 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1694
Wei Jiaf01e3122018-10-18 11:49:44 -07001695 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001696
1697 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1698 if (mAudioSink != NULL) {
1699 streamType = mAudioSink->getAudioStreamType();
1700 }
1701
1702 mOffloadAudio =
Dongwon Kang946bdb32018-11-14 10:12:00 -08001703 JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
1704 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001705 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1706
1707 // Modular DRM: Disabling audio offload if the source is protected
1708 if (mOffloadAudio && mIsDrmProtected) {
1709 mOffloadAudio = false;
1710 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1711 }
1712
1713 if (mOffloadAudio) {
1714 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1715 }
1716
1717 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1718 ++mRendererGeneration;
1719 notify->setInt32("generation", mRendererGeneration);
1720 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1721 mRendererLooper = new ALooper;
1722 mRendererLooper->setName("NuPlayerRenderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001723 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001724 mRendererLooper->registerHandler(mRenderer);
1725
1726 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1727 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001728 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001729 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001730 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001731 return;
1732 }
1733
1734 float rate = getFrameRate();
1735 if (rate > 0) {
1736 mRenderer->setVideoFrameRate(rate);
1737 }
1738
Wei Jiad1864f92018-10-19 12:34:56 -07001739 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001740 // Renderer is created in paused state.
1741 if (play) {
1742 mRenderer->resume();
1743 }
1744
Wei Jia53692fa2017-12-11 10:33:46 -08001745 if (mVideoDecoder != NULL) {
1746 mVideoDecoder->setRenderer(mRenderer);
1747 }
1748 if (mAudioDecoder != NULL) {
1749 mAudioDecoder->setRenderer(mRenderer);
1750 }
1751
1752 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001753 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001754
1755 postScanSources();
1756}
1757
Wei Jiad1864f92018-10-19 12:34:56 -07001758void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001759 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001760
1761 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1762 return;
1763 }
1764
1765 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001766 msg->setInt32("generation", mEOSMonitorGeneration);
1767 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1768}
1769
Wei Jia53692fa2017-12-11 10:33:46 -08001770void NuPlayer2::startPlaybackTimer(const char *where) {
1771 Mutex::Autolock autoLock(mPlayingTimeLock);
1772 if (mLastStartedPlayingTimeNs == 0) {
1773 mLastStartedPlayingTimeNs = systemTime();
1774 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1775 }
1776}
1777
1778void NuPlayer2::stopPlaybackTimer(const char *where) {
1779 Mutex::Autolock autoLock(mPlayingTimeLock);
1780
1781 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1782
1783 if (mLastStartedPlayingTimeNs != 0) {
1784 sp<NuPlayer2Driver> driver = mDriver.promote();
1785 if (driver != NULL) {
1786 int64_t now = systemTime();
1787 int64_t played = now - mLastStartedPlayingTimeNs;
1788 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1789
1790 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001791 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001792 }
1793 }
1794 mLastStartedPlayingTimeNs = 0;
1795 }
1796}
1797
1798void NuPlayer2::startRebufferingTimer() {
1799 Mutex::Autolock autoLock(mPlayingTimeLock);
1800 if (mLastStartedRebufferingTimeNs == 0) {
1801 mLastStartedRebufferingTimeNs = systemTime();
1802 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1803 }
1804}
1805
1806void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1807 Mutex::Autolock autoLock(mPlayingTimeLock);
1808
Wei Jiaf01e3122018-10-18 11:49:44 -07001809 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1810 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001811
1812 if (mLastStartedRebufferingTimeNs != 0) {
1813 sp<NuPlayer2Driver> driver = mDriver.promote();
1814 if (driver != NULL) {
1815 int64_t now = systemTime();
1816 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1817 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1818
1819 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001820 driver->notifyMoreRebufferingTimeUs(
1821 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001822 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001823 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001824 }
1825 }
1826 }
1827 mLastStartedRebufferingTimeNs = 0;
1828 }
1829}
1830
1831void NuPlayer2::onPause() {
1832
1833 stopPlaybackTimer("onPause");
1834
1835 if (mPaused) {
1836 return;
1837 }
1838 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001839 if (mCurrentSourceInfo.mSource != NULL) {
1840 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001841 } else {
1842 ALOGW("pause called when source is gone or not set");
1843 }
1844 if (mRenderer != NULL) {
1845 mRenderer->pause();
1846 } else {
1847 ALOGW("pause called when renderer is gone or not set");
1848 }
1849
1850}
1851
1852bool NuPlayer2::audioDecoderStillNeeded() {
1853 // Audio decoder is no longer needed if it's in shut/shutting down status.
1854 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1855}
1856
1857void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1858 // We wait for both the decoder flush and the renderer flush to complete
1859 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1860
1861 mFlushComplete[audio][isDecoder] = true;
1862 if (!mFlushComplete[audio][!isDecoder]) {
1863 return;
1864 }
1865
1866 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1867 switch (*state) {
1868 case FLUSHING_DECODER:
1869 {
1870 *state = FLUSHED;
1871 break;
1872 }
1873
1874 case FLUSHING_DECODER_SHUTDOWN:
1875 {
1876 *state = SHUTTING_DOWN_DECODER;
1877
1878 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1879 getDecoder(audio)->initiateShutdown();
1880 break;
1881 }
1882
1883 default:
1884 // decoder flush completes only occur in a flushing state.
1885 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1886 break;
1887 }
1888}
1889
1890void NuPlayer2::finishFlushIfPossible() {
1891 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1892 && mFlushingAudio != SHUT_DOWN) {
1893 return;
1894 }
1895
1896 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1897 && mFlushingVideo != SHUT_DOWN) {
1898 return;
1899 }
1900
1901 ALOGV("both audio and video are flushed now.");
1902
1903 mFlushingAudio = NONE;
1904 mFlushingVideo = NONE;
1905
1906 clearFlushComplete();
1907
1908 processDeferredActions();
1909}
1910
1911void NuPlayer2::postScanSources() {
1912 if (mScanSourcesPending) {
1913 return;
1914 }
1915
1916 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1917 msg->setInt32("generation", mScanSourcesGeneration);
1918 msg->post();
1919
1920 mScanSourcesPending = true;
1921}
1922
1923void NuPlayer2::tryOpenAudioSinkForOffload(
1924 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1925 // Note: This is called early in NuPlayer2 to determine whether offloading
1926 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1927
1928 status_t err = mRenderer->openAudioSink(
1929 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001930 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001931 if (err != OK) {
1932 // Any failure we turn off mOffloadAudio.
1933 mOffloadAudio = false;
1934 } else if (mOffloadAudio) {
1935 sendMetaDataToHal(mAudioSink, audioMeta);
1936 }
1937}
1938
1939void NuPlayer2::closeAudioSink() {
1940 mRenderer->closeAudioSink();
1941}
1942
1943void NuPlayer2::restartAudio(
1944 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1945 if (mAudioDecoder != NULL) {
1946 mAudioDecoder->pause();
1947 mAudioDecoder.clear();
1948 mAudioDecoderError = false;
1949 ++mAudioDecoderGeneration;
1950 }
1951 if (mFlushingAudio == FLUSHING_DECODER) {
1952 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1953 mFlushingAudio = FLUSHED;
1954 finishFlushIfPossible();
1955 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1956 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1957 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1958 mFlushingAudio = SHUT_DOWN;
1959 finishFlushIfPossible();
1960 needsToCreateAudioDecoder = false;
1961 }
1962 if (mRenderer == NULL) {
1963 return;
1964 }
1965 closeAudioSink();
1966 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1967 if (mVideoDecoder != NULL) {
1968 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1969 }
1970
1971 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1972
1973 if (forceNonOffload) {
1974 mRenderer->signalDisableOffloadAudio();
1975 mOffloadAudio = false;
1976 }
1977 if (needsToCreateAudioDecoder) {
1978 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1979 }
1980}
1981
1982void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001983 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001984 return;
1985 }
1986
1987 if (mRenderer == NULL) {
1988 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1989 mOffloadAudio = false;
1990 return;
1991 }
1992
Wei Jiaf01e3122018-10-18 11:49:44 -07001993 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
1994 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001995 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1996 const bool hasVideo = (videoFormat != NULL);
1997 bool canOffload = canOffloadStream(
Wei Jiaf01e3122018-10-18 11:49:44 -07001998 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001999 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2000
2001 // Modular DRM: Disabling audio offload if the source is protected
2002 if (canOffload && mIsDrmProtected) {
2003 canOffload = false;
2004 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2005 }
2006
2007 if (canOffload) {
2008 if (!mOffloadAudio) {
2009 mRenderer->signalEnableOffloadAudio();
2010 }
2011 // open audio sink early under offload mode.
2012 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2013 } else {
2014 if (mOffloadAudio) {
2015 mRenderer->signalDisableOffloadAudio();
2016 mOffloadAudio = false;
2017 }
2018 }
2019}
2020
2021status_t NuPlayer2::instantiateDecoder(
2022 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2023 // The audio decoder could be cleared by tear down. If still in shut down
2024 // process, no need to create a new audio decoder.
2025 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2026 return OK;
2027 }
2028
Wei Jiaf01e3122018-10-18 11:49:44 -07002029 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002030
2031 if (format == NULL) {
2032 return UNKNOWN_ERROR;
2033 } else {
2034 status_t err;
2035 if (format->findInt32("err", &err) && err) {
2036 return err;
2037 }
2038 }
2039
2040 format->setInt32("priority", 0 /* realtime */);
2041
2042 if (!audio) {
2043 AString mime;
2044 CHECK(format->findString("mime", &mime));
2045
2046 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2047 if (mCCDecoder == NULL) {
2048 mCCDecoder = new CCDecoder(ccNotify);
2049 }
2050
Wei Jiaf01e3122018-10-18 11:49:44 -07002051 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002052 format->setInt32("secure", true);
2053 }
2054
Wei Jiaf01e3122018-10-18 11:49:44 -07002055 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002056 format->setInt32("protected", true);
2057 }
2058
2059 float rate = getFrameRate();
2060 if (rate > 0) {
2061 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2062 }
2063 }
2064
2065 if (audio) {
2066 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2067 ++mAudioDecoderGeneration;
2068 notify->setInt32("generation", mAudioDecoderGeneration);
2069
2070 if (checkAudioModeChange) {
2071 determineAudioModeChange(format);
2072 }
2073 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002074 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002075
Wei Jiaf01e3122018-10-18 11:49:44 -07002076 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002077 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002078 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002079 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2080 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002081 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002082
Wei Jiaf01e3122018-10-18 11:49:44 -07002083 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002084 ALOGV("instantiateDecoder audio Decoder");
2085 }
2086 mAudioDecoderError = false;
2087 } else {
2088 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2089 ++mVideoDecoderGeneration;
2090 notify->setInt32("generation", mVideoDecoderGeneration);
2091
2092 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002093 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2094 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002095 mVideoDecoderError = false;
2096
2097 // enable FRC if high-quality AV sync is requested, even if not
2098 // directly queuing to display, as this will even improve textureview
2099 // playback.
2100 {
2101 if (property_get_bool("persist.sys.media.avsync", false)) {
2102 format->setInt32("auto-frc", 1);
2103 }
2104 }
2105 }
2106 (*decoder)->init();
2107
2108 // Modular DRM
2109 if (mIsDrmProtected) {
2110 format->setObject("crypto", mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002111 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
2112 mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002113 }
2114
2115 (*decoder)->configure(format);
2116
2117 if (!audio) {
2118 sp<AMessage> params = new AMessage();
2119 float rate = getFrameRate();
2120 if (rate > 0) {
2121 params->setFloat("frame-rate-total", rate);
2122 }
2123
2124 sp<MetaData> fileMeta = getFileMeta();
2125 if (fileMeta != NULL) {
2126 int32_t videoTemporalLayerCount;
2127 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2128 && videoTemporalLayerCount > 0) {
2129 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2130 }
2131 }
2132
2133 if (params->countEntries() > 0) {
2134 (*decoder)->setParameters(params);
2135 }
2136 }
2137 return OK;
2138}
2139
2140void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002141 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002142 const sp<AMessage> &inputFormat,
2143 const sp<AMessage> &outputFormat) {
2144 if (inputFormat == NULL) {
2145 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002146 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002147 return;
2148 }
2149 int32_t err = OK;
2150 inputFormat->findInt32("err", &err);
2151 if (err == -EWOULDBLOCK) {
2152 ALOGW("Video meta is not available yet!");
2153 return;
2154 }
2155 if (err != OK) {
2156 ALOGW("Something is wrong with video meta!");
2157 return;
2158 }
2159
2160 int32_t displayWidth, displayHeight;
2161 if (outputFormat != NULL) {
2162 int32_t width, height;
2163 CHECK(outputFormat->findInt32("width", &width));
2164 CHECK(outputFormat->findInt32("height", &height));
2165
2166 int32_t cropLeft, cropTop, cropRight, cropBottom;
2167 CHECK(outputFormat->findRect(
2168 "crop",
2169 &cropLeft, &cropTop, &cropRight, &cropBottom));
2170
2171 displayWidth = cropRight - cropLeft + 1;
2172 displayHeight = cropBottom - cropTop + 1;
2173
2174 ALOGV("Video output format changed to %d x %d "
2175 "(crop: %d x %d @ (%d, %d))",
2176 width, height,
2177 displayWidth,
2178 displayHeight,
2179 cropLeft, cropTop);
2180 } else {
2181 CHECK(inputFormat->findInt32("width", &displayWidth));
2182 CHECK(inputFormat->findInt32("height", &displayHeight));
2183
2184 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2185 }
2186
2187 // Take into account sample aspect ratio if necessary:
2188 int32_t sarWidth, sarHeight;
2189 if (inputFormat->findInt32("sar-width", &sarWidth)
2190 && inputFormat->findInt32("sar-height", &sarHeight)
2191 && sarWidth > 0 && sarHeight > 0) {
2192 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2193
2194 displayWidth = (displayWidth * sarWidth) / sarHeight;
2195
2196 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2197 } else {
2198 int32_t width, height;
2199 if (inputFormat->findInt32("display-width", &width)
2200 && inputFormat->findInt32("display-height", &height)
2201 && width > 0 && height > 0
2202 && displayWidth > 0 && displayHeight > 0) {
2203 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2204 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2205 } else {
2206 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2207 }
2208 ALOGV("Video display width and height are overridden to %d x %d",
2209 displayWidth, displayHeight);
2210 }
2211 }
2212
2213 int32_t rotationDegrees;
2214 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2215 rotationDegrees = 0;
2216 }
2217
2218 if (rotationDegrees == 90 || rotationDegrees == 270) {
2219 int32_t tmp = displayWidth;
2220 displayWidth = displayHeight;
2221 displayHeight = tmp;
2222 }
2223
2224 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002225 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002226 MEDIA2_SET_VIDEO_SIZE,
2227 displayWidth,
2228 displayHeight);
2229}
2230
Dongwon Kang41929fb2018-09-09 08:29:56 -07002231void NuPlayer2::notifyListener(
2232 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002233 if (mDriver == NULL) {
2234 return;
2235 }
2236
2237 sp<NuPlayer2Driver> driver = mDriver.promote();
2238
2239 if (driver == NULL) {
2240 return;
2241 }
2242
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002243 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002244}
2245
2246void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2247 ALOGV("[%s] flushDecoder needShutdown=%d",
2248 audio ? "audio" : "video", needShutdown);
2249
2250 const sp<DecoderBase> &decoder = getDecoder(audio);
2251 if (decoder == NULL) {
2252 ALOGI("flushDecoder %s without decoder present",
2253 audio ? "audio" : "video");
2254 return;
2255 }
2256
2257 // Make sure we don't continue to scan sources until we finish flushing.
2258 ++mScanSourcesGeneration;
2259 if (mScanSourcesPending) {
2260 if (!needShutdown) {
2261 mDeferredActions.push_back(
2262 new SimpleAction(&NuPlayer2::performScanSources));
2263 }
2264 mScanSourcesPending = false;
2265 }
2266
2267 decoder->signalFlush();
2268
2269 FlushStatus newStatus =
2270 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2271
2272 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2273 mFlushComplete[audio][true /* isDecoder */] = false;
2274 if (audio) {
2275 ALOGE_IF(mFlushingAudio != NONE,
2276 "audio flushDecoder() is called in state %d", mFlushingAudio);
2277 mFlushingAudio = newStatus;
2278 } else {
2279 ALOGE_IF(mFlushingVideo != NONE,
2280 "video flushDecoder() is called in state %d", mFlushingVideo);
2281 mFlushingVideo = newStatus;
2282 }
2283}
2284
2285void NuPlayer2::queueDecoderShutdown(
2286 bool audio, bool video, const sp<AMessage> &reply) {
2287 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2288
2289 mDeferredActions.push_back(
2290 new FlushDecoderAction(
2291 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2292 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2293
2294 mDeferredActions.push_back(
2295 new SimpleAction(&NuPlayer2::performScanSources));
2296
2297 mDeferredActions.push_back(new PostMessageAction(reply));
2298
2299 processDeferredActions();
2300}
2301
2302status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2303 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002304 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2305 status_t ret = native_window_set_scaling_mode(
2306 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002307 if (ret != OK) {
2308 ALOGE("Failed to set scaling mode (%d): %s",
2309 -ret, strerror(-ret));
2310 return ret;
2311 }
2312 }
2313 return OK;
2314}
2315
Dongwon Kang9f631982018-07-10 12:34:41 -07002316status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002317 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2318 msg->setPointer("reply", reply);
2319
2320 sp<AMessage> response;
2321 status_t err = msg->postAndAwaitResponse(&response);
2322 return err;
2323}
2324
Dongwon Kang9f631982018-07-10 12:34:41 -07002325status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002326 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2327 msg->setPointer("reply", reply);
2328 msg->setInt32("type", type);
2329
2330 sp<AMessage> response;
2331 status_t err = msg->postAndAwaitResponse(&response);
2332 if (err == OK && response != NULL) {
2333 CHECK(response->findInt32("err", &err));
2334 }
2335 return err;
2336}
2337
2338status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2339 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2340 msg->setSize("trackIndex", trackIndex);
2341 msg->setInt32("select", select);
2342 msg->setInt64("timeUs", timeUs);
2343
2344 sp<AMessage> response;
2345 status_t err = msg->postAndAwaitResponse(&response);
2346
2347 if (err != OK) {
2348 return err;
2349 }
2350
2351 if (!response->findInt32("err", &err)) {
2352 err = OK;
2353 }
2354
2355 return err;
2356}
2357
2358status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2359 sp<Renderer> renderer = mRenderer;
2360 if (renderer == NULL) {
2361 return NO_INIT;
2362 }
2363
2364 return renderer->getCurrentPosition(mediaUs);
2365}
2366
2367void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2368 CHECK(mTrackStats != NULL);
2369
2370 mTrackStats->clear();
2371 if (mVideoDecoder != NULL) {
2372 mTrackStats->push_back(mVideoDecoder->getStats());
2373 }
2374 if (mAudioDecoder != NULL) {
2375 mTrackStats->push_back(mAudioDecoder->getStats());
2376 }
2377}
2378
2379sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002380 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002381}
2382
2383float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002384 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002385 if (meta == NULL) {
2386 return 0;
2387 }
2388 int32_t rate;
2389 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2390 // fall back to try file meta
2391 sp<MetaData> fileMeta = getFileMeta();
2392 if (fileMeta == NULL) {
2393 ALOGW("source has video meta but not file meta");
2394 return -1;
2395 }
2396 int32_t fileMetaRate;
2397 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2398 return -1;
2399 }
2400 return fileMetaRate;
2401 }
2402 return rate;
2403}
2404
2405void NuPlayer2::schedulePollDuration() {
2406 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2407 msg->setInt32("generation", mPollDurationGeneration);
2408 msg->post();
2409}
2410
2411void NuPlayer2::cancelPollDuration() {
2412 ++mPollDurationGeneration;
2413}
2414
2415void NuPlayer2::processDeferredActions() {
2416 while (!mDeferredActions.empty()) {
2417 // We won't execute any deferred actions until we're no longer in
2418 // an intermediate state, i.e. one more more decoders are currently
2419 // flushing or shutting down.
2420
2421 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2422 // We're currently flushing, postpone the reset until that's
2423 // completed.
2424
2425 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2426 mFlushingAudio, mFlushingVideo);
2427
2428 break;
2429 }
2430
2431 sp<Action> action = *mDeferredActions.begin();
2432 mDeferredActions.erase(mDeferredActions.begin());
2433
2434 action->execute(this);
2435 }
2436}
2437
2438void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2439 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2440 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2441
Wei Jiaf01e3122018-10-18 11:49:44 -07002442 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002443 // This happens when reset occurs right before the loop mode
2444 // asynchronously seeks to the start of the stream.
2445 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002446 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002447 mAudioDecoder.get(), mVideoDecoder.get());
2448 return;
2449 }
2450 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002451 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002452 ++mTimedTextGeneration;
2453
2454 // everything's flushed, continue playback.
2455}
2456
2457void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2458 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2459
2460 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2461 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2462 return;
2463 }
2464
2465 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2466 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2467 }
2468
2469 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2470 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2471 }
2472}
2473
2474void NuPlayer2::performReset() {
2475 ALOGV("performReset");
2476
2477 CHECK(mAudioDecoder == NULL);
2478 CHECK(mVideoDecoder == NULL);
2479
2480 stopPlaybackTimer("performReset");
2481 stopRebufferingTimer(true);
2482
2483 cancelPollDuration();
2484
2485 ++mScanSourcesGeneration;
2486 mScanSourcesPending = false;
2487
2488 if (mRendererLooper != NULL) {
2489 if (mRenderer != NULL) {
2490 mRendererLooper->unregisterHandler(mRenderer->id());
2491 }
2492 mRendererLooper->stop();
2493 mRendererLooper.clear();
2494 }
2495 mRenderer.clear();
2496 ++mRendererGeneration;
2497
Wei Jiaf01e3122018-10-18 11:49:44 -07002498 if (mCurrentSourceInfo.mSource != NULL) {
2499 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08002500
2501 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002502 mCurrentSourceInfo.mSource.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08002503 }
2504
2505 if (mDriver != NULL) {
2506 sp<NuPlayer2Driver> driver = mDriver.promote();
2507 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002508 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002509 }
2510 }
2511
2512 mStarted = false;
2513 mPrepared = false;
2514 mResetting = false;
2515 mSourceStarted = false;
2516
2517 // Modular DRM
2518 if (mCrypto != NULL) {
2519 // decoders will be flushed before this so their mCrypto would go away on their own
2520 // TODO change to ALOGV
2521 ALOGD("performReset mCrypto: %p", mCrypto.get());
2522 mCrypto.clear();
2523 }
2524 mIsDrmProtected = false;
2525}
2526
Wei Jia57aeffd2018-02-15 16:01:14 -08002527void NuPlayer2::performPlayNextDataSource() {
2528 ALOGV("performPlayNextDataSource");
2529
2530 CHECK(mAudioDecoder == NULL);
2531 CHECK(mVideoDecoder == NULL);
2532
2533 stopPlaybackTimer("performPlayNextDataSource");
2534 stopRebufferingTimer(true);
2535
2536 cancelPollDuration();
2537
2538 ++mScanSourcesGeneration;
2539 mScanSourcesPending = false;
2540
2541 ++mRendererGeneration;
2542
Wei Jiaf01e3122018-10-18 11:49:44 -07002543 if (mCurrentSourceInfo.mSource != NULL) {
2544 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002545 }
2546
2547 long previousSrcId;
2548 {
2549 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002550 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002551
2552 mCurrentSourceInfo = mNextSourceInfo;
2553 mNextSourceInfo = SourceInfo();
2554 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002555 }
2556
2557 if (mDriver != NULL) {
2558 sp<NuPlayer2Driver> driver = mDriver.promote();
2559 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002560 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002561
2562 int64_t durationUs;
2563 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2564 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2565 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002566 notifyListener(
2567 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002568 }
2569 }
2570
2571 mStarted = false;
2572 mPrepared = true; // TODO: what if it's not prepared
2573 mResetting = false;
2574 mSourceStarted = false;
2575
Wei Jiad1864f92018-10-19 12:34:56 -07002576 addEndTimeMonitor();
2577
Wei Jia57aeffd2018-02-15 16:01:14 -08002578 // Modular DRM
2579 if (mCrypto != NULL) {
2580 // decoders will be flushed before this so their mCrypto would go away on their own
2581 // TODO change to ALOGV
2582 ALOGD("performReset mCrypto: %p", mCrypto.get());
2583 mCrypto.clear();
2584 }
2585 mIsDrmProtected = false;
2586
2587 if (mRenderer != NULL) {
2588 mRenderer->resume();
2589 }
2590
Wei Jia6376cd52018-09-26 11:42:55 -07002591 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002592 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002593 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002594}
2595
Wei Jia53692fa2017-12-11 10:33:46 -08002596void NuPlayer2::performScanSources() {
2597 ALOGV("performScanSources");
2598
2599 if (!mStarted) {
2600 return;
2601 }
2602
2603 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2604 postScanSources();
2605 }
2606}
2607
Wei Jia28288fb2017-12-15 13:45:29 -08002608void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002609 ALOGV("performSetSurface");
2610
Wei Jia28288fb2017-12-15 13:45:29 -08002611 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002612
2613 // XXX - ignore error from setVideoScalingMode for now
2614 setVideoScalingMode(mVideoScalingMode);
2615
2616 if (mDriver != NULL) {
2617 sp<NuPlayer2Driver> driver = mDriver.promote();
2618 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002619 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002620 }
2621 }
2622}
2623
2624void NuPlayer2::performResumeDecoders(bool needNotify) {
2625 if (needNotify) {
2626 mResumePending = true;
2627 if (mVideoDecoder == NULL) {
2628 // if audio-only, we can notify seek complete now,
2629 // as the resume operation will be relatively fast.
2630 finishResume();
2631 }
2632 }
2633
2634 if (mVideoDecoder != NULL) {
2635 // When there is continuous seek, MediaPlayer will cache the seek
2636 // position, and send down new seek request when previous seek is
2637 // complete. Let's wait for at least one video output frame before
2638 // notifying seek complete, so that the video thumbnail gets updated
2639 // when seekbar is dragged.
2640 mVideoDecoder->signalResume(needNotify);
2641 }
2642
2643 if (mAudioDecoder != NULL) {
2644 mAudioDecoder->signalResume(false /* needNotify */);
2645 }
2646}
2647
2648void NuPlayer2::finishResume() {
2649 if (mResumePending) {
2650 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002651 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002652 }
2653}
2654
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002655void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002656 if (mDriver != NULL) {
2657 sp<NuPlayer2Driver> driver = mDriver.promote();
2658 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002659 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002660 }
2661 }
2662}
2663
2664void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2665 int32_t what;
2666 CHECK(msg->findInt32("what", &what));
2667
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002668 int64_t srcId;
2669 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002670 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002671 case Source::kWhatPrepared:
2672 {
Wei Jiad1864f92018-10-19 12:34:56 -07002673 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2674 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2675 if (srcId == mCurrentSourceInfo.mSrcId) {
2676 if (mCurrentSourceInfo.mSource == NULL) {
2677 // This is a stale notification from a source that was
2678 // asynchronously preparing when the client called reset().
2679 // We handled the reset, the source is gone.
2680 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002681 }
Wei Jiad1864f92018-10-19 12:34:56 -07002682
2683 int32_t err;
2684 CHECK(msg->findInt32("err", &err));
2685
2686 if (err != OK) {
2687 // shut down potential secure codecs in case client never calls reset
2688 mDeferredActions.push_back(
2689 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2690 FLUSH_CMD_SHUTDOWN /* video */));
2691 processDeferredActions();
2692 } else {
2693 mPrepared = true;
2694 }
2695
2696 sp<NuPlayer2Driver> driver = mDriver.promote();
2697 if (driver != NULL) {
2698 // notify duration first, so that it's definitely set when
2699 // the app received the "prepare complete" callback.
2700 int64_t durationUs;
2701 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2702 driver->notifyDuration(srcId, durationUs);
2703 }
2704 driver->notifyPrepareCompleted(srcId, err);
2705 }
2706 } else if (srcId == mNextSourceInfo.mSrcId) {
2707 if (mNextSourceInfo.mSource == NULL) {
2708 break; // stale
2709 }
2710
2711 sp<NuPlayer2Driver> driver = mDriver.promote();
2712 if (driver != NULL) {
2713 int32_t err;
2714 CHECK(msg->findInt32("err", &err));
2715 driver->notifyPrepareCompleted(srcId, err);
2716 }
Wei Jia53692fa2017-12-11 10:33:46 -08002717 }
2718
2719 break;
2720 }
2721
2722 // Modular DRM
2723 case Source::kWhatDrmInfo:
2724 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002725 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002726 sp<ABuffer> drmInfo;
2727 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002728 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002729
Dongwon Kang41929fb2018-09-09 08:29:56 -07002730 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2731 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002732
Dongwon Kang41929fb2018-09-09 08:29:56 -07002733 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002734
2735 break;
2736 }
2737
2738 case Source::kWhatFlagsChanged:
2739 {
2740 uint32_t flags;
2741 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2742
2743 sp<NuPlayer2Driver> driver = mDriver.promote();
2744 if (driver != NULL) {
2745
2746 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2747 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2748 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2749 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2750 (flags & Source::FLAG_CAN_PAUSE) != 0,
2751 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2752 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2753 (flags & Source::FLAG_CAN_SEEK) != 0,
2754 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2755 (flags & Source::FLAG_SECURE) != 0,
2756 (flags & Source::FLAG_PROTECTED) != 0);
2757
2758 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2759 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002760 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002761 }
Wei Jiad1864f92018-10-19 12:34:56 -07002762 if (srcId == mCurrentSourceInfo.mSrcId) {
2763 driver->notifyFlagsChanged(srcId, flags);
2764 }
Wei Jia53692fa2017-12-11 10:33:46 -08002765 }
2766
Wei Jiaf01e3122018-10-18 11:49:44 -07002767 if (srcId == mCurrentSourceInfo.mSrcId) {
2768 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2769 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2770 cancelPollDuration();
2771 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2772 && (flags & Source::FLAG_DYNAMIC_DURATION)
2773 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2774 schedulePollDuration();
2775 }
Wei Jia53692fa2017-12-11 10:33:46 -08002776
Wei Jiaf01e3122018-10-18 11:49:44 -07002777 mCurrentSourceInfo.mSourceFlags = flags;
2778 } else if (srcId == mNextSourceInfo.mSrcId) {
2779 // TODO: handle duration polling for next source.
2780 mNextSourceInfo.mSourceFlags = flags;
2781 }
Wei Jia53692fa2017-12-11 10:33:46 -08002782 break;
2783 }
2784
2785 case Source::kWhatVideoSizeChanged:
2786 {
2787 sp<AMessage> format;
2788 CHECK(msg->findMessage("format", &format));
2789
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002790 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002791 break;
2792 }
2793
2794 case Source::kWhatBufferingUpdate:
2795 {
2796 int32_t percentage;
2797 CHECK(msg->findInt32("percentage", &percentage));
2798
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002799 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002800 break;
2801 }
2802
2803 case Source::kWhatPauseOnBufferingStart:
2804 {
2805 // ignore if not playing
2806 if (mStarted) {
2807 ALOGI("buffer low, pausing...");
2808
2809 startRebufferingTimer();
2810 mPausedForBuffering = true;
2811 onPause();
2812 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002813 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002814 break;
2815 }
2816
2817 case Source::kWhatResumeOnBufferingEnd:
2818 {
2819 // ignore if not playing
2820 if (mStarted) {
2821 ALOGI("buffer ready, resuming...");
2822
2823 stopRebufferingTimer(false);
2824 mPausedForBuffering = false;
2825
2826 // do not resume yet if client didn't unpause
2827 if (!mPausedByClient) {
2828 onResume();
2829 }
2830 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002831 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002832 break;
2833 }
2834
2835 case Source::kWhatCacheStats:
2836 {
2837 int32_t kbps;
2838 CHECK(msg->findInt32("bandwidth", &kbps));
2839
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002840 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002841 break;
2842 }
2843
2844 case Source::kWhatSubtitleData:
2845 {
2846 sp<ABuffer> buffer;
2847 CHECK(msg->findBuffer("buffer", &buffer));
2848
2849 sendSubtitleData(buffer, 0 /* baseIndex */);
2850 break;
2851 }
2852
2853 case Source::kWhatTimedMetaData:
2854 {
2855 sp<ABuffer> buffer;
2856 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002857 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002858 } else {
2859 sendTimedMetaData(buffer);
2860 }
2861 break;
2862 }
2863
2864 case Source::kWhatTimedTextData:
2865 {
2866 int32_t generation;
2867 if (msg->findInt32("generation", &generation)
2868 && generation != mTimedTextGeneration) {
2869 break;
2870 }
2871
2872 sp<ABuffer> buffer;
2873 CHECK(msg->findBuffer("buffer", &buffer));
2874
2875 sp<NuPlayer2Driver> driver = mDriver.promote();
2876 if (driver == NULL) {
2877 break;
2878 }
2879
Wei Jia800fe372018-02-20 15:00:45 -08002880 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002881 int64_t timeUs, posUs;
2882 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002883 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002884 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2885
2886 if (posUs < timeUs) {
2887 if (!msg->findInt32("generation", &generation)) {
2888 msg->setInt32("generation", mTimedTextGeneration);
2889 }
2890 msg->post(timeUs - posUs);
2891 } else {
2892 sendTimedTextData(buffer);
2893 }
2894 break;
2895 }
2896
2897 case Source::kWhatQueueDecoderShutdown:
2898 {
2899 int32_t audio, video;
2900 CHECK(msg->findInt32("audio", &audio));
2901 CHECK(msg->findInt32("video", &video));
2902
2903 sp<AMessage> reply;
2904 CHECK(msg->findMessage("reply", &reply));
2905
2906 queueDecoderShutdown(audio, video, reply);
2907 break;
2908 }
2909
2910 case Source::kWhatDrmNoLicense:
2911 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002912 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002913 break;
2914 }
2915
2916 default:
2917 TRESPASS();
2918 }
2919}
2920
2921void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2922 int32_t what;
2923 CHECK(msg->findInt32("what", &what));
2924
2925 switch (what) {
2926 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2927 {
2928 sp<ABuffer> buffer;
2929 CHECK(msg->findBuffer("buffer", &buffer));
2930
2931 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002932 if (mCurrentSourceInfo.mSource != NULL) {
2933 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002934 }
2935
2936 sendSubtitleData(buffer, inbandTracks);
2937 break;
2938 }
2939
2940 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2941 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002942 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002943
2944 break;
2945 }
2946
2947 default:
2948 TRESPASS();
2949 }
2950
2951
2952}
2953
2954void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2955 int32_t trackIndex;
2956 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002957 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002958 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2959 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2960
Dongwon Kang41929fb2018-09-09 08:29:56 -07002961 PlayerMessage playerMsg;
2962 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2963 playerMsg.add_values()->set_int64_value(timeUs);
2964 playerMsg.add_values()->set_int64_value(durationUs);
2965 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002966
Wei Jiaf01e3122018-10-18 11:49:44 -07002967 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002968}
2969
2970void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2971 int64_t timeUs;
2972 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2973
Dongwon Kang41929fb2018-09-09 08:29:56 -07002974 PlayerMessage playerMsg;
2975 playerMsg.add_values()->set_int64_value(timeUs);
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_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002979}
2980
2981void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2982 const void *data;
2983 size_t size = 0;
2984 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002985 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002986
2987 AString mime;
2988 CHECK(buffer->meta()->findString("mime", &mime));
2989 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2990
2991 data = buffer->data();
2992 size = buffer->size();
2993
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002994 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002995 if (size > 0) {
2996 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2997 int32_t global = 0;
2998 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002999 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003000 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003001 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003002 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003003 TextDescriptions2::getPlayerMessageOfDescriptions(
3004 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003005 }
3006
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003007 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003008 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003009 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003010 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003011 }
3012}
3013
3014const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003015 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003016 case DATA_SOURCE_TYPE_HTTP_LIVE:
3017 return "HTTPLive";
3018
3019 case DATA_SOURCE_TYPE_RTSP:
3020 return "RTSP";
3021
3022 case DATA_SOURCE_TYPE_GENERIC_URL:
3023 return "GenURL";
3024
3025 case DATA_SOURCE_TYPE_GENERIC_FD:
3026 return "GenFD";
3027
3028 case DATA_SOURCE_TYPE_MEDIA:
3029 return "Media";
3030
Wei Jia53692fa2017-12-11 10:33:46 -08003031 case DATA_SOURCE_TYPE_NONE:
3032 default:
3033 return "None";
3034 }
3035 }
3036
3037// Modular DRM begin
3038status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3039{
3040 ALOGV("prepareDrm ");
3041
3042 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3043 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3044 // synchronous call so just passing the address but with local copies of "const" args
3045 uint8_t UUID[16];
3046 memcpy(UUID, uuid, sizeof(UUID));
3047 Vector<uint8_t> sessionId = drmSessionId;
3048 msg->setPointer("uuid", (void*)UUID);
3049 msg->setPointer("drmSessionId", (void*)&sessionId);
3050
3051 sp<AMessage> response;
3052 status_t status = msg->postAndAwaitResponse(&response);
3053
3054 if (status == OK && response != NULL) {
3055 CHECK(response->findInt32("status", &status));
3056 ALOGV("prepareDrm ret: %d ", status);
3057 } else {
3058 ALOGE("prepareDrm err: %d", status);
3059 }
3060
3061 return status;
3062}
3063
3064status_t NuPlayer2::releaseDrm()
3065{
3066 ALOGV("releaseDrm ");
3067
3068 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3069
3070 sp<AMessage> response;
3071 status_t status = msg->postAndAwaitResponse(&response);
3072
3073 if (status == OK && response != NULL) {
3074 CHECK(response->findInt32("status", &status));
3075 ALOGV("releaseDrm ret: %d ", status);
3076 } else {
3077 ALOGE("releaseDrm err: %d", status);
3078 }
3079
3080 return status;
3081}
3082
3083status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3084{
3085 // TODO change to ALOGV
3086 ALOGD("onPrepareDrm ");
3087
3088 status_t status = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -07003089 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003090 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3091 return status;
3092 }
3093
3094 uint8_t *uuid;
3095 Vector<uint8_t> *drmSessionId;
3096 CHECK(msg->findPointer("uuid", (void**)&uuid));
3097 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3098
3099 status = OK;
3100 sp<AMediaCryptoWrapper> crypto = NULL;
3101
Wei Jiaf01e3122018-10-18 11:49:44 -07003102 status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003103 if (crypto == NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003104 ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
Wei Jia53692fa2017-12-11 10:33:46 -08003105 return status;
3106 }
Wei Jiaf01e3122018-10-18 11:49:44 -07003107 ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
Wei Jia53692fa2017-12-11 10:33:46 -08003108
3109 if (mCrypto != NULL) {
3110 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3111 mCrypto.clear();
3112 }
3113
3114 mCrypto = crypto;
3115 mIsDrmProtected = true;
3116 // TODO change to ALOGV
3117 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3118
3119 return status;
3120}
3121
3122status_t NuPlayer2::onReleaseDrm()
3123{
3124 // TODO change to ALOGV
3125 ALOGD("onReleaseDrm ");
3126
3127 if (!mIsDrmProtected) {
3128 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3129 }
3130
3131 mIsDrmProtected = false;
3132
3133 status_t status;
3134 if (mCrypto != NULL) {
3135 // notifying the source first before removing crypto from codec
Wei Jiaf01e3122018-10-18 11:49:44 -07003136 if (mCurrentSourceInfo.mSource != NULL) {
3137 mCurrentSourceInfo.mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003138 }
3139
3140 status=OK;
3141 // first making sure the codecs have released their crypto reference
3142 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3143 if (videoDecoder != NULL) {
3144 status = videoDecoder->releaseCrypto();
3145 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3146 }
3147
3148 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3149 if (audioDecoder != NULL) {
3150 status_t status_audio = audioDecoder->releaseCrypto();
3151 if (status == OK) { // otherwise, returning the first error
3152 status = status_audio;
3153 }
3154 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3155 }
3156
3157 // TODO change to ALOGV
3158 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3159 mCrypto.clear();
3160 } else { // mCrypto == NULL
3161 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3162 status = INVALID_OPERATION;
3163 }
3164
3165 return status;
3166}
3167// Modular DRM end
3168////////////////////////////////////////////////////////////////////////////////
3169
3170sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3171 sp<MetaData> meta = getFormatMeta(audio);
3172
3173 if (meta == NULL) {
3174 return NULL;
3175 }
3176
3177 sp<AMessage> msg = new AMessage;
3178
3179 if(convertMetaDataToMessage(meta, &msg) == OK) {
3180 return msg;
3181 }
3182 return NULL;
3183}
3184
3185void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3186 sp<AMessage> notify = dupNotify();
3187 notify->setInt32("what", kWhatFlagsChanged);
3188 notify->setInt32("flags", flags);
3189 notify->post();
3190}
3191
3192void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3193 sp<AMessage> notify = dupNotify();
3194 notify->setInt32("what", kWhatVideoSizeChanged);
3195 notify->setMessage("format", format);
3196 notify->post();
3197}
3198
3199void NuPlayer2::Source::notifyPrepared(status_t err) {
3200 ALOGV("Source::notifyPrepared %d", err);
3201 sp<AMessage> notify = dupNotify();
3202 notify->setInt32("what", kWhatPrepared);
3203 notify->setInt32("err", err);
3204 notify->post();
3205}
3206
3207void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3208{
3209 ALOGV("Source::notifyDrmInfo");
3210
3211 sp<AMessage> notify = dupNotify();
3212 notify->setInt32("what", kWhatDrmInfo);
3213 notify->setBuffer("drmInfo", drmInfoBuffer);
3214
3215 notify->post();
3216}
3217
Wei Jia53692fa2017-12-11 10:33:46 -08003218void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3219 TRESPASS();
3220}
3221
Wei Jiaf01e3122018-10-18 11:49:44 -07003222NuPlayer2::SourceInfo::SourceInfo()
3223 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3224 mSrcId(0),
3225 mSourceFlags(0),
3226 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003227 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003228}
3229
Wei Jiad1864f92018-10-19 12:34:56 -07003230NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3231 mSource = other.mSource;
3232 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3233 mSrcId = other.mSrcId;
3234 mSourceFlags = other.mSourceFlags;
3235 mStartTimeUs = other.mStartTimeUs;
3236 mEndTimeUs = other.mEndTimeUs;
3237 return *this;
3238}
3239
Wei Jia53692fa2017-12-11 10:33:46 -08003240} // namespace android