blob: 080d923b9433e6abfadae1b6ed7e309d38462447 [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
Wei Jia17944af2018-12-13 18:13:10 -0800794 int64_t srcId;
795 CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
796
Dongwon Kang9f631982018-07-10 12:34:41 -0700797 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800798 CHECK(msg->findPointer("reply", (void**)&reply));
799
Wei Jia17944af2018-12-13 18:13:10 -0800800 // TODO: use correct source info based on srcId.
Wei Jia53692fa2017-12-11 10:33:46 -0800801 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700802 if (mCurrentSourceInfo.mSource != NULL) {
803 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800804 }
805
806 size_t ccTracks = 0;
807 if (mCCDecoder != NULL) {
808 ccTracks = mCCDecoder->getTrackCount();
809 }
810
811 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700812 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800813
814 // write inband tracks
815 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700816 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800817 }
818
819 // write CC track
820 for (size_t i = 0; i < ccTracks; ++i) {
821 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
822 }
823
824 sp<AMessage> response = new AMessage;
825 response->postReply(replyID);
826 break;
827 }
828
829 case kWhatGetSelectedTrack:
830 {
Wei Jia17944af2018-12-13 18:13:10 -0800831 int64_t srcId;
832 CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
833
Wei Jia039224f2018-11-29 17:25:17 -0800834 int32_t type32;
835 CHECK(msg->findInt32("type", (int32_t*)&type32));
836 media_track_type type = (media_track_type)type32;
837
Wei Jia17944af2018-12-13 18:13:10 -0800838 // TODO: use correct source info based on srcId.
Wei Jia039224f2018-11-29 17:25:17 -0800839 size_t inbandTracks = 0;
Wei Jia53692fa2017-12-11 10:33:46 -0800840 status_t err = INVALID_OPERATION;
Wei Jia039224f2018-11-29 17:25:17 -0800841 ssize_t selectedTrack = -1;
Wei Jiaf01e3122018-10-18 11:49:44 -0700842 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800843 err = OK;
Wei Jia039224f2018-11-29 17:25:17 -0800844 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
845 selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800846 }
847
Wei Jia039224f2018-11-29 17:25:17 -0800848 if (selectedTrack == -1 && mCCDecoder != NULL) {
849 err = OK;
850 selectedTrack = mCCDecoder->getSelectedTrack(type);
851 if (selectedTrack != -1) {
852 selectedTrack += inbandTracks;
853 }
854 }
855
856 PlayerMessage* reply;
857 CHECK(msg->findPointer("reply", (void**)&reply));
858 reply->add_values()->set_int32_value(selectedTrack);
859
Wei Jia53692fa2017-12-11 10:33:46 -0800860 sp<AMessage> response = new AMessage;
861 response->setInt32("err", err);
862
863 sp<AReplyToken> replyID;
864 CHECK(msg->senderAwaitsResponse(&replyID));
865 response->postReply(replyID);
866 break;
867 }
868
869 case kWhatSelectTrack:
870 {
871 sp<AReplyToken> replyID;
872 CHECK(msg->senderAwaitsResponse(&replyID));
873
Wei Jia17944af2018-12-13 18:13:10 -0800874 int64_t srcId;
Wei Jia53692fa2017-12-11 10:33:46 -0800875 size_t trackIndex;
876 int32_t select;
877 int64_t timeUs;
Wei Jia17944af2018-12-13 18:13:10 -0800878 CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
Wei Jia53692fa2017-12-11 10:33:46 -0800879 CHECK(msg->findSize("trackIndex", &trackIndex));
880 CHECK(msg->findInt32("select", &select));
881 CHECK(msg->findInt64("timeUs", &timeUs));
882
883 status_t err = INVALID_OPERATION;
884
Wei Jia17944af2018-12-13 18:13:10 -0800885 // TODO: use correct source info based on srcId.
Wei Jia53692fa2017-12-11 10:33:46 -0800886 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700887 if (mCurrentSourceInfo.mSource != NULL) {
888 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800889 }
890 size_t ccTracks = 0;
891 if (mCCDecoder != NULL) {
892 ccTracks = mCCDecoder->getTrackCount();
893 }
894
895 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700896 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800897
898 if (!select && err == OK) {
899 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700900 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800901 if (info != NULL
902 && info->findInt32("type", &type)
903 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
904 ++mTimedTextGeneration;
905 }
906 }
907 } else {
908 trackIndex -= inbandTracks;
909
910 if (trackIndex < ccTracks) {
911 err = mCCDecoder->selectTrack(trackIndex, select);
912 }
913 }
914
915 sp<AMessage> response = new AMessage;
916 response->setInt32("err", err);
917
918 response->postReply(replyID);
919 break;
920 }
921
922 case kWhatPollDuration:
923 {
924 int32_t generation;
925 CHECK(msg->findInt32("generation", &generation));
926
927 if (generation != mPollDurationGeneration) {
928 // stale
929 break;
930 }
931
932 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700933 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800934 sp<NuPlayer2Driver> driver = mDriver.promote();
935 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700936 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800937 }
938 }
939
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -0800940 msg->post(1000000LL); // poll again in a second.
Wei Jia53692fa2017-12-11 10:33:46 -0800941 break;
942 }
943
944 case kWhatSetVideoSurface:
945 {
946
947 sp<RefBase> obj;
948 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800949 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800950
951 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800952 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700953 (mCurrentSourceInfo.mSource != NULL && mStarted
954 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800955 && mVideoDecoder != NULL) ? "have" : "no");
956
Wei Jiaf01e3122018-10-18 11:49:44 -0700957 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
958 // because NuPlayer2 might be in preparing state and it could take long time.
959 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
960 if (mCurrentSourceInfo.mSource == NULL || !mStarted
961 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800962 // NOTE: mVideoDecoder's mNativeWindow is always non-null
963 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
964 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800965 break;
966 }
967
968 mDeferredActions.push_back(
969 new FlushDecoderAction(
970 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
971 FLUSH_CMD_SHUTDOWN /* video */));
972
Wei Jia28288fb2017-12-15 13:45:29 -0800973 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800974
975 if (obj != NULL) {
976 if (mStarted) {
977 // Issue a seek to refresh the video screen only if started otherwise
978 // the extractor may not yet be started and will assert.
979 // If the video decoder is not set (perhaps audio only in this case)
980 // do not perform a seek as it is not needed.
981 int64_t currentPositionUs = 0;
982 if (getCurrentPosition(&currentPositionUs) == OK) {
983 mDeferredActions.push_back(
984 new SeekAction(currentPositionUs,
985 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
986 }
987 }
988
989 // If there is a new surface texture, instantiate decoders
990 // again if possible.
991 mDeferredActions.push_back(
992 new SimpleAction(&NuPlayer2::performScanSources));
993
994 // After a flush without shutdown, decoder is paused.
995 // Don't resume it until source seek is done, otherwise it could
996 // start pulling stale data too soon.
997 mDeferredActions.push_back(
998 new ResumeDecoderAction(false /* needNotify */));
999 }
1000
1001 processDeferredActions();
1002 break;
1003 }
1004
1005 case kWhatSetAudioSink:
1006 {
1007 ALOGV("kWhatSetAudioSink");
1008
1009 sp<RefBase> obj;
1010 CHECK(msg->findObject("sink", &obj));
1011
Wei Jia33abcc72018-01-30 09:47:38 -08001012 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001013 break;
1014 }
1015
1016 case kWhatStart:
1017 {
1018 ALOGV("kWhatStart");
1019 if (mStarted) {
1020 // do not resume yet if the source is still buffering
1021 if (!mPausedForBuffering) {
1022 onResume();
1023 }
1024 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001025 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001026 }
1027 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001028 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001029 break;
1030 }
1031
1032 case kWhatConfigPlayback:
1033 {
1034 sp<AReplyToken> replyID;
1035 CHECK(msg->senderAwaitsResponse(&replyID));
1036 AudioPlaybackRate rate /* sanitized */;
1037 readFromAMessage(msg, &rate);
1038 status_t err = OK;
1039 if (mRenderer != NULL) {
1040 // AudioSink allows only 1.f and 0.f for offload mode.
1041 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001042 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001043 int64_t currentPositionUs;
1044 if (getCurrentPosition(&currentPositionUs) != OK) {
1045 currentPositionUs = mPreviousSeekTimeUs;
1046 }
1047
1048 // Set mPlaybackSettings so that the new audio decoder can
1049 // be created correctly.
1050 mPlaybackSettings = rate;
1051 if (!mPaused) {
1052 mRenderer->pause();
1053 }
1054 restartAudio(
1055 currentPositionUs, true /* forceNonOffload */,
1056 true /* needsToCreateAudioDecoder */);
1057 if (!mPaused) {
1058 mRenderer->resume();
1059 }
1060 }
1061
1062 err = mRenderer->setPlaybackSettings(rate);
1063 }
1064 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001065 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001066
Wei Jia700a7c22018-09-14 18:04:35 -07001067 if (mVideoDecoder != NULL) {
1068 sp<AMessage> params = new AMessage();
1069 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1070 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001071 }
1072 }
1073
Wei Jia53692fa2017-12-11 10:33:46 -08001074 sp<AMessage> response = new AMessage;
1075 response->setInt32("err", err);
1076 response->postReply(replyID);
1077 break;
1078 }
1079
1080 case kWhatGetPlaybackSettings:
1081 {
1082 sp<AReplyToken> replyID;
1083 CHECK(msg->senderAwaitsResponse(&replyID));
1084 AudioPlaybackRate rate = mPlaybackSettings;
1085 status_t err = OK;
1086 if (mRenderer != NULL) {
1087 err = mRenderer->getPlaybackSettings(&rate);
1088 }
1089 if (err == OK) {
1090 // get playback settings used by renderer, as it may be
1091 // slightly off due to audiosink not taking small changes.
1092 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001093 }
1094 sp<AMessage> response = new AMessage;
1095 if (err == OK) {
1096 writeToAMessage(response, rate);
1097 }
1098 response->setInt32("err", err);
1099 response->postReply(replyID);
1100 break;
1101 }
1102
1103 case kWhatConfigSync:
1104 {
1105 sp<AReplyToken> replyID;
1106 CHECK(msg->senderAwaitsResponse(&replyID));
1107
1108 ALOGV("kWhatConfigSync");
1109 AVSyncSettings sync;
1110 float videoFpsHint;
1111 readFromAMessage(msg, &sync, &videoFpsHint);
1112 status_t err = OK;
1113 if (mRenderer != NULL) {
1114 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1115 }
1116 if (err == OK) {
1117 mSyncSettings = sync;
1118 mVideoFpsHint = videoFpsHint;
1119 }
1120 sp<AMessage> response = new AMessage;
1121 response->setInt32("err", err);
1122 response->postReply(replyID);
1123 break;
1124 }
1125
1126 case kWhatGetSyncSettings:
1127 {
1128 sp<AReplyToken> replyID;
1129 CHECK(msg->senderAwaitsResponse(&replyID));
1130 AVSyncSettings sync = mSyncSettings;
1131 float videoFps = mVideoFpsHint;
1132 status_t err = OK;
1133 if (mRenderer != NULL) {
1134 err = mRenderer->getSyncSettings(&sync, &videoFps);
1135 if (err == OK) {
1136 mSyncSettings = sync;
1137 mVideoFpsHint = videoFps;
1138 }
1139 }
1140 sp<AMessage> response = new AMessage;
1141 if (err == OK) {
1142 writeToAMessage(response, sync, videoFps);
1143 }
1144 response->setInt32("err", err);
1145 response->postReply(replyID);
1146 break;
1147 }
1148
1149 case kWhatScanSources:
1150 {
1151 int32_t generation;
1152 CHECK(msg->findInt32("generation", &generation));
1153 if (generation != mScanSourcesGeneration) {
1154 // Drop obsolete msg.
1155 break;
1156 }
1157
1158 mScanSourcesPending = false;
1159
1160 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1161 mAudioDecoder != NULL, mVideoDecoder != NULL);
1162
1163 bool mHadAnySourcesBefore =
1164 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1165 bool rescan = false;
1166
1167 // initialize video before audio because successful initialization of
1168 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001169 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001170 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1171 rescan = true;
1172 }
1173 }
1174
1175 // Don't try to re-open audio sink if there's an existing decoder.
1176 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1177 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1178 rescan = true;
1179 }
1180 }
1181
1182 if (!mHadAnySourcesBefore
1183 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1184 // This is the first time we've found anything playable.
1185
Wei Jiaf01e3122018-10-18 11:49:44 -07001186 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001187 schedulePollDuration();
1188 }
1189 }
1190
1191 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001192 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001193 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1194 // We're not currently decoding anything (no audio or
1195 // video tracks found) and we just ran out of input data.
1196
1197 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001198 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001199 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001200 notifyListener(
1201 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001202 }
1203 }
1204 break;
1205 }
1206
1207 if (rescan) {
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08001208 msg->post(100000LL);
Wei Jia53692fa2017-12-11 10:33:46 -08001209 mScanSourcesPending = true;
1210 }
1211 break;
1212 }
1213
1214 case kWhatVideoNotify:
1215 case kWhatAudioNotify:
1216 {
1217 bool audio = msg->what() == kWhatAudioNotify;
1218
1219 int32_t currentDecoderGeneration =
1220 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1221 int32_t requesterGeneration = currentDecoderGeneration - 1;
1222 CHECK(msg->findInt32("generation", &requesterGeneration));
1223
1224 if (requesterGeneration != currentDecoderGeneration) {
1225 ALOGV("got message from old %s decoder, generation(%d:%d)",
1226 audio ? "audio" : "video", requesterGeneration,
1227 currentDecoderGeneration);
1228 sp<AMessage> reply;
1229 if (!(msg->findMessage("reply", &reply))) {
1230 return;
1231 }
1232
1233 reply->setInt32("err", INFO_DISCONTINUITY);
1234 reply->post();
1235 return;
1236 }
1237
1238 int32_t what;
1239 CHECK(msg->findInt32("what", &what));
1240
1241 if (what == DecoderBase::kWhatInputDiscontinuity) {
1242 int32_t formatChange;
1243 CHECK(msg->findInt32("formatChange", &formatChange));
1244
1245 ALOGV("%s discontinuity: formatChange %d",
1246 audio ? "audio" : "video", formatChange);
1247
1248 if (formatChange) {
1249 mDeferredActions.push_back(
1250 new FlushDecoderAction(
1251 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1252 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1253 }
1254
1255 mDeferredActions.push_back(
1256 new SimpleAction(
1257 &NuPlayer2::performScanSources));
1258
1259 processDeferredActions();
1260 } else if (what == DecoderBase::kWhatEOS) {
1261 int32_t err;
1262 CHECK(msg->findInt32("err", &err));
1263
1264 if (err == ERROR_END_OF_STREAM) {
1265 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1266 } else {
1267 ALOGV("got %s decoder EOS w/ error %d",
1268 audio ? "audio" : "video",
1269 err);
1270 }
1271
1272 mRenderer->queueEOS(audio, err);
1273 } else if (what == DecoderBase::kWhatFlushCompleted) {
1274 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1275
1276 handleFlushComplete(audio, true /* isDecoder */);
1277 finishFlushIfPossible();
1278 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1279 sp<AMessage> format;
1280 CHECK(msg->findMessage("format", &format));
1281
1282 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001283 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001284
1285 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001286 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001287 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1288 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1289 if (audio) {
1290 mAudioDecoder.clear();
1291 mAudioDecoderError = false;
1292 ++mAudioDecoderGeneration;
1293
1294 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1295 mFlushingAudio = SHUT_DOWN;
1296 } else {
1297 mVideoDecoder.clear();
1298 mVideoDecoderError = false;
1299 ++mVideoDecoderGeneration;
1300
1301 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1302 mFlushingVideo = SHUT_DOWN;
1303 }
1304
1305 finishFlushIfPossible();
1306 } else if (what == DecoderBase::kWhatResumeCompleted) {
1307 finishResume();
1308 } else if (what == DecoderBase::kWhatError) {
1309 status_t err;
1310 if (!msg->findInt32("err", &err) || err == OK) {
1311 err = UNKNOWN_ERROR;
1312 }
1313
1314 // Decoder errors can be due to Source (e.g. from streaming),
1315 // or from decoding corrupted bitstreams, or from other decoder
1316 // MediaCodec operations (e.g. from an ongoing reset or seek).
1317 // They may also be due to openAudioSink failure at
1318 // decoder start or after a format change.
1319 //
1320 // We try to gracefully shut down the affected decoder if possible,
1321 // rather than trying to force the shutdown with something
1322 // similar to performReset(). This method can lead to a hang
1323 // if MediaCodec functions block after an error, but they should
1324 // typically return INVALID_OPERATION instead of blocking.
1325
1326 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1327 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1328 err, audio ? "audio" : "video", *flushing);
1329
1330 switch (*flushing) {
1331 case NONE:
1332 mDeferredActions.push_back(
1333 new FlushDecoderAction(
1334 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1335 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1336 processDeferredActions();
1337 break;
1338 case FLUSHING_DECODER:
1339 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1340 break; // Wait for flush to complete.
1341 case FLUSHING_DECODER_SHUTDOWN:
1342 break; // Wait for flush to complete.
1343 case SHUTTING_DOWN_DECODER:
1344 break; // Wait for shutdown to complete.
1345 case FLUSHED:
1346 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1347 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1348 break;
1349 case SHUT_DOWN:
1350 finishFlushIfPossible(); // Should not occur.
1351 break; // Finish anyways.
1352 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001353 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001354 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001355 if (mVideoDecoderError
1356 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1357 || mNativeWindow == NULL
1358 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001359 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001360 // When both audio and video have error, or this stream has only audio
1361 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001362 notifyListener(
1363 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1364 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001365 } else {
1366 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001367 notifyListener(
1368 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1369 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001370 }
1371 mAudioDecoderError = true;
1372 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001373 if (mAudioDecoderError
1374 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001375 || mAudioSink == NULL || mAudioDecoder == NULL) {
1376 // When both audio and video have error, or this stream has only video
1377 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001378 notifyListener(
1379 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1380 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001381 } else {
1382 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001383 notifyListener(
1384 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1385 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001386 }
1387 mVideoDecoderError = true;
1388 }
1389 }
1390 } else {
1391 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1392 what,
1393 what >> 24,
1394 (what >> 16) & 0xff,
1395 (what >> 8) & 0xff,
1396 what & 0xff);
1397 }
1398
1399 break;
1400 }
1401
1402 case kWhatRendererNotify:
1403 {
1404 int32_t requesterGeneration = mRendererGeneration - 1;
1405 CHECK(msg->findInt32("generation", &requesterGeneration));
1406 if (requesterGeneration != mRendererGeneration) {
1407 ALOGV("got message from old renderer, generation(%d:%d)",
1408 requesterGeneration, mRendererGeneration);
1409 return;
1410 }
1411
1412 int32_t what;
1413 CHECK(msg->findInt32("what", &what));
1414
1415 if (what == Renderer::kWhatEOS) {
1416 int32_t audio;
1417 CHECK(msg->findInt32("audio", &audio));
1418
1419 int32_t finalResult;
1420 CHECK(msg->findInt32("finalResult", &finalResult));
1421
1422 if (audio) {
1423 mAudioEOS = true;
1424 } else {
1425 mVideoEOS = true;
1426 }
1427
1428 if (finalResult == ERROR_END_OF_STREAM) {
1429 ALOGV("reached %s EOS", audio ? "audio" : "video");
1430 } else {
1431 ALOGE("%s track encountered an error (%d)",
1432 audio ? "audio" : "video", finalResult);
1433
1434 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001435 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1436 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001437 }
1438
1439 if ((mAudioEOS || mAudioDecoder == NULL)
1440 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001441 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001442 }
1443 } else if (what == Renderer::kWhatFlushComplete) {
1444 int32_t audio;
1445 CHECK(msg->findInt32("audio", &audio));
1446
1447 if (audio) {
1448 mAudioEOS = false;
1449 } else {
1450 mVideoEOS = false;
1451 }
1452
1453 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1454 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1455 || mFlushingAudio == SHUT_DOWN)) {
1456 // Flush has been handled by tear down.
1457 break;
1458 }
1459 handleFlushComplete(audio, false /* isDecoder */);
1460 finishFlushIfPossible();
1461 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001462 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1463 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001464 } else if (what == Renderer::kWhatMediaRenderingStart) {
1465 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001466 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001467 } else if (what == Renderer::kWhatAudioTearDown) {
1468 int32_t reason;
1469 CHECK(msg->findInt32("reason", &reason));
1470 ALOGV("Tear down audio with reason %d.", reason);
1471 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1472 // TimeoutWhenPaused is only for offload mode.
1473 ALOGW("Receive a stale message for teardown.");
1474 break;
1475 }
1476 int64_t positionUs;
1477 if (!msg->findInt64("positionUs", &positionUs)) {
1478 positionUs = mPreviousSeekTimeUs;
1479 }
1480
1481 restartAudio(
1482 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1483 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1484 }
1485 break;
1486 }
1487
1488 case kWhatMoreDataQueued:
1489 {
1490 break;
1491 }
1492
1493 case kWhatReset:
1494 {
1495 ALOGV("kWhatReset");
1496
1497 mResetting = true;
1498 stopPlaybackTimer("kWhatReset");
1499 stopRebufferingTimer(true);
1500
1501 mDeferredActions.push_back(
1502 new FlushDecoderAction(
1503 FLUSH_CMD_SHUTDOWN /* audio */,
1504 FLUSH_CMD_SHUTDOWN /* video */));
1505
1506 mDeferredActions.push_back(
1507 new SimpleAction(&NuPlayer2::performReset));
1508
1509 processDeferredActions();
1510 break;
1511 }
1512
1513 case kWhatNotifyTime:
1514 {
1515 ALOGV("kWhatNotifyTime");
1516 int64_t timerUs;
1517 CHECK(msg->findInt64("timerUs", &timerUs));
1518
Wei Jiaf01e3122018-10-18 11:49:44 -07001519 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001520 break;
1521 }
1522
1523 case kWhatSeek:
1524 {
1525 int64_t seekTimeUs;
1526 int32_t mode;
1527 int32_t needNotify;
1528 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1529 CHECK(msg->findInt32("mode", &mode));
1530 CHECK(msg->findInt32("needNotify", &needNotify));
1531
1532 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1533 (long long)seekTimeUs, mode, needNotify);
1534
1535 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001536 if (!mSourceStarted) {
1537 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001538 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001539 }
Wei Jia083e9092018-02-12 11:46:04 -08001540 if (seekTimeUs > 0) {
1541 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1542 }
1543
Wei Jia53692fa2017-12-11 10:33:46 -08001544 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001545 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001546 }
1547 break;
1548 }
1549
Wei Jia083e9092018-02-12 11:46:04 -08001550 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001551 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001552
Wei Jia53692fa2017-12-11 10:33:46 -08001553 mDeferredActions.push_back(
1554 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1555 FLUSH_CMD_FLUSH /* video */));
1556
1557 mDeferredActions.push_back(
1558 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1559
1560 // After a flush without shutdown, decoder is paused.
1561 // Don't resume it until source seek is done, otherwise it could
1562 // start pulling stale data too soon.
1563 mDeferredActions.push_back(
1564 new ResumeDecoderAction(needNotify));
1565
1566 processDeferredActions();
1567 break;
1568 }
1569
Wei Jiad1864f92018-10-19 12:34:56 -07001570 case kWhatRewind:
1571 {
1572 ALOGV("kWhatRewind");
1573
1574 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1575 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1576
1577 if (!mStarted) {
1578 if (!mSourceStarted) {
1579 mSourceStarted = true;
1580 mCurrentSourceInfo.mSource->start();
1581 }
1582 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1583 break;
1584 }
1585
1586 // seeks can take a while, so we essentially paused
1587 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1588
1589 mDeferredActions.push_back(
1590 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1591 FLUSH_CMD_FLUSH /* video */));
1592
1593 mDeferredActions.push_back(
1594 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1595
1596 // After a flush without shutdown, decoder is paused.
1597 // Don't resume it until source seek is done, otherwise it could
1598 // start pulling stale data too soon.
1599 mDeferredActions.push_back(
1600 new ResumeDecoderAction(false /* needNotify */));
1601
1602 processDeferredActions();
1603 break;
1604 }
1605
Wei Jia53692fa2017-12-11 10:33:46 -08001606 case kWhatPause:
1607 {
Wei Jia6376cd52018-09-26 11:42:55 -07001608 if (!mStarted) {
1609 onStart(false /* play */);
1610 }
Wei Jia53692fa2017-12-11 10:33:46 -08001611 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001612 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001613 mPausedByClient = true;
1614 break;
1615 }
1616
1617 case kWhatSourceNotify:
1618 {
1619 onSourceNotify(msg);
1620 break;
1621 }
1622
1623 case kWhatClosedCaptionNotify:
1624 {
1625 onClosedCaptionNotify(msg);
1626 break;
1627 }
1628
1629 case kWhatPrepareDrm:
1630 {
1631 status_t status = onPrepareDrm(msg);
1632
1633 sp<AMessage> response = new AMessage;
1634 response->setInt32("status", status);
1635 sp<AReplyToken> replyID;
1636 CHECK(msg->senderAwaitsResponse(&replyID));
1637 response->postReply(replyID);
1638 break;
1639 }
1640
1641 case kWhatReleaseDrm:
1642 {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001643 status_t status = onReleaseDrm(msg);
Wei Jia53692fa2017-12-11 10:33:46 -08001644
1645 sp<AMessage> response = new AMessage;
1646 response->setInt32("status", status);
1647 sp<AReplyToken> replyID;
1648 CHECK(msg->senderAwaitsResponse(&replyID));
1649 response->postReply(replyID);
1650 break;
1651 }
1652
1653 default:
1654 TRESPASS();
1655 break;
1656 }
1657}
1658
1659void NuPlayer2::onResume() {
1660 if (!mPaused || mResetting) {
1661 ALOGD_IF(mResetting, "resetting, onResume discarded");
1662 return;
1663 }
1664 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001665 if (mCurrentSourceInfo.mSource != NULL) {
1666 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001667 } else {
1668 ALOGW("resume called when source is gone or not set");
1669 }
1670 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1671 // needed.
1672 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1673 instantiateDecoder(true /* audio */, &mAudioDecoder);
1674 }
1675 if (mRenderer != NULL) {
1676 mRenderer->resume();
1677 } else {
1678 ALOGW("resume called when renderer is gone or not set");
1679 }
1680
1681 startPlaybackTimer("onresume");
1682}
1683
Wei Jia6376cd52018-09-26 11:42:55 -07001684void NuPlayer2::onStart(bool play) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001685 ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001686
1687 if (!mSourceStarted) {
1688 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001689 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001690 }
Wei Jia53692fa2017-12-11 10:33:46 -08001691
1692 mOffloadAudio = false;
1693 mAudioEOS = false;
1694 mVideoEOS = false;
1695 mStarted = true;
1696 mPaused = false;
1697
1698 uint32_t flags = 0;
1699
Wei Jiaf01e3122018-10-18 11:49:44 -07001700 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001701 flags |= Renderer::FLAG_REAL_TIME;
1702 }
1703
Wei Jiaf01e3122018-10-18 11:49:44 -07001704 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1705 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001706 if (!hasAudio && !hasVideo) {
1707 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001708 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001709 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001710 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1711 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001712 return;
1713 }
1714 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1715
Wei Jiaf01e3122018-10-18 11:49:44 -07001716 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001717
1718 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1719 if (mAudioSink != NULL) {
1720 streamType = mAudioSink->getAudioStreamType();
1721 }
1722
1723 mOffloadAudio =
Dongwon Kang946bdb32018-11-14 10:12:00 -08001724 JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
1725 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001726 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1727
1728 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08001729 if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08001730 mOffloadAudio = false;
1731 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1732 }
1733
1734 if (mOffloadAudio) {
1735 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1736 }
1737
1738 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1739 ++mRendererGeneration;
1740 notify->setInt32("generation", mRendererGeneration);
1741 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1742 mRendererLooper = new ALooper;
Wei Jia8c8b57a2018-11-28 11:09:50 -08001743 mRendererLooper->setName("NuPlayer2Renderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001744 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001745 mRendererLooper->registerHandler(mRenderer);
1746
1747 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1748 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001749 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001750 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001751 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001752 return;
1753 }
1754
1755 float rate = getFrameRate();
1756 if (rate > 0) {
1757 mRenderer->setVideoFrameRate(rate);
1758 }
1759
Wei Jiad1864f92018-10-19 12:34:56 -07001760 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001761 // Renderer is created in paused state.
1762 if (play) {
1763 mRenderer->resume();
1764 }
1765
Wei Jia53692fa2017-12-11 10:33:46 -08001766 if (mVideoDecoder != NULL) {
1767 mVideoDecoder->setRenderer(mRenderer);
1768 }
1769 if (mAudioDecoder != NULL) {
1770 mAudioDecoder->setRenderer(mRenderer);
1771 }
1772
1773 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001774 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001775
1776 postScanSources();
1777}
1778
Wei Jiad1864f92018-10-19 12:34:56 -07001779void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001780 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001781
1782 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1783 return;
1784 }
1785
1786 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001787 msg->setInt32("generation", mEOSMonitorGeneration);
1788 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1789}
1790
Wei Jia53692fa2017-12-11 10:33:46 -08001791void NuPlayer2::startPlaybackTimer(const char *where) {
1792 Mutex::Autolock autoLock(mPlayingTimeLock);
1793 if (mLastStartedPlayingTimeNs == 0) {
1794 mLastStartedPlayingTimeNs = systemTime();
1795 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1796 }
1797}
1798
1799void NuPlayer2::stopPlaybackTimer(const char *where) {
1800 Mutex::Autolock autoLock(mPlayingTimeLock);
1801
1802 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1803
1804 if (mLastStartedPlayingTimeNs != 0) {
1805 sp<NuPlayer2Driver> driver = mDriver.promote();
1806 if (driver != NULL) {
1807 int64_t now = systemTime();
1808 int64_t played = now - mLastStartedPlayingTimeNs;
1809 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1810
1811 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001812 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001813 }
1814 }
1815 mLastStartedPlayingTimeNs = 0;
1816 }
1817}
1818
1819void NuPlayer2::startRebufferingTimer() {
1820 Mutex::Autolock autoLock(mPlayingTimeLock);
1821 if (mLastStartedRebufferingTimeNs == 0) {
1822 mLastStartedRebufferingTimeNs = systemTime();
1823 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1824 }
1825}
1826
1827void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1828 Mutex::Autolock autoLock(mPlayingTimeLock);
1829
Wei Jiaf01e3122018-10-18 11:49:44 -07001830 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1831 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001832
1833 if (mLastStartedRebufferingTimeNs != 0) {
1834 sp<NuPlayer2Driver> driver = mDriver.promote();
1835 if (driver != NULL) {
1836 int64_t now = systemTime();
1837 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1838 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1839
1840 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001841 driver->notifyMoreRebufferingTimeUs(
1842 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001843 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001844 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001845 }
1846 }
1847 }
1848 mLastStartedRebufferingTimeNs = 0;
1849 }
1850}
1851
1852void NuPlayer2::onPause() {
1853
1854 stopPlaybackTimer("onPause");
1855
1856 if (mPaused) {
1857 return;
1858 }
1859 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001860 if (mCurrentSourceInfo.mSource != NULL) {
1861 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001862 } else {
1863 ALOGW("pause called when source is gone or not set");
1864 }
1865 if (mRenderer != NULL) {
1866 mRenderer->pause();
1867 } else {
1868 ALOGW("pause called when renderer is gone or not set");
1869 }
1870
1871}
1872
1873bool NuPlayer2::audioDecoderStillNeeded() {
1874 // Audio decoder is no longer needed if it's in shut/shutting down status.
1875 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1876}
1877
1878void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1879 // We wait for both the decoder flush and the renderer flush to complete
1880 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1881
1882 mFlushComplete[audio][isDecoder] = true;
1883 if (!mFlushComplete[audio][!isDecoder]) {
1884 return;
1885 }
1886
1887 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1888 switch (*state) {
1889 case FLUSHING_DECODER:
1890 {
1891 *state = FLUSHED;
1892 break;
1893 }
1894
1895 case FLUSHING_DECODER_SHUTDOWN:
1896 {
1897 *state = SHUTTING_DOWN_DECODER;
1898
1899 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1900 getDecoder(audio)->initiateShutdown();
1901 break;
1902 }
1903
1904 default:
1905 // decoder flush completes only occur in a flushing state.
1906 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1907 break;
1908 }
1909}
1910
1911void NuPlayer2::finishFlushIfPossible() {
1912 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1913 && mFlushingAudio != SHUT_DOWN) {
1914 return;
1915 }
1916
1917 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1918 && mFlushingVideo != SHUT_DOWN) {
1919 return;
1920 }
1921
1922 ALOGV("both audio and video are flushed now.");
1923
1924 mFlushingAudio = NONE;
1925 mFlushingVideo = NONE;
1926
1927 clearFlushComplete();
1928
1929 processDeferredActions();
1930}
1931
1932void NuPlayer2::postScanSources() {
1933 if (mScanSourcesPending) {
1934 return;
1935 }
1936
1937 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1938 msg->setInt32("generation", mScanSourcesGeneration);
1939 msg->post();
1940
1941 mScanSourcesPending = true;
1942}
1943
1944void NuPlayer2::tryOpenAudioSinkForOffload(
1945 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1946 // Note: This is called early in NuPlayer2 to determine whether offloading
1947 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1948
1949 status_t err = mRenderer->openAudioSink(
1950 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001951 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001952 if (err != OK) {
1953 // Any failure we turn off mOffloadAudio.
1954 mOffloadAudio = false;
1955 } else if (mOffloadAudio) {
1956 sendMetaDataToHal(mAudioSink, audioMeta);
1957 }
1958}
1959
1960void NuPlayer2::closeAudioSink() {
1961 mRenderer->closeAudioSink();
1962}
1963
1964void NuPlayer2::restartAudio(
1965 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1966 if (mAudioDecoder != NULL) {
1967 mAudioDecoder->pause();
1968 mAudioDecoder.clear();
1969 mAudioDecoderError = false;
1970 ++mAudioDecoderGeneration;
1971 }
1972 if (mFlushingAudio == FLUSHING_DECODER) {
1973 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1974 mFlushingAudio = FLUSHED;
1975 finishFlushIfPossible();
1976 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1977 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1978 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1979 mFlushingAudio = SHUT_DOWN;
1980 finishFlushIfPossible();
1981 needsToCreateAudioDecoder = false;
1982 }
1983 if (mRenderer == NULL) {
1984 return;
1985 }
1986 closeAudioSink();
1987 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1988 if (mVideoDecoder != NULL) {
1989 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1990 }
1991
1992 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1993
1994 if (forceNonOffload) {
1995 mRenderer->signalDisableOffloadAudio();
1996 mOffloadAudio = false;
1997 }
1998 if (needsToCreateAudioDecoder) {
1999 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
2000 }
2001}
2002
2003void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002004 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002005 return;
2006 }
2007
2008 if (mRenderer == NULL) {
2009 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
2010 mOffloadAudio = false;
2011 return;
2012 }
2013
Wei Jiaf01e3122018-10-18 11:49:44 -07002014 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
2015 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002016 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
2017 const bool hasVideo = (videoFormat != NULL);
Dongwon Kangcd0e4272018-11-15 10:49:14 -08002018 bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
Wei Jiaf01e3122018-10-18 11:49:44 -07002019 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08002020 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2021
2022 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08002023 if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08002024 canOffload = false;
2025 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2026 }
2027
2028 if (canOffload) {
2029 if (!mOffloadAudio) {
2030 mRenderer->signalEnableOffloadAudio();
2031 }
2032 // open audio sink early under offload mode.
2033 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2034 } else {
2035 if (mOffloadAudio) {
2036 mRenderer->signalDisableOffloadAudio();
2037 mOffloadAudio = false;
2038 }
2039 }
2040}
2041
2042status_t NuPlayer2::instantiateDecoder(
2043 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2044 // The audio decoder could be cleared by tear down. If still in shut down
2045 // process, no need to create a new audio decoder.
2046 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2047 return OK;
2048 }
2049
Wei Jiaf01e3122018-10-18 11:49:44 -07002050 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002051
2052 if (format == NULL) {
2053 return UNKNOWN_ERROR;
2054 } else {
2055 status_t err;
2056 if (format->findInt32("err", &err) && err) {
2057 return err;
2058 }
2059 }
2060
2061 format->setInt32("priority", 0 /* realtime */);
2062
2063 if (!audio) {
2064 AString mime;
2065 CHECK(format->findString("mime", &mime));
2066
2067 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2068 if (mCCDecoder == NULL) {
2069 mCCDecoder = new CCDecoder(ccNotify);
2070 }
2071
Wei Jiaf01e3122018-10-18 11:49:44 -07002072 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002073 format->setInt32("secure", true);
2074 }
2075
Wei Jiaf01e3122018-10-18 11:49:44 -07002076 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002077 format->setInt32("protected", true);
2078 }
2079
2080 float rate = getFrameRate();
2081 if (rate > 0) {
2082 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2083 }
2084 }
2085
2086 if (audio) {
2087 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2088 ++mAudioDecoderGeneration;
2089 notify->setInt32("generation", mAudioDecoderGeneration);
2090
2091 if (checkAudioModeChange) {
2092 determineAudioModeChange(format);
2093 }
2094 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002095 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002096
Wei Jiaf01e3122018-10-18 11:49:44 -07002097 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002098 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002099 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002100 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2101 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002102 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002103
Wei Jiaf01e3122018-10-18 11:49:44 -07002104 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002105 ALOGV("instantiateDecoder audio Decoder");
2106 }
2107 mAudioDecoderError = false;
2108 } else {
2109 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2110 ++mVideoDecoderGeneration;
2111 notify->setInt32("generation", mVideoDecoderGeneration);
2112
2113 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002114 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2115 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002116 mVideoDecoderError = false;
2117
2118 // enable FRC if high-quality AV sync is requested, even if not
2119 // directly queuing to display, as this will even improve textureview
2120 // playback.
2121 {
2122 if (property_get_bool("persist.sys.media.avsync", false)) {
2123 format->setInt32("auto-frc", 1);
2124 }
2125 }
2126 }
2127 (*decoder)->init();
2128
2129 // Modular DRM
Robert Shihc3fca0e2018-12-04 17:08:04 -08002130 if (mCurrentSourceInfo.mIsDrmProtected) {
2131 format->setObject("crypto", mCurrentSourceInfo.mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002132 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
Robert Shihc3fca0e2018-12-04 17:08:04 -08002133 mCurrentSourceInfo.mCrypto.get(),
2134 (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002135 }
2136
2137 (*decoder)->configure(format);
2138
2139 if (!audio) {
2140 sp<AMessage> params = new AMessage();
2141 float rate = getFrameRate();
2142 if (rate > 0) {
2143 params->setFloat("frame-rate-total", rate);
2144 }
2145
2146 sp<MetaData> fileMeta = getFileMeta();
2147 if (fileMeta != NULL) {
2148 int32_t videoTemporalLayerCount;
2149 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2150 && videoTemporalLayerCount > 0) {
2151 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2152 }
2153 }
2154
2155 if (params->countEntries() > 0) {
2156 (*decoder)->setParameters(params);
2157 }
2158 }
2159 return OK;
2160}
2161
2162void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002163 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002164 const sp<AMessage> &inputFormat,
2165 const sp<AMessage> &outputFormat) {
2166 if (inputFormat == NULL) {
2167 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002168 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002169 return;
2170 }
2171 int32_t err = OK;
2172 inputFormat->findInt32("err", &err);
2173 if (err == -EWOULDBLOCK) {
2174 ALOGW("Video meta is not available yet!");
2175 return;
2176 }
2177 if (err != OK) {
2178 ALOGW("Something is wrong with video meta!");
2179 return;
2180 }
2181
2182 int32_t displayWidth, displayHeight;
2183 if (outputFormat != NULL) {
2184 int32_t width, height;
2185 CHECK(outputFormat->findInt32("width", &width));
2186 CHECK(outputFormat->findInt32("height", &height));
2187
2188 int32_t cropLeft, cropTop, cropRight, cropBottom;
2189 CHECK(outputFormat->findRect(
2190 "crop",
2191 &cropLeft, &cropTop, &cropRight, &cropBottom));
2192
2193 displayWidth = cropRight - cropLeft + 1;
2194 displayHeight = cropBottom - cropTop + 1;
2195
2196 ALOGV("Video output format changed to %d x %d "
2197 "(crop: %d x %d @ (%d, %d))",
2198 width, height,
2199 displayWidth,
2200 displayHeight,
2201 cropLeft, cropTop);
2202 } else {
2203 CHECK(inputFormat->findInt32("width", &displayWidth));
2204 CHECK(inputFormat->findInt32("height", &displayHeight));
2205
2206 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2207 }
2208
2209 // Take into account sample aspect ratio if necessary:
2210 int32_t sarWidth, sarHeight;
2211 if (inputFormat->findInt32("sar-width", &sarWidth)
2212 && inputFormat->findInt32("sar-height", &sarHeight)
2213 && sarWidth > 0 && sarHeight > 0) {
2214 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2215
2216 displayWidth = (displayWidth * sarWidth) / sarHeight;
2217
2218 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2219 } else {
2220 int32_t width, height;
2221 if (inputFormat->findInt32("display-width", &width)
2222 && inputFormat->findInt32("display-height", &height)
2223 && width > 0 && height > 0
2224 && displayWidth > 0 && displayHeight > 0) {
2225 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2226 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2227 } else {
2228 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2229 }
2230 ALOGV("Video display width and height are overridden to %d x %d",
2231 displayWidth, displayHeight);
2232 }
2233 }
2234
2235 int32_t rotationDegrees;
2236 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2237 rotationDegrees = 0;
2238 }
2239
2240 if (rotationDegrees == 90 || rotationDegrees == 270) {
2241 int32_t tmp = displayWidth;
2242 displayWidth = displayHeight;
2243 displayHeight = tmp;
2244 }
2245
2246 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002247 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002248 MEDIA2_SET_VIDEO_SIZE,
2249 displayWidth,
2250 displayHeight);
2251}
2252
Dongwon Kang41929fb2018-09-09 08:29:56 -07002253void NuPlayer2::notifyListener(
2254 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002255 if (mDriver == NULL) {
2256 return;
2257 }
2258
2259 sp<NuPlayer2Driver> driver = mDriver.promote();
2260
2261 if (driver == NULL) {
2262 return;
2263 }
2264
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002265 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002266}
2267
2268void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2269 ALOGV("[%s] flushDecoder needShutdown=%d",
2270 audio ? "audio" : "video", needShutdown);
2271
2272 const sp<DecoderBase> &decoder = getDecoder(audio);
2273 if (decoder == NULL) {
2274 ALOGI("flushDecoder %s without decoder present",
2275 audio ? "audio" : "video");
2276 return;
2277 }
2278
2279 // Make sure we don't continue to scan sources until we finish flushing.
2280 ++mScanSourcesGeneration;
2281 if (mScanSourcesPending) {
2282 if (!needShutdown) {
2283 mDeferredActions.push_back(
2284 new SimpleAction(&NuPlayer2::performScanSources));
2285 }
2286 mScanSourcesPending = false;
2287 }
2288
2289 decoder->signalFlush();
2290
2291 FlushStatus newStatus =
2292 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2293
2294 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2295 mFlushComplete[audio][true /* isDecoder */] = false;
2296 if (audio) {
2297 ALOGE_IF(mFlushingAudio != NONE,
2298 "audio flushDecoder() is called in state %d", mFlushingAudio);
2299 mFlushingAudio = newStatus;
2300 } else {
2301 ALOGE_IF(mFlushingVideo != NONE,
2302 "video flushDecoder() is called in state %d", mFlushingVideo);
2303 mFlushingVideo = newStatus;
2304 }
2305}
2306
2307void NuPlayer2::queueDecoderShutdown(
2308 bool audio, bool video, const sp<AMessage> &reply) {
2309 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2310
2311 mDeferredActions.push_back(
2312 new FlushDecoderAction(
2313 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2314 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2315
2316 mDeferredActions.push_back(
2317 new SimpleAction(&NuPlayer2::performScanSources));
2318
2319 mDeferredActions.push_back(new PostMessageAction(reply));
2320
2321 processDeferredActions();
2322}
2323
2324status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2325 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002326 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2327 status_t ret = native_window_set_scaling_mode(
2328 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002329 if (ret != OK) {
2330 ALOGE("Failed to set scaling mode (%d): %s",
2331 -ret, strerror(-ret));
2332 return ret;
2333 }
2334 }
2335 return OK;
2336}
2337
Wei Jia17944af2018-12-13 18:13:10 -08002338status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002339 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Wei Jia17944af2018-12-13 18:13:10 -08002340 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002341 msg->setPointer("reply", reply);
2342
2343 sp<AMessage> response;
2344 status_t err = msg->postAndAwaitResponse(&response);
2345 return err;
2346}
2347
Wei Jia17944af2018-12-13 18:13:10 -08002348status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002349 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2350 msg->setPointer("reply", reply);
Wei Jia17944af2018-12-13 18:13:10 -08002351 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002352 msg->setInt32("type", type);
2353
2354 sp<AMessage> response;
2355 status_t err = msg->postAndAwaitResponse(&response);
2356 if (err == OK && response != NULL) {
2357 CHECK(response->findInt32("err", &err));
2358 }
2359 return err;
2360}
2361
Wei Jia17944af2018-12-13 18:13:10 -08002362status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
Wei Jia53692fa2017-12-11 10:33:46 -08002363 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Wei Jia17944af2018-12-13 18:13:10 -08002364 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002365 msg->setSize("trackIndex", trackIndex);
2366 msg->setInt32("select", select);
2367 msg->setInt64("timeUs", timeUs);
2368
2369 sp<AMessage> response;
2370 status_t err = msg->postAndAwaitResponse(&response);
2371
2372 if (err != OK) {
2373 return err;
2374 }
2375
2376 if (!response->findInt32("err", &err)) {
2377 err = OK;
2378 }
2379
2380 return err;
2381}
2382
2383status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2384 sp<Renderer> renderer = mRenderer;
2385 if (renderer == NULL) {
2386 return NO_INIT;
2387 }
2388
2389 return renderer->getCurrentPosition(mediaUs);
2390}
2391
2392void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2393 CHECK(mTrackStats != NULL);
2394
2395 mTrackStats->clear();
2396 if (mVideoDecoder != NULL) {
2397 mTrackStats->push_back(mVideoDecoder->getStats());
2398 }
2399 if (mAudioDecoder != NULL) {
2400 mTrackStats->push_back(mAudioDecoder->getStats());
2401 }
2402}
2403
2404sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002405 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002406}
2407
2408float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002409 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002410 if (meta == NULL) {
2411 return 0;
2412 }
2413 int32_t rate;
2414 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2415 // fall back to try file meta
2416 sp<MetaData> fileMeta = getFileMeta();
2417 if (fileMeta == NULL) {
2418 ALOGW("source has video meta but not file meta");
2419 return -1;
2420 }
2421 int32_t fileMetaRate;
2422 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2423 return -1;
2424 }
2425 return fileMetaRate;
2426 }
2427 return rate;
2428}
2429
2430void NuPlayer2::schedulePollDuration() {
2431 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2432 msg->setInt32("generation", mPollDurationGeneration);
2433 msg->post();
2434}
2435
2436void NuPlayer2::cancelPollDuration() {
2437 ++mPollDurationGeneration;
2438}
2439
2440void NuPlayer2::processDeferredActions() {
2441 while (!mDeferredActions.empty()) {
2442 // We won't execute any deferred actions until we're no longer in
2443 // an intermediate state, i.e. one more more decoders are currently
2444 // flushing or shutting down.
2445
2446 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2447 // We're currently flushing, postpone the reset until that's
2448 // completed.
2449
2450 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2451 mFlushingAudio, mFlushingVideo);
2452
2453 break;
2454 }
2455
2456 sp<Action> action = *mDeferredActions.begin();
2457 mDeferredActions.erase(mDeferredActions.begin());
2458
2459 action->execute(this);
2460 }
2461}
2462
2463void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2464 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2465 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2466
Wei Jiaf01e3122018-10-18 11:49:44 -07002467 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002468 // This happens when reset occurs right before the loop mode
2469 // asynchronously seeks to the start of the stream.
2470 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002471 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002472 mAudioDecoder.get(), mVideoDecoder.get());
2473 return;
2474 }
2475 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002476 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002477 ++mTimedTextGeneration;
2478
2479 // everything's flushed, continue playback.
2480}
2481
2482void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2483 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2484
2485 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2486 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2487 return;
2488 }
2489
2490 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2491 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2492 }
2493
2494 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2495 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2496 }
2497}
2498
2499void NuPlayer2::performReset() {
2500 ALOGV("performReset");
2501
2502 CHECK(mAudioDecoder == NULL);
2503 CHECK(mVideoDecoder == NULL);
2504
2505 stopPlaybackTimer("performReset");
2506 stopRebufferingTimer(true);
2507
2508 cancelPollDuration();
2509
2510 ++mScanSourcesGeneration;
2511 mScanSourcesPending = false;
2512
2513 if (mRendererLooper != NULL) {
2514 if (mRenderer != NULL) {
2515 mRendererLooper->unregisterHandler(mRenderer->id());
2516 }
2517 mRendererLooper->stop();
2518 mRendererLooper.clear();
2519 }
2520 mRenderer.clear();
2521 ++mRendererGeneration;
2522
Robert Shihc3fca0e2018-12-04 17:08:04 -08002523 resetSourceInfo(mCurrentSourceInfo);
2524 resetSourceInfo(mNextSourceInfo);
Wei Jia53692fa2017-12-11 10:33:46 -08002525
2526 if (mDriver != NULL) {
2527 sp<NuPlayer2Driver> driver = mDriver.promote();
2528 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002529 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002530 }
2531 }
2532
2533 mStarted = false;
2534 mPrepared = false;
2535 mResetting = false;
2536 mSourceStarted = false;
2537
Wei Jia53692fa2017-12-11 10:33:46 -08002538}
2539
Wei Jia57aeffd2018-02-15 16:01:14 -08002540void NuPlayer2::performPlayNextDataSource() {
2541 ALOGV("performPlayNextDataSource");
2542
2543 CHECK(mAudioDecoder == NULL);
2544 CHECK(mVideoDecoder == NULL);
2545
2546 stopPlaybackTimer("performPlayNextDataSource");
2547 stopRebufferingTimer(true);
2548
2549 cancelPollDuration();
2550
2551 ++mScanSourcesGeneration;
2552 mScanSourcesPending = false;
2553
2554 ++mRendererGeneration;
2555
Wei Jiaf01e3122018-10-18 11:49:44 -07002556 if (mCurrentSourceInfo.mSource != NULL) {
2557 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002558 }
2559
2560 long previousSrcId;
2561 {
2562 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002563 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002564
2565 mCurrentSourceInfo = mNextSourceInfo;
2566 mNextSourceInfo = SourceInfo();
2567 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002568 }
2569
2570 if (mDriver != NULL) {
2571 sp<NuPlayer2Driver> driver = mDriver.promote();
2572 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002573 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002574
2575 int64_t durationUs;
2576 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2577 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2578 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002579 notifyListener(
2580 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002581 }
2582 }
2583
2584 mStarted = false;
2585 mPrepared = true; // TODO: what if it's not prepared
2586 mResetting = false;
2587 mSourceStarted = false;
2588
Wei Jiad1864f92018-10-19 12:34:56 -07002589 addEndTimeMonitor();
2590
Wei Jia57aeffd2018-02-15 16:01:14 -08002591 if (mRenderer != NULL) {
2592 mRenderer->resume();
2593 }
2594
Wei Jia6376cd52018-09-26 11:42:55 -07002595 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002596 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002597 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002598}
2599
Wei Jia53692fa2017-12-11 10:33:46 -08002600void NuPlayer2::performScanSources() {
2601 ALOGV("performScanSources");
2602
2603 if (!mStarted) {
2604 return;
2605 }
2606
2607 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2608 postScanSources();
2609 }
2610}
2611
Wei Jia28288fb2017-12-15 13:45:29 -08002612void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002613 ALOGV("performSetSurface");
2614
Wei Jia28288fb2017-12-15 13:45:29 -08002615 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002616
2617 // XXX - ignore error from setVideoScalingMode for now
2618 setVideoScalingMode(mVideoScalingMode);
2619
2620 if (mDriver != NULL) {
2621 sp<NuPlayer2Driver> driver = mDriver.promote();
2622 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002623 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002624 }
2625 }
2626}
2627
2628void NuPlayer2::performResumeDecoders(bool needNotify) {
2629 if (needNotify) {
2630 mResumePending = true;
2631 if (mVideoDecoder == NULL) {
2632 // if audio-only, we can notify seek complete now,
2633 // as the resume operation will be relatively fast.
2634 finishResume();
2635 }
2636 }
2637
2638 if (mVideoDecoder != NULL) {
2639 // When there is continuous seek, MediaPlayer will cache the seek
2640 // position, and send down new seek request when previous seek is
2641 // complete. Let's wait for at least one video output frame before
2642 // notifying seek complete, so that the video thumbnail gets updated
2643 // when seekbar is dragged.
2644 mVideoDecoder->signalResume(needNotify);
2645 }
2646
2647 if (mAudioDecoder != NULL) {
2648 mAudioDecoder->signalResume(false /* needNotify */);
2649 }
2650}
2651
2652void NuPlayer2::finishResume() {
2653 if (mResumePending) {
2654 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002655 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002656 }
2657}
2658
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002659void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002660 if (mDriver != NULL) {
2661 sp<NuPlayer2Driver> driver = mDriver.promote();
2662 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002663 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002664 }
2665 }
2666}
2667
2668void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2669 int32_t what;
2670 CHECK(msg->findInt32("what", &what));
2671
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002672 int64_t srcId;
2673 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002674 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002675 case Source::kWhatPrepared:
2676 {
Wei Jiad1864f92018-10-19 12:34:56 -07002677 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2678 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2679 if (srcId == mCurrentSourceInfo.mSrcId) {
2680 if (mCurrentSourceInfo.mSource == NULL) {
2681 // This is a stale notification from a source that was
2682 // asynchronously preparing when the client called reset().
2683 // We handled the reset, the source is gone.
2684 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002685 }
Wei Jiad1864f92018-10-19 12:34:56 -07002686
2687 int32_t err;
2688 CHECK(msg->findInt32("err", &err));
2689
2690 if (err != OK) {
2691 // shut down potential secure codecs in case client never calls reset
2692 mDeferredActions.push_back(
2693 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2694 FLUSH_CMD_SHUTDOWN /* video */));
2695 processDeferredActions();
2696 } else {
2697 mPrepared = true;
2698 }
2699
2700 sp<NuPlayer2Driver> driver = mDriver.promote();
2701 if (driver != NULL) {
2702 // notify duration first, so that it's definitely set when
2703 // the app received the "prepare complete" callback.
2704 int64_t durationUs;
2705 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2706 driver->notifyDuration(srcId, durationUs);
2707 }
2708 driver->notifyPrepareCompleted(srcId, err);
2709 }
2710 } else if (srcId == mNextSourceInfo.mSrcId) {
2711 if (mNextSourceInfo.mSource == NULL) {
2712 break; // stale
2713 }
2714
2715 sp<NuPlayer2Driver> driver = mDriver.promote();
2716 if (driver != NULL) {
2717 int32_t err;
2718 CHECK(msg->findInt32("err", &err));
2719 driver->notifyPrepareCompleted(srcId, err);
2720 }
Wei Jia53692fa2017-12-11 10:33:46 -08002721 }
2722
2723 break;
2724 }
2725
2726 // Modular DRM
2727 case Source::kWhatDrmInfo:
2728 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002729 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002730 sp<ABuffer> drmInfo;
2731 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002732 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002733
Dongwon Kang41929fb2018-09-09 08:29:56 -07002734 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2735 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002736
Dongwon Kang41929fb2018-09-09 08:29:56 -07002737 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002738
2739 break;
2740 }
2741
2742 case Source::kWhatFlagsChanged:
2743 {
2744 uint32_t flags;
2745 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2746
2747 sp<NuPlayer2Driver> driver = mDriver.promote();
2748 if (driver != NULL) {
2749
2750 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2751 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2752 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2753 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2754 (flags & Source::FLAG_CAN_PAUSE) != 0,
2755 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2756 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2757 (flags & Source::FLAG_CAN_SEEK) != 0,
2758 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2759 (flags & Source::FLAG_SECURE) != 0,
2760 (flags & Source::FLAG_PROTECTED) != 0);
2761
2762 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2763 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002764 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002765 }
Wei Jiad1864f92018-10-19 12:34:56 -07002766 if (srcId == mCurrentSourceInfo.mSrcId) {
2767 driver->notifyFlagsChanged(srcId, flags);
2768 }
Wei Jia53692fa2017-12-11 10:33:46 -08002769 }
2770
Wei Jiaf01e3122018-10-18 11:49:44 -07002771 if (srcId == mCurrentSourceInfo.mSrcId) {
2772 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2773 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2774 cancelPollDuration();
2775 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2776 && (flags & Source::FLAG_DYNAMIC_DURATION)
2777 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2778 schedulePollDuration();
2779 }
Wei Jia53692fa2017-12-11 10:33:46 -08002780
Wei Jiaf01e3122018-10-18 11:49:44 -07002781 mCurrentSourceInfo.mSourceFlags = flags;
2782 } else if (srcId == mNextSourceInfo.mSrcId) {
2783 // TODO: handle duration polling for next source.
2784 mNextSourceInfo.mSourceFlags = flags;
2785 }
Wei Jia53692fa2017-12-11 10:33:46 -08002786 break;
2787 }
2788
2789 case Source::kWhatVideoSizeChanged:
2790 {
2791 sp<AMessage> format;
2792 CHECK(msg->findMessage("format", &format));
2793
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002794 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002795 break;
2796 }
2797
2798 case Source::kWhatBufferingUpdate:
2799 {
2800 int32_t percentage;
2801 CHECK(msg->findInt32("percentage", &percentage));
2802
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002803 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002804 break;
2805 }
2806
2807 case Source::kWhatPauseOnBufferingStart:
2808 {
2809 // ignore if not playing
2810 if (mStarted) {
2811 ALOGI("buffer low, pausing...");
2812
2813 startRebufferingTimer();
2814 mPausedForBuffering = true;
2815 onPause();
2816 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002817 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002818 break;
2819 }
2820
2821 case Source::kWhatResumeOnBufferingEnd:
2822 {
2823 // ignore if not playing
2824 if (mStarted) {
2825 ALOGI("buffer ready, resuming...");
2826
2827 stopRebufferingTimer(false);
2828 mPausedForBuffering = false;
2829
2830 // do not resume yet if client didn't unpause
2831 if (!mPausedByClient) {
2832 onResume();
2833 }
2834 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002835 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002836 break;
2837 }
2838
2839 case Source::kWhatCacheStats:
2840 {
2841 int32_t kbps;
2842 CHECK(msg->findInt32("bandwidth", &kbps));
2843
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002844 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002845 break;
2846 }
2847
2848 case Source::kWhatSubtitleData:
2849 {
2850 sp<ABuffer> buffer;
2851 CHECK(msg->findBuffer("buffer", &buffer));
2852
2853 sendSubtitleData(buffer, 0 /* baseIndex */);
2854 break;
2855 }
2856
2857 case Source::kWhatTimedMetaData:
2858 {
2859 sp<ABuffer> buffer;
2860 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002861 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002862 } else {
2863 sendTimedMetaData(buffer);
2864 }
2865 break;
2866 }
2867
2868 case Source::kWhatTimedTextData:
2869 {
2870 int32_t generation;
2871 if (msg->findInt32("generation", &generation)
2872 && generation != mTimedTextGeneration) {
2873 break;
2874 }
2875
2876 sp<ABuffer> buffer;
2877 CHECK(msg->findBuffer("buffer", &buffer));
2878
2879 sp<NuPlayer2Driver> driver = mDriver.promote();
2880 if (driver == NULL) {
2881 break;
2882 }
2883
Wei Jia800fe372018-02-20 15:00:45 -08002884 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002885 int64_t timeUs, posUs;
2886 driver->getCurrentPosition(&posMs);
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08002887 posUs = posMs * 1000LL;
Wei Jia53692fa2017-12-11 10:33:46 -08002888 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2889
2890 if (posUs < timeUs) {
2891 if (!msg->findInt32("generation", &generation)) {
2892 msg->setInt32("generation", mTimedTextGeneration);
2893 }
2894 msg->post(timeUs - posUs);
2895 } else {
2896 sendTimedTextData(buffer);
2897 }
2898 break;
2899 }
2900
2901 case Source::kWhatQueueDecoderShutdown:
2902 {
2903 int32_t audio, video;
2904 CHECK(msg->findInt32("audio", &audio));
2905 CHECK(msg->findInt32("video", &video));
2906
2907 sp<AMessage> reply;
2908 CHECK(msg->findMessage("reply", &reply));
2909
2910 queueDecoderShutdown(audio, video, reply);
2911 break;
2912 }
2913
2914 case Source::kWhatDrmNoLicense:
2915 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002916 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002917 break;
2918 }
2919
2920 default:
2921 TRESPASS();
2922 }
2923}
2924
2925void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2926 int32_t what;
2927 CHECK(msg->findInt32("what", &what));
2928
2929 switch (what) {
2930 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2931 {
2932 sp<ABuffer> buffer;
2933 CHECK(msg->findBuffer("buffer", &buffer));
2934
2935 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002936 if (mCurrentSourceInfo.mSource != NULL) {
2937 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002938 }
2939
2940 sendSubtitleData(buffer, inbandTracks);
2941 break;
2942 }
2943
2944 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2945 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002946 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002947
2948 break;
2949 }
2950
2951 default:
2952 TRESPASS();
2953 }
2954
2955
2956}
2957
2958void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2959 int32_t trackIndex;
2960 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002961 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002962 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2963 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2964
Dongwon Kang41929fb2018-09-09 08:29:56 -07002965 PlayerMessage playerMsg;
2966 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2967 playerMsg.add_values()->set_int64_value(timeUs);
2968 playerMsg.add_values()->set_int64_value(durationUs);
2969 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002970
Wei Jiaf01e3122018-10-18 11:49:44 -07002971 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002972}
2973
2974void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2975 int64_t timeUs;
2976 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2977
Dongwon Kang41929fb2018-09-09 08:29:56 -07002978 PlayerMessage playerMsg;
2979 playerMsg.add_values()->set_int64_value(timeUs);
2980 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002981
Wei Jiaf01e3122018-10-18 11:49:44 -07002982 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002983}
2984
2985void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2986 const void *data;
2987 size_t size = 0;
2988 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002989 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002990
2991 AString mime;
2992 CHECK(buffer->meta()->findString("mime", &mime));
2993 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2994
2995 data = buffer->data();
2996 size = buffer->size();
2997
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002998 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002999 if (size > 0) {
3000 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3001 int32_t global = 0;
3002 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003003 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003004 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003005 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003006 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003007 TextDescriptions2::getPlayerMessageOfDescriptions(
3008 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003009 }
3010
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003011 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003012 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003013 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003014 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003015 }
3016}
3017
3018const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003019 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003020 case DATA_SOURCE_TYPE_HTTP_LIVE:
3021 return "HTTPLive";
3022
3023 case DATA_SOURCE_TYPE_RTSP:
3024 return "RTSP";
3025
3026 case DATA_SOURCE_TYPE_GENERIC_URL:
3027 return "GenURL";
3028
3029 case DATA_SOURCE_TYPE_GENERIC_FD:
3030 return "GenFD";
3031
3032 case DATA_SOURCE_TYPE_MEDIA:
3033 return "Media";
3034
Wei Jia53692fa2017-12-11 10:33:46 -08003035 case DATA_SOURCE_TYPE_NONE:
3036 default:
3037 return "None";
3038 }
3039 }
3040
Robert Shihc3fca0e2018-12-04 17:08:04 -08003041NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
3042 int64_t srcId;
3043 CHECK(msg->findInt64("srcId", &srcId));
3044 if (mCurrentSourceInfo.mSrcId == srcId) {
3045 return &mCurrentSourceInfo;
3046 } else if (mNextSourceInfo.mSrcId == srcId) {
3047 return &mNextSourceInfo;
3048 } else {
3049 return NULL;
3050 }
3051}
3052
3053void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
3054 if (srcInfo.mSource != NULL) {
3055 srcInfo.mSource->stop();
3056
3057 Mutex::Autolock autoLock(mSourceLock);
3058 srcInfo.mSource.clear();
3059 }
3060 // Modular DRM
3061 ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
3062 srcInfo.mCrypto.clear();
3063 srcInfo.mIsDrmProtected = false;
3064}
3065
Wei Jia53692fa2017-12-11 10:33:46 -08003066// Modular DRM begin
Robert Shih3c3728d2018-12-04 17:06:36 -08003067status_t NuPlayer2::prepareDrm(
3068 int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
Wei Jia53692fa2017-12-11 10:33:46 -08003069{
3070 ALOGV("prepareDrm ");
3071
3072 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3073 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3074 // synchronous call so just passing the address but with local copies of "const" args
3075 uint8_t UUID[16];
3076 memcpy(UUID, uuid, sizeof(UUID));
3077 Vector<uint8_t> sessionId = drmSessionId;
Robert Shih3c3728d2018-12-04 17:06:36 -08003078 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003079 msg->setPointer("uuid", (void*)UUID);
3080 msg->setPointer("drmSessionId", (void*)&sessionId);
3081
3082 sp<AMessage> response;
3083 status_t status = msg->postAndAwaitResponse(&response);
3084
3085 if (status == OK && response != NULL) {
3086 CHECK(response->findInt32("status", &status));
3087 ALOGV("prepareDrm ret: %d ", status);
3088 } else {
3089 ALOGE("prepareDrm err: %d", status);
3090 }
3091
3092 return status;
3093}
3094
Robert Shih3c3728d2018-12-04 17:06:36 -08003095status_t NuPlayer2::releaseDrm(int64_t srcId)
Wei Jia53692fa2017-12-11 10:33:46 -08003096{
3097 ALOGV("releaseDrm ");
3098
3099 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
Robert Shih3c3728d2018-12-04 17:06:36 -08003100 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003101
3102 sp<AMessage> response;
3103 status_t status = msg->postAndAwaitResponse(&response);
3104
3105 if (status == OK && response != NULL) {
3106 CHECK(response->findInt32("status", &status));
3107 ALOGV("releaseDrm ret: %d ", status);
3108 } else {
3109 ALOGE("releaseDrm err: %d", status);
3110 }
3111
3112 return status;
3113}
3114
3115status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3116{
3117 // TODO change to ALOGV
3118 ALOGD("onPrepareDrm ");
3119
3120 status_t status = INVALID_OPERATION;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003121 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
3122 if (srcInfo == NULL) {
3123 return status;
3124 }
3125
3126 int64_t srcId = srcInfo->mSrcId;
3127 if (srcInfo->mSource == NULL) {
3128 ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
3129 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003130 return status;
3131 }
3132
3133 uint8_t *uuid;
3134 Vector<uint8_t> *drmSessionId;
3135 CHECK(msg->findPointer("uuid", (void**)&uuid));
3136 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3137
3138 status = OK;
3139 sp<AMediaCryptoWrapper> crypto = NULL;
3140
Robert Shihc3fca0e2018-12-04 17:08:04 -08003141 status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003142 if (crypto == NULL) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08003143 ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
3144 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003145 return status;
3146 }
Robert Shihc3fca0e2018-12-04 17:08:04 -08003147 ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003148
Robert Shihc3fca0e2018-12-04 17:08:04 -08003149 if (srcInfo->mCrypto != NULL) {
3150 ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
3151 (long long)srcId, srcInfo->mCrypto.get());
3152 srcInfo->mCrypto.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08003153 }
3154
Robert Shihc3fca0e2018-12-04 17:08:04 -08003155 srcInfo->mCrypto = crypto;
3156 srcInfo->mIsDrmProtected = true;
Wei Jia53692fa2017-12-11 10:33:46 -08003157 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003158 ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08003159
3160 return status;
3161}
3162
Robert Shihc3fca0e2018-12-04 17:08:04 -08003163status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
Wei Jia53692fa2017-12-11 10:33:46 -08003164{
3165 // TODO change to ALOGV
3166 ALOGD("onReleaseDrm ");
Robert Shihc3fca0e2018-12-04 17:08:04 -08003167 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
3168 if (srcInfo == NULL) {
3169 return INVALID_OPERATION;
Wei Jia53692fa2017-12-11 10:33:46 -08003170 }
3171
Robert Shihc3fca0e2018-12-04 17:08:04 -08003172 int64_t srcId = srcInfo->mSrcId;
3173 if (!srcInfo->mIsDrmProtected) {
3174 ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
3175 (long long)srcId);
3176 }
3177
3178 srcInfo->mIsDrmProtected = false;
Wei Jia53692fa2017-12-11 10:33:46 -08003179
3180 status_t status;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003181 if (srcInfo->mCrypto != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003182 // notifying the source first before removing crypto from codec
Robert Shihc3fca0e2018-12-04 17:08:04 -08003183 if (srcInfo->mSource != NULL) {
3184 srcInfo->mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003185 }
3186
3187 status=OK;
3188 // first making sure the codecs have released their crypto reference
3189 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3190 if (videoDecoder != NULL) {
3191 status = videoDecoder->releaseCrypto();
3192 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3193 }
3194
3195 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3196 if (audioDecoder != NULL) {
3197 status_t status_audio = audioDecoder->releaseCrypto();
3198 if (status == OK) { // otherwise, returning the first error
3199 status = status_audio;
3200 }
3201 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3202 }
3203
3204 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003205 ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
3206 srcInfo->mCrypto.clear();
3207 } else { // srcInfo->mCrypto == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08003208 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3209 status = INVALID_OPERATION;
3210 }
3211
3212 return status;
3213}
3214// Modular DRM end
3215////////////////////////////////////////////////////////////////////////////////
3216
3217sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3218 sp<MetaData> meta = getFormatMeta(audio);
3219
3220 if (meta == NULL) {
3221 return NULL;
3222 }
3223
3224 sp<AMessage> msg = new AMessage;
3225
3226 if(convertMetaDataToMessage(meta, &msg) == OK) {
3227 return msg;
3228 }
3229 return NULL;
3230}
3231
3232void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3233 sp<AMessage> notify = dupNotify();
3234 notify->setInt32("what", kWhatFlagsChanged);
3235 notify->setInt32("flags", flags);
3236 notify->post();
3237}
3238
3239void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3240 sp<AMessage> notify = dupNotify();
3241 notify->setInt32("what", kWhatVideoSizeChanged);
3242 notify->setMessage("format", format);
3243 notify->post();
3244}
3245
3246void NuPlayer2::Source::notifyPrepared(status_t err) {
3247 ALOGV("Source::notifyPrepared %d", err);
3248 sp<AMessage> notify = dupNotify();
3249 notify->setInt32("what", kWhatPrepared);
3250 notify->setInt32("err", err);
3251 notify->post();
3252}
3253
3254void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3255{
3256 ALOGV("Source::notifyDrmInfo");
3257
3258 sp<AMessage> notify = dupNotify();
3259 notify->setInt32("what", kWhatDrmInfo);
3260 notify->setBuffer("drmInfo", drmInfoBuffer);
3261
3262 notify->post();
3263}
3264
Wei Jia53692fa2017-12-11 10:33:46 -08003265void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3266 TRESPASS();
3267}
3268
Wei Jiaf01e3122018-10-18 11:49:44 -07003269NuPlayer2::SourceInfo::SourceInfo()
3270 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3271 mSrcId(0),
3272 mSourceFlags(0),
3273 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003274 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003275}
3276
Wei Jiad1864f92018-10-19 12:34:56 -07003277NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3278 mSource = other.mSource;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003279 mCrypto = other.mCrypto;
Wei Jiad1864f92018-10-19 12:34:56 -07003280 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3281 mSrcId = other.mSrcId;
3282 mSourceFlags = other.mSourceFlags;
3283 mStartTimeUs = other.mStartTimeUs;
3284 mEndTimeUs = other.mEndTimeUs;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003285 mIsDrmProtected = other.mIsDrmProtected;
Wei Jiad1864f92018-10-19 12:34:56 -07003286 return *this;
3287}
3288
Wei Jia53692fa2017-12-11 10:33:46 -08003289} // namespace android