blob: bc17d132e5db1d734a950deb8db62ba834eba173 [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "NuPlayer2"
19
20#include <inttypes.h>
21
22#include <utils/Log.h>
23
24#include "NuPlayer2.h"
25
Wei Jia2409c872018-02-02 10:34:33 -080026#include "HTTPLiveSource2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080027#include "NuPlayer2CCDecoder.h"
28#include "NuPlayer2Decoder.h"
29#include "NuPlayer2DecoderBase.h"
30#include "NuPlayer2DecoderPassThrough.h"
31#include "NuPlayer2Driver.h"
32#include "NuPlayer2Renderer.h"
33#include "NuPlayer2Source.h"
Wei Jia2409c872018-02-02 10:34:33 -080034#include "RTSPSource2.h"
35#include "GenericSource2.h"
Dongwon Kanga0e816a2018-09-10 19:46:49 -070036#include "TextDescriptions2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080037
38#include "ATSParser.h"
39
40#include <cutils/properties.h>
41
42#include <media/AudioParameter.h>
43#include <media/AudioResamplerPublic.h>
44#include <media/AVSyncSettings.h>
Wei Jiac2636032018-02-01 09:15:25 -080045#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080046#include <media/MediaCodecBuffer.h>
Wei Jia28288fb2017-12-15 13:45:29 -080047#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080048
49#include <media/stagefright/foundation/hexdump.h>
50#include <media/stagefright/foundation/ABuffer.h>
51#include <media/stagefright/foundation/ADebug.h>
52#include <media/stagefright/foundation/AMessage.h>
53#include <media/stagefright/foundation/avc_utils.h>
54#include <media/stagefright/MediaBuffer.h>
55#include <media/stagefright/MediaClock.h>
56#include <media/stagefright/MediaDefs.h>
57#include <media/stagefright/MediaErrors.h>
58#include <media/stagefright/MetaData.h>
59
Wei Jia53692fa2017-12-11 10:33:46 -080060#include "ESDS.h"
61#include <media/stagefright/Utils.h>
62
Wei Jia28288fb2017-12-15 13:45:29 -080063#include <system/window.h>
64
Wei Jia53692fa2017-12-11 10:33:46 -080065namespace android {
66
Wei Jia33abcc72018-01-30 09:47:38 -080067static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
Wei Jia53692fa2017-12-11 10:33:46 -080068 const sp<MetaData>& meta) {
69 int32_t sampleRate = 0;
70 int32_t bitRate = 0;
71 int32_t channelMask = 0;
72 int32_t delaySamples = 0;
73 int32_t paddingSamples = 0;
74
75 AudioParameter param = AudioParameter();
76
77 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
78 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
79 }
80 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
81 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
82 }
83 if (meta->findInt32(kKeyBitRate, &bitRate)) {
84 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
85 }
86 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
87 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
88 }
89 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
90 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
91 }
92
93 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
94 "delaySample %d, paddingSample %d", bitRate, sampleRate,
95 channelMask, delaySamples, paddingSamples);
96
97 sink->setParameters(param.toString());
98 return OK;
99}
100
101
102struct NuPlayer2::Action : public RefBase {
103 Action() {}
104
105 virtual void execute(NuPlayer2 *player) = 0;
106
107private:
108 DISALLOW_EVIL_CONSTRUCTORS(Action);
109};
110
111struct NuPlayer2::SeekAction : public Action {
112 explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
113 : mSeekTimeUs(seekTimeUs),
114 mMode(mode) {
115 }
116
117 virtual void execute(NuPlayer2 *player) {
118 player->performSeek(mSeekTimeUs, mMode);
119 }
120
121private:
122 int64_t mSeekTimeUs;
123 MediaPlayer2SeekMode mMode;
124
125 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
126};
127
128struct NuPlayer2::ResumeDecoderAction : public Action {
129 explicit ResumeDecoderAction(bool needNotify)
130 : mNeedNotify(needNotify) {
131 }
132
133 virtual void execute(NuPlayer2 *player) {
134 player->performResumeDecoders(mNeedNotify);
135 }
136
137private:
138 bool mNeedNotify;
139
140 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
141};
142
143struct NuPlayer2::SetSurfaceAction : public Action {
Wei Jia28288fb2017-12-15 13:45:29 -0800144 explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
145 : mNativeWindow(nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800146 }
147
148 virtual void execute(NuPlayer2 *player) {
Wei Jia28288fb2017-12-15 13:45:29 -0800149 player->performSetSurface(mNativeWindow);
Wei Jia53692fa2017-12-11 10:33:46 -0800150 }
151
152private:
Wei Jia28288fb2017-12-15 13:45:29 -0800153 sp<ANativeWindowWrapper> mNativeWindow;
Wei Jia53692fa2017-12-11 10:33:46 -0800154
155 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
156};
157
158struct NuPlayer2::FlushDecoderAction : public Action {
159 FlushDecoderAction(FlushCommand audio, FlushCommand video)
160 : mAudio(audio),
161 mVideo(video) {
162 }
163
164 virtual void execute(NuPlayer2 *player) {
165 player->performDecoderFlush(mAudio, mVideo);
166 }
167
168private:
169 FlushCommand mAudio;
170 FlushCommand mVideo;
171
172 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
173};
174
175struct NuPlayer2::PostMessageAction : public Action {
176 explicit PostMessageAction(const sp<AMessage> &msg)
177 : mMessage(msg) {
178 }
179
180 virtual void execute(NuPlayer2 *) {
181 mMessage->post();
182 }
183
184private:
185 sp<AMessage> mMessage;
186
187 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
188};
189
190// Use this if there's no state necessary to save in order to execute
191// the action.
192struct NuPlayer2::SimpleAction : public Action {
193 typedef void (NuPlayer2::*ActionFunc)();
194
195 explicit SimpleAction(ActionFunc func)
196 : mFunc(func) {
197 }
198
199 virtual void execute(NuPlayer2 *player) {
200 (player->*mFunc)();
201 }
202
203private:
204 ActionFunc mFunc;
205
206 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
207};
208
209////////////////////////////////////////////////////////////////////////////////
210
Wei Jia003fdb52018-02-06 14:44:32 -0800211NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
212 : mPID(pid),
213 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800214 mMediaClock(mediaClock),
Wei Jia53692fa2017-12-11 10:33:46 -0800215 mOffloadAudio(false),
216 mAudioDecoderGeneration(0),
217 mVideoDecoderGeneration(0),
218 mRendererGeneration(0),
Wei Jiad1864f92018-10-19 12:34:56 -0700219 mEOSMonitorGeneration(0),
Wei Jia53692fa2017-12-11 10:33:46 -0800220 mLastStartedPlayingTimeNs(0),
221 mPreviousSeekTimeUs(0),
222 mAudioEOS(false),
223 mVideoEOS(false),
224 mScanSourcesPending(false),
225 mScanSourcesGeneration(0),
226 mPollDurationGeneration(0),
227 mTimedTextGeneration(0),
228 mFlushingAudio(NONE),
229 mFlushingVideo(NONE),
230 mResumePending(false),
231 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
232 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
233 mVideoFpsHint(-1.f),
234 mStarted(false),
235 mPrepared(false),
236 mResetting(false),
237 mSourceStarted(false),
238 mAudioDecoderError(false),
239 mVideoDecoderError(false),
240 mPaused(false),
241 mPausedByClient(true),
242 mPausedForBuffering(false),
Wei Jiaf01e3122018-10-18 11:49:44 -0700243 mIsDrmProtected(false) {
Wei Jia53692fa2017-12-11 10:33:46 -0800244 CHECK(mediaClock != NULL);
245 clearFlushComplete();
246}
247
248NuPlayer2::~NuPlayer2() {
249}
250
Wei Jia53692fa2017-12-11 10:33:46 -0800251void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
252 mDriver = driver;
253}
254
Wei Jia53692fa2017-12-11 10:33:46 -0800255static bool IsHTTPLiveURL(const char *url) {
256 if (!strncasecmp("http://", url, 7)
257 || !strncasecmp("https://", url, 8)
258 || !strncasecmp("file://", url, 7)) {
259 size_t len = strlen(url);
260 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
261 return true;
262 }
263
264 if (strstr(url,"m3u8")) {
265 return true;
266 }
267 }
268
269 return false;
270}
271
Wei Jia72bf2a02018-02-06 15:29:23 -0800272status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
273 sp<Source> *source,
274 DATA_SOURCE_TYPE *dataSourceType) {
275 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800276 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800277 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800278
Wei Jiac2636032018-02-01 09:15:25 -0800279 switch (dsd->mType) {
280 case DataSourceDesc::TYPE_URL:
281 {
282 const char *url = dsd->mUrl.c_str();
283 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800284
Wei Jiac2636032018-02-01 09:15:25 -0800285 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
286 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800287
Wei Jiac2636032018-02-01 09:15:25 -0800288 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800289 *source = new HTTPLiveSource2(notify, httpService, url, headers);
290 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
291 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800292 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800293 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800294 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800295 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
296 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800297 } else if ((!strncasecmp(url, "http://", 7)
298 || !strncasecmp(url, "https://", 8))
299 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
300 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800301 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800302 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800303 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
304 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800305 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800306 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800307
Wei Jia2409c872018-02-02 10:34:33 -0800308 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800309 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800310
Robert Shih49fb89d2018-01-31 17:53:19 -0800311 err = genericSource->setDataSource(url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800312
313 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800314 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800315 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800316 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800317 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800318 }
319
320 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800321 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800322 }
323 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800324 }
325
Wei Jiac2636032018-02-01 09:15:25 -0800326 case DataSourceDesc::TYPE_FD:
327 {
Wei Jia2409c872018-02-02 10:34:33 -0800328 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800329 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800330
Wei Jia72bf2a02018-02-06 15:29:23 -0800331 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
332 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
333 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800334
Wei Jia72bf2a02018-02-06 15:29:23 -0800335 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800336
Wei Jiac2636032018-02-01 09:15:25 -0800337 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800338 ALOGE("Failed to create NuPlayer2Source!");
339 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800340 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800341 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800342 }
Wei Jia53692fa2017-12-11 10:33:46 -0800343
Wei Jia72bf2a02018-02-06 15:29:23 -0800344 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800345 break;
346 }
Wei Jia53692fa2017-12-11 10:33:46 -0800347
Wei Jiac2636032018-02-01 09:15:25 -0800348 case DataSourceDesc::TYPE_CALLBACK:
349 {
Wei Jia2409c872018-02-02 10:34:33 -0800350 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800351 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800352 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800353
Wei Jiac2636032018-02-01 09:15:25 -0800354 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800355 ALOGE("Failed to create NuPlayer2Source!");
356 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800357 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800358 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800359 }
360
Wei Jia72bf2a02018-02-06 15:29:23 -0800361 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800362 break;
363 }
364
365 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800366 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800367 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800368 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800369 ALOGE("invalid data source type!");
370 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800371 }
372
Wei Jia72bf2a02018-02-06 15:29:23 -0800373 return err;
374}
375
376void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
377 DATA_SOURCE_TYPE dataSourceType;
378 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800379 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800380
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800381 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
382 // and expects notifySetDataSourceCompleted regardless of success or failure.
383 // This will be changed since setDataSource should be asynchronous at JAVA level.
384 // When it succeeds, app will get onInfo notification. Otherwise, onError
385 // will be called.
386 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800387 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800388 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800389 return;
390 }
391
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800392 // Now, source != NULL.
393 */
394
Wei Jiaf01e3122018-10-18 11:49:44 -0700395 mCurrentSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800396
397 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800398 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800399 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700400 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
401 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia72bf2a02018-02-06 15:29:23 -0800402 msg->post();
403}
404
405void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
406 DATA_SOURCE_TYPE dataSourceType;
407 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800408 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800409
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800410 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800411 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800412 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800413 return;
414 }
415
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800416 // Now, source != NULL.
417 */
418
Wei Jiaf01e3122018-10-18 11:49:44 -0700419 mNextSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800420
421 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
422 msg->setObject("source", source);
423 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700424 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
425 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia53692fa2017-12-11 10:33:46 -0800426 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800427}
428
Wei Jia57aeffd2018-02-15 16:01:14 -0800429void NuPlayer2::playNextDataSource(int64_t srcId) {
430 disconnectSource();
431
432 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
433 msg->setInt64("srcId", srcId);
434 msg->post();
435}
436
Wei Jia53692fa2017-12-11 10:33:46 -0800437status_t NuPlayer2::getBufferingSettings(
438 BufferingSettings *buffering /* nonnull */) {
439 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
440 sp<AMessage> response;
441 status_t err = msg->postAndAwaitResponse(&response);
442 if (err == OK && response != NULL) {
443 CHECK(response->findInt32("err", &err));
444 if (err == OK) {
445 readFromAMessage(response, buffering);
446 }
447 }
448 return err;
449}
450
451status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
452 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
453 writeToAMessage(msg, buffering);
454 sp<AMessage> response;
455 status_t err = msg->postAndAwaitResponse(&response);
456 if (err == OK && response != NULL) {
457 CHECK(response->findInt32("err", &err));
458 }
459 return err;
460}
461
462void NuPlayer2::prepareAsync() {
463 ALOGV("prepareAsync");
464
465 (new AMessage(kWhatPrepare, this))->post();
466}
467
Wei Jia28288fb2017-12-15 13:45:29 -0800468void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800469 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
470
Wei Jia28288fb2017-12-15 13:45:29 -0800471 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800472 msg->setObject("surface", NULL);
473 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800474 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800475 }
476
477 msg->post();
478}
479
Wei Jia33abcc72018-01-30 09:47:38 -0800480void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800481 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
482 msg->setObject("sink", sink);
483 msg->post();
484}
485
486void NuPlayer2::start() {
487 (new AMessage(kWhatStart, this))->post();
488}
489
490status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
491 // do some cursory validation of the settings here. audio modes are
492 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700493 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800494 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
495 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
496 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
497 return BAD_VALUE;
498 }
499 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
500 writeToAMessage(msg, rate);
501 sp<AMessage> response;
502 status_t err = msg->postAndAwaitResponse(&response);
503 if (err == OK && response != NULL) {
504 CHECK(response->findInt32("err", &err));
505 }
506 return err;
507}
508
509status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
510 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
511 sp<AMessage> response;
512 status_t err = msg->postAndAwaitResponse(&response);
513 if (err == OK && response != NULL) {
514 CHECK(response->findInt32("err", &err));
515 if (err == OK) {
516 readFromAMessage(response, rate);
517 }
518 }
519 return err;
520}
521
522status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
523 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
524 writeToAMessage(msg, sync, videoFpsHint);
525 sp<AMessage> response;
526 status_t err = msg->postAndAwaitResponse(&response);
527 if (err == OK && response != NULL) {
528 CHECK(response->findInt32("err", &err));
529 }
530 return err;
531}
532
533status_t NuPlayer2::getSyncSettings(
534 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
535 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
536 sp<AMessage> response;
537 status_t err = msg->postAndAwaitResponse(&response);
538 if (err == OK && response != NULL) {
539 CHECK(response->findInt32("err", &err));
540 if (err == OK) {
541 readFromAMessage(response, sync, videoFps);
542 }
543 }
544 return err;
545}
546
547void NuPlayer2::pause() {
548 (new AMessage(kWhatPause, this))->post();
549}
550
551void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800552 disconnectSource();
553 (new AMessage(kWhatReset, this))->post();
554}
555
556void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800557 sp<Source> source;
558 {
559 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700560 source = mCurrentSourceInfo.mSource;
Wei Jia53692fa2017-12-11 10:33:46 -0800561 }
562
563 if (source != NULL) {
564 // During a reset, the data source might be unresponsive already, we need to
565 // disconnect explicitly so that reads exit promptly.
566 // We can't queue the disconnect request to the looper, as it might be
567 // queued behind a stuck read and never gets processed.
568 // Doing a disconnect outside the looper to allows the pending reads to exit
569 // (either successfully or with error).
570 source->disconnect();
571 }
572
Wei Jia53692fa2017-12-11 10:33:46 -0800573}
574
575status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
576 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
577 notify->setInt64("timerUs", mediaTimeUs);
578 mMediaClock->addTimer(notify, mediaTimeUs);
579 return OK;
580}
581
582void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
583 sp<AMessage> msg = new AMessage(kWhatSeek, this);
584 msg->setInt64("seekTimeUs", seekTimeUs);
585 msg->setInt32("mode", mode);
586 msg->setInt32("needNotify", needNotify);
587 msg->post();
588}
589
Wei Jiad1864f92018-10-19 12:34:56 -0700590void NuPlayer2::rewind() {
591 sp<AMessage> msg = new AMessage(kWhatRewind, this);
592 msg->post();
593}
594
Wei Jia53692fa2017-12-11 10:33:46 -0800595void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700596 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800597 if (format == NULL) {
598 ALOGE("NULL format");
599 return;
600 }
601 int32_t trackType;
602 if (!format->findInt32("type", &trackType)) {
603 ALOGE("no track type");
604 return;
605 }
606
607 AString mime;
608 if (!format->findString("mime", &mime)) {
609 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
610 // If we can't find the mimetype here it means that we wouldn't be needing
611 // the mimetype on the Java end. We still write a placeholder mime to keep the
612 // (de)serialization logic simple.
613 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
614 mime = "audio/";
615 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
616 mime = "video/";
617 } else {
618 ALOGE("unknown track type: %d", trackType);
619 return;
620 }
621 }
622
623 AString lang;
624 if (!format->findString("language", &lang)) {
625 ALOGE("no language");
626 return;
627 }
628
Dongwon Kang9f631982018-07-10 12:34:41 -0700629 reply->add_values()->set_int32_value(trackType);
630 reply->add_values()->set_string_value(mime.c_str());
631 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800632
633 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
634 int32_t isAuto, isDefault, isForced;
635 CHECK(format->findInt32("auto", &isAuto));
636 CHECK(format->findInt32("default", &isDefault));
637 CHECK(format->findInt32("forced", &isForced));
638
Dongwon Kang9f631982018-07-10 12:34:41 -0700639 reply->add_values()->set_int32_value(isAuto);
640 reply->add_values()->set_int32_value(isDefault);
641 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800642 }
643}
644
645void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
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() {
Wei Jiad1864f92018-10-19 12:34:56 -07001756 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001757
1758 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1759 return;
1760 }
1761
1762 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001763 msg->setInt32("generation", mEOSMonitorGeneration);
1764 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1765}
1766
Wei Jia53692fa2017-12-11 10:33:46 -08001767void NuPlayer2::startPlaybackTimer(const char *where) {
1768 Mutex::Autolock autoLock(mPlayingTimeLock);
1769 if (mLastStartedPlayingTimeNs == 0) {
1770 mLastStartedPlayingTimeNs = systemTime();
1771 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1772 }
1773}
1774
1775void NuPlayer2::stopPlaybackTimer(const char *where) {
1776 Mutex::Autolock autoLock(mPlayingTimeLock);
1777
1778 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1779
1780 if (mLastStartedPlayingTimeNs != 0) {
1781 sp<NuPlayer2Driver> driver = mDriver.promote();
1782 if (driver != NULL) {
1783 int64_t now = systemTime();
1784 int64_t played = now - mLastStartedPlayingTimeNs;
1785 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1786
1787 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001788 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001789 }
1790 }
1791 mLastStartedPlayingTimeNs = 0;
1792 }
1793}
1794
1795void NuPlayer2::startRebufferingTimer() {
1796 Mutex::Autolock autoLock(mPlayingTimeLock);
1797 if (mLastStartedRebufferingTimeNs == 0) {
1798 mLastStartedRebufferingTimeNs = systemTime();
1799 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1800 }
1801}
1802
1803void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1804 Mutex::Autolock autoLock(mPlayingTimeLock);
1805
Wei Jiaf01e3122018-10-18 11:49:44 -07001806 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1807 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001808
1809 if (mLastStartedRebufferingTimeNs != 0) {
1810 sp<NuPlayer2Driver> driver = mDriver.promote();
1811 if (driver != NULL) {
1812 int64_t now = systemTime();
1813 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1814 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1815
1816 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001817 driver->notifyMoreRebufferingTimeUs(
1818 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001819 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001820 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001821 }
1822 }
1823 }
1824 mLastStartedRebufferingTimeNs = 0;
1825 }
1826}
1827
1828void NuPlayer2::onPause() {
1829
1830 stopPlaybackTimer("onPause");
1831
1832 if (mPaused) {
1833 return;
1834 }
1835 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001836 if (mCurrentSourceInfo.mSource != NULL) {
1837 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001838 } else {
1839 ALOGW("pause called when source is gone or not set");
1840 }
1841 if (mRenderer != NULL) {
1842 mRenderer->pause();
1843 } else {
1844 ALOGW("pause called when renderer is gone or not set");
1845 }
1846
1847}
1848
1849bool NuPlayer2::audioDecoderStillNeeded() {
1850 // Audio decoder is no longer needed if it's in shut/shutting down status.
1851 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1852}
1853
1854void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1855 // We wait for both the decoder flush and the renderer flush to complete
1856 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1857
1858 mFlushComplete[audio][isDecoder] = true;
1859 if (!mFlushComplete[audio][!isDecoder]) {
1860 return;
1861 }
1862
1863 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1864 switch (*state) {
1865 case FLUSHING_DECODER:
1866 {
1867 *state = FLUSHED;
1868 break;
1869 }
1870
1871 case FLUSHING_DECODER_SHUTDOWN:
1872 {
1873 *state = SHUTTING_DOWN_DECODER;
1874
1875 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1876 getDecoder(audio)->initiateShutdown();
1877 break;
1878 }
1879
1880 default:
1881 // decoder flush completes only occur in a flushing state.
1882 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1883 break;
1884 }
1885}
1886
1887void NuPlayer2::finishFlushIfPossible() {
1888 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1889 && mFlushingAudio != SHUT_DOWN) {
1890 return;
1891 }
1892
1893 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1894 && mFlushingVideo != SHUT_DOWN) {
1895 return;
1896 }
1897
1898 ALOGV("both audio and video are flushed now.");
1899
1900 mFlushingAudio = NONE;
1901 mFlushingVideo = NONE;
1902
1903 clearFlushComplete();
1904
1905 processDeferredActions();
1906}
1907
1908void NuPlayer2::postScanSources() {
1909 if (mScanSourcesPending) {
1910 return;
1911 }
1912
1913 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1914 msg->setInt32("generation", mScanSourcesGeneration);
1915 msg->post();
1916
1917 mScanSourcesPending = true;
1918}
1919
1920void NuPlayer2::tryOpenAudioSinkForOffload(
1921 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1922 // Note: This is called early in NuPlayer2 to determine whether offloading
1923 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1924
1925 status_t err = mRenderer->openAudioSink(
1926 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001927 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001928 if (err != OK) {
1929 // Any failure we turn off mOffloadAudio.
1930 mOffloadAudio = false;
1931 } else if (mOffloadAudio) {
1932 sendMetaDataToHal(mAudioSink, audioMeta);
1933 }
1934}
1935
1936void NuPlayer2::closeAudioSink() {
1937 mRenderer->closeAudioSink();
1938}
1939
1940void NuPlayer2::restartAudio(
1941 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1942 if (mAudioDecoder != NULL) {
1943 mAudioDecoder->pause();
1944 mAudioDecoder.clear();
1945 mAudioDecoderError = false;
1946 ++mAudioDecoderGeneration;
1947 }
1948 if (mFlushingAudio == FLUSHING_DECODER) {
1949 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1950 mFlushingAudio = FLUSHED;
1951 finishFlushIfPossible();
1952 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1953 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1954 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1955 mFlushingAudio = SHUT_DOWN;
1956 finishFlushIfPossible();
1957 needsToCreateAudioDecoder = false;
1958 }
1959 if (mRenderer == NULL) {
1960 return;
1961 }
1962 closeAudioSink();
1963 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1964 if (mVideoDecoder != NULL) {
1965 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1966 }
1967
1968 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1969
1970 if (forceNonOffload) {
1971 mRenderer->signalDisableOffloadAudio();
1972 mOffloadAudio = false;
1973 }
1974 if (needsToCreateAudioDecoder) {
1975 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1976 }
1977}
1978
1979void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001980 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001981 return;
1982 }
1983
1984 if (mRenderer == NULL) {
1985 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1986 mOffloadAudio = false;
1987 return;
1988 }
1989
Wei Jiaf01e3122018-10-18 11:49:44 -07001990 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
1991 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001992 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1993 const bool hasVideo = (videoFormat != NULL);
1994 bool canOffload = canOffloadStream(
Wei Jiaf01e3122018-10-18 11:49:44 -07001995 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001996 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1997
1998 // Modular DRM: Disabling audio offload if the source is protected
1999 if (canOffload && mIsDrmProtected) {
2000 canOffload = false;
2001 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2002 }
2003
2004 if (canOffload) {
2005 if (!mOffloadAudio) {
2006 mRenderer->signalEnableOffloadAudio();
2007 }
2008 // open audio sink early under offload mode.
2009 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2010 } else {
2011 if (mOffloadAudio) {
2012 mRenderer->signalDisableOffloadAudio();
2013 mOffloadAudio = false;
2014 }
2015 }
2016}
2017
2018status_t NuPlayer2::instantiateDecoder(
2019 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2020 // The audio decoder could be cleared by tear down. If still in shut down
2021 // process, no need to create a new audio decoder.
2022 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2023 return OK;
2024 }
2025
Wei Jiaf01e3122018-10-18 11:49:44 -07002026 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002027
2028 if (format == NULL) {
2029 return UNKNOWN_ERROR;
2030 } else {
2031 status_t err;
2032 if (format->findInt32("err", &err) && err) {
2033 return err;
2034 }
2035 }
2036
2037 format->setInt32("priority", 0 /* realtime */);
2038
2039 if (!audio) {
2040 AString mime;
2041 CHECK(format->findString("mime", &mime));
2042
2043 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2044 if (mCCDecoder == NULL) {
2045 mCCDecoder = new CCDecoder(ccNotify);
2046 }
2047
Wei Jiaf01e3122018-10-18 11:49:44 -07002048 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002049 format->setInt32("secure", true);
2050 }
2051
Wei Jiaf01e3122018-10-18 11:49:44 -07002052 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002053 format->setInt32("protected", true);
2054 }
2055
2056 float rate = getFrameRate();
2057 if (rate > 0) {
2058 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2059 }
2060 }
2061
2062 if (audio) {
2063 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2064 ++mAudioDecoderGeneration;
2065 notify->setInt32("generation", mAudioDecoderGeneration);
2066
2067 if (checkAudioModeChange) {
2068 determineAudioModeChange(format);
2069 }
2070 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002071 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002072
Wei Jiaf01e3122018-10-18 11:49:44 -07002073 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002074 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002075 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002076 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2077 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002078 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002079
Wei Jiaf01e3122018-10-18 11:49:44 -07002080 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002081 ALOGV("instantiateDecoder audio Decoder");
2082 }
2083 mAudioDecoderError = false;
2084 } else {
2085 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2086 ++mVideoDecoderGeneration;
2087 notify->setInt32("generation", mVideoDecoderGeneration);
2088
2089 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002090 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2091 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002092 mVideoDecoderError = false;
2093
2094 // enable FRC if high-quality AV sync is requested, even if not
2095 // directly queuing to display, as this will even improve textureview
2096 // playback.
2097 {
2098 if (property_get_bool("persist.sys.media.avsync", false)) {
2099 format->setInt32("auto-frc", 1);
2100 }
2101 }
2102 }
2103 (*decoder)->init();
2104
2105 // Modular DRM
2106 if (mIsDrmProtected) {
2107 format->setObject("crypto", mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002108 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
2109 mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002110 }
2111
2112 (*decoder)->configure(format);
2113
2114 if (!audio) {
2115 sp<AMessage> params = new AMessage();
2116 float rate = getFrameRate();
2117 if (rate > 0) {
2118 params->setFloat("frame-rate-total", rate);
2119 }
2120
2121 sp<MetaData> fileMeta = getFileMeta();
2122 if (fileMeta != NULL) {
2123 int32_t videoTemporalLayerCount;
2124 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2125 && videoTemporalLayerCount > 0) {
2126 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2127 }
2128 }
2129
2130 if (params->countEntries() > 0) {
2131 (*decoder)->setParameters(params);
2132 }
2133 }
2134 return OK;
2135}
2136
2137void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002138 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002139 const sp<AMessage> &inputFormat,
2140 const sp<AMessage> &outputFormat) {
2141 if (inputFormat == NULL) {
2142 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002143 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002144 return;
2145 }
2146 int32_t err = OK;
2147 inputFormat->findInt32("err", &err);
2148 if (err == -EWOULDBLOCK) {
2149 ALOGW("Video meta is not available yet!");
2150 return;
2151 }
2152 if (err != OK) {
2153 ALOGW("Something is wrong with video meta!");
2154 return;
2155 }
2156
2157 int32_t displayWidth, displayHeight;
2158 if (outputFormat != NULL) {
2159 int32_t width, height;
2160 CHECK(outputFormat->findInt32("width", &width));
2161 CHECK(outputFormat->findInt32("height", &height));
2162
2163 int32_t cropLeft, cropTop, cropRight, cropBottom;
2164 CHECK(outputFormat->findRect(
2165 "crop",
2166 &cropLeft, &cropTop, &cropRight, &cropBottom));
2167
2168 displayWidth = cropRight - cropLeft + 1;
2169 displayHeight = cropBottom - cropTop + 1;
2170
2171 ALOGV("Video output format changed to %d x %d "
2172 "(crop: %d x %d @ (%d, %d))",
2173 width, height,
2174 displayWidth,
2175 displayHeight,
2176 cropLeft, cropTop);
2177 } else {
2178 CHECK(inputFormat->findInt32("width", &displayWidth));
2179 CHECK(inputFormat->findInt32("height", &displayHeight));
2180
2181 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2182 }
2183
2184 // Take into account sample aspect ratio if necessary:
2185 int32_t sarWidth, sarHeight;
2186 if (inputFormat->findInt32("sar-width", &sarWidth)
2187 && inputFormat->findInt32("sar-height", &sarHeight)
2188 && sarWidth > 0 && sarHeight > 0) {
2189 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2190
2191 displayWidth = (displayWidth * sarWidth) / sarHeight;
2192
2193 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2194 } else {
2195 int32_t width, height;
2196 if (inputFormat->findInt32("display-width", &width)
2197 && inputFormat->findInt32("display-height", &height)
2198 && width > 0 && height > 0
2199 && displayWidth > 0 && displayHeight > 0) {
2200 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2201 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2202 } else {
2203 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2204 }
2205 ALOGV("Video display width and height are overridden to %d x %d",
2206 displayWidth, displayHeight);
2207 }
2208 }
2209
2210 int32_t rotationDegrees;
2211 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2212 rotationDegrees = 0;
2213 }
2214
2215 if (rotationDegrees == 90 || rotationDegrees == 270) {
2216 int32_t tmp = displayWidth;
2217 displayWidth = displayHeight;
2218 displayHeight = tmp;
2219 }
2220
2221 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002222 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002223 MEDIA2_SET_VIDEO_SIZE,
2224 displayWidth,
2225 displayHeight);
2226}
2227
Dongwon Kang41929fb2018-09-09 08:29:56 -07002228void NuPlayer2::notifyListener(
2229 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002230 if (mDriver == NULL) {
2231 return;
2232 }
2233
2234 sp<NuPlayer2Driver> driver = mDriver.promote();
2235
2236 if (driver == NULL) {
2237 return;
2238 }
2239
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002240 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002241}
2242
2243void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2244 ALOGV("[%s] flushDecoder needShutdown=%d",
2245 audio ? "audio" : "video", needShutdown);
2246
2247 const sp<DecoderBase> &decoder = getDecoder(audio);
2248 if (decoder == NULL) {
2249 ALOGI("flushDecoder %s without decoder present",
2250 audio ? "audio" : "video");
2251 return;
2252 }
2253
2254 // Make sure we don't continue to scan sources until we finish flushing.
2255 ++mScanSourcesGeneration;
2256 if (mScanSourcesPending) {
2257 if (!needShutdown) {
2258 mDeferredActions.push_back(
2259 new SimpleAction(&NuPlayer2::performScanSources));
2260 }
2261 mScanSourcesPending = false;
2262 }
2263
2264 decoder->signalFlush();
2265
2266 FlushStatus newStatus =
2267 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2268
2269 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2270 mFlushComplete[audio][true /* isDecoder */] = false;
2271 if (audio) {
2272 ALOGE_IF(mFlushingAudio != NONE,
2273 "audio flushDecoder() is called in state %d", mFlushingAudio);
2274 mFlushingAudio = newStatus;
2275 } else {
2276 ALOGE_IF(mFlushingVideo != NONE,
2277 "video flushDecoder() is called in state %d", mFlushingVideo);
2278 mFlushingVideo = newStatus;
2279 }
2280}
2281
2282void NuPlayer2::queueDecoderShutdown(
2283 bool audio, bool video, const sp<AMessage> &reply) {
2284 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2285
2286 mDeferredActions.push_back(
2287 new FlushDecoderAction(
2288 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2289 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2290
2291 mDeferredActions.push_back(
2292 new SimpleAction(&NuPlayer2::performScanSources));
2293
2294 mDeferredActions.push_back(new PostMessageAction(reply));
2295
2296 processDeferredActions();
2297}
2298
2299status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2300 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002301 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2302 status_t ret = native_window_set_scaling_mode(
2303 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002304 if (ret != OK) {
2305 ALOGE("Failed to set scaling mode (%d): %s",
2306 -ret, strerror(-ret));
2307 return ret;
2308 }
2309 }
2310 return OK;
2311}
2312
Dongwon Kang9f631982018-07-10 12:34:41 -07002313status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002314 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2315 msg->setPointer("reply", reply);
2316
2317 sp<AMessage> response;
2318 status_t err = msg->postAndAwaitResponse(&response);
2319 return err;
2320}
2321
Dongwon Kang9f631982018-07-10 12:34:41 -07002322status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002323 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2324 msg->setPointer("reply", reply);
2325 msg->setInt32("type", type);
2326
2327 sp<AMessage> response;
2328 status_t err = msg->postAndAwaitResponse(&response);
2329 if (err == OK && response != NULL) {
2330 CHECK(response->findInt32("err", &err));
2331 }
2332 return err;
2333}
2334
2335status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2336 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2337 msg->setSize("trackIndex", trackIndex);
2338 msg->setInt32("select", select);
2339 msg->setInt64("timeUs", timeUs);
2340
2341 sp<AMessage> response;
2342 status_t err = msg->postAndAwaitResponse(&response);
2343
2344 if (err != OK) {
2345 return err;
2346 }
2347
2348 if (!response->findInt32("err", &err)) {
2349 err = OK;
2350 }
2351
2352 return err;
2353}
2354
2355status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2356 sp<Renderer> renderer = mRenderer;
2357 if (renderer == NULL) {
2358 return NO_INIT;
2359 }
2360
2361 return renderer->getCurrentPosition(mediaUs);
2362}
2363
2364void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2365 CHECK(mTrackStats != NULL);
2366
2367 mTrackStats->clear();
2368 if (mVideoDecoder != NULL) {
2369 mTrackStats->push_back(mVideoDecoder->getStats());
2370 }
2371 if (mAudioDecoder != NULL) {
2372 mTrackStats->push_back(mAudioDecoder->getStats());
2373 }
2374}
2375
2376sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002377 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002378}
2379
2380float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002381 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002382 if (meta == NULL) {
2383 return 0;
2384 }
2385 int32_t rate;
2386 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2387 // fall back to try file meta
2388 sp<MetaData> fileMeta = getFileMeta();
2389 if (fileMeta == NULL) {
2390 ALOGW("source has video meta but not file meta");
2391 return -1;
2392 }
2393 int32_t fileMetaRate;
2394 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2395 return -1;
2396 }
2397 return fileMetaRate;
2398 }
2399 return rate;
2400}
2401
2402void NuPlayer2::schedulePollDuration() {
2403 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2404 msg->setInt32("generation", mPollDurationGeneration);
2405 msg->post();
2406}
2407
2408void NuPlayer2::cancelPollDuration() {
2409 ++mPollDurationGeneration;
2410}
2411
2412void NuPlayer2::processDeferredActions() {
2413 while (!mDeferredActions.empty()) {
2414 // We won't execute any deferred actions until we're no longer in
2415 // an intermediate state, i.e. one more more decoders are currently
2416 // flushing or shutting down.
2417
2418 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2419 // We're currently flushing, postpone the reset until that's
2420 // completed.
2421
2422 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2423 mFlushingAudio, mFlushingVideo);
2424
2425 break;
2426 }
2427
2428 sp<Action> action = *mDeferredActions.begin();
2429 mDeferredActions.erase(mDeferredActions.begin());
2430
2431 action->execute(this);
2432 }
2433}
2434
2435void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2436 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2437 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2438
Wei Jiaf01e3122018-10-18 11:49:44 -07002439 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002440 // This happens when reset occurs right before the loop mode
2441 // asynchronously seeks to the start of the stream.
2442 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002443 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002444 mAudioDecoder.get(), mVideoDecoder.get());
2445 return;
2446 }
2447 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002448 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002449 ++mTimedTextGeneration;
2450
2451 // everything's flushed, continue playback.
2452}
2453
2454void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2455 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2456
2457 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2458 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2459 return;
2460 }
2461
2462 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2463 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2464 }
2465
2466 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2467 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2468 }
2469}
2470
2471void NuPlayer2::performReset() {
2472 ALOGV("performReset");
2473
2474 CHECK(mAudioDecoder == NULL);
2475 CHECK(mVideoDecoder == NULL);
2476
2477 stopPlaybackTimer("performReset");
2478 stopRebufferingTimer(true);
2479
2480 cancelPollDuration();
2481
2482 ++mScanSourcesGeneration;
2483 mScanSourcesPending = false;
2484
2485 if (mRendererLooper != NULL) {
2486 if (mRenderer != NULL) {
2487 mRendererLooper->unregisterHandler(mRenderer->id());
2488 }
2489 mRendererLooper->stop();
2490 mRendererLooper.clear();
2491 }
2492 mRenderer.clear();
2493 ++mRendererGeneration;
2494
Wei Jiaf01e3122018-10-18 11:49:44 -07002495 if (mCurrentSourceInfo.mSource != NULL) {
2496 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08002497
2498 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002499 mCurrentSourceInfo.mSource.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08002500 }
2501
2502 if (mDriver != NULL) {
2503 sp<NuPlayer2Driver> driver = mDriver.promote();
2504 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002505 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002506 }
2507 }
2508
2509 mStarted = false;
2510 mPrepared = false;
2511 mResetting = false;
2512 mSourceStarted = false;
2513
2514 // Modular DRM
2515 if (mCrypto != NULL) {
2516 // decoders will be flushed before this so their mCrypto would go away on their own
2517 // TODO change to ALOGV
2518 ALOGD("performReset mCrypto: %p", mCrypto.get());
2519 mCrypto.clear();
2520 }
2521 mIsDrmProtected = false;
2522}
2523
Wei Jia57aeffd2018-02-15 16:01:14 -08002524void NuPlayer2::performPlayNextDataSource() {
2525 ALOGV("performPlayNextDataSource");
2526
2527 CHECK(mAudioDecoder == NULL);
2528 CHECK(mVideoDecoder == NULL);
2529
2530 stopPlaybackTimer("performPlayNextDataSource");
2531 stopRebufferingTimer(true);
2532
2533 cancelPollDuration();
2534
2535 ++mScanSourcesGeneration;
2536 mScanSourcesPending = false;
2537
2538 ++mRendererGeneration;
2539
Wei Jiaf01e3122018-10-18 11:49:44 -07002540 if (mCurrentSourceInfo.mSource != NULL) {
2541 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002542 }
2543
2544 long previousSrcId;
2545 {
2546 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002547 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002548
2549 mCurrentSourceInfo = mNextSourceInfo;
2550 mNextSourceInfo = SourceInfo();
2551 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002552 }
2553
2554 if (mDriver != NULL) {
2555 sp<NuPlayer2Driver> driver = mDriver.promote();
2556 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002557 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002558
2559 int64_t durationUs;
2560 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2561 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2562 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002563 notifyListener(
2564 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002565 }
2566 }
2567
2568 mStarted = false;
2569 mPrepared = true; // TODO: what if it's not prepared
2570 mResetting = false;
2571 mSourceStarted = false;
2572
Wei Jiad1864f92018-10-19 12:34:56 -07002573 addEndTimeMonitor();
2574
Wei Jia57aeffd2018-02-15 16:01:14 -08002575 // Modular DRM
2576 if (mCrypto != NULL) {
2577 // decoders will be flushed before this so their mCrypto would go away on their own
2578 // TODO change to ALOGV
2579 ALOGD("performReset mCrypto: %p", mCrypto.get());
2580 mCrypto.clear();
2581 }
2582 mIsDrmProtected = false;
2583
2584 if (mRenderer != NULL) {
2585 mRenderer->resume();
2586 }
2587
Wei Jia6376cd52018-09-26 11:42:55 -07002588 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002589 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002590 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002591}
2592
Wei Jia53692fa2017-12-11 10:33:46 -08002593void NuPlayer2::performScanSources() {
2594 ALOGV("performScanSources");
2595
2596 if (!mStarted) {
2597 return;
2598 }
2599
2600 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2601 postScanSources();
2602 }
2603}
2604
Wei Jia28288fb2017-12-15 13:45:29 -08002605void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002606 ALOGV("performSetSurface");
2607
Wei Jia28288fb2017-12-15 13:45:29 -08002608 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002609
2610 // XXX - ignore error from setVideoScalingMode for now
2611 setVideoScalingMode(mVideoScalingMode);
2612
2613 if (mDriver != NULL) {
2614 sp<NuPlayer2Driver> driver = mDriver.promote();
2615 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002616 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002617 }
2618 }
2619}
2620
2621void NuPlayer2::performResumeDecoders(bool needNotify) {
2622 if (needNotify) {
2623 mResumePending = true;
2624 if (mVideoDecoder == NULL) {
2625 // if audio-only, we can notify seek complete now,
2626 // as the resume operation will be relatively fast.
2627 finishResume();
2628 }
2629 }
2630
2631 if (mVideoDecoder != NULL) {
2632 // When there is continuous seek, MediaPlayer will cache the seek
2633 // position, and send down new seek request when previous seek is
2634 // complete. Let's wait for at least one video output frame before
2635 // notifying seek complete, so that the video thumbnail gets updated
2636 // when seekbar is dragged.
2637 mVideoDecoder->signalResume(needNotify);
2638 }
2639
2640 if (mAudioDecoder != NULL) {
2641 mAudioDecoder->signalResume(false /* needNotify */);
2642 }
2643}
2644
2645void NuPlayer2::finishResume() {
2646 if (mResumePending) {
2647 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002648 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002649 }
2650}
2651
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002652void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002653 if (mDriver != NULL) {
2654 sp<NuPlayer2Driver> driver = mDriver.promote();
2655 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002656 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002657 }
2658 }
2659}
2660
2661void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2662 int32_t what;
2663 CHECK(msg->findInt32("what", &what));
2664
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002665 int64_t srcId;
2666 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002667 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002668 case Source::kWhatPrepared:
2669 {
Wei Jiad1864f92018-10-19 12:34:56 -07002670 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2671 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2672 if (srcId == mCurrentSourceInfo.mSrcId) {
2673 if (mCurrentSourceInfo.mSource == NULL) {
2674 // This is a stale notification from a source that was
2675 // asynchronously preparing when the client called reset().
2676 // We handled the reset, the source is gone.
2677 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002678 }
Wei Jiad1864f92018-10-19 12:34:56 -07002679
2680 int32_t err;
2681 CHECK(msg->findInt32("err", &err));
2682
2683 if (err != OK) {
2684 // shut down potential secure codecs in case client never calls reset
2685 mDeferredActions.push_back(
2686 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2687 FLUSH_CMD_SHUTDOWN /* video */));
2688 processDeferredActions();
2689 } else {
2690 mPrepared = true;
2691 }
2692
2693 sp<NuPlayer2Driver> driver = mDriver.promote();
2694 if (driver != NULL) {
2695 // notify duration first, so that it's definitely set when
2696 // the app received the "prepare complete" callback.
2697 int64_t durationUs;
2698 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2699 driver->notifyDuration(srcId, durationUs);
2700 }
2701 driver->notifyPrepareCompleted(srcId, err);
2702 }
2703 } else if (srcId == mNextSourceInfo.mSrcId) {
2704 if (mNextSourceInfo.mSource == NULL) {
2705 break; // stale
2706 }
2707
2708 sp<NuPlayer2Driver> driver = mDriver.promote();
2709 if (driver != NULL) {
2710 int32_t err;
2711 CHECK(msg->findInt32("err", &err));
2712 driver->notifyPrepareCompleted(srcId, err);
2713 }
Wei Jia53692fa2017-12-11 10:33:46 -08002714 }
2715
2716 break;
2717 }
2718
2719 // Modular DRM
2720 case Source::kWhatDrmInfo:
2721 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002722 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002723 sp<ABuffer> drmInfo;
2724 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002725 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002726
Dongwon Kang41929fb2018-09-09 08:29:56 -07002727 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2728 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002729
Dongwon Kang41929fb2018-09-09 08:29:56 -07002730 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002731
2732 break;
2733 }
2734
2735 case Source::kWhatFlagsChanged:
2736 {
2737 uint32_t flags;
2738 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2739
2740 sp<NuPlayer2Driver> driver = mDriver.promote();
2741 if (driver != NULL) {
2742
2743 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2744 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2745 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2746 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2747 (flags & Source::FLAG_CAN_PAUSE) != 0,
2748 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2749 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2750 (flags & Source::FLAG_CAN_SEEK) != 0,
2751 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2752 (flags & Source::FLAG_SECURE) != 0,
2753 (flags & Source::FLAG_PROTECTED) != 0);
2754
2755 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2756 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002757 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002758 }
Wei Jiad1864f92018-10-19 12:34:56 -07002759 if (srcId == mCurrentSourceInfo.mSrcId) {
2760 driver->notifyFlagsChanged(srcId, flags);
2761 }
Wei Jia53692fa2017-12-11 10:33:46 -08002762 }
2763
Wei Jiaf01e3122018-10-18 11:49:44 -07002764 if (srcId == mCurrentSourceInfo.mSrcId) {
2765 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2766 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2767 cancelPollDuration();
2768 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2769 && (flags & Source::FLAG_DYNAMIC_DURATION)
2770 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2771 schedulePollDuration();
2772 }
Wei Jia53692fa2017-12-11 10:33:46 -08002773
Wei Jiaf01e3122018-10-18 11:49:44 -07002774 mCurrentSourceInfo.mSourceFlags = flags;
2775 } else if (srcId == mNextSourceInfo.mSrcId) {
2776 // TODO: handle duration polling for next source.
2777 mNextSourceInfo.mSourceFlags = flags;
2778 }
Wei Jia53692fa2017-12-11 10:33:46 -08002779 break;
2780 }
2781
2782 case Source::kWhatVideoSizeChanged:
2783 {
2784 sp<AMessage> format;
2785 CHECK(msg->findMessage("format", &format));
2786
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002787 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002788 break;
2789 }
2790
2791 case Source::kWhatBufferingUpdate:
2792 {
2793 int32_t percentage;
2794 CHECK(msg->findInt32("percentage", &percentage));
2795
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002796 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002797 break;
2798 }
2799
2800 case Source::kWhatPauseOnBufferingStart:
2801 {
2802 // ignore if not playing
2803 if (mStarted) {
2804 ALOGI("buffer low, pausing...");
2805
2806 startRebufferingTimer();
2807 mPausedForBuffering = true;
2808 onPause();
2809 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002810 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002811 break;
2812 }
2813
2814 case Source::kWhatResumeOnBufferingEnd:
2815 {
2816 // ignore if not playing
2817 if (mStarted) {
2818 ALOGI("buffer ready, resuming...");
2819
2820 stopRebufferingTimer(false);
2821 mPausedForBuffering = false;
2822
2823 // do not resume yet if client didn't unpause
2824 if (!mPausedByClient) {
2825 onResume();
2826 }
2827 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002828 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002829 break;
2830 }
2831
2832 case Source::kWhatCacheStats:
2833 {
2834 int32_t kbps;
2835 CHECK(msg->findInt32("bandwidth", &kbps));
2836
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002837 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002838 break;
2839 }
2840
2841 case Source::kWhatSubtitleData:
2842 {
2843 sp<ABuffer> buffer;
2844 CHECK(msg->findBuffer("buffer", &buffer));
2845
2846 sendSubtitleData(buffer, 0 /* baseIndex */);
2847 break;
2848 }
2849
2850 case Source::kWhatTimedMetaData:
2851 {
2852 sp<ABuffer> buffer;
2853 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002854 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002855 } else {
2856 sendTimedMetaData(buffer);
2857 }
2858 break;
2859 }
2860
2861 case Source::kWhatTimedTextData:
2862 {
2863 int32_t generation;
2864 if (msg->findInt32("generation", &generation)
2865 && generation != mTimedTextGeneration) {
2866 break;
2867 }
2868
2869 sp<ABuffer> buffer;
2870 CHECK(msg->findBuffer("buffer", &buffer));
2871
2872 sp<NuPlayer2Driver> driver = mDriver.promote();
2873 if (driver == NULL) {
2874 break;
2875 }
2876
Wei Jia800fe372018-02-20 15:00:45 -08002877 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002878 int64_t timeUs, posUs;
2879 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002880 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002881 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2882
2883 if (posUs < timeUs) {
2884 if (!msg->findInt32("generation", &generation)) {
2885 msg->setInt32("generation", mTimedTextGeneration);
2886 }
2887 msg->post(timeUs - posUs);
2888 } else {
2889 sendTimedTextData(buffer);
2890 }
2891 break;
2892 }
2893
2894 case Source::kWhatQueueDecoderShutdown:
2895 {
2896 int32_t audio, video;
2897 CHECK(msg->findInt32("audio", &audio));
2898 CHECK(msg->findInt32("video", &video));
2899
2900 sp<AMessage> reply;
2901 CHECK(msg->findMessage("reply", &reply));
2902
2903 queueDecoderShutdown(audio, video, reply);
2904 break;
2905 }
2906
2907 case Source::kWhatDrmNoLicense:
2908 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002909 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002910 break;
2911 }
2912
2913 default:
2914 TRESPASS();
2915 }
2916}
2917
2918void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2919 int32_t what;
2920 CHECK(msg->findInt32("what", &what));
2921
2922 switch (what) {
2923 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2924 {
2925 sp<ABuffer> buffer;
2926 CHECK(msg->findBuffer("buffer", &buffer));
2927
2928 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002929 if (mCurrentSourceInfo.mSource != NULL) {
2930 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002931 }
2932
2933 sendSubtitleData(buffer, inbandTracks);
2934 break;
2935 }
2936
2937 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2938 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002939 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002940
2941 break;
2942 }
2943
2944 default:
2945 TRESPASS();
2946 }
2947
2948
2949}
2950
2951void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2952 int32_t trackIndex;
2953 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002954 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002955 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2956 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2957
Dongwon Kang41929fb2018-09-09 08:29:56 -07002958 PlayerMessage playerMsg;
2959 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2960 playerMsg.add_values()->set_int64_value(timeUs);
2961 playerMsg.add_values()->set_int64_value(durationUs);
2962 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002963
Wei Jiaf01e3122018-10-18 11:49:44 -07002964 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002965}
2966
2967void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2968 int64_t timeUs;
2969 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2970
Dongwon Kang41929fb2018-09-09 08:29:56 -07002971 PlayerMessage playerMsg;
2972 playerMsg.add_values()->set_int64_value(timeUs);
2973 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002974
Wei Jiaf01e3122018-10-18 11:49:44 -07002975 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002976}
2977
2978void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2979 const void *data;
2980 size_t size = 0;
2981 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002982 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002983
2984 AString mime;
2985 CHECK(buffer->meta()->findString("mime", &mime));
2986 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2987
2988 data = buffer->data();
2989 size = buffer->size();
2990
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002991 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002992 if (size > 0) {
2993 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2994 int32_t global = 0;
2995 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002996 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002997 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002998 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002999 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003000 TextDescriptions2::getPlayerMessageOfDescriptions(
3001 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003002 }
3003
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003004 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003005 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003006 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003007 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003008 }
3009}
3010
3011const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003012 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003013 case DATA_SOURCE_TYPE_HTTP_LIVE:
3014 return "HTTPLive";
3015
3016 case DATA_SOURCE_TYPE_RTSP:
3017 return "RTSP";
3018
3019 case DATA_SOURCE_TYPE_GENERIC_URL:
3020 return "GenURL";
3021
3022 case DATA_SOURCE_TYPE_GENERIC_FD:
3023 return "GenFD";
3024
3025 case DATA_SOURCE_TYPE_MEDIA:
3026 return "Media";
3027
Wei Jia53692fa2017-12-11 10:33:46 -08003028 case DATA_SOURCE_TYPE_NONE:
3029 default:
3030 return "None";
3031 }
3032 }
3033
3034// Modular DRM begin
3035status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3036{
3037 ALOGV("prepareDrm ");
3038
3039 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3040 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3041 // synchronous call so just passing the address but with local copies of "const" args
3042 uint8_t UUID[16];
3043 memcpy(UUID, uuid, sizeof(UUID));
3044 Vector<uint8_t> sessionId = drmSessionId;
3045 msg->setPointer("uuid", (void*)UUID);
3046 msg->setPointer("drmSessionId", (void*)&sessionId);
3047
3048 sp<AMessage> response;
3049 status_t status = msg->postAndAwaitResponse(&response);
3050
3051 if (status == OK && response != NULL) {
3052 CHECK(response->findInt32("status", &status));
3053 ALOGV("prepareDrm ret: %d ", status);
3054 } else {
3055 ALOGE("prepareDrm err: %d", status);
3056 }
3057
3058 return status;
3059}
3060
3061status_t NuPlayer2::releaseDrm()
3062{
3063 ALOGV("releaseDrm ");
3064
3065 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3066
3067 sp<AMessage> response;
3068 status_t status = msg->postAndAwaitResponse(&response);
3069
3070 if (status == OK && response != NULL) {
3071 CHECK(response->findInt32("status", &status));
3072 ALOGV("releaseDrm ret: %d ", status);
3073 } else {
3074 ALOGE("releaseDrm err: %d", status);
3075 }
3076
3077 return status;
3078}
3079
3080status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3081{
3082 // TODO change to ALOGV
3083 ALOGD("onPrepareDrm ");
3084
3085 status_t status = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -07003086 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003087 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3088 return status;
3089 }
3090
3091 uint8_t *uuid;
3092 Vector<uint8_t> *drmSessionId;
3093 CHECK(msg->findPointer("uuid", (void**)&uuid));
3094 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3095
3096 status = OK;
3097 sp<AMediaCryptoWrapper> crypto = NULL;
3098
Wei Jiaf01e3122018-10-18 11:49:44 -07003099 status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003100 if (crypto == NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003101 ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
Wei Jia53692fa2017-12-11 10:33:46 -08003102 return status;
3103 }
Wei Jiaf01e3122018-10-18 11:49:44 -07003104 ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
Wei Jia53692fa2017-12-11 10:33:46 -08003105
3106 if (mCrypto != NULL) {
3107 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3108 mCrypto.clear();
3109 }
3110
3111 mCrypto = crypto;
3112 mIsDrmProtected = true;
3113 // TODO change to ALOGV
3114 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3115
3116 return status;
3117}
3118
3119status_t NuPlayer2::onReleaseDrm()
3120{
3121 // TODO change to ALOGV
3122 ALOGD("onReleaseDrm ");
3123
3124 if (!mIsDrmProtected) {
3125 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3126 }
3127
3128 mIsDrmProtected = false;
3129
3130 status_t status;
3131 if (mCrypto != NULL) {
3132 // notifying the source first before removing crypto from codec
Wei Jiaf01e3122018-10-18 11:49:44 -07003133 if (mCurrentSourceInfo.mSource != NULL) {
3134 mCurrentSourceInfo.mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003135 }
3136
3137 status=OK;
3138 // first making sure the codecs have released their crypto reference
3139 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3140 if (videoDecoder != NULL) {
3141 status = videoDecoder->releaseCrypto();
3142 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3143 }
3144
3145 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3146 if (audioDecoder != NULL) {
3147 status_t status_audio = audioDecoder->releaseCrypto();
3148 if (status == OK) { // otherwise, returning the first error
3149 status = status_audio;
3150 }
3151 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3152 }
3153
3154 // TODO change to ALOGV
3155 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3156 mCrypto.clear();
3157 } else { // mCrypto == NULL
3158 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3159 status = INVALID_OPERATION;
3160 }
3161
3162 return status;
3163}
3164// Modular DRM end
3165////////////////////////////////////////////////////////////////////////////////
3166
3167sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3168 sp<MetaData> meta = getFormatMeta(audio);
3169
3170 if (meta == NULL) {
3171 return NULL;
3172 }
3173
3174 sp<AMessage> msg = new AMessage;
3175
3176 if(convertMetaDataToMessage(meta, &msg) == OK) {
3177 return msg;
3178 }
3179 return NULL;
3180}
3181
3182void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3183 sp<AMessage> notify = dupNotify();
3184 notify->setInt32("what", kWhatFlagsChanged);
3185 notify->setInt32("flags", flags);
3186 notify->post();
3187}
3188
3189void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3190 sp<AMessage> notify = dupNotify();
3191 notify->setInt32("what", kWhatVideoSizeChanged);
3192 notify->setMessage("format", format);
3193 notify->post();
3194}
3195
3196void NuPlayer2::Source::notifyPrepared(status_t err) {
3197 ALOGV("Source::notifyPrepared %d", err);
3198 sp<AMessage> notify = dupNotify();
3199 notify->setInt32("what", kWhatPrepared);
3200 notify->setInt32("err", err);
3201 notify->post();
3202}
3203
3204void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3205{
3206 ALOGV("Source::notifyDrmInfo");
3207
3208 sp<AMessage> notify = dupNotify();
3209 notify->setInt32("what", kWhatDrmInfo);
3210 notify->setBuffer("drmInfo", drmInfoBuffer);
3211
3212 notify->post();
3213}
3214
Wei Jia53692fa2017-12-11 10:33:46 -08003215void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3216 TRESPASS();
3217}
3218
Wei Jiaf01e3122018-10-18 11:49:44 -07003219NuPlayer2::SourceInfo::SourceInfo()
3220 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3221 mSrcId(0),
3222 mSourceFlags(0),
3223 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003224 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003225}
3226
Wei Jiad1864f92018-10-19 12:34:56 -07003227NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3228 mSource = other.mSource;
3229 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3230 mSrcId = other.mSrcId;
3231 mSourceFlags = other.mSourceFlags;
3232 mStartTimeUs = other.mStartTimeUs;
3233 mEndTimeUs = other.mEndTimeUs;
3234 return *this;
3235}
3236
Wei Jia53692fa2017-12-11 10:33:46 -08003237} // namespace android