blob: 100cdaed2d317696d0649981313dd7f923180e05 [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) {
1994 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1995 }
1996
1997 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1998
1999 if (forceNonOffload) {
2000 mRenderer->signalDisableOffloadAudio();
2001 mOffloadAudio = false;
2002 }
2003 if (needsToCreateAudioDecoder) {
2004 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
2005 }
2006}
2007
2008void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002009 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002010 return;
2011 }
2012
2013 if (mRenderer == NULL) {
2014 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
2015 mOffloadAudio = false;
2016 return;
2017 }
2018
Wei Jiaf01e3122018-10-18 11:49:44 -07002019 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
2020 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002021 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
2022 const bool hasVideo = (videoFormat != NULL);
Dongwon Kangcd0e4272018-11-15 10:49:14 -08002023 bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
Wei Jiaf01e3122018-10-18 11:49:44 -07002024 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08002025 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
2026
2027 // Modular DRM: Disabling audio offload if the source is protected
Robert Shihc3fca0e2018-12-04 17:08:04 -08002028 if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
Wei Jia53692fa2017-12-11 10:33:46 -08002029 canOffload = false;
2030 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
2031 }
2032
2033 if (canOffload) {
2034 if (!mOffloadAudio) {
2035 mRenderer->signalEnableOffloadAudio();
2036 }
2037 // open audio sink early under offload mode.
2038 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
2039 } else {
2040 if (mOffloadAudio) {
2041 mRenderer->signalDisableOffloadAudio();
2042 mOffloadAudio = false;
2043 }
2044 }
2045}
2046
2047status_t NuPlayer2::instantiateDecoder(
2048 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
2049 // The audio decoder could be cleared by tear down. If still in shut down
2050 // process, no need to create a new audio decoder.
2051 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
2052 return OK;
2053 }
2054
Wei Jiaf01e3122018-10-18 11:49:44 -07002055 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08002056
2057 if (format == NULL) {
2058 return UNKNOWN_ERROR;
2059 } else {
2060 status_t err;
2061 if (format->findInt32("err", &err) && err) {
2062 return err;
2063 }
2064 }
2065
2066 format->setInt32("priority", 0 /* realtime */);
2067
2068 if (!audio) {
2069 AString mime;
2070 CHECK(format->findString("mime", &mime));
2071
2072 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
2073 if (mCCDecoder == NULL) {
2074 mCCDecoder = new CCDecoder(ccNotify);
2075 }
2076
Wei Jiaf01e3122018-10-18 11:49:44 -07002077 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08002078 format->setInt32("secure", true);
2079 }
2080
Wei Jiaf01e3122018-10-18 11:49:44 -07002081 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08002082 format->setInt32("protected", true);
2083 }
2084
2085 float rate = getFrameRate();
2086 if (rate > 0) {
2087 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
2088 }
2089 }
2090
Ray Essick372e8f22019-02-11 11:38:31 -08002091 Mutex::Autolock autoLock(mDecoderLock);
2092
Wei Jia53692fa2017-12-11 10:33:46 -08002093 if (audio) {
2094 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
2095 ++mAudioDecoderGeneration;
2096 notify->setInt32("generation", mAudioDecoderGeneration);
2097
2098 if (checkAudioModeChange) {
2099 determineAudioModeChange(format);
2100 }
2101 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002102 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002103
Wei Jiaf01e3122018-10-18 11:49:44 -07002104 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002105 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002106 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002107 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2108 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002109 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002110
Wei Jiaf01e3122018-10-18 11:49:44 -07002111 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002112 ALOGV("instantiateDecoder audio Decoder");
2113 }
2114 mAudioDecoderError = false;
2115 } else {
2116 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2117 ++mVideoDecoderGeneration;
2118 notify->setInt32("generation", mVideoDecoderGeneration);
2119
2120 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002121 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2122 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002123 mVideoDecoderError = false;
2124
2125 // enable FRC if high-quality AV sync is requested, even if not
2126 // directly queuing to display, as this will even improve textureview
2127 // playback.
2128 {
2129 if (property_get_bool("persist.sys.media.avsync", false)) {
2130 format->setInt32("auto-frc", 1);
2131 }
2132 }
2133 }
2134 (*decoder)->init();
2135
2136 // Modular DRM
Robert Shihc3fca0e2018-12-04 17:08:04 -08002137 if (mCurrentSourceInfo.mIsDrmProtected) {
2138 format->setObject("crypto", mCurrentSourceInfo.mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002139 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
Robert Shihc3fca0e2018-12-04 17:08:04 -08002140 mCurrentSourceInfo.mCrypto.get(),
2141 (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002142 }
2143
2144 (*decoder)->configure(format);
2145
2146 if (!audio) {
2147 sp<AMessage> params = new AMessage();
2148 float rate = getFrameRate();
2149 if (rate > 0) {
2150 params->setFloat("frame-rate-total", rate);
2151 }
2152
2153 sp<MetaData> fileMeta = getFileMeta();
2154 if (fileMeta != NULL) {
2155 int32_t videoTemporalLayerCount;
2156 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2157 && videoTemporalLayerCount > 0) {
2158 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2159 }
2160 }
2161
2162 if (params->countEntries() > 0) {
2163 (*decoder)->setParameters(params);
2164 }
2165 }
2166 return OK;
2167}
2168
2169void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002170 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002171 const sp<AMessage> &inputFormat,
2172 const sp<AMessage> &outputFormat) {
2173 if (inputFormat == NULL) {
2174 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002175 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002176 return;
2177 }
2178 int32_t err = OK;
2179 inputFormat->findInt32("err", &err);
2180 if (err == -EWOULDBLOCK) {
2181 ALOGW("Video meta is not available yet!");
2182 return;
2183 }
2184 if (err != OK) {
2185 ALOGW("Something is wrong with video meta!");
2186 return;
2187 }
2188
2189 int32_t displayWidth, displayHeight;
2190 if (outputFormat != NULL) {
2191 int32_t width, height;
2192 CHECK(outputFormat->findInt32("width", &width));
2193 CHECK(outputFormat->findInt32("height", &height));
2194
2195 int32_t cropLeft, cropTop, cropRight, cropBottom;
2196 CHECK(outputFormat->findRect(
2197 "crop",
2198 &cropLeft, &cropTop, &cropRight, &cropBottom));
2199
2200 displayWidth = cropRight - cropLeft + 1;
2201 displayHeight = cropBottom - cropTop + 1;
2202
2203 ALOGV("Video output format changed to %d x %d "
2204 "(crop: %d x %d @ (%d, %d))",
2205 width, height,
2206 displayWidth,
2207 displayHeight,
2208 cropLeft, cropTop);
2209 } else {
2210 CHECK(inputFormat->findInt32("width", &displayWidth));
2211 CHECK(inputFormat->findInt32("height", &displayHeight));
2212
2213 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2214 }
2215
2216 // Take into account sample aspect ratio if necessary:
2217 int32_t sarWidth, sarHeight;
2218 if (inputFormat->findInt32("sar-width", &sarWidth)
2219 && inputFormat->findInt32("sar-height", &sarHeight)
2220 && sarWidth > 0 && sarHeight > 0) {
2221 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2222
2223 displayWidth = (displayWidth * sarWidth) / sarHeight;
2224
2225 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2226 } else {
2227 int32_t width, height;
2228 if (inputFormat->findInt32("display-width", &width)
2229 && inputFormat->findInt32("display-height", &height)
2230 && width > 0 && height > 0
2231 && displayWidth > 0 && displayHeight > 0) {
2232 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2233 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2234 } else {
2235 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2236 }
2237 ALOGV("Video display width and height are overridden to %d x %d",
2238 displayWidth, displayHeight);
2239 }
2240 }
2241
2242 int32_t rotationDegrees;
2243 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2244 rotationDegrees = 0;
2245 }
2246
2247 if (rotationDegrees == 90 || rotationDegrees == 270) {
2248 int32_t tmp = displayWidth;
2249 displayWidth = displayHeight;
2250 displayHeight = tmp;
2251 }
2252
2253 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002254 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002255 MEDIA2_SET_VIDEO_SIZE,
2256 displayWidth,
2257 displayHeight);
2258}
2259
Dongwon Kang41929fb2018-09-09 08:29:56 -07002260void NuPlayer2::notifyListener(
2261 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002262 if (mDriver == NULL) {
2263 return;
2264 }
2265
2266 sp<NuPlayer2Driver> driver = mDriver.promote();
2267
2268 if (driver == NULL) {
2269 return;
2270 }
2271
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002272 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002273}
2274
2275void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2276 ALOGV("[%s] flushDecoder needShutdown=%d",
2277 audio ? "audio" : "video", needShutdown);
2278
2279 const sp<DecoderBase> &decoder = getDecoder(audio);
2280 if (decoder == NULL) {
2281 ALOGI("flushDecoder %s without decoder present",
2282 audio ? "audio" : "video");
2283 return;
2284 }
2285
2286 // Make sure we don't continue to scan sources until we finish flushing.
2287 ++mScanSourcesGeneration;
2288 if (mScanSourcesPending) {
2289 if (!needShutdown) {
2290 mDeferredActions.push_back(
2291 new SimpleAction(&NuPlayer2::performScanSources));
2292 }
2293 mScanSourcesPending = false;
2294 }
2295
2296 decoder->signalFlush();
2297
2298 FlushStatus newStatus =
2299 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2300
2301 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2302 mFlushComplete[audio][true /* isDecoder */] = false;
2303 if (audio) {
2304 ALOGE_IF(mFlushingAudio != NONE,
2305 "audio flushDecoder() is called in state %d", mFlushingAudio);
2306 mFlushingAudio = newStatus;
2307 } else {
2308 ALOGE_IF(mFlushingVideo != NONE,
2309 "video flushDecoder() is called in state %d", mFlushingVideo);
2310 mFlushingVideo = newStatus;
2311 }
2312}
2313
2314void NuPlayer2::queueDecoderShutdown(
2315 bool audio, bool video, const sp<AMessage> &reply) {
2316 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2317
2318 mDeferredActions.push_back(
2319 new FlushDecoderAction(
2320 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2321 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2322
2323 mDeferredActions.push_back(
2324 new SimpleAction(&NuPlayer2::performScanSources));
2325
2326 mDeferredActions.push_back(new PostMessageAction(reply));
2327
2328 processDeferredActions();
2329}
2330
2331status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2332 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002333 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2334 status_t ret = native_window_set_scaling_mode(
2335 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002336 if (ret != OK) {
2337 ALOGE("Failed to set scaling mode (%d): %s",
2338 -ret, strerror(-ret));
2339 return ret;
2340 }
2341 }
2342 return OK;
2343}
2344
Wei Jia17944af2018-12-13 18:13:10 -08002345status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002346 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
Wei Jia17944af2018-12-13 18:13:10 -08002347 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002348 msg->setPointer("reply", reply);
2349
2350 sp<AMessage> response;
2351 status_t err = msg->postAndAwaitResponse(&response);
2352 return err;
2353}
2354
Wei Jia17944af2018-12-13 18:13:10 -08002355status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002356 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2357 msg->setPointer("reply", reply);
Wei Jia17944af2018-12-13 18:13:10 -08002358 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002359 msg->setInt32("type", type);
2360
2361 sp<AMessage> response;
2362 status_t err = msg->postAndAwaitResponse(&response);
2363 if (err == OK && response != NULL) {
2364 CHECK(response->findInt32("err", &err));
2365 }
2366 return err;
2367}
2368
Wei Jia17944af2018-12-13 18:13:10 -08002369status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
Wei Jia53692fa2017-12-11 10:33:46 -08002370 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
Wei Jia17944af2018-12-13 18:13:10 -08002371 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002372 msg->setSize("trackIndex", trackIndex);
2373 msg->setInt32("select", select);
2374 msg->setInt64("timeUs", timeUs);
2375
2376 sp<AMessage> response;
2377 status_t err = msg->postAndAwaitResponse(&response);
2378
2379 if (err != OK) {
2380 return err;
2381 }
2382
2383 if (!response->findInt32("err", &err)) {
2384 err = OK;
2385 }
2386
2387 return err;
2388}
2389
2390status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2391 sp<Renderer> renderer = mRenderer;
2392 if (renderer == NULL) {
2393 return NO_INIT;
2394 }
2395
2396 return renderer->getCurrentPosition(mediaUs);
2397}
2398
2399void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2400 CHECK(mTrackStats != NULL);
2401
2402 mTrackStats->clear();
Ray Essick372e8f22019-02-11 11:38:31 -08002403
2404 Mutex::Autolock autoLock(mDecoderLock);
Wei Jia53692fa2017-12-11 10:33:46 -08002405 if (mVideoDecoder != NULL) {
2406 mTrackStats->push_back(mVideoDecoder->getStats());
2407 }
2408 if (mAudioDecoder != NULL) {
2409 mTrackStats->push_back(mAudioDecoder->getStats());
2410 }
2411}
2412
2413sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002414 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002415}
2416
2417float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002418 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002419 if (meta == NULL) {
2420 return 0;
2421 }
2422 int32_t rate;
2423 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2424 // fall back to try file meta
2425 sp<MetaData> fileMeta = getFileMeta();
2426 if (fileMeta == NULL) {
2427 ALOGW("source has video meta but not file meta");
2428 return -1;
2429 }
2430 int32_t fileMetaRate;
2431 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2432 return -1;
2433 }
2434 return fileMetaRate;
2435 }
2436 return rate;
2437}
2438
2439void NuPlayer2::schedulePollDuration() {
2440 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2441 msg->setInt32("generation", mPollDurationGeneration);
2442 msg->post();
2443}
2444
2445void NuPlayer2::cancelPollDuration() {
2446 ++mPollDurationGeneration;
2447}
2448
2449void NuPlayer2::processDeferredActions() {
2450 while (!mDeferredActions.empty()) {
2451 // We won't execute any deferred actions until we're no longer in
2452 // an intermediate state, i.e. one more more decoders are currently
2453 // flushing or shutting down.
2454
2455 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2456 // We're currently flushing, postpone the reset until that's
2457 // completed.
2458
2459 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2460 mFlushingAudio, mFlushingVideo);
2461
2462 break;
2463 }
2464
2465 sp<Action> action = *mDeferredActions.begin();
2466 mDeferredActions.erase(mDeferredActions.begin());
2467
2468 action->execute(this);
2469 }
2470}
2471
2472void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2473 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2474 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2475
Wei Jiaf01e3122018-10-18 11:49:44 -07002476 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002477 // This happens when reset occurs right before the loop mode
2478 // asynchronously seeks to the start of the stream.
2479 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002480 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002481 mAudioDecoder.get(), mVideoDecoder.get());
2482 return;
2483 }
2484 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002485 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002486 ++mTimedTextGeneration;
2487
2488 // everything's flushed, continue playback.
2489}
2490
2491void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2492 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2493
2494 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2495 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2496 return;
2497 }
2498
2499 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2500 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2501 }
2502
2503 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2504 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2505 }
2506}
2507
2508void NuPlayer2::performReset() {
2509 ALOGV("performReset");
2510
2511 CHECK(mAudioDecoder == NULL);
2512 CHECK(mVideoDecoder == NULL);
2513
2514 stopPlaybackTimer("performReset");
2515 stopRebufferingTimer(true);
2516
2517 cancelPollDuration();
2518
2519 ++mScanSourcesGeneration;
2520 mScanSourcesPending = false;
2521
2522 if (mRendererLooper != NULL) {
2523 if (mRenderer != NULL) {
2524 mRendererLooper->unregisterHandler(mRenderer->id());
2525 }
2526 mRendererLooper->stop();
2527 mRendererLooper.clear();
2528 }
2529 mRenderer.clear();
2530 ++mRendererGeneration;
2531
Robert Shihc3fca0e2018-12-04 17:08:04 -08002532 resetSourceInfo(mCurrentSourceInfo);
2533 resetSourceInfo(mNextSourceInfo);
Wei Jia53692fa2017-12-11 10:33:46 -08002534
2535 if (mDriver != NULL) {
2536 sp<NuPlayer2Driver> driver = mDriver.promote();
2537 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002538 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002539 }
2540 }
2541
2542 mStarted = false;
2543 mPrepared = false;
2544 mResetting = false;
2545 mSourceStarted = false;
2546
Wei Jia53692fa2017-12-11 10:33:46 -08002547}
2548
Wei Jia57aeffd2018-02-15 16:01:14 -08002549void NuPlayer2::performPlayNextDataSource() {
2550 ALOGV("performPlayNextDataSource");
2551
2552 CHECK(mAudioDecoder == NULL);
2553 CHECK(mVideoDecoder == NULL);
2554
2555 stopPlaybackTimer("performPlayNextDataSource");
2556 stopRebufferingTimer(true);
2557
2558 cancelPollDuration();
2559
2560 ++mScanSourcesGeneration;
2561 mScanSourcesPending = false;
2562
2563 ++mRendererGeneration;
2564
Wei Jiaf01e3122018-10-18 11:49:44 -07002565 if (mCurrentSourceInfo.mSource != NULL) {
2566 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002567 }
2568
2569 long previousSrcId;
2570 {
2571 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002572 previousSrcId = mCurrentSourceInfo.mSrcId;
Wei Jiad1864f92018-10-19 12:34:56 -07002573
2574 mCurrentSourceInfo = mNextSourceInfo;
2575 mNextSourceInfo = SourceInfo();
2576 mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002577 }
2578
2579 if (mDriver != NULL) {
2580 sp<NuPlayer2Driver> driver = mDriver.promote();
2581 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002582 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiad1864f92018-10-19 12:34:56 -07002583
2584 int64_t durationUs;
2585 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2586 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
2587 }
Wei Jiaf01e3122018-10-18 11:49:44 -07002588 notifyListener(
2589 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002590 }
2591 }
2592
2593 mStarted = false;
2594 mPrepared = true; // TODO: what if it's not prepared
2595 mResetting = false;
2596 mSourceStarted = false;
2597
Wei Jiad1864f92018-10-19 12:34:56 -07002598 addEndTimeMonitor();
2599
Wei Jia57aeffd2018-02-15 16:01:14 -08002600 if (mRenderer != NULL) {
2601 mRenderer->resume();
2602 }
2603
Wei Jia6376cd52018-09-26 11:42:55 -07002604 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002605 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002606 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002607}
2608
Wei Jia53692fa2017-12-11 10:33:46 -08002609void NuPlayer2::performScanSources() {
2610 ALOGV("performScanSources");
2611
2612 if (!mStarted) {
2613 return;
2614 }
2615
2616 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2617 postScanSources();
2618 }
2619}
2620
Wei Jia28288fb2017-12-15 13:45:29 -08002621void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002622 ALOGV("performSetSurface");
2623
Wei Jia28288fb2017-12-15 13:45:29 -08002624 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002625
2626 // XXX - ignore error from setVideoScalingMode for now
2627 setVideoScalingMode(mVideoScalingMode);
2628
2629 if (mDriver != NULL) {
2630 sp<NuPlayer2Driver> driver = mDriver.promote();
2631 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002632 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002633 }
2634 }
2635}
2636
2637void NuPlayer2::performResumeDecoders(bool needNotify) {
2638 if (needNotify) {
2639 mResumePending = true;
2640 if (mVideoDecoder == NULL) {
2641 // if audio-only, we can notify seek complete now,
2642 // as the resume operation will be relatively fast.
2643 finishResume();
2644 }
2645 }
2646
2647 if (mVideoDecoder != NULL) {
2648 // When there is continuous seek, MediaPlayer will cache the seek
2649 // position, and send down new seek request when previous seek is
2650 // complete. Let's wait for at least one video output frame before
2651 // notifying seek complete, so that the video thumbnail gets updated
2652 // when seekbar is dragged.
2653 mVideoDecoder->signalResume(needNotify);
2654 }
2655
2656 if (mAudioDecoder != NULL) {
2657 mAudioDecoder->signalResume(false /* needNotify */);
2658 }
2659}
2660
2661void NuPlayer2::finishResume() {
2662 if (mResumePending) {
2663 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002664 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002665 }
2666}
2667
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002668void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002669 if (mDriver != NULL) {
2670 sp<NuPlayer2Driver> driver = mDriver.promote();
2671 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002672 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002673 }
2674 }
2675}
2676
2677void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2678 int32_t what;
2679 CHECK(msg->findInt32("what", &what));
2680
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002681 int64_t srcId;
2682 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002683 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002684 case Source::kWhatPrepared:
2685 {
Wei Jiad1864f92018-10-19 12:34:56 -07002686 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
2687 mCurrentSourceInfo.mSource.get(), (long long)srcId);
2688 if (srcId == mCurrentSourceInfo.mSrcId) {
2689 if (mCurrentSourceInfo.mSource == NULL) {
2690 // This is a stale notification from a source that was
2691 // asynchronously preparing when the client called reset().
2692 // We handled the reset, the source is gone.
2693 break;
Wei Jia53692fa2017-12-11 10:33:46 -08002694 }
Wei Jiad1864f92018-10-19 12:34:56 -07002695
2696 int32_t err;
2697 CHECK(msg->findInt32("err", &err));
2698
2699 if (err != OK) {
2700 // shut down potential secure codecs in case client never calls reset
2701 mDeferredActions.push_back(
2702 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2703 FLUSH_CMD_SHUTDOWN /* video */));
2704 processDeferredActions();
2705 } else {
2706 mPrepared = true;
2707 }
2708
2709 sp<NuPlayer2Driver> driver = mDriver.promote();
2710 if (driver != NULL) {
2711 // notify duration first, so that it's definitely set when
2712 // the app received the "prepare complete" callback.
2713 int64_t durationUs;
2714 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
2715 driver->notifyDuration(srcId, durationUs);
2716 }
2717 driver->notifyPrepareCompleted(srcId, err);
2718 }
2719 } else if (srcId == mNextSourceInfo.mSrcId) {
2720 if (mNextSourceInfo.mSource == NULL) {
2721 break; // stale
2722 }
2723
2724 sp<NuPlayer2Driver> driver = mDriver.promote();
2725 if (driver != NULL) {
2726 int32_t err;
2727 CHECK(msg->findInt32("err", &err));
2728 driver->notifyPrepareCompleted(srcId, err);
2729 }
Wei Jia53692fa2017-12-11 10:33:46 -08002730 }
2731
2732 break;
2733 }
2734
2735 // Modular DRM
2736 case Source::kWhatDrmInfo:
2737 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002738 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002739 sp<ABuffer> drmInfo;
2740 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002741 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002742
Dongwon Kang41929fb2018-09-09 08:29:56 -07002743 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2744 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002745
Dongwon Kang41929fb2018-09-09 08:29:56 -07002746 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002747
2748 break;
2749 }
2750
2751 case Source::kWhatFlagsChanged:
2752 {
2753 uint32_t flags;
2754 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2755
2756 sp<NuPlayer2Driver> driver = mDriver.promote();
2757 if (driver != NULL) {
2758
2759 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2760 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2761 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2762 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2763 (flags & Source::FLAG_CAN_PAUSE) != 0,
2764 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2765 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2766 (flags & Source::FLAG_CAN_SEEK) != 0,
2767 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2768 (flags & Source::FLAG_SECURE) != 0,
2769 (flags & Source::FLAG_PROTECTED) != 0);
2770
2771 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2772 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002773 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002774 }
Wei Jiad1864f92018-10-19 12:34:56 -07002775 if (srcId == mCurrentSourceInfo.mSrcId) {
2776 driver->notifyFlagsChanged(srcId, flags);
2777 }
Wei Jia53692fa2017-12-11 10:33:46 -08002778 }
2779
Wei Jiaf01e3122018-10-18 11:49:44 -07002780 if (srcId == mCurrentSourceInfo.mSrcId) {
2781 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2782 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2783 cancelPollDuration();
2784 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2785 && (flags & Source::FLAG_DYNAMIC_DURATION)
2786 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2787 schedulePollDuration();
2788 }
Wei Jia53692fa2017-12-11 10:33:46 -08002789
Wei Jiaf01e3122018-10-18 11:49:44 -07002790 mCurrentSourceInfo.mSourceFlags = flags;
2791 } else if (srcId == mNextSourceInfo.mSrcId) {
2792 // TODO: handle duration polling for next source.
2793 mNextSourceInfo.mSourceFlags = flags;
2794 }
Wei Jia53692fa2017-12-11 10:33:46 -08002795 break;
2796 }
2797
2798 case Source::kWhatVideoSizeChanged:
2799 {
2800 sp<AMessage> format;
2801 CHECK(msg->findMessage("format", &format));
2802
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002803 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002804 break;
2805 }
2806
2807 case Source::kWhatBufferingUpdate:
2808 {
2809 int32_t percentage;
2810 CHECK(msg->findInt32("percentage", &percentage));
2811
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002812 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002813 break;
2814 }
2815
2816 case Source::kWhatPauseOnBufferingStart:
2817 {
2818 // ignore if not playing
2819 if (mStarted) {
2820 ALOGI("buffer low, pausing...");
2821
2822 startRebufferingTimer();
2823 mPausedForBuffering = true;
2824 onPause();
2825 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002826 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002827 break;
2828 }
2829
2830 case Source::kWhatResumeOnBufferingEnd:
2831 {
2832 // ignore if not playing
2833 if (mStarted) {
2834 ALOGI("buffer ready, resuming...");
2835
2836 stopRebufferingTimer(false);
2837 mPausedForBuffering = false;
2838
2839 // do not resume yet if client didn't unpause
2840 if (!mPausedByClient) {
2841 onResume();
2842 }
2843 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002844 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002845 break;
2846 }
2847
2848 case Source::kWhatCacheStats:
2849 {
2850 int32_t kbps;
2851 CHECK(msg->findInt32("bandwidth", &kbps));
2852
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002853 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002854 break;
2855 }
2856
2857 case Source::kWhatSubtitleData:
2858 {
2859 sp<ABuffer> buffer;
2860 CHECK(msg->findBuffer("buffer", &buffer));
2861
2862 sendSubtitleData(buffer, 0 /* baseIndex */);
2863 break;
2864 }
2865
2866 case Source::kWhatTimedMetaData:
2867 {
2868 sp<ABuffer> buffer;
2869 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002870 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002871 } else {
2872 sendTimedMetaData(buffer);
2873 }
2874 break;
2875 }
2876
2877 case Source::kWhatTimedTextData:
2878 {
2879 int32_t generation;
2880 if (msg->findInt32("generation", &generation)
2881 && generation != mTimedTextGeneration) {
2882 break;
2883 }
2884
2885 sp<ABuffer> buffer;
2886 CHECK(msg->findBuffer("buffer", &buffer));
2887
2888 sp<NuPlayer2Driver> driver = mDriver.promote();
2889 if (driver == NULL) {
2890 break;
2891 }
2892
Wei Jia800fe372018-02-20 15:00:45 -08002893 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002894 int64_t timeUs, posUs;
2895 driver->getCurrentPosition(&posMs);
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08002896 posUs = posMs * 1000LL;
Wei Jia53692fa2017-12-11 10:33:46 -08002897 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2898
2899 if (posUs < timeUs) {
2900 if (!msg->findInt32("generation", &generation)) {
2901 msg->setInt32("generation", mTimedTextGeneration);
2902 }
2903 msg->post(timeUs - posUs);
2904 } else {
2905 sendTimedTextData(buffer);
2906 }
2907 break;
2908 }
2909
2910 case Source::kWhatQueueDecoderShutdown:
2911 {
2912 int32_t audio, video;
2913 CHECK(msg->findInt32("audio", &audio));
2914 CHECK(msg->findInt32("video", &video));
2915
2916 sp<AMessage> reply;
2917 CHECK(msg->findMessage("reply", &reply));
2918
2919 queueDecoderShutdown(audio, video, reply);
2920 break;
2921 }
2922
2923 case Source::kWhatDrmNoLicense:
2924 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002925 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002926 break;
2927 }
2928
2929 default:
2930 TRESPASS();
2931 }
2932}
2933
2934void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2935 int32_t what;
2936 CHECK(msg->findInt32("what", &what));
2937
2938 switch (what) {
2939 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2940 {
2941 sp<ABuffer> buffer;
2942 CHECK(msg->findBuffer("buffer", &buffer));
2943
2944 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002945 if (mCurrentSourceInfo.mSource != NULL) {
2946 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002947 }
2948
2949 sendSubtitleData(buffer, inbandTracks);
2950 break;
2951 }
2952
2953 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2954 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002955 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002956
2957 break;
2958 }
2959
2960 default:
2961 TRESPASS();
2962 }
2963
2964
2965}
2966
2967void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2968 int32_t trackIndex;
2969 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002970 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002971 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2972 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2973
Dongwon Kang41929fb2018-09-09 08:29:56 -07002974 PlayerMessage playerMsg;
2975 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2976 playerMsg.add_values()->set_int64_value(timeUs);
2977 playerMsg.add_values()->set_int64_value(durationUs);
2978 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002979
Wei Jiaf01e3122018-10-18 11:49:44 -07002980 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002981}
2982
2983void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2984 int64_t timeUs;
2985 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2986
Dongwon Kang41929fb2018-09-09 08:29:56 -07002987 PlayerMessage playerMsg;
2988 playerMsg.add_values()->set_int64_value(timeUs);
2989 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002990
Wei Jiaf01e3122018-10-18 11:49:44 -07002991 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002992}
2993
2994void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2995 const void *data;
2996 size_t size = 0;
2997 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002998 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002999
3000 AString mime;
3001 CHECK(buffer->meta()->findString("mime", &mime));
3002 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
3003
3004 data = buffer->data();
3005 size = buffer->size();
3006
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003007 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08003008 if (size > 0) {
3009 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3010 int32_t global = 0;
3011 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003012 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003013 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003014 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08003015 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003016 TextDescriptions2::getPlayerMessageOfDescriptions(
3017 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003018 }
3019
Dongwon Kanga0e816a2018-09-10 19:46:49 -07003020 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003021 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08003022 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07003023 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08003024 }
3025}
3026
3027const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07003028 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08003029 case DATA_SOURCE_TYPE_HTTP_LIVE:
3030 return "HTTPLive";
3031
3032 case DATA_SOURCE_TYPE_RTSP:
3033 return "RTSP";
3034
3035 case DATA_SOURCE_TYPE_GENERIC_URL:
3036 return "GenURL";
3037
3038 case DATA_SOURCE_TYPE_GENERIC_FD:
3039 return "GenFD";
3040
3041 case DATA_SOURCE_TYPE_MEDIA:
3042 return "Media";
3043
Wei Jia53692fa2017-12-11 10:33:46 -08003044 case DATA_SOURCE_TYPE_NONE:
3045 default:
3046 return "None";
3047 }
3048 }
3049
Robert Shihc3fca0e2018-12-04 17:08:04 -08003050NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
3051 int64_t srcId;
3052 CHECK(msg->findInt64("srcId", &srcId));
3053 if (mCurrentSourceInfo.mSrcId == srcId) {
3054 return &mCurrentSourceInfo;
3055 } else if (mNextSourceInfo.mSrcId == srcId) {
3056 return &mNextSourceInfo;
3057 } else {
3058 return NULL;
3059 }
3060}
3061
3062void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
3063 if (srcInfo.mSource != NULL) {
3064 srcInfo.mSource->stop();
3065
3066 Mutex::Autolock autoLock(mSourceLock);
3067 srcInfo.mSource.clear();
3068 }
3069 // Modular DRM
3070 ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
3071 srcInfo.mCrypto.clear();
3072 srcInfo.mIsDrmProtected = false;
3073}
3074
Wei Jia53692fa2017-12-11 10:33:46 -08003075// Modular DRM begin
Robert Shih3c3728d2018-12-04 17:06:36 -08003076status_t NuPlayer2::prepareDrm(
3077 int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
Wei Jia53692fa2017-12-11 10:33:46 -08003078{
3079 ALOGV("prepareDrm ");
3080
3081 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3082 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3083 // synchronous call so just passing the address but with local copies of "const" args
3084 uint8_t UUID[16];
3085 memcpy(UUID, uuid, sizeof(UUID));
3086 Vector<uint8_t> sessionId = drmSessionId;
Robert Shih3c3728d2018-12-04 17:06:36 -08003087 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003088 msg->setPointer("uuid", (void*)UUID);
3089 msg->setPointer("drmSessionId", (void*)&sessionId);
3090
3091 sp<AMessage> response;
3092 status_t status = msg->postAndAwaitResponse(&response);
3093
3094 if (status == OK && response != NULL) {
3095 CHECK(response->findInt32("status", &status));
3096 ALOGV("prepareDrm ret: %d ", status);
3097 } else {
3098 ALOGE("prepareDrm err: %d", status);
3099 }
3100
3101 return status;
3102}
3103
Robert Shih3c3728d2018-12-04 17:06:36 -08003104status_t NuPlayer2::releaseDrm(int64_t srcId)
Wei Jia53692fa2017-12-11 10:33:46 -08003105{
3106 ALOGV("releaseDrm ");
3107
3108 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
Robert Shih3c3728d2018-12-04 17:06:36 -08003109 msg->setInt64("srcId", srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003110
3111 sp<AMessage> response;
3112 status_t status = msg->postAndAwaitResponse(&response);
3113
3114 if (status == OK && response != NULL) {
3115 CHECK(response->findInt32("status", &status));
3116 ALOGV("releaseDrm ret: %d ", status);
3117 } else {
3118 ALOGE("releaseDrm err: %d", status);
3119 }
3120
3121 return status;
3122}
3123
3124status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
3125{
3126 // TODO change to ALOGV
3127 ALOGD("onPrepareDrm ");
3128
3129 status_t status = INVALID_OPERATION;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003130 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
3131 if (srcInfo == NULL) {
3132 return status;
3133 }
3134
3135 int64_t srcId = srcInfo->mSrcId;
3136 if (srcInfo->mSource == NULL) {
3137 ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
3138 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003139 return status;
3140 }
3141
3142 uint8_t *uuid;
3143 Vector<uint8_t> *drmSessionId;
3144 CHECK(msg->findPointer("uuid", (void**)&uuid));
3145 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3146
3147 status = OK;
3148 sp<AMediaCryptoWrapper> crypto = NULL;
3149
Robert Shihc3fca0e2018-12-04 17:08:04 -08003150 status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003151 if (crypto == NULL) {
Robert Shihc3fca0e2018-12-04 17:08:04 -08003152 ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
3153 (long long)srcId, status);
Wei Jia53692fa2017-12-11 10:33:46 -08003154 return status;
3155 }
Robert Shihc3fca0e2018-12-04 17:08:04 -08003156 ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08003157
Robert Shihc3fca0e2018-12-04 17:08:04 -08003158 if (srcInfo->mCrypto != NULL) {
3159 ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
3160 (long long)srcId, srcInfo->mCrypto.get());
3161 srcInfo->mCrypto.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08003162 }
3163
Robert Shihc3fca0e2018-12-04 17:08:04 -08003164 srcInfo->mCrypto = crypto;
3165 srcInfo->mIsDrmProtected = true;
Wei Jia53692fa2017-12-11 10:33:46 -08003166 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003167 ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
Wei Jia53692fa2017-12-11 10:33:46 -08003168
3169 return status;
3170}
3171
Robert Shihc3fca0e2018-12-04 17:08:04 -08003172status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
Wei Jia53692fa2017-12-11 10:33:46 -08003173{
3174 // TODO change to ALOGV
3175 ALOGD("onReleaseDrm ");
Robert Shihc3fca0e2018-12-04 17:08:04 -08003176 SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
3177 if (srcInfo == NULL) {
3178 return INVALID_OPERATION;
Wei Jia53692fa2017-12-11 10:33:46 -08003179 }
3180
Robert Shihc3fca0e2018-12-04 17:08:04 -08003181 int64_t srcId = srcInfo->mSrcId;
3182 if (!srcInfo->mIsDrmProtected) {
3183 ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
3184 (long long)srcId);
3185 }
3186
3187 srcInfo->mIsDrmProtected = false;
Wei Jia53692fa2017-12-11 10:33:46 -08003188
3189 status_t status;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003190 if (srcInfo->mCrypto != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08003191 // notifying the source first before removing crypto from codec
Robert Shihc3fca0e2018-12-04 17:08:04 -08003192 if (srcInfo->mSource != NULL) {
3193 srcInfo->mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003194 }
3195
3196 status=OK;
3197 // first making sure the codecs have released their crypto reference
3198 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3199 if (videoDecoder != NULL) {
3200 status = videoDecoder->releaseCrypto();
3201 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3202 }
3203
3204 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3205 if (audioDecoder != NULL) {
3206 status_t status_audio = audioDecoder->releaseCrypto();
3207 if (status == OK) { // otherwise, returning the first error
3208 status = status_audio;
3209 }
3210 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3211 }
3212
3213 // TODO change to ALOGV
Robert Shihc3fca0e2018-12-04 17:08:04 -08003214 ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
3215 srcInfo->mCrypto.clear();
3216 } else { // srcInfo->mCrypto == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08003217 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3218 status = INVALID_OPERATION;
3219 }
3220
3221 return status;
3222}
3223// Modular DRM end
3224////////////////////////////////////////////////////////////////////////////////
3225
3226sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3227 sp<MetaData> meta = getFormatMeta(audio);
3228
3229 if (meta == NULL) {
3230 return NULL;
3231 }
3232
3233 sp<AMessage> msg = new AMessage;
3234
3235 if(convertMetaDataToMessage(meta, &msg) == OK) {
3236 return msg;
3237 }
3238 return NULL;
3239}
3240
3241void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3242 sp<AMessage> notify = dupNotify();
3243 notify->setInt32("what", kWhatFlagsChanged);
3244 notify->setInt32("flags", flags);
3245 notify->post();
3246}
3247
3248void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3249 sp<AMessage> notify = dupNotify();
3250 notify->setInt32("what", kWhatVideoSizeChanged);
3251 notify->setMessage("format", format);
3252 notify->post();
3253}
3254
3255void NuPlayer2::Source::notifyPrepared(status_t err) {
3256 ALOGV("Source::notifyPrepared %d", err);
3257 sp<AMessage> notify = dupNotify();
3258 notify->setInt32("what", kWhatPrepared);
3259 notify->setInt32("err", err);
3260 notify->post();
3261}
3262
3263void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3264{
3265 ALOGV("Source::notifyDrmInfo");
3266
3267 sp<AMessage> notify = dupNotify();
3268 notify->setInt32("what", kWhatDrmInfo);
3269 notify->setBuffer("drmInfo", drmInfoBuffer);
3270
3271 notify->post();
3272}
3273
Wei Jia53692fa2017-12-11 10:33:46 -08003274void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3275 TRESPASS();
3276}
3277
Wei Jiaf01e3122018-10-18 11:49:44 -07003278NuPlayer2::SourceInfo::SourceInfo()
3279 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3280 mSrcId(0),
3281 mSourceFlags(0),
3282 mStartTimeUs(0),
Wei Jiae31ac8a2018-10-25 11:06:21 -07003283 mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003284}
3285
Wei Jiad1864f92018-10-19 12:34:56 -07003286NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
3287 mSource = other.mSource;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003288 mCrypto = other.mCrypto;
Wei Jiad1864f92018-10-19 12:34:56 -07003289 mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
3290 mSrcId = other.mSrcId;
3291 mSourceFlags = other.mSourceFlags;
3292 mStartTimeUs = other.mStartTimeUs;
3293 mEndTimeUs = other.mEndTimeUs;
Robert Shihc3fca0e2018-12-04 17:08:04 -08003294 mIsDrmProtected = other.mIsDrmProtected;
Wei Jiad1864f92018-10-19 12:34:56 -07003295 return *this;
3296}
3297
Wei Jia53692fa2017-12-11 10:33:46 -08003298} // namespace android