blob: d608d4a8361f627952d24d3a350d31f72b677514 [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) {
Ray Essick372e8f22019-02-11 11:38:31 -08001292 Mutex::Autolock autoLock(mDecoderLock);
Wei Jia53692fa2017-12-11 10:33:46 -08001293 mAudioDecoder.clear();
1294 mAudioDecoderError = false;
1295 ++mAudioDecoderGeneration;
1296
1297 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1298 mFlushingAudio = SHUT_DOWN;
1299 } else {
Ray Essick372e8f22019-02-11 11:38:31 -08001300 Mutex::Autolock autoLock(mDecoderLock);
Wei Jia53692fa2017-12-11 10:33:46 -08001301 mVideoDecoder.clear();
1302 mVideoDecoderError = false;
1303 ++mVideoDecoderGeneration;
1304
1305 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1306 mFlushingVideo = SHUT_DOWN;
1307 }
1308
1309 finishFlushIfPossible();
1310 } else if (what == DecoderBase::kWhatResumeCompleted) {
1311 finishResume();
1312 } else if (what == DecoderBase::kWhatError) {
1313 status_t err;
1314 if (!msg->findInt32("err", &err) || err == OK) {
1315 err = UNKNOWN_ERROR;
1316 }
1317
1318 // Decoder errors can be due to Source (e.g. from streaming),
1319 // or from decoding corrupted bitstreams, or from other decoder
1320 // MediaCodec operations (e.g. from an ongoing reset or seek).
1321 // They may also be due to openAudioSink failure at
1322 // decoder start or after a format change.
1323 //
1324 // We try to gracefully shut down the affected decoder if possible,
1325 // rather than trying to force the shutdown with something
1326 // similar to performReset(). This method can lead to a hang
1327 // if MediaCodec functions block after an error, but they should
1328 // typically return INVALID_OPERATION instead of blocking.
1329
1330 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1331 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1332 err, audio ? "audio" : "video", *flushing);
1333
1334 switch (*flushing) {
1335 case NONE:
1336 mDeferredActions.push_back(
1337 new FlushDecoderAction(
1338 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1339 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1340 processDeferredActions();
1341 break;
1342 case FLUSHING_DECODER:
1343 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1344 break; // Wait for flush to complete.
1345 case FLUSHING_DECODER_SHUTDOWN:
1346 break; // Wait for flush to complete.
1347 case SHUTTING_DOWN_DECODER:
1348 break; // Wait for shutdown to complete.
1349 case FLUSHED:
1350 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1351 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1352 break;
1353 case SHUT_DOWN:
1354 finishFlushIfPossible(); // Should not occur.
1355 break; // Finish anyways.
1356 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001357 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001358 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001359 if (mVideoDecoderError
1360 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1361 || mNativeWindow == NULL
1362 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001363 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001364 // When both audio and video have error, or this stream has only audio
1365 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001366 notifyListener(
1367 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1368 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001369 } else {
1370 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001371 notifyListener(
1372 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1373 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001374 }
1375 mAudioDecoderError = true;
1376 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001377 if (mAudioDecoderError
1378 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001379 || mAudioSink == NULL || mAudioDecoder == NULL) {
1380 // When both audio and video have error, or this stream has only video
1381 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001382 notifyListener(
1383 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1384 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001385 } else {
1386 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001387 notifyListener(
1388 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1389 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001390 }
1391 mVideoDecoderError = true;
1392 }
1393 }
1394 } else {
1395 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1396 what,
1397 what >> 24,
1398 (what >> 16) & 0xff,
1399 (what >> 8) & 0xff,
1400 what & 0xff);
1401 }
1402
1403 break;
1404 }
1405
1406 case kWhatRendererNotify:
1407 {
1408 int32_t requesterGeneration = mRendererGeneration - 1;
1409 CHECK(msg->findInt32("generation", &requesterGeneration));
1410 if (requesterGeneration != mRendererGeneration) {
1411 ALOGV("got message from old renderer, generation(%d:%d)",
1412 requesterGeneration, mRendererGeneration);
1413 return;
1414 }
1415
1416 int32_t what;
1417 CHECK(msg->findInt32("what", &what));
1418
1419 if (what == Renderer::kWhatEOS) {
1420 int32_t audio;
1421 CHECK(msg->findInt32("audio", &audio));
1422
1423 int32_t finalResult;
1424 CHECK(msg->findInt32("finalResult", &finalResult));
1425
1426 if (audio) {
1427 mAudioEOS = true;
1428 } else {
1429 mVideoEOS = true;
1430 }
1431
1432 if (finalResult == ERROR_END_OF_STREAM) {
1433 ALOGV("reached %s EOS", audio ? "audio" : "video");
1434 } else {
1435 ALOGE("%s track encountered an error (%d)",
1436 audio ? "audio" : "video", finalResult);
1437
1438 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001439 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1440 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001441 }
1442
1443 if ((mAudioEOS || mAudioDecoder == NULL)
1444 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001445 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001446 }
1447 } else if (what == Renderer::kWhatFlushComplete) {
1448 int32_t audio;
1449 CHECK(msg->findInt32("audio", &audio));
1450
1451 if (audio) {
1452 mAudioEOS = false;
1453 } else {
1454 mVideoEOS = false;
1455 }
1456
1457 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1458 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1459 || mFlushingAudio == SHUT_DOWN)) {
1460 // Flush has been handled by tear down.
1461 break;
1462 }
1463 handleFlushComplete(audio, false /* isDecoder */);
1464 finishFlushIfPossible();
1465 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001466 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1467 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001468 } else if (what == Renderer::kWhatMediaRenderingStart) {
1469 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001470 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001471 } else if (what == Renderer::kWhatAudioTearDown) {
1472 int32_t reason;
1473 CHECK(msg->findInt32("reason", &reason));
1474 ALOGV("Tear down audio with reason %d.", reason);
1475 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1476 // TimeoutWhenPaused is only for offload mode.
1477 ALOGW("Receive a stale message for teardown.");
1478 break;
1479 }
1480 int64_t positionUs;
1481 if (!msg->findInt64("positionUs", &positionUs)) {
1482 positionUs = mPreviousSeekTimeUs;
1483 }
1484
1485 restartAudio(
1486 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1487 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1488 }
1489 break;
1490 }
1491
1492 case kWhatMoreDataQueued:
1493 {
1494 break;
1495 }
1496
1497 case kWhatReset:
1498 {
1499 ALOGV("kWhatReset");
1500
1501 mResetting = true;
1502 stopPlaybackTimer("kWhatReset");
1503 stopRebufferingTimer(true);
1504
1505 mDeferredActions.push_back(
1506 new FlushDecoderAction(
1507 FLUSH_CMD_SHUTDOWN /* audio */,
1508 FLUSH_CMD_SHUTDOWN /* video */));
1509
1510 mDeferredActions.push_back(
1511 new SimpleAction(&NuPlayer2::performReset));
1512
1513 processDeferredActions();
1514 break;
1515 }
1516
1517 case kWhatNotifyTime:
1518 {
1519 ALOGV("kWhatNotifyTime");
1520 int64_t timerUs;
1521 CHECK(msg->findInt64("timerUs", &timerUs));
1522
Wei Jiaf01e3122018-10-18 11:49:44 -07001523 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001524 break;
1525 }
1526
1527 case kWhatSeek:
1528 {
1529 int64_t seekTimeUs;
1530 int32_t mode;
1531 int32_t needNotify;
1532 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1533 CHECK(msg->findInt32("mode", &mode));
1534 CHECK(msg->findInt32("needNotify", &needNotify));
1535
1536 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1537 (long long)seekTimeUs, mode, needNotify);
1538
1539 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001540 if (!mSourceStarted) {
1541 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001542 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001543 }
Wei Jia083e9092018-02-12 11:46:04 -08001544 if (seekTimeUs > 0) {
1545 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1546 }
1547
Wei Jia53692fa2017-12-11 10:33:46 -08001548 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001549 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001550 }
1551 break;
1552 }
1553
Wei Jia083e9092018-02-12 11:46:04 -08001554 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001555 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001556
Wei Jia53692fa2017-12-11 10:33:46 -08001557 mDeferredActions.push_back(
1558 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1559 FLUSH_CMD_FLUSH /* video */));
1560
1561 mDeferredActions.push_back(
1562 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1563
1564 // After a flush without shutdown, decoder is paused.
1565 // Don't resume it until source seek is done, otherwise it could
1566 // start pulling stale data too soon.
1567 mDeferredActions.push_back(
1568 new ResumeDecoderAction(needNotify));
1569
1570 processDeferredActions();
1571 break;
1572 }
1573
Wei Jiad1864f92018-10-19 12:34:56 -07001574 case kWhatRewind:
1575 {
1576 ALOGV("kWhatRewind");
1577
1578 int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
1579 int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
1580
1581 if (!mStarted) {
1582 if (!mSourceStarted) {
1583 mSourceStarted = true;
1584 mCurrentSourceInfo.mSource->start();
1585 }
1586 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1587 break;
1588 }
1589
1590 // seeks can take a while, so we essentially paused
1591 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
1592
1593 mDeferredActions.push_back(
1594 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1595 FLUSH_CMD_FLUSH /* video */));
1596
1597 mDeferredActions.push_back(
1598 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1599
1600 // After a flush without shutdown, decoder is paused.
1601 // Don't resume it until source seek is done, otherwise it could
1602 // start pulling stale data too soon.
1603 mDeferredActions.push_back(
1604 new ResumeDecoderAction(false /* needNotify */));
1605
1606 processDeferredActions();
1607 break;
1608 }
1609
Wei Jia53692fa2017-12-11 10:33:46 -08001610 case kWhatPause:
1611 {
Wei Jia6376cd52018-09-26 11:42:55 -07001612 if (!mStarted) {
1613 onStart(false /* play */);
1614 }
Wei Jia53692fa2017-12-11 10:33:46 -08001615 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001616 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001617 mPausedByClient = true;
1618 break;
1619 }
1620
1621 case kWhatSourceNotify:
1622 {
1623 onSourceNotify(msg);
1624 break;
1625 }
1626
1627 case kWhatClosedCaptionNotify:
1628 {
1629 onClosedCaptionNotify(msg);
1630 break;
1631 }
1632
1633 case kWhatPrepareDrm:
1634 {
1635 status_t status = onPrepareDrm(msg);
1636
1637 sp<AMessage> response = new AMessage;
1638 response->setInt32("status", status);
1639 sp<AReplyToken> replyID;
1640 CHECK(msg->senderAwaitsResponse(&replyID));
1641 response->postReply(replyID);
1642 break;
1643 }
1644
1645 case kWhatReleaseDrm:
1646 {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001647 status_t status = onReleaseDrm(msg);
Wei Jia53692fa2017-12-11 10:33:46 -08001648
1649 sp<AMessage> response = new AMessage;
1650 response->setInt32("status", status);
1651 sp<AReplyToken> replyID;
1652 CHECK(msg->senderAwaitsResponse(&replyID));
1653 response->postReply(replyID);
1654 break;
1655 }
1656
1657 default:
1658 TRESPASS();
1659 break;
1660 }
1661}
1662
1663void NuPlayer2::onResume() {
1664 if (!mPaused || mResetting) {
1665 ALOGD_IF(mResetting, "resetting, onResume discarded");
1666 return;
1667 }
1668 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001669 if (mCurrentSourceInfo.mSource != NULL) {
1670 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001671 } else {
1672 ALOGW("resume called when source is gone or not set");
1673 }
1674 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1675 // needed.
1676 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1677 instantiateDecoder(true /* audio */, &mAudioDecoder);
1678 }
1679 if (mRenderer != NULL) {
1680 mRenderer->resume();
1681 } else {
1682 ALOGW("resume called when renderer is gone or not set");
1683 }
1684
1685 startPlaybackTimer("onresume");
1686}
1687
Wei Jia6376cd52018-09-26 11:42:55 -07001688void NuPlayer2::onStart(bool play) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08001689 ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08001690
1691 if (!mSourceStarted) {
1692 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001693 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001694 }
Wei Jia53692fa2017-12-11 10:33:46 -08001695
1696 mOffloadAudio = false;
1697 mAudioEOS = false;
1698 mVideoEOS = false;
1699 mStarted = true;
1700 mPaused = false;
1701
1702 uint32_t flags = 0;
1703
Wei Jiaf01e3122018-10-18 11:49:44 -07001704 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001705 flags |= Renderer::FLAG_REAL_TIME;
1706 }
1707
Wei Jiaf01e3122018-10-18 11:49:44 -07001708 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1709 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001710 if (!hasAudio && !hasVideo) {
1711 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001712 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001713 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001714 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1715 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001716 return;
1717 }
1718 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1719
Wei Jiaf01e3122018-10-18 11:49:44 -07001720 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001721
1722 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1723 if (mAudioSink != NULL) {
1724 streamType = mAudioSink->getAudioStreamType();
1725 }
1726
1727 mOffloadAudio =
Dongwon Kang946bdb32018-11-14 10:12:00 -08001728 JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
1729 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001730 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1731
1732 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08001733 if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08001734 mOffloadAudio = false;
1735 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1736 }
1737
1738 if (mOffloadAudio) {
1739 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1740 }
1741
1742 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1743 ++mRendererGeneration;
1744 notify->setInt32("generation", mRendererGeneration);
Dichen Zhangfc9f40f2019-01-04 14:15:28 -08001745 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, mContext, flags);
Wei Jia53692fa2017-12-11 10:33:46 -08001746 mRendererLooper = new ALooper;
Wei Jia8c8b57a2018-11-28 11:09:50 -08001747 mRendererLooper->setName("NuPlayer2Renderer");
Dichen Zhangf8726912018-10-17 13:31:26 -07001748 mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
Wei Jia53692fa2017-12-11 10:33:46 -08001749 mRendererLooper->registerHandler(mRenderer);
1750
1751 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1752 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001753 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001754 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001755 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001756 return;
1757 }
1758
1759 float rate = getFrameRate();
1760 if (rate > 0) {
1761 mRenderer->setVideoFrameRate(rate);
1762 }
1763
Wei Jiad1864f92018-10-19 12:34:56 -07001764 addEndTimeMonitor();
Wei Jia6376cd52018-09-26 11:42:55 -07001765 // Renderer is created in paused state.
1766 if (play) {
1767 mRenderer->resume();
1768 }
1769
Wei Jia53692fa2017-12-11 10:33:46 -08001770 if (mVideoDecoder != NULL) {
1771 mVideoDecoder->setRenderer(mRenderer);
1772 }
1773 if (mAudioDecoder != NULL) {
1774 mAudioDecoder->setRenderer(mRenderer);
1775 }
1776
1777 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001778 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001779
1780 postScanSources();
1781}
1782
Wei Jiad1864f92018-10-19 12:34:56 -07001783void NuPlayer2::addEndTimeMonitor() {
Wei Jiad1864f92018-10-19 12:34:56 -07001784 ++mEOSMonitorGeneration;
Wei Jiae31ac8a2018-10-25 11:06:21 -07001785
1786 if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
1787 return;
1788 }
1789
1790 sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
Wei Jiad1864f92018-10-19 12:34:56 -07001791 msg->setInt32("generation", mEOSMonitorGeneration);
1792 mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
1793}
1794
Wei Jia53692fa2017-12-11 10:33:46 -08001795void NuPlayer2::startPlaybackTimer(const char *where) {
1796 Mutex::Autolock autoLock(mPlayingTimeLock);
1797 if (mLastStartedPlayingTimeNs == 0) {
1798 mLastStartedPlayingTimeNs = systemTime();
1799 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1800 }
1801}
1802
1803void NuPlayer2::stopPlaybackTimer(const char *where) {
1804 Mutex::Autolock autoLock(mPlayingTimeLock);
1805
1806 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1807
1808 if (mLastStartedPlayingTimeNs != 0) {
1809 sp<NuPlayer2Driver> driver = mDriver.promote();
1810 if (driver != NULL) {
1811 int64_t now = systemTime();
1812 int64_t played = now - mLastStartedPlayingTimeNs;
1813 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1814
1815 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001816 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001817 }
1818 }
1819 mLastStartedPlayingTimeNs = 0;
1820 }
1821}
1822
1823void NuPlayer2::startRebufferingTimer() {
1824 Mutex::Autolock autoLock(mPlayingTimeLock);
1825 if (mLastStartedRebufferingTimeNs == 0) {
1826 mLastStartedRebufferingTimeNs = systemTime();
1827 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1828 }
1829}
1830
1831void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1832 Mutex::Autolock autoLock(mPlayingTimeLock);
1833
Wei Jiaf01e3122018-10-18 11:49:44 -07001834 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1835 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001836
1837 if (mLastStartedRebufferingTimeNs != 0) {
1838 sp<NuPlayer2Driver> driver = mDriver.promote();
1839 if (driver != NULL) {
1840 int64_t now = systemTime();
1841 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1842 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1843
1844 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001845 driver->notifyMoreRebufferingTimeUs(
1846 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001847 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001848 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001849 }
1850 }
1851 }
1852 mLastStartedRebufferingTimeNs = 0;
1853 }
1854}
1855
1856void NuPlayer2::onPause() {
1857
1858 stopPlaybackTimer("onPause");
1859
1860 if (mPaused) {
1861 return;
1862 }
1863 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001864 if (mCurrentSourceInfo.mSource != NULL) {
1865 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001866 } else {
1867 ALOGW("pause called when source is gone or not set");
1868 }
1869 if (mRenderer != NULL) {
1870 mRenderer->pause();
1871 } else {
1872 ALOGW("pause called when renderer is gone or not set");
1873 }
1874
1875}
1876
1877bool NuPlayer2::audioDecoderStillNeeded() {
1878 // Audio decoder is no longer needed if it's in shut/shutting down status.
1879 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1880}
1881
1882void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1883 // We wait for both the decoder flush and the renderer flush to complete
1884 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1885
1886 mFlushComplete[audio][isDecoder] = true;
1887 if (!mFlushComplete[audio][!isDecoder]) {
1888 return;
1889 }
1890
1891 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1892 switch (*state) {
1893 case FLUSHING_DECODER:
1894 {
1895 *state = FLUSHED;
1896 break;
1897 }
1898
1899 case FLUSHING_DECODER_SHUTDOWN:
1900 {
1901 *state = SHUTTING_DOWN_DECODER;
1902
1903 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1904 getDecoder(audio)->initiateShutdown();
1905 break;
1906 }
1907
1908 default:
1909 // decoder flush completes only occur in a flushing state.
1910 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1911 break;
1912 }
1913}
1914
1915void NuPlayer2::finishFlushIfPossible() {
1916 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1917 && mFlushingAudio != SHUT_DOWN) {
1918 return;
1919 }
1920
1921 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1922 && mFlushingVideo != SHUT_DOWN) {
1923 return;
1924 }
1925
1926 ALOGV("both audio and video are flushed now.");
1927
1928 mFlushingAudio = NONE;
1929 mFlushingVideo = NONE;
1930
1931 clearFlushComplete();
1932
1933 processDeferredActions();
1934}
1935
1936void NuPlayer2::postScanSources() {
1937 if (mScanSourcesPending) {
1938 return;
1939 }
1940
1941 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1942 msg->setInt32("generation", mScanSourcesGeneration);
1943 msg->post();
1944
1945 mScanSourcesPending = true;
1946}
1947
1948void NuPlayer2::tryOpenAudioSinkForOffload(
1949 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1950 // Note: This is called early in NuPlayer2 to determine whether offloading
1951 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1952
1953 status_t err = mRenderer->openAudioSink(
1954 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001955 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001956 if (err != OK) {
1957 // Any failure we turn off mOffloadAudio.
1958 mOffloadAudio = false;
1959 } else if (mOffloadAudio) {
1960 sendMetaDataToHal(mAudioSink, audioMeta);
1961 }
1962}
1963
1964void NuPlayer2::closeAudioSink() {
1965 mRenderer->closeAudioSink();
1966}
1967
1968void NuPlayer2::restartAudio(
1969 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1970 if (mAudioDecoder != NULL) {
1971 mAudioDecoder->pause();
Ray Essick372e8f22019-02-11 11:38:31 -08001972 Mutex::Autolock autoLock(mDecoderLock);
Wei Jia53692fa2017-12-11 10:33:46 -08001973 mAudioDecoder.clear();
1974 mAudioDecoderError = false;
1975 ++mAudioDecoderGeneration;
1976 }
1977 if (mFlushingAudio == FLUSHING_DECODER) {
1978 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1979 mFlushingAudio = FLUSHED;
1980 finishFlushIfPossible();
1981 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1982 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1983 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1984 mFlushingAudio = SHUT_DOWN;
1985 finishFlushIfPossible();
1986 needsToCreateAudioDecoder = false;
1987 }
1988 if (mRenderer == NULL) {
1989 return;
1990 }
1991 closeAudioSink();
1992 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1993 if (mVideoDecoder != NULL) {
Dichen Zhang8bd4d392019-02-13 10:38:06 -08001994 mDeferredActions.push_back(
1995 new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
1996 FLUSH_CMD_FLUSH /* video */));
1997 mDeferredActions.push_back(
1998 new SeekAction(currentPositionUs,
1999 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
2000 // After a flush without shutdown, decoder is paused.
2001 // Don't resume it until source seek is done, otherwise it could
2002 // start pulling stale data too soon.
2003 mDeferredActions.push_back(new ResumeDecoderAction(false));
2004 processDeferredActions();
2005 } else {
2006 performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
Wei Jia53692fa2017-12-11 10:33:46 -08002007 }
2008
Wei Jia53692fa2017-12-11 10:33:46 -08002009 if (forceNonOffload) {
2010 mRenderer->signalDisableOffloadAudio();
2011 mOffloadAudio = false;
2012 }
2013 if (needsToCreateAudioDecoder) {
2014 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
2015 }
2016}
2017
2018void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002019 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002020 return;
2021 }
2022
2023 if (mRenderer == NULL) {
2024 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
2025 mOffloadAudio = false;
2026 return;
2027 }
2028
Wei Jiaf01e3122018-10-18 11:49:44 -07002029 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
2030 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002031 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
2032 const bool hasVideo = (videoFormat != NULL);
Dongwon Kangcd0e4272018-11-15 10:49:14 -08002033 bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
Wei Jiaf01e3122018-10-18 11:49:44 -07002034 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08002035 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2036
2037 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08002038 if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08002039 canOffload = false;
2040 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2041 }
2042
2043 if (canOffload) {
2044 if (!mOffloadAudio) {
2045 mRenderer->signalEnableOffloadAudio();
2046 }
2047 // open audio sink early under offload mode.
2048 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2049 } else {
2050 if (mOffloadAudio) {
2051 mRenderer->signalDisableOffloadAudio();
2052 mOffloadAudio = false;
2053 }
2054 }
2055}
2056
2057status_t NuPlayer2::instantiateDecoder(
2058 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2059 // The audio decoder could be cleared by tear down. If still in shut down
2060 // process, no need to create a new audio decoder.
2061 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2062 return OK;
2063 }
2064
Wei Jiaf01e3122018-10-18 11:49:44 -07002065 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002066
2067 if (format == NULL) {
2068 return UNKNOWN_ERROR;
2069 } else {
2070 status_t err;
2071 if (format->findInt32("err", &err) && err) {
2072 return err;
2073 }
2074 }
2075
2076 format->setInt32("priority", 0 /* realtime */);
2077
2078 if (!audio) {
2079 AString mime;
2080 CHECK(format->findString("mime", &mime));
2081
2082 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2083 if (mCCDecoder == NULL) {
2084 mCCDecoder = new CCDecoder(ccNotify);
2085 }
2086
Wei Jiaf01e3122018-10-18 11:49:44 -07002087 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002088 format->setInt32("secure", true);
2089 }
2090
Wei Jiaf01e3122018-10-18 11:49:44 -07002091 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002092 format->setInt32("protected", true);
2093 }
2094
2095 float rate = getFrameRate();
2096 if (rate > 0) {
2097 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2098 }
2099 }
2100
Ray Essick372e8f22019-02-11 11:38:31 -08002101 Mutex::Autolock autoLock(mDecoderLock);
2102
Wei Jia53692fa2017-12-11 10:33:46 -08002103 if (audio) {
2104 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2105 ++mAudioDecoderGeneration;
2106 notify->setInt32("generation", mAudioDecoderGeneration);
2107
2108 if (checkAudioModeChange) {
2109 determineAudioModeChange(format);
2110 }
2111 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002112 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002113
Wei Jiaf01e3122018-10-18 11:49:44 -07002114 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002115 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002116 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002117 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2118 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002119 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002120
Wei Jiaf01e3122018-10-18 11:49:44 -07002121 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002122 ALOGV("instantiateDecoder audio Decoder");
2123 }
2124 mAudioDecoderError = false;
2125 } else {
2126 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2127 ++mVideoDecoderGeneration;
2128 notify->setInt32("generation", mVideoDecoderGeneration);
2129
2130 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002131 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2132 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002133 mVideoDecoderError = false;
2134
2135 // enable FRC if high-quality AV sync is requested, even if not
2136 // directly queuing to display, as this will even improve textureview
2137 // playback.
2138 {
2139 if (property_get_bool("persist.sys.media.avsync", false)) {
2140 format->setInt32("auto-frc", 1);
2141 }
2142 }
2143 }
2144 (*decoder)->init();
2145
2146 // Modular DRM
Robert Shihc3fca0e2018-12-04 17:08:04 -08002147 if (mCurrentSourceInfo.mIsDrmProtected) {
2148 format->setObject("crypto", mCurrentSourceInfo.mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002149 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
Robert Shihc3fca0e2018-12-04 17:08:04 -08002150 mCurrentSourceInfo.mCrypto.get(),
2151 (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002152 }
2153
2154 (*decoder)->configure(format);
2155
2156 if (!audio) {
2157 sp<AMessage> params = new AMessage();
2158 float rate = getFrameRate();
2159 if (rate > 0) {
2160 params->setFloat("frame-rate-total", rate);
2161 }
2162
2163 sp<MetaData> fileMeta = getFileMeta();
2164 if (fileMeta != NULL) {
2165 int32_t videoTemporalLayerCount;
2166 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2167 && videoTemporalLayerCount > 0) {
2168 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2169 }
2170 }
2171
2172 if (params->countEntries() > 0) {
2173 (*decoder)->setParameters(params);
2174 }
2175 }
2176 return OK;
2177}
2178
2179void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002180 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002181 const sp<AMessage> &inputFormat,
2182 const sp<AMessage> &outputFormat) {
2183 if (inputFormat == NULL) {
2184 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002185 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002186 return;
2187 }
2188 int32_t err = OK;
2189 inputFormat->findInt32("err", &err);
2190 if (err == -EWOULDBLOCK) {
2191 ALOGW("Video meta is not available yet!");
2192 return;
2193 }
2194 if (err != OK) {
2195 ALOGW("Something is wrong with video meta!");
2196 return;
2197 }
2198
2199 int32_t displayWidth, displayHeight;
2200 if (outputFormat != NULL) {
2201 int32_t width, height;
2202 CHECK(outputFormat->findInt32("width", &width));
2203 CHECK(outputFormat->findInt32("height", &height));
2204
2205 int32_t cropLeft, cropTop, cropRight, cropBottom;
2206 CHECK(outputFormat->findRect(
2207 "crop",
2208 &cropLeft, &cropTop, &cropRight, &cropBottom));
2209
2210 displayWidth = cropRight - cropLeft + 1;
2211 displayHeight = cropBottom - cropTop + 1;
2212
2213 ALOGV("Video output format changed to %d x %d "
2214 "(crop: %d x %d @ (%d, %d))",
2215 width, height,
2216 displayWidth,
2217 displayHeight,
2218 cropLeft, cropTop);
2219 } else {
2220 CHECK(inputFormat->findInt32("width", &displayWidth));
2221 CHECK(inputFormat->findInt32("height", &displayHeight));
2222
2223 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2224 }
2225
2226 // Take into account sample aspect ratio if necessary:
2227 int32_t sarWidth, sarHeight;
2228 if (inputFormat->findInt32("sar-width", &sarWidth)
2229 && inputFormat->findInt32("sar-height", &sarHeight)
2230 && sarWidth > 0 && sarHeight > 0) {
2231 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2232
2233 displayWidth = (displayWidth * sarWidth) / sarHeight;
2234
2235 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2236 } else {
2237 int32_t width, height;
2238 if (inputFormat->findInt32("display-width", &width)
2239 && inputFormat->findInt32("display-height", &height)
2240 && width > 0 && height > 0
2241 && displayWidth > 0 && displayHeight > 0) {
2242 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2243 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2244 } else {
2245 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2246 }
2247 ALOGV("Video display width and height are overridden to %d x %d",
2248 displayWidth, displayHeight);
2249 }
2250 }
2251
2252 int32_t rotationDegrees;
2253 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2254 rotationDegrees = 0;
2255 }
2256
2257 if (rotationDegrees == 90 || rotationDegrees == 270) {
2258 int32_t tmp = displayWidth;
2259 displayWidth = displayHeight;
2260 displayHeight = tmp;
2261 }
2262
2263 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002264 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002265 MEDIA2_SET_VIDEO_SIZE,
2266 displayWidth,
2267 displayHeight);
2268}
2269
Dongwon Kang41929fb2018-09-09 08:29:56 -07002270void NuPlayer2::notifyListener(
2271 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002272 if (mDriver == NULL) {
2273 return;
2274 }
2275
2276 sp<NuPlayer2Driver> driver = mDriver.promote();
2277
2278 if (driver == NULL) {
2279 return;
2280 }
2281
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002282 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002283}
2284
2285void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2286 ALOGV("[%s] flushDecoder needShutdown=%d",
2287 audio ? "audio" : "video", needShutdown);
2288
2289 const sp<DecoderBase> &decoder = getDecoder(audio);
2290 if (decoder == NULL) {
2291 ALOGI("flushDecoder %s without decoder present",
2292 audio ? "audio" : "video");
2293 return;
2294 }
2295
2296 // Make sure we don't continue to scan sources until we finish flushing.
2297 ++mScanSourcesGeneration;
2298 if (mScanSourcesPending) {
2299 if (!needShutdown) {
2300 mDeferredActions.push_back(
2301 new SimpleAction(&NuPlayer2::performScanSources));
2302 }
2303 mScanSourcesPending = false;
2304 }
2305
2306 decoder->signalFlush();
2307
2308 FlushStatus newStatus =
2309 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2310
2311 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2312 mFlushComplete[audio][true /* isDecoder */] = false;
2313 if (audio) {
2314 ALOGE_IF(mFlushingAudio != NONE,
2315 "audio flushDecoder() is called in state %d", mFlushingAudio);
2316 mFlushingAudio = newStatus;
2317 } else {
2318 ALOGE_IF(mFlushingVideo != NONE,
2319 "video flushDecoder() is called in state %d", mFlushingVideo);
2320 mFlushingVideo = newStatus;
2321 }
2322}
2323
2324void NuPlayer2::queueDecoderShutdown(
2325 bool audio, bool video, const sp<AMessage> &reply) {
2326 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2327
2328 mDeferredActions.push_back(
2329 new FlushDecoderAction(
2330 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2331 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2332
2333 mDeferredActions.push_back(
2334 new SimpleAction(&NuPlayer2::performScanSources));
2335
2336 mDeferredActions.push_back(new PostMessageAction(reply));
2337
2338 processDeferredActions();
2339}
2340
2341status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2342 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002343 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2344 status_t ret = native_window_set_scaling_mode(
2345 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002346 if (ret != OK) {
2347 ALOGE("Failed to set scaling mode (%d): %s",
2348 -ret, strerror(-ret));
2349 return ret;
2350 }
2351 }
2352 return OK;
2353}
2354
Wei Jia17944af2018-12-13 18:13:10 -08002355status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002356 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Wei Jia17944af2018-12-13 18:13:10 -08002357 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002358 msg->setPointer("reply", reply);
2359
2360 sp<AMessage> response;
2361 status_t err = msg->postAndAwaitResponse(&response);
2362 return err;
2363}
2364
Wei Jia17944af2018-12-13 18:13:10 -08002365status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002366 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2367 msg->setPointer("reply", reply);
Wei Jia17944af2018-12-13 18:13:10 -08002368 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002369 msg->setInt32("type", type);
2370
2371 sp<AMessage> response;
2372 status_t err = msg->postAndAwaitResponse(&response);
2373 if (err == OK && response != NULL) {
2374 CHECK(response->findInt32("err", &err));
2375 }
2376 return err;
2377}
2378
Wei Jia17944af2018-12-13 18:13:10 -08002379status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
Wei Jia53692fa2017-12-11 10:33:46 -08002380 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Wei Jia17944af2018-12-13 18:13:10 -08002381 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002382 msg->setSize("trackIndex", trackIndex);
2383 msg->setInt32("select", select);
2384 msg->setInt64("timeUs", timeUs);
2385
2386 sp<AMessage> response;
2387 status_t err = msg->postAndAwaitResponse(&response);
2388
2389 if (err != OK) {
2390 return err;
2391 }
2392
2393 if (!response->findInt32("err", &err)) {
2394 err = OK;
2395 }
2396
2397 return err;
2398}
2399
2400status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2401 sp<Renderer> renderer = mRenderer;
2402 if (renderer == NULL) {
2403 return NO_INIT;
2404 }
2405
2406 return renderer->getCurrentPosition(mediaUs);
2407}
2408
2409void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2410 CHECK(mTrackStats != NULL);
2411
2412 mTrackStats->clear();
Ray Essick372e8f22019-02-11 11:38:31 -08002413
2414 Mutex::Autolock autoLock(mDecoderLock);
Wei Jia53692fa2017-12-11 10:33:46 -08002415 if (mVideoDecoder != NULL) {
2416 mTrackStats->push_back(mVideoDecoder->getStats());
2417 }
2418 if (mAudioDecoder != NULL) {
2419 mTrackStats->push_back(mAudioDecoder->getStats());
2420 }
2421}
2422
2423sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002424 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002425}
2426
2427float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002428 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002429 if (meta == NULL) {
2430 return 0;
2431 }
2432 int32_t rate;
2433 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2434 // fall back to try file meta
2435 sp<MetaData> fileMeta = getFileMeta();
2436 if (fileMeta == NULL) {
2437 ALOGW("source has video meta but not file meta");
2438 return -1;
2439 }
2440 int32_t fileMetaRate;
2441 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2442 return -1;
2443 }
2444 return fileMetaRate;
2445 }
2446 return rate;
2447}
2448
2449void NuPlayer2::schedulePollDuration() {
2450 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2451 msg->setInt32("generation", mPollDurationGeneration);
2452 msg->post();
2453}
2454
2455void NuPlayer2::cancelPollDuration() {
2456 ++mPollDurationGeneration;
2457}
2458
2459void NuPlayer2::processDeferredActions() {
2460 while (!mDeferredActions.empty()) {
2461 // We won't execute any deferred actions until we're no longer in
2462 // an intermediate state, i.e. one more more decoders are currently
2463 // flushing or shutting down.
2464
2465 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2466 // We're currently flushing, postpone the reset until that's
2467 // completed.
2468
2469 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2470 mFlushingAudio, mFlushingVideo);
2471
2472 break;
2473 }
2474
2475 sp<Action> action = *mDeferredActions.begin();
2476 mDeferredActions.erase(mDeferredActions.begin());
2477
2478 action->execute(this);
2479 }
2480}
2481
2482void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2483 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2484 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2485
Wei Jiaf01e3122018-10-18 11:49:44 -07002486 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002487 // This happens when reset occurs right before the loop mode
2488 // asynchronously seeks to the start of the stream.
2489 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002490 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002491 mAudioDecoder.get(), mVideoDecoder.get());
2492 return;
2493 }
2494 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002495 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002496 ++mTimedTextGeneration;
2497
2498 // everything's flushed, continue playback.
2499}
2500
2501void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2502 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2503
2504 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2505 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2506 return;
2507 }
2508
2509 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2510 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2511 }
2512
2513 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2514 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2515 }
2516}
2517
2518void NuPlayer2::performReset() {
2519 ALOGV("performReset");
2520
2521 CHECK(mAudioDecoder == NULL);
2522 CHECK(mVideoDecoder == NULL);
2523
2524 stopPlaybackTimer("performReset");
2525 stopRebufferingTimer(true);
2526
2527 cancelPollDuration();
2528
2529 ++mScanSourcesGeneration;
2530 mScanSourcesPending = false;
2531
2532 if (mRendererLooper != NULL) {
2533 if (mRenderer != NULL) {
2534 mRendererLooper->unregisterHandler(mRenderer->id());
2535 }
2536 mRendererLooper->stop();
2537 mRendererLooper.clear();
2538 }
2539 mRenderer.clear();
2540 ++mRendererGeneration;
2541
Robert Shihc3fca0e2018-12-04 17:08:04 -08002542 resetSourceInfo(mCurrentSourceInfo);
2543 resetSourceInfo(mNextSourceInfo);
Wei Jia53692fa2017-12-11 10:33:46 -08002544
2545 if (mDriver != NULL) {
2546 sp<NuPlayer2Driver> driver = mDriver.promote();
2547 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002548 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002549 }
2550 }
2551
2552 mStarted = false;
2553 mPrepared = false;
2554 mResetting = false;
2555 mSourceStarted = false;
2556
Wei Jia53692fa2017-12-11 10:33:46 -08002557}
2558
Wei Jia57aeffd2018-02-15 16:01:14 -08002559void NuPlayer2::performPlayNextDataSource() {
2560 ALOGV("performPlayNextDataSource");
2561
2562 CHECK(mAudioDecoder == NULL);
2563 CHECK(mVideoDecoder == NULL);
2564
2565 stopPlaybackTimer("performPlayNextDataSource");
2566 stopRebufferingTimer(true);
2567
2568 cancelPollDuration();
2569
2570 ++mScanSourcesGeneration;
2571 mScanSourcesPending = false;
2572
2573 ++mRendererGeneration;
2574
Wei Jiaf01e3122018-10-18 11:49:44 -07002575 if (mCurrentSourceInfo.mSource != NULL) {
2576 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002577 }
2578
2579 long previousSrcId;
2580 {
2581 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002582 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002583
2584 mCurrentSourceInfo = mNextSourceInfo;
2585 mNextSourceInfo = SourceInfo();
2586 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002587 }
2588
2589 if (mDriver != NULL) {
2590 sp<NuPlayer2Driver> driver = mDriver.promote();
2591 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002592 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002593
2594 int64_t durationUs;
2595 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2596 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2597 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002598 notifyListener(
2599 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002600 }
2601 }
2602
2603 mStarted = false;
2604 mPrepared = true; // TODO: what if it's not prepared
2605 mResetting = false;
2606 mSourceStarted = false;
2607
Wei Jiad1864f92018-10-19 12:34:56 -07002608 addEndTimeMonitor();
2609
Wei Jia57aeffd2018-02-15 16:01:14 -08002610 if (mRenderer != NULL) {
2611 mRenderer->resume();
2612 }
2613
Wei Jia6376cd52018-09-26 11:42:55 -07002614 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002615 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002616 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002617}
2618
Wei Jia53692fa2017-12-11 10:33:46 -08002619void NuPlayer2::performScanSources() {
2620 ALOGV("performScanSources");
2621
2622 if (!mStarted) {
2623 return;
2624 }
2625
2626 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2627 postScanSources();
2628 }
2629}
2630
Wei Jia28288fb2017-12-15 13:45:29 -08002631void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002632 ALOGV("performSetSurface");
2633
Wei Jia28288fb2017-12-15 13:45:29 -08002634 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002635
2636 // XXX - ignore error from setVideoScalingMode for now
2637 setVideoScalingMode(mVideoScalingMode);
2638
2639 if (mDriver != NULL) {
2640 sp<NuPlayer2Driver> driver = mDriver.promote();
2641 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002642 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002643 }
2644 }
2645}
2646
2647void NuPlayer2::performResumeDecoders(bool needNotify) {
2648 if (needNotify) {
2649 mResumePending = true;
2650 if (mVideoDecoder == NULL) {
2651 // if audio-only, we can notify seek complete now,
2652 // as the resume operation will be relatively fast.
2653 finishResume();
2654 }
2655 }
2656
2657 if (mVideoDecoder != NULL) {
2658 // When there is continuous seek, MediaPlayer will cache the seek
2659 // position, and send down new seek request when previous seek is
2660 // complete. Let's wait for at least one video output frame before
2661 // notifying seek complete, so that the video thumbnail gets updated
2662 // when seekbar is dragged.
2663 mVideoDecoder->signalResume(needNotify);
2664 }
2665
2666 if (mAudioDecoder != NULL) {
2667 mAudioDecoder->signalResume(false /* needNotify */);
2668 }
2669}
2670
2671void NuPlayer2::finishResume() {
2672 if (mResumePending) {
2673 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002674 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002675 }
2676}
2677
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002678void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002679 if (mDriver != NULL) {
2680 sp<NuPlayer2Driver> driver = mDriver.promote();
2681 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002682 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002683 }
2684 }
2685}
2686
2687void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2688 int32_t what;
2689 CHECK(msg->findInt32("what", &what));
2690
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002691 int64_t srcId;
2692 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002693 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002694 case Source::kWhatPrepared:
2695 {
Wei Jiad1864f92018-10-19 12:34:56 -07002696 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2697 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2698 if (srcId == mCurrentSourceInfo.mSrcId) {
2699 if (mCurrentSourceInfo.mSource == NULL) {
2700 // This is a stale notification from a source that was
2701 // asynchronously preparing when the client called reset().
2702 // We handled the reset, the source is gone.
2703 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002704 }
Wei Jiad1864f92018-10-19 12:34:56 -07002705
2706 int32_t err;
2707 CHECK(msg->findInt32("err", &err));
2708
2709 if (err != OK) {
2710 // shut down potential secure codecs in case client never calls reset
2711 mDeferredActions.push_back(
2712 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2713 FLUSH_CMD_SHUTDOWN /* video */));
2714 processDeferredActions();
2715 } else {
2716 mPrepared = true;
2717 }
2718
2719 sp<NuPlayer2Driver> driver = mDriver.promote();
2720 if (driver != NULL) {
2721 // notify duration first, so that it's definitely set when
2722 // the app received the "prepare complete" callback.
2723 int64_t durationUs;
2724 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2725 driver->notifyDuration(srcId, durationUs);
2726 }
2727 driver->notifyPrepareCompleted(srcId, err);
2728 }
2729 } else if (srcId == mNextSourceInfo.mSrcId) {
2730 if (mNextSourceInfo.mSource == NULL) {
2731 break; // stale
2732 }
2733
2734 sp<NuPlayer2Driver> driver = mDriver.promote();
2735 if (driver != NULL) {
2736 int32_t err;
2737 CHECK(msg->findInt32("err", &err));
2738 driver->notifyPrepareCompleted(srcId, err);
2739 }
Wei Jia53692fa2017-12-11 10:33:46 -08002740 }
2741
2742 break;
2743 }
2744
2745 // Modular DRM
2746 case Source::kWhatDrmInfo:
2747 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002748 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002749 sp<ABuffer> drmInfo;
2750 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002751 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002752
Dongwon Kang41929fb2018-09-09 08:29:56 -07002753 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2754 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002755
Dongwon Kang41929fb2018-09-09 08:29:56 -07002756 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002757
2758 break;
2759 }
2760
2761 case Source::kWhatFlagsChanged:
2762 {
2763 uint32_t flags;
2764 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2765
2766 sp<NuPlayer2Driver> driver = mDriver.promote();
2767 if (driver != NULL) {
2768
2769 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2770 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2771 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2772 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2773 (flags & Source::FLAG_CAN_PAUSE) != 0,
2774 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2775 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2776 (flags & Source::FLAG_CAN_SEEK) != 0,
2777 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2778 (flags & Source::FLAG_SECURE) != 0,
2779 (flags & Source::FLAG_PROTECTED) != 0);
2780
2781 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2782 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002783 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002784 }
Wei Jiad1864f92018-10-19 12:34:56 -07002785 if (srcId == mCurrentSourceInfo.mSrcId) {
2786 driver->notifyFlagsChanged(srcId, flags);
2787 }
Wei Jia53692fa2017-12-11 10:33:46 -08002788 }
2789
Wei Jiaf01e3122018-10-18 11:49:44 -07002790 if (srcId == mCurrentSourceInfo.mSrcId) {
2791 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2792 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2793 cancelPollDuration();
2794 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2795 && (flags & Source::FLAG_DYNAMIC_DURATION)
2796 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2797 schedulePollDuration();
2798 }
Wei Jia53692fa2017-12-11 10:33:46 -08002799
Wei Jiaf01e3122018-10-18 11:49:44 -07002800 mCurrentSourceInfo.mSourceFlags = flags;
2801 } else if (srcId == mNextSourceInfo.mSrcId) {
2802 // TODO: handle duration polling for next source.
2803 mNextSourceInfo.mSourceFlags = flags;
2804 }
Wei Jia53692fa2017-12-11 10:33:46 -08002805 break;
2806 }
2807
2808 case Source::kWhatVideoSizeChanged:
2809 {
2810 sp<AMessage> format;
2811 CHECK(msg->findMessage("format", &format));
2812
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002813 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002814 break;
2815 }
2816
2817 case Source::kWhatBufferingUpdate:
2818 {
2819 int32_t percentage;
2820 CHECK(msg->findInt32("percentage", &percentage));
2821
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002822 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002823 break;
2824 }
2825
2826 case Source::kWhatPauseOnBufferingStart:
2827 {
2828 // ignore if not playing
2829 if (mStarted) {
2830 ALOGI("buffer low, pausing...");
2831
2832 startRebufferingTimer();
2833 mPausedForBuffering = true;
2834 onPause();
2835 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002836 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002837 break;
2838 }
2839
2840 case Source::kWhatResumeOnBufferingEnd:
2841 {
2842 // ignore if not playing
2843 if (mStarted) {
2844 ALOGI("buffer ready, resuming...");
2845
2846 stopRebufferingTimer(false);
2847 mPausedForBuffering = false;
2848
2849 // do not resume yet if client didn't unpause
2850 if (!mPausedByClient) {
2851 onResume();
2852 }
2853 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002854 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002855 break;
2856 }
2857
2858 case Source::kWhatCacheStats:
2859 {
2860 int32_t kbps;
2861 CHECK(msg->findInt32("bandwidth", &kbps));
2862
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002863 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002864 break;
2865 }
2866
2867 case Source::kWhatSubtitleData:
2868 {
2869 sp<ABuffer> buffer;
2870 CHECK(msg->findBuffer("buffer", &buffer));
2871
2872 sendSubtitleData(buffer, 0 /* baseIndex */);
2873 break;
2874 }
2875
2876 case Source::kWhatTimedMetaData:
2877 {
2878 sp<ABuffer> buffer;
2879 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002880 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002881 } else {
2882 sendTimedMetaData(buffer);
2883 }
2884 break;
2885 }
2886
2887 case Source::kWhatTimedTextData:
2888 {
2889 int32_t generation;
2890 if (msg->findInt32("generation", &generation)
2891 && generation != mTimedTextGeneration) {
2892 break;
2893 }
2894
2895 sp<ABuffer> buffer;
2896 CHECK(msg->findBuffer("buffer", &buffer));
2897
2898 sp<NuPlayer2Driver> driver = mDriver.promote();
2899 if (driver == NULL) {
2900 break;
2901 }
2902
Wei Jia800fe372018-02-20 15:00:45 -08002903 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002904 int64_t timeUs, posUs;
2905 driver->getCurrentPosition(&posMs);
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08002906 posUs = posMs * 1000LL;
Wei Jia53692fa2017-12-11 10:33:46 -08002907 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2908
2909 if (posUs < timeUs) {
2910 if (!msg->findInt32("generation", &generation)) {
2911 msg->setInt32("generation", mTimedTextGeneration);
2912 }
2913 msg->post(timeUs - posUs);
2914 } else {
2915 sendTimedTextData(buffer);
2916 }
2917 break;
2918 }
2919
2920 case Source::kWhatQueueDecoderShutdown:
2921 {
2922 int32_t audio, video;
2923 CHECK(msg->findInt32("audio", &audio));
2924 CHECK(msg->findInt32("video", &video));
2925
2926 sp<AMessage> reply;
2927 CHECK(msg->findMessage("reply", &reply));
2928
2929 queueDecoderShutdown(audio, video, reply);
2930 break;
2931 }
2932
2933 case Source::kWhatDrmNoLicense:
2934 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002935 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002936 break;
2937 }
2938
2939 default:
2940 TRESPASS();
2941 }
2942}
2943
2944void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2945 int32_t what;
2946 CHECK(msg->findInt32("what", &what));
2947
2948 switch (what) {
2949 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2950 {
2951 sp<ABuffer> buffer;
2952 CHECK(msg->findBuffer("buffer", &buffer));
2953
2954 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002955 if (mCurrentSourceInfo.mSource != NULL) {
2956 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002957 }
2958
2959 sendSubtitleData(buffer, inbandTracks);
2960 break;
2961 }
2962
2963 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2964 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002965 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002966
2967 break;
2968 }
2969
2970 default:
2971 TRESPASS();
2972 }
2973
2974
2975}
2976
2977void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2978 int32_t trackIndex;
2979 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002980 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002981 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2982 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2983
Dongwon Kang41929fb2018-09-09 08:29:56 -07002984 PlayerMessage playerMsg;
2985 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2986 playerMsg.add_values()->set_int64_value(timeUs);
2987 playerMsg.add_values()->set_int64_value(durationUs);
2988 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002989
Wei Jiaf01e3122018-10-18 11:49:44 -07002990 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002991}
2992
2993void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2994 int64_t timeUs;
2995 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2996
Dongwon Kang41929fb2018-09-09 08:29:56 -07002997 PlayerMessage playerMsg;
2998 playerMsg.add_values()->set_int64_value(timeUs);
2999 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08003000
Wei Jiaf01e3122018-10-18 11:49:44 -07003001 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003002}
3003
3004void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
3005 const void *data;
3006 size_t size = 0;
3007 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003008 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08003009
3010 AString mime;
3011 CHECK(buffer->meta()->findString("mime", &mime));
3012 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
3013
3014 data = buffer->data();
3015 size = buffer->size();
3016
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003017 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08003018 if (size > 0) {
3019 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3020 int32_t global = 0;
3021 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003022 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003023 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003024 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003025 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003026 TextDescriptions2::getPlayerMessageOfDescriptions(
3027 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003028 }
3029
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003030 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003031 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003032 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003033 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003034 }
3035}
3036
3037const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003038 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003039 case DATA_SOURCE_TYPE_HTTP_LIVE:
3040 return "HTTPLive";
3041
3042 case DATA_SOURCE_TYPE_RTSP:
3043 return "RTSP";
3044
3045 case DATA_SOURCE_TYPE_GENERIC_URL:
3046 return "GenURL";
3047
3048 case DATA_SOURCE_TYPE_GENERIC_FD:
3049 return "GenFD";
3050
3051 case DATA_SOURCE_TYPE_MEDIA:
3052 return "Media";
3053
Wei Jia53692fa2017-12-11 10:33:46 -08003054 case DATA_SOURCE_TYPE_NONE:
3055 default:
3056 return "None";
3057 }
3058 }
3059
Robert Shihc3fca0e2018-12-04 17:08:04 -08003060NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
3061 int64_t srcId;
3062 CHECK(msg->findInt64("srcId", &srcId));
3063 if (mCurrentSourceInfo.mSrcId == srcId) {
3064 return &mCurrentSourceInfo;
3065 } else if (mNextSourceInfo.mSrcId == srcId) {
3066 return &mNextSourceInfo;
3067 } else {
3068 return NULL;
3069 }
3070}
3071
3072void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
3073 if (srcInfo.mSource != NULL) {
3074 srcInfo.mSource->stop();
3075
3076 Mutex::Autolock autoLock(mSourceLock);
3077 srcInfo.mSource.clear();
3078 }
3079 // Modular DRM
3080 ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
3081 srcInfo.mCrypto.clear();
3082 srcInfo.mIsDrmProtected = false;
3083}
3084
Wei Jia53692fa2017-12-11 10:33:46 -08003085// Modular DRM begin
Robert Shih3c3728d2018-12-04 17:06:36 -08003086status_t NuPlayer2::prepareDrm(
3087 int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
Wei Jia53692fa2017-12-11 10:33:46 -08003088{
3089 ALOGV("prepareDrm ");
3090
3091 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3092 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3093 // synchronous call so just passing the address but with local copies of "const" args
3094 uint8_t UUID[16];
3095 memcpy(UUID, uuid, sizeof(UUID));
3096 Vector<uint8_t> sessionId = drmSessionId;
Robert Shih3c3728d2018-12-04 17:06:36 -08003097 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003098 msg->setPointer("uuid", (void*)UUID);
3099 msg->setPointer("drmSessionId", (void*)&sessionId);
3100
3101 sp<AMessage> response;
3102 status_t status = msg->postAndAwaitResponse(&response);
3103
3104 if (status == OK && response != NULL) {
3105 CHECK(response->findInt32("status", &status));
3106 ALOGV("prepareDrm ret: %d ", status);
3107 } else {
3108 ALOGE("prepareDrm err: %d", status);
3109 }
3110
3111 return status;
3112}
3113
Robert Shih3c3728d2018-12-04 17:06:36 -08003114status_t NuPlayer2::releaseDrm(int64_t srcId)
Wei Jia53692fa2017-12-11 10:33:46 -08003115{
3116 ALOGV("releaseDrm ");
3117
3118 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
Robert Shih3c3728d2018-12-04 17:06:36 -08003119 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003120
3121 sp<AMessage> response;
3122 status_t status = msg->postAndAwaitResponse(&response);
3123
3124 if (status == OK && response != NULL) {
3125 CHECK(response->findInt32("status", &status));
3126 ALOGV("releaseDrm ret: %d ", status);
3127 } else {
3128 ALOGE("releaseDrm err: %d", status);
3129 }
3130
3131 return status;
3132}
3133
3134status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3135{
3136 // TODO change to ALOGV
3137 ALOGD("onPrepareDrm ");
3138
3139 status_t status = INVALID_OPERATION;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003140 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
3141 if (srcInfo == NULL) {
3142 return status;
3143 }
3144
3145 int64_t srcId = srcInfo->mSrcId;
3146 if (srcInfo->mSource == NULL) {
3147 ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
3148 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003149 return status;
3150 }
3151
3152 uint8_t *uuid;
3153 Vector<uint8_t> *drmSessionId;
3154 CHECK(msg->findPointer("uuid", (void**)&uuid));
3155 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3156
3157 status = OK;
3158 sp<AMediaCryptoWrapper> crypto = NULL;
3159
Robert Shihc3fca0e2018-12-04 17:08:04 -08003160 status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003161 if (crypto == NULL) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08003162 ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
3163 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003164 return status;
3165 }
Robert Shihc3fca0e2018-12-04 17:08:04 -08003166 ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003167
Robert Shihc3fca0e2018-12-04 17:08:04 -08003168 if (srcInfo->mCrypto != NULL) {
3169 ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
3170 (long long)srcId, srcInfo->mCrypto.get());
3171 srcInfo->mCrypto.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08003172 }
3173
Robert Shihc3fca0e2018-12-04 17:08:04 -08003174 srcInfo->mCrypto = crypto;
3175 srcInfo->mIsDrmProtected = true;
Wei Jia53692fa2017-12-11 10:33:46 -08003176 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003177 ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08003178
3179 return status;
3180}
3181
Robert Shihc3fca0e2018-12-04 17:08:04 -08003182status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
Wei Jia53692fa2017-12-11 10:33:46 -08003183{
3184 // TODO change to ALOGV
3185 ALOGD("onReleaseDrm ");
Robert Shihc3fca0e2018-12-04 17:08:04 -08003186 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
3187 if (srcInfo == NULL) {
3188 return INVALID_OPERATION;
Wei Jia53692fa2017-12-11 10:33:46 -08003189 }
3190
Robert Shihc3fca0e2018-12-04 17:08:04 -08003191 int64_t srcId = srcInfo->mSrcId;
3192 if (!srcInfo->mIsDrmProtected) {
3193 ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
3194 (long long)srcId);
3195 }
3196
3197 srcInfo->mIsDrmProtected = false;
Wei Jia53692fa2017-12-11 10:33:46 -08003198
3199 status_t status;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003200 if (srcInfo->mCrypto != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003201 // notifying the source first before removing crypto from codec
Robert Shihc3fca0e2018-12-04 17:08:04 -08003202 if (srcInfo->mSource != NULL) {
3203 srcInfo->mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003204 }
3205
3206 status=OK;
3207 // first making sure the codecs have released their crypto reference
3208 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3209 if (videoDecoder != NULL) {
3210 status = videoDecoder->releaseCrypto();
3211 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3212 }
3213
3214 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3215 if (audioDecoder != NULL) {
3216 status_t status_audio = audioDecoder->releaseCrypto();
3217 if (status == OK) { // otherwise, returning the first error
3218 status = status_audio;
3219 }
3220 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3221 }
3222
3223 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003224 ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
3225 srcInfo->mCrypto.clear();
3226 } else { // srcInfo->mCrypto == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08003227 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3228 status = INVALID_OPERATION;
3229 }
3230
3231 return status;
3232}
3233// Modular DRM end
3234////////////////////////////////////////////////////////////////////////////////
3235
3236sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3237 sp<MetaData> meta = getFormatMeta(audio);
3238
3239 if (meta == NULL) {
3240 return NULL;
3241 }
3242
3243 sp<AMessage> msg = new AMessage;
3244
3245 if(convertMetaDataToMessage(meta, &msg) == OK) {
3246 return msg;
3247 }
3248 return NULL;
3249}
3250
3251void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3252 sp<AMessage> notify = dupNotify();
3253 notify->setInt32("what", kWhatFlagsChanged);
3254 notify->setInt32("flags", flags);
3255 notify->post();
3256}
3257
3258void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3259 sp<AMessage> notify = dupNotify();
3260 notify->setInt32("what", kWhatVideoSizeChanged);
3261 notify->setMessage("format", format);
3262 notify->post();
3263}
3264
3265void NuPlayer2::Source::notifyPrepared(status_t err) {
3266 ALOGV("Source::notifyPrepared %d", err);
3267 sp<AMessage> notify = dupNotify();
3268 notify->setInt32("what", kWhatPrepared);
3269 notify->setInt32("err", err);
3270 notify->post();
3271}
3272
3273void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3274{
3275 ALOGV("Source::notifyDrmInfo");
3276
3277 sp<AMessage> notify = dupNotify();
3278 notify->setInt32("what", kWhatDrmInfo);
3279 notify->setBuffer("drmInfo", drmInfoBuffer);
3280
3281 notify->post();
3282}
3283
Wei Jia53692fa2017-12-11 10:33:46 -08003284void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3285 TRESPASS();
3286}
3287
Wei Jiaf01e3122018-10-18 11:49:44 -07003288NuPlayer2::SourceInfo::SourceInfo()
3289 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3290 mSrcId(0),
3291 mSourceFlags(0),
3292 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003293 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003294}
3295
Wei Jiad1864f92018-10-19 12:34:56 -07003296NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3297 mSource = other.mSource;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003298 mCrypto = other.mCrypto;
Wei Jiad1864f92018-10-19 12:34:56 -07003299 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3300 mSrcId = other.mSrcId;
3301 mSourceFlags = other.mSourceFlags;
3302 mStartTimeUs = other.mStartTimeUs;
3303 mEndTimeUs = other.mEndTimeUs;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003304 mIsDrmProtected = other.mIsDrmProtected;
Wei Jiad1864f92018-10-19 12:34:56 -07003305 return *this;
3306}
3307
Wei Jia53692fa2017-12-11 10:33:46 -08003308} // namespace android