blob: 156185044764c2a4baef45c644b263481bb7d151 [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "NuPlayer2"
19
20#include <inttypes.h>
21
22#include <utils/Log.h>
23
24#include "NuPlayer2.h"
25
Wei Jia2409c872018-02-02 10:34:33 -080026#include "HTTPLiveSource2.h"
Dongwon Kang946bdb32018-11-14 10:12:00 -080027#include "JMediaPlayer2Utils.h"
Wei Jia53692fa2017-12-11 10:33:46 -080028#include "NuPlayer2CCDecoder.h"
29#include "NuPlayer2Decoder.h"
30#include "NuPlayer2DecoderBase.h"
31#include "NuPlayer2DecoderPassThrough.h"
32#include "NuPlayer2Driver.h"
33#include "NuPlayer2Renderer.h"
34#include "NuPlayer2Source.h"
Wei Jia2409c872018-02-02 10:34:33 -080035#include "RTSPSource2.h"
36#include "GenericSource2.h"
Dongwon Kanga0e816a2018-09-10 19:46:49 -070037#include "TextDescriptions2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080038
39#include "ATSParser.h"
40
41#include <cutils/properties.h>
42
43#include <media/AudioParameter.h>
44#include <media/AudioResamplerPublic.h>
45#include <media/AVSyncSettings.h>
Wei Jiac2636032018-02-01 09:15:25 -080046#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080047#include <media/MediaCodecBuffer.h>
Wei Jia28288fb2017-12-15 13:45:29 -080048#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080049
50#include <media/stagefright/foundation/hexdump.h>
51#include <media/stagefright/foundation/ABuffer.h>
52#include <media/stagefright/foundation/ADebug.h>
53#include <media/stagefright/foundation/AMessage.h>
54#include <media/stagefright/foundation/avc_utils.h>
55#include <media/stagefright/MediaBuffer.h>
56#include <media/stagefright/MediaClock.h>
57#include <media/stagefright/MediaDefs.h>
58#include <media/stagefright/MediaErrors.h>
59#include <media/stagefright/MetaData.h>
60
Wei Jia53692fa2017-12-11 10:33:46 -080061#include "ESDS.h"
62#include <media/stagefright/Utils.h>
63
Wei Jia28288fb2017-12-15 13:45:29 -080064#include <system/window.h>
65
Wei Jia53692fa2017-12-11 10:33:46 -080066namespace android {
67
Wei Jia33abcc72018-01-30 09:47:38 -080068static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
Wei Jia53692fa2017-12-11 10:33:46 -080069 const sp<MetaData>& meta) {
70 int32_t sampleRate = 0;
71 int32_t bitRate = 0;
72 int32_t channelMask = 0;
73 int32_t delaySamples = 0;
74 int32_t paddingSamples = 0;
75
76 AudioParameter param = AudioParameter();
77
78 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
79 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
80 }
81 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
82 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
83 }
84 if (meta->findInt32(kKeyBitRate, &bitRate)) {
85 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
86 }
87 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
88 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
89 }
90 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
91 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
92 }
93
94 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
95 "delaySample %d, paddingSample %d", bitRate, sampleRate,
96 channelMask, delaySamples, paddingSamples);
97
98 sink->setParameters(param.toString());
99 return OK;
100}
101
102
103struct NuPlayer2::Action : public RefBase {
104 Action() {}
105
106 virtual void execute(NuPlayer2 *player) = 0;
107
108private:
109 DISALLOW_EVIL_CONSTRUCTORS(Action);
110};
111
112struct NuPlayer2::SeekAction : public Action {
113 explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
114 : mSeekTimeUs(seekTimeUs),
115 mMode(mode) {
116 }
117
118 virtual void execute(NuPlayer2 *player) {
119 player->performSeek(mSeekTimeUs, mMode);
120 }
121
122private:
123 int64_t mSeekTimeUs;
124 MediaPlayer2SeekMode mMode;
125
126 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
127};
128
129struct NuPlayer2::ResumeDecoderAction : public Action {
130 explicit ResumeDecoderAction(bool needNotify)
131 : mNeedNotify(needNotify) {
132 }
133
134 virtual void execute(NuPlayer2 *player) {
135 player->performResumeDecoders(mNeedNotify);
136 }
137
138private:
139 bool mNeedNotify;
140
141 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
142};
143
144struct NuPlayer2::SetSurfaceAction : public Action {
Wei Jia28288fb2017-12-15 13:45:29 -0800145 explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
146 : mNativeWindow(nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800147 }
148
149 virtual void execute(NuPlayer2 *player) {
Wei Jia28288fb2017-12-15 13:45:29 -0800150 player->performSetSurface(mNativeWindow);
Wei Jia53692fa2017-12-11 10:33:46 -0800151 }
152
153private:
Wei Jia28288fb2017-12-15 13:45:29 -0800154 sp<ANativeWindowWrapper> mNativeWindow;
Wei Jia53692fa2017-12-11 10:33:46 -0800155
156 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
157};
158
159struct NuPlayer2::FlushDecoderAction : public Action {
160 FlushDecoderAction(FlushCommand audio, FlushCommand video)
161 : mAudio(audio),
162 mVideo(video) {
163 }
164
165 virtual void execute(NuPlayer2 *player) {
166 player->performDecoderFlush(mAudio, mVideo);
167 }
168
169private:
170 FlushCommand mAudio;
171 FlushCommand mVideo;
172
173 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
174};
175
176struct NuPlayer2::PostMessageAction : public Action {
177 explicit PostMessageAction(const sp<AMessage> &msg)
178 : mMessage(msg) {
179 }
180
181 virtual void execute(NuPlayer2 *) {
182 mMessage->post();
183 }
184
185private:
186 sp<AMessage> mMessage;
187
188 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
189};
190
191// Use this if there's no state necessary to save in order to execute
192// the action.
193struct NuPlayer2::SimpleAction : public Action {
194 typedef void (NuPlayer2::*ActionFunc)();
195
196 explicit SimpleAction(ActionFunc func)
197 : mFunc(func) {
198 }
199
200 virtual void execute(NuPlayer2 *player) {
201 (player->*mFunc)();
202 }
203
204private:
205 ActionFunc mFunc;
206
207 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
208};
209
210////////////////////////////////////////////////////////////////////////////////
211
Wei Jia003fdb52018-02-06 14:44:32 -0800212NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
213 : mPID(pid),
214 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800215 mMediaClock(mediaClock),
Wei Jia53692fa2017-12-11 10:33:46 -0800216 mOffloadAudio(false),
217 mAudioDecoderGeneration(0),
218 mVideoDecoderGeneration(0),
219 mRendererGeneration(0),
Wei Jiad1864f92018-10-19 12:34:56 -0700220 mEOSMonitorGeneration(0),
Wei Jia53692fa2017-12-11 10:33:46 -0800221 mLastStartedPlayingTimeNs(0),
222 mPreviousSeekTimeUs(0),
223 mAudioEOS(false),
224 mVideoEOS(false),
225 mScanSourcesPending(false),
226 mScanSourcesGeneration(0),
227 mPollDurationGeneration(0),
228 mTimedTextGeneration(0),
229 mFlushingAudio(NONE),
230 mFlushingVideo(NONE),
231 mResumePending(false),
232 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
233 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
234 mVideoFpsHint(-1.f),
235 mStarted(false),
236 mPrepared(false),
237 mResetting(false),
238 mSourceStarted(false),
239 mAudioDecoderError(false),
240 mVideoDecoderError(false),
241 mPaused(false),
242 mPausedByClient(true),
Robert Shihc3fca0e2018-12-04 17:08:04 -0800243 mPausedForBuffering(false) {
Wei Jia53692fa2017-12-11 10:33:46 -0800244 CHECK(mediaClock != NULL);
245 clearFlushComplete();
246}
247
248NuPlayer2::~NuPlayer2() {
249}
250
Wei Jia53692fa2017-12-11 10:33:46 -0800251void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
252 mDriver = driver;
253}
254
Wei Jia53692fa2017-12-11 10:33:46 -0800255static bool IsHTTPLiveURL(const char *url) {
256 if (!strncasecmp("http://", url, 7)
257 || !strncasecmp("https://", url, 8)
258 || !strncasecmp("file://", url, 7)) {
259 size_t len = strlen(url);
260 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
261 return true;
262 }
263
264 if (strstr(url,"m3u8")) {
265 return true;
266 }
267 }
268
269 return false;
270}
271
Wei Jia72bf2a02018-02-06 15:29:23 -0800272status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
273 sp<Source> *source,
274 DATA_SOURCE_TYPE *dataSourceType) {
275 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800276 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800277 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800278
Wei Jiac2636032018-02-01 09:15:25 -0800279 switch (dsd->mType) {
280 case DataSourceDesc::TYPE_URL:
281 {
282 const char *url = dsd->mUrl.c_str();
283 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800284
Wei Jiac2636032018-02-01 09:15:25 -0800285 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
286 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800287
Wei Jiac2636032018-02-01 09:15:25 -0800288 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800289 *source = new HTTPLiveSource2(notify, httpService, url, headers);
290 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
291 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800292 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800293 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800294 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800295 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
296 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800297 } else if ((!strncasecmp(url, "http://", 7)
298 || !strncasecmp(url, "https://", 8))
299 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
300 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800301 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800302 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800303 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
304 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800305 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800306 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800307
Wei Jia2409c872018-02-02 10:34:33 -0800308 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800309 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800310
Robert Shih49fb89d2018-01-31 17:53:19 -0800311 err = genericSource->setDataSource(url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800312
313 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800314 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800315 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800316 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800317 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800318 }
319
320 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800321 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800322 }
323 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800324 }
325
Wei Jiac2636032018-02-01 09:15:25 -0800326 case DataSourceDesc::TYPE_FD:
327 {
Wei Jia2409c872018-02-02 10:34:33 -0800328 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800329 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800330
Wei Jia72bf2a02018-02-06 15:29:23 -0800331 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
332 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
333 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800334
Wei Jia72bf2a02018-02-06 15:29:23 -0800335 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800336
Wei Jiac2636032018-02-01 09:15:25 -0800337 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800338 ALOGE("Failed to create NuPlayer2Source!");
339 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800340 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800341 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800342 }
Wei Jia53692fa2017-12-11 10:33:46 -0800343
Wei Jia72bf2a02018-02-06 15:29:23 -0800344 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800345 break;
346 }
Wei Jia53692fa2017-12-11 10:33:46 -0800347
Wei Jiac2636032018-02-01 09:15:25 -0800348 case DataSourceDesc::TYPE_CALLBACK:
349 {
Wei Jia2409c872018-02-02 10:34:33 -0800350 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800351 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800352 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800353
Wei Jiac2636032018-02-01 09:15:25 -0800354 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800355 ALOGE("Failed to create NuPlayer2Source!");
356 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800357 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800358 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800359 }
360
Wei Jia72bf2a02018-02-06 15:29:23 -0800361 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800362 break;
363 }
364
365 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800366 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800367 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800368 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800369 ALOGE("invalid data source type!");
370 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800371 }
372
Wei Jia72bf2a02018-02-06 15:29:23 -0800373 return err;
374}
375
376void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
377 DATA_SOURCE_TYPE dataSourceType;
378 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800379 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800380
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800381 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
382 // and expects notifySetDataSourceCompleted regardless of success or failure.
383 // This will be changed since setDataSource should be asynchronous at JAVA level.
384 // When it succeeds, app will get onInfo notification. Otherwise, onError
385 // will be called.
386 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800387 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800388 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800389 return;
390 }
391
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800392 // Now, source != NULL.
393 */
394
Wei Jiaf01e3122018-10-18 11:49:44 -0700395 mCurrentSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800396
397 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800398 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800399 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700400 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
401 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia72bf2a02018-02-06 15:29:23 -0800402 msg->post();
403}
404
405void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
406 DATA_SOURCE_TYPE dataSourceType;
407 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800408 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800409
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800410 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800411 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800412 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800413 return;
414 }
415
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800416 // Now, source != NULL.
417 */
418
Wei Jiaf01e3122018-10-18 11:49:44 -0700419 mNextSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800420
421 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
422 msg->setObject("source", source);
423 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700424 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
425 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia53692fa2017-12-11 10:33:46 -0800426 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800427}
428
Wei Jia57aeffd2018-02-15 16:01:14 -0800429void NuPlayer2::playNextDataSource(int64_t srcId) {
430 disconnectSource();
431
432 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
433 msg->setInt64("srcId", srcId);
434 msg->post();
435}
436
Wei Jia53692fa2017-12-11 10:33:46 -0800437status_t NuPlayer2::getBufferingSettings(
438 BufferingSettings *buffering /* nonnull */) {
439 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
440 sp<AMessage> response;
441 status_t err = msg->postAndAwaitResponse(&response);
442 if (err == OK && response != NULL) {
443 CHECK(response->findInt32("err", &err));
444 if (err == OK) {
445 readFromAMessage(response, buffering);
446 }
447 }
448 return err;
449}
450
451status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
452 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
453 writeToAMessage(msg, buffering);
454 sp<AMessage> response;
455 status_t err = msg->postAndAwaitResponse(&response);
456 if (err == OK && response != NULL) {
457 CHECK(response->findInt32("err", &err));
458 }
459 return err;
460}
461
462void NuPlayer2::prepareAsync() {
463 ALOGV("prepareAsync");
464
465 (new AMessage(kWhatPrepare, this))->post();
466}
467
Wei Jia28288fb2017-12-15 13:45:29 -0800468void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800469 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
470
Wei Jia28288fb2017-12-15 13:45:29 -0800471 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800472 msg->setObject("surface", NULL);
473 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800474 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800475 }
476
477 msg->post();
478}
479
Wei Jia33abcc72018-01-30 09:47:38 -0800480void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800481 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
482 msg->setObject("sink", sink);
483 msg->post();
484}
485
486void NuPlayer2::start() {
487 (new AMessage(kWhatStart, this))->post();
488}
489
490status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
491 // do some cursory validation of the settings here. audio modes are
492 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700493 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800494 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
495 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
496 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
497 return BAD_VALUE;
498 }
499 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
500 writeToAMessage(msg, rate);
501 sp<AMessage> response;
502 status_t err = msg->postAndAwaitResponse(&response);
503 if (err == OK && response != NULL) {
504 CHECK(response->findInt32("err", &err));
505 }
506 return err;
507}
508
509status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
510 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
511 sp<AMessage> response;
512 status_t err = msg->postAndAwaitResponse(&response);
513 if (err == OK && response != NULL) {
514 CHECK(response->findInt32("err", &err));
515 if (err == OK) {
516 readFromAMessage(response, rate);
517 }
518 }
519 return err;
520}
521
522status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
523 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
524 writeToAMessage(msg, sync, videoFpsHint);
525 sp<AMessage> response;
526 status_t err = msg->postAndAwaitResponse(&response);
527 if (err == OK && response != NULL) {
528 CHECK(response->findInt32("err", &err));
529 }
530 return err;
531}
532
533status_t NuPlayer2::getSyncSettings(
534 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
535 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
536 sp<AMessage> response;
537 status_t err = msg->postAndAwaitResponse(&response);
538 if (err == OK && response != NULL) {
539 CHECK(response->findInt32("err", &err));
540 if (err == OK) {
541 readFromAMessage(response, sync, videoFps);
542 }
543 }
544 return err;
545}
546
547void NuPlayer2::pause() {
548 (new AMessage(kWhatPause, this))->post();
549}
550
551void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800552 disconnectSource();
553 (new AMessage(kWhatReset, this))->post();
554}
555
556void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800557 sp<Source> source;
558 {
559 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700560 source = mCurrentSourceInfo.mSource;
Wei Jia53692fa2017-12-11 10:33:46 -0800561 }
562
563 if (source != NULL) {
564 // During a reset, the data source might be unresponsive already, we need to
565 // disconnect explicitly so that reads exit promptly.
566 // We can't queue the disconnect request to the looper, as it might be
567 // queued behind a stuck read and never gets processed.
568 // Doing a disconnect outside the looper to allows the pending reads to exit
569 // (either successfully or with error).
570 source->disconnect();
571 }
572
Wei Jia53692fa2017-12-11 10:33:46 -0800573}
574
575status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
576 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
577 notify->setInt64("timerUs", mediaTimeUs);
578 mMediaClock->addTimer(notify, mediaTimeUs);
579 return OK;
580}
581
582void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
583 sp<AMessage> msg = new AMessage(kWhatSeek, this);
584 msg->setInt64("seekTimeUs", seekTimeUs);
585 msg->setInt32("mode", mode);
586 msg->setInt32("needNotify", needNotify);
587 msg->post();
588}
589
Wei Jiad1864f92018-10-19 12:34:56 -0700590void NuPlayer2::rewind() {
591 sp<AMessage> msg = new AMessage(kWhatRewind, this);
592 msg->post();
593}
594
Wei Jia53692fa2017-12-11 10:33:46 -0800595void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700596 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800597 if (format == NULL) {
598 ALOGE("NULL format");
599 return;
600 }
601 int32_t trackType;
602 if (!format->findInt32("type", &trackType)) {
603 ALOGE("no track type");
604 return;
605 }
606
607 AString mime;
608 if (!format->findString("mime", &mime)) {
609 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
610 // If we can't find the mimetype here it means that we wouldn't be needing
611 // the mimetype on the Java end. We still write a placeholder mime to keep the
612 // (de)serialization logic simple.
613 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
614 mime = "audio/";
615 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
616 mime = "video/";
617 } else {
618 ALOGE("unknown track type: %d", trackType);
619 return;
620 }
621 }
622
623 AString lang;
624 if (!format->findString("language", &lang)) {
625 ALOGE("no language");
626 return;
627 }
628
Dongwon Kang9f631982018-07-10 12:34:41 -0700629 reply->add_values()->set_int32_value(trackType);
630 reply->add_values()->set_string_value(mime.c_str());
631 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800632
633 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
634 int32_t isAuto, isDefault, isForced;
635 CHECK(format->findInt32("auto", &isAuto));
636 CHECK(format->findInt32("default", &isDefault));
637 CHECK(format->findInt32("forced", &isForced));
638
Dongwon Kang9f631982018-07-10 12:34:41 -0700639 reply->add_values()->set_int32_value(isAuto);
640 reply->add_values()->set_int32_value(isDefault);
641 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800642 }
643}
644
645void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
Dichen Zhangf8726912018-10-17 13:31:26 -0700646
Wei Jia53692fa2017-12-11 10:33:46 -0800647 switch (msg->what()) {
648 case kWhatSetDataSource:
649 {
650 ALOGV("kWhatSetDataSource");
651
Wei Jiaf01e3122018-10-18 11:49:44 -0700652 CHECK(mCurrentSourceInfo.mSource == NULL);
Wei Jia53692fa2017-12-11 10:33:46 -0800653
654 status_t err = OK;
655 sp<RefBase> obj;
656 CHECK(msg->findObject("source", &obj));
657 if (obj != NULL) {
658 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700659 CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
660 CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
661 CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
662 mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800663 } else {
664 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800665 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800666 }
667
668 CHECK(mDriver != NULL);
669 sp<NuPlayer2Driver> driver = mDriver.promote();
670 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700671 driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800672 }
673 break;
674 }
675
Wei Jia72bf2a02018-02-06 15:29:23 -0800676 case kWhatPrepareNextDataSource:
677 {
678 ALOGV("kWhatPrepareNextDataSource");
679
680 status_t err = OK;
681 sp<RefBase> obj;
682 CHECK(msg->findObject("source", &obj));
683 if (obj != NULL) {
684 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700685 CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
686 CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
687 CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
688 mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
689 mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
Wei Jia72bf2a02018-02-06 15:29:23 -0800690 } else {
691 err = UNKNOWN_ERROR;
692 }
693
694 break;
695 }
696
Wei Jia57aeffd2018-02-15 16:01:14 -0800697 case kWhatPlayNextDataSource:
698 {
699 ALOGV("kWhatPlayNextDataSource");
700 int64_t srcId;
701 CHECK(msg->findInt64("srcId", &srcId));
Wei Jiaf01e3122018-10-18 11:49:44 -0700702 if (srcId != mNextSourceInfo.mSrcId) {
Wei Jia57aeffd2018-02-15 16:01:14 -0800703 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
704 return;
705 }
706
707 mResetting = true;
708 stopPlaybackTimer("kWhatPlayNextDataSource");
709 stopRebufferingTimer(true);
710
711 mDeferredActions.push_back(
712 new FlushDecoderAction(
713 FLUSH_CMD_SHUTDOWN /* audio */,
714 FLUSH_CMD_SHUTDOWN /* video */));
715
716 mDeferredActions.push_back(
717 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
718
719 processDeferredActions();
720 break;
721 }
722
Wei Jiad1864f92018-10-19 12:34:56 -0700723 case kWhatEOSMonitor:
724 {
725 int32_t generation;
726 CHECK(msg->findInt32("generation", &generation));
727 int32_t reason;
728 CHECK(msg->findInt32("reason", &reason));
729
730 if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
731 break; // stale or reset
732 }
733
734 ALOGV("kWhatEOSMonitor");
735 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
736 break;
737 }
738
Wei Jia53692fa2017-12-11 10:33:46 -0800739 case kWhatGetBufferingSettings:
740 {
741 sp<AReplyToken> replyID;
742 CHECK(msg->senderAwaitsResponse(&replyID));
743
744 ALOGV("kWhatGetBufferingSettings");
745 BufferingSettings buffering;
746 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700747 if (mCurrentSourceInfo.mSource != NULL) {
748 err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800749 } else {
750 err = INVALID_OPERATION;
751 }
752 sp<AMessage> response = new AMessage;
753 if (err == OK) {
754 writeToAMessage(response, buffering);
755 }
756 response->setInt32("err", err);
757 response->postReply(replyID);
758 break;
759 }
760
761 case kWhatSetBufferingSettings:
762 {
763 sp<AReplyToken> replyID;
764 CHECK(msg->senderAwaitsResponse(&replyID));
765
766 ALOGV("kWhatSetBufferingSettings");
767 BufferingSettings buffering;
768 readFromAMessage(msg, &buffering);
769 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700770 if (mCurrentSourceInfo.mSource != NULL) {
771 err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800772 } else {
773 err = INVALID_OPERATION;
774 }
775 sp<AMessage> response = new AMessage;
776 response->setInt32("err", err);
777 response->postReply(replyID);
778 break;
779 }
780
781 case kWhatPrepare:
782 {
783 ALOGV("onMessageReceived kWhatPrepare");
784
Wei Jiaf01e3122018-10-18 11:49:44 -0700785 mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800786 break;
787 }
788
789 case kWhatGetTrackInfo:
790 {
791 sp<AReplyToken> replyID;
792 CHECK(msg->senderAwaitsResponse(&replyID));
793
Dongwon Kang9f631982018-07-10 12:34:41 -0700794 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800795 CHECK(msg->findPointer("reply", (void**)&reply));
796
797 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700798 if (mCurrentSourceInfo.mSource != NULL) {
799 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800800 }
801
802 size_t ccTracks = 0;
803 if (mCCDecoder != NULL) {
804 ccTracks = mCCDecoder->getTrackCount();
805 }
806
807 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700808 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800809
810 // write inband tracks
811 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700812 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800813 }
814
815 // write CC track
816 for (size_t i = 0; i < ccTracks; ++i) {
817 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
818 }
819
820 sp<AMessage> response = new AMessage;
821 response->postReply(replyID);
822 break;
823 }
824
825 case kWhatGetSelectedTrack:
826 {
Wei Jia039224f2018-11-29 17:25:17 -0800827 int32_t type32;
828 CHECK(msg->findInt32("type", (int32_t*)&type32));
829 media_track_type type = (media_track_type)type32;
830
831 size_t inbandTracks = 0;
Wei Jia53692fa2017-12-11 10:33:46 -0800832 status_t err = INVALID_OPERATION;
Wei Jia039224f2018-11-29 17:25:17 -0800833 ssize_t selectedTrack = -1;
Wei Jiaf01e3122018-10-18 11:49:44 -0700834 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800835 err = OK;
Wei Jia039224f2018-11-29 17:25:17 -0800836 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
837 selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800838 }
839
Wei Jia039224f2018-11-29 17:25:17 -0800840 if (selectedTrack == -1 && mCCDecoder != NULL) {
841 err = OK;
842 selectedTrack = mCCDecoder->getSelectedTrack(type);
843 if (selectedTrack != -1) {
844 selectedTrack += inbandTracks;
845 }
846 }
847
848 PlayerMessage* reply;
849 CHECK(msg->findPointer("reply", (void**)&reply));
850 reply->add_values()->set_int32_value(selectedTrack);
851
Wei Jia53692fa2017-12-11 10:33:46 -0800852 sp<AMessage> response = new AMessage;
853 response->setInt32("err", err);
854
855 sp<AReplyToken> replyID;
856 CHECK(msg->senderAwaitsResponse(&replyID));
857 response->postReply(replyID);
858 break;
859 }
860
861 case kWhatSelectTrack:
862 {
863 sp<AReplyToken> replyID;
864 CHECK(msg->senderAwaitsResponse(&replyID));
865
866 size_t trackIndex;
867 int32_t select;
868 int64_t timeUs;
869 CHECK(msg->findSize("trackIndex", &trackIndex));
870 CHECK(msg->findInt32("select", &select));
871 CHECK(msg->findInt64("timeUs", &timeUs));
872
873 status_t err = INVALID_OPERATION;
874
875 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700876 if (mCurrentSourceInfo.mSource != NULL) {
877 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800878 }
879 size_t ccTracks = 0;
880 if (mCCDecoder != NULL) {
881 ccTracks = mCCDecoder->getTrackCount();
882 }
883
884 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700885 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800886
887 if (!select && err == OK) {
888 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700889 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800890 if (info != NULL
891 && info->findInt32("type", &type)
892 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
893 ++mTimedTextGeneration;
894 }
895 }
896 } else {
897 trackIndex -= inbandTracks;
898
899 if (trackIndex < ccTracks) {
900 err = mCCDecoder->selectTrack(trackIndex, select);
901 }
902 }
903
904 sp<AMessage> response = new AMessage;
905 response->setInt32("err", err);
906
907 response->postReply(replyID);
908 break;
909 }
910
911 case kWhatPollDuration:
912 {
913 int32_t generation;
914 CHECK(msg->findInt32("generation", &generation));
915
916 if (generation != mPollDurationGeneration) {
917 // stale
918 break;
919 }
920
921 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700922 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800923 sp<NuPlayer2Driver> driver = mDriver.promote();
924 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700925 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800926 }
927 }
928
929 msg->post(1000000ll); // poll again in a second.
930 break;
931 }
932
933 case kWhatSetVideoSurface:
934 {
935
936 sp<RefBase> obj;
937 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800938 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800939
940 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800941 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700942 (mCurrentSourceInfo.mSource != NULL && mStarted
943 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800944 && mVideoDecoder != NULL) ? "have" : "no");
945
Wei Jiaf01e3122018-10-18 11:49:44 -0700946 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
947 // because NuPlayer2 might be in preparing state and it could take long time.
948 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
949 if (mCurrentSourceInfo.mSource == NULL || !mStarted
950 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800951 // NOTE: mVideoDecoder's mNativeWindow is always non-null
952 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
953 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800954 break;
955 }
956
957 mDeferredActions.push_back(
958 new FlushDecoderAction(
959 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
960 FLUSH_CMD_SHUTDOWN /* video */));
961
Wei Jia28288fb2017-12-15 13:45:29 -0800962 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800963
964 if (obj != NULL) {
965 if (mStarted) {
966 // Issue a seek to refresh the video screen only if started otherwise
967 // the extractor may not yet be started and will assert.
968 // If the video decoder is not set (perhaps audio only in this case)
969 // do not perform a seek as it is not needed.
970 int64_t currentPositionUs = 0;
971 if (getCurrentPosition(&currentPositionUs) == OK) {
972 mDeferredActions.push_back(
973 new SeekAction(currentPositionUs,
974 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
975 }
976 }
977
978 // If there is a new surface texture, instantiate decoders
979 // again if possible.
980 mDeferredActions.push_back(
981 new SimpleAction(&NuPlayer2::performScanSources));
982
983 // After a flush without shutdown, decoder is paused.
984 // Don't resume it until source seek is done, otherwise it could
985 // start pulling stale data too soon.
986 mDeferredActions.push_back(
987 new ResumeDecoderAction(false /* needNotify */));
988 }
989
990 processDeferredActions();
991 break;
992 }
993
994 case kWhatSetAudioSink:
995 {
996 ALOGV("kWhatSetAudioSink");
997
998 sp<RefBase> obj;
999 CHECK(msg->findObject("sink", &obj));
1000
Wei Jia33abcc72018-01-30 09:47:38 -08001001 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001002 break;
1003 }
1004
1005 case kWhatStart:
1006 {
1007 ALOGV("kWhatStart");
1008 if (mStarted) {
1009 // do not resume yet if the source is still buffering
1010 if (!mPausedForBuffering) {
1011 onResume();
1012 }
1013 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001014 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001015 }
1016 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001017 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001018 break;
1019 }
1020
1021 case kWhatConfigPlayback:
1022 {
1023 sp<AReplyToken> replyID;
1024 CHECK(msg->senderAwaitsResponse(&replyID));
1025 AudioPlaybackRate rate /* sanitized */;
1026 readFromAMessage(msg, &rate);
1027 status_t err = OK;
1028 if (mRenderer != NULL) {
1029 // AudioSink allows only 1.f and 0.f for offload mode.
1030 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001031 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001032 int64_t currentPositionUs;
1033 if (getCurrentPosition(&currentPositionUs) != OK) {
1034 currentPositionUs = mPreviousSeekTimeUs;
1035 }
1036
1037 // Set mPlaybackSettings so that the new audio decoder can
1038 // be created correctly.
1039 mPlaybackSettings = rate;
1040 if (!mPaused) {
1041 mRenderer->pause();
1042 }
1043 restartAudio(
1044 currentPositionUs, true /* forceNonOffload */,
1045 true /* needsToCreateAudioDecoder */);
1046 if (!mPaused) {
1047 mRenderer->resume();
1048 }
1049 }
1050
1051 err = mRenderer->setPlaybackSettings(rate);
1052 }
1053 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001054 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001055
Wei Jia700a7c22018-09-14 18:04:35 -07001056 if (mVideoDecoder != NULL) {
1057 sp<AMessage> params = new AMessage();
1058 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1059 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001060 }
1061 }
1062
Wei Jia53692fa2017-12-11 10:33:46 -08001063 sp<AMessage> response = new AMessage;
1064 response->setInt32("err", err);
1065 response->postReply(replyID);
1066 break;
1067 }
1068
1069 case kWhatGetPlaybackSettings:
1070 {
1071 sp<AReplyToken> replyID;
1072 CHECK(msg->senderAwaitsResponse(&replyID));
1073 AudioPlaybackRate rate = mPlaybackSettings;
1074 status_t err = OK;
1075 if (mRenderer != NULL) {
1076 err = mRenderer->getPlaybackSettings(&rate);
1077 }
1078 if (err == OK) {
1079 // get playback settings used by renderer, as it may be
1080 // slightly off due to audiosink not taking small changes.
1081 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001082 }
1083 sp<AMessage> response = new AMessage;
1084 if (err == OK) {
1085 writeToAMessage(response, rate);
1086 }
1087 response->setInt32("err", err);
1088 response->postReply(replyID);
1089 break;
1090 }
1091
1092 case kWhatConfigSync:
1093 {
1094 sp<AReplyToken> replyID;
1095 CHECK(msg->senderAwaitsResponse(&replyID));
1096
1097 ALOGV("kWhatConfigSync");
1098 AVSyncSettings sync;
1099 float videoFpsHint;
1100 readFromAMessage(msg, &sync, &videoFpsHint);
1101 status_t err = OK;
1102 if (mRenderer != NULL) {
1103 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1104 }
1105 if (err == OK) {
1106 mSyncSettings = sync;
1107 mVideoFpsHint = videoFpsHint;
1108 }
1109 sp<AMessage> response = new AMessage;
1110 response->setInt32("err", err);
1111 response->postReply(replyID);
1112 break;
1113 }
1114
1115 case kWhatGetSyncSettings:
1116 {
1117 sp<AReplyToken> replyID;
1118 CHECK(msg->senderAwaitsResponse(&replyID));
1119 AVSyncSettings sync = mSyncSettings;
1120 float videoFps = mVideoFpsHint;
1121 status_t err = OK;
1122 if (mRenderer != NULL) {
1123 err = mRenderer->getSyncSettings(&sync, &videoFps);
1124 if (err == OK) {
1125 mSyncSettings = sync;
1126 mVideoFpsHint = videoFps;
1127 }
1128 }
1129 sp<AMessage> response = new AMessage;
1130 if (err == OK) {
1131 writeToAMessage(response, sync, videoFps);
1132 }
1133 response->setInt32("err", err);
1134 response->postReply(replyID);
1135 break;
1136 }
1137
1138 case kWhatScanSources:
1139 {
1140 int32_t generation;
1141 CHECK(msg->findInt32("generation", &generation));
1142 if (generation != mScanSourcesGeneration) {
1143 // Drop obsolete msg.
1144 break;
1145 }
1146
1147 mScanSourcesPending = false;
1148
1149 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1150 mAudioDecoder != NULL, mVideoDecoder != NULL);
1151
1152 bool mHadAnySourcesBefore =
1153 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1154 bool rescan = false;
1155
1156 // initialize video before audio because successful initialization of
1157 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001158 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001159 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1160 rescan = true;
1161 }
1162 }
1163
1164 // Don't try to re-open audio sink if there's an existing decoder.
1165 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1166 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1167 rescan = true;
1168 }
1169 }
1170
1171 if (!mHadAnySourcesBefore
1172 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1173 // This is the first time we've found anything playable.
1174
Wei Jiaf01e3122018-10-18 11:49:44 -07001175 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001176 schedulePollDuration();
1177 }
1178 }
1179
1180 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001181 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001182 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1183 // We're not currently decoding anything (no audio or
1184 // video tracks found) and we just ran out of input data.
1185
1186 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001187 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001188 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001189 notifyListener(
1190 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001191 }
1192 }
1193 break;
1194 }
1195
1196 if (rescan) {
1197 msg->post(100000ll);
1198 mScanSourcesPending = true;
1199 }
1200 break;
1201 }
1202
1203 case kWhatVideoNotify:
1204 case kWhatAudioNotify:
1205 {
1206 bool audio = msg->what() == kWhatAudioNotify;
1207
1208 int32_t currentDecoderGeneration =
1209 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1210 int32_t requesterGeneration = currentDecoderGeneration - 1;
1211 CHECK(msg->findInt32("generation", &requesterGeneration));
1212
1213 if (requesterGeneration != currentDecoderGeneration) {
1214 ALOGV("got message from old %s decoder, generation(%d:%d)",
1215 audio ? "audio" : "video", requesterGeneration,
1216 currentDecoderGeneration);
1217 sp<AMessage> reply;
1218 if (!(msg->findMessage("reply", &reply))) {
1219 return;
1220 }
1221
1222 reply->setInt32("err", INFO_DISCONTINUITY);
1223 reply->post();
1224 return;
1225 }
1226
1227 int32_t what;
1228 CHECK(msg->findInt32("what", &what));
1229
1230 if (what == DecoderBase::kWhatInputDiscontinuity) {
1231 int32_t formatChange;
1232 CHECK(msg->findInt32("formatChange", &formatChange));
1233
1234 ALOGV("%s discontinuity: formatChange %d",
1235 audio ? "audio" : "video", formatChange);
1236
1237 if (formatChange) {
1238 mDeferredActions.push_back(
1239 new FlushDecoderAction(
1240 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1241 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1242 }
1243
1244 mDeferredActions.push_back(
1245 new SimpleAction(
1246 &NuPlayer2::performScanSources));
1247
1248 processDeferredActions();
1249 } else if (what == DecoderBase::kWhatEOS) {
1250 int32_t err;
1251 CHECK(msg->findInt32("err", &err));
1252
1253 if (err == ERROR_END_OF_STREAM) {
1254 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1255 } else {
1256 ALOGV("got %s decoder EOS w/ error %d",
1257 audio ? "audio" : "video",
1258 err);
1259 }
1260
1261 mRenderer->queueEOS(audio, err);
1262 } else if (what == DecoderBase::kWhatFlushCompleted) {
1263 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1264
1265 handleFlushComplete(audio, true /* isDecoder */);
1266 finishFlushIfPossible();
1267 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1268 sp<AMessage> format;
1269 CHECK(msg->findMessage("format", &format));
1270
1271 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001272 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001273
1274 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001275 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001276 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1277 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1278 if (audio) {
1279 mAudioDecoder.clear();
1280 mAudioDecoderError = false;
1281 ++mAudioDecoderGeneration;
1282
1283 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1284 mFlushingAudio = SHUT_DOWN;
1285 } else {
1286 mVideoDecoder.clear();
1287 mVideoDecoderError = false;
1288 ++mVideoDecoderGeneration;
1289
1290 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1291 mFlushingVideo = SHUT_DOWN;
1292 }
1293
1294 finishFlushIfPossible();
1295 } else if (what == DecoderBase::kWhatResumeCompleted) {
1296 finishResume();
1297 } else if (what == DecoderBase::kWhatError) {
1298 status_t err;
1299 if (!msg->findInt32("err", &err) || err == OK) {
1300 err = UNKNOWN_ERROR;
1301 }
1302
1303 // Decoder errors can be due to Source (e.g. from streaming),
1304 // or from decoding corrupted bitstreams, or from other decoder
1305 // MediaCodec operations (e.g. from an ongoing reset or seek).
1306 // They may also be due to openAudioSink failure at
1307 // decoder start or after a format change.
1308 //
1309 // We try to gracefully shut down the affected decoder if possible,
1310 // rather than trying to force the shutdown with something
1311 // similar to performReset(). This method can lead to a hang
1312 // if MediaCodec functions block after an error, but they should
1313 // typically return INVALID_OPERATION instead of blocking.
1314
1315 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1316 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1317 err, audio ? "audio" : "video", *flushing);
1318
1319 switch (*flushing) {
1320 case NONE:
1321 mDeferredActions.push_back(
1322 new FlushDecoderAction(
1323 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1324 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1325 processDeferredActions();
1326 break;
1327 case FLUSHING_DECODER:
1328 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1329 break; // Wait for flush to complete.
1330 case FLUSHING_DECODER_SHUTDOWN:
1331 break; // Wait for flush to complete.
1332 case SHUTTING_DOWN_DECODER:
1333 break; // Wait for shutdown to complete.
1334 case FLUSHED:
1335 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1336 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1337 break;
1338 case SHUT_DOWN:
1339 finishFlushIfPossible(); // Should not occur.
1340 break; // Finish anyways.
1341 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001342 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001343 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001344 if (mVideoDecoderError
1345 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1346 || mNativeWindow == NULL
1347 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001348 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001349 // When both audio and video have error, or this stream has only audio
1350 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001351 notifyListener(
1352 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1353 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001354 } else {
1355 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001356 notifyListener(
1357 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1358 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001359 }
1360 mAudioDecoderError = true;
1361 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001362 if (mAudioDecoderError
1363 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001364 || mAudioSink == NULL || mAudioDecoder == NULL) {
1365 // When both audio and video have error, or this stream has only video
1366 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001367 notifyListener(
1368 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1369 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001370 } else {
1371 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001372 notifyListener(
1373 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1374 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001375 }
1376 mVideoDecoderError = true;
1377 }
1378 }
1379 } else {
1380 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1381 what,
1382 what >> 24,
1383 (what >> 16) & 0xff,
1384 (what >> 8) & 0xff,
1385 what & 0xff);
1386 }
1387
1388 break;
1389 }
1390
1391 case kWhatRendererNotify:
1392 {
1393 int32_t requesterGeneration = mRendererGeneration - 1;
1394 CHECK(msg->findInt32("generation", &requesterGeneration));
1395 if (requesterGeneration != mRendererGeneration) {
1396 ALOGV("got message from old renderer, generation(%d:%d)",
1397 requesterGeneration, mRendererGeneration);
1398 return;
1399 }
1400
1401 int32_t what;
1402 CHECK(msg->findInt32("what", &what));
1403
1404 if (what == Renderer::kWhatEOS) {
1405 int32_t audio;
1406 CHECK(msg->findInt32("audio", &audio));
1407
1408 int32_t finalResult;
1409 CHECK(msg->findInt32("finalResult", &finalResult));
1410
1411 if (audio) {
1412 mAudioEOS = true;
1413 } else {
1414 mVideoEOS = true;
1415 }
1416
1417 if (finalResult == ERROR_END_OF_STREAM) {
1418 ALOGV("reached %s EOS", audio ? "audio" : "video");
1419 } else {
1420 ALOGE("%s track encountered an error (%d)",
1421 audio ? "audio" : "video", finalResult);
1422
1423 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001424 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1425 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001426 }
1427
1428 if ((mAudioEOS || mAudioDecoder == NULL)
1429 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001430 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001431 }
1432 } else if (what == Renderer::kWhatFlushComplete) {
1433 int32_t audio;
1434 CHECK(msg->findInt32("audio", &audio));
1435
1436 if (audio) {
1437 mAudioEOS = false;
1438 } else {
1439 mVideoEOS = false;
1440 }
1441
1442 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1443 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1444 || mFlushingAudio == SHUT_DOWN)) {
1445 // Flush has been handled by tear down.
1446 break;
1447 }
1448 handleFlushComplete(audio, false /* isDecoder */);
1449 finishFlushIfPossible();
1450 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001451 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1452 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001453 } else if (what == Renderer::kWhatMediaRenderingStart) {
1454 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001455 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001456 } else if (what == Renderer::kWhatAudioTearDown) {
1457 int32_t reason;
1458 CHECK(msg->findInt32("reason", &reason));
1459 ALOGV("Tear down audio with reason %d.", reason);
1460 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1461 // TimeoutWhenPaused is only for offload mode.
1462 ALOGW("Receive a stale message for teardown.");
1463 break;
1464 }
1465 int64_t positionUs;
1466 if (!msg->findInt64("positionUs", &positionUs)) {
1467 positionUs = mPreviousSeekTimeUs;
1468 }
1469
1470 restartAudio(
1471 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1472 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1473 }
1474 break;
1475 }
1476
1477 case kWhatMoreDataQueued:
1478 {
1479 break;
1480 }
1481
1482 case kWhatReset:
1483 {
1484 ALOGV("kWhatReset");
1485
1486 mResetting = true;
1487 stopPlaybackTimer("kWhatReset");
1488 stopRebufferingTimer(true);
1489
1490 mDeferredActions.push_back(
1491 new FlushDecoderAction(
1492 FLUSH_CMD_SHUTDOWN /* audio */,
1493 FLUSH_CMD_SHUTDOWN /* video */));
1494
1495 mDeferredActions.push_back(
1496 new SimpleAction(&NuPlayer2::performReset));
1497
1498 processDeferredActions();
1499 break;
1500 }
1501
1502 case kWhatNotifyTime:
1503 {
1504 ALOGV("kWhatNotifyTime");
1505 int64_t timerUs;
1506 CHECK(msg->findInt64("timerUs", &timerUs));
1507
Wei Jiaf01e3122018-10-18 11:49:44 -07001508 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001509 break;
1510 }
1511
1512 case kWhatSeek:
1513 {
1514 int64_t seekTimeUs;
1515 int32_t mode;
1516 int32_t needNotify;
1517 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1518 CHECK(msg->findInt32("mode", &mode));
1519 CHECK(msg->findInt32("needNotify", &needNotify));
1520
1521 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1522 (long long)seekTimeUs, mode, needNotify);
1523
1524 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001525 if (!mSourceStarted) {
1526 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001527 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001528 }
Wei Jia083e9092018-02-12 11:46:04 -08001529 if (seekTimeUs > 0) {
1530 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1531 }
1532
Wei Jia53692fa2017-12-11 10:33:46 -08001533 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001534 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001535 }
1536 break;
1537 }
1538
Wei Jia083e9092018-02-12 11:46:04 -08001539 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001540 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001541
Wei Jia53692fa2017-12-11 10:33:46 -08001542 mDeferredActions.push_back(
1543 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1544 FLUSH_CMD_FLUSH /* video */));
1545
1546 mDeferredActions.push_back(
1547 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1548
1549 // After a flush without shutdown, decoder is paused.
1550 // Don't resume it until source seek is done, otherwise it could
1551 // start pulling stale data too soon.
1552 mDeferredActions.push_back(
1553 new ResumeDecoderAction(needNotify));
1554
1555 processDeferredActions();
1556 break;
1557 }
1558
Wei Jiad1864f92018-10-19 12:34:56 -07001559 case kWhatRewind:
1560 {
1561 ALOGV("kWhatRewind");
1562
1563 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1564 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1565
1566 if (!mStarted) {
1567 if (!mSourceStarted) {
1568 mSourceStarted = true;
1569 mCurrentSourceInfo.mSource->start();
1570 }
1571 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1572 break;
1573 }
1574
1575 // seeks can take a while, so we essentially paused
1576 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1577
1578 mDeferredActions.push_back(
1579 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1580 FLUSH_CMD_FLUSH /* video */));
1581
1582 mDeferredActions.push_back(
1583 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1584
1585 // After a flush without shutdown, decoder is paused.
1586 // Don't resume it until source seek is done, otherwise it could
1587 // start pulling stale data too soon.
1588 mDeferredActions.push_back(
1589 new ResumeDecoderAction(false /* needNotify */));
1590
1591 processDeferredActions();
1592 break;
1593 }
1594
Wei Jia53692fa2017-12-11 10:33:46 -08001595 case kWhatPause:
1596 {
Wei Jia6376cd52018-09-26 11:42:55 -07001597 if (!mStarted) {
1598 onStart(false /* play */);
1599 }
Wei Jia53692fa2017-12-11 10:33:46 -08001600 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001601 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001602 mPausedByClient = true;
1603 break;
1604 }
1605
1606 case kWhatSourceNotify:
1607 {
1608 onSourceNotify(msg);
1609 break;
1610 }
1611
1612 case kWhatClosedCaptionNotify:
1613 {
1614 onClosedCaptionNotify(msg);
1615 break;
1616 }
1617
1618 case kWhatPrepareDrm:
1619 {
1620 status_t status = onPrepareDrm(msg);
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 case kWhatReleaseDrm:
1631 {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001632 status_t status = onReleaseDrm(msg);
Wei Jia53692fa2017-12-11 10:33:46 -08001633
1634 sp<AMessage> response = new AMessage;
1635 response->setInt32("status", status);
1636 sp<AReplyToken> replyID;
1637 CHECK(msg->senderAwaitsResponse(&replyID));
1638 response->postReply(replyID);
1639 break;
1640 }
1641
1642 default:
1643 TRESPASS();
1644 break;
1645 }
1646}
1647
1648void NuPlayer2::onResume() {
1649 if (!mPaused || mResetting) {
1650 ALOGD_IF(mResetting, "resetting, onResume discarded");
1651 return;
1652 }
1653 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001654 if (mCurrentSourceInfo.mSource != NULL) {
1655 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001656 } else {
1657 ALOGW("resume called when source is gone or not set");
1658 }
1659 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1660 // needed.
1661 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1662 instantiateDecoder(true /* audio */, &mAudioDecoder);
1663 }
1664 if (mRenderer != NULL) {
1665 mRenderer->resume();
1666 } else {
1667 ALOGW("resume called when renderer is gone or not set");
1668 }
1669
1670 startPlaybackTimer("onresume");
1671}
1672
Wei Jia6376cd52018-09-26 11:42:55 -07001673void NuPlayer2::onStart(bool play) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001674 ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001675
1676 if (!mSourceStarted) {
1677 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001678 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001679 }
Wei Jia53692fa2017-12-11 10:33:46 -08001680
1681 mOffloadAudio = false;
1682 mAudioEOS = false;
1683 mVideoEOS = false;
1684 mStarted = true;
1685 mPaused = false;
1686
1687 uint32_t flags = 0;
1688
Wei Jiaf01e3122018-10-18 11:49:44 -07001689 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001690 flags |= Renderer::FLAG_REAL_TIME;
1691 }
1692
Wei Jiaf01e3122018-10-18 11:49:44 -07001693 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1694 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001695 if (!hasAudio && !hasVideo) {
1696 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001697 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001698 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001699 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1700 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001701 return;
1702 }
1703 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1704
Wei Jiaf01e3122018-10-18 11:49:44 -07001705 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001706
1707 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1708 if (mAudioSink != NULL) {
1709 streamType = mAudioSink->getAudioStreamType();
1710 }
1711
1712 mOffloadAudio =
Dongwon Kang946bdb32018-11-14 10:12:00 -08001713 JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
1714 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001715 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1716
1717 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08001718 if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08001719 mOffloadAudio = false;
1720 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1721 }
1722
1723 if (mOffloadAudio) {
1724 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1725 }
1726
1727 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1728 ++mRendererGeneration;
1729 notify->setInt32("generation", mRendererGeneration);
1730 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1731 mRendererLooper = new ALooper;
Wei Jia8c8b57a2018-11-28 11:09:50 -08001732 mRendererLooper->setName("NuPlayer2Renderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001733 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001734 mRendererLooper->registerHandler(mRenderer);
1735
1736 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1737 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001738 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001739 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001740 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001741 return;
1742 }
1743
1744 float rate = getFrameRate();
1745 if (rate > 0) {
1746 mRenderer->setVideoFrameRate(rate);
1747 }
1748
Wei Jiad1864f92018-10-19 12:34:56 -07001749 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001750 // Renderer is created in paused state.
1751 if (play) {
1752 mRenderer->resume();
1753 }
1754
Wei Jia53692fa2017-12-11 10:33:46 -08001755 if (mVideoDecoder != NULL) {
1756 mVideoDecoder->setRenderer(mRenderer);
1757 }
1758 if (mAudioDecoder != NULL) {
1759 mAudioDecoder->setRenderer(mRenderer);
1760 }
1761
1762 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001763 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001764
1765 postScanSources();
1766}
1767
Wei Jiad1864f92018-10-19 12:34:56 -07001768void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001769 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001770
1771 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1772 return;
1773 }
1774
1775 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001776 msg->setInt32("generation", mEOSMonitorGeneration);
1777 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1778}
1779
Wei Jia53692fa2017-12-11 10:33:46 -08001780void NuPlayer2::startPlaybackTimer(const char *where) {
1781 Mutex::Autolock autoLock(mPlayingTimeLock);
1782 if (mLastStartedPlayingTimeNs == 0) {
1783 mLastStartedPlayingTimeNs = systemTime();
1784 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1785 }
1786}
1787
1788void NuPlayer2::stopPlaybackTimer(const char *where) {
1789 Mutex::Autolock autoLock(mPlayingTimeLock);
1790
1791 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1792
1793 if (mLastStartedPlayingTimeNs != 0) {
1794 sp<NuPlayer2Driver> driver = mDriver.promote();
1795 if (driver != NULL) {
1796 int64_t now = systemTime();
1797 int64_t played = now - mLastStartedPlayingTimeNs;
1798 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1799
1800 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001801 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001802 }
1803 }
1804 mLastStartedPlayingTimeNs = 0;
1805 }
1806}
1807
1808void NuPlayer2::startRebufferingTimer() {
1809 Mutex::Autolock autoLock(mPlayingTimeLock);
1810 if (mLastStartedRebufferingTimeNs == 0) {
1811 mLastStartedRebufferingTimeNs = systemTime();
1812 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1813 }
1814}
1815
1816void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1817 Mutex::Autolock autoLock(mPlayingTimeLock);
1818
Wei Jiaf01e3122018-10-18 11:49:44 -07001819 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1820 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001821
1822 if (mLastStartedRebufferingTimeNs != 0) {
1823 sp<NuPlayer2Driver> driver = mDriver.promote();
1824 if (driver != NULL) {
1825 int64_t now = systemTime();
1826 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1827 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1828
1829 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001830 driver->notifyMoreRebufferingTimeUs(
1831 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001832 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001833 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001834 }
1835 }
1836 }
1837 mLastStartedRebufferingTimeNs = 0;
1838 }
1839}
1840
1841void NuPlayer2::onPause() {
1842
1843 stopPlaybackTimer("onPause");
1844
1845 if (mPaused) {
1846 return;
1847 }
1848 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001849 if (mCurrentSourceInfo.mSource != NULL) {
1850 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001851 } else {
1852 ALOGW("pause called when source is gone or not set");
1853 }
1854 if (mRenderer != NULL) {
1855 mRenderer->pause();
1856 } else {
1857 ALOGW("pause called when renderer is gone or not set");
1858 }
1859
1860}
1861
1862bool NuPlayer2::audioDecoderStillNeeded() {
1863 // Audio decoder is no longer needed if it's in shut/shutting down status.
1864 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1865}
1866
1867void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1868 // We wait for both the decoder flush and the renderer flush to complete
1869 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1870
1871 mFlushComplete[audio][isDecoder] = true;
1872 if (!mFlushComplete[audio][!isDecoder]) {
1873 return;
1874 }
1875
1876 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1877 switch (*state) {
1878 case FLUSHING_DECODER:
1879 {
1880 *state = FLUSHED;
1881 break;
1882 }
1883
1884 case FLUSHING_DECODER_SHUTDOWN:
1885 {
1886 *state = SHUTTING_DOWN_DECODER;
1887
1888 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1889 getDecoder(audio)->initiateShutdown();
1890 break;
1891 }
1892
1893 default:
1894 // decoder flush completes only occur in a flushing state.
1895 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1896 break;
1897 }
1898}
1899
1900void NuPlayer2::finishFlushIfPossible() {
1901 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1902 && mFlushingAudio != SHUT_DOWN) {
1903 return;
1904 }
1905
1906 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1907 && mFlushingVideo != SHUT_DOWN) {
1908 return;
1909 }
1910
1911 ALOGV("both audio and video are flushed now.");
1912
1913 mFlushingAudio = NONE;
1914 mFlushingVideo = NONE;
1915
1916 clearFlushComplete();
1917
1918 processDeferredActions();
1919}
1920
1921void NuPlayer2::postScanSources() {
1922 if (mScanSourcesPending) {
1923 return;
1924 }
1925
1926 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1927 msg->setInt32("generation", mScanSourcesGeneration);
1928 msg->post();
1929
1930 mScanSourcesPending = true;
1931}
1932
1933void NuPlayer2::tryOpenAudioSinkForOffload(
1934 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1935 // Note: This is called early in NuPlayer2 to determine whether offloading
1936 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1937
1938 status_t err = mRenderer->openAudioSink(
1939 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001940 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001941 if (err != OK) {
1942 // Any failure we turn off mOffloadAudio.
1943 mOffloadAudio = false;
1944 } else if (mOffloadAudio) {
1945 sendMetaDataToHal(mAudioSink, audioMeta);
1946 }
1947}
1948
1949void NuPlayer2::closeAudioSink() {
1950 mRenderer->closeAudioSink();
1951}
1952
1953void NuPlayer2::restartAudio(
1954 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1955 if (mAudioDecoder != NULL) {
1956 mAudioDecoder->pause();
1957 mAudioDecoder.clear();
1958 mAudioDecoderError = false;
1959 ++mAudioDecoderGeneration;
1960 }
1961 if (mFlushingAudio == FLUSHING_DECODER) {
1962 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1963 mFlushingAudio = FLUSHED;
1964 finishFlushIfPossible();
1965 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1966 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1967 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1968 mFlushingAudio = SHUT_DOWN;
1969 finishFlushIfPossible();
1970 needsToCreateAudioDecoder = false;
1971 }
1972 if (mRenderer == NULL) {
1973 return;
1974 }
1975 closeAudioSink();
1976 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1977 if (mVideoDecoder != NULL) {
1978 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1979 }
1980
1981 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1982
1983 if (forceNonOffload) {
1984 mRenderer->signalDisableOffloadAudio();
1985 mOffloadAudio = false;
1986 }
1987 if (needsToCreateAudioDecoder) {
1988 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1989 }
1990}
1991
1992void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001993 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001994 return;
1995 }
1996
1997 if (mRenderer == NULL) {
1998 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1999 mOffloadAudio = false;
2000 return;
2001 }
2002
Wei Jiaf01e3122018-10-18 11:49:44 -07002003 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
2004 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002005 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
2006 const bool hasVideo = (videoFormat != NULL);
Dongwon Kangcd0e4272018-11-15 10:49:14 -08002007 bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
Wei Jiaf01e3122018-10-18 11:49:44 -07002008 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08002009 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2010
2011 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08002012 if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08002013 canOffload = false;
2014 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2015 }
2016
2017 if (canOffload) {
2018 if (!mOffloadAudio) {
2019 mRenderer->signalEnableOffloadAudio();
2020 }
2021 // open audio sink early under offload mode.
2022 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2023 } else {
2024 if (mOffloadAudio) {
2025 mRenderer->signalDisableOffloadAudio();
2026 mOffloadAudio = false;
2027 }
2028 }
2029}
2030
2031status_t NuPlayer2::instantiateDecoder(
2032 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2033 // The audio decoder could be cleared by tear down. If still in shut down
2034 // process, no need to create a new audio decoder.
2035 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2036 return OK;
2037 }
2038
Wei Jiaf01e3122018-10-18 11:49:44 -07002039 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002040
2041 if (format == NULL) {
2042 return UNKNOWN_ERROR;
2043 } else {
2044 status_t err;
2045 if (format->findInt32("err", &err) && err) {
2046 return err;
2047 }
2048 }
2049
2050 format->setInt32("priority", 0 /* realtime */);
2051
2052 if (!audio) {
2053 AString mime;
2054 CHECK(format->findString("mime", &mime));
2055
2056 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2057 if (mCCDecoder == NULL) {
2058 mCCDecoder = new CCDecoder(ccNotify);
2059 }
2060
Wei Jiaf01e3122018-10-18 11:49:44 -07002061 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002062 format->setInt32("secure", true);
2063 }
2064
Wei Jiaf01e3122018-10-18 11:49:44 -07002065 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002066 format->setInt32("protected", true);
2067 }
2068
2069 float rate = getFrameRate();
2070 if (rate > 0) {
2071 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2072 }
2073 }
2074
2075 if (audio) {
2076 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2077 ++mAudioDecoderGeneration;
2078 notify->setInt32("generation", mAudioDecoderGeneration);
2079
2080 if (checkAudioModeChange) {
2081 determineAudioModeChange(format);
2082 }
2083 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002084 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002085
Wei Jiaf01e3122018-10-18 11:49:44 -07002086 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002087 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002088 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002089 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2090 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002091 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002092
Wei Jiaf01e3122018-10-18 11:49:44 -07002093 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002094 ALOGV("instantiateDecoder audio Decoder");
2095 }
2096 mAudioDecoderError = false;
2097 } else {
2098 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2099 ++mVideoDecoderGeneration;
2100 notify->setInt32("generation", mVideoDecoderGeneration);
2101
2102 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002103 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2104 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002105 mVideoDecoderError = false;
2106
2107 // enable FRC if high-quality AV sync is requested, even if not
2108 // directly queuing to display, as this will even improve textureview
2109 // playback.
2110 {
2111 if (property_get_bool("persist.sys.media.avsync", false)) {
2112 format->setInt32("auto-frc", 1);
2113 }
2114 }
2115 }
2116 (*decoder)->init();
2117
2118 // Modular DRM
Robert Shihc3fca0e2018-12-04 17:08:04 -08002119 if (mCurrentSourceInfo.mIsDrmProtected) {
2120 format->setObject("crypto", mCurrentSourceInfo.mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002121 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
Robert Shihc3fca0e2018-12-04 17:08:04 -08002122 mCurrentSourceInfo.mCrypto.get(),
2123 (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002124 }
2125
2126 (*decoder)->configure(format);
2127
2128 if (!audio) {
2129 sp<AMessage> params = new AMessage();
2130 float rate = getFrameRate();
2131 if (rate > 0) {
2132 params->setFloat("frame-rate-total", rate);
2133 }
2134
2135 sp<MetaData> fileMeta = getFileMeta();
2136 if (fileMeta != NULL) {
2137 int32_t videoTemporalLayerCount;
2138 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2139 && videoTemporalLayerCount > 0) {
2140 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2141 }
2142 }
2143
2144 if (params->countEntries() > 0) {
2145 (*decoder)->setParameters(params);
2146 }
2147 }
2148 return OK;
2149}
2150
2151void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002152 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002153 const sp<AMessage> &inputFormat,
2154 const sp<AMessage> &outputFormat) {
2155 if (inputFormat == NULL) {
2156 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002157 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002158 return;
2159 }
2160 int32_t err = OK;
2161 inputFormat->findInt32("err", &err);
2162 if (err == -EWOULDBLOCK) {
2163 ALOGW("Video meta is not available yet!");
2164 return;
2165 }
2166 if (err != OK) {
2167 ALOGW("Something is wrong with video meta!");
2168 return;
2169 }
2170
2171 int32_t displayWidth, displayHeight;
2172 if (outputFormat != NULL) {
2173 int32_t width, height;
2174 CHECK(outputFormat->findInt32("width", &width));
2175 CHECK(outputFormat->findInt32("height", &height));
2176
2177 int32_t cropLeft, cropTop, cropRight, cropBottom;
2178 CHECK(outputFormat->findRect(
2179 "crop",
2180 &cropLeft, &cropTop, &cropRight, &cropBottom));
2181
2182 displayWidth = cropRight - cropLeft + 1;
2183 displayHeight = cropBottom - cropTop + 1;
2184
2185 ALOGV("Video output format changed to %d x %d "
2186 "(crop: %d x %d @ (%d, %d))",
2187 width, height,
2188 displayWidth,
2189 displayHeight,
2190 cropLeft, cropTop);
2191 } else {
2192 CHECK(inputFormat->findInt32("width", &displayWidth));
2193 CHECK(inputFormat->findInt32("height", &displayHeight));
2194
2195 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2196 }
2197
2198 // Take into account sample aspect ratio if necessary:
2199 int32_t sarWidth, sarHeight;
2200 if (inputFormat->findInt32("sar-width", &sarWidth)
2201 && inputFormat->findInt32("sar-height", &sarHeight)
2202 && sarWidth > 0 && sarHeight > 0) {
2203 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2204
2205 displayWidth = (displayWidth * sarWidth) / sarHeight;
2206
2207 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2208 } else {
2209 int32_t width, height;
2210 if (inputFormat->findInt32("display-width", &width)
2211 && inputFormat->findInt32("display-height", &height)
2212 && width > 0 && height > 0
2213 && displayWidth > 0 && displayHeight > 0) {
2214 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2215 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2216 } else {
2217 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2218 }
2219 ALOGV("Video display width and height are overridden to %d x %d",
2220 displayWidth, displayHeight);
2221 }
2222 }
2223
2224 int32_t rotationDegrees;
2225 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2226 rotationDegrees = 0;
2227 }
2228
2229 if (rotationDegrees == 90 || rotationDegrees == 270) {
2230 int32_t tmp = displayWidth;
2231 displayWidth = displayHeight;
2232 displayHeight = tmp;
2233 }
2234
2235 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002236 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002237 MEDIA2_SET_VIDEO_SIZE,
2238 displayWidth,
2239 displayHeight);
2240}
2241
Dongwon Kang41929fb2018-09-09 08:29:56 -07002242void NuPlayer2::notifyListener(
2243 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002244 if (mDriver == NULL) {
2245 return;
2246 }
2247
2248 sp<NuPlayer2Driver> driver = mDriver.promote();
2249
2250 if (driver == NULL) {
2251 return;
2252 }
2253
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002254 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002255}
2256
2257void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2258 ALOGV("[%s] flushDecoder needShutdown=%d",
2259 audio ? "audio" : "video", needShutdown);
2260
2261 const sp<DecoderBase> &decoder = getDecoder(audio);
2262 if (decoder == NULL) {
2263 ALOGI("flushDecoder %s without decoder present",
2264 audio ? "audio" : "video");
2265 return;
2266 }
2267
2268 // Make sure we don't continue to scan sources until we finish flushing.
2269 ++mScanSourcesGeneration;
2270 if (mScanSourcesPending) {
2271 if (!needShutdown) {
2272 mDeferredActions.push_back(
2273 new SimpleAction(&NuPlayer2::performScanSources));
2274 }
2275 mScanSourcesPending = false;
2276 }
2277
2278 decoder->signalFlush();
2279
2280 FlushStatus newStatus =
2281 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2282
2283 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2284 mFlushComplete[audio][true /* isDecoder */] = false;
2285 if (audio) {
2286 ALOGE_IF(mFlushingAudio != NONE,
2287 "audio flushDecoder() is called in state %d", mFlushingAudio);
2288 mFlushingAudio = newStatus;
2289 } else {
2290 ALOGE_IF(mFlushingVideo != NONE,
2291 "video flushDecoder() is called in state %d", mFlushingVideo);
2292 mFlushingVideo = newStatus;
2293 }
2294}
2295
2296void NuPlayer2::queueDecoderShutdown(
2297 bool audio, bool video, const sp<AMessage> &reply) {
2298 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2299
2300 mDeferredActions.push_back(
2301 new FlushDecoderAction(
2302 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2303 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2304
2305 mDeferredActions.push_back(
2306 new SimpleAction(&NuPlayer2::performScanSources));
2307
2308 mDeferredActions.push_back(new PostMessageAction(reply));
2309
2310 processDeferredActions();
2311}
2312
2313status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2314 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002315 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2316 status_t ret = native_window_set_scaling_mode(
2317 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002318 if (ret != OK) {
2319 ALOGE("Failed to set scaling mode (%d): %s",
2320 -ret, strerror(-ret));
2321 return ret;
2322 }
2323 }
2324 return OK;
2325}
2326
Dongwon Kang9f631982018-07-10 12:34:41 -07002327status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002328 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2329 msg->setPointer("reply", reply);
2330
2331 sp<AMessage> response;
2332 status_t err = msg->postAndAwaitResponse(&response);
2333 return err;
2334}
2335
Dongwon Kang9f631982018-07-10 12:34:41 -07002336status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002337 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2338 msg->setPointer("reply", reply);
2339 msg->setInt32("type", type);
2340
2341 sp<AMessage> response;
2342 status_t err = msg->postAndAwaitResponse(&response);
2343 if (err == OK && response != NULL) {
2344 CHECK(response->findInt32("err", &err));
2345 }
2346 return err;
2347}
2348
2349status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2350 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2351 msg->setSize("trackIndex", trackIndex);
2352 msg->setInt32("select", select);
2353 msg->setInt64("timeUs", timeUs);
2354
2355 sp<AMessage> response;
2356 status_t err = msg->postAndAwaitResponse(&response);
2357
2358 if (err != OK) {
2359 return err;
2360 }
2361
2362 if (!response->findInt32("err", &err)) {
2363 err = OK;
2364 }
2365
2366 return err;
2367}
2368
2369status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2370 sp<Renderer> renderer = mRenderer;
2371 if (renderer == NULL) {
2372 return NO_INIT;
2373 }
2374
2375 return renderer->getCurrentPosition(mediaUs);
2376}
2377
2378void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2379 CHECK(mTrackStats != NULL);
2380
2381 mTrackStats->clear();
2382 if (mVideoDecoder != NULL) {
2383 mTrackStats->push_back(mVideoDecoder->getStats());
2384 }
2385 if (mAudioDecoder != NULL) {
2386 mTrackStats->push_back(mAudioDecoder->getStats());
2387 }
2388}
2389
2390sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002391 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002392}
2393
2394float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002395 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002396 if (meta == NULL) {
2397 return 0;
2398 }
2399 int32_t rate;
2400 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2401 // fall back to try file meta
2402 sp<MetaData> fileMeta = getFileMeta();
2403 if (fileMeta == NULL) {
2404 ALOGW("source has video meta but not file meta");
2405 return -1;
2406 }
2407 int32_t fileMetaRate;
2408 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2409 return -1;
2410 }
2411 return fileMetaRate;
2412 }
2413 return rate;
2414}
2415
2416void NuPlayer2::schedulePollDuration() {
2417 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2418 msg->setInt32("generation", mPollDurationGeneration);
2419 msg->post();
2420}
2421
2422void NuPlayer2::cancelPollDuration() {
2423 ++mPollDurationGeneration;
2424}
2425
2426void NuPlayer2::processDeferredActions() {
2427 while (!mDeferredActions.empty()) {
2428 // We won't execute any deferred actions until we're no longer in
2429 // an intermediate state, i.e. one more more decoders are currently
2430 // flushing or shutting down.
2431
2432 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2433 // We're currently flushing, postpone the reset until that's
2434 // completed.
2435
2436 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2437 mFlushingAudio, mFlushingVideo);
2438
2439 break;
2440 }
2441
2442 sp<Action> action = *mDeferredActions.begin();
2443 mDeferredActions.erase(mDeferredActions.begin());
2444
2445 action->execute(this);
2446 }
2447}
2448
2449void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2450 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2451 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2452
Wei Jiaf01e3122018-10-18 11:49:44 -07002453 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002454 // This happens when reset occurs right before the loop mode
2455 // asynchronously seeks to the start of the stream.
2456 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002457 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002458 mAudioDecoder.get(), mVideoDecoder.get());
2459 return;
2460 }
2461 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002462 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002463 ++mTimedTextGeneration;
2464
2465 // everything's flushed, continue playback.
2466}
2467
2468void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2469 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2470
2471 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2472 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2473 return;
2474 }
2475
2476 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2477 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2478 }
2479
2480 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2481 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2482 }
2483}
2484
2485void NuPlayer2::performReset() {
2486 ALOGV("performReset");
2487
2488 CHECK(mAudioDecoder == NULL);
2489 CHECK(mVideoDecoder == NULL);
2490
2491 stopPlaybackTimer("performReset");
2492 stopRebufferingTimer(true);
2493
2494 cancelPollDuration();
2495
2496 ++mScanSourcesGeneration;
2497 mScanSourcesPending = false;
2498
2499 if (mRendererLooper != NULL) {
2500 if (mRenderer != NULL) {
2501 mRendererLooper->unregisterHandler(mRenderer->id());
2502 }
2503 mRendererLooper->stop();
2504 mRendererLooper.clear();
2505 }
2506 mRenderer.clear();
2507 ++mRendererGeneration;
2508
Robert Shihc3fca0e2018-12-04 17:08:04 -08002509 resetSourceInfo(mCurrentSourceInfo);
2510 resetSourceInfo(mNextSourceInfo);
Wei Jia53692fa2017-12-11 10:33:46 -08002511
2512 if (mDriver != NULL) {
2513 sp<NuPlayer2Driver> driver = mDriver.promote();
2514 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002515 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002516 }
2517 }
2518
2519 mStarted = false;
2520 mPrepared = false;
2521 mResetting = false;
2522 mSourceStarted = false;
2523
Wei Jia53692fa2017-12-11 10:33:46 -08002524}
2525
Wei Jia57aeffd2018-02-15 16:01:14 -08002526void NuPlayer2::performPlayNextDataSource() {
2527 ALOGV("performPlayNextDataSource");
2528
2529 CHECK(mAudioDecoder == NULL);
2530 CHECK(mVideoDecoder == NULL);
2531
2532 stopPlaybackTimer("performPlayNextDataSource");
2533 stopRebufferingTimer(true);
2534
2535 cancelPollDuration();
2536
2537 ++mScanSourcesGeneration;
2538 mScanSourcesPending = false;
2539
2540 ++mRendererGeneration;
2541
Wei Jiaf01e3122018-10-18 11:49:44 -07002542 if (mCurrentSourceInfo.mSource != NULL) {
2543 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002544 }
2545
2546 long previousSrcId;
2547 {
2548 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002549 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002550
2551 mCurrentSourceInfo = mNextSourceInfo;
2552 mNextSourceInfo = SourceInfo();
2553 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002554 }
2555
2556 if (mDriver != NULL) {
2557 sp<NuPlayer2Driver> driver = mDriver.promote();
2558 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002559 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002560
2561 int64_t durationUs;
2562 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2563 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2564 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002565 notifyListener(
2566 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002567 }
2568 }
2569
2570 mStarted = false;
2571 mPrepared = true; // TODO: what if it's not prepared
2572 mResetting = false;
2573 mSourceStarted = false;
2574
Wei Jiad1864f92018-10-19 12:34:56 -07002575 addEndTimeMonitor();
2576
Wei Jia57aeffd2018-02-15 16:01:14 -08002577 if (mRenderer != NULL) {
2578 mRenderer->resume();
2579 }
2580
Wei Jia6376cd52018-09-26 11:42:55 -07002581 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002582 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002583 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002584}
2585
Wei Jia53692fa2017-12-11 10:33:46 -08002586void NuPlayer2::performScanSources() {
2587 ALOGV("performScanSources");
2588
2589 if (!mStarted) {
2590 return;
2591 }
2592
2593 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2594 postScanSources();
2595 }
2596}
2597
Wei Jia28288fb2017-12-15 13:45:29 -08002598void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002599 ALOGV("performSetSurface");
2600
Wei Jia28288fb2017-12-15 13:45:29 -08002601 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002602
2603 // XXX - ignore error from setVideoScalingMode for now
2604 setVideoScalingMode(mVideoScalingMode);
2605
2606 if (mDriver != NULL) {
2607 sp<NuPlayer2Driver> driver = mDriver.promote();
2608 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002609 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002610 }
2611 }
2612}
2613
2614void NuPlayer2::performResumeDecoders(bool needNotify) {
2615 if (needNotify) {
2616 mResumePending = true;
2617 if (mVideoDecoder == NULL) {
2618 // if audio-only, we can notify seek complete now,
2619 // as the resume operation will be relatively fast.
2620 finishResume();
2621 }
2622 }
2623
2624 if (mVideoDecoder != NULL) {
2625 // When there is continuous seek, MediaPlayer will cache the seek
2626 // position, and send down new seek request when previous seek is
2627 // complete. Let's wait for at least one video output frame before
2628 // notifying seek complete, so that the video thumbnail gets updated
2629 // when seekbar is dragged.
2630 mVideoDecoder->signalResume(needNotify);
2631 }
2632
2633 if (mAudioDecoder != NULL) {
2634 mAudioDecoder->signalResume(false /* needNotify */);
2635 }
2636}
2637
2638void NuPlayer2::finishResume() {
2639 if (mResumePending) {
2640 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002641 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002642 }
2643}
2644
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002645void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002646 if (mDriver != NULL) {
2647 sp<NuPlayer2Driver> driver = mDriver.promote();
2648 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002649 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002650 }
2651 }
2652}
2653
2654void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2655 int32_t what;
2656 CHECK(msg->findInt32("what", &what));
2657
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002658 int64_t srcId;
2659 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002660 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002661 case Source::kWhatPrepared:
2662 {
Wei Jiad1864f92018-10-19 12:34:56 -07002663 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2664 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2665 if (srcId == mCurrentSourceInfo.mSrcId) {
2666 if (mCurrentSourceInfo.mSource == NULL) {
2667 // This is a stale notification from a source that was
2668 // asynchronously preparing when the client called reset().
2669 // We handled the reset, the source is gone.
2670 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002671 }
Wei Jiad1864f92018-10-19 12:34:56 -07002672
2673 int32_t err;
2674 CHECK(msg->findInt32("err", &err));
2675
2676 if (err != OK) {
2677 // shut down potential secure codecs in case client never calls reset
2678 mDeferredActions.push_back(
2679 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2680 FLUSH_CMD_SHUTDOWN /* video */));
2681 processDeferredActions();
2682 } else {
2683 mPrepared = true;
2684 }
2685
2686 sp<NuPlayer2Driver> driver = mDriver.promote();
2687 if (driver != NULL) {
2688 // notify duration first, so that it's definitely set when
2689 // the app received the "prepare complete" callback.
2690 int64_t durationUs;
2691 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2692 driver->notifyDuration(srcId, durationUs);
2693 }
2694 driver->notifyPrepareCompleted(srcId, err);
2695 }
2696 } else if (srcId == mNextSourceInfo.mSrcId) {
2697 if (mNextSourceInfo.mSource == NULL) {
2698 break; // stale
2699 }
2700
2701 sp<NuPlayer2Driver> driver = mDriver.promote();
2702 if (driver != NULL) {
2703 int32_t err;
2704 CHECK(msg->findInt32("err", &err));
2705 driver->notifyPrepareCompleted(srcId, err);
2706 }
Wei Jia53692fa2017-12-11 10:33:46 -08002707 }
2708
2709 break;
2710 }
2711
2712 // Modular DRM
2713 case Source::kWhatDrmInfo:
2714 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002715 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002716 sp<ABuffer> drmInfo;
2717 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002718 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002719
Dongwon Kang41929fb2018-09-09 08:29:56 -07002720 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2721 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002722
Dongwon Kang41929fb2018-09-09 08:29:56 -07002723 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002724
2725 break;
2726 }
2727
2728 case Source::kWhatFlagsChanged:
2729 {
2730 uint32_t flags;
2731 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2732
2733 sp<NuPlayer2Driver> driver = mDriver.promote();
2734 if (driver != NULL) {
2735
2736 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2737 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2738 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2739 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2740 (flags & Source::FLAG_CAN_PAUSE) != 0,
2741 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2742 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2743 (flags & Source::FLAG_CAN_SEEK) != 0,
2744 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2745 (flags & Source::FLAG_SECURE) != 0,
2746 (flags & Source::FLAG_PROTECTED) != 0);
2747
2748 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2749 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002750 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002751 }
Wei Jiad1864f92018-10-19 12:34:56 -07002752 if (srcId == mCurrentSourceInfo.mSrcId) {
2753 driver->notifyFlagsChanged(srcId, flags);
2754 }
Wei Jia53692fa2017-12-11 10:33:46 -08002755 }
2756
Wei Jiaf01e3122018-10-18 11:49:44 -07002757 if (srcId == mCurrentSourceInfo.mSrcId) {
2758 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2759 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2760 cancelPollDuration();
2761 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2762 && (flags & Source::FLAG_DYNAMIC_DURATION)
2763 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2764 schedulePollDuration();
2765 }
Wei Jia53692fa2017-12-11 10:33:46 -08002766
Wei Jiaf01e3122018-10-18 11:49:44 -07002767 mCurrentSourceInfo.mSourceFlags = flags;
2768 } else if (srcId == mNextSourceInfo.mSrcId) {
2769 // TODO: handle duration polling for next source.
2770 mNextSourceInfo.mSourceFlags = flags;
2771 }
Wei Jia53692fa2017-12-11 10:33:46 -08002772 break;
2773 }
2774
2775 case Source::kWhatVideoSizeChanged:
2776 {
2777 sp<AMessage> format;
2778 CHECK(msg->findMessage("format", &format));
2779
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002780 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002781 break;
2782 }
2783
2784 case Source::kWhatBufferingUpdate:
2785 {
2786 int32_t percentage;
2787 CHECK(msg->findInt32("percentage", &percentage));
2788
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002789 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002790 break;
2791 }
2792
2793 case Source::kWhatPauseOnBufferingStart:
2794 {
2795 // ignore if not playing
2796 if (mStarted) {
2797 ALOGI("buffer low, pausing...");
2798
2799 startRebufferingTimer();
2800 mPausedForBuffering = true;
2801 onPause();
2802 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002803 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002804 break;
2805 }
2806
2807 case Source::kWhatResumeOnBufferingEnd:
2808 {
2809 // ignore if not playing
2810 if (mStarted) {
2811 ALOGI("buffer ready, resuming...");
2812
2813 stopRebufferingTimer(false);
2814 mPausedForBuffering = false;
2815
2816 // do not resume yet if client didn't unpause
2817 if (!mPausedByClient) {
2818 onResume();
2819 }
2820 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002821 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002822 break;
2823 }
2824
2825 case Source::kWhatCacheStats:
2826 {
2827 int32_t kbps;
2828 CHECK(msg->findInt32("bandwidth", &kbps));
2829
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002830 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002831 break;
2832 }
2833
2834 case Source::kWhatSubtitleData:
2835 {
2836 sp<ABuffer> buffer;
2837 CHECK(msg->findBuffer("buffer", &buffer));
2838
2839 sendSubtitleData(buffer, 0 /* baseIndex */);
2840 break;
2841 }
2842
2843 case Source::kWhatTimedMetaData:
2844 {
2845 sp<ABuffer> buffer;
2846 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002847 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002848 } else {
2849 sendTimedMetaData(buffer);
2850 }
2851 break;
2852 }
2853
2854 case Source::kWhatTimedTextData:
2855 {
2856 int32_t generation;
2857 if (msg->findInt32("generation", &generation)
2858 && generation != mTimedTextGeneration) {
2859 break;
2860 }
2861
2862 sp<ABuffer> buffer;
2863 CHECK(msg->findBuffer("buffer", &buffer));
2864
2865 sp<NuPlayer2Driver> driver = mDriver.promote();
2866 if (driver == NULL) {
2867 break;
2868 }
2869
Wei Jia800fe372018-02-20 15:00:45 -08002870 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002871 int64_t timeUs, posUs;
2872 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002873 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002874 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2875
2876 if (posUs < timeUs) {
2877 if (!msg->findInt32("generation", &generation)) {
2878 msg->setInt32("generation", mTimedTextGeneration);
2879 }
2880 msg->post(timeUs - posUs);
2881 } else {
2882 sendTimedTextData(buffer);
2883 }
2884 break;
2885 }
2886
2887 case Source::kWhatQueueDecoderShutdown:
2888 {
2889 int32_t audio, video;
2890 CHECK(msg->findInt32("audio", &audio));
2891 CHECK(msg->findInt32("video", &video));
2892
2893 sp<AMessage> reply;
2894 CHECK(msg->findMessage("reply", &reply));
2895
2896 queueDecoderShutdown(audio, video, reply);
2897 break;
2898 }
2899
2900 case Source::kWhatDrmNoLicense:
2901 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002902 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002903 break;
2904 }
2905
2906 default:
2907 TRESPASS();
2908 }
2909}
2910
2911void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2912 int32_t what;
2913 CHECK(msg->findInt32("what", &what));
2914
2915 switch (what) {
2916 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2917 {
2918 sp<ABuffer> buffer;
2919 CHECK(msg->findBuffer("buffer", &buffer));
2920
2921 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002922 if (mCurrentSourceInfo.mSource != NULL) {
2923 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002924 }
2925
2926 sendSubtitleData(buffer, inbandTracks);
2927 break;
2928 }
2929
2930 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2931 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002932 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002933
2934 break;
2935 }
2936
2937 default:
2938 TRESPASS();
2939 }
2940
2941
2942}
2943
2944void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2945 int32_t trackIndex;
2946 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002947 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002948 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2949 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2950
Dongwon Kang41929fb2018-09-09 08:29:56 -07002951 PlayerMessage playerMsg;
2952 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2953 playerMsg.add_values()->set_int64_value(timeUs);
2954 playerMsg.add_values()->set_int64_value(durationUs);
2955 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002956
Wei Jiaf01e3122018-10-18 11:49:44 -07002957 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002958}
2959
2960void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2961 int64_t timeUs;
2962 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2963
Dongwon Kang41929fb2018-09-09 08:29:56 -07002964 PlayerMessage playerMsg;
2965 playerMsg.add_values()->set_int64_value(timeUs);
2966 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002967
Wei Jiaf01e3122018-10-18 11:49:44 -07002968 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002969}
2970
2971void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2972 const void *data;
2973 size_t size = 0;
2974 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002975 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002976
2977 AString mime;
2978 CHECK(buffer->meta()->findString("mime", &mime));
2979 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2980
2981 data = buffer->data();
2982 size = buffer->size();
2983
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002984 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002985 if (size > 0) {
2986 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2987 int32_t global = 0;
2988 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002989 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002990 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002991 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002992 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002993 TextDescriptions2::getPlayerMessageOfDescriptions(
2994 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002995 }
2996
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002997 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002998 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002999 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003000 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003001 }
3002}
3003
3004const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003005 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003006 case DATA_SOURCE_TYPE_HTTP_LIVE:
3007 return "HTTPLive";
3008
3009 case DATA_SOURCE_TYPE_RTSP:
3010 return "RTSP";
3011
3012 case DATA_SOURCE_TYPE_GENERIC_URL:
3013 return "GenURL";
3014
3015 case DATA_SOURCE_TYPE_GENERIC_FD:
3016 return "GenFD";
3017
3018 case DATA_SOURCE_TYPE_MEDIA:
3019 return "Media";
3020
Wei Jia53692fa2017-12-11 10:33:46 -08003021 case DATA_SOURCE_TYPE_NONE:
3022 default:
3023 return "None";
3024 }
3025 }
3026
Robert Shihc3fca0e2018-12-04 17:08:04 -08003027NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
3028 int64_t srcId;
3029 CHECK(msg->findInt64("srcId", &srcId));
3030 if (mCurrentSourceInfo.mSrcId == srcId) {
3031 return &mCurrentSourceInfo;
3032 } else if (mNextSourceInfo.mSrcId == srcId) {
3033 return &mNextSourceInfo;
3034 } else {
3035 return NULL;
3036 }
3037}
3038
3039void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
3040 if (srcInfo.mSource != NULL) {
3041 srcInfo.mSource->stop();
3042
3043 Mutex::Autolock autoLock(mSourceLock);
3044 srcInfo.mSource.clear();
3045 }
3046 // Modular DRM
3047 ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
3048 srcInfo.mCrypto.clear();
3049 srcInfo.mIsDrmProtected = false;
3050}
3051
Wei Jia53692fa2017-12-11 10:33:46 -08003052// Modular DRM begin
Robert Shih3c3728d2018-12-04 17:06:36 -08003053status_t NuPlayer2::prepareDrm(
3054 int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
Wei Jia53692fa2017-12-11 10:33:46 -08003055{
3056 ALOGV("prepareDrm ");
3057
3058 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3059 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3060 // synchronous call so just passing the address but with local copies of "const" args
3061 uint8_t UUID[16];
3062 memcpy(UUID, uuid, sizeof(UUID));
3063 Vector<uint8_t> sessionId = drmSessionId;
Robert Shih3c3728d2018-12-04 17:06:36 -08003064 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003065 msg->setPointer("uuid", (void*)UUID);
3066 msg->setPointer("drmSessionId", (void*)&sessionId);
3067
3068 sp<AMessage> response;
3069 status_t status = msg->postAndAwaitResponse(&response);
3070
3071 if (status == OK && response != NULL) {
3072 CHECK(response->findInt32("status", &status));
3073 ALOGV("prepareDrm ret: %d ", status);
3074 } else {
3075 ALOGE("prepareDrm err: %d", status);
3076 }
3077
3078 return status;
3079}
3080
Robert Shih3c3728d2018-12-04 17:06:36 -08003081status_t NuPlayer2::releaseDrm(int64_t srcId)
Wei Jia53692fa2017-12-11 10:33:46 -08003082{
3083 ALOGV("releaseDrm ");
3084
3085 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
Robert Shih3c3728d2018-12-04 17:06:36 -08003086 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003087
3088 sp<AMessage> response;
3089 status_t status = msg->postAndAwaitResponse(&response);
3090
3091 if (status == OK && response != NULL) {
3092 CHECK(response->findInt32("status", &status));
3093 ALOGV("releaseDrm ret: %d ", status);
3094 } else {
3095 ALOGE("releaseDrm err: %d", status);
3096 }
3097
3098 return status;
3099}
3100
3101status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3102{
3103 // TODO change to ALOGV
3104 ALOGD("onPrepareDrm ");
3105
3106 status_t status = INVALID_OPERATION;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003107 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
3108 if (srcInfo == NULL) {
3109 return status;
3110 }
3111
3112 int64_t srcId = srcInfo->mSrcId;
3113 if (srcInfo->mSource == NULL) {
3114 ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
3115 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003116 return status;
3117 }
3118
3119 uint8_t *uuid;
3120 Vector<uint8_t> *drmSessionId;
3121 CHECK(msg->findPointer("uuid", (void**)&uuid));
3122 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3123
3124 status = OK;
3125 sp<AMediaCryptoWrapper> crypto = NULL;
3126
Robert Shihc3fca0e2018-12-04 17:08:04 -08003127 status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003128 if (crypto == NULL) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08003129 ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
3130 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003131 return status;
3132 }
Robert Shihc3fca0e2018-12-04 17:08:04 -08003133 ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003134
Robert Shihc3fca0e2018-12-04 17:08:04 -08003135 if (srcInfo->mCrypto != NULL) {
3136 ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
3137 (long long)srcId, srcInfo->mCrypto.get());
3138 srcInfo->mCrypto.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08003139 }
3140
Robert Shihc3fca0e2018-12-04 17:08:04 -08003141 srcInfo->mCrypto = crypto;
3142 srcInfo->mIsDrmProtected = true;
Wei Jia53692fa2017-12-11 10:33:46 -08003143 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003144 ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08003145
3146 return status;
3147}
3148
Robert Shihc3fca0e2018-12-04 17:08:04 -08003149status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
Wei Jia53692fa2017-12-11 10:33:46 -08003150{
3151 // TODO change to ALOGV
3152 ALOGD("onReleaseDrm ");
Robert Shihc3fca0e2018-12-04 17:08:04 -08003153 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
3154 if (srcInfo == NULL) {
3155 return INVALID_OPERATION;
Wei Jia53692fa2017-12-11 10:33:46 -08003156 }
3157
Robert Shihc3fca0e2018-12-04 17:08:04 -08003158 int64_t srcId = srcInfo->mSrcId;
3159 if (!srcInfo->mIsDrmProtected) {
3160 ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
3161 (long long)srcId);
3162 }
3163
3164 srcInfo->mIsDrmProtected = false;
Wei Jia53692fa2017-12-11 10:33:46 -08003165
3166 status_t status;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003167 if (srcInfo->mCrypto != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003168 // notifying the source first before removing crypto from codec
Robert Shihc3fca0e2018-12-04 17:08:04 -08003169 if (srcInfo->mSource != NULL) {
3170 srcInfo->mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003171 }
3172
3173 status=OK;
3174 // first making sure the codecs have released their crypto reference
3175 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3176 if (videoDecoder != NULL) {
3177 status = videoDecoder->releaseCrypto();
3178 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3179 }
3180
3181 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3182 if (audioDecoder != NULL) {
3183 status_t status_audio = audioDecoder->releaseCrypto();
3184 if (status == OK) { // otherwise, returning the first error
3185 status = status_audio;
3186 }
3187 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3188 }
3189
3190 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003191 ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
3192 srcInfo->mCrypto.clear();
3193 } else { // srcInfo->mCrypto == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08003194 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3195 status = INVALID_OPERATION;
3196 }
3197
3198 return status;
3199}
3200// Modular DRM end
3201////////////////////////////////////////////////////////////////////////////////
3202
3203sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3204 sp<MetaData> meta = getFormatMeta(audio);
3205
3206 if (meta == NULL) {
3207 return NULL;
3208 }
3209
3210 sp<AMessage> msg = new AMessage;
3211
3212 if(convertMetaDataToMessage(meta, &msg) == OK) {
3213 return msg;
3214 }
3215 return NULL;
3216}
3217
3218void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3219 sp<AMessage> notify = dupNotify();
3220 notify->setInt32("what", kWhatFlagsChanged);
3221 notify->setInt32("flags", flags);
3222 notify->post();
3223}
3224
3225void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3226 sp<AMessage> notify = dupNotify();
3227 notify->setInt32("what", kWhatVideoSizeChanged);
3228 notify->setMessage("format", format);
3229 notify->post();
3230}
3231
3232void NuPlayer2::Source::notifyPrepared(status_t err) {
3233 ALOGV("Source::notifyPrepared %d", err);
3234 sp<AMessage> notify = dupNotify();
3235 notify->setInt32("what", kWhatPrepared);
3236 notify->setInt32("err", err);
3237 notify->post();
3238}
3239
3240void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3241{
3242 ALOGV("Source::notifyDrmInfo");
3243
3244 sp<AMessage> notify = dupNotify();
3245 notify->setInt32("what", kWhatDrmInfo);
3246 notify->setBuffer("drmInfo", drmInfoBuffer);
3247
3248 notify->post();
3249}
3250
Wei Jia53692fa2017-12-11 10:33:46 -08003251void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3252 TRESPASS();
3253}
3254
Wei Jiaf01e3122018-10-18 11:49:44 -07003255NuPlayer2::SourceInfo::SourceInfo()
3256 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3257 mSrcId(0),
3258 mSourceFlags(0),
3259 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003260 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003261}
3262
Wei Jiad1864f92018-10-19 12:34:56 -07003263NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3264 mSource = other.mSource;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003265 mCrypto = other.mCrypto;
Wei Jiad1864f92018-10-19 12:34:56 -07003266 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3267 mSrcId = other.mSrcId;
3268 mSourceFlags = other.mSourceFlags;
3269 mStartTimeUs = other.mStartTimeUs;
3270 mEndTimeUs = other.mEndTimeUs;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003271 mIsDrmProtected = other.mIsDrmProtected;
Wei Jiad1864f92018-10-19 12:34:56 -07003272 return *this;
3273}
3274
Wei Jia53692fa2017-12-11 10:33:46 -08003275} // namespace android