blob: c37460ba02d789f91efe108f2bcf5fd6623b9174 [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"
Wei Jia53692fa2017-12-11 10:33:46 -080027#include "NuPlayer2CCDecoder.h"
28#include "NuPlayer2Decoder.h"
29#include "NuPlayer2DecoderBase.h"
30#include "NuPlayer2DecoderPassThrough.h"
31#include "NuPlayer2Driver.h"
32#include "NuPlayer2Renderer.h"
33#include "NuPlayer2Source.h"
Wei Jia2409c872018-02-02 10:34:33 -080034#include "RTSPSource2.h"
35#include "GenericSource2.h"
Dongwon Kanga0e816a2018-09-10 19:46:49 -070036#include "TextDescriptions2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080037
38#include "ATSParser.h"
39
40#include <cutils/properties.h>
41
42#include <media/AudioParameter.h>
43#include <media/AudioResamplerPublic.h>
44#include <media/AVSyncSettings.h>
Wei Jiac2636032018-02-01 09:15:25 -080045#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080046#include <media/MediaCodecBuffer.h>
Wei Jia28288fb2017-12-15 13:45:29 -080047#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080048
49#include <media/stagefright/foundation/hexdump.h>
50#include <media/stagefright/foundation/ABuffer.h>
51#include <media/stagefright/foundation/ADebug.h>
52#include <media/stagefright/foundation/AMessage.h>
53#include <media/stagefright/foundation/avc_utils.h>
54#include <media/stagefright/MediaBuffer.h>
55#include <media/stagefright/MediaClock.h>
56#include <media/stagefright/MediaDefs.h>
57#include <media/stagefright/MediaErrors.h>
58#include <media/stagefright/MetaData.h>
59
Wei Jia53692fa2017-12-11 10:33:46 -080060#include "ESDS.h"
61#include <media/stagefright/Utils.h>
62
Wei Jia28288fb2017-12-15 13:45:29 -080063#include <system/window.h>
64
Wei Jia53692fa2017-12-11 10:33:46 -080065namespace android {
66
Wei Jia33abcc72018-01-30 09:47:38 -080067static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
Wei Jia53692fa2017-12-11 10:33:46 -080068 const sp<MetaData>& meta) {
69 int32_t sampleRate = 0;
70 int32_t bitRate = 0;
71 int32_t channelMask = 0;
72 int32_t delaySamples = 0;
73 int32_t paddingSamples = 0;
74
75 AudioParameter param = AudioParameter();
76
77 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
78 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
79 }
80 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
81 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
82 }
83 if (meta->findInt32(kKeyBitRate, &bitRate)) {
84 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
85 }
86 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
87 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
88 }
89 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
90 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
91 }
92
93 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
94 "delaySample %d, paddingSample %d", bitRate, sampleRate,
95 channelMask, delaySamples, paddingSamples);
96
97 sink->setParameters(param.toString());
98 return OK;
99}
100
101
102struct NuPlayer2::Action : public RefBase {
103 Action() {}
104
105 virtual void execute(NuPlayer2 *player) = 0;
106
107private:
108 DISALLOW_EVIL_CONSTRUCTORS(Action);
109};
110
111struct NuPlayer2::SeekAction : public Action {
112 explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
113 : mSeekTimeUs(seekTimeUs),
114 mMode(mode) {
115 }
116
117 virtual void execute(NuPlayer2 *player) {
118 player->performSeek(mSeekTimeUs, mMode);
119 }
120
121private:
122 int64_t mSeekTimeUs;
123 MediaPlayer2SeekMode mMode;
124
125 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
126};
127
128struct NuPlayer2::ResumeDecoderAction : public Action {
129 explicit ResumeDecoderAction(bool needNotify)
130 : mNeedNotify(needNotify) {
131 }
132
133 virtual void execute(NuPlayer2 *player) {
134 player->performResumeDecoders(mNeedNotify);
135 }
136
137private:
138 bool mNeedNotify;
139
140 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
141};
142
143struct NuPlayer2::SetSurfaceAction : public Action {
Wei Jia28288fb2017-12-15 13:45:29 -0800144 explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
145 : mNativeWindow(nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800146 }
147
148 virtual void execute(NuPlayer2 *player) {
Wei Jia28288fb2017-12-15 13:45:29 -0800149 player->performSetSurface(mNativeWindow);
Wei Jia53692fa2017-12-11 10:33:46 -0800150 }
151
152private:
Wei Jia28288fb2017-12-15 13:45:29 -0800153 sp<ANativeWindowWrapper> mNativeWindow;
Wei Jia53692fa2017-12-11 10:33:46 -0800154
155 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
156};
157
158struct NuPlayer2::FlushDecoderAction : public Action {
159 FlushDecoderAction(FlushCommand audio, FlushCommand video)
160 : mAudio(audio),
161 mVideo(video) {
162 }
163
164 virtual void execute(NuPlayer2 *player) {
165 player->performDecoderFlush(mAudio, mVideo);
166 }
167
168private:
169 FlushCommand mAudio;
170 FlushCommand mVideo;
171
172 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
173};
174
175struct NuPlayer2::PostMessageAction : public Action {
176 explicit PostMessageAction(const sp<AMessage> &msg)
177 : mMessage(msg) {
178 }
179
180 virtual void execute(NuPlayer2 *) {
181 mMessage->post();
182 }
183
184private:
185 sp<AMessage> mMessage;
186
187 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
188};
189
190// Use this if there's no state necessary to save in order to execute
191// the action.
192struct NuPlayer2::SimpleAction : public Action {
193 typedef void (NuPlayer2::*ActionFunc)();
194
195 explicit SimpleAction(ActionFunc func)
196 : mFunc(func) {
197 }
198
199 virtual void execute(NuPlayer2 *player) {
200 (player->*mFunc)();
201 }
202
203private:
204 ActionFunc mFunc;
205
206 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
207};
208
209////////////////////////////////////////////////////////////////////////////////
210
Wei Jia003fdb52018-02-06 14:44:32 -0800211NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
212 : mPID(pid),
213 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800214 mMediaClock(mediaClock),
Wei Jia53692fa2017-12-11 10:33:46 -0800215 mOffloadAudio(false),
216 mAudioDecoderGeneration(0),
217 mVideoDecoderGeneration(0),
218 mRendererGeneration(0),
Wei Jiad1864f92018-10-19 12:34:56 -0700219 mEOSMonitorGeneration(0),
Wei Jia53692fa2017-12-11 10:33:46 -0800220 mLastStartedPlayingTimeNs(0),
221 mPreviousSeekTimeUs(0),
222 mAudioEOS(false),
223 mVideoEOS(false),
224 mScanSourcesPending(false),
225 mScanSourcesGeneration(0),
226 mPollDurationGeneration(0),
227 mTimedTextGeneration(0),
228 mFlushingAudio(NONE),
229 mFlushingVideo(NONE),
230 mResumePending(false),
231 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
232 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
233 mVideoFpsHint(-1.f),
234 mStarted(false),
235 mPrepared(false),
236 mResetting(false),
237 mSourceStarted(false),
238 mAudioDecoderError(false),
239 mVideoDecoderError(false),
240 mPaused(false),
241 mPausedByClient(true),
242 mPausedForBuffering(false),
Wei Jiaf01e3122018-10-18 11:49:44 -0700243 mIsDrmProtected(false) {
Wei Jia53692fa2017-12-11 10:33:46 -0800244 CHECK(mediaClock != NULL);
245 clearFlushComplete();
246}
247
248NuPlayer2::~NuPlayer2() {
249}
250
Wei Jia53692fa2017-12-11 10:33:46 -0800251void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
252 mDriver = driver;
253}
254
Wei Jia53692fa2017-12-11 10:33:46 -0800255static bool IsHTTPLiveURL(const char *url) {
256 if (!strncasecmp("http://", url, 7)
257 || !strncasecmp("https://", url, 8)
258 || !strncasecmp("file://", url, 7)) {
259 size_t len = strlen(url);
260 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
261 return true;
262 }
263
264 if (strstr(url,"m3u8")) {
265 return true;
266 }
267 }
268
269 return false;
270}
271
Wei Jia72bf2a02018-02-06 15:29:23 -0800272status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
273 sp<Source> *source,
274 DATA_SOURCE_TYPE *dataSourceType) {
275 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800276 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800277 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800278
Wei Jiac2636032018-02-01 09:15:25 -0800279 switch (dsd->mType) {
280 case DataSourceDesc::TYPE_URL:
281 {
282 const char *url = dsd->mUrl.c_str();
283 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800284
Wei Jiac2636032018-02-01 09:15:25 -0800285 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
286 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800287
Wei Jiac2636032018-02-01 09:15:25 -0800288 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800289 *source = new HTTPLiveSource2(notify, httpService, url, headers);
290 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
291 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800292 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800293 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800294 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800295 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
296 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800297 } else if ((!strncasecmp(url, "http://", 7)
298 || !strncasecmp(url, "https://", 8))
299 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
300 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800301 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800302 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800303 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
304 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800305 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800306 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800307
Wei Jia2409c872018-02-02 10:34:33 -0800308 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800309 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800310
Robert Shih49fb89d2018-01-31 17:53:19 -0800311 err = genericSource->setDataSource(url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800312
313 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800314 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800315 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800316 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800317 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800318 }
319
320 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800321 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800322 }
323 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800324 }
325
Wei Jiac2636032018-02-01 09:15:25 -0800326 case DataSourceDesc::TYPE_FD:
327 {
Wei Jia2409c872018-02-02 10:34:33 -0800328 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800329 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800330
Wei Jia72bf2a02018-02-06 15:29:23 -0800331 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
332 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
333 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800334
Wei Jia72bf2a02018-02-06 15:29:23 -0800335 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800336
Wei Jiac2636032018-02-01 09:15:25 -0800337 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800338 ALOGE("Failed to create NuPlayer2Source!");
339 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800340 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800341 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800342 }
Wei Jia53692fa2017-12-11 10:33:46 -0800343
Wei Jia72bf2a02018-02-06 15:29:23 -0800344 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800345 break;
346 }
Wei Jia53692fa2017-12-11 10:33:46 -0800347
Wei Jiac2636032018-02-01 09:15:25 -0800348 case DataSourceDesc::TYPE_CALLBACK:
349 {
Wei Jia2409c872018-02-02 10:34:33 -0800350 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800351 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800352 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800353
Wei Jiac2636032018-02-01 09:15:25 -0800354 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800355 ALOGE("Failed to create NuPlayer2Source!");
356 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800357 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800358 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800359 }
360
Wei Jia72bf2a02018-02-06 15:29:23 -0800361 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800362 break;
363 }
364
365 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800366 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800367 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800368 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800369 ALOGE("invalid data source type!");
370 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800371 }
372
Wei Jia72bf2a02018-02-06 15:29:23 -0800373 return err;
374}
375
376void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
377 DATA_SOURCE_TYPE dataSourceType;
378 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800379 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800380
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800381 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
382 // and expects notifySetDataSourceCompleted regardless of success or failure.
383 // This will be changed since setDataSource should be asynchronous at JAVA level.
384 // When it succeeds, app will get onInfo notification. Otherwise, onError
385 // will be called.
386 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800387 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800388 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800389 return;
390 }
391
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800392 // Now, source != NULL.
393 */
394
Wei Jiaf01e3122018-10-18 11:49:44 -0700395 mCurrentSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800396
397 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800398 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800399 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700400 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
401 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia72bf2a02018-02-06 15:29:23 -0800402 msg->post();
403}
404
405void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
406 DATA_SOURCE_TYPE dataSourceType;
407 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800408 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800409
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800410 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800411 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800412 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800413 return;
414 }
415
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800416 // Now, source != NULL.
417 */
418
Wei Jiaf01e3122018-10-18 11:49:44 -0700419 mNextSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800420
421 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
422 msg->setObject("source", source);
423 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700424 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
425 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia53692fa2017-12-11 10:33:46 -0800426 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800427}
428
Wei Jia57aeffd2018-02-15 16:01:14 -0800429void NuPlayer2::playNextDataSource(int64_t srcId) {
430 disconnectSource();
431
432 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
433 msg->setInt64("srcId", srcId);
434 msg->post();
435}
436
Wei Jia53692fa2017-12-11 10:33:46 -0800437status_t NuPlayer2::getBufferingSettings(
438 BufferingSettings *buffering /* nonnull */) {
439 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
440 sp<AMessage> response;
441 status_t err = msg->postAndAwaitResponse(&response);
442 if (err == OK && response != NULL) {
443 CHECK(response->findInt32("err", &err));
444 if (err == OK) {
445 readFromAMessage(response, buffering);
446 }
447 }
448 return err;
449}
450
451status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
452 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
453 writeToAMessage(msg, buffering);
454 sp<AMessage> response;
455 status_t err = msg->postAndAwaitResponse(&response);
456 if (err == OK && response != NULL) {
457 CHECK(response->findInt32("err", &err));
458 }
459 return err;
460}
461
462void NuPlayer2::prepareAsync() {
463 ALOGV("prepareAsync");
464
465 (new AMessage(kWhatPrepare, this))->post();
466}
467
Wei Jia28288fb2017-12-15 13:45:29 -0800468void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800469 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
470
Wei Jia28288fb2017-12-15 13:45:29 -0800471 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800472 msg->setObject("surface", NULL);
473 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800474 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800475 }
476
477 msg->post();
478}
479
Wei Jia33abcc72018-01-30 09:47:38 -0800480void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800481 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
482 msg->setObject("sink", sink);
483 msg->post();
484}
485
486void NuPlayer2::start() {
487 (new AMessage(kWhatStart, this))->post();
488}
489
490status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
491 // do some cursory validation of the settings here. audio modes are
492 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700493 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800494 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
495 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
496 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
497 return BAD_VALUE;
498 }
499 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
500 writeToAMessage(msg, rate);
501 sp<AMessage> response;
502 status_t err = msg->postAndAwaitResponse(&response);
503 if (err == OK && response != NULL) {
504 CHECK(response->findInt32("err", &err));
505 }
506 return err;
507}
508
509status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
510 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
511 sp<AMessage> response;
512 status_t err = msg->postAndAwaitResponse(&response);
513 if (err == OK && response != NULL) {
514 CHECK(response->findInt32("err", &err));
515 if (err == OK) {
516 readFromAMessage(response, rate);
517 }
518 }
519 return err;
520}
521
522status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
523 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
524 writeToAMessage(msg, sync, videoFpsHint);
525 sp<AMessage> response;
526 status_t err = msg->postAndAwaitResponse(&response);
527 if (err == OK && response != NULL) {
528 CHECK(response->findInt32("err", &err));
529 }
530 return err;
531}
532
533status_t NuPlayer2::getSyncSettings(
534 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
535 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
536 sp<AMessage> response;
537 status_t err = msg->postAndAwaitResponse(&response);
538 if (err == OK && response != NULL) {
539 CHECK(response->findInt32("err", &err));
540 if (err == OK) {
541 readFromAMessage(response, sync, videoFps);
542 }
543 }
544 return err;
545}
546
547void NuPlayer2::pause() {
548 (new AMessage(kWhatPause, this))->post();
549}
550
551void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800552 disconnectSource();
553 (new AMessage(kWhatReset, this))->post();
554}
555
556void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800557 sp<Source> source;
558 {
559 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700560 source = mCurrentSourceInfo.mSource;
Wei Jia53692fa2017-12-11 10:33:46 -0800561 }
562
563 if (source != NULL) {
564 // During a reset, the data source might be unresponsive already, we need to
565 // disconnect explicitly so that reads exit promptly.
566 // We can't queue the disconnect request to the looper, as it might be
567 // queued behind a stuck read and never gets processed.
568 // Doing a disconnect outside the looper to allows the pending reads to exit
569 // (either successfully or with error).
570 source->disconnect();
571 }
572
Wei Jia53692fa2017-12-11 10:33:46 -0800573}
574
575status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
576 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
577 notify->setInt64("timerUs", mediaTimeUs);
578 mMediaClock->addTimer(notify, mediaTimeUs);
579 return OK;
580}
581
582void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
583 sp<AMessage> msg = new AMessage(kWhatSeek, this);
584 msg->setInt64("seekTimeUs", seekTimeUs);
585 msg->setInt32("mode", mode);
586 msg->setInt32("needNotify", needNotify);
587 msg->post();
588}
589
Wei Jiad1864f92018-10-19 12:34:56 -0700590void NuPlayer2::rewind() {
591 sp<AMessage> msg = new AMessage(kWhatRewind, this);
592 msg->post();
593}
594
Wei Jia53692fa2017-12-11 10:33:46 -0800595void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700596 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800597 if (format == NULL) {
598 ALOGE("NULL format");
599 return;
600 }
601 int32_t trackType;
602 if (!format->findInt32("type", &trackType)) {
603 ALOGE("no track type");
604 return;
605 }
606
607 AString mime;
608 if (!format->findString("mime", &mime)) {
609 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
610 // If we can't find the mimetype here it means that we wouldn't be needing
611 // the mimetype on the Java end. We still write a placeholder mime to keep the
612 // (de)serialization logic simple.
613 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
614 mime = "audio/";
615 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
616 mime = "video/";
617 } else {
618 ALOGE("unknown track type: %d", trackType);
619 return;
620 }
621 }
622
623 AString lang;
624 if (!format->findString("language", &lang)) {
625 ALOGE("no language");
626 return;
627 }
628
Dongwon Kang9f631982018-07-10 12:34:41 -0700629 reply->add_values()->set_int32_value(trackType);
630 reply->add_values()->set_string_value(mime.c_str());
631 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800632
633 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
634 int32_t isAuto, isDefault, isForced;
635 CHECK(format->findInt32("auto", &isAuto));
636 CHECK(format->findInt32("default", &isDefault));
637 CHECK(format->findInt32("forced", &isForced));
638
Dongwon Kang9f631982018-07-10 12:34:41 -0700639 reply->add_values()->set_int32_value(isAuto);
640 reply->add_values()->set_int32_value(isDefault);
641 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800642 }
643}
644
645void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
Dichen Zhangf8726912018-10-17 13:31:26 -0700646
Wei Jia53692fa2017-12-11 10:33:46 -0800647 switch (msg->what()) {
648 case kWhatSetDataSource:
649 {
650 ALOGV("kWhatSetDataSource");
651
Wei Jiaf01e3122018-10-18 11:49:44 -0700652 CHECK(mCurrentSourceInfo.mSource == NULL);
Wei Jia53692fa2017-12-11 10:33:46 -0800653
654 status_t err = OK;
655 sp<RefBase> obj;
656 CHECK(msg->findObject("source", &obj));
657 if (obj != NULL) {
658 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700659 CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
660 CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
661 CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
662 mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800663 } else {
664 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800665 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800666 }
667
668 CHECK(mDriver != NULL);
669 sp<NuPlayer2Driver> driver = mDriver.promote();
670 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700671 driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800672 }
673 break;
674 }
675
Wei Jia72bf2a02018-02-06 15:29:23 -0800676 case kWhatPrepareNextDataSource:
677 {
678 ALOGV("kWhatPrepareNextDataSource");
679
680 status_t err = OK;
681 sp<RefBase> obj;
682 CHECK(msg->findObject("source", &obj));
683 if (obj != NULL) {
684 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700685 CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
686 CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
687 CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
688 mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
689 mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
Wei Jia72bf2a02018-02-06 15:29:23 -0800690 } else {
691 err = UNKNOWN_ERROR;
692 }
693
694 break;
695 }
696
Wei Jia57aeffd2018-02-15 16:01:14 -0800697 case kWhatPlayNextDataSource:
698 {
699 ALOGV("kWhatPlayNextDataSource");
700 int64_t srcId;
701 CHECK(msg->findInt64("srcId", &srcId));
Wei Jiaf01e3122018-10-18 11:49:44 -0700702 if (srcId != mNextSourceInfo.mSrcId) {
Wei Jia57aeffd2018-02-15 16:01:14 -0800703 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
704 return;
705 }
706
707 mResetting = true;
708 stopPlaybackTimer("kWhatPlayNextDataSource");
709 stopRebufferingTimer(true);
710
711 mDeferredActions.push_back(
712 new FlushDecoderAction(
713 FLUSH_CMD_SHUTDOWN /* audio */,
714 FLUSH_CMD_SHUTDOWN /* video */));
715
716 mDeferredActions.push_back(
717 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
718
719 processDeferredActions();
720 break;
721 }
722
Wei Jiad1864f92018-10-19 12:34:56 -0700723 case kWhatEOSMonitor:
724 {
725 int32_t generation;
726 CHECK(msg->findInt32("generation", &generation));
727 int32_t reason;
728 CHECK(msg->findInt32("reason", &reason));
729
730 if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
731 break; // stale or reset
732 }
733
734 ALOGV("kWhatEOSMonitor");
735 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
736 break;
737 }
738
Wei Jia53692fa2017-12-11 10:33:46 -0800739 case kWhatGetBufferingSettings:
740 {
741 sp<AReplyToken> replyID;
742 CHECK(msg->senderAwaitsResponse(&replyID));
743
744 ALOGV("kWhatGetBufferingSettings");
745 BufferingSettings buffering;
746 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700747 if (mCurrentSourceInfo.mSource != NULL) {
748 err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800749 } else {
750 err = INVALID_OPERATION;
751 }
752 sp<AMessage> response = new AMessage;
753 if (err == OK) {
754 writeToAMessage(response, buffering);
755 }
756 response->setInt32("err", err);
757 response->postReply(replyID);
758 break;
759 }
760
761 case kWhatSetBufferingSettings:
762 {
763 sp<AReplyToken> replyID;
764 CHECK(msg->senderAwaitsResponse(&replyID));
765
766 ALOGV("kWhatSetBufferingSettings");
767 BufferingSettings buffering;
768 readFromAMessage(msg, &buffering);
769 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700770 if (mCurrentSourceInfo.mSource != NULL) {
771 err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800772 } else {
773 err = INVALID_OPERATION;
774 }
775 sp<AMessage> response = new AMessage;
776 response->setInt32("err", err);
777 response->postReply(replyID);
778 break;
779 }
780
781 case kWhatPrepare:
782 {
783 ALOGV("onMessageReceived kWhatPrepare");
784
Wei Jiaf01e3122018-10-18 11:49:44 -0700785 mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800786 break;
787 }
788
789 case kWhatGetTrackInfo:
790 {
791 sp<AReplyToken> replyID;
792 CHECK(msg->senderAwaitsResponse(&replyID));
793
Dongwon Kang9f631982018-07-10 12:34:41 -0700794 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800795 CHECK(msg->findPointer("reply", (void**)&reply));
796
797 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700798 if (mCurrentSourceInfo.mSource != NULL) {
799 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800800 }
801
802 size_t ccTracks = 0;
803 if (mCCDecoder != NULL) {
804 ccTracks = mCCDecoder->getTrackCount();
805 }
806
807 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700808 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800809
810 // write inband tracks
811 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700812 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800813 }
814
815 // write CC track
816 for (size_t i = 0; i < ccTracks; ++i) {
817 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
818 }
819
820 sp<AMessage> response = new AMessage;
821 response->postReply(replyID);
822 break;
823 }
824
825 case kWhatGetSelectedTrack:
826 {
827 status_t err = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -0700828 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800829 err = OK;
830
831 int32_t type32;
832 CHECK(msg->findInt32("type", (int32_t*)&type32));
833 media_track_type type = (media_track_type)type32;
Wei Jiaf01e3122018-10-18 11:49:44 -0700834 ssize_t selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800835
Dongwon Kang9f631982018-07-10 12:34:41 -0700836 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800837 CHECK(msg->findPointer("reply", (void**)&reply));
Dongwon Kang9f631982018-07-10 12:34:41 -0700838 reply->add_values()->set_int32_value(selectedTrack);
Wei Jia53692fa2017-12-11 10:33:46 -0800839 }
840
841 sp<AMessage> response = new AMessage;
842 response->setInt32("err", err);
843
844 sp<AReplyToken> replyID;
845 CHECK(msg->senderAwaitsResponse(&replyID));
846 response->postReply(replyID);
847 break;
848 }
849
850 case kWhatSelectTrack:
851 {
852 sp<AReplyToken> replyID;
853 CHECK(msg->senderAwaitsResponse(&replyID));
854
855 size_t trackIndex;
856 int32_t select;
857 int64_t timeUs;
858 CHECK(msg->findSize("trackIndex", &trackIndex));
859 CHECK(msg->findInt32("select", &select));
860 CHECK(msg->findInt64("timeUs", &timeUs));
861
862 status_t err = INVALID_OPERATION;
863
864 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700865 if (mCurrentSourceInfo.mSource != NULL) {
866 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800867 }
868 size_t ccTracks = 0;
869 if (mCCDecoder != NULL) {
870 ccTracks = mCCDecoder->getTrackCount();
871 }
872
873 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700874 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800875
876 if (!select && err == OK) {
877 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700878 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800879 if (info != NULL
880 && info->findInt32("type", &type)
881 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
882 ++mTimedTextGeneration;
883 }
884 }
885 } else {
886 trackIndex -= inbandTracks;
887
888 if (trackIndex < ccTracks) {
889 err = mCCDecoder->selectTrack(trackIndex, select);
890 }
891 }
892
893 sp<AMessage> response = new AMessage;
894 response->setInt32("err", err);
895
896 response->postReply(replyID);
897 break;
898 }
899
900 case kWhatPollDuration:
901 {
902 int32_t generation;
903 CHECK(msg->findInt32("generation", &generation));
904
905 if (generation != mPollDurationGeneration) {
906 // stale
907 break;
908 }
909
910 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700911 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800912 sp<NuPlayer2Driver> driver = mDriver.promote();
913 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700914 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800915 }
916 }
917
918 msg->post(1000000ll); // poll again in a second.
919 break;
920 }
921
922 case kWhatSetVideoSurface:
923 {
924
925 sp<RefBase> obj;
926 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800927 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800928
929 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800930 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700931 (mCurrentSourceInfo.mSource != NULL && mStarted
932 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800933 && mVideoDecoder != NULL) ? "have" : "no");
934
Wei Jiaf01e3122018-10-18 11:49:44 -0700935 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
936 // because NuPlayer2 might be in preparing state and it could take long time.
937 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
938 if (mCurrentSourceInfo.mSource == NULL || !mStarted
939 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800940 // NOTE: mVideoDecoder's mNativeWindow is always non-null
941 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
942 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800943 break;
944 }
945
946 mDeferredActions.push_back(
947 new FlushDecoderAction(
948 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
949 FLUSH_CMD_SHUTDOWN /* video */));
950
Wei Jia28288fb2017-12-15 13:45:29 -0800951 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800952
953 if (obj != NULL) {
954 if (mStarted) {
955 // Issue a seek to refresh the video screen only if started otherwise
956 // the extractor may not yet be started and will assert.
957 // If the video decoder is not set (perhaps audio only in this case)
958 // do not perform a seek as it is not needed.
959 int64_t currentPositionUs = 0;
960 if (getCurrentPosition(&currentPositionUs) == OK) {
961 mDeferredActions.push_back(
962 new SeekAction(currentPositionUs,
963 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
964 }
965 }
966
967 // If there is a new surface texture, instantiate decoders
968 // again if possible.
969 mDeferredActions.push_back(
970 new SimpleAction(&NuPlayer2::performScanSources));
971
972 // After a flush without shutdown, decoder is paused.
973 // Don't resume it until source seek is done, otherwise it could
974 // start pulling stale data too soon.
975 mDeferredActions.push_back(
976 new ResumeDecoderAction(false /* needNotify */));
977 }
978
979 processDeferredActions();
980 break;
981 }
982
983 case kWhatSetAudioSink:
984 {
985 ALOGV("kWhatSetAudioSink");
986
987 sp<RefBase> obj;
988 CHECK(msg->findObject("sink", &obj));
989
Wei Jia33abcc72018-01-30 09:47:38 -0800990 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800991 break;
992 }
993
994 case kWhatStart:
995 {
996 ALOGV("kWhatStart");
997 if (mStarted) {
998 // do not resume yet if the source is still buffering
999 if (!mPausedForBuffering) {
1000 onResume();
1001 }
1002 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001003 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001004 }
1005 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001006 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001007 break;
1008 }
1009
1010 case kWhatConfigPlayback:
1011 {
1012 sp<AReplyToken> replyID;
1013 CHECK(msg->senderAwaitsResponse(&replyID));
1014 AudioPlaybackRate rate /* sanitized */;
1015 readFromAMessage(msg, &rate);
1016 status_t err = OK;
1017 if (mRenderer != NULL) {
1018 // AudioSink allows only 1.f and 0.f for offload mode.
1019 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001020 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001021 int64_t currentPositionUs;
1022 if (getCurrentPosition(&currentPositionUs) != OK) {
1023 currentPositionUs = mPreviousSeekTimeUs;
1024 }
1025
1026 // Set mPlaybackSettings so that the new audio decoder can
1027 // be created correctly.
1028 mPlaybackSettings = rate;
1029 if (!mPaused) {
1030 mRenderer->pause();
1031 }
1032 restartAudio(
1033 currentPositionUs, true /* forceNonOffload */,
1034 true /* needsToCreateAudioDecoder */);
1035 if (!mPaused) {
1036 mRenderer->resume();
1037 }
1038 }
1039
1040 err = mRenderer->setPlaybackSettings(rate);
1041 }
1042 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001043 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001044
Wei Jia700a7c22018-09-14 18:04:35 -07001045 if (mVideoDecoder != NULL) {
1046 sp<AMessage> params = new AMessage();
1047 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1048 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001049 }
1050 }
1051
Wei Jia53692fa2017-12-11 10:33:46 -08001052 sp<AMessage> response = new AMessage;
1053 response->setInt32("err", err);
1054 response->postReply(replyID);
1055 break;
1056 }
1057
1058 case kWhatGetPlaybackSettings:
1059 {
1060 sp<AReplyToken> replyID;
1061 CHECK(msg->senderAwaitsResponse(&replyID));
1062 AudioPlaybackRate rate = mPlaybackSettings;
1063 status_t err = OK;
1064 if (mRenderer != NULL) {
1065 err = mRenderer->getPlaybackSettings(&rate);
1066 }
1067 if (err == OK) {
1068 // get playback settings used by renderer, as it may be
1069 // slightly off due to audiosink not taking small changes.
1070 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001071 }
1072 sp<AMessage> response = new AMessage;
1073 if (err == OK) {
1074 writeToAMessage(response, rate);
1075 }
1076 response->setInt32("err", err);
1077 response->postReply(replyID);
1078 break;
1079 }
1080
1081 case kWhatConfigSync:
1082 {
1083 sp<AReplyToken> replyID;
1084 CHECK(msg->senderAwaitsResponse(&replyID));
1085
1086 ALOGV("kWhatConfigSync");
1087 AVSyncSettings sync;
1088 float videoFpsHint;
1089 readFromAMessage(msg, &sync, &videoFpsHint);
1090 status_t err = OK;
1091 if (mRenderer != NULL) {
1092 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1093 }
1094 if (err == OK) {
1095 mSyncSettings = sync;
1096 mVideoFpsHint = videoFpsHint;
1097 }
1098 sp<AMessage> response = new AMessage;
1099 response->setInt32("err", err);
1100 response->postReply(replyID);
1101 break;
1102 }
1103
1104 case kWhatGetSyncSettings:
1105 {
1106 sp<AReplyToken> replyID;
1107 CHECK(msg->senderAwaitsResponse(&replyID));
1108 AVSyncSettings sync = mSyncSettings;
1109 float videoFps = mVideoFpsHint;
1110 status_t err = OK;
1111 if (mRenderer != NULL) {
1112 err = mRenderer->getSyncSettings(&sync, &videoFps);
1113 if (err == OK) {
1114 mSyncSettings = sync;
1115 mVideoFpsHint = videoFps;
1116 }
1117 }
1118 sp<AMessage> response = new AMessage;
1119 if (err == OK) {
1120 writeToAMessage(response, sync, videoFps);
1121 }
1122 response->setInt32("err", err);
1123 response->postReply(replyID);
1124 break;
1125 }
1126
1127 case kWhatScanSources:
1128 {
1129 int32_t generation;
1130 CHECK(msg->findInt32("generation", &generation));
1131 if (generation != mScanSourcesGeneration) {
1132 // Drop obsolete msg.
1133 break;
1134 }
1135
1136 mScanSourcesPending = false;
1137
1138 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1139 mAudioDecoder != NULL, mVideoDecoder != NULL);
1140
1141 bool mHadAnySourcesBefore =
1142 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1143 bool rescan = false;
1144
1145 // initialize video before audio because successful initialization of
1146 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001147 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001148 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1149 rescan = true;
1150 }
1151 }
1152
1153 // Don't try to re-open audio sink if there's an existing decoder.
1154 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1155 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1156 rescan = true;
1157 }
1158 }
1159
1160 if (!mHadAnySourcesBefore
1161 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1162 // This is the first time we've found anything playable.
1163
Wei Jiaf01e3122018-10-18 11:49:44 -07001164 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001165 schedulePollDuration();
1166 }
1167 }
1168
1169 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001170 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001171 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1172 // We're not currently decoding anything (no audio or
1173 // video tracks found) and we just ran out of input data.
1174
1175 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001176 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001177 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001178 notifyListener(
1179 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001180 }
1181 }
1182 break;
1183 }
1184
1185 if (rescan) {
1186 msg->post(100000ll);
1187 mScanSourcesPending = true;
1188 }
1189 break;
1190 }
1191
1192 case kWhatVideoNotify:
1193 case kWhatAudioNotify:
1194 {
1195 bool audio = msg->what() == kWhatAudioNotify;
1196
1197 int32_t currentDecoderGeneration =
1198 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1199 int32_t requesterGeneration = currentDecoderGeneration - 1;
1200 CHECK(msg->findInt32("generation", &requesterGeneration));
1201
1202 if (requesterGeneration != currentDecoderGeneration) {
1203 ALOGV("got message from old %s decoder, generation(%d:%d)",
1204 audio ? "audio" : "video", requesterGeneration,
1205 currentDecoderGeneration);
1206 sp<AMessage> reply;
1207 if (!(msg->findMessage("reply", &reply))) {
1208 return;
1209 }
1210
1211 reply->setInt32("err", INFO_DISCONTINUITY);
1212 reply->post();
1213 return;
1214 }
1215
1216 int32_t what;
1217 CHECK(msg->findInt32("what", &what));
1218
1219 if (what == DecoderBase::kWhatInputDiscontinuity) {
1220 int32_t formatChange;
1221 CHECK(msg->findInt32("formatChange", &formatChange));
1222
1223 ALOGV("%s discontinuity: formatChange %d",
1224 audio ? "audio" : "video", formatChange);
1225
1226 if (formatChange) {
1227 mDeferredActions.push_back(
1228 new FlushDecoderAction(
1229 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1230 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1231 }
1232
1233 mDeferredActions.push_back(
1234 new SimpleAction(
1235 &NuPlayer2::performScanSources));
1236
1237 processDeferredActions();
1238 } else if (what == DecoderBase::kWhatEOS) {
1239 int32_t err;
1240 CHECK(msg->findInt32("err", &err));
1241
1242 if (err == ERROR_END_OF_STREAM) {
1243 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1244 } else {
1245 ALOGV("got %s decoder EOS w/ error %d",
1246 audio ? "audio" : "video",
1247 err);
1248 }
1249
1250 mRenderer->queueEOS(audio, err);
1251 } else if (what == DecoderBase::kWhatFlushCompleted) {
1252 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1253
1254 handleFlushComplete(audio, true /* isDecoder */);
1255 finishFlushIfPossible();
1256 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1257 sp<AMessage> format;
1258 CHECK(msg->findMessage("format", &format));
1259
1260 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001261 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001262
1263 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001264 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001265 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1266 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1267 if (audio) {
1268 mAudioDecoder.clear();
1269 mAudioDecoderError = false;
1270 ++mAudioDecoderGeneration;
1271
1272 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1273 mFlushingAudio = SHUT_DOWN;
1274 } else {
1275 mVideoDecoder.clear();
1276 mVideoDecoderError = false;
1277 ++mVideoDecoderGeneration;
1278
1279 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1280 mFlushingVideo = SHUT_DOWN;
1281 }
1282
1283 finishFlushIfPossible();
1284 } else if (what == DecoderBase::kWhatResumeCompleted) {
1285 finishResume();
1286 } else if (what == DecoderBase::kWhatError) {
1287 status_t err;
1288 if (!msg->findInt32("err", &err) || err == OK) {
1289 err = UNKNOWN_ERROR;
1290 }
1291
1292 // Decoder errors can be due to Source (e.g. from streaming),
1293 // or from decoding corrupted bitstreams, or from other decoder
1294 // MediaCodec operations (e.g. from an ongoing reset or seek).
1295 // They may also be due to openAudioSink failure at
1296 // decoder start or after a format change.
1297 //
1298 // We try to gracefully shut down the affected decoder if possible,
1299 // rather than trying to force the shutdown with something
1300 // similar to performReset(). This method can lead to a hang
1301 // if MediaCodec functions block after an error, but they should
1302 // typically return INVALID_OPERATION instead of blocking.
1303
1304 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1305 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1306 err, audio ? "audio" : "video", *flushing);
1307
1308 switch (*flushing) {
1309 case NONE:
1310 mDeferredActions.push_back(
1311 new FlushDecoderAction(
1312 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1313 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1314 processDeferredActions();
1315 break;
1316 case FLUSHING_DECODER:
1317 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1318 break; // Wait for flush to complete.
1319 case FLUSHING_DECODER_SHUTDOWN:
1320 break; // Wait for flush to complete.
1321 case SHUTTING_DOWN_DECODER:
1322 break; // Wait for shutdown to complete.
1323 case FLUSHED:
1324 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1325 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1326 break;
1327 case SHUT_DOWN:
1328 finishFlushIfPossible(); // Should not occur.
1329 break; // Finish anyways.
1330 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001331 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001332 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001333 if (mVideoDecoderError
1334 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1335 || mNativeWindow == NULL
1336 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001337 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001338 // When both audio and video have error, or this stream has only audio
1339 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001340 notifyListener(
1341 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1342 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001343 } else {
1344 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001345 notifyListener(
1346 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1347 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001348 }
1349 mAudioDecoderError = true;
1350 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001351 if (mAudioDecoderError
1352 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001353 || mAudioSink == NULL || mAudioDecoder == NULL) {
1354 // When both audio and video have error, or this stream has only video
1355 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001356 notifyListener(
1357 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1358 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001359 } else {
1360 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001361 notifyListener(
1362 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1363 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001364 }
1365 mVideoDecoderError = true;
1366 }
1367 }
1368 } else {
1369 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1370 what,
1371 what >> 24,
1372 (what >> 16) & 0xff,
1373 (what >> 8) & 0xff,
1374 what & 0xff);
1375 }
1376
1377 break;
1378 }
1379
1380 case kWhatRendererNotify:
1381 {
1382 int32_t requesterGeneration = mRendererGeneration - 1;
1383 CHECK(msg->findInt32("generation", &requesterGeneration));
1384 if (requesterGeneration != mRendererGeneration) {
1385 ALOGV("got message from old renderer, generation(%d:%d)",
1386 requesterGeneration, mRendererGeneration);
1387 return;
1388 }
1389
1390 int32_t what;
1391 CHECK(msg->findInt32("what", &what));
1392
1393 if (what == Renderer::kWhatEOS) {
1394 int32_t audio;
1395 CHECK(msg->findInt32("audio", &audio));
1396
1397 int32_t finalResult;
1398 CHECK(msg->findInt32("finalResult", &finalResult));
1399
1400 if (audio) {
1401 mAudioEOS = true;
1402 } else {
1403 mVideoEOS = true;
1404 }
1405
1406 if (finalResult == ERROR_END_OF_STREAM) {
1407 ALOGV("reached %s EOS", audio ? "audio" : "video");
1408 } else {
1409 ALOGE("%s track encountered an error (%d)",
1410 audio ? "audio" : "video", finalResult);
1411
1412 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001413 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1414 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001415 }
1416
1417 if ((mAudioEOS || mAudioDecoder == NULL)
1418 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001419 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001420 }
1421 } else if (what == Renderer::kWhatFlushComplete) {
1422 int32_t audio;
1423 CHECK(msg->findInt32("audio", &audio));
1424
1425 if (audio) {
1426 mAudioEOS = false;
1427 } else {
1428 mVideoEOS = false;
1429 }
1430
1431 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1432 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1433 || mFlushingAudio == SHUT_DOWN)) {
1434 // Flush has been handled by tear down.
1435 break;
1436 }
1437 handleFlushComplete(audio, false /* isDecoder */);
1438 finishFlushIfPossible();
1439 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001440 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1441 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001442 } else if (what == Renderer::kWhatMediaRenderingStart) {
1443 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001444 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001445 } else if (what == Renderer::kWhatAudioTearDown) {
1446 int32_t reason;
1447 CHECK(msg->findInt32("reason", &reason));
1448 ALOGV("Tear down audio with reason %d.", reason);
1449 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1450 // TimeoutWhenPaused is only for offload mode.
1451 ALOGW("Receive a stale message for teardown.");
1452 break;
1453 }
1454 int64_t positionUs;
1455 if (!msg->findInt64("positionUs", &positionUs)) {
1456 positionUs = mPreviousSeekTimeUs;
1457 }
1458
1459 restartAudio(
1460 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1461 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1462 }
1463 break;
1464 }
1465
1466 case kWhatMoreDataQueued:
1467 {
1468 break;
1469 }
1470
1471 case kWhatReset:
1472 {
1473 ALOGV("kWhatReset");
1474
1475 mResetting = true;
1476 stopPlaybackTimer("kWhatReset");
1477 stopRebufferingTimer(true);
1478
1479 mDeferredActions.push_back(
1480 new FlushDecoderAction(
1481 FLUSH_CMD_SHUTDOWN /* audio */,
1482 FLUSH_CMD_SHUTDOWN /* video */));
1483
1484 mDeferredActions.push_back(
1485 new SimpleAction(&NuPlayer2::performReset));
1486
1487 processDeferredActions();
1488 break;
1489 }
1490
1491 case kWhatNotifyTime:
1492 {
1493 ALOGV("kWhatNotifyTime");
1494 int64_t timerUs;
1495 CHECK(msg->findInt64("timerUs", &timerUs));
1496
Wei Jiaf01e3122018-10-18 11:49:44 -07001497 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001498 break;
1499 }
1500
1501 case kWhatSeek:
1502 {
1503 int64_t seekTimeUs;
1504 int32_t mode;
1505 int32_t needNotify;
1506 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1507 CHECK(msg->findInt32("mode", &mode));
1508 CHECK(msg->findInt32("needNotify", &needNotify));
1509
1510 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1511 (long long)seekTimeUs, mode, needNotify);
1512
1513 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001514 if (!mSourceStarted) {
1515 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001516 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001517 }
Wei Jia083e9092018-02-12 11:46:04 -08001518 if (seekTimeUs > 0) {
1519 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1520 }
1521
Wei Jia53692fa2017-12-11 10:33:46 -08001522 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001523 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001524 }
1525 break;
1526 }
1527
Wei Jia083e9092018-02-12 11:46:04 -08001528 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001529 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001530
Wei Jia53692fa2017-12-11 10:33:46 -08001531 mDeferredActions.push_back(
1532 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1533 FLUSH_CMD_FLUSH /* video */));
1534
1535 mDeferredActions.push_back(
1536 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1537
1538 // After a flush without shutdown, decoder is paused.
1539 // Don't resume it until source seek is done, otherwise it could
1540 // start pulling stale data too soon.
1541 mDeferredActions.push_back(
1542 new ResumeDecoderAction(needNotify));
1543
1544 processDeferredActions();
1545 break;
1546 }
1547
Wei Jiad1864f92018-10-19 12:34:56 -07001548 case kWhatRewind:
1549 {
1550 ALOGV("kWhatRewind");
1551
1552 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1553 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1554
1555 if (!mStarted) {
1556 if (!mSourceStarted) {
1557 mSourceStarted = true;
1558 mCurrentSourceInfo.mSource->start();
1559 }
1560 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1561 break;
1562 }
1563
1564 // seeks can take a while, so we essentially paused
1565 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1566
1567 mDeferredActions.push_back(
1568 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1569 FLUSH_CMD_FLUSH /* video */));
1570
1571 mDeferredActions.push_back(
1572 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1573
1574 // After a flush without shutdown, decoder is paused.
1575 // Don't resume it until source seek is done, otherwise it could
1576 // start pulling stale data too soon.
1577 mDeferredActions.push_back(
1578 new ResumeDecoderAction(false /* needNotify */));
1579
1580 processDeferredActions();
1581 break;
1582 }
1583
Wei Jia53692fa2017-12-11 10:33:46 -08001584 case kWhatPause:
1585 {
Wei Jia6376cd52018-09-26 11:42:55 -07001586 if (!mStarted) {
1587 onStart(false /* play */);
1588 }
Wei Jia53692fa2017-12-11 10:33:46 -08001589 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001590 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001591 mPausedByClient = true;
1592 break;
1593 }
1594
1595 case kWhatSourceNotify:
1596 {
1597 onSourceNotify(msg);
1598 break;
1599 }
1600
1601 case kWhatClosedCaptionNotify:
1602 {
1603 onClosedCaptionNotify(msg);
1604 break;
1605 }
1606
1607 case kWhatPrepareDrm:
1608 {
1609 status_t status = onPrepareDrm(msg);
1610
1611 sp<AMessage> response = new AMessage;
1612 response->setInt32("status", status);
1613 sp<AReplyToken> replyID;
1614 CHECK(msg->senderAwaitsResponse(&replyID));
1615 response->postReply(replyID);
1616 break;
1617 }
1618
1619 case kWhatReleaseDrm:
1620 {
1621 status_t status = onReleaseDrm();
1622
1623 sp<AMessage> response = new AMessage;
1624 response->setInt32("status", status);
1625 sp<AReplyToken> replyID;
1626 CHECK(msg->senderAwaitsResponse(&replyID));
1627 response->postReply(replyID);
1628 break;
1629 }
1630
1631 default:
1632 TRESPASS();
1633 break;
1634 }
1635}
1636
1637void NuPlayer2::onResume() {
1638 if (!mPaused || mResetting) {
1639 ALOGD_IF(mResetting, "resetting, onResume discarded");
1640 return;
1641 }
1642 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001643 if (mCurrentSourceInfo.mSource != NULL) {
1644 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001645 } else {
1646 ALOGW("resume called when source is gone or not set");
1647 }
1648 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1649 // needed.
1650 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1651 instantiateDecoder(true /* audio */, &mAudioDecoder);
1652 }
1653 if (mRenderer != NULL) {
1654 mRenderer->resume();
1655 } else {
1656 ALOGW("resume called when renderer is gone or not set");
1657 }
1658
1659 startPlaybackTimer("onresume");
1660}
1661
Wei Jia6376cd52018-09-26 11:42:55 -07001662void NuPlayer2::onStart(bool play) {
Wei Jia53692fa2017-12-11 10:33:46 -08001663 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1664
1665 if (!mSourceStarted) {
1666 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001667 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001668 }
Wei Jia53692fa2017-12-11 10:33:46 -08001669
1670 mOffloadAudio = false;
1671 mAudioEOS = false;
1672 mVideoEOS = false;
1673 mStarted = true;
1674 mPaused = false;
1675
1676 uint32_t flags = 0;
1677
Wei Jiaf01e3122018-10-18 11:49:44 -07001678 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001679 flags |= Renderer::FLAG_REAL_TIME;
1680 }
1681
Wei Jiaf01e3122018-10-18 11:49:44 -07001682 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1683 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001684 if (!hasAudio && !hasVideo) {
1685 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001686 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001687 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001688 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1689 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001690 return;
1691 }
1692 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1693
Wei Jiaf01e3122018-10-18 11:49:44 -07001694 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001695
1696 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1697 if (mAudioSink != NULL) {
1698 streamType = mAudioSink->getAudioStreamType();
1699 }
1700
1701 mOffloadAudio =
Wei Jiaf01e3122018-10-18 11:49:44 -07001702 canOffloadStream(audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001703 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1704
1705 // Modular DRM: Disabling audio offload if the source is protected
1706 if (mOffloadAudio && mIsDrmProtected) {
1707 mOffloadAudio = false;
1708 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1709 }
1710
1711 if (mOffloadAudio) {
1712 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1713 }
1714
1715 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1716 ++mRendererGeneration;
1717 notify->setInt32("generation", mRendererGeneration);
1718 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1719 mRendererLooper = new ALooper;
1720 mRendererLooper->setName("NuPlayerRenderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001721 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001722 mRendererLooper->registerHandler(mRenderer);
1723
1724 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1725 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001726 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001727 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001728 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001729 return;
1730 }
1731
1732 float rate = getFrameRate();
1733 if (rate > 0) {
1734 mRenderer->setVideoFrameRate(rate);
1735 }
1736
Wei Jiad1864f92018-10-19 12:34:56 -07001737 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001738 // Renderer is created in paused state.
1739 if (play) {
1740 mRenderer->resume();
1741 }
1742
Wei Jia53692fa2017-12-11 10:33:46 -08001743 if (mVideoDecoder != NULL) {
1744 mVideoDecoder->setRenderer(mRenderer);
1745 }
1746 if (mAudioDecoder != NULL) {
1747 mAudioDecoder->setRenderer(mRenderer);
1748 }
1749
1750 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001751 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001752
1753 postScanSources();
1754}
1755
Wei Jiad1864f92018-10-19 12:34:56 -07001756void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001757 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001758
1759 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1760 return;
1761 }
1762
1763 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001764 msg->setInt32("generation", mEOSMonitorGeneration);
1765 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1766}
1767
Wei Jia53692fa2017-12-11 10:33:46 -08001768void NuPlayer2::startPlaybackTimer(const char *where) {
1769 Mutex::Autolock autoLock(mPlayingTimeLock);
1770 if (mLastStartedPlayingTimeNs == 0) {
1771 mLastStartedPlayingTimeNs = systemTime();
1772 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1773 }
1774}
1775
1776void NuPlayer2::stopPlaybackTimer(const char *where) {
1777 Mutex::Autolock autoLock(mPlayingTimeLock);
1778
1779 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1780
1781 if (mLastStartedPlayingTimeNs != 0) {
1782 sp<NuPlayer2Driver> driver = mDriver.promote();
1783 if (driver != NULL) {
1784 int64_t now = systemTime();
1785 int64_t played = now - mLastStartedPlayingTimeNs;
1786 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1787
1788 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001789 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001790 }
1791 }
1792 mLastStartedPlayingTimeNs = 0;
1793 }
1794}
1795
1796void NuPlayer2::startRebufferingTimer() {
1797 Mutex::Autolock autoLock(mPlayingTimeLock);
1798 if (mLastStartedRebufferingTimeNs == 0) {
1799 mLastStartedRebufferingTimeNs = systemTime();
1800 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1801 }
1802}
1803
1804void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1805 Mutex::Autolock autoLock(mPlayingTimeLock);
1806
Wei Jiaf01e3122018-10-18 11:49:44 -07001807 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1808 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001809
1810 if (mLastStartedRebufferingTimeNs != 0) {
1811 sp<NuPlayer2Driver> driver = mDriver.promote();
1812 if (driver != NULL) {
1813 int64_t now = systemTime();
1814 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1815 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1816
1817 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001818 driver->notifyMoreRebufferingTimeUs(
1819 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001820 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001821 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001822 }
1823 }
1824 }
1825 mLastStartedRebufferingTimeNs = 0;
1826 }
1827}
1828
1829void NuPlayer2::onPause() {
1830
1831 stopPlaybackTimer("onPause");
1832
1833 if (mPaused) {
1834 return;
1835 }
1836 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001837 if (mCurrentSourceInfo.mSource != NULL) {
1838 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001839 } else {
1840 ALOGW("pause called when source is gone or not set");
1841 }
1842 if (mRenderer != NULL) {
1843 mRenderer->pause();
1844 } else {
1845 ALOGW("pause called when renderer is gone or not set");
1846 }
1847
1848}
1849
1850bool NuPlayer2::audioDecoderStillNeeded() {
1851 // Audio decoder is no longer needed if it's in shut/shutting down status.
1852 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1853}
1854
1855void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1856 // We wait for both the decoder flush and the renderer flush to complete
1857 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1858
1859 mFlushComplete[audio][isDecoder] = true;
1860 if (!mFlushComplete[audio][!isDecoder]) {
1861 return;
1862 }
1863
1864 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1865 switch (*state) {
1866 case FLUSHING_DECODER:
1867 {
1868 *state = FLUSHED;
1869 break;
1870 }
1871
1872 case FLUSHING_DECODER_SHUTDOWN:
1873 {
1874 *state = SHUTTING_DOWN_DECODER;
1875
1876 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1877 getDecoder(audio)->initiateShutdown();
1878 break;
1879 }
1880
1881 default:
1882 // decoder flush completes only occur in a flushing state.
1883 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1884 break;
1885 }
1886}
1887
1888void NuPlayer2::finishFlushIfPossible() {
1889 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1890 && mFlushingAudio != SHUT_DOWN) {
1891 return;
1892 }
1893
1894 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1895 && mFlushingVideo != SHUT_DOWN) {
1896 return;
1897 }
1898
1899 ALOGV("both audio and video are flushed now.");
1900
1901 mFlushingAudio = NONE;
1902 mFlushingVideo = NONE;
1903
1904 clearFlushComplete();
1905
1906 processDeferredActions();
1907}
1908
1909void NuPlayer2::postScanSources() {
1910 if (mScanSourcesPending) {
1911 return;
1912 }
1913
1914 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1915 msg->setInt32("generation", mScanSourcesGeneration);
1916 msg->post();
1917
1918 mScanSourcesPending = true;
1919}
1920
1921void NuPlayer2::tryOpenAudioSinkForOffload(
1922 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1923 // Note: This is called early in NuPlayer2 to determine whether offloading
1924 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1925
1926 status_t err = mRenderer->openAudioSink(
1927 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001928 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001929 if (err != OK) {
1930 // Any failure we turn off mOffloadAudio.
1931 mOffloadAudio = false;
1932 } else if (mOffloadAudio) {
1933 sendMetaDataToHal(mAudioSink, audioMeta);
1934 }
1935}
1936
1937void NuPlayer2::closeAudioSink() {
1938 mRenderer->closeAudioSink();
1939}
1940
1941void NuPlayer2::restartAudio(
1942 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1943 if (mAudioDecoder != NULL) {
1944 mAudioDecoder->pause();
1945 mAudioDecoder.clear();
1946 mAudioDecoderError = false;
1947 ++mAudioDecoderGeneration;
1948 }
1949 if (mFlushingAudio == FLUSHING_DECODER) {
1950 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1951 mFlushingAudio = FLUSHED;
1952 finishFlushIfPossible();
1953 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1954 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1955 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1956 mFlushingAudio = SHUT_DOWN;
1957 finishFlushIfPossible();
1958 needsToCreateAudioDecoder = false;
1959 }
1960 if (mRenderer == NULL) {
1961 return;
1962 }
1963 closeAudioSink();
1964 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1965 if (mVideoDecoder != NULL) {
1966 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1967 }
1968
1969 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1970
1971 if (forceNonOffload) {
1972 mRenderer->signalDisableOffloadAudio();
1973 mOffloadAudio = false;
1974 }
1975 if (needsToCreateAudioDecoder) {
1976 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1977 }
1978}
1979
1980void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001981 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001982 return;
1983 }
1984
1985 if (mRenderer == NULL) {
1986 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1987 mOffloadAudio = false;
1988 return;
1989 }
1990
Wei Jiaf01e3122018-10-18 11:49:44 -07001991 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
1992 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001993 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1994 const bool hasVideo = (videoFormat != NULL);
1995 bool canOffload = canOffloadStream(
Wei Jiaf01e3122018-10-18 11:49:44 -07001996 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001997 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1998
1999 // Modular DRM: Disabling audio offload if the source is protected
2000 if (canOffload && mIsDrmProtected) {
2001 canOffload = false;
2002 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2003 }
2004
2005 if (canOffload) {
2006 if (!mOffloadAudio) {
2007 mRenderer->signalEnableOffloadAudio();
2008 }
2009 // open audio sink early under offload mode.
2010 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2011 } else {
2012 if (mOffloadAudio) {
2013 mRenderer->signalDisableOffloadAudio();
2014 mOffloadAudio = false;
2015 }
2016 }
2017}
2018
2019status_t NuPlayer2::instantiateDecoder(
2020 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2021 // The audio decoder could be cleared by tear down. If still in shut down
2022 // process, no need to create a new audio decoder.
2023 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2024 return OK;
2025 }
2026
Wei Jiaf01e3122018-10-18 11:49:44 -07002027 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002028
2029 if (format == NULL) {
2030 return UNKNOWN_ERROR;
2031 } else {
2032 status_t err;
2033 if (format->findInt32("err", &err) && err) {
2034 return err;
2035 }
2036 }
2037
2038 format->setInt32("priority", 0 /* realtime */);
2039
2040 if (!audio) {
2041 AString mime;
2042 CHECK(format->findString("mime", &mime));
2043
2044 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2045 if (mCCDecoder == NULL) {
2046 mCCDecoder = new CCDecoder(ccNotify);
2047 }
2048
Wei Jiaf01e3122018-10-18 11:49:44 -07002049 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002050 format->setInt32("secure", true);
2051 }
2052
Wei Jiaf01e3122018-10-18 11:49:44 -07002053 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002054 format->setInt32("protected", true);
2055 }
2056
2057 float rate = getFrameRate();
2058 if (rate > 0) {
2059 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2060 }
2061 }
2062
2063 if (audio) {
2064 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2065 ++mAudioDecoderGeneration;
2066 notify->setInt32("generation", mAudioDecoderGeneration);
2067
2068 if (checkAudioModeChange) {
2069 determineAudioModeChange(format);
2070 }
2071 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002072 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002073
Wei Jiaf01e3122018-10-18 11:49:44 -07002074 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002075 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002076 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002077 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2078 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002079 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002080
Wei Jiaf01e3122018-10-18 11:49:44 -07002081 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002082 ALOGV("instantiateDecoder audio Decoder");
2083 }
2084 mAudioDecoderError = false;
2085 } else {
2086 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2087 ++mVideoDecoderGeneration;
2088 notify->setInt32("generation", mVideoDecoderGeneration);
2089
2090 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002091 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2092 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002093 mVideoDecoderError = false;
2094
2095 // enable FRC if high-quality AV sync is requested, even if not
2096 // directly queuing to display, as this will even improve textureview
2097 // playback.
2098 {
2099 if (property_get_bool("persist.sys.media.avsync", false)) {
2100 format->setInt32("auto-frc", 1);
2101 }
2102 }
2103 }
2104 (*decoder)->init();
2105
2106 // Modular DRM
2107 if (mIsDrmProtected) {
2108 format->setObject("crypto", mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002109 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
2110 mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002111 }
2112
2113 (*decoder)->configure(format);
2114
2115 if (!audio) {
2116 sp<AMessage> params = new AMessage();
2117 float rate = getFrameRate();
2118 if (rate > 0) {
2119 params->setFloat("frame-rate-total", rate);
2120 }
2121
2122 sp<MetaData> fileMeta = getFileMeta();
2123 if (fileMeta != NULL) {
2124 int32_t videoTemporalLayerCount;
2125 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2126 && videoTemporalLayerCount > 0) {
2127 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2128 }
2129 }
2130
2131 if (params->countEntries() > 0) {
2132 (*decoder)->setParameters(params);
2133 }
2134 }
2135 return OK;
2136}
2137
2138void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002139 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002140 const sp<AMessage> &inputFormat,
2141 const sp<AMessage> &outputFormat) {
2142 if (inputFormat == NULL) {
2143 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002144 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002145 return;
2146 }
2147 int32_t err = OK;
2148 inputFormat->findInt32("err", &err);
2149 if (err == -EWOULDBLOCK) {
2150 ALOGW("Video meta is not available yet!");
2151 return;
2152 }
2153 if (err != OK) {
2154 ALOGW("Something is wrong with video meta!");
2155 return;
2156 }
2157
2158 int32_t displayWidth, displayHeight;
2159 if (outputFormat != NULL) {
2160 int32_t width, height;
2161 CHECK(outputFormat->findInt32("width", &width));
2162 CHECK(outputFormat->findInt32("height", &height));
2163
2164 int32_t cropLeft, cropTop, cropRight, cropBottom;
2165 CHECK(outputFormat->findRect(
2166 "crop",
2167 &cropLeft, &cropTop, &cropRight, &cropBottom));
2168
2169 displayWidth = cropRight - cropLeft + 1;
2170 displayHeight = cropBottom - cropTop + 1;
2171
2172 ALOGV("Video output format changed to %d x %d "
2173 "(crop: %d x %d @ (%d, %d))",
2174 width, height,
2175 displayWidth,
2176 displayHeight,
2177 cropLeft, cropTop);
2178 } else {
2179 CHECK(inputFormat->findInt32("width", &displayWidth));
2180 CHECK(inputFormat->findInt32("height", &displayHeight));
2181
2182 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2183 }
2184
2185 // Take into account sample aspect ratio if necessary:
2186 int32_t sarWidth, sarHeight;
2187 if (inputFormat->findInt32("sar-width", &sarWidth)
2188 && inputFormat->findInt32("sar-height", &sarHeight)
2189 && sarWidth > 0 && sarHeight > 0) {
2190 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2191
2192 displayWidth = (displayWidth * sarWidth) / sarHeight;
2193
2194 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2195 } else {
2196 int32_t width, height;
2197 if (inputFormat->findInt32("display-width", &width)
2198 && inputFormat->findInt32("display-height", &height)
2199 && width > 0 && height > 0
2200 && displayWidth > 0 && displayHeight > 0) {
2201 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2202 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2203 } else {
2204 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2205 }
2206 ALOGV("Video display width and height are overridden to %d x %d",
2207 displayWidth, displayHeight);
2208 }
2209 }
2210
2211 int32_t rotationDegrees;
2212 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2213 rotationDegrees = 0;
2214 }
2215
2216 if (rotationDegrees == 90 || rotationDegrees == 270) {
2217 int32_t tmp = displayWidth;
2218 displayWidth = displayHeight;
2219 displayHeight = tmp;
2220 }
2221
2222 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002223 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002224 MEDIA2_SET_VIDEO_SIZE,
2225 displayWidth,
2226 displayHeight);
2227}
2228
Dongwon Kang41929fb2018-09-09 08:29:56 -07002229void NuPlayer2::notifyListener(
2230 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002231 if (mDriver == NULL) {
2232 return;
2233 }
2234
2235 sp<NuPlayer2Driver> driver = mDriver.promote();
2236
2237 if (driver == NULL) {
2238 return;
2239 }
2240
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002241 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002242}
2243
2244void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2245 ALOGV("[%s] flushDecoder needShutdown=%d",
2246 audio ? "audio" : "video", needShutdown);
2247
2248 const sp<DecoderBase> &decoder = getDecoder(audio);
2249 if (decoder == NULL) {
2250 ALOGI("flushDecoder %s without decoder present",
2251 audio ? "audio" : "video");
2252 return;
2253 }
2254
2255 // Make sure we don't continue to scan sources until we finish flushing.
2256 ++mScanSourcesGeneration;
2257 if (mScanSourcesPending) {
2258 if (!needShutdown) {
2259 mDeferredActions.push_back(
2260 new SimpleAction(&NuPlayer2::performScanSources));
2261 }
2262 mScanSourcesPending = false;
2263 }
2264
2265 decoder->signalFlush();
2266
2267 FlushStatus newStatus =
2268 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2269
2270 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2271 mFlushComplete[audio][true /* isDecoder */] = false;
2272 if (audio) {
2273 ALOGE_IF(mFlushingAudio != NONE,
2274 "audio flushDecoder() is called in state %d", mFlushingAudio);
2275 mFlushingAudio = newStatus;
2276 } else {
2277 ALOGE_IF(mFlushingVideo != NONE,
2278 "video flushDecoder() is called in state %d", mFlushingVideo);
2279 mFlushingVideo = newStatus;
2280 }
2281}
2282
2283void NuPlayer2::queueDecoderShutdown(
2284 bool audio, bool video, const sp<AMessage> &reply) {
2285 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2286
2287 mDeferredActions.push_back(
2288 new FlushDecoderAction(
2289 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2290 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2291
2292 mDeferredActions.push_back(
2293 new SimpleAction(&NuPlayer2::performScanSources));
2294
2295 mDeferredActions.push_back(new PostMessageAction(reply));
2296
2297 processDeferredActions();
2298}
2299
2300status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2301 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002302 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2303 status_t ret = native_window_set_scaling_mode(
2304 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002305 if (ret != OK) {
2306 ALOGE("Failed to set scaling mode (%d): %s",
2307 -ret, strerror(-ret));
2308 return ret;
2309 }
2310 }
2311 return OK;
2312}
2313
Dongwon Kang9f631982018-07-10 12:34:41 -07002314status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002315 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2316 msg->setPointer("reply", reply);
2317
2318 sp<AMessage> response;
2319 status_t err = msg->postAndAwaitResponse(&response);
2320 return err;
2321}
2322
Dongwon Kang9f631982018-07-10 12:34:41 -07002323status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002324 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2325 msg->setPointer("reply", reply);
2326 msg->setInt32("type", type);
2327
2328 sp<AMessage> response;
2329 status_t err = msg->postAndAwaitResponse(&response);
2330 if (err == OK && response != NULL) {
2331 CHECK(response->findInt32("err", &err));
2332 }
2333 return err;
2334}
2335
2336status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2337 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2338 msg->setSize("trackIndex", trackIndex);
2339 msg->setInt32("select", select);
2340 msg->setInt64("timeUs", timeUs);
2341
2342 sp<AMessage> response;
2343 status_t err = msg->postAndAwaitResponse(&response);
2344
2345 if (err != OK) {
2346 return err;
2347 }
2348
2349 if (!response->findInt32("err", &err)) {
2350 err = OK;
2351 }
2352
2353 return err;
2354}
2355
2356status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2357 sp<Renderer> renderer = mRenderer;
2358 if (renderer == NULL) {
2359 return NO_INIT;
2360 }
2361
2362 return renderer->getCurrentPosition(mediaUs);
2363}
2364
2365void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2366 CHECK(mTrackStats != NULL);
2367
2368 mTrackStats->clear();
2369 if (mVideoDecoder != NULL) {
2370 mTrackStats->push_back(mVideoDecoder->getStats());
2371 }
2372 if (mAudioDecoder != NULL) {
2373 mTrackStats->push_back(mAudioDecoder->getStats());
2374 }
2375}
2376
2377sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002378 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002379}
2380
2381float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002382 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002383 if (meta == NULL) {
2384 return 0;
2385 }
2386 int32_t rate;
2387 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2388 // fall back to try file meta
2389 sp<MetaData> fileMeta = getFileMeta();
2390 if (fileMeta == NULL) {
2391 ALOGW("source has video meta but not file meta");
2392 return -1;
2393 }
2394 int32_t fileMetaRate;
2395 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2396 return -1;
2397 }
2398 return fileMetaRate;
2399 }
2400 return rate;
2401}
2402
2403void NuPlayer2::schedulePollDuration() {
2404 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2405 msg->setInt32("generation", mPollDurationGeneration);
2406 msg->post();
2407}
2408
2409void NuPlayer2::cancelPollDuration() {
2410 ++mPollDurationGeneration;
2411}
2412
2413void NuPlayer2::processDeferredActions() {
2414 while (!mDeferredActions.empty()) {
2415 // We won't execute any deferred actions until we're no longer in
2416 // an intermediate state, i.e. one more more decoders are currently
2417 // flushing or shutting down.
2418
2419 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2420 // We're currently flushing, postpone the reset until that's
2421 // completed.
2422
2423 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2424 mFlushingAudio, mFlushingVideo);
2425
2426 break;
2427 }
2428
2429 sp<Action> action = *mDeferredActions.begin();
2430 mDeferredActions.erase(mDeferredActions.begin());
2431
2432 action->execute(this);
2433 }
2434}
2435
2436void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2437 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2438 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2439
Wei Jiaf01e3122018-10-18 11:49:44 -07002440 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002441 // This happens when reset occurs right before the loop mode
2442 // asynchronously seeks to the start of the stream.
2443 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002444 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002445 mAudioDecoder.get(), mVideoDecoder.get());
2446 return;
2447 }
2448 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002449 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002450 ++mTimedTextGeneration;
2451
2452 // everything's flushed, continue playback.
2453}
2454
2455void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2456 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2457
2458 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2459 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2460 return;
2461 }
2462
2463 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2464 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2465 }
2466
2467 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2468 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2469 }
2470}
2471
2472void NuPlayer2::performReset() {
2473 ALOGV("performReset");
2474
2475 CHECK(mAudioDecoder == NULL);
2476 CHECK(mVideoDecoder == NULL);
2477
2478 stopPlaybackTimer("performReset");
2479 stopRebufferingTimer(true);
2480
2481 cancelPollDuration();
2482
2483 ++mScanSourcesGeneration;
2484 mScanSourcesPending = false;
2485
2486 if (mRendererLooper != NULL) {
2487 if (mRenderer != NULL) {
2488 mRendererLooper->unregisterHandler(mRenderer->id());
2489 }
2490 mRendererLooper->stop();
2491 mRendererLooper.clear();
2492 }
2493 mRenderer.clear();
2494 ++mRendererGeneration;
2495
Wei Jiaf01e3122018-10-18 11:49:44 -07002496 if (mCurrentSourceInfo.mSource != NULL) {
2497 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08002498
2499 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002500 mCurrentSourceInfo.mSource.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08002501 }
2502
2503 if (mDriver != NULL) {
2504 sp<NuPlayer2Driver> driver = mDriver.promote();
2505 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002506 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002507 }
2508 }
2509
2510 mStarted = false;
2511 mPrepared = false;
2512 mResetting = false;
2513 mSourceStarted = false;
2514
2515 // Modular DRM
2516 if (mCrypto != NULL) {
2517 // decoders will be flushed before this so their mCrypto would go away on their own
2518 // TODO change to ALOGV
2519 ALOGD("performReset mCrypto: %p", mCrypto.get());
2520 mCrypto.clear();
2521 }
2522 mIsDrmProtected = false;
2523}
2524
Wei Jia57aeffd2018-02-15 16:01:14 -08002525void NuPlayer2::performPlayNextDataSource() {
2526 ALOGV("performPlayNextDataSource");
2527
2528 CHECK(mAudioDecoder == NULL);
2529 CHECK(mVideoDecoder == NULL);
2530
2531 stopPlaybackTimer("performPlayNextDataSource");
2532 stopRebufferingTimer(true);
2533
2534 cancelPollDuration();
2535
2536 ++mScanSourcesGeneration;
2537 mScanSourcesPending = false;
2538
2539 ++mRendererGeneration;
2540
Wei Jiaf01e3122018-10-18 11:49:44 -07002541 if (mCurrentSourceInfo.mSource != NULL) {
2542 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002543 }
2544
2545 long previousSrcId;
2546 {
2547 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002548 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002549
2550 mCurrentSourceInfo = mNextSourceInfo;
2551 mNextSourceInfo = SourceInfo();
2552 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002553 }
2554
2555 if (mDriver != NULL) {
2556 sp<NuPlayer2Driver> driver = mDriver.promote();
2557 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002558 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002559
2560 int64_t durationUs;
2561 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2562 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2563 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002564 notifyListener(
2565 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002566 }
2567 }
2568
2569 mStarted = false;
2570 mPrepared = true; // TODO: what if it's not prepared
2571 mResetting = false;
2572 mSourceStarted = false;
2573
Wei Jiad1864f92018-10-19 12:34:56 -07002574 addEndTimeMonitor();
2575
Wei Jia57aeffd2018-02-15 16:01:14 -08002576 // Modular DRM
2577 if (mCrypto != NULL) {
2578 // decoders will be flushed before this so their mCrypto would go away on their own
2579 // TODO change to ALOGV
2580 ALOGD("performReset mCrypto: %p", mCrypto.get());
2581 mCrypto.clear();
2582 }
2583 mIsDrmProtected = false;
2584
2585 if (mRenderer != NULL) {
2586 mRenderer->resume();
2587 }
2588
Wei Jia6376cd52018-09-26 11:42:55 -07002589 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002590 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002591 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002592}
2593
Wei Jia53692fa2017-12-11 10:33:46 -08002594void NuPlayer2::performScanSources() {
2595 ALOGV("performScanSources");
2596
2597 if (!mStarted) {
2598 return;
2599 }
2600
2601 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2602 postScanSources();
2603 }
2604}
2605
Wei Jia28288fb2017-12-15 13:45:29 -08002606void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002607 ALOGV("performSetSurface");
2608
Wei Jia28288fb2017-12-15 13:45:29 -08002609 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002610
2611 // XXX - ignore error from setVideoScalingMode for now
2612 setVideoScalingMode(mVideoScalingMode);
2613
2614 if (mDriver != NULL) {
2615 sp<NuPlayer2Driver> driver = mDriver.promote();
2616 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002617 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002618 }
2619 }
2620}
2621
2622void NuPlayer2::performResumeDecoders(bool needNotify) {
2623 if (needNotify) {
2624 mResumePending = true;
2625 if (mVideoDecoder == NULL) {
2626 // if audio-only, we can notify seek complete now,
2627 // as the resume operation will be relatively fast.
2628 finishResume();
2629 }
2630 }
2631
2632 if (mVideoDecoder != NULL) {
2633 // When there is continuous seek, MediaPlayer will cache the seek
2634 // position, and send down new seek request when previous seek is
2635 // complete. Let's wait for at least one video output frame before
2636 // notifying seek complete, so that the video thumbnail gets updated
2637 // when seekbar is dragged.
2638 mVideoDecoder->signalResume(needNotify);
2639 }
2640
2641 if (mAudioDecoder != NULL) {
2642 mAudioDecoder->signalResume(false /* needNotify */);
2643 }
2644}
2645
2646void NuPlayer2::finishResume() {
2647 if (mResumePending) {
2648 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002649 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002650 }
2651}
2652
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002653void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002654 if (mDriver != NULL) {
2655 sp<NuPlayer2Driver> driver = mDriver.promote();
2656 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002657 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002658 }
2659 }
2660}
2661
2662void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2663 int32_t what;
2664 CHECK(msg->findInt32("what", &what));
2665
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002666 int64_t srcId;
2667 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002668 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002669 case Source::kWhatPrepared:
2670 {
Wei Jiad1864f92018-10-19 12:34:56 -07002671 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2672 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2673 if (srcId == mCurrentSourceInfo.mSrcId) {
2674 if (mCurrentSourceInfo.mSource == NULL) {
2675 // This is a stale notification from a source that was
2676 // asynchronously preparing when the client called reset().
2677 // We handled the reset, the source is gone.
2678 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002679 }
Wei Jiad1864f92018-10-19 12:34:56 -07002680
2681 int32_t err;
2682 CHECK(msg->findInt32("err", &err));
2683
2684 if (err != OK) {
2685 // shut down potential secure codecs in case client never calls reset
2686 mDeferredActions.push_back(
2687 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2688 FLUSH_CMD_SHUTDOWN /* video */));
2689 processDeferredActions();
2690 } else {
2691 mPrepared = true;
2692 }
2693
2694 sp<NuPlayer2Driver> driver = mDriver.promote();
2695 if (driver != NULL) {
2696 // notify duration first, so that it's definitely set when
2697 // the app received the "prepare complete" callback.
2698 int64_t durationUs;
2699 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2700 driver->notifyDuration(srcId, durationUs);
2701 }
2702 driver->notifyPrepareCompleted(srcId, err);
2703 }
2704 } else if (srcId == mNextSourceInfo.mSrcId) {
2705 if (mNextSourceInfo.mSource == NULL) {
2706 break; // stale
2707 }
2708
2709 sp<NuPlayer2Driver> driver = mDriver.promote();
2710 if (driver != NULL) {
2711 int32_t err;
2712 CHECK(msg->findInt32("err", &err));
2713 driver->notifyPrepareCompleted(srcId, err);
2714 }
Wei Jia53692fa2017-12-11 10:33:46 -08002715 }
2716
2717 break;
2718 }
2719
2720 // Modular DRM
2721 case Source::kWhatDrmInfo:
2722 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002723 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002724 sp<ABuffer> drmInfo;
2725 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002726 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002727
Dongwon Kang41929fb2018-09-09 08:29:56 -07002728 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2729 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002730
Dongwon Kang41929fb2018-09-09 08:29:56 -07002731 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002732
2733 break;
2734 }
2735
2736 case Source::kWhatFlagsChanged:
2737 {
2738 uint32_t flags;
2739 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2740
2741 sp<NuPlayer2Driver> driver = mDriver.promote();
2742 if (driver != NULL) {
2743
2744 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2745 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2746 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2747 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2748 (flags & Source::FLAG_CAN_PAUSE) != 0,
2749 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2750 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2751 (flags & Source::FLAG_CAN_SEEK) != 0,
2752 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2753 (flags & Source::FLAG_SECURE) != 0,
2754 (flags & Source::FLAG_PROTECTED) != 0);
2755
2756 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2757 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002758 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002759 }
Wei Jiad1864f92018-10-19 12:34:56 -07002760 if (srcId == mCurrentSourceInfo.mSrcId) {
2761 driver->notifyFlagsChanged(srcId, flags);
2762 }
Wei Jia53692fa2017-12-11 10:33:46 -08002763 }
2764
Wei Jiaf01e3122018-10-18 11:49:44 -07002765 if (srcId == mCurrentSourceInfo.mSrcId) {
2766 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2767 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2768 cancelPollDuration();
2769 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2770 && (flags & Source::FLAG_DYNAMIC_DURATION)
2771 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2772 schedulePollDuration();
2773 }
Wei Jia53692fa2017-12-11 10:33:46 -08002774
Wei Jiaf01e3122018-10-18 11:49:44 -07002775 mCurrentSourceInfo.mSourceFlags = flags;
2776 } else if (srcId == mNextSourceInfo.mSrcId) {
2777 // TODO: handle duration polling for next source.
2778 mNextSourceInfo.mSourceFlags = flags;
2779 }
Wei Jia53692fa2017-12-11 10:33:46 -08002780 break;
2781 }
2782
2783 case Source::kWhatVideoSizeChanged:
2784 {
2785 sp<AMessage> format;
2786 CHECK(msg->findMessage("format", &format));
2787
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002788 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002789 break;
2790 }
2791
2792 case Source::kWhatBufferingUpdate:
2793 {
2794 int32_t percentage;
2795 CHECK(msg->findInt32("percentage", &percentage));
2796
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002797 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002798 break;
2799 }
2800
2801 case Source::kWhatPauseOnBufferingStart:
2802 {
2803 // ignore if not playing
2804 if (mStarted) {
2805 ALOGI("buffer low, pausing...");
2806
2807 startRebufferingTimer();
2808 mPausedForBuffering = true;
2809 onPause();
2810 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002811 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002812 break;
2813 }
2814
2815 case Source::kWhatResumeOnBufferingEnd:
2816 {
2817 // ignore if not playing
2818 if (mStarted) {
2819 ALOGI("buffer ready, resuming...");
2820
2821 stopRebufferingTimer(false);
2822 mPausedForBuffering = false;
2823
2824 // do not resume yet if client didn't unpause
2825 if (!mPausedByClient) {
2826 onResume();
2827 }
2828 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002829 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002830 break;
2831 }
2832
2833 case Source::kWhatCacheStats:
2834 {
2835 int32_t kbps;
2836 CHECK(msg->findInt32("bandwidth", &kbps));
2837
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002838 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002839 break;
2840 }
2841
2842 case Source::kWhatSubtitleData:
2843 {
2844 sp<ABuffer> buffer;
2845 CHECK(msg->findBuffer("buffer", &buffer));
2846
2847 sendSubtitleData(buffer, 0 /* baseIndex */);
2848 break;
2849 }
2850
2851 case Source::kWhatTimedMetaData:
2852 {
2853 sp<ABuffer> buffer;
2854 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002855 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002856 } else {
2857 sendTimedMetaData(buffer);
2858 }
2859 break;
2860 }
2861
2862 case Source::kWhatTimedTextData:
2863 {
2864 int32_t generation;
2865 if (msg->findInt32("generation", &generation)
2866 && generation != mTimedTextGeneration) {
2867 break;
2868 }
2869
2870 sp<ABuffer> buffer;
2871 CHECK(msg->findBuffer("buffer", &buffer));
2872
2873 sp<NuPlayer2Driver> driver = mDriver.promote();
2874 if (driver == NULL) {
2875 break;
2876 }
2877
Wei Jia800fe372018-02-20 15:00:45 -08002878 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002879 int64_t timeUs, posUs;
2880 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002881 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002882 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2883
2884 if (posUs < timeUs) {
2885 if (!msg->findInt32("generation", &generation)) {
2886 msg->setInt32("generation", mTimedTextGeneration);
2887 }
2888 msg->post(timeUs - posUs);
2889 } else {
2890 sendTimedTextData(buffer);
2891 }
2892 break;
2893 }
2894
2895 case Source::kWhatQueueDecoderShutdown:
2896 {
2897 int32_t audio, video;
2898 CHECK(msg->findInt32("audio", &audio));
2899 CHECK(msg->findInt32("video", &video));
2900
2901 sp<AMessage> reply;
2902 CHECK(msg->findMessage("reply", &reply));
2903
2904 queueDecoderShutdown(audio, video, reply);
2905 break;
2906 }
2907
2908 case Source::kWhatDrmNoLicense:
2909 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002910 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002911 break;
2912 }
2913
2914 default:
2915 TRESPASS();
2916 }
2917}
2918
2919void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2920 int32_t what;
2921 CHECK(msg->findInt32("what", &what));
2922
2923 switch (what) {
2924 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2925 {
2926 sp<ABuffer> buffer;
2927 CHECK(msg->findBuffer("buffer", &buffer));
2928
2929 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002930 if (mCurrentSourceInfo.mSource != NULL) {
2931 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002932 }
2933
2934 sendSubtitleData(buffer, inbandTracks);
2935 break;
2936 }
2937
2938 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2939 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002940 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002941
2942 break;
2943 }
2944
2945 default:
2946 TRESPASS();
2947 }
2948
2949
2950}
2951
2952void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2953 int32_t trackIndex;
2954 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002955 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002956 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2957 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2958
Dongwon Kang41929fb2018-09-09 08:29:56 -07002959 PlayerMessage playerMsg;
2960 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2961 playerMsg.add_values()->set_int64_value(timeUs);
2962 playerMsg.add_values()->set_int64_value(durationUs);
2963 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002964
Wei Jiaf01e3122018-10-18 11:49:44 -07002965 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002966}
2967
2968void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2969 int64_t timeUs;
2970 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2971
Dongwon Kang41929fb2018-09-09 08:29:56 -07002972 PlayerMessage playerMsg;
2973 playerMsg.add_values()->set_int64_value(timeUs);
2974 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002975
Wei Jiaf01e3122018-10-18 11:49:44 -07002976 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002977}
2978
2979void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2980 const void *data;
2981 size_t size = 0;
2982 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002983 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002984
2985 AString mime;
2986 CHECK(buffer->meta()->findString("mime", &mime));
2987 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2988
2989 data = buffer->data();
2990 size = buffer->size();
2991
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002992 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002993 if (size > 0) {
2994 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2995 int32_t global = 0;
2996 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002997 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002998 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002999 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003000 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003001 TextDescriptions2::getPlayerMessageOfDescriptions(
3002 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003003 }
3004
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003005 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003006 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003007 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003008 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003009 }
3010}
3011
3012const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003013 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003014 case DATA_SOURCE_TYPE_HTTP_LIVE:
3015 return "HTTPLive";
3016
3017 case DATA_SOURCE_TYPE_RTSP:
3018 return "RTSP";
3019
3020 case DATA_SOURCE_TYPE_GENERIC_URL:
3021 return "GenURL";
3022
3023 case DATA_SOURCE_TYPE_GENERIC_FD:
3024 return "GenFD";
3025
3026 case DATA_SOURCE_TYPE_MEDIA:
3027 return "Media";
3028
Wei Jia53692fa2017-12-11 10:33:46 -08003029 case DATA_SOURCE_TYPE_NONE:
3030 default:
3031 return "None";
3032 }
3033 }
3034
3035// Modular DRM begin
3036status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3037{
3038 ALOGV("prepareDrm ");
3039
3040 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3041 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3042 // synchronous call so just passing the address but with local copies of "const" args
3043 uint8_t UUID[16];
3044 memcpy(UUID, uuid, sizeof(UUID));
3045 Vector<uint8_t> sessionId = drmSessionId;
3046 msg->setPointer("uuid", (void*)UUID);
3047 msg->setPointer("drmSessionId", (void*)&sessionId);
3048
3049 sp<AMessage> response;
3050 status_t status = msg->postAndAwaitResponse(&response);
3051
3052 if (status == OK && response != NULL) {
3053 CHECK(response->findInt32("status", &status));
3054 ALOGV("prepareDrm ret: %d ", status);
3055 } else {
3056 ALOGE("prepareDrm err: %d", status);
3057 }
3058
3059 return status;
3060}
3061
3062status_t NuPlayer2::releaseDrm()
3063{
3064 ALOGV("releaseDrm ");
3065
3066 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3067
3068 sp<AMessage> response;
3069 status_t status = msg->postAndAwaitResponse(&response);
3070
3071 if (status == OK && response != NULL) {
3072 CHECK(response->findInt32("status", &status));
3073 ALOGV("releaseDrm ret: %d ", status);
3074 } else {
3075 ALOGE("releaseDrm err: %d", status);
3076 }
3077
3078 return status;
3079}
3080
3081status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3082{
3083 // TODO change to ALOGV
3084 ALOGD("onPrepareDrm ");
3085
3086 status_t status = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -07003087 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003088 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3089 return status;
3090 }
3091
3092 uint8_t *uuid;
3093 Vector<uint8_t> *drmSessionId;
3094 CHECK(msg->findPointer("uuid", (void**)&uuid));
3095 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3096
3097 status = OK;
3098 sp<AMediaCryptoWrapper> crypto = NULL;
3099
Wei Jiaf01e3122018-10-18 11:49:44 -07003100 status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003101 if (crypto == NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003102 ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
Wei Jia53692fa2017-12-11 10:33:46 -08003103 return status;
3104 }
Wei Jiaf01e3122018-10-18 11:49:44 -07003105 ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
Wei Jia53692fa2017-12-11 10:33:46 -08003106
3107 if (mCrypto != NULL) {
3108 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3109 mCrypto.clear();
3110 }
3111
3112 mCrypto = crypto;
3113 mIsDrmProtected = true;
3114 // TODO change to ALOGV
3115 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3116
3117 return status;
3118}
3119
3120status_t NuPlayer2::onReleaseDrm()
3121{
3122 // TODO change to ALOGV
3123 ALOGD("onReleaseDrm ");
3124
3125 if (!mIsDrmProtected) {
3126 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3127 }
3128
3129 mIsDrmProtected = false;
3130
3131 status_t status;
3132 if (mCrypto != NULL) {
3133 // notifying the source first before removing crypto from codec
Wei Jiaf01e3122018-10-18 11:49:44 -07003134 if (mCurrentSourceInfo.mSource != NULL) {
3135 mCurrentSourceInfo.mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003136 }
3137
3138 status=OK;
3139 // first making sure the codecs have released their crypto reference
3140 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3141 if (videoDecoder != NULL) {
3142 status = videoDecoder->releaseCrypto();
3143 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3144 }
3145
3146 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3147 if (audioDecoder != NULL) {
3148 status_t status_audio = audioDecoder->releaseCrypto();
3149 if (status == OK) { // otherwise, returning the first error
3150 status = status_audio;
3151 }
3152 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3153 }
3154
3155 // TODO change to ALOGV
3156 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3157 mCrypto.clear();
3158 } else { // mCrypto == NULL
3159 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3160 status = INVALID_OPERATION;
3161 }
3162
3163 return status;
3164}
3165// Modular DRM end
3166////////////////////////////////////////////////////////////////////////////////
3167
3168sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3169 sp<MetaData> meta = getFormatMeta(audio);
3170
3171 if (meta == NULL) {
3172 return NULL;
3173 }
3174
3175 sp<AMessage> msg = new AMessage;
3176
3177 if(convertMetaDataToMessage(meta, &msg) == OK) {
3178 return msg;
3179 }
3180 return NULL;
3181}
3182
3183void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3184 sp<AMessage> notify = dupNotify();
3185 notify->setInt32("what", kWhatFlagsChanged);
3186 notify->setInt32("flags", flags);
3187 notify->post();
3188}
3189
3190void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3191 sp<AMessage> notify = dupNotify();
3192 notify->setInt32("what", kWhatVideoSizeChanged);
3193 notify->setMessage("format", format);
3194 notify->post();
3195}
3196
3197void NuPlayer2::Source::notifyPrepared(status_t err) {
3198 ALOGV("Source::notifyPrepared %d", err);
3199 sp<AMessage> notify = dupNotify();
3200 notify->setInt32("what", kWhatPrepared);
3201 notify->setInt32("err", err);
3202 notify->post();
3203}
3204
3205void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3206{
3207 ALOGV("Source::notifyDrmInfo");
3208
3209 sp<AMessage> notify = dupNotify();
3210 notify->setInt32("what", kWhatDrmInfo);
3211 notify->setBuffer("drmInfo", drmInfoBuffer);
3212
3213 notify->post();
3214}
3215
Wei Jia53692fa2017-12-11 10:33:46 -08003216void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3217 TRESPASS();
3218}
3219
Wei Jiaf01e3122018-10-18 11:49:44 -07003220NuPlayer2::SourceInfo::SourceInfo()
3221 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3222 mSrcId(0),
3223 mSourceFlags(0),
3224 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003225 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003226}
3227
Wei Jiad1864f92018-10-19 12:34:56 -07003228NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3229 mSource = other.mSource;
3230 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3231 mSrcId = other.mSrcId;
3232 mSourceFlags = other.mSourceFlags;
3233 mStartTimeUs = other.mStartTimeUs;
3234 mEndTimeUs = other.mEndTimeUs;
3235 return *this;
3236}
3237
Wei Jia53692fa2017-12-11 10:33:46 -08003238} // namespace android