blob: 5b7bf4a52b798edcae5802b9087a8613bef5739d [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
Wei Jia72bf2a02018-02-06 15:29:23 -0800311 err = genericSource->setDataSource(httpService, 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) {
646 switch (msg->what()) {
647 case kWhatSetDataSource:
648 {
649 ALOGV("kWhatSetDataSource");
650
Wei Jiaf01e3122018-10-18 11:49:44 -0700651 CHECK(mCurrentSourceInfo.mSource == NULL);
Wei Jia53692fa2017-12-11 10:33:46 -0800652
653 status_t err = OK;
654 sp<RefBase> obj;
655 CHECK(msg->findObject("source", &obj));
656 if (obj != NULL) {
657 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700658 CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
659 CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
660 CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
661 mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800662 } else {
663 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800664 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800665 }
666
667 CHECK(mDriver != NULL);
668 sp<NuPlayer2Driver> driver = mDriver.promote();
669 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700670 driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800671 }
672 break;
673 }
674
Wei Jia72bf2a02018-02-06 15:29:23 -0800675 case kWhatPrepareNextDataSource:
676 {
677 ALOGV("kWhatPrepareNextDataSource");
678
679 status_t err = OK;
680 sp<RefBase> obj;
681 CHECK(msg->findObject("source", &obj));
682 if (obj != NULL) {
683 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700684 CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
685 CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
686 CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
687 mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
688 mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
Wei Jia72bf2a02018-02-06 15:29:23 -0800689 } else {
690 err = UNKNOWN_ERROR;
691 }
692
693 break;
694 }
695
Wei Jia57aeffd2018-02-15 16:01:14 -0800696 case kWhatPlayNextDataSource:
697 {
698 ALOGV("kWhatPlayNextDataSource");
699 int64_t srcId;
700 CHECK(msg->findInt64("srcId", &srcId));
Wei Jiaf01e3122018-10-18 11:49:44 -0700701 if (srcId != mNextSourceInfo.mSrcId) {
Wei Jia57aeffd2018-02-15 16:01:14 -0800702 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
703 return;
704 }
705
706 mResetting = true;
707 stopPlaybackTimer("kWhatPlayNextDataSource");
708 stopRebufferingTimer(true);
709
710 mDeferredActions.push_back(
711 new FlushDecoderAction(
712 FLUSH_CMD_SHUTDOWN /* audio */,
713 FLUSH_CMD_SHUTDOWN /* video */));
714
715 mDeferredActions.push_back(
716 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
717
718 processDeferredActions();
719 break;
720 }
721
Wei Jiad1864f92018-10-19 12:34:56 -0700722 case kWhatEOSMonitor:
723 {
724 int32_t generation;
725 CHECK(msg->findInt32("generation", &generation));
726 int32_t reason;
727 CHECK(msg->findInt32("reason", &reason));
728
729 if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
730 break; // stale or reset
731 }
732
733 ALOGV("kWhatEOSMonitor");
734 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
735 break;
736 }
737
Wei Jia53692fa2017-12-11 10:33:46 -0800738 case kWhatGetBufferingSettings:
739 {
740 sp<AReplyToken> replyID;
741 CHECK(msg->senderAwaitsResponse(&replyID));
742
743 ALOGV("kWhatGetBufferingSettings");
744 BufferingSettings buffering;
745 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700746 if (mCurrentSourceInfo.mSource != NULL) {
747 err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800748 } else {
749 err = INVALID_OPERATION;
750 }
751 sp<AMessage> response = new AMessage;
752 if (err == OK) {
753 writeToAMessage(response, buffering);
754 }
755 response->setInt32("err", err);
756 response->postReply(replyID);
757 break;
758 }
759
760 case kWhatSetBufferingSettings:
761 {
762 sp<AReplyToken> replyID;
763 CHECK(msg->senderAwaitsResponse(&replyID));
764
765 ALOGV("kWhatSetBufferingSettings");
766 BufferingSettings buffering;
767 readFromAMessage(msg, &buffering);
768 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700769 if (mCurrentSourceInfo.mSource != NULL) {
770 err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800771 } else {
772 err = INVALID_OPERATION;
773 }
774 sp<AMessage> response = new AMessage;
775 response->setInt32("err", err);
776 response->postReply(replyID);
777 break;
778 }
779
780 case kWhatPrepare:
781 {
782 ALOGV("onMessageReceived kWhatPrepare");
783
Wei Jiaf01e3122018-10-18 11:49:44 -0700784 mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800785 break;
786 }
787
788 case kWhatGetTrackInfo:
789 {
790 sp<AReplyToken> replyID;
791 CHECK(msg->senderAwaitsResponse(&replyID));
792
Dongwon Kang9f631982018-07-10 12:34:41 -0700793 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800794 CHECK(msg->findPointer("reply", (void**)&reply));
795
796 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700797 if (mCurrentSourceInfo.mSource != NULL) {
798 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800799 }
800
801 size_t ccTracks = 0;
802 if (mCCDecoder != NULL) {
803 ccTracks = mCCDecoder->getTrackCount();
804 }
805
806 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700807 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800808
809 // write inband tracks
810 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700811 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800812 }
813
814 // write CC track
815 for (size_t i = 0; i < ccTracks; ++i) {
816 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
817 }
818
819 sp<AMessage> response = new AMessage;
820 response->postReply(replyID);
821 break;
822 }
823
824 case kWhatGetSelectedTrack:
825 {
826 status_t err = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -0700827 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800828 err = OK;
829
830 int32_t type32;
831 CHECK(msg->findInt32("type", (int32_t*)&type32));
832 media_track_type type = (media_track_type)type32;
Wei Jiaf01e3122018-10-18 11:49:44 -0700833 ssize_t selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800834
Dongwon Kang9f631982018-07-10 12:34:41 -0700835 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800836 CHECK(msg->findPointer("reply", (void**)&reply));
Dongwon Kang9f631982018-07-10 12:34:41 -0700837 reply->add_values()->set_int32_value(selectedTrack);
Wei Jia53692fa2017-12-11 10:33:46 -0800838 }
839
840 sp<AMessage> response = new AMessage;
841 response->setInt32("err", err);
842
843 sp<AReplyToken> replyID;
844 CHECK(msg->senderAwaitsResponse(&replyID));
845 response->postReply(replyID);
846 break;
847 }
848
849 case kWhatSelectTrack:
850 {
851 sp<AReplyToken> replyID;
852 CHECK(msg->senderAwaitsResponse(&replyID));
853
854 size_t trackIndex;
855 int32_t select;
856 int64_t timeUs;
857 CHECK(msg->findSize("trackIndex", &trackIndex));
858 CHECK(msg->findInt32("select", &select));
859 CHECK(msg->findInt64("timeUs", &timeUs));
860
861 status_t err = INVALID_OPERATION;
862
863 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700864 if (mCurrentSourceInfo.mSource != NULL) {
865 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800866 }
867 size_t ccTracks = 0;
868 if (mCCDecoder != NULL) {
869 ccTracks = mCCDecoder->getTrackCount();
870 }
871
872 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700873 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800874
875 if (!select && err == OK) {
876 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700877 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800878 if (info != NULL
879 && info->findInt32("type", &type)
880 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
881 ++mTimedTextGeneration;
882 }
883 }
884 } else {
885 trackIndex -= inbandTracks;
886
887 if (trackIndex < ccTracks) {
888 err = mCCDecoder->selectTrack(trackIndex, select);
889 }
890 }
891
892 sp<AMessage> response = new AMessage;
893 response->setInt32("err", err);
894
895 response->postReply(replyID);
896 break;
897 }
898
899 case kWhatPollDuration:
900 {
901 int32_t generation;
902 CHECK(msg->findInt32("generation", &generation));
903
904 if (generation != mPollDurationGeneration) {
905 // stale
906 break;
907 }
908
909 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700910 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800911 sp<NuPlayer2Driver> driver = mDriver.promote();
912 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700913 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800914 }
915 }
916
917 msg->post(1000000ll); // poll again in a second.
918 break;
919 }
920
921 case kWhatSetVideoSurface:
922 {
923
924 sp<RefBase> obj;
925 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800926 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800927
928 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800929 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700930 (mCurrentSourceInfo.mSource != NULL && mStarted
931 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800932 && mVideoDecoder != NULL) ? "have" : "no");
933
Wei Jiaf01e3122018-10-18 11:49:44 -0700934 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
935 // because NuPlayer2 might be in preparing state and it could take long time.
936 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
937 if (mCurrentSourceInfo.mSource == NULL || !mStarted
938 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800939 // NOTE: mVideoDecoder's mNativeWindow is always non-null
940 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
941 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800942 break;
943 }
944
945 mDeferredActions.push_back(
946 new FlushDecoderAction(
947 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
948 FLUSH_CMD_SHUTDOWN /* video */));
949
Wei Jia28288fb2017-12-15 13:45:29 -0800950 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800951
952 if (obj != NULL) {
953 if (mStarted) {
954 // Issue a seek to refresh the video screen only if started otherwise
955 // the extractor may not yet be started and will assert.
956 // If the video decoder is not set (perhaps audio only in this case)
957 // do not perform a seek as it is not needed.
958 int64_t currentPositionUs = 0;
959 if (getCurrentPosition(&currentPositionUs) == OK) {
960 mDeferredActions.push_back(
961 new SeekAction(currentPositionUs,
962 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
963 }
964 }
965
966 // If there is a new surface texture, instantiate decoders
967 // again if possible.
968 mDeferredActions.push_back(
969 new SimpleAction(&NuPlayer2::performScanSources));
970
971 // After a flush without shutdown, decoder is paused.
972 // Don't resume it until source seek is done, otherwise it could
973 // start pulling stale data too soon.
974 mDeferredActions.push_back(
975 new ResumeDecoderAction(false /* needNotify */));
976 }
977
978 processDeferredActions();
979 break;
980 }
981
982 case kWhatSetAudioSink:
983 {
984 ALOGV("kWhatSetAudioSink");
985
986 sp<RefBase> obj;
987 CHECK(msg->findObject("sink", &obj));
988
Wei Jia33abcc72018-01-30 09:47:38 -0800989 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800990 break;
991 }
992
993 case kWhatStart:
994 {
995 ALOGV("kWhatStart");
996 if (mStarted) {
997 // do not resume yet if the source is still buffering
998 if (!mPausedForBuffering) {
999 onResume();
1000 }
1001 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001002 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001003 }
1004 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001005 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001006 break;
1007 }
1008
1009 case kWhatConfigPlayback:
1010 {
1011 sp<AReplyToken> replyID;
1012 CHECK(msg->senderAwaitsResponse(&replyID));
1013 AudioPlaybackRate rate /* sanitized */;
1014 readFromAMessage(msg, &rate);
1015 status_t err = OK;
1016 if (mRenderer != NULL) {
1017 // AudioSink allows only 1.f and 0.f for offload mode.
1018 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001019 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001020 int64_t currentPositionUs;
1021 if (getCurrentPosition(&currentPositionUs) != OK) {
1022 currentPositionUs = mPreviousSeekTimeUs;
1023 }
1024
1025 // Set mPlaybackSettings so that the new audio decoder can
1026 // be created correctly.
1027 mPlaybackSettings = rate;
1028 if (!mPaused) {
1029 mRenderer->pause();
1030 }
1031 restartAudio(
1032 currentPositionUs, true /* forceNonOffload */,
1033 true /* needsToCreateAudioDecoder */);
1034 if (!mPaused) {
1035 mRenderer->resume();
1036 }
1037 }
1038
1039 err = mRenderer->setPlaybackSettings(rate);
1040 }
1041 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001042 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001043
Wei Jia700a7c22018-09-14 18:04:35 -07001044 if (mVideoDecoder != NULL) {
1045 sp<AMessage> params = new AMessage();
1046 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1047 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001048 }
1049 }
1050
Wei Jia53692fa2017-12-11 10:33:46 -08001051 sp<AMessage> response = new AMessage;
1052 response->setInt32("err", err);
1053 response->postReply(replyID);
1054 break;
1055 }
1056
1057 case kWhatGetPlaybackSettings:
1058 {
1059 sp<AReplyToken> replyID;
1060 CHECK(msg->senderAwaitsResponse(&replyID));
1061 AudioPlaybackRate rate = mPlaybackSettings;
1062 status_t err = OK;
1063 if (mRenderer != NULL) {
1064 err = mRenderer->getPlaybackSettings(&rate);
1065 }
1066 if (err == OK) {
1067 // get playback settings used by renderer, as it may be
1068 // slightly off due to audiosink not taking small changes.
1069 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001070 }
1071 sp<AMessage> response = new AMessage;
1072 if (err == OK) {
1073 writeToAMessage(response, rate);
1074 }
1075 response->setInt32("err", err);
1076 response->postReply(replyID);
1077 break;
1078 }
1079
1080 case kWhatConfigSync:
1081 {
1082 sp<AReplyToken> replyID;
1083 CHECK(msg->senderAwaitsResponse(&replyID));
1084
1085 ALOGV("kWhatConfigSync");
1086 AVSyncSettings sync;
1087 float videoFpsHint;
1088 readFromAMessage(msg, &sync, &videoFpsHint);
1089 status_t err = OK;
1090 if (mRenderer != NULL) {
1091 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1092 }
1093 if (err == OK) {
1094 mSyncSettings = sync;
1095 mVideoFpsHint = videoFpsHint;
1096 }
1097 sp<AMessage> response = new AMessage;
1098 response->setInt32("err", err);
1099 response->postReply(replyID);
1100 break;
1101 }
1102
1103 case kWhatGetSyncSettings:
1104 {
1105 sp<AReplyToken> replyID;
1106 CHECK(msg->senderAwaitsResponse(&replyID));
1107 AVSyncSettings sync = mSyncSettings;
1108 float videoFps = mVideoFpsHint;
1109 status_t err = OK;
1110 if (mRenderer != NULL) {
1111 err = mRenderer->getSyncSettings(&sync, &videoFps);
1112 if (err == OK) {
1113 mSyncSettings = sync;
1114 mVideoFpsHint = videoFps;
1115 }
1116 }
1117 sp<AMessage> response = new AMessage;
1118 if (err == OK) {
1119 writeToAMessage(response, sync, videoFps);
1120 }
1121 response->setInt32("err", err);
1122 response->postReply(replyID);
1123 break;
1124 }
1125
1126 case kWhatScanSources:
1127 {
1128 int32_t generation;
1129 CHECK(msg->findInt32("generation", &generation));
1130 if (generation != mScanSourcesGeneration) {
1131 // Drop obsolete msg.
1132 break;
1133 }
1134
1135 mScanSourcesPending = false;
1136
1137 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1138 mAudioDecoder != NULL, mVideoDecoder != NULL);
1139
1140 bool mHadAnySourcesBefore =
1141 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1142 bool rescan = false;
1143
1144 // initialize video before audio because successful initialization of
1145 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001146 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001147 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1148 rescan = true;
1149 }
1150 }
1151
1152 // Don't try to re-open audio sink if there's an existing decoder.
1153 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1154 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1155 rescan = true;
1156 }
1157 }
1158
1159 if (!mHadAnySourcesBefore
1160 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1161 // This is the first time we've found anything playable.
1162
Wei Jiaf01e3122018-10-18 11:49:44 -07001163 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001164 schedulePollDuration();
1165 }
1166 }
1167
1168 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001169 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001170 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1171 // We're not currently decoding anything (no audio or
1172 // video tracks found) and we just ran out of input data.
1173
1174 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001175 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001176 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001177 notifyListener(
1178 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001179 }
1180 }
1181 break;
1182 }
1183
1184 if (rescan) {
1185 msg->post(100000ll);
1186 mScanSourcesPending = true;
1187 }
1188 break;
1189 }
1190
1191 case kWhatVideoNotify:
1192 case kWhatAudioNotify:
1193 {
1194 bool audio = msg->what() == kWhatAudioNotify;
1195
1196 int32_t currentDecoderGeneration =
1197 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1198 int32_t requesterGeneration = currentDecoderGeneration - 1;
1199 CHECK(msg->findInt32("generation", &requesterGeneration));
1200
1201 if (requesterGeneration != currentDecoderGeneration) {
1202 ALOGV("got message from old %s decoder, generation(%d:%d)",
1203 audio ? "audio" : "video", requesterGeneration,
1204 currentDecoderGeneration);
1205 sp<AMessage> reply;
1206 if (!(msg->findMessage("reply", &reply))) {
1207 return;
1208 }
1209
1210 reply->setInt32("err", INFO_DISCONTINUITY);
1211 reply->post();
1212 return;
1213 }
1214
1215 int32_t what;
1216 CHECK(msg->findInt32("what", &what));
1217
1218 if (what == DecoderBase::kWhatInputDiscontinuity) {
1219 int32_t formatChange;
1220 CHECK(msg->findInt32("formatChange", &formatChange));
1221
1222 ALOGV("%s discontinuity: formatChange %d",
1223 audio ? "audio" : "video", formatChange);
1224
1225 if (formatChange) {
1226 mDeferredActions.push_back(
1227 new FlushDecoderAction(
1228 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1229 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1230 }
1231
1232 mDeferredActions.push_back(
1233 new SimpleAction(
1234 &NuPlayer2::performScanSources));
1235
1236 processDeferredActions();
1237 } else if (what == DecoderBase::kWhatEOS) {
1238 int32_t err;
1239 CHECK(msg->findInt32("err", &err));
1240
1241 if (err == ERROR_END_OF_STREAM) {
1242 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1243 } else {
1244 ALOGV("got %s decoder EOS w/ error %d",
1245 audio ? "audio" : "video",
1246 err);
1247 }
1248
1249 mRenderer->queueEOS(audio, err);
1250 } else if (what == DecoderBase::kWhatFlushCompleted) {
1251 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1252
1253 handleFlushComplete(audio, true /* isDecoder */);
1254 finishFlushIfPossible();
1255 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1256 sp<AMessage> format;
1257 CHECK(msg->findMessage("format", &format));
1258
1259 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001260 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001261
1262 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001263 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001264 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1265 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1266 if (audio) {
1267 mAudioDecoder.clear();
1268 mAudioDecoderError = false;
1269 ++mAudioDecoderGeneration;
1270
1271 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1272 mFlushingAudio = SHUT_DOWN;
1273 } else {
1274 mVideoDecoder.clear();
1275 mVideoDecoderError = false;
1276 ++mVideoDecoderGeneration;
1277
1278 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1279 mFlushingVideo = SHUT_DOWN;
1280 }
1281
1282 finishFlushIfPossible();
1283 } else if (what == DecoderBase::kWhatResumeCompleted) {
1284 finishResume();
1285 } else if (what == DecoderBase::kWhatError) {
1286 status_t err;
1287 if (!msg->findInt32("err", &err) || err == OK) {
1288 err = UNKNOWN_ERROR;
1289 }
1290
1291 // Decoder errors can be due to Source (e.g. from streaming),
1292 // or from decoding corrupted bitstreams, or from other decoder
1293 // MediaCodec operations (e.g. from an ongoing reset or seek).
1294 // They may also be due to openAudioSink failure at
1295 // decoder start or after a format change.
1296 //
1297 // We try to gracefully shut down the affected decoder if possible,
1298 // rather than trying to force the shutdown with something
1299 // similar to performReset(). This method can lead to a hang
1300 // if MediaCodec functions block after an error, but they should
1301 // typically return INVALID_OPERATION instead of blocking.
1302
1303 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1304 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1305 err, audio ? "audio" : "video", *flushing);
1306
1307 switch (*flushing) {
1308 case NONE:
1309 mDeferredActions.push_back(
1310 new FlushDecoderAction(
1311 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1312 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1313 processDeferredActions();
1314 break;
1315 case FLUSHING_DECODER:
1316 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1317 break; // Wait for flush to complete.
1318 case FLUSHING_DECODER_SHUTDOWN:
1319 break; // Wait for flush to complete.
1320 case SHUTTING_DOWN_DECODER:
1321 break; // Wait for shutdown to complete.
1322 case FLUSHED:
1323 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1324 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1325 break;
1326 case SHUT_DOWN:
1327 finishFlushIfPossible(); // Should not occur.
1328 break; // Finish anyways.
1329 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001330 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001331 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001332 if (mVideoDecoderError
1333 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1334 || mNativeWindow == NULL
1335 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001336 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001337 // When both audio and video have error, or this stream has only audio
1338 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001339 notifyListener(
1340 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1341 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001342 } else {
1343 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001344 notifyListener(
1345 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1346 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001347 }
1348 mAudioDecoderError = true;
1349 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001350 if (mAudioDecoderError
1351 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001352 || mAudioSink == NULL || mAudioDecoder == NULL) {
1353 // When both audio and video have error, or this stream has only video
1354 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001355 notifyListener(
1356 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1357 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001358 } else {
1359 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001360 notifyListener(
1361 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1362 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001363 }
1364 mVideoDecoderError = true;
1365 }
1366 }
1367 } else {
1368 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1369 what,
1370 what >> 24,
1371 (what >> 16) & 0xff,
1372 (what >> 8) & 0xff,
1373 what & 0xff);
1374 }
1375
1376 break;
1377 }
1378
1379 case kWhatRendererNotify:
1380 {
1381 int32_t requesterGeneration = mRendererGeneration - 1;
1382 CHECK(msg->findInt32("generation", &requesterGeneration));
1383 if (requesterGeneration != mRendererGeneration) {
1384 ALOGV("got message from old renderer, generation(%d:%d)",
1385 requesterGeneration, mRendererGeneration);
1386 return;
1387 }
1388
1389 int32_t what;
1390 CHECK(msg->findInt32("what", &what));
1391
1392 if (what == Renderer::kWhatEOS) {
1393 int32_t audio;
1394 CHECK(msg->findInt32("audio", &audio));
1395
1396 int32_t finalResult;
1397 CHECK(msg->findInt32("finalResult", &finalResult));
1398
1399 if (audio) {
1400 mAudioEOS = true;
1401 } else {
1402 mVideoEOS = true;
1403 }
1404
1405 if (finalResult == ERROR_END_OF_STREAM) {
1406 ALOGV("reached %s EOS", audio ? "audio" : "video");
1407 } else {
1408 ALOGE("%s track encountered an error (%d)",
1409 audio ? "audio" : "video", finalResult);
1410
1411 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001412 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1413 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001414 }
1415
1416 if ((mAudioEOS || mAudioDecoder == NULL)
1417 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001418 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001419 }
1420 } else if (what == Renderer::kWhatFlushComplete) {
1421 int32_t audio;
1422 CHECK(msg->findInt32("audio", &audio));
1423
1424 if (audio) {
1425 mAudioEOS = false;
1426 } else {
1427 mVideoEOS = false;
1428 }
1429
1430 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1431 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1432 || mFlushingAudio == SHUT_DOWN)) {
1433 // Flush has been handled by tear down.
1434 break;
1435 }
1436 handleFlushComplete(audio, false /* isDecoder */);
1437 finishFlushIfPossible();
1438 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001439 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1440 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001441 } else if (what == Renderer::kWhatMediaRenderingStart) {
1442 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001443 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001444 } else if (what == Renderer::kWhatAudioTearDown) {
1445 int32_t reason;
1446 CHECK(msg->findInt32("reason", &reason));
1447 ALOGV("Tear down audio with reason %d.", reason);
1448 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1449 // TimeoutWhenPaused is only for offload mode.
1450 ALOGW("Receive a stale message for teardown.");
1451 break;
1452 }
1453 int64_t positionUs;
1454 if (!msg->findInt64("positionUs", &positionUs)) {
1455 positionUs = mPreviousSeekTimeUs;
1456 }
1457
1458 restartAudio(
1459 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1460 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1461 }
1462 break;
1463 }
1464
1465 case kWhatMoreDataQueued:
1466 {
1467 break;
1468 }
1469
1470 case kWhatReset:
1471 {
1472 ALOGV("kWhatReset");
1473
1474 mResetting = true;
1475 stopPlaybackTimer("kWhatReset");
1476 stopRebufferingTimer(true);
1477
1478 mDeferredActions.push_back(
1479 new FlushDecoderAction(
1480 FLUSH_CMD_SHUTDOWN /* audio */,
1481 FLUSH_CMD_SHUTDOWN /* video */));
1482
1483 mDeferredActions.push_back(
1484 new SimpleAction(&NuPlayer2::performReset));
1485
1486 processDeferredActions();
1487 break;
1488 }
1489
1490 case kWhatNotifyTime:
1491 {
1492 ALOGV("kWhatNotifyTime");
1493 int64_t timerUs;
1494 CHECK(msg->findInt64("timerUs", &timerUs));
1495
Wei Jiaf01e3122018-10-18 11:49:44 -07001496 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001497 break;
1498 }
1499
1500 case kWhatSeek:
1501 {
1502 int64_t seekTimeUs;
1503 int32_t mode;
1504 int32_t needNotify;
1505 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1506 CHECK(msg->findInt32("mode", &mode));
1507 CHECK(msg->findInt32("needNotify", &needNotify));
1508
1509 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1510 (long long)seekTimeUs, mode, needNotify);
1511
1512 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001513 if (!mSourceStarted) {
1514 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001515 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001516 }
Wei Jia083e9092018-02-12 11:46:04 -08001517 if (seekTimeUs > 0) {
1518 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1519 }
1520
Wei Jia53692fa2017-12-11 10:33:46 -08001521 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001522 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001523 }
1524 break;
1525 }
1526
Wei Jia083e9092018-02-12 11:46:04 -08001527 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001528 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001529
Wei Jia53692fa2017-12-11 10:33:46 -08001530 mDeferredActions.push_back(
1531 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1532 FLUSH_CMD_FLUSH /* video */));
1533
1534 mDeferredActions.push_back(
1535 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1536
1537 // After a flush without shutdown, decoder is paused.
1538 // Don't resume it until source seek is done, otherwise it could
1539 // start pulling stale data too soon.
1540 mDeferredActions.push_back(
1541 new ResumeDecoderAction(needNotify));
1542
1543 processDeferredActions();
1544 break;
1545 }
1546
Wei Jiad1864f92018-10-19 12:34:56 -07001547 case kWhatRewind:
1548 {
1549 ALOGV("kWhatRewind");
1550
1551 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1552 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1553
1554 if (!mStarted) {
1555 if (!mSourceStarted) {
1556 mSourceStarted = true;
1557 mCurrentSourceInfo.mSource->start();
1558 }
1559 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1560 break;
1561 }
1562
1563 // seeks can take a while, so we essentially paused
1564 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1565
1566 mDeferredActions.push_back(
1567 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1568 FLUSH_CMD_FLUSH /* video */));
1569
1570 mDeferredActions.push_back(
1571 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1572
1573 // After a flush without shutdown, decoder is paused.
1574 // Don't resume it until source seek is done, otherwise it could
1575 // start pulling stale data too soon.
1576 mDeferredActions.push_back(
1577 new ResumeDecoderAction(false /* needNotify */));
1578
1579 processDeferredActions();
1580 break;
1581 }
1582
Wei Jia53692fa2017-12-11 10:33:46 -08001583 case kWhatPause:
1584 {
Wei Jia6376cd52018-09-26 11:42:55 -07001585 if (!mStarted) {
1586 onStart(false /* play */);
1587 }
Wei Jia53692fa2017-12-11 10:33:46 -08001588 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001589 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001590 mPausedByClient = true;
1591 break;
1592 }
1593
1594 case kWhatSourceNotify:
1595 {
1596 onSourceNotify(msg);
1597 break;
1598 }
1599
1600 case kWhatClosedCaptionNotify:
1601 {
1602 onClosedCaptionNotify(msg);
1603 break;
1604 }
1605
1606 case kWhatPrepareDrm:
1607 {
1608 status_t status = onPrepareDrm(msg);
1609
1610 sp<AMessage> response = new AMessage;
1611 response->setInt32("status", status);
1612 sp<AReplyToken> replyID;
1613 CHECK(msg->senderAwaitsResponse(&replyID));
1614 response->postReply(replyID);
1615 break;
1616 }
1617
1618 case kWhatReleaseDrm:
1619 {
1620 status_t status = onReleaseDrm();
1621
1622 sp<AMessage> response = new AMessage;
1623 response->setInt32("status", status);
1624 sp<AReplyToken> replyID;
1625 CHECK(msg->senderAwaitsResponse(&replyID));
1626 response->postReply(replyID);
1627 break;
1628 }
1629
1630 default:
1631 TRESPASS();
1632 break;
1633 }
1634}
1635
1636void NuPlayer2::onResume() {
1637 if (!mPaused || mResetting) {
1638 ALOGD_IF(mResetting, "resetting, onResume discarded");
1639 return;
1640 }
1641 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001642 if (mCurrentSourceInfo.mSource != NULL) {
1643 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001644 } else {
1645 ALOGW("resume called when source is gone or not set");
1646 }
1647 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1648 // needed.
1649 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1650 instantiateDecoder(true /* audio */, &mAudioDecoder);
1651 }
1652 if (mRenderer != NULL) {
1653 mRenderer->resume();
1654 } else {
1655 ALOGW("resume called when renderer is gone or not set");
1656 }
1657
1658 startPlaybackTimer("onresume");
1659}
1660
Wei Jia6376cd52018-09-26 11:42:55 -07001661void NuPlayer2::onStart(bool play) {
Wei Jia53692fa2017-12-11 10:33:46 -08001662 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1663
1664 if (!mSourceStarted) {
1665 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001666 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001667 }
Wei Jia53692fa2017-12-11 10:33:46 -08001668
1669 mOffloadAudio = false;
1670 mAudioEOS = false;
1671 mVideoEOS = false;
1672 mStarted = true;
1673 mPaused = false;
1674
1675 uint32_t flags = 0;
1676
Wei Jiaf01e3122018-10-18 11:49:44 -07001677 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001678 flags |= Renderer::FLAG_REAL_TIME;
1679 }
1680
Wei Jiaf01e3122018-10-18 11:49:44 -07001681 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1682 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001683 if (!hasAudio && !hasVideo) {
1684 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001685 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001686 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001687 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1688 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001689 return;
1690 }
1691 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1692
Wei Jiaf01e3122018-10-18 11:49:44 -07001693 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001694
1695 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1696 if (mAudioSink != NULL) {
1697 streamType = mAudioSink->getAudioStreamType();
1698 }
1699
1700 mOffloadAudio =
Wei Jiaf01e3122018-10-18 11:49:44 -07001701 canOffloadStream(audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001702 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1703
1704 // Modular DRM: Disabling audio offload if the source is protected
1705 if (mOffloadAudio && mIsDrmProtected) {
1706 mOffloadAudio = false;
1707 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1708 }
1709
1710 if (mOffloadAudio) {
1711 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1712 }
1713
1714 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1715 ++mRendererGeneration;
1716 notify->setInt32("generation", mRendererGeneration);
1717 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1718 mRendererLooper = new ALooper;
1719 mRendererLooper->setName("NuPlayerRenderer");
1720 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1721 mRendererLooper->registerHandler(mRenderer);
1722
1723 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1724 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001725 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001726 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001727 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001728 return;
1729 }
1730
1731 float rate = getFrameRate();
1732 if (rate > 0) {
1733 mRenderer->setVideoFrameRate(rate);
1734 }
1735
Wei Jiad1864f92018-10-19 12:34:56 -07001736 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001737 // Renderer is created in paused state.
1738 if (play) {
1739 mRenderer->resume();
1740 }
1741
Wei Jia53692fa2017-12-11 10:33:46 -08001742 if (mVideoDecoder != NULL) {
1743 mVideoDecoder->setRenderer(mRenderer);
1744 }
1745 if (mAudioDecoder != NULL) {
1746 mAudioDecoder->setRenderer(mRenderer);
1747 }
1748
1749 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001750 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001751
1752 postScanSources();
1753}
1754
Wei Jiad1864f92018-10-19 12:34:56 -07001755void NuPlayer2::addEndTimeMonitor() {
1756 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
1757 ++mEOSMonitorGeneration;
1758 msg->setInt32("generation", mEOSMonitorGeneration);
1759 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1760}
1761
Wei Jia53692fa2017-12-11 10:33:46 -08001762void NuPlayer2::startPlaybackTimer(const char *where) {
1763 Mutex::Autolock autoLock(mPlayingTimeLock);
1764 if (mLastStartedPlayingTimeNs == 0) {
1765 mLastStartedPlayingTimeNs = systemTime();
1766 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1767 }
1768}
1769
1770void NuPlayer2::stopPlaybackTimer(const char *where) {
1771 Mutex::Autolock autoLock(mPlayingTimeLock);
1772
1773 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1774
1775 if (mLastStartedPlayingTimeNs != 0) {
1776 sp<NuPlayer2Driver> driver = mDriver.promote();
1777 if (driver != NULL) {
1778 int64_t now = systemTime();
1779 int64_t played = now - mLastStartedPlayingTimeNs;
1780 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1781
1782 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001783 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001784 }
1785 }
1786 mLastStartedPlayingTimeNs = 0;
1787 }
1788}
1789
1790void NuPlayer2::startRebufferingTimer() {
1791 Mutex::Autolock autoLock(mPlayingTimeLock);
1792 if (mLastStartedRebufferingTimeNs == 0) {
1793 mLastStartedRebufferingTimeNs = systemTime();
1794 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1795 }
1796}
1797
1798void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1799 Mutex::Autolock autoLock(mPlayingTimeLock);
1800
Wei Jiaf01e3122018-10-18 11:49:44 -07001801 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1802 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001803
1804 if (mLastStartedRebufferingTimeNs != 0) {
1805 sp<NuPlayer2Driver> driver = mDriver.promote();
1806 if (driver != NULL) {
1807 int64_t now = systemTime();
1808 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1809 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1810
1811 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001812 driver->notifyMoreRebufferingTimeUs(
1813 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001814 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001815 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001816 }
1817 }
1818 }
1819 mLastStartedRebufferingTimeNs = 0;
1820 }
1821}
1822
1823void NuPlayer2::onPause() {
1824
1825 stopPlaybackTimer("onPause");
1826
1827 if (mPaused) {
1828 return;
1829 }
1830 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001831 if (mCurrentSourceInfo.mSource != NULL) {
1832 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001833 } else {
1834 ALOGW("pause called when source is gone or not set");
1835 }
1836 if (mRenderer != NULL) {
1837 mRenderer->pause();
1838 } else {
1839 ALOGW("pause called when renderer is gone or not set");
1840 }
1841
1842}
1843
1844bool NuPlayer2::audioDecoderStillNeeded() {
1845 // Audio decoder is no longer needed if it's in shut/shutting down status.
1846 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1847}
1848
1849void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1850 // We wait for both the decoder flush and the renderer flush to complete
1851 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1852
1853 mFlushComplete[audio][isDecoder] = true;
1854 if (!mFlushComplete[audio][!isDecoder]) {
1855 return;
1856 }
1857
1858 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1859 switch (*state) {
1860 case FLUSHING_DECODER:
1861 {
1862 *state = FLUSHED;
1863 break;
1864 }
1865
1866 case FLUSHING_DECODER_SHUTDOWN:
1867 {
1868 *state = SHUTTING_DOWN_DECODER;
1869
1870 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1871 getDecoder(audio)->initiateShutdown();
1872 break;
1873 }
1874
1875 default:
1876 // decoder flush completes only occur in a flushing state.
1877 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1878 break;
1879 }
1880}
1881
1882void NuPlayer2::finishFlushIfPossible() {
1883 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1884 && mFlushingAudio != SHUT_DOWN) {
1885 return;
1886 }
1887
1888 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1889 && mFlushingVideo != SHUT_DOWN) {
1890 return;
1891 }
1892
1893 ALOGV("both audio and video are flushed now.");
1894
1895 mFlushingAudio = NONE;
1896 mFlushingVideo = NONE;
1897
1898 clearFlushComplete();
1899
1900 processDeferredActions();
1901}
1902
1903void NuPlayer2::postScanSources() {
1904 if (mScanSourcesPending) {
1905 return;
1906 }
1907
1908 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1909 msg->setInt32("generation", mScanSourcesGeneration);
1910 msg->post();
1911
1912 mScanSourcesPending = true;
1913}
1914
1915void NuPlayer2::tryOpenAudioSinkForOffload(
1916 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1917 // Note: This is called early in NuPlayer2 to determine whether offloading
1918 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1919
1920 status_t err = mRenderer->openAudioSink(
1921 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001922 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001923 if (err != OK) {
1924 // Any failure we turn off mOffloadAudio.
1925 mOffloadAudio = false;
1926 } else if (mOffloadAudio) {
1927 sendMetaDataToHal(mAudioSink, audioMeta);
1928 }
1929}
1930
1931void NuPlayer2::closeAudioSink() {
1932 mRenderer->closeAudioSink();
1933}
1934
1935void NuPlayer2::restartAudio(
1936 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1937 if (mAudioDecoder != NULL) {
1938 mAudioDecoder->pause();
1939 mAudioDecoder.clear();
1940 mAudioDecoderError = false;
1941 ++mAudioDecoderGeneration;
1942 }
1943 if (mFlushingAudio == FLUSHING_DECODER) {
1944 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1945 mFlushingAudio = FLUSHED;
1946 finishFlushIfPossible();
1947 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1948 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1949 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1950 mFlushingAudio = SHUT_DOWN;
1951 finishFlushIfPossible();
1952 needsToCreateAudioDecoder = false;
1953 }
1954 if (mRenderer == NULL) {
1955 return;
1956 }
1957 closeAudioSink();
1958 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1959 if (mVideoDecoder != NULL) {
1960 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1961 }
1962
1963 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1964
1965 if (forceNonOffload) {
1966 mRenderer->signalDisableOffloadAudio();
1967 mOffloadAudio = false;
1968 }
1969 if (needsToCreateAudioDecoder) {
1970 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1971 }
1972}
1973
1974void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001975 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001976 return;
1977 }
1978
1979 if (mRenderer == NULL) {
1980 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1981 mOffloadAudio = false;
1982 return;
1983 }
1984
Wei Jiaf01e3122018-10-18 11:49:44 -07001985 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
1986 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001987 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1988 const bool hasVideo = (videoFormat != NULL);
1989 bool canOffload = canOffloadStream(
Wei Jiaf01e3122018-10-18 11:49:44 -07001990 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001991 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1992
1993 // Modular DRM: Disabling audio offload if the source is protected
1994 if (canOffload && mIsDrmProtected) {
1995 canOffload = false;
1996 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1997 }
1998
1999 if (canOffload) {
2000 if (!mOffloadAudio) {
2001 mRenderer->signalEnableOffloadAudio();
2002 }
2003 // open audio sink early under offload mode.
2004 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2005 } else {
2006 if (mOffloadAudio) {
2007 mRenderer->signalDisableOffloadAudio();
2008 mOffloadAudio = false;
2009 }
2010 }
2011}
2012
2013status_t NuPlayer2::instantiateDecoder(
2014 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2015 // The audio decoder could be cleared by tear down. If still in shut down
2016 // process, no need to create a new audio decoder.
2017 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2018 return OK;
2019 }
2020
Wei Jiaf01e3122018-10-18 11:49:44 -07002021 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002022
2023 if (format == NULL) {
2024 return UNKNOWN_ERROR;
2025 } else {
2026 status_t err;
2027 if (format->findInt32("err", &err) && err) {
2028 return err;
2029 }
2030 }
2031
2032 format->setInt32("priority", 0 /* realtime */);
2033
2034 if (!audio) {
2035 AString mime;
2036 CHECK(format->findString("mime", &mime));
2037
2038 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2039 if (mCCDecoder == NULL) {
2040 mCCDecoder = new CCDecoder(ccNotify);
2041 }
2042
Wei Jiaf01e3122018-10-18 11:49:44 -07002043 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002044 format->setInt32("secure", true);
2045 }
2046
Wei Jiaf01e3122018-10-18 11:49:44 -07002047 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002048 format->setInt32("protected", true);
2049 }
2050
2051 float rate = getFrameRate();
2052 if (rate > 0) {
2053 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2054 }
2055 }
2056
2057 if (audio) {
2058 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2059 ++mAudioDecoderGeneration;
2060 notify->setInt32("generation", mAudioDecoderGeneration);
2061
2062 if (checkAudioModeChange) {
2063 determineAudioModeChange(format);
2064 }
2065 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002066 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002067
Wei Jiaf01e3122018-10-18 11:49:44 -07002068 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002069 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002070 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002071 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2072 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002073 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002074
Wei Jiaf01e3122018-10-18 11:49:44 -07002075 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002076 ALOGV("instantiateDecoder audio Decoder");
2077 }
2078 mAudioDecoderError = false;
2079 } else {
2080 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2081 ++mVideoDecoderGeneration;
2082 notify->setInt32("generation", mVideoDecoderGeneration);
2083
2084 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002085 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2086 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002087 mVideoDecoderError = false;
2088
2089 // enable FRC if high-quality AV sync is requested, even if not
2090 // directly queuing to display, as this will even improve textureview
2091 // playback.
2092 {
2093 if (property_get_bool("persist.sys.media.avsync", false)) {
2094 format->setInt32("auto-frc", 1);
2095 }
2096 }
2097 }
2098 (*decoder)->init();
2099
2100 // Modular DRM
2101 if (mIsDrmProtected) {
2102 format->setObject("crypto", mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002103 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
2104 mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002105 }
2106
2107 (*decoder)->configure(format);
2108
2109 if (!audio) {
2110 sp<AMessage> params = new AMessage();
2111 float rate = getFrameRate();
2112 if (rate > 0) {
2113 params->setFloat("frame-rate-total", rate);
2114 }
2115
2116 sp<MetaData> fileMeta = getFileMeta();
2117 if (fileMeta != NULL) {
2118 int32_t videoTemporalLayerCount;
2119 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2120 && videoTemporalLayerCount > 0) {
2121 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2122 }
2123 }
2124
2125 if (params->countEntries() > 0) {
2126 (*decoder)->setParameters(params);
2127 }
2128 }
2129 return OK;
2130}
2131
2132void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002133 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002134 const sp<AMessage> &inputFormat,
2135 const sp<AMessage> &outputFormat) {
2136 if (inputFormat == NULL) {
2137 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002138 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002139 return;
2140 }
2141 int32_t err = OK;
2142 inputFormat->findInt32("err", &err);
2143 if (err == -EWOULDBLOCK) {
2144 ALOGW("Video meta is not available yet!");
2145 return;
2146 }
2147 if (err != OK) {
2148 ALOGW("Something is wrong with video meta!");
2149 return;
2150 }
2151
2152 int32_t displayWidth, displayHeight;
2153 if (outputFormat != NULL) {
2154 int32_t width, height;
2155 CHECK(outputFormat->findInt32("width", &width));
2156 CHECK(outputFormat->findInt32("height", &height));
2157
2158 int32_t cropLeft, cropTop, cropRight, cropBottom;
2159 CHECK(outputFormat->findRect(
2160 "crop",
2161 &cropLeft, &cropTop, &cropRight, &cropBottom));
2162
2163 displayWidth = cropRight - cropLeft + 1;
2164 displayHeight = cropBottom - cropTop + 1;
2165
2166 ALOGV("Video output format changed to %d x %d "
2167 "(crop: %d x %d @ (%d, %d))",
2168 width, height,
2169 displayWidth,
2170 displayHeight,
2171 cropLeft, cropTop);
2172 } else {
2173 CHECK(inputFormat->findInt32("width", &displayWidth));
2174 CHECK(inputFormat->findInt32("height", &displayHeight));
2175
2176 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2177 }
2178
2179 // Take into account sample aspect ratio if necessary:
2180 int32_t sarWidth, sarHeight;
2181 if (inputFormat->findInt32("sar-width", &sarWidth)
2182 && inputFormat->findInt32("sar-height", &sarHeight)
2183 && sarWidth > 0 && sarHeight > 0) {
2184 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2185
2186 displayWidth = (displayWidth * sarWidth) / sarHeight;
2187
2188 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2189 } else {
2190 int32_t width, height;
2191 if (inputFormat->findInt32("display-width", &width)
2192 && inputFormat->findInt32("display-height", &height)
2193 && width > 0 && height > 0
2194 && displayWidth > 0 && displayHeight > 0) {
2195 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2196 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2197 } else {
2198 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2199 }
2200 ALOGV("Video display width and height are overridden to %d x %d",
2201 displayWidth, displayHeight);
2202 }
2203 }
2204
2205 int32_t rotationDegrees;
2206 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2207 rotationDegrees = 0;
2208 }
2209
2210 if (rotationDegrees == 90 || rotationDegrees == 270) {
2211 int32_t tmp = displayWidth;
2212 displayWidth = displayHeight;
2213 displayHeight = tmp;
2214 }
2215
2216 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002217 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002218 MEDIA2_SET_VIDEO_SIZE,
2219 displayWidth,
2220 displayHeight);
2221}
2222
Dongwon Kang41929fb2018-09-09 08:29:56 -07002223void NuPlayer2::notifyListener(
2224 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002225 if (mDriver == NULL) {
2226 return;
2227 }
2228
2229 sp<NuPlayer2Driver> driver = mDriver.promote();
2230
2231 if (driver == NULL) {
2232 return;
2233 }
2234
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002235 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002236}
2237
2238void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2239 ALOGV("[%s] flushDecoder needShutdown=%d",
2240 audio ? "audio" : "video", needShutdown);
2241
2242 const sp<DecoderBase> &decoder = getDecoder(audio);
2243 if (decoder == NULL) {
2244 ALOGI("flushDecoder %s without decoder present",
2245 audio ? "audio" : "video");
2246 return;
2247 }
2248
2249 // Make sure we don't continue to scan sources until we finish flushing.
2250 ++mScanSourcesGeneration;
2251 if (mScanSourcesPending) {
2252 if (!needShutdown) {
2253 mDeferredActions.push_back(
2254 new SimpleAction(&NuPlayer2::performScanSources));
2255 }
2256 mScanSourcesPending = false;
2257 }
2258
2259 decoder->signalFlush();
2260
2261 FlushStatus newStatus =
2262 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2263
2264 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2265 mFlushComplete[audio][true /* isDecoder */] = false;
2266 if (audio) {
2267 ALOGE_IF(mFlushingAudio != NONE,
2268 "audio flushDecoder() is called in state %d", mFlushingAudio);
2269 mFlushingAudio = newStatus;
2270 } else {
2271 ALOGE_IF(mFlushingVideo != NONE,
2272 "video flushDecoder() is called in state %d", mFlushingVideo);
2273 mFlushingVideo = newStatus;
2274 }
2275}
2276
2277void NuPlayer2::queueDecoderShutdown(
2278 bool audio, bool video, const sp<AMessage> &reply) {
2279 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2280
2281 mDeferredActions.push_back(
2282 new FlushDecoderAction(
2283 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2284 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2285
2286 mDeferredActions.push_back(
2287 new SimpleAction(&NuPlayer2::performScanSources));
2288
2289 mDeferredActions.push_back(new PostMessageAction(reply));
2290
2291 processDeferredActions();
2292}
2293
2294status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2295 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002296 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2297 status_t ret = native_window_set_scaling_mode(
2298 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002299 if (ret != OK) {
2300 ALOGE("Failed to set scaling mode (%d): %s",
2301 -ret, strerror(-ret));
2302 return ret;
2303 }
2304 }
2305 return OK;
2306}
2307
Dongwon Kang9f631982018-07-10 12:34:41 -07002308status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002309 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2310 msg->setPointer("reply", reply);
2311
2312 sp<AMessage> response;
2313 status_t err = msg->postAndAwaitResponse(&response);
2314 return err;
2315}
2316
Dongwon Kang9f631982018-07-10 12:34:41 -07002317status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002318 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2319 msg->setPointer("reply", reply);
2320 msg->setInt32("type", type);
2321
2322 sp<AMessage> response;
2323 status_t err = msg->postAndAwaitResponse(&response);
2324 if (err == OK && response != NULL) {
2325 CHECK(response->findInt32("err", &err));
2326 }
2327 return err;
2328}
2329
2330status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2331 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2332 msg->setSize("trackIndex", trackIndex);
2333 msg->setInt32("select", select);
2334 msg->setInt64("timeUs", timeUs);
2335
2336 sp<AMessage> response;
2337 status_t err = msg->postAndAwaitResponse(&response);
2338
2339 if (err != OK) {
2340 return err;
2341 }
2342
2343 if (!response->findInt32("err", &err)) {
2344 err = OK;
2345 }
2346
2347 return err;
2348}
2349
2350status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2351 sp<Renderer> renderer = mRenderer;
2352 if (renderer == NULL) {
2353 return NO_INIT;
2354 }
2355
2356 return renderer->getCurrentPosition(mediaUs);
2357}
2358
2359void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2360 CHECK(mTrackStats != NULL);
2361
2362 mTrackStats->clear();
2363 if (mVideoDecoder != NULL) {
2364 mTrackStats->push_back(mVideoDecoder->getStats());
2365 }
2366 if (mAudioDecoder != NULL) {
2367 mTrackStats->push_back(mAudioDecoder->getStats());
2368 }
2369}
2370
2371sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002372 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002373}
2374
2375float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002376 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002377 if (meta == NULL) {
2378 return 0;
2379 }
2380 int32_t rate;
2381 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2382 // fall back to try file meta
2383 sp<MetaData> fileMeta = getFileMeta();
2384 if (fileMeta == NULL) {
2385 ALOGW("source has video meta but not file meta");
2386 return -1;
2387 }
2388 int32_t fileMetaRate;
2389 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2390 return -1;
2391 }
2392 return fileMetaRate;
2393 }
2394 return rate;
2395}
2396
2397void NuPlayer2::schedulePollDuration() {
2398 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2399 msg->setInt32("generation", mPollDurationGeneration);
2400 msg->post();
2401}
2402
2403void NuPlayer2::cancelPollDuration() {
2404 ++mPollDurationGeneration;
2405}
2406
2407void NuPlayer2::processDeferredActions() {
2408 while (!mDeferredActions.empty()) {
2409 // We won't execute any deferred actions until we're no longer in
2410 // an intermediate state, i.e. one more more decoders are currently
2411 // flushing or shutting down.
2412
2413 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2414 // We're currently flushing, postpone the reset until that's
2415 // completed.
2416
2417 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2418 mFlushingAudio, mFlushingVideo);
2419
2420 break;
2421 }
2422
2423 sp<Action> action = *mDeferredActions.begin();
2424 mDeferredActions.erase(mDeferredActions.begin());
2425
2426 action->execute(this);
2427 }
2428}
2429
2430void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2431 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2432 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2433
Wei Jiaf01e3122018-10-18 11:49:44 -07002434 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002435 // This happens when reset occurs right before the loop mode
2436 // asynchronously seeks to the start of the stream.
2437 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002438 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002439 mAudioDecoder.get(), mVideoDecoder.get());
2440 return;
2441 }
2442 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002443 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002444 ++mTimedTextGeneration;
2445
2446 // everything's flushed, continue playback.
2447}
2448
2449void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2450 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2451
2452 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2453 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2454 return;
2455 }
2456
2457 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2458 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2459 }
2460
2461 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2462 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2463 }
2464}
2465
2466void NuPlayer2::performReset() {
2467 ALOGV("performReset");
2468
2469 CHECK(mAudioDecoder == NULL);
2470 CHECK(mVideoDecoder == NULL);
2471
2472 stopPlaybackTimer("performReset");
2473 stopRebufferingTimer(true);
2474
2475 cancelPollDuration();
2476
2477 ++mScanSourcesGeneration;
2478 mScanSourcesPending = false;
2479
2480 if (mRendererLooper != NULL) {
2481 if (mRenderer != NULL) {
2482 mRendererLooper->unregisterHandler(mRenderer->id());
2483 }
2484 mRendererLooper->stop();
2485 mRendererLooper.clear();
2486 }
2487 mRenderer.clear();
2488 ++mRendererGeneration;
2489
Wei Jiaf01e3122018-10-18 11:49:44 -07002490 if (mCurrentSourceInfo.mSource != NULL) {
2491 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08002492
2493 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002494 mCurrentSourceInfo.mSource.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08002495 }
2496
2497 if (mDriver != NULL) {
2498 sp<NuPlayer2Driver> driver = mDriver.promote();
2499 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002500 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002501 }
2502 }
2503
2504 mStarted = false;
2505 mPrepared = false;
2506 mResetting = false;
2507 mSourceStarted = false;
2508
2509 // Modular DRM
2510 if (mCrypto != NULL) {
2511 // decoders will be flushed before this so their mCrypto would go away on their own
2512 // TODO change to ALOGV
2513 ALOGD("performReset mCrypto: %p", mCrypto.get());
2514 mCrypto.clear();
2515 }
2516 mIsDrmProtected = false;
2517}
2518
Wei Jia57aeffd2018-02-15 16:01:14 -08002519void NuPlayer2::performPlayNextDataSource() {
2520 ALOGV("performPlayNextDataSource");
2521
2522 CHECK(mAudioDecoder == NULL);
2523 CHECK(mVideoDecoder == NULL);
2524
2525 stopPlaybackTimer("performPlayNextDataSource");
2526 stopRebufferingTimer(true);
2527
2528 cancelPollDuration();
2529
2530 ++mScanSourcesGeneration;
2531 mScanSourcesPending = false;
2532
2533 ++mRendererGeneration;
2534
Wei Jiaf01e3122018-10-18 11:49:44 -07002535 if (mCurrentSourceInfo.mSource != NULL) {
2536 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002537 }
2538
2539 long previousSrcId;
2540 {
2541 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002542 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002543
2544 mCurrentSourceInfo = mNextSourceInfo;
2545 mNextSourceInfo = SourceInfo();
2546 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002547 }
2548
2549 if (mDriver != NULL) {
2550 sp<NuPlayer2Driver> driver = mDriver.promote();
2551 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002552 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002553
2554 int64_t durationUs;
2555 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2556 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2557 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002558 notifyListener(
2559 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002560 }
2561 }
2562
2563 mStarted = false;
2564 mPrepared = true; // TODO: what if it's not prepared
2565 mResetting = false;
2566 mSourceStarted = false;
2567
Wei Jiad1864f92018-10-19 12:34:56 -07002568 addEndTimeMonitor();
2569
Wei Jia57aeffd2018-02-15 16:01:14 -08002570 // Modular DRM
2571 if (mCrypto != NULL) {
2572 // decoders will be flushed before this so their mCrypto would go away on their own
2573 // TODO change to ALOGV
2574 ALOGD("performReset mCrypto: %p", mCrypto.get());
2575 mCrypto.clear();
2576 }
2577 mIsDrmProtected = false;
2578
2579 if (mRenderer != NULL) {
2580 mRenderer->resume();
2581 }
2582
Wei Jia6376cd52018-09-26 11:42:55 -07002583 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002584 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002585 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002586}
2587
Wei Jia53692fa2017-12-11 10:33:46 -08002588void NuPlayer2::performScanSources() {
2589 ALOGV("performScanSources");
2590
2591 if (!mStarted) {
2592 return;
2593 }
2594
2595 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2596 postScanSources();
2597 }
2598}
2599
Wei Jia28288fb2017-12-15 13:45:29 -08002600void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002601 ALOGV("performSetSurface");
2602
Wei Jia28288fb2017-12-15 13:45:29 -08002603 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002604
2605 // XXX - ignore error from setVideoScalingMode for now
2606 setVideoScalingMode(mVideoScalingMode);
2607
2608 if (mDriver != NULL) {
2609 sp<NuPlayer2Driver> driver = mDriver.promote();
2610 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002611 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002612 }
2613 }
2614}
2615
2616void NuPlayer2::performResumeDecoders(bool needNotify) {
2617 if (needNotify) {
2618 mResumePending = true;
2619 if (mVideoDecoder == NULL) {
2620 // if audio-only, we can notify seek complete now,
2621 // as the resume operation will be relatively fast.
2622 finishResume();
2623 }
2624 }
2625
2626 if (mVideoDecoder != NULL) {
2627 // When there is continuous seek, MediaPlayer will cache the seek
2628 // position, and send down new seek request when previous seek is
2629 // complete. Let's wait for at least one video output frame before
2630 // notifying seek complete, so that the video thumbnail gets updated
2631 // when seekbar is dragged.
2632 mVideoDecoder->signalResume(needNotify);
2633 }
2634
2635 if (mAudioDecoder != NULL) {
2636 mAudioDecoder->signalResume(false /* needNotify */);
2637 }
2638}
2639
2640void NuPlayer2::finishResume() {
2641 if (mResumePending) {
2642 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002643 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002644 }
2645}
2646
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002647void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002648 if (mDriver != NULL) {
2649 sp<NuPlayer2Driver> driver = mDriver.promote();
2650 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002651 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002652 }
2653 }
2654}
2655
2656void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2657 int32_t what;
2658 CHECK(msg->findInt32("what", &what));
2659
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002660 int64_t srcId;
2661 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002662 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002663 case Source::kWhatPrepared:
2664 {
Wei Jiad1864f92018-10-19 12:34:56 -07002665 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2666 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2667 if (srcId == mCurrentSourceInfo.mSrcId) {
2668 if (mCurrentSourceInfo.mSource == NULL) {
2669 // This is a stale notification from a source that was
2670 // asynchronously preparing when the client called reset().
2671 // We handled the reset, the source is gone.
2672 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002673 }
Wei Jiad1864f92018-10-19 12:34:56 -07002674
2675 int32_t err;
2676 CHECK(msg->findInt32("err", &err));
2677
2678 if (err != OK) {
2679 // shut down potential secure codecs in case client never calls reset
2680 mDeferredActions.push_back(
2681 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2682 FLUSH_CMD_SHUTDOWN /* video */));
2683 processDeferredActions();
2684 } else {
2685 mPrepared = true;
2686 }
2687
2688 sp<NuPlayer2Driver> driver = mDriver.promote();
2689 if (driver != NULL) {
2690 // notify duration first, so that it's definitely set when
2691 // the app received the "prepare complete" callback.
2692 int64_t durationUs;
2693 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2694 driver->notifyDuration(srcId, durationUs);
2695 }
2696 driver->notifyPrepareCompleted(srcId, err);
2697 }
2698 } else if (srcId == mNextSourceInfo.mSrcId) {
2699 if (mNextSourceInfo.mSource == NULL) {
2700 break; // stale
2701 }
2702
2703 sp<NuPlayer2Driver> driver = mDriver.promote();
2704 if (driver != NULL) {
2705 int32_t err;
2706 CHECK(msg->findInt32("err", &err));
2707 driver->notifyPrepareCompleted(srcId, err);
2708 }
Wei Jia53692fa2017-12-11 10:33:46 -08002709 }
2710
2711 break;
2712 }
2713
2714 // Modular DRM
2715 case Source::kWhatDrmInfo:
2716 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002717 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002718 sp<ABuffer> drmInfo;
2719 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002720 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002721
Dongwon Kang41929fb2018-09-09 08:29:56 -07002722 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2723 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002724
Dongwon Kang41929fb2018-09-09 08:29:56 -07002725 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002726
2727 break;
2728 }
2729
2730 case Source::kWhatFlagsChanged:
2731 {
2732 uint32_t flags;
2733 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2734
2735 sp<NuPlayer2Driver> driver = mDriver.promote();
2736 if (driver != NULL) {
2737
2738 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2739 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2740 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2741 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2742 (flags & Source::FLAG_CAN_PAUSE) != 0,
2743 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2744 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2745 (flags & Source::FLAG_CAN_SEEK) != 0,
2746 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2747 (flags & Source::FLAG_SECURE) != 0,
2748 (flags & Source::FLAG_PROTECTED) != 0);
2749
2750 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2751 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002752 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002753 }
Wei Jiad1864f92018-10-19 12:34:56 -07002754 if (srcId == mCurrentSourceInfo.mSrcId) {
2755 driver->notifyFlagsChanged(srcId, flags);
2756 }
Wei Jia53692fa2017-12-11 10:33:46 -08002757 }
2758
Wei Jiaf01e3122018-10-18 11:49:44 -07002759 if (srcId == mCurrentSourceInfo.mSrcId) {
2760 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2761 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2762 cancelPollDuration();
2763 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2764 && (flags & Source::FLAG_DYNAMIC_DURATION)
2765 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2766 schedulePollDuration();
2767 }
Wei Jia53692fa2017-12-11 10:33:46 -08002768
Wei Jiaf01e3122018-10-18 11:49:44 -07002769 mCurrentSourceInfo.mSourceFlags = flags;
2770 } else if (srcId == mNextSourceInfo.mSrcId) {
2771 // TODO: handle duration polling for next source.
2772 mNextSourceInfo.mSourceFlags = flags;
2773 }
Wei Jia53692fa2017-12-11 10:33:46 -08002774 break;
2775 }
2776
2777 case Source::kWhatVideoSizeChanged:
2778 {
2779 sp<AMessage> format;
2780 CHECK(msg->findMessage("format", &format));
2781
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002782 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002783 break;
2784 }
2785
2786 case Source::kWhatBufferingUpdate:
2787 {
2788 int32_t percentage;
2789 CHECK(msg->findInt32("percentage", &percentage));
2790
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002791 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002792 break;
2793 }
2794
2795 case Source::kWhatPauseOnBufferingStart:
2796 {
2797 // ignore if not playing
2798 if (mStarted) {
2799 ALOGI("buffer low, pausing...");
2800
2801 startRebufferingTimer();
2802 mPausedForBuffering = true;
2803 onPause();
2804 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002805 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002806 break;
2807 }
2808
2809 case Source::kWhatResumeOnBufferingEnd:
2810 {
2811 // ignore if not playing
2812 if (mStarted) {
2813 ALOGI("buffer ready, resuming...");
2814
2815 stopRebufferingTimer(false);
2816 mPausedForBuffering = false;
2817
2818 // do not resume yet if client didn't unpause
2819 if (!mPausedByClient) {
2820 onResume();
2821 }
2822 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002823 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002824 break;
2825 }
2826
2827 case Source::kWhatCacheStats:
2828 {
2829 int32_t kbps;
2830 CHECK(msg->findInt32("bandwidth", &kbps));
2831
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002832 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002833 break;
2834 }
2835
2836 case Source::kWhatSubtitleData:
2837 {
2838 sp<ABuffer> buffer;
2839 CHECK(msg->findBuffer("buffer", &buffer));
2840
2841 sendSubtitleData(buffer, 0 /* baseIndex */);
2842 break;
2843 }
2844
2845 case Source::kWhatTimedMetaData:
2846 {
2847 sp<ABuffer> buffer;
2848 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002849 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002850 } else {
2851 sendTimedMetaData(buffer);
2852 }
2853 break;
2854 }
2855
2856 case Source::kWhatTimedTextData:
2857 {
2858 int32_t generation;
2859 if (msg->findInt32("generation", &generation)
2860 && generation != mTimedTextGeneration) {
2861 break;
2862 }
2863
2864 sp<ABuffer> buffer;
2865 CHECK(msg->findBuffer("buffer", &buffer));
2866
2867 sp<NuPlayer2Driver> driver = mDriver.promote();
2868 if (driver == NULL) {
2869 break;
2870 }
2871
Wei Jia800fe372018-02-20 15:00:45 -08002872 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002873 int64_t timeUs, posUs;
2874 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002875 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002876 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2877
2878 if (posUs < timeUs) {
2879 if (!msg->findInt32("generation", &generation)) {
2880 msg->setInt32("generation", mTimedTextGeneration);
2881 }
2882 msg->post(timeUs - posUs);
2883 } else {
2884 sendTimedTextData(buffer);
2885 }
2886 break;
2887 }
2888
2889 case Source::kWhatQueueDecoderShutdown:
2890 {
2891 int32_t audio, video;
2892 CHECK(msg->findInt32("audio", &audio));
2893 CHECK(msg->findInt32("video", &video));
2894
2895 sp<AMessage> reply;
2896 CHECK(msg->findMessage("reply", &reply));
2897
2898 queueDecoderShutdown(audio, video, reply);
2899 break;
2900 }
2901
2902 case Source::kWhatDrmNoLicense:
2903 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002904 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002905 break;
2906 }
2907
2908 default:
2909 TRESPASS();
2910 }
2911}
2912
2913void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2914 int32_t what;
2915 CHECK(msg->findInt32("what", &what));
2916
2917 switch (what) {
2918 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2919 {
2920 sp<ABuffer> buffer;
2921 CHECK(msg->findBuffer("buffer", &buffer));
2922
2923 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002924 if (mCurrentSourceInfo.mSource != NULL) {
2925 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002926 }
2927
2928 sendSubtitleData(buffer, inbandTracks);
2929 break;
2930 }
2931
2932 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2933 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002934 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002935
2936 break;
2937 }
2938
2939 default:
2940 TRESPASS();
2941 }
2942
2943
2944}
2945
2946void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2947 int32_t trackIndex;
2948 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002949 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002950 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2951 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2952
Dongwon Kang41929fb2018-09-09 08:29:56 -07002953 PlayerMessage playerMsg;
2954 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2955 playerMsg.add_values()->set_int64_value(timeUs);
2956 playerMsg.add_values()->set_int64_value(durationUs);
2957 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002958
Wei Jiaf01e3122018-10-18 11:49:44 -07002959 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002960}
2961
2962void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2963 int64_t timeUs;
2964 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2965
Dongwon Kang41929fb2018-09-09 08:29:56 -07002966 PlayerMessage playerMsg;
2967 playerMsg.add_values()->set_int64_value(timeUs);
2968 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002969
Wei Jiaf01e3122018-10-18 11:49:44 -07002970 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002971}
2972
2973void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2974 const void *data;
2975 size_t size = 0;
2976 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002977 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002978
2979 AString mime;
2980 CHECK(buffer->meta()->findString("mime", &mime));
2981 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2982
2983 data = buffer->data();
2984 size = buffer->size();
2985
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002986 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002987 if (size > 0) {
2988 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2989 int32_t global = 0;
2990 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002991 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002992 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002993 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002994 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002995 TextDescriptions2::getPlayerMessageOfDescriptions(
2996 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002997 }
2998
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002999 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003000 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003001 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003002 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003003 }
3004}
3005
3006const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003007 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003008 case DATA_SOURCE_TYPE_HTTP_LIVE:
3009 return "HTTPLive";
3010
3011 case DATA_SOURCE_TYPE_RTSP:
3012 return "RTSP";
3013
3014 case DATA_SOURCE_TYPE_GENERIC_URL:
3015 return "GenURL";
3016
3017 case DATA_SOURCE_TYPE_GENERIC_FD:
3018 return "GenFD";
3019
3020 case DATA_SOURCE_TYPE_MEDIA:
3021 return "Media";
3022
Wei Jia53692fa2017-12-11 10:33:46 -08003023 case DATA_SOURCE_TYPE_NONE:
3024 default:
3025 return "None";
3026 }
3027 }
3028
3029// Modular DRM begin
3030status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3031{
3032 ALOGV("prepareDrm ");
3033
3034 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3035 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3036 // synchronous call so just passing the address but with local copies of "const" args
3037 uint8_t UUID[16];
3038 memcpy(UUID, uuid, sizeof(UUID));
3039 Vector<uint8_t> sessionId = drmSessionId;
3040 msg->setPointer("uuid", (void*)UUID);
3041 msg->setPointer("drmSessionId", (void*)&sessionId);
3042
3043 sp<AMessage> response;
3044 status_t status = msg->postAndAwaitResponse(&response);
3045
3046 if (status == OK && response != NULL) {
3047 CHECK(response->findInt32("status", &status));
3048 ALOGV("prepareDrm ret: %d ", status);
3049 } else {
3050 ALOGE("prepareDrm err: %d", status);
3051 }
3052
3053 return status;
3054}
3055
3056status_t NuPlayer2::releaseDrm()
3057{
3058 ALOGV("releaseDrm ");
3059
3060 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3061
3062 sp<AMessage> response;
3063 status_t status = msg->postAndAwaitResponse(&response);
3064
3065 if (status == OK && response != NULL) {
3066 CHECK(response->findInt32("status", &status));
3067 ALOGV("releaseDrm ret: %d ", status);
3068 } else {
3069 ALOGE("releaseDrm err: %d", status);
3070 }
3071
3072 return status;
3073}
3074
3075status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3076{
3077 // TODO change to ALOGV
3078 ALOGD("onPrepareDrm ");
3079
3080 status_t status = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -07003081 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003082 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3083 return status;
3084 }
3085
3086 uint8_t *uuid;
3087 Vector<uint8_t> *drmSessionId;
3088 CHECK(msg->findPointer("uuid", (void**)&uuid));
3089 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3090
3091 status = OK;
3092 sp<AMediaCryptoWrapper> crypto = NULL;
3093
Wei Jiaf01e3122018-10-18 11:49:44 -07003094 status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003095 if (crypto == NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003096 ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
Wei Jia53692fa2017-12-11 10:33:46 -08003097 return status;
3098 }
Wei Jiaf01e3122018-10-18 11:49:44 -07003099 ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
Wei Jia53692fa2017-12-11 10:33:46 -08003100
3101 if (mCrypto != NULL) {
3102 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3103 mCrypto.clear();
3104 }
3105
3106 mCrypto = crypto;
3107 mIsDrmProtected = true;
3108 // TODO change to ALOGV
3109 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3110
3111 return status;
3112}
3113
3114status_t NuPlayer2::onReleaseDrm()
3115{
3116 // TODO change to ALOGV
3117 ALOGD("onReleaseDrm ");
3118
3119 if (!mIsDrmProtected) {
3120 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3121 }
3122
3123 mIsDrmProtected = false;
3124
3125 status_t status;
3126 if (mCrypto != NULL) {
3127 // notifying the source first before removing crypto from codec
Wei Jiaf01e3122018-10-18 11:49:44 -07003128 if (mCurrentSourceInfo.mSource != NULL) {
3129 mCurrentSourceInfo.mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003130 }
3131
3132 status=OK;
3133 // first making sure the codecs have released their crypto reference
3134 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3135 if (videoDecoder != NULL) {
3136 status = videoDecoder->releaseCrypto();
3137 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3138 }
3139
3140 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3141 if (audioDecoder != NULL) {
3142 status_t status_audio = audioDecoder->releaseCrypto();
3143 if (status == OK) { // otherwise, returning the first error
3144 status = status_audio;
3145 }
3146 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3147 }
3148
3149 // TODO change to ALOGV
3150 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3151 mCrypto.clear();
3152 } else { // mCrypto == NULL
3153 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3154 status = INVALID_OPERATION;
3155 }
3156
3157 return status;
3158}
3159// Modular DRM end
3160////////////////////////////////////////////////////////////////////////////////
3161
3162sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3163 sp<MetaData> meta = getFormatMeta(audio);
3164
3165 if (meta == NULL) {
3166 return NULL;
3167 }
3168
3169 sp<AMessage> msg = new AMessage;
3170
3171 if(convertMetaDataToMessage(meta, &msg) == OK) {
3172 return msg;
3173 }
3174 return NULL;
3175}
3176
3177void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3178 sp<AMessage> notify = dupNotify();
3179 notify->setInt32("what", kWhatFlagsChanged);
3180 notify->setInt32("flags", flags);
3181 notify->post();
3182}
3183
3184void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3185 sp<AMessage> notify = dupNotify();
3186 notify->setInt32("what", kWhatVideoSizeChanged);
3187 notify->setMessage("format", format);
3188 notify->post();
3189}
3190
3191void NuPlayer2::Source::notifyPrepared(status_t err) {
3192 ALOGV("Source::notifyPrepared %d", err);
3193 sp<AMessage> notify = dupNotify();
3194 notify->setInt32("what", kWhatPrepared);
3195 notify->setInt32("err", err);
3196 notify->post();
3197}
3198
3199void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3200{
3201 ALOGV("Source::notifyDrmInfo");
3202
3203 sp<AMessage> notify = dupNotify();
3204 notify->setInt32("what", kWhatDrmInfo);
3205 notify->setBuffer("drmInfo", drmInfoBuffer);
3206
3207 notify->post();
3208}
3209
Wei Jia53692fa2017-12-11 10:33:46 -08003210void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3211 TRESPASS();
3212}
3213
Wei Jiaf01e3122018-10-18 11:49:44 -07003214NuPlayer2::SourceInfo::SourceInfo()
3215 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3216 mSrcId(0),
3217 mSourceFlags(0),
3218 mStartTimeUs(0),
3219 mEndTimeUs(INT64_MAX) {
3220}
3221
Wei Jiad1864f92018-10-19 12:34:56 -07003222NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3223 mSource = other.mSource;
3224 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3225 mSrcId = other.mSrcId;
3226 mSourceFlags = other.mSourceFlags;
3227 mStartTimeUs = other.mStartTimeUs;
3228 mEndTimeUs = other.mEndTimeUs;
3229 return *this;
3230}
3231
Wei Jia53692fa2017-12-11 10:33:46 -08003232} // namespace android