blob: 5bd16744eae3577a146bdbe15fccd395b9415b34 [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"
Wei Jia53692fa2017-12-11 10:33:46 -080027#include "NuPlayer2CCDecoder.h"
28#include "NuPlayer2Decoder.h"
29#include "NuPlayer2DecoderBase.h"
30#include "NuPlayer2DecoderPassThrough.h"
31#include "NuPlayer2Driver.h"
32#include "NuPlayer2Renderer.h"
33#include "NuPlayer2Source.h"
Wei Jia2409c872018-02-02 10:34:33 -080034#include "RTSPSource2.h"
35#include "GenericSource2.h"
Dongwon Kanga0e816a2018-09-10 19:46:49 -070036#include "TextDescriptions2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080037
38#include "ATSParser.h"
39
40#include <cutils/properties.h>
41
42#include <media/AudioParameter.h>
43#include <media/AudioResamplerPublic.h>
44#include <media/AVSyncSettings.h>
Wei Jiac2636032018-02-01 09:15:25 -080045#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080046#include <media/MediaCodecBuffer.h>
Wei Jia28288fb2017-12-15 13:45:29 -080047#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080048
49#include <media/stagefright/foundation/hexdump.h>
50#include <media/stagefright/foundation/ABuffer.h>
51#include <media/stagefright/foundation/ADebug.h>
52#include <media/stagefright/foundation/AMessage.h>
53#include <media/stagefright/foundation/avc_utils.h>
54#include <media/stagefright/MediaBuffer.h>
55#include <media/stagefright/MediaClock.h>
56#include <media/stagefright/MediaDefs.h>
57#include <media/stagefright/MediaErrors.h>
58#include <media/stagefright/MetaData.h>
59
Wei Jia53692fa2017-12-11 10:33:46 -080060#include "ESDS.h"
61#include <media/stagefright/Utils.h>
62
Wei Jia28288fb2017-12-15 13:45:29 -080063#include <system/window.h>
64
Wei Jia53692fa2017-12-11 10:33:46 -080065namespace android {
66
Wei Jia33abcc72018-01-30 09:47:38 -080067static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
Wei Jia53692fa2017-12-11 10:33:46 -080068 const sp<MetaData>& meta) {
69 int32_t sampleRate = 0;
70 int32_t bitRate = 0;
71 int32_t channelMask = 0;
72 int32_t delaySamples = 0;
73 int32_t paddingSamples = 0;
74
75 AudioParameter param = AudioParameter();
76
77 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
78 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
79 }
80 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
81 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
82 }
83 if (meta->findInt32(kKeyBitRate, &bitRate)) {
84 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
85 }
86 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
87 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
88 }
89 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
90 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
91 }
92
93 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
94 "delaySample %d, paddingSample %d", bitRate, sampleRate,
95 channelMask, delaySamples, paddingSamples);
96
97 sink->setParameters(param.toString());
98 return OK;
99}
100
101
102struct NuPlayer2::Action : public RefBase {
103 Action() {}
104
105 virtual void execute(NuPlayer2 *player) = 0;
106
107private:
108 DISALLOW_EVIL_CONSTRUCTORS(Action);
109};
110
111struct NuPlayer2::SeekAction : public Action {
112 explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
113 : mSeekTimeUs(seekTimeUs),
114 mMode(mode) {
115 }
116
117 virtual void execute(NuPlayer2 *player) {
118 player->performSeek(mSeekTimeUs, mMode);
119 }
120
121private:
122 int64_t mSeekTimeUs;
123 MediaPlayer2SeekMode mMode;
124
125 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
126};
127
128struct NuPlayer2::ResumeDecoderAction : public Action {
129 explicit ResumeDecoderAction(bool needNotify)
130 : mNeedNotify(needNotify) {
131 }
132
133 virtual void execute(NuPlayer2 *player) {
134 player->performResumeDecoders(mNeedNotify);
135 }
136
137private:
138 bool mNeedNotify;
139
140 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
141};
142
143struct NuPlayer2::SetSurfaceAction : public Action {
Wei Jia28288fb2017-12-15 13:45:29 -0800144 explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
145 : mNativeWindow(nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800146 }
147
148 virtual void execute(NuPlayer2 *player) {
Wei Jia28288fb2017-12-15 13:45:29 -0800149 player->performSetSurface(mNativeWindow);
Wei Jia53692fa2017-12-11 10:33:46 -0800150 }
151
152private:
Wei Jia28288fb2017-12-15 13:45:29 -0800153 sp<ANativeWindowWrapper> mNativeWindow;
Wei Jia53692fa2017-12-11 10:33:46 -0800154
155 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
156};
157
158struct NuPlayer2::FlushDecoderAction : public Action {
159 FlushDecoderAction(FlushCommand audio, FlushCommand video)
160 : mAudio(audio),
161 mVideo(video) {
162 }
163
164 virtual void execute(NuPlayer2 *player) {
165 player->performDecoderFlush(mAudio, mVideo);
166 }
167
168private:
169 FlushCommand mAudio;
170 FlushCommand mVideo;
171
172 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
173};
174
175struct NuPlayer2::PostMessageAction : public Action {
176 explicit PostMessageAction(const sp<AMessage> &msg)
177 : mMessage(msg) {
178 }
179
180 virtual void execute(NuPlayer2 *) {
181 mMessage->post();
182 }
183
184private:
185 sp<AMessage> mMessage;
186
187 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
188};
189
190// Use this if there's no state necessary to save in order to execute
191// the action.
192struct NuPlayer2::SimpleAction : public Action {
193 typedef void (NuPlayer2::*ActionFunc)();
194
195 explicit SimpleAction(ActionFunc func)
196 : mFunc(func) {
197 }
198
199 virtual void execute(NuPlayer2 *player) {
200 (player->*mFunc)();
201 }
202
203private:
204 ActionFunc mFunc;
205
206 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
207};
208
209////////////////////////////////////////////////////////////////////////////////
210
Wei Jia003fdb52018-02-06 14:44:32 -0800211NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
212 : mPID(pid),
213 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800214 mMediaClock(mediaClock),
215 mSourceFlags(0),
216 mOffloadAudio(false),
217 mAudioDecoderGeneration(0),
218 mVideoDecoderGeneration(0),
219 mRendererGeneration(0),
220 mLastStartedPlayingTimeNs(0),
221 mPreviousSeekTimeUs(0),
222 mAudioEOS(false),
223 mVideoEOS(false),
224 mScanSourcesPending(false),
225 mScanSourcesGeneration(0),
226 mPollDurationGeneration(0),
227 mTimedTextGeneration(0),
228 mFlushingAudio(NONE),
229 mFlushingVideo(NONE),
230 mResumePending(false),
231 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
232 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
233 mVideoFpsHint(-1.f),
234 mStarted(false),
235 mPrepared(false),
236 mResetting(false),
237 mSourceStarted(false),
238 mAudioDecoderError(false),
239 mVideoDecoderError(false),
240 mPaused(false),
241 mPausedByClient(true),
242 mPausedForBuffering(false),
243 mIsDrmProtected(false),
244 mDataSourceType(DATA_SOURCE_TYPE_NONE) {
245 CHECK(mediaClock != NULL);
246 clearFlushComplete();
247}
248
249NuPlayer2::~NuPlayer2() {
250}
251
Wei Jia53692fa2017-12-11 10:33:46 -0800252void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
253 mDriver = driver;
254}
255
Wei Jia53692fa2017-12-11 10:33:46 -0800256static bool IsHTTPLiveURL(const char *url) {
257 if (!strncasecmp("http://", url, 7)
258 || !strncasecmp("https://", url, 8)
259 || !strncasecmp("file://", url, 7)) {
260 size_t len = strlen(url);
261 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
262 return true;
263 }
264
265 if (strstr(url,"m3u8")) {
266 return true;
267 }
268 }
269
270 return false;
271}
272
Wei Jia72bf2a02018-02-06 15:29:23 -0800273status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
274 sp<Source> *source,
275 DATA_SOURCE_TYPE *dataSourceType) {
276 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800277 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800278 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800279
Wei Jiac2636032018-02-01 09:15:25 -0800280 switch (dsd->mType) {
281 case DataSourceDesc::TYPE_URL:
282 {
283 const char *url = dsd->mUrl.c_str();
284 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800285
Wei Jiac2636032018-02-01 09:15:25 -0800286 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
287 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800288
Wei Jiac2636032018-02-01 09:15:25 -0800289 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800290 *source = new HTTPLiveSource2(notify, httpService, url, headers);
291 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
292 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800293 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800294 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800295 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800296 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
297 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800298 } else if ((!strncasecmp(url, "http://", 7)
299 || !strncasecmp(url, "https://", 8))
300 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
301 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800302 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800303 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800304 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
305 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800306 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800307 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800308
Wei Jia2409c872018-02-02 10:34:33 -0800309 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800310 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800311
Wei Jia72bf2a02018-02-06 15:29:23 -0800312 err = genericSource->setDataSource(httpService, url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800313
314 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800315 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800316 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800317 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800318 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800319 }
320
321 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800322 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800323 }
324 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800325 }
326
Wei Jiac2636032018-02-01 09:15:25 -0800327 case DataSourceDesc::TYPE_FD:
328 {
Wei Jia2409c872018-02-02 10:34:33 -0800329 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800330 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800331
Wei Jia72bf2a02018-02-06 15:29:23 -0800332 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
333 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
334 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800335
Wei Jia72bf2a02018-02-06 15:29:23 -0800336 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800337
Wei Jiac2636032018-02-01 09:15:25 -0800338 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800339 ALOGE("Failed to create NuPlayer2Source!");
340 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800341 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800342 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800343 }
Wei Jia53692fa2017-12-11 10:33:46 -0800344
Wei Jia72bf2a02018-02-06 15:29:23 -0800345 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800346 break;
347 }
Wei Jia53692fa2017-12-11 10:33:46 -0800348
Wei Jiac2636032018-02-01 09:15:25 -0800349 case DataSourceDesc::TYPE_CALLBACK:
350 {
Wei Jia2409c872018-02-02 10:34:33 -0800351 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800352 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800353 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800354
Wei Jiac2636032018-02-01 09:15:25 -0800355 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800356 ALOGE("Failed to create NuPlayer2Source!");
357 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800358 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800359 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800360 }
361
Wei Jia72bf2a02018-02-06 15:29:23 -0800362 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800363 break;
364 }
365
366 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800367 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800368 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800369 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800370 ALOGE("invalid data source type!");
371 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800372 }
373
Wei Jia72bf2a02018-02-06 15:29:23 -0800374 return err;
375}
376
377void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
378 DATA_SOURCE_TYPE dataSourceType;
379 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800380 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800381
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800382 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
383 // and expects notifySetDataSourceCompleted regardless of success or failure.
384 // This will be changed since setDataSource should be asynchronous at JAVA level.
385 // When it succeeds, app will get onInfo notification. Otherwise, onError
386 // will be called.
387 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800388 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800389 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800390 return;
391 }
392
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800393 // Now, source != NULL.
394 */
395
Wei Jia72bf2a02018-02-06 15:29:23 -0800396 mDataSourceType = dataSourceType;
397
398 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800399 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800400 msg->setInt64("srcId", dsd->mId);
401 msg->post();
402}
403
404void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
405 DATA_SOURCE_TYPE dataSourceType;
406 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800407 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800408
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800409 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800410 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800411 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800412 return;
413 }
414
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800415 // Now, source != NULL.
416 */
417
Wei Jia72bf2a02018-02-06 15:29:23 -0800418 mNextDataSourceType = dataSourceType;
419
420 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
421 msg->setObject("source", source);
422 msg->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800423 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800424}
425
Wei Jia57aeffd2018-02-15 16:01:14 -0800426void NuPlayer2::playNextDataSource(int64_t srcId) {
427 disconnectSource();
428
429 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
430 msg->setInt64("srcId", srcId);
431 msg->post();
432}
433
Wei Jia53692fa2017-12-11 10:33:46 -0800434status_t NuPlayer2::getBufferingSettings(
435 BufferingSettings *buffering /* nonnull */) {
436 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
437 sp<AMessage> response;
438 status_t err = msg->postAndAwaitResponse(&response);
439 if (err == OK && response != NULL) {
440 CHECK(response->findInt32("err", &err));
441 if (err == OK) {
442 readFromAMessage(response, buffering);
443 }
444 }
445 return err;
446}
447
448status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
449 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
450 writeToAMessage(msg, buffering);
451 sp<AMessage> response;
452 status_t err = msg->postAndAwaitResponse(&response);
453 if (err == OK && response != NULL) {
454 CHECK(response->findInt32("err", &err));
455 }
456 return err;
457}
458
459void NuPlayer2::prepareAsync() {
460 ALOGV("prepareAsync");
461
462 (new AMessage(kWhatPrepare, this))->post();
463}
464
Wei Jia28288fb2017-12-15 13:45:29 -0800465void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800466 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
467
Wei Jia28288fb2017-12-15 13:45:29 -0800468 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800469 msg->setObject("surface", NULL);
470 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800471 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800472 }
473
474 msg->post();
475}
476
Wei Jia33abcc72018-01-30 09:47:38 -0800477void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800478 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
479 msg->setObject("sink", sink);
480 msg->post();
481}
482
483void NuPlayer2::start() {
484 (new AMessage(kWhatStart, this))->post();
485}
486
487status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
488 // do some cursory validation of the settings here. audio modes are
489 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700490 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800491 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
492 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
493 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
494 return BAD_VALUE;
495 }
496 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
497 writeToAMessage(msg, rate);
498 sp<AMessage> response;
499 status_t err = msg->postAndAwaitResponse(&response);
500 if (err == OK && response != NULL) {
501 CHECK(response->findInt32("err", &err));
502 }
503 return err;
504}
505
506status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
507 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
508 sp<AMessage> response;
509 status_t err = msg->postAndAwaitResponse(&response);
510 if (err == OK && response != NULL) {
511 CHECK(response->findInt32("err", &err));
512 if (err == OK) {
513 readFromAMessage(response, rate);
514 }
515 }
516 return err;
517}
518
519status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
520 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
521 writeToAMessage(msg, sync, videoFpsHint);
522 sp<AMessage> response;
523 status_t err = msg->postAndAwaitResponse(&response);
524 if (err == OK && response != NULL) {
525 CHECK(response->findInt32("err", &err));
526 }
527 return err;
528}
529
530status_t NuPlayer2::getSyncSettings(
531 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
532 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
533 sp<AMessage> response;
534 status_t err = msg->postAndAwaitResponse(&response);
535 if (err == OK && response != NULL) {
536 CHECK(response->findInt32("err", &err));
537 if (err == OK) {
538 readFromAMessage(response, sync, videoFps);
539 }
540 }
541 return err;
542}
543
544void NuPlayer2::pause() {
545 (new AMessage(kWhatPause, this))->post();
546}
547
548void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800549 disconnectSource();
550 (new AMessage(kWhatReset, this))->post();
551}
552
553void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800554 sp<Source> source;
555 {
556 Mutex::Autolock autoLock(mSourceLock);
557 source = mSource;
558 }
559
560 if (source != NULL) {
561 // During a reset, the data source might be unresponsive already, we need to
562 // disconnect explicitly so that reads exit promptly.
563 // We can't queue the disconnect request to the looper, as it might be
564 // queued behind a stuck read and never gets processed.
565 // Doing a disconnect outside the looper to allows the pending reads to exit
566 // (either successfully or with error).
567 source->disconnect();
568 }
569
Wei Jia53692fa2017-12-11 10:33:46 -0800570}
571
572status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
573 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
574 notify->setInt64("timerUs", mediaTimeUs);
575 mMediaClock->addTimer(notify, mediaTimeUs);
576 return OK;
577}
578
579void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
580 sp<AMessage> msg = new AMessage(kWhatSeek, this);
581 msg->setInt64("seekTimeUs", seekTimeUs);
582 msg->setInt32("mode", mode);
583 msg->setInt32("needNotify", needNotify);
584 msg->post();
585}
586
Wei Jia53692fa2017-12-11 10:33:46 -0800587void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700588 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800589 if (format == NULL) {
590 ALOGE("NULL format");
591 return;
592 }
593 int32_t trackType;
594 if (!format->findInt32("type", &trackType)) {
595 ALOGE("no track type");
596 return;
597 }
598
599 AString mime;
600 if (!format->findString("mime", &mime)) {
601 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
602 // If we can't find the mimetype here it means that we wouldn't be needing
603 // the mimetype on the Java end. We still write a placeholder mime to keep the
604 // (de)serialization logic simple.
605 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
606 mime = "audio/";
607 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
608 mime = "video/";
609 } else {
610 ALOGE("unknown track type: %d", trackType);
611 return;
612 }
613 }
614
615 AString lang;
616 if (!format->findString("language", &lang)) {
617 ALOGE("no language");
618 return;
619 }
620
Dongwon Kang9f631982018-07-10 12:34:41 -0700621 reply->add_values()->set_int32_value(trackType);
622 reply->add_values()->set_string_value(mime.c_str());
623 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800624
625 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
626 int32_t isAuto, isDefault, isForced;
627 CHECK(format->findInt32("auto", &isAuto));
628 CHECK(format->findInt32("default", &isDefault));
629 CHECK(format->findInt32("forced", &isForced));
630
Dongwon Kang9f631982018-07-10 12:34:41 -0700631 reply->add_values()->set_int32_value(isAuto);
632 reply->add_values()->set_int32_value(isDefault);
633 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800634 }
635}
636
637void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
638 switch (msg->what()) {
639 case kWhatSetDataSource:
640 {
641 ALOGV("kWhatSetDataSource");
642
643 CHECK(mSource == NULL);
644
645 status_t err = OK;
646 sp<RefBase> obj;
647 CHECK(msg->findObject("source", &obj));
648 if (obj != NULL) {
649 Mutex::Autolock autoLock(mSourceLock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800650 CHECK(msg->findInt64("srcId", &mSrcId));
Wei Jia53692fa2017-12-11 10:33:46 -0800651 mSource = static_cast<Source *>(obj.get());
652 } else {
653 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800654 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800655 }
656
657 CHECK(mDriver != NULL);
658 sp<NuPlayer2Driver> driver = mDriver.promote();
659 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800660 driver->notifySetDataSourceCompleted(mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800661 }
662 break;
663 }
664
Wei Jia72bf2a02018-02-06 15:29:23 -0800665 case kWhatPrepareNextDataSource:
666 {
667 ALOGV("kWhatPrepareNextDataSource");
668
669 status_t err = OK;
670 sp<RefBase> obj;
671 CHECK(msg->findObject("source", &obj));
672 if (obj != NULL) {
673 Mutex::Autolock autoLock(mSourceLock);
674 CHECK(msg->findInt64("srcId", &mNextSrcId));
675 mNextSource = static_cast<Source *>(obj.get());
676 mNextSource->prepareAsync();
677 } else {
678 err = UNKNOWN_ERROR;
679 }
680
681 break;
682 }
683
Wei Jia57aeffd2018-02-15 16:01:14 -0800684 case kWhatPlayNextDataSource:
685 {
686 ALOGV("kWhatPlayNextDataSource");
687 int64_t srcId;
688 CHECK(msg->findInt64("srcId", &srcId));
689 if (srcId != mNextSrcId) {
690 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
691 return;
692 }
693
694 mResetting = true;
695 stopPlaybackTimer("kWhatPlayNextDataSource");
696 stopRebufferingTimer(true);
697
698 mDeferredActions.push_back(
699 new FlushDecoderAction(
700 FLUSH_CMD_SHUTDOWN /* audio */,
701 FLUSH_CMD_SHUTDOWN /* video */));
702
703 mDeferredActions.push_back(
704 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
705
706 processDeferredActions();
707 break;
708 }
709
Wei Jia53692fa2017-12-11 10:33:46 -0800710 case kWhatGetBufferingSettings:
711 {
712 sp<AReplyToken> replyID;
713 CHECK(msg->senderAwaitsResponse(&replyID));
714
715 ALOGV("kWhatGetBufferingSettings");
716 BufferingSettings buffering;
717 status_t err = OK;
718 if (mSource != NULL) {
719 err = mSource->getBufferingSettings(&buffering);
720 } else {
721 err = INVALID_OPERATION;
722 }
723 sp<AMessage> response = new AMessage;
724 if (err == OK) {
725 writeToAMessage(response, buffering);
726 }
727 response->setInt32("err", err);
728 response->postReply(replyID);
729 break;
730 }
731
732 case kWhatSetBufferingSettings:
733 {
734 sp<AReplyToken> replyID;
735 CHECK(msg->senderAwaitsResponse(&replyID));
736
737 ALOGV("kWhatSetBufferingSettings");
738 BufferingSettings buffering;
739 readFromAMessage(msg, &buffering);
740 status_t err = OK;
741 if (mSource != NULL) {
742 err = mSource->setBufferingSettings(buffering);
743 } else {
744 err = INVALID_OPERATION;
745 }
746 sp<AMessage> response = new AMessage;
747 response->setInt32("err", err);
748 response->postReply(replyID);
749 break;
750 }
751
752 case kWhatPrepare:
753 {
754 ALOGV("onMessageReceived kWhatPrepare");
755
756 mSource->prepareAsync();
757 break;
758 }
759
760 case kWhatGetTrackInfo:
761 {
762 sp<AReplyToken> replyID;
763 CHECK(msg->senderAwaitsResponse(&replyID));
764
Dongwon Kang9f631982018-07-10 12:34:41 -0700765 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800766 CHECK(msg->findPointer("reply", (void**)&reply));
767
768 size_t inbandTracks = 0;
769 if (mSource != NULL) {
770 inbandTracks = mSource->getTrackCount();
771 }
772
773 size_t ccTracks = 0;
774 if (mCCDecoder != NULL) {
775 ccTracks = mCCDecoder->getTrackCount();
776 }
777
778 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700779 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800780
781 // write inband tracks
782 for (size_t i = 0; i < inbandTracks; ++i) {
783 writeTrackInfo(reply, mSource->getTrackInfo(i));
784 }
785
786 // write CC track
787 for (size_t i = 0; i < ccTracks; ++i) {
788 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
789 }
790
791 sp<AMessage> response = new AMessage;
792 response->postReply(replyID);
793 break;
794 }
795
796 case kWhatGetSelectedTrack:
797 {
798 status_t err = INVALID_OPERATION;
799 if (mSource != NULL) {
800 err = OK;
801
802 int32_t type32;
803 CHECK(msg->findInt32("type", (int32_t*)&type32));
804 media_track_type type = (media_track_type)type32;
805 ssize_t selectedTrack = mSource->getSelectedTrack(type);
806
Dongwon Kang9f631982018-07-10 12:34:41 -0700807 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800808 CHECK(msg->findPointer("reply", (void**)&reply));
Dongwon Kang9f631982018-07-10 12:34:41 -0700809 reply->add_values()->set_int32_value(selectedTrack);
Wei Jia53692fa2017-12-11 10:33:46 -0800810 }
811
812 sp<AMessage> response = new AMessage;
813 response->setInt32("err", err);
814
815 sp<AReplyToken> replyID;
816 CHECK(msg->senderAwaitsResponse(&replyID));
817 response->postReply(replyID);
818 break;
819 }
820
821 case kWhatSelectTrack:
822 {
823 sp<AReplyToken> replyID;
824 CHECK(msg->senderAwaitsResponse(&replyID));
825
826 size_t trackIndex;
827 int32_t select;
828 int64_t timeUs;
829 CHECK(msg->findSize("trackIndex", &trackIndex));
830 CHECK(msg->findInt32("select", &select));
831 CHECK(msg->findInt64("timeUs", &timeUs));
832
833 status_t err = INVALID_OPERATION;
834
835 size_t inbandTracks = 0;
836 if (mSource != NULL) {
837 inbandTracks = mSource->getTrackCount();
838 }
839 size_t ccTracks = 0;
840 if (mCCDecoder != NULL) {
841 ccTracks = mCCDecoder->getTrackCount();
842 }
843
844 if (trackIndex < inbandTracks) {
845 err = mSource->selectTrack(trackIndex, select, timeUs);
846
847 if (!select && err == OK) {
848 int32_t type;
849 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
850 if (info != NULL
851 && info->findInt32("type", &type)
852 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
853 ++mTimedTextGeneration;
854 }
855 }
856 } else {
857 trackIndex -= inbandTracks;
858
859 if (trackIndex < ccTracks) {
860 err = mCCDecoder->selectTrack(trackIndex, select);
861 }
862 }
863
864 sp<AMessage> response = new AMessage;
865 response->setInt32("err", err);
866
867 response->postReply(replyID);
868 break;
869 }
870
871 case kWhatPollDuration:
872 {
873 int32_t generation;
874 CHECK(msg->findInt32("generation", &generation));
875
876 if (generation != mPollDurationGeneration) {
877 // stale
878 break;
879 }
880
881 int64_t durationUs;
882 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
883 sp<NuPlayer2Driver> driver = mDriver.promote();
884 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800885 driver->notifyDuration(mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800886 }
887 }
888
889 msg->post(1000000ll); // poll again in a second.
890 break;
891 }
892
893 case kWhatSetVideoSurface:
894 {
895
896 sp<RefBase> obj;
897 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800898 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800899
900 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800901 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jia53692fa2017-12-11 10:33:46 -0800902 (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
903 && mVideoDecoder != NULL) ? "have" : "no");
904
905 // Need to check mStarted before calling mSource->getFormat because NuPlayer2 might
906 // be in preparing state and it could take long time.
907 // When mStarted is true, mSource must have been set.
908 if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800909 // NOTE: mVideoDecoder's mNativeWindow is always non-null
910 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
911 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800912 break;
913 }
914
915 mDeferredActions.push_back(
916 new FlushDecoderAction(
917 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
918 FLUSH_CMD_SHUTDOWN /* video */));
919
Wei Jia28288fb2017-12-15 13:45:29 -0800920 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800921
922 if (obj != NULL) {
923 if (mStarted) {
924 // Issue a seek to refresh the video screen only if started otherwise
925 // the extractor may not yet be started and will assert.
926 // If the video decoder is not set (perhaps audio only in this case)
927 // do not perform a seek as it is not needed.
928 int64_t currentPositionUs = 0;
929 if (getCurrentPosition(&currentPositionUs) == OK) {
930 mDeferredActions.push_back(
931 new SeekAction(currentPositionUs,
932 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
933 }
934 }
935
936 // If there is a new surface texture, instantiate decoders
937 // again if possible.
938 mDeferredActions.push_back(
939 new SimpleAction(&NuPlayer2::performScanSources));
940
941 // After a flush without shutdown, decoder is paused.
942 // Don't resume it until source seek is done, otherwise it could
943 // start pulling stale data too soon.
944 mDeferredActions.push_back(
945 new ResumeDecoderAction(false /* needNotify */));
946 }
947
948 processDeferredActions();
949 break;
950 }
951
952 case kWhatSetAudioSink:
953 {
954 ALOGV("kWhatSetAudioSink");
955
956 sp<RefBase> obj;
957 CHECK(msg->findObject("sink", &obj));
958
Wei Jia33abcc72018-01-30 09:47:38 -0800959 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800960 break;
961 }
962
963 case kWhatStart:
964 {
965 ALOGV("kWhatStart");
966 if (mStarted) {
967 // do not resume yet if the source is still buffering
968 if (!mPausedForBuffering) {
969 onResume();
970 }
971 } else {
Wei Jia6376cd52018-09-26 11:42:55 -0700972 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -0800973 }
974 mPausedByClient = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800975 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -0800976 break;
977 }
978
979 case kWhatConfigPlayback:
980 {
981 sp<AReplyToken> replyID;
982 CHECK(msg->senderAwaitsResponse(&replyID));
983 AudioPlaybackRate rate /* sanitized */;
984 readFromAMessage(msg, &rate);
985 status_t err = OK;
986 if (mRenderer != NULL) {
987 // AudioSink allows only 1.f and 0.f for offload mode.
988 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -0700989 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -0800990 int64_t currentPositionUs;
991 if (getCurrentPosition(&currentPositionUs) != OK) {
992 currentPositionUs = mPreviousSeekTimeUs;
993 }
994
995 // Set mPlaybackSettings so that the new audio decoder can
996 // be created correctly.
997 mPlaybackSettings = rate;
998 if (!mPaused) {
999 mRenderer->pause();
1000 }
1001 restartAudio(
1002 currentPositionUs, true /* forceNonOffload */,
1003 true /* needsToCreateAudioDecoder */);
1004 if (!mPaused) {
1005 mRenderer->resume();
1006 }
1007 }
1008
1009 err = mRenderer->setPlaybackSettings(rate);
1010 }
1011 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001012 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001013
Wei Jia700a7c22018-09-14 18:04:35 -07001014 if (mVideoDecoder != NULL) {
1015 sp<AMessage> params = new AMessage();
1016 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1017 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001018 }
1019 }
1020
Wei Jia53692fa2017-12-11 10:33:46 -08001021 sp<AMessage> response = new AMessage;
1022 response->setInt32("err", err);
1023 response->postReply(replyID);
1024 break;
1025 }
1026
1027 case kWhatGetPlaybackSettings:
1028 {
1029 sp<AReplyToken> replyID;
1030 CHECK(msg->senderAwaitsResponse(&replyID));
1031 AudioPlaybackRate rate = mPlaybackSettings;
1032 status_t err = OK;
1033 if (mRenderer != NULL) {
1034 err = mRenderer->getPlaybackSettings(&rate);
1035 }
1036 if (err == OK) {
1037 // get playback settings used by renderer, as it may be
1038 // slightly off due to audiosink not taking small changes.
1039 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001040 }
1041 sp<AMessage> response = new AMessage;
1042 if (err == OK) {
1043 writeToAMessage(response, rate);
1044 }
1045 response->setInt32("err", err);
1046 response->postReply(replyID);
1047 break;
1048 }
1049
1050 case kWhatConfigSync:
1051 {
1052 sp<AReplyToken> replyID;
1053 CHECK(msg->senderAwaitsResponse(&replyID));
1054
1055 ALOGV("kWhatConfigSync");
1056 AVSyncSettings sync;
1057 float videoFpsHint;
1058 readFromAMessage(msg, &sync, &videoFpsHint);
1059 status_t err = OK;
1060 if (mRenderer != NULL) {
1061 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1062 }
1063 if (err == OK) {
1064 mSyncSettings = sync;
1065 mVideoFpsHint = videoFpsHint;
1066 }
1067 sp<AMessage> response = new AMessage;
1068 response->setInt32("err", err);
1069 response->postReply(replyID);
1070 break;
1071 }
1072
1073 case kWhatGetSyncSettings:
1074 {
1075 sp<AReplyToken> replyID;
1076 CHECK(msg->senderAwaitsResponse(&replyID));
1077 AVSyncSettings sync = mSyncSettings;
1078 float videoFps = mVideoFpsHint;
1079 status_t err = OK;
1080 if (mRenderer != NULL) {
1081 err = mRenderer->getSyncSettings(&sync, &videoFps);
1082 if (err == OK) {
1083 mSyncSettings = sync;
1084 mVideoFpsHint = videoFps;
1085 }
1086 }
1087 sp<AMessage> response = new AMessage;
1088 if (err == OK) {
1089 writeToAMessage(response, sync, videoFps);
1090 }
1091 response->setInt32("err", err);
1092 response->postReply(replyID);
1093 break;
1094 }
1095
1096 case kWhatScanSources:
1097 {
1098 int32_t generation;
1099 CHECK(msg->findInt32("generation", &generation));
1100 if (generation != mScanSourcesGeneration) {
1101 // Drop obsolete msg.
1102 break;
1103 }
1104
1105 mScanSourcesPending = false;
1106
1107 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1108 mAudioDecoder != NULL, mVideoDecoder != NULL);
1109
1110 bool mHadAnySourcesBefore =
1111 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1112 bool rescan = false;
1113
1114 // initialize video before audio because successful initialization of
1115 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001116 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001117 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1118 rescan = true;
1119 }
1120 }
1121
1122 // Don't try to re-open audio sink if there's an existing decoder.
1123 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1124 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1125 rescan = true;
1126 }
1127 }
1128
1129 if (!mHadAnySourcesBefore
1130 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1131 // This is the first time we've found anything playable.
1132
1133 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
1134 schedulePollDuration();
1135 }
1136 }
1137
1138 status_t err;
1139 if ((err = mSource->feedMoreTSData()) != OK) {
1140 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1141 // We're not currently decoding anything (no audio or
1142 // video tracks found) and we just ran out of input data.
1143
1144 if (err == ERROR_END_OF_STREAM) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001145 notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001146 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001147 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001148 }
1149 }
1150 break;
1151 }
1152
1153 if (rescan) {
1154 msg->post(100000ll);
1155 mScanSourcesPending = true;
1156 }
1157 break;
1158 }
1159
1160 case kWhatVideoNotify:
1161 case kWhatAudioNotify:
1162 {
1163 bool audio = msg->what() == kWhatAudioNotify;
1164
1165 int32_t currentDecoderGeneration =
1166 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1167 int32_t requesterGeneration = currentDecoderGeneration - 1;
1168 CHECK(msg->findInt32("generation", &requesterGeneration));
1169
1170 if (requesterGeneration != currentDecoderGeneration) {
1171 ALOGV("got message from old %s decoder, generation(%d:%d)",
1172 audio ? "audio" : "video", requesterGeneration,
1173 currentDecoderGeneration);
1174 sp<AMessage> reply;
1175 if (!(msg->findMessage("reply", &reply))) {
1176 return;
1177 }
1178
1179 reply->setInt32("err", INFO_DISCONTINUITY);
1180 reply->post();
1181 return;
1182 }
1183
1184 int32_t what;
1185 CHECK(msg->findInt32("what", &what));
1186
1187 if (what == DecoderBase::kWhatInputDiscontinuity) {
1188 int32_t formatChange;
1189 CHECK(msg->findInt32("formatChange", &formatChange));
1190
1191 ALOGV("%s discontinuity: formatChange %d",
1192 audio ? "audio" : "video", formatChange);
1193
1194 if (formatChange) {
1195 mDeferredActions.push_back(
1196 new FlushDecoderAction(
1197 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1198 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1199 }
1200
1201 mDeferredActions.push_back(
1202 new SimpleAction(
1203 &NuPlayer2::performScanSources));
1204
1205 processDeferredActions();
1206 } else if (what == DecoderBase::kWhatEOS) {
1207 int32_t err;
1208 CHECK(msg->findInt32("err", &err));
1209
1210 if (err == ERROR_END_OF_STREAM) {
1211 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1212 } else {
1213 ALOGV("got %s decoder EOS w/ error %d",
1214 audio ? "audio" : "video",
1215 err);
1216 }
1217
1218 mRenderer->queueEOS(audio, err);
1219 } else if (what == DecoderBase::kWhatFlushCompleted) {
1220 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1221
1222 handleFlushComplete(audio, true /* isDecoder */);
1223 finishFlushIfPossible();
1224 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1225 sp<AMessage> format;
1226 CHECK(msg->findMessage("format", &format));
1227
1228 sp<AMessage> inputFormat =
1229 mSource->getFormat(false /* audio */);
1230
1231 setVideoScalingMode(mVideoScalingMode);
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001232 updateVideoSize(mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001233 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1234 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1235 if (audio) {
1236 mAudioDecoder.clear();
1237 mAudioDecoderError = false;
1238 ++mAudioDecoderGeneration;
1239
1240 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1241 mFlushingAudio = SHUT_DOWN;
1242 } else {
1243 mVideoDecoder.clear();
1244 mVideoDecoderError = false;
1245 ++mVideoDecoderGeneration;
1246
1247 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1248 mFlushingVideo = SHUT_DOWN;
1249 }
1250
1251 finishFlushIfPossible();
1252 } else if (what == DecoderBase::kWhatResumeCompleted) {
1253 finishResume();
1254 } else if (what == DecoderBase::kWhatError) {
1255 status_t err;
1256 if (!msg->findInt32("err", &err) || err == OK) {
1257 err = UNKNOWN_ERROR;
1258 }
1259
1260 // Decoder errors can be due to Source (e.g. from streaming),
1261 // or from decoding corrupted bitstreams, or from other decoder
1262 // MediaCodec operations (e.g. from an ongoing reset or seek).
1263 // They may also be due to openAudioSink failure at
1264 // decoder start or after a format change.
1265 //
1266 // We try to gracefully shut down the affected decoder if possible,
1267 // rather than trying to force the shutdown with something
1268 // similar to performReset(). This method can lead to a hang
1269 // if MediaCodec functions block after an error, but they should
1270 // typically return INVALID_OPERATION instead of blocking.
1271
1272 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1273 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1274 err, audio ? "audio" : "video", *flushing);
1275
1276 switch (*flushing) {
1277 case NONE:
1278 mDeferredActions.push_back(
1279 new FlushDecoderAction(
1280 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1281 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1282 processDeferredActions();
1283 break;
1284 case FLUSHING_DECODER:
1285 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1286 break; // Wait for flush to complete.
1287 case FLUSHING_DECODER_SHUTDOWN:
1288 break; // Wait for flush to complete.
1289 case SHUTTING_DOWN_DECODER:
1290 break; // Wait for shutdown to complete.
1291 case FLUSHED:
1292 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1293 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1294 break;
1295 case SHUT_DOWN:
1296 finishFlushIfPossible(); // Should not occur.
1297 break; // Finish anyways.
1298 }
1299 if (mSource != nullptr) {
1300 if (audio) {
1301 if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001302 || mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
1303 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001304 // When both audio and video have error, or this stream has only audio
1305 // which has error, notify client of error.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001306 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001307 } else {
1308 // Only audio track has error. Video track could be still good to play.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001309 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001310 }
1311 mAudioDecoderError = true;
1312 } else {
1313 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
1314 || mAudioSink == NULL || mAudioDecoder == NULL) {
1315 // When both audio and video have error, or this stream has only video
1316 // which has error, notify client of error.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001317 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001318 } else {
1319 // Only video track has error. Audio track could be still good to play.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001320 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001321 }
1322 mVideoDecoderError = true;
1323 }
1324 }
1325 } else {
1326 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1327 what,
1328 what >> 24,
1329 (what >> 16) & 0xff,
1330 (what >> 8) & 0xff,
1331 what & 0xff);
1332 }
1333
1334 break;
1335 }
1336
1337 case kWhatRendererNotify:
1338 {
1339 int32_t requesterGeneration = mRendererGeneration - 1;
1340 CHECK(msg->findInt32("generation", &requesterGeneration));
1341 if (requesterGeneration != mRendererGeneration) {
1342 ALOGV("got message from old renderer, generation(%d:%d)",
1343 requesterGeneration, mRendererGeneration);
1344 return;
1345 }
1346
1347 int32_t what;
1348 CHECK(msg->findInt32("what", &what));
1349
1350 if (what == Renderer::kWhatEOS) {
1351 int32_t audio;
1352 CHECK(msg->findInt32("audio", &audio));
1353
1354 int32_t finalResult;
1355 CHECK(msg->findInt32("finalResult", &finalResult));
1356
1357 if (audio) {
1358 mAudioEOS = true;
1359 } else {
1360 mVideoEOS = true;
1361 }
1362
1363 if (finalResult == ERROR_END_OF_STREAM) {
1364 ALOGV("reached %s EOS", audio ? "audio" : "video");
1365 } else {
1366 ALOGE("%s track encountered an error (%d)",
1367 audio ? "audio" : "video", finalResult);
1368
1369 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001370 mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001371 }
1372
1373 if ((mAudioEOS || mAudioDecoder == NULL)
1374 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001375 notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001376 }
1377 } else if (what == Renderer::kWhatFlushComplete) {
1378 int32_t audio;
1379 CHECK(msg->findInt32("audio", &audio));
1380
1381 if (audio) {
1382 mAudioEOS = false;
1383 } else {
1384 mVideoEOS = false;
1385 }
1386
1387 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1388 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1389 || mFlushingAudio == SHUT_DOWN)) {
1390 // Flush has been handled by tear down.
1391 break;
1392 }
1393 handleFlushComplete(audio, false /* isDecoder */);
1394 finishFlushIfPossible();
1395 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jia57aeffd2018-02-15 16:01:14 -08001396 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001397 } else if (what == Renderer::kWhatMediaRenderingStart) {
1398 ALOGV("media rendering started");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001399 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001400 } else if (what == Renderer::kWhatAudioTearDown) {
1401 int32_t reason;
1402 CHECK(msg->findInt32("reason", &reason));
1403 ALOGV("Tear down audio with reason %d.", reason);
1404 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1405 // TimeoutWhenPaused is only for offload mode.
1406 ALOGW("Receive a stale message for teardown.");
1407 break;
1408 }
1409 int64_t positionUs;
1410 if (!msg->findInt64("positionUs", &positionUs)) {
1411 positionUs = mPreviousSeekTimeUs;
1412 }
1413
1414 restartAudio(
1415 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1416 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1417 }
1418 break;
1419 }
1420
1421 case kWhatMoreDataQueued:
1422 {
1423 break;
1424 }
1425
1426 case kWhatReset:
1427 {
1428 ALOGV("kWhatReset");
1429
1430 mResetting = true;
1431 stopPlaybackTimer("kWhatReset");
1432 stopRebufferingTimer(true);
1433
1434 mDeferredActions.push_back(
1435 new FlushDecoderAction(
1436 FLUSH_CMD_SHUTDOWN /* audio */,
1437 FLUSH_CMD_SHUTDOWN /* video */));
1438
1439 mDeferredActions.push_back(
1440 new SimpleAction(&NuPlayer2::performReset));
1441
1442 processDeferredActions();
1443 break;
1444 }
1445
1446 case kWhatNotifyTime:
1447 {
1448 ALOGV("kWhatNotifyTime");
1449 int64_t timerUs;
1450 CHECK(msg->findInt64("timerUs", &timerUs));
1451
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001452 notifyListener(mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001453 break;
1454 }
1455
1456 case kWhatSeek:
1457 {
1458 int64_t seekTimeUs;
1459 int32_t mode;
1460 int32_t needNotify;
1461 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1462 CHECK(msg->findInt32("mode", &mode));
1463 CHECK(msg->findInt32("needNotify", &needNotify));
1464
1465 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1466 (long long)seekTimeUs, mode, needNotify);
1467
1468 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001469 if (!mSourceStarted) {
1470 mSourceStarted = true;
1471 mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001472 }
Wei Jia083e9092018-02-12 11:46:04 -08001473 if (seekTimeUs > 0) {
1474 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1475 }
1476
Wei Jia53692fa2017-12-11 10:33:46 -08001477 if (needNotify) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001478 notifyDriverSeekComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001479 }
1480 break;
1481 }
1482
Wei Jia083e9092018-02-12 11:46:04 -08001483 // seeks can take a while, so we essentially paused
1484 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
1485
Wei Jia53692fa2017-12-11 10:33:46 -08001486 mDeferredActions.push_back(
1487 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1488 FLUSH_CMD_FLUSH /* video */));
1489
1490 mDeferredActions.push_back(
1491 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1492
1493 // After a flush without shutdown, decoder is paused.
1494 // Don't resume it until source seek is done, otherwise it could
1495 // start pulling stale data too soon.
1496 mDeferredActions.push_back(
1497 new ResumeDecoderAction(needNotify));
1498
1499 processDeferredActions();
1500 break;
1501 }
1502
1503 case kWhatPause:
1504 {
Wei Jia6376cd52018-09-26 11:42:55 -07001505 if (!mStarted) {
1506 onStart(false /* play */);
1507 }
Wei Jia53692fa2017-12-11 10:33:46 -08001508 onPause();
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001509 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001510 mPausedByClient = true;
1511 break;
1512 }
1513
1514 case kWhatSourceNotify:
1515 {
1516 onSourceNotify(msg);
1517 break;
1518 }
1519
1520 case kWhatClosedCaptionNotify:
1521 {
1522 onClosedCaptionNotify(msg);
1523 break;
1524 }
1525
1526 case kWhatPrepareDrm:
1527 {
1528 status_t status = onPrepareDrm(msg);
1529
1530 sp<AMessage> response = new AMessage;
1531 response->setInt32("status", status);
1532 sp<AReplyToken> replyID;
1533 CHECK(msg->senderAwaitsResponse(&replyID));
1534 response->postReply(replyID);
1535 break;
1536 }
1537
1538 case kWhatReleaseDrm:
1539 {
1540 status_t status = onReleaseDrm();
1541
1542 sp<AMessage> response = new AMessage;
1543 response->setInt32("status", status);
1544 sp<AReplyToken> replyID;
1545 CHECK(msg->senderAwaitsResponse(&replyID));
1546 response->postReply(replyID);
1547 break;
1548 }
1549
1550 default:
1551 TRESPASS();
1552 break;
1553 }
1554}
1555
1556void NuPlayer2::onResume() {
1557 if (!mPaused || mResetting) {
1558 ALOGD_IF(mResetting, "resetting, onResume discarded");
1559 return;
1560 }
1561 mPaused = false;
1562 if (mSource != NULL) {
1563 mSource->resume();
1564 } else {
1565 ALOGW("resume called when source is gone or not set");
1566 }
1567 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1568 // needed.
1569 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1570 instantiateDecoder(true /* audio */, &mAudioDecoder);
1571 }
1572 if (mRenderer != NULL) {
1573 mRenderer->resume();
1574 } else {
1575 ALOGW("resume called when renderer is gone or not set");
1576 }
1577
1578 startPlaybackTimer("onresume");
1579}
1580
Wei Jia6376cd52018-09-26 11:42:55 -07001581void NuPlayer2::onStart(bool play) {
Wei Jia53692fa2017-12-11 10:33:46 -08001582 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1583
1584 if (!mSourceStarted) {
1585 mSourceStarted = true;
1586 mSource->start();
1587 }
Wei Jia53692fa2017-12-11 10:33:46 -08001588
1589 mOffloadAudio = false;
1590 mAudioEOS = false;
1591 mVideoEOS = false;
1592 mStarted = true;
1593 mPaused = false;
1594
1595 uint32_t flags = 0;
1596
1597 if (mSource->isRealTime()) {
1598 flags |= Renderer::FLAG_REAL_TIME;
1599 }
1600
1601 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1602 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1603 if (!hasAudio && !hasVideo) {
1604 ALOGE("no metadata for either audio or video source");
1605 mSource->stop();
1606 mSourceStarted = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001607 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001608 return;
1609 }
1610 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1611
1612 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1613
1614 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1615 if (mAudioSink != NULL) {
1616 streamType = mAudioSink->getAudioStreamType();
1617 }
1618
1619 mOffloadAudio =
1620 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
1621 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1622
1623 // Modular DRM: Disabling audio offload if the source is protected
1624 if (mOffloadAudio && mIsDrmProtected) {
1625 mOffloadAudio = false;
1626 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1627 }
1628
1629 if (mOffloadAudio) {
1630 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1631 }
1632
1633 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1634 ++mRendererGeneration;
1635 notify->setInt32("generation", mRendererGeneration);
1636 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1637 mRendererLooper = new ALooper;
1638 mRendererLooper->setName("NuPlayerRenderer");
1639 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1640 mRendererLooper->registerHandler(mRenderer);
1641
1642 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1643 if (err != OK) {
1644 mSource->stop();
1645 mSourceStarted = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001646 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001647 return;
1648 }
1649
1650 float rate = getFrameRate();
1651 if (rate > 0) {
1652 mRenderer->setVideoFrameRate(rate);
1653 }
1654
Wei Jia6376cd52018-09-26 11:42:55 -07001655 // Renderer is created in paused state.
1656 if (play) {
1657 mRenderer->resume();
1658 }
1659
Wei Jia53692fa2017-12-11 10:33:46 -08001660 if (mVideoDecoder != NULL) {
1661 mVideoDecoder->setRenderer(mRenderer);
1662 }
1663 if (mAudioDecoder != NULL) {
1664 mAudioDecoder->setRenderer(mRenderer);
1665 }
1666
1667 startPlaybackTimer("onstart");
Wei Jia975be2f2018-08-23 18:23:04 -07001668 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001669
1670 postScanSources();
1671}
1672
1673void NuPlayer2::startPlaybackTimer(const char *where) {
1674 Mutex::Autolock autoLock(mPlayingTimeLock);
1675 if (mLastStartedPlayingTimeNs == 0) {
1676 mLastStartedPlayingTimeNs = systemTime();
1677 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1678 }
1679}
1680
1681void NuPlayer2::stopPlaybackTimer(const char *where) {
1682 Mutex::Autolock autoLock(mPlayingTimeLock);
1683
1684 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1685
1686 if (mLastStartedPlayingTimeNs != 0) {
1687 sp<NuPlayer2Driver> driver = mDriver.promote();
1688 if (driver != NULL) {
1689 int64_t now = systemTime();
1690 int64_t played = now - mLastStartedPlayingTimeNs;
1691 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1692
1693 if (played > 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001694 driver->notifyMorePlayingTimeUs(mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001695 }
1696 }
1697 mLastStartedPlayingTimeNs = 0;
1698 }
1699}
1700
1701void NuPlayer2::startRebufferingTimer() {
1702 Mutex::Autolock autoLock(mPlayingTimeLock);
1703 if (mLastStartedRebufferingTimeNs == 0) {
1704 mLastStartedRebufferingTimeNs = systemTime();
1705 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1706 }
1707}
1708
1709void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1710 Mutex::Autolock autoLock(mPlayingTimeLock);
1711
1712 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)", mLastStartedRebufferingTimeNs, exitingPlayback);
1713
1714 if (mLastStartedRebufferingTimeNs != 0) {
1715 sp<NuPlayer2Driver> driver = mDriver.promote();
1716 if (driver != NULL) {
1717 int64_t now = systemTime();
1718 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1719 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1720
1721 if (rebuffered > 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001722 driver->notifyMoreRebufferingTimeUs(mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001723 if (exitingPlayback) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001724 driver->notifyRebufferingWhenExit(mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001725 }
1726 }
1727 }
1728 mLastStartedRebufferingTimeNs = 0;
1729 }
1730}
1731
1732void NuPlayer2::onPause() {
1733
1734 stopPlaybackTimer("onPause");
1735
1736 if (mPaused) {
1737 return;
1738 }
1739 mPaused = true;
1740 if (mSource != NULL) {
1741 mSource->pause();
1742 } else {
1743 ALOGW("pause called when source is gone or not set");
1744 }
1745 if (mRenderer != NULL) {
1746 mRenderer->pause();
1747 } else {
1748 ALOGW("pause called when renderer is gone or not set");
1749 }
1750
1751}
1752
1753bool NuPlayer2::audioDecoderStillNeeded() {
1754 // Audio decoder is no longer needed if it's in shut/shutting down status.
1755 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1756}
1757
1758void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1759 // We wait for both the decoder flush and the renderer flush to complete
1760 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1761
1762 mFlushComplete[audio][isDecoder] = true;
1763 if (!mFlushComplete[audio][!isDecoder]) {
1764 return;
1765 }
1766
1767 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1768 switch (*state) {
1769 case FLUSHING_DECODER:
1770 {
1771 *state = FLUSHED;
1772 break;
1773 }
1774
1775 case FLUSHING_DECODER_SHUTDOWN:
1776 {
1777 *state = SHUTTING_DOWN_DECODER;
1778
1779 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1780 getDecoder(audio)->initiateShutdown();
1781 break;
1782 }
1783
1784 default:
1785 // decoder flush completes only occur in a flushing state.
1786 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1787 break;
1788 }
1789}
1790
1791void NuPlayer2::finishFlushIfPossible() {
1792 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1793 && mFlushingAudio != SHUT_DOWN) {
1794 return;
1795 }
1796
1797 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1798 && mFlushingVideo != SHUT_DOWN) {
1799 return;
1800 }
1801
1802 ALOGV("both audio and video are flushed now.");
1803
1804 mFlushingAudio = NONE;
1805 mFlushingVideo = NONE;
1806
1807 clearFlushComplete();
1808
1809 processDeferredActions();
1810}
1811
1812void NuPlayer2::postScanSources() {
1813 if (mScanSourcesPending) {
1814 return;
1815 }
1816
1817 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1818 msg->setInt32("generation", mScanSourcesGeneration);
1819 msg->post();
1820
1821 mScanSourcesPending = true;
1822}
1823
1824void NuPlayer2::tryOpenAudioSinkForOffload(
1825 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1826 // Note: This is called early in NuPlayer2 to determine whether offloading
1827 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1828
1829 status_t err = mRenderer->openAudioSink(
1830 format, true /* offloadOnly */, hasVideo,
1831 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
1832 if (err != OK) {
1833 // Any failure we turn off mOffloadAudio.
1834 mOffloadAudio = false;
1835 } else if (mOffloadAudio) {
1836 sendMetaDataToHal(mAudioSink, audioMeta);
1837 }
1838}
1839
1840void NuPlayer2::closeAudioSink() {
1841 mRenderer->closeAudioSink();
1842}
1843
1844void NuPlayer2::restartAudio(
1845 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1846 if (mAudioDecoder != NULL) {
1847 mAudioDecoder->pause();
1848 mAudioDecoder.clear();
1849 mAudioDecoderError = false;
1850 ++mAudioDecoderGeneration;
1851 }
1852 if (mFlushingAudio == FLUSHING_DECODER) {
1853 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1854 mFlushingAudio = FLUSHED;
1855 finishFlushIfPossible();
1856 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1857 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1858 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1859 mFlushingAudio = SHUT_DOWN;
1860 finishFlushIfPossible();
1861 needsToCreateAudioDecoder = false;
1862 }
1863 if (mRenderer == NULL) {
1864 return;
1865 }
1866 closeAudioSink();
1867 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1868 if (mVideoDecoder != NULL) {
1869 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1870 }
1871
1872 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1873
1874 if (forceNonOffload) {
1875 mRenderer->signalDisableOffloadAudio();
1876 mOffloadAudio = false;
1877 }
1878 if (needsToCreateAudioDecoder) {
1879 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1880 }
1881}
1882
1883void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
1884 if (mSource == NULL || mAudioSink == NULL) {
1885 return;
1886 }
1887
1888 if (mRenderer == NULL) {
1889 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1890 mOffloadAudio = false;
1891 return;
1892 }
1893
1894 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1895 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1896 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1897 const bool hasVideo = (videoFormat != NULL);
1898 bool canOffload = canOffloadStream(
1899 audioMeta, hasVideo, mSource->isStreaming(), streamType)
1900 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1901
1902 // Modular DRM: Disabling audio offload if the source is protected
1903 if (canOffload && mIsDrmProtected) {
1904 canOffload = false;
1905 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1906 }
1907
1908 if (canOffload) {
1909 if (!mOffloadAudio) {
1910 mRenderer->signalEnableOffloadAudio();
1911 }
1912 // open audio sink early under offload mode.
1913 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
1914 } else {
1915 if (mOffloadAudio) {
1916 mRenderer->signalDisableOffloadAudio();
1917 mOffloadAudio = false;
1918 }
1919 }
1920}
1921
1922status_t NuPlayer2::instantiateDecoder(
1923 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
1924 // The audio decoder could be cleared by tear down. If still in shut down
1925 // process, no need to create a new audio decoder.
1926 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
1927 return OK;
1928 }
1929
1930 sp<AMessage> format = mSource->getFormat(audio);
1931
1932 if (format == NULL) {
1933 return UNKNOWN_ERROR;
1934 } else {
1935 status_t err;
1936 if (format->findInt32("err", &err) && err) {
1937 return err;
1938 }
1939 }
1940
1941 format->setInt32("priority", 0 /* realtime */);
1942
1943 if (!audio) {
1944 AString mime;
1945 CHECK(format->findString("mime", &mime));
1946
1947 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
1948 if (mCCDecoder == NULL) {
1949 mCCDecoder = new CCDecoder(ccNotify);
1950 }
1951
1952 if (mSourceFlags & Source::FLAG_SECURE) {
1953 format->setInt32("secure", true);
1954 }
1955
1956 if (mSourceFlags & Source::FLAG_PROTECTED) {
1957 format->setInt32("protected", true);
1958 }
1959
1960 float rate = getFrameRate();
1961 if (rate > 0) {
1962 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
1963 }
1964 }
1965
1966 if (audio) {
1967 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1968 ++mAudioDecoderGeneration;
1969 notify->setInt32("generation", mAudioDecoderGeneration);
1970
1971 if (checkAudioModeChange) {
1972 determineAudioModeChange(format);
1973 }
1974 if (mOffloadAudio) {
1975 mSource->setOffloadAudio(true /* offload */);
1976
1977 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1978 format->setInt32("has-video", hasVideo);
1979 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
1980 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
1981 } else {
1982 mSource->setOffloadAudio(false /* offload */);
1983
1984 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
1985 ALOGV("instantiateDecoder audio Decoder");
1986 }
1987 mAudioDecoderError = false;
1988 } else {
1989 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
1990 ++mVideoDecoderGeneration;
1991 notify->setInt32("generation", mVideoDecoderGeneration);
1992
1993 *decoder = new Decoder(
Wei Jia28288fb2017-12-15 13:45:29 -08001994 notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08001995 mVideoDecoderError = false;
1996
1997 // enable FRC if high-quality AV sync is requested, even if not
1998 // directly queuing to display, as this will even improve textureview
1999 // playback.
2000 {
2001 if (property_get_bool("persist.sys.media.avsync", false)) {
2002 format->setInt32("auto-frc", 1);
2003 }
2004 }
2005 }
2006 (*decoder)->init();
2007
2008 // Modular DRM
2009 if (mIsDrmProtected) {
2010 format->setObject("crypto", mCrypto);
2011 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d", mCrypto.get(),
2012 (mSourceFlags & Source::FLAG_SECURE) != 0);
2013 }
2014
2015 (*decoder)->configure(format);
2016
2017 if (!audio) {
2018 sp<AMessage> params = new AMessage();
2019 float rate = getFrameRate();
2020 if (rate > 0) {
2021 params->setFloat("frame-rate-total", rate);
2022 }
2023
2024 sp<MetaData> fileMeta = getFileMeta();
2025 if (fileMeta != NULL) {
2026 int32_t videoTemporalLayerCount;
2027 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2028 && videoTemporalLayerCount > 0) {
2029 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2030 }
2031 }
2032
2033 if (params->countEntries() > 0) {
2034 (*decoder)->setParameters(params);
2035 }
2036 }
2037 return OK;
2038}
2039
2040void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002041 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002042 const sp<AMessage> &inputFormat,
2043 const sp<AMessage> &outputFormat) {
2044 if (inputFormat == NULL) {
2045 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002046 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002047 return;
2048 }
2049 int32_t err = OK;
2050 inputFormat->findInt32("err", &err);
2051 if (err == -EWOULDBLOCK) {
2052 ALOGW("Video meta is not available yet!");
2053 return;
2054 }
2055 if (err != OK) {
2056 ALOGW("Something is wrong with video meta!");
2057 return;
2058 }
2059
2060 int32_t displayWidth, displayHeight;
2061 if (outputFormat != NULL) {
2062 int32_t width, height;
2063 CHECK(outputFormat->findInt32("width", &width));
2064 CHECK(outputFormat->findInt32("height", &height));
2065
2066 int32_t cropLeft, cropTop, cropRight, cropBottom;
2067 CHECK(outputFormat->findRect(
2068 "crop",
2069 &cropLeft, &cropTop, &cropRight, &cropBottom));
2070
2071 displayWidth = cropRight - cropLeft + 1;
2072 displayHeight = cropBottom - cropTop + 1;
2073
2074 ALOGV("Video output format changed to %d x %d "
2075 "(crop: %d x %d @ (%d, %d))",
2076 width, height,
2077 displayWidth,
2078 displayHeight,
2079 cropLeft, cropTop);
2080 } else {
2081 CHECK(inputFormat->findInt32("width", &displayWidth));
2082 CHECK(inputFormat->findInt32("height", &displayHeight));
2083
2084 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2085 }
2086
2087 // Take into account sample aspect ratio if necessary:
2088 int32_t sarWidth, sarHeight;
2089 if (inputFormat->findInt32("sar-width", &sarWidth)
2090 && inputFormat->findInt32("sar-height", &sarHeight)
2091 && sarWidth > 0 && sarHeight > 0) {
2092 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2093
2094 displayWidth = (displayWidth * sarWidth) / sarHeight;
2095
2096 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2097 } else {
2098 int32_t width, height;
2099 if (inputFormat->findInt32("display-width", &width)
2100 && inputFormat->findInt32("display-height", &height)
2101 && width > 0 && height > 0
2102 && displayWidth > 0 && displayHeight > 0) {
2103 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2104 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2105 } else {
2106 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2107 }
2108 ALOGV("Video display width and height are overridden to %d x %d",
2109 displayWidth, displayHeight);
2110 }
2111 }
2112
2113 int32_t rotationDegrees;
2114 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2115 rotationDegrees = 0;
2116 }
2117
2118 if (rotationDegrees == 90 || rotationDegrees == 270) {
2119 int32_t tmp = displayWidth;
2120 displayWidth = displayHeight;
2121 displayHeight = tmp;
2122 }
2123
2124 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002125 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002126 MEDIA2_SET_VIDEO_SIZE,
2127 displayWidth,
2128 displayHeight);
2129}
2130
Dongwon Kang41929fb2018-09-09 08:29:56 -07002131void NuPlayer2::notifyListener(
2132 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002133 if (mDriver == NULL) {
2134 return;
2135 }
2136
2137 sp<NuPlayer2Driver> driver = mDriver.promote();
2138
2139 if (driver == NULL) {
2140 return;
2141 }
2142
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002143 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002144}
2145
2146void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2147 ALOGV("[%s] flushDecoder needShutdown=%d",
2148 audio ? "audio" : "video", needShutdown);
2149
2150 const sp<DecoderBase> &decoder = getDecoder(audio);
2151 if (decoder == NULL) {
2152 ALOGI("flushDecoder %s without decoder present",
2153 audio ? "audio" : "video");
2154 return;
2155 }
2156
2157 // Make sure we don't continue to scan sources until we finish flushing.
2158 ++mScanSourcesGeneration;
2159 if (mScanSourcesPending) {
2160 if (!needShutdown) {
2161 mDeferredActions.push_back(
2162 new SimpleAction(&NuPlayer2::performScanSources));
2163 }
2164 mScanSourcesPending = false;
2165 }
2166
2167 decoder->signalFlush();
2168
2169 FlushStatus newStatus =
2170 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2171
2172 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2173 mFlushComplete[audio][true /* isDecoder */] = false;
2174 if (audio) {
2175 ALOGE_IF(mFlushingAudio != NONE,
2176 "audio flushDecoder() is called in state %d", mFlushingAudio);
2177 mFlushingAudio = newStatus;
2178 } else {
2179 ALOGE_IF(mFlushingVideo != NONE,
2180 "video flushDecoder() is called in state %d", mFlushingVideo);
2181 mFlushingVideo = newStatus;
2182 }
2183}
2184
2185void NuPlayer2::queueDecoderShutdown(
2186 bool audio, bool video, const sp<AMessage> &reply) {
2187 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2188
2189 mDeferredActions.push_back(
2190 new FlushDecoderAction(
2191 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2192 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2193
2194 mDeferredActions.push_back(
2195 new SimpleAction(&NuPlayer2::performScanSources));
2196
2197 mDeferredActions.push_back(new PostMessageAction(reply));
2198
2199 processDeferredActions();
2200}
2201
2202status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2203 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002204 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2205 status_t ret = native_window_set_scaling_mode(
2206 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002207 if (ret != OK) {
2208 ALOGE("Failed to set scaling mode (%d): %s",
2209 -ret, strerror(-ret));
2210 return ret;
2211 }
2212 }
2213 return OK;
2214}
2215
Dongwon Kang9f631982018-07-10 12:34:41 -07002216status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002217 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2218 msg->setPointer("reply", reply);
2219
2220 sp<AMessage> response;
2221 status_t err = msg->postAndAwaitResponse(&response);
2222 return err;
2223}
2224
Dongwon Kang9f631982018-07-10 12:34:41 -07002225status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002226 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2227 msg->setPointer("reply", reply);
2228 msg->setInt32("type", type);
2229
2230 sp<AMessage> response;
2231 status_t err = msg->postAndAwaitResponse(&response);
2232 if (err == OK && response != NULL) {
2233 CHECK(response->findInt32("err", &err));
2234 }
2235 return err;
2236}
2237
2238status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2239 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2240 msg->setSize("trackIndex", trackIndex);
2241 msg->setInt32("select", select);
2242 msg->setInt64("timeUs", timeUs);
2243
2244 sp<AMessage> response;
2245 status_t err = msg->postAndAwaitResponse(&response);
2246
2247 if (err != OK) {
2248 return err;
2249 }
2250
2251 if (!response->findInt32("err", &err)) {
2252 err = OK;
2253 }
2254
2255 return err;
2256}
2257
2258status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2259 sp<Renderer> renderer = mRenderer;
2260 if (renderer == NULL) {
2261 return NO_INIT;
2262 }
2263
2264 return renderer->getCurrentPosition(mediaUs);
2265}
2266
2267void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2268 CHECK(mTrackStats != NULL);
2269
2270 mTrackStats->clear();
2271 if (mVideoDecoder != NULL) {
2272 mTrackStats->push_back(mVideoDecoder->getStats());
2273 }
2274 if (mAudioDecoder != NULL) {
2275 mTrackStats->push_back(mAudioDecoder->getStats());
2276 }
2277}
2278
2279sp<MetaData> NuPlayer2::getFileMeta() {
2280 return mSource->getFileFormatMeta();
2281}
2282
2283float NuPlayer2::getFrameRate() {
2284 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2285 if (meta == NULL) {
2286 return 0;
2287 }
2288 int32_t rate;
2289 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2290 // fall back to try file meta
2291 sp<MetaData> fileMeta = getFileMeta();
2292 if (fileMeta == NULL) {
2293 ALOGW("source has video meta but not file meta");
2294 return -1;
2295 }
2296 int32_t fileMetaRate;
2297 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2298 return -1;
2299 }
2300 return fileMetaRate;
2301 }
2302 return rate;
2303}
2304
2305void NuPlayer2::schedulePollDuration() {
2306 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2307 msg->setInt32("generation", mPollDurationGeneration);
2308 msg->post();
2309}
2310
2311void NuPlayer2::cancelPollDuration() {
2312 ++mPollDurationGeneration;
2313}
2314
2315void NuPlayer2::processDeferredActions() {
2316 while (!mDeferredActions.empty()) {
2317 // We won't execute any deferred actions until we're no longer in
2318 // an intermediate state, i.e. one more more decoders are currently
2319 // flushing or shutting down.
2320
2321 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2322 // We're currently flushing, postpone the reset until that's
2323 // completed.
2324
2325 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2326 mFlushingAudio, mFlushingVideo);
2327
2328 break;
2329 }
2330
2331 sp<Action> action = *mDeferredActions.begin();
2332 mDeferredActions.erase(mDeferredActions.begin());
2333
2334 action->execute(this);
2335 }
2336}
2337
2338void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2339 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2340 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2341
2342 if (mSource == NULL) {
2343 // This happens when reset occurs right before the loop mode
2344 // asynchronously seeks to the start of the stream.
2345 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2346 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2347 mAudioDecoder.get(), mVideoDecoder.get());
2348 return;
2349 }
2350 mPreviousSeekTimeUs = seekTimeUs;
2351 mSource->seekTo(seekTimeUs, mode);
2352 ++mTimedTextGeneration;
2353
2354 // everything's flushed, continue playback.
2355}
2356
2357void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2358 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2359
2360 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2361 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2362 return;
2363 }
2364
2365 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2366 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2367 }
2368
2369 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2370 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2371 }
2372}
2373
2374void NuPlayer2::performReset() {
2375 ALOGV("performReset");
2376
2377 CHECK(mAudioDecoder == NULL);
2378 CHECK(mVideoDecoder == NULL);
2379
2380 stopPlaybackTimer("performReset");
2381 stopRebufferingTimer(true);
2382
2383 cancelPollDuration();
2384
2385 ++mScanSourcesGeneration;
2386 mScanSourcesPending = false;
2387
2388 if (mRendererLooper != NULL) {
2389 if (mRenderer != NULL) {
2390 mRendererLooper->unregisterHandler(mRenderer->id());
2391 }
2392 mRendererLooper->stop();
2393 mRendererLooper.clear();
2394 }
2395 mRenderer.clear();
2396 ++mRendererGeneration;
2397
2398 if (mSource != NULL) {
2399 mSource->stop();
2400
2401 Mutex::Autolock autoLock(mSourceLock);
2402 mSource.clear();
2403 }
2404
2405 if (mDriver != NULL) {
2406 sp<NuPlayer2Driver> driver = mDriver.promote();
2407 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002408 driver->notifyResetComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002409 }
2410 }
2411
2412 mStarted = false;
2413 mPrepared = false;
2414 mResetting = false;
2415 mSourceStarted = false;
2416
2417 // Modular DRM
2418 if (mCrypto != NULL) {
2419 // decoders will be flushed before this so their mCrypto would go away on their own
2420 // TODO change to ALOGV
2421 ALOGD("performReset mCrypto: %p", mCrypto.get());
2422 mCrypto.clear();
2423 }
2424 mIsDrmProtected = false;
2425}
2426
Wei Jia57aeffd2018-02-15 16:01:14 -08002427void NuPlayer2::performPlayNextDataSource() {
2428 ALOGV("performPlayNextDataSource");
2429
2430 CHECK(mAudioDecoder == NULL);
2431 CHECK(mVideoDecoder == NULL);
2432
2433 stopPlaybackTimer("performPlayNextDataSource");
2434 stopRebufferingTimer(true);
2435
2436 cancelPollDuration();
2437
2438 ++mScanSourcesGeneration;
2439 mScanSourcesPending = false;
2440
2441 ++mRendererGeneration;
2442
2443 if (mSource != NULL) {
2444 mSource->stop();
2445 }
2446
2447 long previousSrcId;
2448 {
2449 Mutex::Autolock autoLock(mSourceLock);
2450 mSource = mNextSource;
2451 mNextSource = NULL;
2452 previousSrcId = mSrcId;
2453 mSrcId = mNextSrcId;
2454 ++mNextSrcId; // to distinguish the two sources.
2455 }
2456
2457 if (mDriver != NULL) {
2458 sp<NuPlayer2Driver> driver = mDriver.promote();
2459 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002460 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
2461 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002462 }
2463 }
2464
2465 mStarted = false;
2466 mPrepared = true; // TODO: what if it's not prepared
2467 mResetting = false;
2468 mSourceStarted = false;
2469
2470 // Modular DRM
2471 if (mCrypto != NULL) {
2472 // decoders will be flushed before this so their mCrypto would go away on their own
2473 // TODO change to ALOGV
2474 ALOGD("performReset mCrypto: %p", mCrypto.get());
2475 mCrypto.clear();
2476 }
2477 mIsDrmProtected = false;
2478
2479 if (mRenderer != NULL) {
2480 mRenderer->resume();
2481 }
2482
Wei Jia6376cd52018-09-26 11:42:55 -07002483 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002484 mPausedByClient = false;
2485 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
2486}
2487
Wei Jia53692fa2017-12-11 10:33:46 -08002488void NuPlayer2::performScanSources() {
2489 ALOGV("performScanSources");
2490
2491 if (!mStarted) {
2492 return;
2493 }
2494
2495 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2496 postScanSources();
2497 }
2498}
2499
Wei Jia28288fb2017-12-15 13:45:29 -08002500void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002501 ALOGV("performSetSurface");
2502
Wei Jia28288fb2017-12-15 13:45:29 -08002503 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002504
2505 // XXX - ignore error from setVideoScalingMode for now
2506 setVideoScalingMode(mVideoScalingMode);
2507
2508 if (mDriver != NULL) {
2509 sp<NuPlayer2Driver> driver = mDriver.promote();
2510 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002511 driver->notifySetSurfaceComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002512 }
2513 }
2514}
2515
2516void NuPlayer2::performResumeDecoders(bool needNotify) {
2517 if (needNotify) {
2518 mResumePending = true;
2519 if (mVideoDecoder == NULL) {
2520 // if audio-only, we can notify seek complete now,
2521 // as the resume operation will be relatively fast.
2522 finishResume();
2523 }
2524 }
2525
2526 if (mVideoDecoder != NULL) {
2527 // When there is continuous seek, MediaPlayer will cache the seek
2528 // position, and send down new seek request when previous seek is
2529 // complete. Let's wait for at least one video output frame before
2530 // notifying seek complete, so that the video thumbnail gets updated
2531 // when seekbar is dragged.
2532 mVideoDecoder->signalResume(needNotify);
2533 }
2534
2535 if (mAudioDecoder != NULL) {
2536 mAudioDecoder->signalResume(false /* needNotify */);
2537 }
2538}
2539
2540void NuPlayer2::finishResume() {
2541 if (mResumePending) {
2542 mResumePending = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002543 notifyDriverSeekComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002544 }
2545}
2546
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002547void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002548 if (mDriver != NULL) {
2549 sp<NuPlayer2Driver> driver = mDriver.promote();
2550 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002551 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002552 }
2553 }
2554}
2555
2556void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2557 int32_t what;
2558 CHECK(msg->findInt32("what", &what));
2559
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002560 int64_t srcId;
2561 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002562 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002563 case Source::kWhatPrepared:
2564 {
2565 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
2566 if (mSource == NULL) {
2567 // This is a stale notification from a source that was
2568 // asynchronously preparing when the client called reset().
2569 // We handled the reset, the source is gone.
2570 break;
2571 }
2572
2573 int32_t err;
2574 CHECK(msg->findInt32("err", &err));
2575
2576 if (err != OK) {
2577 // shut down potential secure codecs in case client never calls reset
2578 mDeferredActions.push_back(
2579 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2580 FLUSH_CMD_SHUTDOWN /* video */));
2581 processDeferredActions();
2582 } else {
2583 mPrepared = true;
2584 }
2585
2586 sp<NuPlayer2Driver> driver = mDriver.promote();
2587 if (driver != NULL) {
2588 // notify duration first, so that it's definitely set when
2589 // the app received the "prepare complete" callback.
2590 int64_t durationUs;
2591 if (mSource->getDuration(&durationUs) == OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002592 driver->notifyDuration(srcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -08002593 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002594 driver->notifyPrepareCompleted(srcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -08002595 }
2596
2597 break;
2598 }
2599
2600 // Modular DRM
2601 case Source::kWhatDrmInfo:
2602 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002603 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002604 sp<ABuffer> drmInfo;
2605 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002606 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002607
Dongwon Kang41929fb2018-09-09 08:29:56 -07002608 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2609 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002610
Dongwon Kang41929fb2018-09-09 08:29:56 -07002611 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002612
2613 break;
2614 }
2615
2616 case Source::kWhatFlagsChanged:
2617 {
2618 uint32_t flags;
2619 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2620
2621 sp<NuPlayer2Driver> driver = mDriver.promote();
2622 if (driver != NULL) {
2623
2624 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2625 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2626 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2627 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2628 (flags & Source::FLAG_CAN_PAUSE) != 0,
2629 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2630 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2631 (flags & Source::FLAG_CAN_SEEK) != 0,
2632 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2633 (flags & Source::FLAG_SECURE) != 0,
2634 (flags & Source::FLAG_PROTECTED) != 0);
2635
2636 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2637 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002638 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002639 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002640 driver->notifyFlagsChanged(srcId, flags);
Wei Jia53692fa2017-12-11 10:33:46 -08002641 }
2642
2643 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2644 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2645 cancelPollDuration();
2646 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2647 && (flags & Source::FLAG_DYNAMIC_DURATION)
2648 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2649 schedulePollDuration();
2650 }
2651
2652 mSourceFlags = flags;
2653 break;
2654 }
2655
2656 case Source::kWhatVideoSizeChanged:
2657 {
2658 sp<AMessage> format;
2659 CHECK(msg->findMessage("format", &format));
2660
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002661 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002662 break;
2663 }
2664
2665 case Source::kWhatBufferingUpdate:
2666 {
2667 int32_t percentage;
2668 CHECK(msg->findInt32("percentage", &percentage));
2669
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002670 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002671 break;
2672 }
2673
2674 case Source::kWhatPauseOnBufferingStart:
2675 {
2676 // ignore if not playing
2677 if (mStarted) {
2678 ALOGI("buffer low, pausing...");
2679
2680 startRebufferingTimer();
2681 mPausedForBuffering = true;
2682 onPause();
2683 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002684 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002685 break;
2686 }
2687
2688 case Source::kWhatResumeOnBufferingEnd:
2689 {
2690 // ignore if not playing
2691 if (mStarted) {
2692 ALOGI("buffer ready, resuming...");
2693
2694 stopRebufferingTimer(false);
2695 mPausedForBuffering = false;
2696
2697 // do not resume yet if client didn't unpause
2698 if (!mPausedByClient) {
2699 onResume();
2700 }
2701 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002702 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002703 break;
2704 }
2705
2706 case Source::kWhatCacheStats:
2707 {
2708 int32_t kbps;
2709 CHECK(msg->findInt32("bandwidth", &kbps));
2710
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002711 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002712 break;
2713 }
2714
2715 case Source::kWhatSubtitleData:
2716 {
2717 sp<ABuffer> buffer;
2718 CHECK(msg->findBuffer("buffer", &buffer));
2719
2720 sendSubtitleData(buffer, 0 /* baseIndex */);
2721 break;
2722 }
2723
2724 case Source::kWhatTimedMetaData:
2725 {
2726 sp<ABuffer> buffer;
2727 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002728 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002729 } else {
2730 sendTimedMetaData(buffer);
2731 }
2732 break;
2733 }
2734
2735 case Source::kWhatTimedTextData:
2736 {
2737 int32_t generation;
2738 if (msg->findInt32("generation", &generation)
2739 && generation != mTimedTextGeneration) {
2740 break;
2741 }
2742
2743 sp<ABuffer> buffer;
2744 CHECK(msg->findBuffer("buffer", &buffer));
2745
2746 sp<NuPlayer2Driver> driver = mDriver.promote();
2747 if (driver == NULL) {
2748 break;
2749 }
2750
Wei Jia800fe372018-02-20 15:00:45 -08002751 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002752 int64_t timeUs, posUs;
2753 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002754 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002755 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2756
2757 if (posUs < timeUs) {
2758 if (!msg->findInt32("generation", &generation)) {
2759 msg->setInt32("generation", mTimedTextGeneration);
2760 }
2761 msg->post(timeUs - posUs);
2762 } else {
2763 sendTimedTextData(buffer);
2764 }
2765 break;
2766 }
2767
2768 case Source::kWhatQueueDecoderShutdown:
2769 {
2770 int32_t audio, video;
2771 CHECK(msg->findInt32("audio", &audio));
2772 CHECK(msg->findInt32("video", &video));
2773
2774 sp<AMessage> reply;
2775 CHECK(msg->findMessage("reply", &reply));
2776
2777 queueDecoderShutdown(audio, video, reply);
2778 break;
2779 }
2780
2781 case Source::kWhatDrmNoLicense:
2782 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002783 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002784 break;
2785 }
2786
2787 default:
2788 TRESPASS();
2789 }
2790}
2791
2792void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2793 int32_t what;
2794 CHECK(msg->findInt32("what", &what));
2795
2796 switch (what) {
2797 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2798 {
2799 sp<ABuffer> buffer;
2800 CHECK(msg->findBuffer("buffer", &buffer));
2801
2802 size_t inbandTracks = 0;
2803 if (mSource != NULL) {
2804 inbandTracks = mSource->getTrackCount();
2805 }
2806
2807 sendSubtitleData(buffer, inbandTracks);
2808 break;
2809 }
2810
2811 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2812 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002813 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002814
2815 break;
2816 }
2817
2818 default:
2819 TRESPASS();
2820 }
2821
2822
2823}
2824
2825void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2826 int32_t trackIndex;
2827 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002828 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002829 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2830 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2831
Dongwon Kang41929fb2018-09-09 08:29:56 -07002832 PlayerMessage playerMsg;
2833 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2834 playerMsg.add_values()->set_int64_value(timeUs);
2835 playerMsg.add_values()->set_int64_value(durationUs);
2836 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002837
Dongwon Kang41929fb2018-09-09 08:29:56 -07002838 notifyListener(mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002839}
2840
2841void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2842 int64_t timeUs;
2843 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2844
Dongwon Kang41929fb2018-09-09 08:29:56 -07002845 PlayerMessage playerMsg;
2846 playerMsg.add_values()->set_int64_value(timeUs);
2847 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002848
Dongwon Kang41929fb2018-09-09 08:29:56 -07002849 notifyListener(mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002850}
2851
2852void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2853 const void *data;
2854 size_t size = 0;
2855 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002856 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002857
2858 AString mime;
2859 CHECK(buffer->meta()->findString("mime", &mime));
2860 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2861
2862 data = buffer->data();
2863 size = buffer->size();
2864
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002865 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002866 if (size > 0) {
2867 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2868 int32_t global = 0;
2869 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002870 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002871 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002872 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002873 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002874 TextDescriptions2::getPlayerMessageOfDescriptions(
2875 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002876 }
2877
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002878 if (playerMsg.values_size() > 0) {
2879 notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002880 } else { // send an empty timed text
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002881 notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002882 }
2883}
2884
2885const char *NuPlayer2::getDataSourceType() {
2886 switch (mDataSourceType) {
2887 case DATA_SOURCE_TYPE_HTTP_LIVE:
2888 return "HTTPLive";
2889
2890 case DATA_SOURCE_TYPE_RTSP:
2891 return "RTSP";
2892
2893 case DATA_SOURCE_TYPE_GENERIC_URL:
2894 return "GenURL";
2895
2896 case DATA_SOURCE_TYPE_GENERIC_FD:
2897 return "GenFD";
2898
2899 case DATA_SOURCE_TYPE_MEDIA:
2900 return "Media";
2901
Wei Jia53692fa2017-12-11 10:33:46 -08002902 case DATA_SOURCE_TYPE_NONE:
2903 default:
2904 return "None";
2905 }
2906 }
2907
2908// Modular DRM begin
2909status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
2910{
2911 ALOGV("prepareDrm ");
2912
2913 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
2914 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
2915 // synchronous call so just passing the address but with local copies of "const" args
2916 uint8_t UUID[16];
2917 memcpy(UUID, uuid, sizeof(UUID));
2918 Vector<uint8_t> sessionId = drmSessionId;
2919 msg->setPointer("uuid", (void*)UUID);
2920 msg->setPointer("drmSessionId", (void*)&sessionId);
2921
2922 sp<AMessage> response;
2923 status_t status = msg->postAndAwaitResponse(&response);
2924
2925 if (status == OK && response != NULL) {
2926 CHECK(response->findInt32("status", &status));
2927 ALOGV("prepareDrm ret: %d ", status);
2928 } else {
2929 ALOGE("prepareDrm err: %d", status);
2930 }
2931
2932 return status;
2933}
2934
2935status_t NuPlayer2::releaseDrm()
2936{
2937 ALOGV("releaseDrm ");
2938
2939 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
2940
2941 sp<AMessage> response;
2942 status_t status = msg->postAndAwaitResponse(&response);
2943
2944 if (status == OK && response != NULL) {
2945 CHECK(response->findInt32("status", &status));
2946 ALOGV("releaseDrm ret: %d ", status);
2947 } else {
2948 ALOGE("releaseDrm err: %d", status);
2949 }
2950
2951 return status;
2952}
2953
2954status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
2955{
2956 // TODO change to ALOGV
2957 ALOGD("onPrepareDrm ");
2958
2959 status_t status = INVALID_OPERATION;
2960 if (mSource == NULL) {
2961 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
2962 return status;
2963 }
2964
2965 uint8_t *uuid;
2966 Vector<uint8_t> *drmSessionId;
2967 CHECK(msg->findPointer("uuid", (void**)&uuid));
2968 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
2969
2970 status = OK;
2971 sp<AMediaCryptoWrapper> crypto = NULL;
2972
2973 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
2974 if (crypto == NULL) {
2975 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
2976 return status;
2977 }
2978 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
2979
2980 if (mCrypto != NULL) {
2981 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
2982 mCrypto.clear();
2983 }
2984
2985 mCrypto = crypto;
2986 mIsDrmProtected = true;
2987 // TODO change to ALOGV
2988 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
2989
2990 return status;
2991}
2992
2993status_t NuPlayer2::onReleaseDrm()
2994{
2995 // TODO change to ALOGV
2996 ALOGD("onReleaseDrm ");
2997
2998 if (!mIsDrmProtected) {
2999 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3000 }
3001
3002 mIsDrmProtected = false;
3003
3004 status_t status;
3005 if (mCrypto != NULL) {
3006 // notifying the source first before removing crypto from codec
3007 if (mSource != NULL) {
3008 mSource->releaseDrm();
3009 }
3010
3011 status=OK;
3012 // first making sure the codecs have released their crypto reference
3013 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3014 if (videoDecoder != NULL) {
3015 status = videoDecoder->releaseCrypto();
3016 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3017 }
3018
3019 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3020 if (audioDecoder != NULL) {
3021 status_t status_audio = audioDecoder->releaseCrypto();
3022 if (status == OK) { // otherwise, returning the first error
3023 status = status_audio;
3024 }
3025 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3026 }
3027
3028 // TODO change to ALOGV
3029 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3030 mCrypto.clear();
3031 } else { // mCrypto == NULL
3032 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3033 status = INVALID_OPERATION;
3034 }
3035
3036 return status;
3037}
3038// Modular DRM end
3039////////////////////////////////////////////////////////////////////////////////
3040
3041sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3042 sp<MetaData> meta = getFormatMeta(audio);
3043
3044 if (meta == NULL) {
3045 return NULL;
3046 }
3047
3048 sp<AMessage> msg = new AMessage;
3049
3050 if(convertMetaDataToMessage(meta, &msg) == OK) {
3051 return msg;
3052 }
3053 return NULL;
3054}
3055
3056void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3057 sp<AMessage> notify = dupNotify();
3058 notify->setInt32("what", kWhatFlagsChanged);
3059 notify->setInt32("flags", flags);
3060 notify->post();
3061}
3062
3063void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3064 sp<AMessage> notify = dupNotify();
3065 notify->setInt32("what", kWhatVideoSizeChanged);
3066 notify->setMessage("format", format);
3067 notify->post();
3068}
3069
3070void NuPlayer2::Source::notifyPrepared(status_t err) {
3071 ALOGV("Source::notifyPrepared %d", err);
3072 sp<AMessage> notify = dupNotify();
3073 notify->setInt32("what", kWhatPrepared);
3074 notify->setInt32("err", err);
3075 notify->post();
3076}
3077
3078void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3079{
3080 ALOGV("Source::notifyDrmInfo");
3081
3082 sp<AMessage> notify = dupNotify();
3083 notify->setInt32("what", kWhatDrmInfo);
3084 notify->setBuffer("drmInfo", drmInfoBuffer);
3085
3086 notify->post();
3087}
3088
Wei Jia53692fa2017-12-11 10:33:46 -08003089void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3090 TRESPASS();
3091}
3092
3093} // namespace android