blob: 5da6e2496a73d26ae3edf29d540ffe673a50ce89 [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
Dichen Zhangfc9f40f2019-01-04 14:15:28 -0800212NuPlayer2::NuPlayer2(
213 pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context)
Wei Jia003fdb52018-02-06 14:44:32 -0800214 : mPID(pid),
215 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800216 mMediaClock(mediaClock),
Wei Jia53692fa2017-12-11 10:33:46 -0800217 mOffloadAudio(false),
218 mAudioDecoderGeneration(0),
219 mVideoDecoderGeneration(0),
220 mRendererGeneration(0),
Wei Jiad1864f92018-10-19 12:34:56 -0700221 mEOSMonitorGeneration(0),
Wei Jia53692fa2017-12-11 10:33:46 -0800222 mLastStartedPlayingTimeNs(0),
223 mPreviousSeekTimeUs(0),
224 mAudioEOS(false),
225 mVideoEOS(false),
226 mScanSourcesPending(false),
227 mScanSourcesGeneration(0),
228 mPollDurationGeneration(0),
229 mTimedTextGeneration(0),
230 mFlushingAudio(NONE),
231 mFlushingVideo(NONE),
232 mResumePending(false),
233 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
234 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
235 mVideoFpsHint(-1.f),
236 mStarted(false),
237 mPrepared(false),
238 mResetting(false),
239 mSourceStarted(false),
240 mAudioDecoderError(false),
241 mVideoDecoderError(false),
242 mPaused(false),
243 mPausedByClient(true),
Dichen Zhangfc9f40f2019-01-04 14:15:28 -0800244 mPausedForBuffering(false),
245 mContext(context) {
Wei Jia53692fa2017-12-11 10:33:46 -0800246 CHECK(mediaClock != NULL);
247 clearFlushComplete();
248}
249
250NuPlayer2::~NuPlayer2() {
251}
252
Wei Jia53692fa2017-12-11 10:33:46 -0800253void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
254 mDriver = driver;
255}
256
Wei Jia53692fa2017-12-11 10:33:46 -0800257static bool IsHTTPLiveURL(const char *url) {
258 if (!strncasecmp("http://", url, 7)
259 || !strncasecmp("https://", url, 8)
260 || !strncasecmp("file://", url, 7)) {
261 size_t len = strlen(url);
262 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
263 return true;
264 }
265
266 if (strstr(url,"m3u8")) {
267 return true;
268 }
269 }
270
271 return false;
272}
273
Wei Jia72bf2a02018-02-06 15:29:23 -0800274status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
275 sp<Source> *source,
276 DATA_SOURCE_TYPE *dataSourceType) {
277 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800278 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800279 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800280
Wei Jiac2636032018-02-01 09:15:25 -0800281 switch (dsd->mType) {
282 case DataSourceDesc::TYPE_URL:
283 {
284 const char *url = dsd->mUrl.c_str();
285 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800286
Wei Jiac2636032018-02-01 09:15:25 -0800287 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
288 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800289
Wei Jiac2636032018-02-01 09:15:25 -0800290 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800291 *source = new HTTPLiveSource2(notify, httpService, url, headers);
292 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
293 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800294 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800295 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800296 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800297 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
298 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800299 } else if ((!strncasecmp(url, "http://", 7)
300 || !strncasecmp(url, "https://", 8))
301 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
302 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800303 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800304 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800305 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
306 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800307 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800308 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800309
Wei Jia2409c872018-02-02 10:34:33 -0800310 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800311 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800312
Robert Shih49fb89d2018-01-31 17:53:19 -0800313 err = genericSource->setDataSource(url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800314
315 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800316 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800317 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800318 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800319 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800320 }
321
322 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800323 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800324 }
325 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800326 }
327
Wei Jiac2636032018-02-01 09:15:25 -0800328 case DataSourceDesc::TYPE_FD:
329 {
Wei Jia2409c872018-02-02 10:34:33 -0800330 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800331 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800332
Wei Jia72bf2a02018-02-06 15:29:23 -0800333 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
334 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
335 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800336
Wei Jia72bf2a02018-02-06 15:29:23 -0800337 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800338
Wei Jiac2636032018-02-01 09:15:25 -0800339 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800340 ALOGE("Failed to create NuPlayer2Source!");
341 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800342 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800343 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800344 }
Wei Jia53692fa2017-12-11 10:33:46 -0800345
Wei Jia72bf2a02018-02-06 15:29:23 -0800346 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800347 break;
348 }
Wei Jia53692fa2017-12-11 10:33:46 -0800349
Wei Jiac2636032018-02-01 09:15:25 -0800350 case DataSourceDesc::TYPE_CALLBACK:
351 {
Wei Jia2409c872018-02-02 10:34:33 -0800352 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800353 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800354 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800355
Wei Jiac2636032018-02-01 09:15:25 -0800356 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800357 ALOGE("Failed to create NuPlayer2Source!");
358 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800359 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800360 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800361 }
362
Wei Jia72bf2a02018-02-06 15:29:23 -0800363 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800364 break;
365 }
366
367 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800368 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800369 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800370 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800371 ALOGE("invalid data source type!");
372 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800373 }
374
Wei Jia72bf2a02018-02-06 15:29:23 -0800375 return err;
376}
377
378void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
379 DATA_SOURCE_TYPE dataSourceType;
380 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800381 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800382
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800383 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
384 // and expects notifySetDataSourceCompleted regardless of success or failure.
385 // This will be changed since setDataSource should be asynchronous at JAVA level.
386 // When it succeeds, app will get onInfo notification. Otherwise, onError
387 // will be called.
388 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800389 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800390 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800391 return;
392 }
393
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800394 // Now, source != NULL.
395 */
396
Wei Jiaf01e3122018-10-18 11:49:44 -0700397 mCurrentSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800398
399 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800400 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800401 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700402 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
403 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia72bf2a02018-02-06 15:29:23 -0800404 msg->post();
405}
406
407void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
408 DATA_SOURCE_TYPE dataSourceType;
409 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800410 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800411
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800412 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800413 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800414 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800415 return;
416 }
417
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800418 // Now, source != NULL.
419 */
420
Wei Jiaf01e3122018-10-18 11:49:44 -0700421 mNextSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800422
423 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
424 msg->setObject("source", source);
425 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700426 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
427 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia53692fa2017-12-11 10:33:46 -0800428 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800429}
430
Wei Jia57aeffd2018-02-15 16:01:14 -0800431void NuPlayer2::playNextDataSource(int64_t srcId) {
432 disconnectSource();
433
434 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
435 msg->setInt64("srcId", srcId);
436 msg->post();
437}
438
Wei Jia53692fa2017-12-11 10:33:46 -0800439status_t NuPlayer2::getBufferingSettings(
440 BufferingSettings *buffering /* nonnull */) {
441 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
442 sp<AMessage> response;
443 status_t err = msg->postAndAwaitResponse(&response);
444 if (err == OK && response != NULL) {
445 CHECK(response->findInt32("err", &err));
446 if (err == OK) {
447 readFromAMessage(response, buffering);
448 }
449 }
450 return err;
451}
452
453status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
454 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
455 writeToAMessage(msg, buffering);
456 sp<AMessage> response;
457 status_t err = msg->postAndAwaitResponse(&response);
458 if (err == OK && response != NULL) {
459 CHECK(response->findInt32("err", &err));
460 }
461 return err;
462}
463
464void NuPlayer2::prepareAsync() {
465 ALOGV("prepareAsync");
466
467 (new AMessage(kWhatPrepare, this))->post();
468}
469
Wei Jia28288fb2017-12-15 13:45:29 -0800470void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800471 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
472
Wei Jia28288fb2017-12-15 13:45:29 -0800473 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800474 msg->setObject("surface", NULL);
475 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800476 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800477 }
478
479 msg->post();
480}
481
Wei Jia33abcc72018-01-30 09:47:38 -0800482void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800483 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
484 msg->setObject("sink", sink);
485 msg->post();
486}
487
488void NuPlayer2::start() {
489 (new AMessage(kWhatStart, this))->post();
490}
491
492status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
493 // do some cursory validation of the settings here. audio modes are
494 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700495 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800496 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
497 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
498 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
499 return BAD_VALUE;
500 }
501 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
502 writeToAMessage(msg, rate);
503 sp<AMessage> response;
504 status_t err = msg->postAndAwaitResponse(&response);
505 if (err == OK && response != NULL) {
506 CHECK(response->findInt32("err", &err));
507 }
508 return err;
509}
510
511status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
512 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
513 sp<AMessage> response;
514 status_t err = msg->postAndAwaitResponse(&response);
515 if (err == OK && response != NULL) {
516 CHECK(response->findInt32("err", &err));
517 if (err == OK) {
518 readFromAMessage(response, rate);
519 }
520 }
521 return err;
522}
523
524status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
525 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
526 writeToAMessage(msg, sync, videoFpsHint);
527 sp<AMessage> response;
528 status_t err = msg->postAndAwaitResponse(&response);
529 if (err == OK && response != NULL) {
530 CHECK(response->findInt32("err", &err));
531 }
532 return err;
533}
534
535status_t NuPlayer2::getSyncSettings(
536 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
537 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
538 sp<AMessage> response;
539 status_t err = msg->postAndAwaitResponse(&response);
540 if (err == OK && response != NULL) {
541 CHECK(response->findInt32("err", &err));
542 if (err == OK) {
543 readFromAMessage(response, sync, videoFps);
544 }
545 }
546 return err;
547}
548
549void NuPlayer2::pause() {
550 (new AMessage(kWhatPause, this))->post();
551}
552
553void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800554 disconnectSource();
555 (new AMessage(kWhatReset, this))->post();
556}
557
558void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800559 sp<Source> source;
560 {
561 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700562 source = mCurrentSourceInfo.mSource;
Wei Jia53692fa2017-12-11 10:33:46 -0800563 }
564
565 if (source != NULL) {
566 // During a reset, the data source might be unresponsive already, we need to
567 // disconnect explicitly so that reads exit promptly.
568 // We can't queue the disconnect request to the looper, as it might be
569 // queued behind a stuck read and never gets processed.
570 // Doing a disconnect outside the looper to allows the pending reads to exit
571 // (either successfully or with error).
572 source->disconnect();
573 }
574
Wei Jia53692fa2017-12-11 10:33:46 -0800575}
576
577status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
578 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
579 notify->setInt64("timerUs", mediaTimeUs);
580 mMediaClock->addTimer(notify, mediaTimeUs);
581 return OK;
582}
583
584void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
585 sp<AMessage> msg = new AMessage(kWhatSeek, this);
586 msg->setInt64("seekTimeUs", seekTimeUs);
587 msg->setInt32("mode", mode);
588 msg->setInt32("needNotify", needNotify);
589 msg->post();
590}
591
Wei Jiad1864f92018-10-19 12:34:56 -0700592void NuPlayer2::rewind() {
593 sp<AMessage> msg = new AMessage(kWhatRewind, this);
594 msg->post();
595}
596
Wei Jia53692fa2017-12-11 10:33:46 -0800597void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700598 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800599 if (format == NULL) {
600 ALOGE("NULL format");
601 return;
602 }
603 int32_t trackType;
604 if (!format->findInt32("type", &trackType)) {
605 ALOGE("no track type");
606 return;
607 }
608
609 AString mime;
610 if (!format->findString("mime", &mime)) {
611 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
612 // If we can't find the mimetype here it means that we wouldn't be needing
613 // the mimetype on the Java end. We still write a placeholder mime to keep the
614 // (de)serialization logic simple.
615 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
616 mime = "audio/";
617 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
618 mime = "video/";
619 } else {
620 ALOGE("unknown track type: %d", trackType);
621 return;
622 }
623 }
624
625 AString lang;
626 if (!format->findString("language", &lang)) {
627 ALOGE("no language");
628 return;
629 }
630
Dongwon Kang9f631982018-07-10 12:34:41 -0700631 reply->add_values()->set_int32_value(trackType);
632 reply->add_values()->set_string_value(mime.c_str());
633 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800634
635 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
636 int32_t isAuto, isDefault, isForced;
637 CHECK(format->findInt32("auto", &isAuto));
638 CHECK(format->findInt32("default", &isDefault));
639 CHECK(format->findInt32("forced", &isForced));
640
Dongwon Kang9f631982018-07-10 12:34:41 -0700641 reply->add_values()->set_int32_value(isAuto);
642 reply->add_values()->set_int32_value(isDefault);
643 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800644 }
645}
646
647void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
Dichen Zhangf8726912018-10-17 13:31:26 -0700648
Wei Jia53692fa2017-12-11 10:33:46 -0800649 switch (msg->what()) {
650 case kWhatSetDataSource:
651 {
652 ALOGV("kWhatSetDataSource");
653
Wei Jiaf01e3122018-10-18 11:49:44 -0700654 CHECK(mCurrentSourceInfo.mSource == NULL);
Wei Jia53692fa2017-12-11 10:33:46 -0800655
656 status_t err = OK;
657 sp<RefBase> obj;
658 CHECK(msg->findObject("source", &obj));
659 if (obj != NULL) {
660 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700661 CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
662 CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
663 CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
664 mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800665 } else {
666 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800667 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800668 }
669
670 CHECK(mDriver != NULL);
671 sp<NuPlayer2Driver> driver = mDriver.promote();
672 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700673 driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800674 }
675 break;
676 }
677
Wei Jia72bf2a02018-02-06 15:29:23 -0800678 case kWhatPrepareNextDataSource:
679 {
680 ALOGV("kWhatPrepareNextDataSource");
681
682 status_t err = OK;
683 sp<RefBase> obj;
684 CHECK(msg->findObject("source", &obj));
685 if (obj != NULL) {
686 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700687 CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
688 CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
689 CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
690 mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
691 mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
Wei Jia72bf2a02018-02-06 15:29:23 -0800692 } else {
693 err = UNKNOWN_ERROR;
694 }
695
696 break;
697 }
698
Wei Jia57aeffd2018-02-15 16:01:14 -0800699 case kWhatPlayNextDataSource:
700 {
701 ALOGV("kWhatPlayNextDataSource");
702 int64_t srcId;
703 CHECK(msg->findInt64("srcId", &srcId));
Wei Jiaf01e3122018-10-18 11:49:44 -0700704 if (srcId != mNextSourceInfo.mSrcId) {
Wei Jia57aeffd2018-02-15 16:01:14 -0800705 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
706 return;
707 }
708
709 mResetting = true;
710 stopPlaybackTimer("kWhatPlayNextDataSource");
711 stopRebufferingTimer(true);
712
713 mDeferredActions.push_back(
714 new FlushDecoderAction(
715 FLUSH_CMD_SHUTDOWN /* audio */,
716 FLUSH_CMD_SHUTDOWN /* video */));
717
718 mDeferredActions.push_back(
719 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
720
721 processDeferredActions();
722 break;
723 }
724
Wei Jiad1864f92018-10-19 12:34:56 -0700725 case kWhatEOSMonitor:
726 {
727 int32_t generation;
728 CHECK(msg->findInt32("generation", &generation));
729 int32_t reason;
730 CHECK(msg->findInt32("reason", &reason));
731
732 if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
733 break; // stale or reset
734 }
735
736 ALOGV("kWhatEOSMonitor");
737 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
738 break;
739 }
740
Wei Jia53692fa2017-12-11 10:33:46 -0800741 case kWhatGetBufferingSettings:
742 {
743 sp<AReplyToken> replyID;
744 CHECK(msg->senderAwaitsResponse(&replyID));
745
746 ALOGV("kWhatGetBufferingSettings");
747 BufferingSettings buffering;
748 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700749 if (mCurrentSourceInfo.mSource != NULL) {
750 err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800751 } else {
752 err = INVALID_OPERATION;
753 }
754 sp<AMessage> response = new AMessage;
755 if (err == OK) {
756 writeToAMessage(response, buffering);
757 }
758 response->setInt32("err", err);
759 response->postReply(replyID);
760 break;
761 }
762
763 case kWhatSetBufferingSettings:
764 {
765 sp<AReplyToken> replyID;
766 CHECK(msg->senderAwaitsResponse(&replyID));
767
768 ALOGV("kWhatSetBufferingSettings");
769 BufferingSettings buffering;
770 readFromAMessage(msg, &buffering);
771 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700772 if (mCurrentSourceInfo.mSource != NULL) {
773 err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800774 } else {
775 err = INVALID_OPERATION;
776 }
777 sp<AMessage> response = new AMessage;
778 response->setInt32("err", err);
779 response->postReply(replyID);
780 break;
781 }
782
783 case kWhatPrepare:
784 {
785 ALOGV("onMessageReceived kWhatPrepare");
786
Wei Jiaf01e3122018-10-18 11:49:44 -0700787 mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800788 break;
789 }
790
791 case kWhatGetTrackInfo:
792 {
793 sp<AReplyToken> replyID;
794 CHECK(msg->senderAwaitsResponse(&replyID));
795
Wei Jia17944af2018-12-13 18:13:10 -0800796 int64_t srcId;
797 CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
798
Dongwon Kang9f631982018-07-10 12:34:41 -0700799 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800800 CHECK(msg->findPointer("reply", (void**)&reply));
801
Wei Jia17944af2018-12-13 18:13:10 -0800802 // TODO: use correct source info based on srcId.
Wei Jia53692fa2017-12-11 10:33:46 -0800803 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700804 if (mCurrentSourceInfo.mSource != NULL) {
805 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800806 }
807
808 size_t ccTracks = 0;
809 if (mCCDecoder != NULL) {
810 ccTracks = mCCDecoder->getTrackCount();
811 }
812
813 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700814 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800815
816 // write inband tracks
817 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700818 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800819 }
820
821 // write CC track
822 for (size_t i = 0; i < ccTracks; ++i) {
823 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
824 }
825
826 sp<AMessage> response = new AMessage;
827 response->postReply(replyID);
828 break;
829 }
830
831 case kWhatGetSelectedTrack:
832 {
Wei Jia17944af2018-12-13 18:13:10 -0800833 int64_t srcId;
834 CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
835
Wei Jia039224f2018-11-29 17:25:17 -0800836 int32_t type32;
837 CHECK(msg->findInt32("type", (int32_t*)&type32));
838 media_track_type type = (media_track_type)type32;
839
Wei Jia17944af2018-12-13 18:13:10 -0800840 // TODO: use correct source info based on srcId.
Wei Jia039224f2018-11-29 17:25:17 -0800841 size_t inbandTracks = 0;
Wei Jia53692fa2017-12-11 10:33:46 -0800842 status_t err = INVALID_OPERATION;
Wei Jia039224f2018-11-29 17:25:17 -0800843 ssize_t selectedTrack = -1;
Wei Jiaf01e3122018-10-18 11:49:44 -0700844 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800845 err = OK;
Wei Jia039224f2018-11-29 17:25:17 -0800846 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
847 selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800848 }
849
Wei Jia039224f2018-11-29 17:25:17 -0800850 if (selectedTrack == -1 && mCCDecoder != NULL) {
851 err = OK;
852 selectedTrack = mCCDecoder->getSelectedTrack(type);
853 if (selectedTrack != -1) {
854 selectedTrack += inbandTracks;
855 }
856 }
857
858 PlayerMessage* reply;
859 CHECK(msg->findPointer("reply", (void**)&reply));
860 reply->add_values()->set_int32_value(selectedTrack);
861
Wei Jia53692fa2017-12-11 10:33:46 -0800862 sp<AMessage> response = new AMessage;
863 response->setInt32("err", err);
864
865 sp<AReplyToken> replyID;
866 CHECK(msg->senderAwaitsResponse(&replyID));
867 response->postReply(replyID);
868 break;
869 }
870
871 case kWhatSelectTrack:
872 {
873 sp<AReplyToken> replyID;
874 CHECK(msg->senderAwaitsResponse(&replyID));
875
Wei Jia17944af2018-12-13 18:13:10 -0800876 int64_t srcId;
Wei Jia53692fa2017-12-11 10:33:46 -0800877 size_t trackIndex;
878 int32_t select;
879 int64_t timeUs;
Wei Jia17944af2018-12-13 18:13:10 -0800880 CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
Wei Jia53692fa2017-12-11 10:33:46 -0800881 CHECK(msg->findSize("trackIndex", &trackIndex));
882 CHECK(msg->findInt32("select", &select));
883 CHECK(msg->findInt64("timeUs", &timeUs));
884
885 status_t err = INVALID_OPERATION;
886
Wei Jia17944af2018-12-13 18:13:10 -0800887 // TODO: use correct source info based on srcId.
Wei Jia53692fa2017-12-11 10:33:46 -0800888 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700889 if (mCurrentSourceInfo.mSource != NULL) {
890 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800891 }
892 size_t ccTracks = 0;
893 if (mCCDecoder != NULL) {
894 ccTracks = mCCDecoder->getTrackCount();
895 }
896
897 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700898 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800899
900 if (!select && err == OK) {
901 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700902 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800903 if (info != NULL
904 && info->findInt32("type", &type)
905 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
906 ++mTimedTextGeneration;
907 }
908 }
909 } else {
910 trackIndex -= inbandTracks;
911
912 if (trackIndex < ccTracks) {
913 err = mCCDecoder->selectTrack(trackIndex, select);
914 }
915 }
916
917 sp<AMessage> response = new AMessage;
918 response->setInt32("err", err);
919
920 response->postReply(replyID);
921 break;
922 }
923
924 case kWhatPollDuration:
925 {
926 int32_t generation;
927 CHECK(msg->findInt32("generation", &generation));
928
929 if (generation != mPollDurationGeneration) {
930 // stale
931 break;
932 }
933
934 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700935 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800936 sp<NuPlayer2Driver> driver = mDriver.promote();
937 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700938 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800939 }
940 }
941
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -0800942 msg->post(1000000LL); // poll again in a second.
Wei Jia53692fa2017-12-11 10:33:46 -0800943 break;
944 }
945
946 case kWhatSetVideoSurface:
947 {
948
949 sp<RefBase> obj;
950 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800951 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800952
953 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800954 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700955 (mCurrentSourceInfo.mSource != NULL && mStarted
956 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800957 && mVideoDecoder != NULL) ? "have" : "no");
958
Wei Jiaf01e3122018-10-18 11:49:44 -0700959 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
960 // because NuPlayer2 might be in preparing state and it could take long time.
961 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
962 if (mCurrentSourceInfo.mSource == NULL || !mStarted
963 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800964 // NOTE: mVideoDecoder's mNativeWindow is always non-null
965 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
966 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800967 break;
968 }
969
970 mDeferredActions.push_back(
971 new FlushDecoderAction(
972 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
973 FLUSH_CMD_SHUTDOWN /* video */));
974
Wei Jia28288fb2017-12-15 13:45:29 -0800975 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800976
977 if (obj != NULL) {
978 if (mStarted) {
979 // Issue a seek to refresh the video screen only if started otherwise
980 // the extractor may not yet be started and will assert.
981 // If the video decoder is not set (perhaps audio only in this case)
982 // do not perform a seek as it is not needed.
983 int64_t currentPositionUs = 0;
984 if (getCurrentPosition(&currentPositionUs) == OK) {
985 mDeferredActions.push_back(
986 new SeekAction(currentPositionUs,
987 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
988 }
989 }
990
991 // If there is a new surface texture, instantiate decoders
992 // again if possible.
993 mDeferredActions.push_back(
994 new SimpleAction(&NuPlayer2::performScanSources));
995
996 // After a flush without shutdown, decoder is paused.
997 // Don't resume it until source seek is done, otherwise it could
998 // start pulling stale data too soon.
999 mDeferredActions.push_back(
1000 new ResumeDecoderAction(false /* needNotify */));
1001 }
1002
1003 processDeferredActions();
1004 break;
1005 }
1006
1007 case kWhatSetAudioSink:
1008 {
1009 ALOGV("kWhatSetAudioSink");
1010
1011 sp<RefBase> obj;
1012 CHECK(msg->findObject("sink", &obj));
1013
Wei Jia33abcc72018-01-30 09:47:38 -08001014 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001015 break;
1016 }
1017
1018 case kWhatStart:
1019 {
1020 ALOGV("kWhatStart");
1021 if (mStarted) {
1022 // do not resume yet if the source is still buffering
1023 if (!mPausedForBuffering) {
1024 onResume();
1025 }
1026 } else {
Wei Jia6376cd52018-09-26 11:42:55 -07001027 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -08001028 }
1029 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001030 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001031 break;
1032 }
1033
1034 case kWhatConfigPlayback:
1035 {
1036 sp<AReplyToken> replyID;
1037 CHECK(msg->senderAwaitsResponse(&replyID));
1038 AudioPlaybackRate rate /* sanitized */;
1039 readFromAMessage(msg, &rate);
1040 status_t err = OK;
1041 if (mRenderer != NULL) {
1042 // AudioSink allows only 1.f and 0.f for offload mode.
1043 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -07001044 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -08001045 int64_t currentPositionUs;
1046 if (getCurrentPosition(&currentPositionUs) != OK) {
1047 currentPositionUs = mPreviousSeekTimeUs;
1048 }
1049
1050 // Set mPlaybackSettings so that the new audio decoder can
1051 // be created correctly.
1052 mPlaybackSettings = rate;
1053 if (!mPaused) {
1054 mRenderer->pause();
1055 }
1056 restartAudio(
1057 currentPositionUs, true /* forceNonOffload */,
1058 true /* needsToCreateAudioDecoder */);
1059 if (!mPaused) {
1060 mRenderer->resume();
1061 }
1062 }
1063
1064 err = mRenderer->setPlaybackSettings(rate);
1065 }
1066 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001067 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001068
Wei Jia700a7c22018-09-14 18:04:35 -07001069 if (mVideoDecoder != NULL) {
1070 sp<AMessage> params = new AMessage();
1071 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1072 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001073 }
1074 }
1075
Wei Jia53692fa2017-12-11 10:33:46 -08001076 sp<AMessage> response = new AMessage;
1077 response->setInt32("err", err);
1078 response->postReply(replyID);
1079 break;
1080 }
1081
1082 case kWhatGetPlaybackSettings:
1083 {
1084 sp<AReplyToken> replyID;
1085 CHECK(msg->senderAwaitsResponse(&replyID));
1086 AudioPlaybackRate rate = mPlaybackSettings;
1087 status_t err = OK;
1088 if (mRenderer != NULL) {
1089 err = mRenderer->getPlaybackSettings(&rate);
1090 }
1091 if (err == OK) {
1092 // get playback settings used by renderer, as it may be
1093 // slightly off due to audiosink not taking small changes.
1094 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001095 }
1096 sp<AMessage> response = new AMessage;
1097 if (err == OK) {
1098 writeToAMessage(response, rate);
1099 }
1100 response->setInt32("err", err);
1101 response->postReply(replyID);
1102 break;
1103 }
1104
1105 case kWhatConfigSync:
1106 {
1107 sp<AReplyToken> replyID;
1108 CHECK(msg->senderAwaitsResponse(&replyID));
1109
1110 ALOGV("kWhatConfigSync");
1111 AVSyncSettings sync;
1112 float videoFpsHint;
1113 readFromAMessage(msg, &sync, &videoFpsHint);
1114 status_t err = OK;
1115 if (mRenderer != NULL) {
1116 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1117 }
1118 if (err == OK) {
1119 mSyncSettings = sync;
1120 mVideoFpsHint = videoFpsHint;
1121 }
1122 sp<AMessage> response = new AMessage;
1123 response->setInt32("err", err);
1124 response->postReply(replyID);
1125 break;
1126 }
1127
1128 case kWhatGetSyncSettings:
1129 {
1130 sp<AReplyToken> replyID;
1131 CHECK(msg->senderAwaitsResponse(&replyID));
1132 AVSyncSettings sync = mSyncSettings;
1133 float videoFps = mVideoFpsHint;
1134 status_t err = OK;
1135 if (mRenderer != NULL) {
1136 err = mRenderer->getSyncSettings(&sync, &videoFps);
1137 if (err == OK) {
1138 mSyncSettings = sync;
1139 mVideoFpsHint = videoFps;
1140 }
1141 }
1142 sp<AMessage> response = new AMessage;
1143 if (err == OK) {
1144 writeToAMessage(response, sync, videoFps);
1145 }
1146 response->setInt32("err", err);
1147 response->postReply(replyID);
1148 break;
1149 }
1150
1151 case kWhatScanSources:
1152 {
1153 int32_t generation;
1154 CHECK(msg->findInt32("generation", &generation));
1155 if (generation != mScanSourcesGeneration) {
1156 // Drop obsolete msg.
1157 break;
1158 }
1159
1160 mScanSourcesPending = false;
1161
1162 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1163 mAudioDecoder != NULL, mVideoDecoder != NULL);
1164
1165 bool mHadAnySourcesBefore =
1166 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1167 bool rescan = false;
1168
1169 // initialize video before audio because successful initialization of
1170 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001171 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001172 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1173 rescan = true;
1174 }
1175 }
1176
1177 // Don't try to re-open audio sink if there's an existing decoder.
1178 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1179 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1180 rescan = true;
1181 }
1182 }
1183
1184 if (!mHadAnySourcesBefore
1185 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1186 // This is the first time we've found anything playable.
1187
Wei Jiaf01e3122018-10-18 11:49:44 -07001188 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001189 schedulePollDuration();
1190 }
1191 }
1192
1193 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001194 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001195 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1196 // We're not currently decoding anything (no audio or
1197 // video tracks found) and we just ran out of input data.
1198
1199 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001200 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001201 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001202 notifyListener(
1203 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001204 }
1205 }
1206 break;
1207 }
1208
1209 if (rescan) {
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08001210 msg->post(100000LL);
Wei Jia53692fa2017-12-11 10:33:46 -08001211 mScanSourcesPending = true;
1212 }
1213 break;
1214 }
1215
1216 case kWhatVideoNotify:
1217 case kWhatAudioNotify:
1218 {
1219 bool audio = msg->what() == kWhatAudioNotify;
1220
1221 int32_t currentDecoderGeneration =
1222 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1223 int32_t requesterGeneration = currentDecoderGeneration - 1;
1224 CHECK(msg->findInt32("generation", &requesterGeneration));
1225
1226 if (requesterGeneration != currentDecoderGeneration) {
1227 ALOGV("got message from old %s decoder, generation(%d:%d)",
1228 audio ? "audio" : "video", requesterGeneration,
1229 currentDecoderGeneration);
1230 sp<AMessage> reply;
1231 if (!(msg->findMessage("reply", &reply))) {
1232 return;
1233 }
1234
1235 reply->setInt32("err", INFO_DISCONTINUITY);
1236 reply->post();
1237 return;
1238 }
1239
1240 int32_t what;
1241 CHECK(msg->findInt32("what", &what));
1242
1243 if (what == DecoderBase::kWhatInputDiscontinuity) {
1244 int32_t formatChange;
1245 CHECK(msg->findInt32("formatChange", &formatChange));
1246
1247 ALOGV("%s discontinuity: formatChange %d",
1248 audio ? "audio" : "video", formatChange);
1249
1250 if (formatChange) {
1251 mDeferredActions.push_back(
1252 new FlushDecoderAction(
1253 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1254 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1255 }
1256
1257 mDeferredActions.push_back(
1258 new SimpleAction(
1259 &NuPlayer2::performScanSources));
1260
1261 processDeferredActions();
1262 } else if (what == DecoderBase::kWhatEOS) {
1263 int32_t err;
1264 CHECK(msg->findInt32("err", &err));
1265
1266 if (err == ERROR_END_OF_STREAM) {
1267 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1268 } else {
1269 ALOGV("got %s decoder EOS w/ error %d",
1270 audio ? "audio" : "video",
1271 err);
1272 }
1273
1274 mRenderer->queueEOS(audio, err);
1275 } else if (what == DecoderBase::kWhatFlushCompleted) {
1276 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1277
1278 handleFlushComplete(audio, true /* isDecoder */);
1279 finishFlushIfPossible();
1280 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1281 sp<AMessage> format;
1282 CHECK(msg->findMessage("format", &format));
1283
1284 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001285 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001286
1287 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001288 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001289 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1290 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1291 if (audio) {
1292 mAudioDecoder.clear();
1293 mAudioDecoderError = false;
1294 ++mAudioDecoderGeneration;
1295
1296 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1297 mFlushingAudio = SHUT_DOWN;
1298 } else {
1299 mVideoDecoder.clear();
1300 mVideoDecoderError = false;
1301 ++mVideoDecoderGeneration;
1302
1303 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1304 mFlushingVideo = SHUT_DOWN;
1305 }
1306
1307 finishFlushIfPossible();
1308 } else if (what == DecoderBase::kWhatResumeCompleted) {
1309 finishResume();
1310 } else if (what == DecoderBase::kWhatError) {
1311 status_t err;
1312 if (!msg->findInt32("err", &err) || err == OK) {
1313 err = UNKNOWN_ERROR;
1314 }
1315
1316 // Decoder errors can be due to Source (e.g. from streaming),
1317 // or from decoding corrupted bitstreams, or from other decoder
1318 // MediaCodec operations (e.g. from an ongoing reset or seek).
1319 // They may also be due to openAudioSink failure at
1320 // decoder start or after a format change.
1321 //
1322 // We try to gracefully shut down the affected decoder if possible,
1323 // rather than trying to force the shutdown with something
1324 // similar to performReset(). This method can lead to a hang
1325 // if MediaCodec functions block after an error, but they should
1326 // typically return INVALID_OPERATION instead of blocking.
1327
1328 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1329 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1330 err, audio ? "audio" : "video", *flushing);
1331
1332 switch (*flushing) {
1333 case NONE:
1334 mDeferredActions.push_back(
1335 new FlushDecoderAction(
1336 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1337 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1338 processDeferredActions();
1339 break;
1340 case FLUSHING_DECODER:
1341 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1342 break; // Wait for flush to complete.
1343 case FLUSHING_DECODER_SHUTDOWN:
1344 break; // Wait for flush to complete.
1345 case SHUTTING_DOWN_DECODER:
1346 break; // Wait for shutdown to complete.
1347 case FLUSHED:
1348 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1349 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1350 break;
1351 case SHUT_DOWN:
1352 finishFlushIfPossible(); // Should not occur.
1353 break; // Finish anyways.
1354 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001355 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001356 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001357 if (mVideoDecoderError
1358 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1359 || mNativeWindow == NULL
1360 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001361 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001362 // When both audio and video have error, or this stream has only audio
1363 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001364 notifyListener(
1365 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1366 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001367 } else {
1368 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001369 notifyListener(
1370 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1371 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001372 }
1373 mAudioDecoderError = true;
1374 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001375 if (mAudioDecoderError
1376 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001377 || mAudioSink == NULL || mAudioDecoder == NULL) {
1378 // When both audio and video have error, or this stream has only video
1379 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001380 notifyListener(
1381 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1382 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001383 } else {
1384 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001385 notifyListener(
1386 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1387 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001388 }
1389 mVideoDecoderError = true;
1390 }
1391 }
1392 } else {
1393 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1394 what,
1395 what >> 24,
1396 (what >> 16) & 0xff,
1397 (what >> 8) & 0xff,
1398 what & 0xff);
1399 }
1400
1401 break;
1402 }
1403
1404 case kWhatRendererNotify:
1405 {
1406 int32_t requesterGeneration = mRendererGeneration - 1;
1407 CHECK(msg->findInt32("generation", &requesterGeneration));
1408 if (requesterGeneration != mRendererGeneration) {
1409 ALOGV("got message from old renderer, generation(%d:%d)",
1410 requesterGeneration, mRendererGeneration);
1411 return;
1412 }
1413
1414 int32_t what;
1415 CHECK(msg->findInt32("what", &what));
1416
1417 if (what == Renderer::kWhatEOS) {
1418 int32_t audio;
1419 CHECK(msg->findInt32("audio", &audio));
1420
1421 int32_t finalResult;
1422 CHECK(msg->findInt32("finalResult", &finalResult));
1423
1424 if (audio) {
1425 mAudioEOS = true;
1426 } else {
1427 mVideoEOS = true;
1428 }
1429
1430 if (finalResult == ERROR_END_OF_STREAM) {
1431 ALOGV("reached %s EOS", audio ? "audio" : "video");
1432 } else {
1433 ALOGE("%s track encountered an error (%d)",
1434 audio ? "audio" : "video", finalResult);
1435
1436 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001437 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1438 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001439 }
1440
1441 if ((mAudioEOS || mAudioDecoder == NULL)
1442 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001443 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001444 }
1445 } else if (what == Renderer::kWhatFlushComplete) {
1446 int32_t audio;
1447 CHECK(msg->findInt32("audio", &audio));
1448
1449 if (audio) {
1450 mAudioEOS = false;
1451 } else {
1452 mVideoEOS = false;
1453 }
1454
1455 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1456 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1457 || mFlushingAudio == SHUT_DOWN)) {
1458 // Flush has been handled by tear down.
1459 break;
1460 }
1461 handleFlushComplete(audio, false /* isDecoder */);
1462 finishFlushIfPossible();
1463 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001464 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1465 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001466 } else if (what == Renderer::kWhatMediaRenderingStart) {
1467 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001468 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001469 } else if (what == Renderer::kWhatAudioTearDown) {
1470 int32_t reason;
1471 CHECK(msg->findInt32("reason", &reason));
1472 ALOGV("Tear down audio with reason %d.", reason);
1473 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1474 // TimeoutWhenPaused is only for offload mode.
1475 ALOGW("Receive a stale message for teardown.");
1476 break;
1477 }
1478 int64_t positionUs;
1479 if (!msg->findInt64("positionUs", &positionUs)) {
1480 positionUs = mPreviousSeekTimeUs;
1481 }
1482
1483 restartAudio(
1484 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1485 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1486 }
1487 break;
1488 }
1489
1490 case kWhatMoreDataQueued:
1491 {
1492 break;
1493 }
1494
1495 case kWhatReset:
1496 {
1497 ALOGV("kWhatReset");
1498
1499 mResetting = true;
1500 stopPlaybackTimer("kWhatReset");
1501 stopRebufferingTimer(true);
1502
1503 mDeferredActions.push_back(
1504 new FlushDecoderAction(
1505 FLUSH_CMD_SHUTDOWN /* audio */,
1506 FLUSH_CMD_SHUTDOWN /* video */));
1507
1508 mDeferredActions.push_back(
1509 new SimpleAction(&NuPlayer2::performReset));
1510
1511 processDeferredActions();
1512 break;
1513 }
1514
1515 case kWhatNotifyTime:
1516 {
1517 ALOGV("kWhatNotifyTime");
1518 int64_t timerUs;
1519 CHECK(msg->findInt64("timerUs", &timerUs));
1520
Wei Jiaf01e3122018-10-18 11:49:44 -07001521 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001522 break;
1523 }
1524
1525 case kWhatSeek:
1526 {
1527 int64_t seekTimeUs;
1528 int32_t mode;
1529 int32_t needNotify;
1530 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1531 CHECK(msg->findInt32("mode", &mode));
1532 CHECK(msg->findInt32("needNotify", &needNotify));
1533
1534 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1535 (long long)seekTimeUs, mode, needNotify);
1536
1537 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001538 if (!mSourceStarted) {
1539 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001540 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001541 }
Wei Jia083e9092018-02-12 11:46:04 -08001542 if (seekTimeUs > 0) {
1543 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1544 }
1545
Wei Jia53692fa2017-12-11 10:33:46 -08001546 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001547 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001548 }
1549 break;
1550 }
1551
Wei Jia083e9092018-02-12 11:46:04 -08001552 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001553 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001554
Wei Jia53692fa2017-12-11 10:33:46 -08001555 mDeferredActions.push_back(
1556 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1557 FLUSH_CMD_FLUSH /* video */));
1558
1559 mDeferredActions.push_back(
1560 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1561
1562 // After a flush without shutdown, decoder is paused.
1563 // Don't resume it until source seek is done, otherwise it could
1564 // start pulling stale data too soon.
1565 mDeferredActions.push_back(
1566 new ResumeDecoderAction(needNotify));
1567
1568 processDeferredActions();
1569 break;
1570 }
1571
Wei Jiad1864f92018-10-19 12:34:56 -07001572 case kWhatRewind:
1573 {
1574 ALOGV("kWhatRewind");
1575
1576 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1577 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1578
1579 if (!mStarted) {
1580 if (!mSourceStarted) {
1581 mSourceStarted = true;
1582 mCurrentSourceInfo.mSource->start();
1583 }
1584 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1585 break;
1586 }
1587
1588 // seeks can take a while, so we essentially paused
1589 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1590
1591 mDeferredActions.push_back(
1592 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1593 FLUSH_CMD_FLUSH /* video */));
1594
1595 mDeferredActions.push_back(
1596 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1597
1598 // After a flush without shutdown, decoder is paused.
1599 // Don't resume it until source seek is done, otherwise it could
1600 // start pulling stale data too soon.
1601 mDeferredActions.push_back(
1602 new ResumeDecoderAction(false /* needNotify */));
1603
1604 processDeferredActions();
1605 break;
1606 }
1607
Wei Jia53692fa2017-12-11 10:33:46 -08001608 case kWhatPause:
1609 {
Wei Jia6376cd52018-09-26 11:42:55 -07001610 if (!mStarted) {
1611 onStart(false /* play */);
1612 }
Wei Jia53692fa2017-12-11 10:33:46 -08001613 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001614 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001615 mPausedByClient = true;
1616 break;
1617 }
1618
1619 case kWhatSourceNotify:
1620 {
1621 onSourceNotify(msg);
1622 break;
1623 }
1624
1625 case kWhatClosedCaptionNotify:
1626 {
1627 onClosedCaptionNotify(msg);
1628 break;
1629 }
1630
1631 case kWhatPrepareDrm:
1632 {
1633 status_t status = onPrepareDrm(msg);
1634
1635 sp<AMessage> response = new AMessage;
1636 response->setInt32("status", status);
1637 sp<AReplyToken> replyID;
1638 CHECK(msg->senderAwaitsResponse(&replyID));
1639 response->postReply(replyID);
1640 break;
1641 }
1642
1643 case kWhatReleaseDrm:
1644 {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001645 status_t status = onReleaseDrm(msg);
Wei Jia53692fa2017-12-11 10:33:46 -08001646
1647 sp<AMessage> response = new AMessage;
1648 response->setInt32("status", status);
1649 sp<AReplyToken> replyID;
1650 CHECK(msg->senderAwaitsResponse(&replyID));
1651 response->postReply(replyID);
1652 break;
1653 }
1654
1655 default:
1656 TRESPASS();
1657 break;
1658 }
1659}
1660
1661void NuPlayer2::onResume() {
1662 if (!mPaused || mResetting) {
1663 ALOGD_IF(mResetting, "resetting, onResume discarded");
1664 return;
1665 }
1666 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001667 if (mCurrentSourceInfo.mSource != NULL) {
1668 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001669 } else {
1670 ALOGW("resume called when source is gone or not set");
1671 }
1672 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1673 // needed.
1674 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1675 instantiateDecoder(true /* audio */, &mAudioDecoder);
1676 }
1677 if (mRenderer != NULL) {
1678 mRenderer->resume();
1679 } else {
1680 ALOGW("resume called when renderer is gone or not set");
1681 }
1682
1683 startPlaybackTimer("onresume");
1684}
1685
Wei Jia6376cd52018-09-26 11:42:55 -07001686void NuPlayer2::onStart(bool play) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001687 ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001688
1689 if (!mSourceStarted) {
1690 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001691 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001692 }
Wei Jia53692fa2017-12-11 10:33:46 -08001693
1694 mOffloadAudio = false;
1695 mAudioEOS = false;
1696 mVideoEOS = false;
1697 mStarted = true;
1698 mPaused = false;
1699
1700 uint32_t flags = 0;
1701
Wei Jiaf01e3122018-10-18 11:49:44 -07001702 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001703 flags |= Renderer::FLAG_REAL_TIME;
1704 }
1705
Wei Jiaf01e3122018-10-18 11:49:44 -07001706 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1707 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001708 if (!hasAudio && !hasVideo) {
1709 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001710 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001711 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001712 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1713 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001714 return;
1715 }
1716 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1717
Wei Jiaf01e3122018-10-18 11:49:44 -07001718 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001719
1720 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1721 if (mAudioSink != NULL) {
1722 streamType = mAudioSink->getAudioStreamType();
1723 }
1724
1725 mOffloadAudio =
Dongwon Kang946bdb32018-11-14 10:12:00 -08001726 JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
1727 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001728 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1729
1730 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08001731 if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08001732 mOffloadAudio = false;
1733 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1734 }
1735
1736 if (mOffloadAudio) {
1737 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1738 }
1739
1740 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1741 ++mRendererGeneration;
1742 notify->setInt32("generation", mRendererGeneration);
Dichen Zhangfc9f40f2019-01-04 14:15:28 -08001743 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, mContext, flags);
Wei Jia53692fa2017-12-11 10:33:46 -08001744 mRendererLooper = new ALooper;
Wei Jia8c8b57a2018-11-28 11:09:50 -08001745 mRendererLooper->setName("NuPlayer2Renderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001746 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001747 mRendererLooper->registerHandler(mRenderer);
1748
1749 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1750 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001751 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001752 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001753 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001754 return;
1755 }
1756
1757 float rate = getFrameRate();
1758 if (rate > 0) {
1759 mRenderer->setVideoFrameRate(rate);
1760 }
1761
Wei Jiad1864f92018-10-19 12:34:56 -07001762 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001763 // Renderer is created in paused state.
1764 if (play) {
1765 mRenderer->resume();
1766 }
1767
Wei Jia53692fa2017-12-11 10:33:46 -08001768 if (mVideoDecoder != NULL) {
1769 mVideoDecoder->setRenderer(mRenderer);
1770 }
1771 if (mAudioDecoder != NULL) {
1772 mAudioDecoder->setRenderer(mRenderer);
1773 }
1774
1775 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001776 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001777
1778 postScanSources();
1779}
1780
Wei Jiad1864f92018-10-19 12:34:56 -07001781void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001782 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001783
1784 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1785 return;
1786 }
1787
1788 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001789 msg->setInt32("generation", mEOSMonitorGeneration);
1790 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1791}
1792
Wei Jia53692fa2017-12-11 10:33:46 -08001793void NuPlayer2::startPlaybackTimer(const char *where) {
1794 Mutex::Autolock autoLock(mPlayingTimeLock);
1795 if (mLastStartedPlayingTimeNs == 0) {
1796 mLastStartedPlayingTimeNs = systemTime();
1797 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1798 }
1799}
1800
1801void NuPlayer2::stopPlaybackTimer(const char *where) {
1802 Mutex::Autolock autoLock(mPlayingTimeLock);
1803
1804 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1805
1806 if (mLastStartedPlayingTimeNs != 0) {
1807 sp<NuPlayer2Driver> driver = mDriver.promote();
1808 if (driver != NULL) {
1809 int64_t now = systemTime();
1810 int64_t played = now - mLastStartedPlayingTimeNs;
1811 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1812
1813 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001814 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001815 }
1816 }
1817 mLastStartedPlayingTimeNs = 0;
1818 }
1819}
1820
1821void NuPlayer2::startRebufferingTimer() {
1822 Mutex::Autolock autoLock(mPlayingTimeLock);
1823 if (mLastStartedRebufferingTimeNs == 0) {
1824 mLastStartedRebufferingTimeNs = systemTime();
1825 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1826 }
1827}
1828
1829void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1830 Mutex::Autolock autoLock(mPlayingTimeLock);
1831
Wei Jiaf01e3122018-10-18 11:49:44 -07001832 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1833 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001834
1835 if (mLastStartedRebufferingTimeNs != 0) {
1836 sp<NuPlayer2Driver> driver = mDriver.promote();
1837 if (driver != NULL) {
1838 int64_t now = systemTime();
1839 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1840 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1841
1842 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001843 driver->notifyMoreRebufferingTimeUs(
1844 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001845 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001846 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001847 }
1848 }
1849 }
1850 mLastStartedRebufferingTimeNs = 0;
1851 }
1852}
1853
1854void NuPlayer2::onPause() {
1855
1856 stopPlaybackTimer("onPause");
1857
1858 if (mPaused) {
1859 return;
1860 }
1861 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001862 if (mCurrentSourceInfo.mSource != NULL) {
1863 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001864 } else {
1865 ALOGW("pause called when source is gone or not set");
1866 }
1867 if (mRenderer != NULL) {
1868 mRenderer->pause();
1869 } else {
1870 ALOGW("pause called when renderer is gone or not set");
1871 }
1872
1873}
1874
1875bool NuPlayer2::audioDecoderStillNeeded() {
1876 // Audio decoder is no longer needed if it's in shut/shutting down status.
1877 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1878}
1879
1880void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1881 // We wait for both the decoder flush and the renderer flush to complete
1882 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1883
1884 mFlushComplete[audio][isDecoder] = true;
1885 if (!mFlushComplete[audio][!isDecoder]) {
1886 return;
1887 }
1888
1889 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1890 switch (*state) {
1891 case FLUSHING_DECODER:
1892 {
1893 *state = FLUSHED;
1894 break;
1895 }
1896
1897 case FLUSHING_DECODER_SHUTDOWN:
1898 {
1899 *state = SHUTTING_DOWN_DECODER;
1900
1901 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1902 getDecoder(audio)->initiateShutdown();
1903 break;
1904 }
1905
1906 default:
1907 // decoder flush completes only occur in a flushing state.
1908 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1909 break;
1910 }
1911}
1912
1913void NuPlayer2::finishFlushIfPossible() {
1914 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1915 && mFlushingAudio != SHUT_DOWN) {
1916 return;
1917 }
1918
1919 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1920 && mFlushingVideo != SHUT_DOWN) {
1921 return;
1922 }
1923
1924 ALOGV("both audio and video are flushed now.");
1925
1926 mFlushingAudio = NONE;
1927 mFlushingVideo = NONE;
1928
1929 clearFlushComplete();
1930
1931 processDeferredActions();
1932}
1933
1934void NuPlayer2::postScanSources() {
1935 if (mScanSourcesPending) {
1936 return;
1937 }
1938
1939 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1940 msg->setInt32("generation", mScanSourcesGeneration);
1941 msg->post();
1942
1943 mScanSourcesPending = true;
1944}
1945
1946void NuPlayer2::tryOpenAudioSinkForOffload(
1947 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1948 // Note: This is called early in NuPlayer2 to determine whether offloading
1949 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1950
1951 status_t err = mRenderer->openAudioSink(
1952 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001953 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001954 if (err != OK) {
1955 // Any failure we turn off mOffloadAudio.
1956 mOffloadAudio = false;
1957 } else if (mOffloadAudio) {
1958 sendMetaDataToHal(mAudioSink, audioMeta);
1959 }
1960}
1961
1962void NuPlayer2::closeAudioSink() {
1963 mRenderer->closeAudioSink();
1964}
1965
1966void NuPlayer2::restartAudio(
1967 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1968 if (mAudioDecoder != NULL) {
1969 mAudioDecoder->pause();
1970 mAudioDecoder.clear();
1971 mAudioDecoderError = false;
1972 ++mAudioDecoderGeneration;
1973 }
1974 if (mFlushingAudio == FLUSHING_DECODER) {
1975 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1976 mFlushingAudio = FLUSHED;
1977 finishFlushIfPossible();
1978 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1979 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1980 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1981 mFlushingAudio = SHUT_DOWN;
1982 finishFlushIfPossible();
1983 needsToCreateAudioDecoder = false;
1984 }
1985 if (mRenderer == NULL) {
1986 return;
1987 }
1988 closeAudioSink();
1989 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1990 if (mVideoDecoder != NULL) {
1991 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1992 }
1993
1994 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1995
1996 if (forceNonOffload) {
1997 mRenderer->signalDisableOffloadAudio();
1998 mOffloadAudio = false;
1999 }
2000 if (needsToCreateAudioDecoder) {
2001 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
2002 }
2003}
2004
2005void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002006 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002007 return;
2008 }
2009
2010 if (mRenderer == NULL) {
2011 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
2012 mOffloadAudio = false;
2013 return;
2014 }
2015
Wei Jiaf01e3122018-10-18 11:49:44 -07002016 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
2017 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002018 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
2019 const bool hasVideo = (videoFormat != NULL);
Dongwon Kangcd0e4272018-11-15 10:49:14 -08002020 bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
Wei Jiaf01e3122018-10-18 11:49:44 -07002021 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08002022 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2023
2024 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08002025 if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08002026 canOffload = false;
2027 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2028 }
2029
2030 if (canOffload) {
2031 if (!mOffloadAudio) {
2032 mRenderer->signalEnableOffloadAudio();
2033 }
2034 // open audio sink early under offload mode.
2035 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2036 } else {
2037 if (mOffloadAudio) {
2038 mRenderer->signalDisableOffloadAudio();
2039 mOffloadAudio = false;
2040 }
2041 }
2042}
2043
2044status_t NuPlayer2::instantiateDecoder(
2045 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2046 // The audio decoder could be cleared by tear down. If still in shut down
2047 // process, no need to create a new audio decoder.
2048 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2049 return OK;
2050 }
2051
Wei Jiaf01e3122018-10-18 11:49:44 -07002052 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002053
2054 if (format == NULL) {
2055 return UNKNOWN_ERROR;
2056 } else {
2057 status_t err;
2058 if (format->findInt32("err", &err) && err) {
2059 return err;
2060 }
2061 }
2062
2063 format->setInt32("priority", 0 /* realtime */);
2064
2065 if (!audio) {
2066 AString mime;
2067 CHECK(format->findString("mime", &mime));
2068
2069 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2070 if (mCCDecoder == NULL) {
2071 mCCDecoder = new CCDecoder(ccNotify);
2072 }
2073
Wei Jiaf01e3122018-10-18 11:49:44 -07002074 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002075 format->setInt32("secure", true);
2076 }
2077
Wei Jiaf01e3122018-10-18 11:49:44 -07002078 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002079 format->setInt32("protected", true);
2080 }
2081
2082 float rate = getFrameRate();
2083 if (rate > 0) {
2084 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2085 }
2086 }
2087
2088 if (audio) {
2089 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2090 ++mAudioDecoderGeneration;
2091 notify->setInt32("generation", mAudioDecoderGeneration);
2092
2093 if (checkAudioModeChange) {
2094 determineAudioModeChange(format);
2095 }
2096 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002097 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002098
Wei Jiaf01e3122018-10-18 11:49:44 -07002099 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002100 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002101 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002102 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2103 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002104 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002105
Wei Jiaf01e3122018-10-18 11:49:44 -07002106 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002107 ALOGV("instantiateDecoder audio Decoder");
2108 }
2109 mAudioDecoderError = false;
2110 } else {
2111 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2112 ++mVideoDecoderGeneration;
2113 notify->setInt32("generation", mVideoDecoderGeneration);
2114
2115 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002116 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2117 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002118 mVideoDecoderError = false;
2119
2120 // enable FRC if high-quality AV sync is requested, even if not
2121 // directly queuing to display, as this will even improve textureview
2122 // playback.
2123 {
2124 if (property_get_bool("persist.sys.media.avsync", false)) {
2125 format->setInt32("auto-frc", 1);
2126 }
2127 }
2128 }
2129 (*decoder)->init();
2130
2131 // Modular DRM
Robert Shihc3fca0e2018-12-04 17:08:04 -08002132 if (mCurrentSourceInfo.mIsDrmProtected) {
2133 format->setObject("crypto", mCurrentSourceInfo.mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002134 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
Robert Shihc3fca0e2018-12-04 17:08:04 -08002135 mCurrentSourceInfo.mCrypto.get(),
2136 (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002137 }
2138
2139 (*decoder)->configure(format);
2140
2141 if (!audio) {
2142 sp<AMessage> params = new AMessage();
2143 float rate = getFrameRate();
2144 if (rate > 0) {
2145 params->setFloat("frame-rate-total", rate);
2146 }
2147
2148 sp<MetaData> fileMeta = getFileMeta();
2149 if (fileMeta != NULL) {
2150 int32_t videoTemporalLayerCount;
2151 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2152 && videoTemporalLayerCount > 0) {
2153 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2154 }
2155 }
2156
2157 if (params->countEntries() > 0) {
2158 (*decoder)->setParameters(params);
2159 }
2160 }
2161 return OK;
2162}
2163
2164void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002165 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002166 const sp<AMessage> &inputFormat,
2167 const sp<AMessage> &outputFormat) {
2168 if (inputFormat == NULL) {
2169 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002170 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002171 return;
2172 }
2173 int32_t err = OK;
2174 inputFormat->findInt32("err", &err);
2175 if (err == -EWOULDBLOCK) {
2176 ALOGW("Video meta is not available yet!");
2177 return;
2178 }
2179 if (err != OK) {
2180 ALOGW("Something is wrong with video meta!");
2181 return;
2182 }
2183
2184 int32_t displayWidth, displayHeight;
2185 if (outputFormat != NULL) {
2186 int32_t width, height;
2187 CHECK(outputFormat->findInt32("width", &width));
2188 CHECK(outputFormat->findInt32("height", &height));
2189
2190 int32_t cropLeft, cropTop, cropRight, cropBottom;
2191 CHECK(outputFormat->findRect(
2192 "crop",
2193 &cropLeft, &cropTop, &cropRight, &cropBottom));
2194
2195 displayWidth = cropRight - cropLeft + 1;
2196 displayHeight = cropBottom - cropTop + 1;
2197
2198 ALOGV("Video output format changed to %d x %d "
2199 "(crop: %d x %d @ (%d, %d))",
2200 width, height,
2201 displayWidth,
2202 displayHeight,
2203 cropLeft, cropTop);
2204 } else {
2205 CHECK(inputFormat->findInt32("width", &displayWidth));
2206 CHECK(inputFormat->findInt32("height", &displayHeight));
2207
2208 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2209 }
2210
2211 // Take into account sample aspect ratio if necessary:
2212 int32_t sarWidth, sarHeight;
2213 if (inputFormat->findInt32("sar-width", &sarWidth)
2214 && inputFormat->findInt32("sar-height", &sarHeight)
2215 && sarWidth > 0 && sarHeight > 0) {
2216 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2217
2218 displayWidth = (displayWidth * sarWidth) / sarHeight;
2219
2220 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2221 } else {
2222 int32_t width, height;
2223 if (inputFormat->findInt32("display-width", &width)
2224 && inputFormat->findInt32("display-height", &height)
2225 && width > 0 && height > 0
2226 && displayWidth > 0 && displayHeight > 0) {
2227 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2228 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2229 } else {
2230 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2231 }
2232 ALOGV("Video display width and height are overridden to %d x %d",
2233 displayWidth, displayHeight);
2234 }
2235 }
2236
2237 int32_t rotationDegrees;
2238 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2239 rotationDegrees = 0;
2240 }
2241
2242 if (rotationDegrees == 90 || rotationDegrees == 270) {
2243 int32_t tmp = displayWidth;
2244 displayWidth = displayHeight;
2245 displayHeight = tmp;
2246 }
2247
2248 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002249 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002250 MEDIA2_SET_VIDEO_SIZE,
2251 displayWidth,
2252 displayHeight);
2253}
2254
Dongwon Kang41929fb2018-09-09 08:29:56 -07002255void NuPlayer2::notifyListener(
2256 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002257 if (mDriver == NULL) {
2258 return;
2259 }
2260
2261 sp<NuPlayer2Driver> driver = mDriver.promote();
2262
2263 if (driver == NULL) {
2264 return;
2265 }
2266
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002267 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002268}
2269
2270void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2271 ALOGV("[%s] flushDecoder needShutdown=%d",
2272 audio ? "audio" : "video", needShutdown);
2273
2274 const sp<DecoderBase> &decoder = getDecoder(audio);
2275 if (decoder == NULL) {
2276 ALOGI("flushDecoder %s without decoder present",
2277 audio ? "audio" : "video");
2278 return;
2279 }
2280
2281 // Make sure we don't continue to scan sources until we finish flushing.
2282 ++mScanSourcesGeneration;
2283 if (mScanSourcesPending) {
2284 if (!needShutdown) {
2285 mDeferredActions.push_back(
2286 new SimpleAction(&NuPlayer2::performScanSources));
2287 }
2288 mScanSourcesPending = false;
2289 }
2290
2291 decoder->signalFlush();
2292
2293 FlushStatus newStatus =
2294 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2295
2296 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2297 mFlushComplete[audio][true /* isDecoder */] = false;
2298 if (audio) {
2299 ALOGE_IF(mFlushingAudio != NONE,
2300 "audio flushDecoder() is called in state %d", mFlushingAudio);
2301 mFlushingAudio = newStatus;
2302 } else {
2303 ALOGE_IF(mFlushingVideo != NONE,
2304 "video flushDecoder() is called in state %d", mFlushingVideo);
2305 mFlushingVideo = newStatus;
2306 }
2307}
2308
2309void NuPlayer2::queueDecoderShutdown(
2310 bool audio, bool video, const sp<AMessage> &reply) {
2311 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2312
2313 mDeferredActions.push_back(
2314 new FlushDecoderAction(
2315 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2316 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2317
2318 mDeferredActions.push_back(
2319 new SimpleAction(&NuPlayer2::performScanSources));
2320
2321 mDeferredActions.push_back(new PostMessageAction(reply));
2322
2323 processDeferredActions();
2324}
2325
2326status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2327 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002328 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2329 status_t ret = native_window_set_scaling_mode(
2330 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002331 if (ret != OK) {
2332 ALOGE("Failed to set scaling mode (%d): %s",
2333 -ret, strerror(-ret));
2334 return ret;
2335 }
2336 }
2337 return OK;
2338}
2339
Wei Jia17944af2018-12-13 18:13:10 -08002340status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002341 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Wei Jia17944af2018-12-13 18:13:10 -08002342 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002343 msg->setPointer("reply", reply);
2344
2345 sp<AMessage> response;
2346 status_t err = msg->postAndAwaitResponse(&response);
2347 return err;
2348}
2349
Wei Jia17944af2018-12-13 18:13:10 -08002350status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002351 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2352 msg->setPointer("reply", reply);
Wei Jia17944af2018-12-13 18:13:10 -08002353 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002354 msg->setInt32("type", type);
2355
2356 sp<AMessage> response;
2357 status_t err = msg->postAndAwaitResponse(&response);
2358 if (err == OK && response != NULL) {
2359 CHECK(response->findInt32("err", &err));
2360 }
2361 return err;
2362}
2363
Wei Jia17944af2018-12-13 18:13:10 -08002364status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
Wei Jia53692fa2017-12-11 10:33:46 -08002365 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Wei Jia17944af2018-12-13 18:13:10 -08002366 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002367 msg->setSize("trackIndex", trackIndex);
2368 msg->setInt32("select", select);
2369 msg->setInt64("timeUs", timeUs);
2370
2371 sp<AMessage> response;
2372 status_t err = msg->postAndAwaitResponse(&response);
2373
2374 if (err != OK) {
2375 return err;
2376 }
2377
2378 if (!response->findInt32("err", &err)) {
2379 err = OK;
2380 }
2381
2382 return err;
2383}
2384
2385status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2386 sp<Renderer> renderer = mRenderer;
2387 if (renderer == NULL) {
2388 return NO_INIT;
2389 }
2390
2391 return renderer->getCurrentPosition(mediaUs);
2392}
2393
2394void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2395 CHECK(mTrackStats != NULL);
2396
2397 mTrackStats->clear();
2398 if (mVideoDecoder != NULL) {
2399 mTrackStats->push_back(mVideoDecoder->getStats());
2400 }
2401 if (mAudioDecoder != NULL) {
2402 mTrackStats->push_back(mAudioDecoder->getStats());
2403 }
2404}
2405
2406sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002407 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002408}
2409
2410float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002411 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002412 if (meta == NULL) {
2413 return 0;
2414 }
2415 int32_t rate;
2416 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2417 // fall back to try file meta
2418 sp<MetaData> fileMeta = getFileMeta();
2419 if (fileMeta == NULL) {
2420 ALOGW("source has video meta but not file meta");
2421 return -1;
2422 }
2423 int32_t fileMetaRate;
2424 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2425 return -1;
2426 }
2427 return fileMetaRate;
2428 }
2429 return rate;
2430}
2431
2432void NuPlayer2::schedulePollDuration() {
2433 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2434 msg->setInt32("generation", mPollDurationGeneration);
2435 msg->post();
2436}
2437
2438void NuPlayer2::cancelPollDuration() {
2439 ++mPollDurationGeneration;
2440}
2441
2442void NuPlayer2::processDeferredActions() {
2443 while (!mDeferredActions.empty()) {
2444 // We won't execute any deferred actions until we're no longer in
2445 // an intermediate state, i.e. one more more decoders are currently
2446 // flushing or shutting down.
2447
2448 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2449 // We're currently flushing, postpone the reset until that's
2450 // completed.
2451
2452 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2453 mFlushingAudio, mFlushingVideo);
2454
2455 break;
2456 }
2457
2458 sp<Action> action = *mDeferredActions.begin();
2459 mDeferredActions.erase(mDeferredActions.begin());
2460
2461 action->execute(this);
2462 }
2463}
2464
2465void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2466 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2467 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2468
Wei Jiaf01e3122018-10-18 11:49:44 -07002469 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002470 // This happens when reset occurs right before the loop mode
2471 // asynchronously seeks to the start of the stream.
2472 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002473 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002474 mAudioDecoder.get(), mVideoDecoder.get());
2475 return;
2476 }
2477 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002478 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002479 ++mTimedTextGeneration;
2480
2481 // everything's flushed, continue playback.
2482}
2483
2484void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2485 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2486
2487 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2488 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2489 return;
2490 }
2491
2492 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2493 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2494 }
2495
2496 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2497 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2498 }
2499}
2500
2501void NuPlayer2::performReset() {
2502 ALOGV("performReset");
2503
2504 CHECK(mAudioDecoder == NULL);
2505 CHECK(mVideoDecoder == NULL);
2506
2507 stopPlaybackTimer("performReset");
2508 stopRebufferingTimer(true);
2509
2510 cancelPollDuration();
2511
2512 ++mScanSourcesGeneration;
2513 mScanSourcesPending = false;
2514
2515 if (mRendererLooper != NULL) {
2516 if (mRenderer != NULL) {
2517 mRendererLooper->unregisterHandler(mRenderer->id());
2518 }
2519 mRendererLooper->stop();
2520 mRendererLooper.clear();
2521 }
2522 mRenderer.clear();
2523 ++mRendererGeneration;
2524
Robert Shihc3fca0e2018-12-04 17:08:04 -08002525 resetSourceInfo(mCurrentSourceInfo);
2526 resetSourceInfo(mNextSourceInfo);
Wei Jia53692fa2017-12-11 10:33:46 -08002527
2528 if (mDriver != NULL) {
2529 sp<NuPlayer2Driver> driver = mDriver.promote();
2530 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002531 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002532 }
2533 }
2534
2535 mStarted = false;
2536 mPrepared = false;
2537 mResetting = false;
2538 mSourceStarted = false;
2539
Wei Jia53692fa2017-12-11 10:33:46 -08002540}
2541
Wei Jia57aeffd2018-02-15 16:01:14 -08002542void NuPlayer2::performPlayNextDataSource() {
2543 ALOGV("performPlayNextDataSource");
2544
2545 CHECK(mAudioDecoder == NULL);
2546 CHECK(mVideoDecoder == NULL);
2547
2548 stopPlaybackTimer("performPlayNextDataSource");
2549 stopRebufferingTimer(true);
2550
2551 cancelPollDuration();
2552
2553 ++mScanSourcesGeneration;
2554 mScanSourcesPending = false;
2555
2556 ++mRendererGeneration;
2557
Wei Jiaf01e3122018-10-18 11:49:44 -07002558 if (mCurrentSourceInfo.mSource != NULL) {
2559 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002560 }
2561
2562 long previousSrcId;
2563 {
2564 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002565 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002566
2567 mCurrentSourceInfo = mNextSourceInfo;
2568 mNextSourceInfo = SourceInfo();
2569 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002570 }
2571
2572 if (mDriver != NULL) {
2573 sp<NuPlayer2Driver> driver = mDriver.promote();
2574 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002575 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002576
2577 int64_t durationUs;
2578 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2579 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2580 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002581 notifyListener(
2582 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002583 }
2584 }
2585
2586 mStarted = false;
2587 mPrepared = true; // TODO: what if it's not prepared
2588 mResetting = false;
2589 mSourceStarted = false;
2590
Wei Jiad1864f92018-10-19 12:34:56 -07002591 addEndTimeMonitor();
2592
Wei Jia57aeffd2018-02-15 16:01:14 -08002593 if (mRenderer != NULL) {
2594 mRenderer->resume();
2595 }
2596
Wei Jia6376cd52018-09-26 11:42:55 -07002597 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002598 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002599 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002600}
2601
Wei Jia53692fa2017-12-11 10:33:46 -08002602void NuPlayer2::performScanSources() {
2603 ALOGV("performScanSources");
2604
2605 if (!mStarted) {
2606 return;
2607 }
2608
2609 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2610 postScanSources();
2611 }
2612}
2613
Wei Jia28288fb2017-12-15 13:45:29 -08002614void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002615 ALOGV("performSetSurface");
2616
Wei Jia28288fb2017-12-15 13:45:29 -08002617 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002618
2619 // XXX - ignore error from setVideoScalingMode for now
2620 setVideoScalingMode(mVideoScalingMode);
2621
2622 if (mDriver != NULL) {
2623 sp<NuPlayer2Driver> driver = mDriver.promote();
2624 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002625 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002626 }
2627 }
2628}
2629
2630void NuPlayer2::performResumeDecoders(bool needNotify) {
2631 if (needNotify) {
2632 mResumePending = true;
2633 if (mVideoDecoder == NULL) {
2634 // if audio-only, we can notify seek complete now,
2635 // as the resume operation will be relatively fast.
2636 finishResume();
2637 }
2638 }
2639
2640 if (mVideoDecoder != NULL) {
2641 // When there is continuous seek, MediaPlayer will cache the seek
2642 // position, and send down new seek request when previous seek is
2643 // complete. Let's wait for at least one video output frame before
2644 // notifying seek complete, so that the video thumbnail gets updated
2645 // when seekbar is dragged.
2646 mVideoDecoder->signalResume(needNotify);
2647 }
2648
2649 if (mAudioDecoder != NULL) {
2650 mAudioDecoder->signalResume(false /* needNotify */);
2651 }
2652}
2653
2654void NuPlayer2::finishResume() {
2655 if (mResumePending) {
2656 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002657 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002658 }
2659}
2660
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002661void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002662 if (mDriver != NULL) {
2663 sp<NuPlayer2Driver> driver = mDriver.promote();
2664 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002665 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002666 }
2667 }
2668}
2669
2670void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2671 int32_t what;
2672 CHECK(msg->findInt32("what", &what));
2673
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002674 int64_t srcId;
2675 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002676 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002677 case Source::kWhatPrepared:
2678 {
Wei Jiad1864f92018-10-19 12:34:56 -07002679 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2680 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2681 if (srcId == mCurrentSourceInfo.mSrcId) {
2682 if (mCurrentSourceInfo.mSource == NULL) {
2683 // This is a stale notification from a source that was
2684 // asynchronously preparing when the client called reset().
2685 // We handled the reset, the source is gone.
2686 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002687 }
Wei Jiad1864f92018-10-19 12:34:56 -07002688
2689 int32_t err;
2690 CHECK(msg->findInt32("err", &err));
2691
2692 if (err != OK) {
2693 // shut down potential secure codecs in case client never calls reset
2694 mDeferredActions.push_back(
2695 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2696 FLUSH_CMD_SHUTDOWN /* video */));
2697 processDeferredActions();
2698 } else {
2699 mPrepared = true;
2700 }
2701
2702 sp<NuPlayer2Driver> driver = mDriver.promote();
2703 if (driver != NULL) {
2704 // notify duration first, so that it's definitely set when
2705 // the app received the "prepare complete" callback.
2706 int64_t durationUs;
2707 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2708 driver->notifyDuration(srcId, durationUs);
2709 }
2710 driver->notifyPrepareCompleted(srcId, err);
2711 }
2712 } else if (srcId == mNextSourceInfo.mSrcId) {
2713 if (mNextSourceInfo.mSource == NULL) {
2714 break; // stale
2715 }
2716
2717 sp<NuPlayer2Driver> driver = mDriver.promote();
2718 if (driver != NULL) {
2719 int32_t err;
2720 CHECK(msg->findInt32("err", &err));
2721 driver->notifyPrepareCompleted(srcId, err);
2722 }
Wei Jia53692fa2017-12-11 10:33:46 -08002723 }
2724
2725 break;
2726 }
2727
2728 // Modular DRM
2729 case Source::kWhatDrmInfo:
2730 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002731 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002732 sp<ABuffer> drmInfo;
2733 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002734 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002735
Dongwon Kang41929fb2018-09-09 08:29:56 -07002736 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2737 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002738
Dongwon Kang41929fb2018-09-09 08:29:56 -07002739 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002740
2741 break;
2742 }
2743
2744 case Source::kWhatFlagsChanged:
2745 {
2746 uint32_t flags;
2747 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2748
2749 sp<NuPlayer2Driver> driver = mDriver.promote();
2750 if (driver != NULL) {
2751
2752 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2753 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2754 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2755 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2756 (flags & Source::FLAG_CAN_PAUSE) != 0,
2757 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2758 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2759 (flags & Source::FLAG_CAN_SEEK) != 0,
2760 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2761 (flags & Source::FLAG_SECURE) != 0,
2762 (flags & Source::FLAG_PROTECTED) != 0);
2763
2764 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2765 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002766 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002767 }
Wei Jiad1864f92018-10-19 12:34:56 -07002768 if (srcId == mCurrentSourceInfo.mSrcId) {
2769 driver->notifyFlagsChanged(srcId, flags);
2770 }
Wei Jia53692fa2017-12-11 10:33:46 -08002771 }
2772
Wei Jiaf01e3122018-10-18 11:49:44 -07002773 if (srcId == mCurrentSourceInfo.mSrcId) {
2774 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2775 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2776 cancelPollDuration();
2777 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2778 && (flags & Source::FLAG_DYNAMIC_DURATION)
2779 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2780 schedulePollDuration();
2781 }
Wei Jia53692fa2017-12-11 10:33:46 -08002782
Wei Jiaf01e3122018-10-18 11:49:44 -07002783 mCurrentSourceInfo.mSourceFlags = flags;
2784 } else if (srcId == mNextSourceInfo.mSrcId) {
2785 // TODO: handle duration polling for next source.
2786 mNextSourceInfo.mSourceFlags = flags;
2787 }
Wei Jia53692fa2017-12-11 10:33:46 -08002788 break;
2789 }
2790
2791 case Source::kWhatVideoSizeChanged:
2792 {
2793 sp<AMessage> format;
2794 CHECK(msg->findMessage("format", &format));
2795
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002796 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002797 break;
2798 }
2799
2800 case Source::kWhatBufferingUpdate:
2801 {
2802 int32_t percentage;
2803 CHECK(msg->findInt32("percentage", &percentage));
2804
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002805 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002806 break;
2807 }
2808
2809 case Source::kWhatPauseOnBufferingStart:
2810 {
2811 // ignore if not playing
2812 if (mStarted) {
2813 ALOGI("buffer low, pausing...");
2814
2815 startRebufferingTimer();
2816 mPausedForBuffering = true;
2817 onPause();
2818 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002819 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002820 break;
2821 }
2822
2823 case Source::kWhatResumeOnBufferingEnd:
2824 {
2825 // ignore if not playing
2826 if (mStarted) {
2827 ALOGI("buffer ready, resuming...");
2828
2829 stopRebufferingTimer(false);
2830 mPausedForBuffering = false;
2831
2832 // do not resume yet if client didn't unpause
2833 if (!mPausedByClient) {
2834 onResume();
2835 }
2836 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002837 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002838 break;
2839 }
2840
2841 case Source::kWhatCacheStats:
2842 {
2843 int32_t kbps;
2844 CHECK(msg->findInt32("bandwidth", &kbps));
2845
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002846 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002847 break;
2848 }
2849
2850 case Source::kWhatSubtitleData:
2851 {
2852 sp<ABuffer> buffer;
2853 CHECK(msg->findBuffer("buffer", &buffer));
2854
2855 sendSubtitleData(buffer, 0 /* baseIndex */);
2856 break;
2857 }
2858
2859 case Source::kWhatTimedMetaData:
2860 {
2861 sp<ABuffer> buffer;
2862 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002863 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002864 } else {
2865 sendTimedMetaData(buffer);
2866 }
2867 break;
2868 }
2869
2870 case Source::kWhatTimedTextData:
2871 {
2872 int32_t generation;
2873 if (msg->findInt32("generation", &generation)
2874 && generation != mTimedTextGeneration) {
2875 break;
2876 }
2877
2878 sp<ABuffer> buffer;
2879 CHECK(msg->findBuffer("buffer", &buffer));
2880
2881 sp<NuPlayer2Driver> driver = mDriver.promote();
2882 if (driver == NULL) {
2883 break;
2884 }
2885
Wei Jia800fe372018-02-20 15:00:45 -08002886 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002887 int64_t timeUs, posUs;
2888 driver->getCurrentPosition(&posMs);
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08002889 posUs = posMs * 1000LL;
Wei Jia53692fa2017-12-11 10:33:46 -08002890 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2891
2892 if (posUs < timeUs) {
2893 if (!msg->findInt32("generation", &generation)) {
2894 msg->setInt32("generation", mTimedTextGeneration);
2895 }
2896 msg->post(timeUs - posUs);
2897 } else {
2898 sendTimedTextData(buffer);
2899 }
2900 break;
2901 }
2902
2903 case Source::kWhatQueueDecoderShutdown:
2904 {
2905 int32_t audio, video;
2906 CHECK(msg->findInt32("audio", &audio));
2907 CHECK(msg->findInt32("video", &video));
2908
2909 sp<AMessage> reply;
2910 CHECK(msg->findMessage("reply", &reply));
2911
2912 queueDecoderShutdown(audio, video, reply);
2913 break;
2914 }
2915
2916 case Source::kWhatDrmNoLicense:
2917 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002918 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002919 break;
2920 }
2921
2922 default:
2923 TRESPASS();
2924 }
2925}
2926
2927void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2928 int32_t what;
2929 CHECK(msg->findInt32("what", &what));
2930
2931 switch (what) {
2932 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2933 {
2934 sp<ABuffer> buffer;
2935 CHECK(msg->findBuffer("buffer", &buffer));
2936
2937 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002938 if (mCurrentSourceInfo.mSource != NULL) {
2939 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002940 }
2941
2942 sendSubtitleData(buffer, inbandTracks);
2943 break;
2944 }
2945
2946 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2947 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002948 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002949
2950 break;
2951 }
2952
2953 default:
2954 TRESPASS();
2955 }
2956
2957
2958}
2959
2960void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2961 int32_t trackIndex;
2962 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002963 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002964 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2965 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2966
Dongwon Kang41929fb2018-09-09 08:29:56 -07002967 PlayerMessage playerMsg;
2968 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2969 playerMsg.add_values()->set_int64_value(timeUs);
2970 playerMsg.add_values()->set_int64_value(durationUs);
2971 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002972
Wei Jiaf01e3122018-10-18 11:49:44 -07002973 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002974}
2975
2976void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2977 int64_t timeUs;
2978 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2979
Dongwon Kang41929fb2018-09-09 08:29:56 -07002980 PlayerMessage playerMsg;
2981 playerMsg.add_values()->set_int64_value(timeUs);
2982 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002983
Wei Jiaf01e3122018-10-18 11:49:44 -07002984 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002985}
2986
2987void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2988 const void *data;
2989 size_t size = 0;
2990 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002991 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002992
2993 AString mime;
2994 CHECK(buffer->meta()->findString("mime", &mime));
2995 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2996
2997 data = buffer->data();
2998 size = buffer->size();
2999
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003000 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08003001 if (size > 0) {
3002 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3003 int32_t global = 0;
3004 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003005 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003006 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003007 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003008 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003009 TextDescriptions2::getPlayerMessageOfDescriptions(
3010 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003011 }
3012
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003013 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003014 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003015 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003016 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003017 }
3018}
3019
3020const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003021 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003022 case DATA_SOURCE_TYPE_HTTP_LIVE:
3023 return "HTTPLive";
3024
3025 case DATA_SOURCE_TYPE_RTSP:
3026 return "RTSP";
3027
3028 case DATA_SOURCE_TYPE_GENERIC_URL:
3029 return "GenURL";
3030
3031 case DATA_SOURCE_TYPE_GENERIC_FD:
3032 return "GenFD";
3033
3034 case DATA_SOURCE_TYPE_MEDIA:
3035 return "Media";
3036
Wei Jia53692fa2017-12-11 10:33:46 -08003037 case DATA_SOURCE_TYPE_NONE:
3038 default:
3039 return "None";
3040 }
3041 }
3042
Robert Shihc3fca0e2018-12-04 17:08:04 -08003043NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
3044 int64_t srcId;
3045 CHECK(msg->findInt64("srcId", &srcId));
3046 if (mCurrentSourceInfo.mSrcId == srcId) {
3047 return &mCurrentSourceInfo;
3048 } else if (mNextSourceInfo.mSrcId == srcId) {
3049 return &mNextSourceInfo;
3050 } else {
3051 return NULL;
3052 }
3053}
3054
3055void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
3056 if (srcInfo.mSource != NULL) {
3057 srcInfo.mSource->stop();
3058
3059 Mutex::Autolock autoLock(mSourceLock);
3060 srcInfo.mSource.clear();
3061 }
3062 // Modular DRM
3063 ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
3064 srcInfo.mCrypto.clear();
3065 srcInfo.mIsDrmProtected = false;
3066}
3067
Wei Jia53692fa2017-12-11 10:33:46 -08003068// Modular DRM begin
Robert Shih3c3728d2018-12-04 17:06:36 -08003069status_t NuPlayer2::prepareDrm(
3070 int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
Wei Jia53692fa2017-12-11 10:33:46 -08003071{
3072 ALOGV("prepareDrm ");
3073
3074 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3075 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3076 // synchronous call so just passing the address but with local copies of "const" args
3077 uint8_t UUID[16];
3078 memcpy(UUID, uuid, sizeof(UUID));
3079 Vector<uint8_t> sessionId = drmSessionId;
Robert Shih3c3728d2018-12-04 17:06:36 -08003080 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003081 msg->setPointer("uuid", (void*)UUID);
3082 msg->setPointer("drmSessionId", (void*)&sessionId);
3083
3084 sp<AMessage> response;
3085 status_t status = msg->postAndAwaitResponse(&response);
3086
3087 if (status == OK && response != NULL) {
3088 CHECK(response->findInt32("status", &status));
3089 ALOGV("prepareDrm ret: %d ", status);
3090 } else {
3091 ALOGE("prepareDrm err: %d", status);
3092 }
3093
3094 return status;
3095}
3096
Robert Shih3c3728d2018-12-04 17:06:36 -08003097status_t NuPlayer2::releaseDrm(int64_t srcId)
Wei Jia53692fa2017-12-11 10:33:46 -08003098{
3099 ALOGV("releaseDrm ");
3100
3101 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
Robert Shih3c3728d2018-12-04 17:06:36 -08003102 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003103
3104 sp<AMessage> response;
3105 status_t status = msg->postAndAwaitResponse(&response);
3106
3107 if (status == OK && response != NULL) {
3108 CHECK(response->findInt32("status", &status));
3109 ALOGV("releaseDrm ret: %d ", status);
3110 } else {
3111 ALOGE("releaseDrm err: %d", status);
3112 }
3113
3114 return status;
3115}
3116
3117status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3118{
3119 // TODO change to ALOGV
3120 ALOGD("onPrepareDrm ");
3121
3122 status_t status = INVALID_OPERATION;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003123 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
3124 if (srcInfo == NULL) {
3125 return status;
3126 }
3127
3128 int64_t srcId = srcInfo->mSrcId;
3129 if (srcInfo->mSource == NULL) {
3130 ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
3131 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003132 return status;
3133 }
3134
3135 uint8_t *uuid;
3136 Vector<uint8_t> *drmSessionId;
3137 CHECK(msg->findPointer("uuid", (void**)&uuid));
3138 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3139
3140 status = OK;
3141 sp<AMediaCryptoWrapper> crypto = NULL;
3142
Robert Shihc3fca0e2018-12-04 17:08:04 -08003143 status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003144 if (crypto == NULL) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08003145 ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
3146 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003147 return status;
3148 }
Robert Shihc3fca0e2018-12-04 17:08:04 -08003149 ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003150
Robert Shihc3fca0e2018-12-04 17:08:04 -08003151 if (srcInfo->mCrypto != NULL) {
3152 ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
3153 (long long)srcId, srcInfo->mCrypto.get());
3154 srcInfo->mCrypto.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08003155 }
3156
Robert Shihc3fca0e2018-12-04 17:08:04 -08003157 srcInfo->mCrypto = crypto;
3158 srcInfo->mIsDrmProtected = true;
Wei Jia53692fa2017-12-11 10:33:46 -08003159 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003160 ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08003161
3162 return status;
3163}
3164
Robert Shihc3fca0e2018-12-04 17:08:04 -08003165status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
Wei Jia53692fa2017-12-11 10:33:46 -08003166{
3167 // TODO change to ALOGV
3168 ALOGD("onReleaseDrm ");
Robert Shihc3fca0e2018-12-04 17:08:04 -08003169 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
3170 if (srcInfo == NULL) {
3171 return INVALID_OPERATION;
Wei Jia53692fa2017-12-11 10:33:46 -08003172 }
3173
Robert Shihc3fca0e2018-12-04 17:08:04 -08003174 int64_t srcId = srcInfo->mSrcId;
3175 if (!srcInfo->mIsDrmProtected) {
3176 ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
3177 (long long)srcId);
3178 }
3179
3180 srcInfo->mIsDrmProtected = false;
Wei Jia53692fa2017-12-11 10:33:46 -08003181
3182 status_t status;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003183 if (srcInfo->mCrypto != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003184 // notifying the source first before removing crypto from codec
Robert Shihc3fca0e2018-12-04 17:08:04 -08003185 if (srcInfo->mSource != NULL) {
3186 srcInfo->mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003187 }
3188
3189 status=OK;
3190 // first making sure the codecs have released their crypto reference
3191 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3192 if (videoDecoder != NULL) {
3193 status = videoDecoder->releaseCrypto();
3194 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3195 }
3196
3197 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3198 if (audioDecoder != NULL) {
3199 status_t status_audio = audioDecoder->releaseCrypto();
3200 if (status == OK) { // otherwise, returning the first error
3201 status = status_audio;
3202 }
3203 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3204 }
3205
3206 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003207 ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
3208 srcInfo->mCrypto.clear();
3209 } else { // srcInfo->mCrypto == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08003210 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3211 status = INVALID_OPERATION;
3212 }
3213
3214 return status;
3215}
3216// Modular DRM end
3217////////////////////////////////////////////////////////////////////////////////
3218
3219sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3220 sp<MetaData> meta = getFormatMeta(audio);
3221
3222 if (meta == NULL) {
3223 return NULL;
3224 }
3225
3226 sp<AMessage> msg = new AMessage;
3227
3228 if(convertMetaDataToMessage(meta, &msg) == OK) {
3229 return msg;
3230 }
3231 return NULL;
3232}
3233
3234void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3235 sp<AMessage> notify = dupNotify();
3236 notify->setInt32("what", kWhatFlagsChanged);
3237 notify->setInt32("flags", flags);
3238 notify->post();
3239}
3240
3241void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3242 sp<AMessage> notify = dupNotify();
3243 notify->setInt32("what", kWhatVideoSizeChanged);
3244 notify->setMessage("format", format);
3245 notify->post();
3246}
3247
3248void NuPlayer2::Source::notifyPrepared(status_t err) {
3249 ALOGV("Source::notifyPrepared %d", err);
3250 sp<AMessage> notify = dupNotify();
3251 notify->setInt32("what", kWhatPrepared);
3252 notify->setInt32("err", err);
3253 notify->post();
3254}
3255
3256void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3257{
3258 ALOGV("Source::notifyDrmInfo");
3259
3260 sp<AMessage> notify = dupNotify();
3261 notify->setInt32("what", kWhatDrmInfo);
3262 notify->setBuffer("drmInfo", drmInfoBuffer);
3263
3264 notify->post();
3265}
3266
Wei Jia53692fa2017-12-11 10:33:46 -08003267void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3268 TRESPASS();
3269}
3270
Wei Jiaf01e3122018-10-18 11:49:44 -07003271NuPlayer2::SourceInfo::SourceInfo()
3272 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3273 mSrcId(0),
3274 mSourceFlags(0),
3275 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003276 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003277}
3278
Wei Jiad1864f92018-10-19 12:34:56 -07003279NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3280 mSource = other.mSource;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003281 mCrypto = other.mCrypto;
Wei Jiad1864f92018-10-19 12:34:56 -07003282 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3283 mSrcId = other.mSrcId;
3284 mSourceFlags = other.mSourceFlags;
3285 mStartTimeUs = other.mStartTimeUs;
3286 mEndTimeUs = other.mEndTimeUs;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003287 mIsDrmProtected = other.mIsDrmProtected;
Wei Jiad1864f92018-10-19 12:34:56 -07003288 return *this;
3289}
3290
Wei Jia53692fa2017-12-11 10:33:46 -08003291} // namespace android