blob: 837bbc8659deffca3f4862e9fe5e7afa426105c4 [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"
Wei Jia53692fa2017-12-11 10:33:46 -080036#include "TextDescriptions.h"
37
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.
490 if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
491 || 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
587
588void NuPlayer2::writeTrackInfo(
589 Parcel* reply, const sp<AMessage>& format) const {
590 if (format == NULL) {
591 ALOGE("NULL format");
592 return;
593 }
594 int32_t trackType;
595 if (!format->findInt32("type", &trackType)) {
596 ALOGE("no track type");
597 return;
598 }
599
600 AString mime;
601 if (!format->findString("mime", &mime)) {
602 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
603 // If we can't find the mimetype here it means that we wouldn't be needing
604 // the mimetype on the Java end. We still write a placeholder mime to keep the
605 // (de)serialization logic simple.
606 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
607 mime = "audio/";
608 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
609 mime = "video/";
610 } else {
611 ALOGE("unknown track type: %d", trackType);
612 return;
613 }
614 }
615
616 AString lang;
617 if (!format->findString("language", &lang)) {
618 ALOGE("no language");
619 return;
620 }
621
622 reply->writeInt32(2); // write something non-zero
623 reply->writeInt32(trackType);
624 reply->writeString16(String16(mime.c_str()));
625 reply->writeString16(String16(lang.c_str()));
626
627 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
628 int32_t isAuto, isDefault, isForced;
629 CHECK(format->findInt32("auto", &isAuto));
630 CHECK(format->findInt32("default", &isDefault));
631 CHECK(format->findInt32("forced", &isForced));
632
633 reply->writeInt32(isAuto);
634 reply->writeInt32(isDefault);
635 reply->writeInt32(isForced);
636 }
637}
638
639void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
640 switch (msg->what()) {
641 case kWhatSetDataSource:
642 {
643 ALOGV("kWhatSetDataSource");
644
645 CHECK(mSource == NULL);
646
647 status_t err = OK;
648 sp<RefBase> obj;
649 CHECK(msg->findObject("source", &obj));
650 if (obj != NULL) {
651 Mutex::Autolock autoLock(mSourceLock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800652 CHECK(msg->findInt64("srcId", &mSrcId));
Wei Jia53692fa2017-12-11 10:33:46 -0800653 mSource = static_cast<Source *>(obj.get());
654 } else {
655 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800656 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800657 }
658
659 CHECK(mDriver != NULL);
660 sp<NuPlayer2Driver> driver = mDriver.promote();
661 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800662 driver->notifySetDataSourceCompleted(mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800663 }
664 break;
665 }
666
Wei Jia72bf2a02018-02-06 15:29:23 -0800667 case kWhatPrepareNextDataSource:
668 {
669 ALOGV("kWhatPrepareNextDataSource");
670
671 status_t err = OK;
672 sp<RefBase> obj;
673 CHECK(msg->findObject("source", &obj));
674 if (obj != NULL) {
675 Mutex::Autolock autoLock(mSourceLock);
676 CHECK(msg->findInt64("srcId", &mNextSrcId));
677 mNextSource = static_cast<Source *>(obj.get());
678 mNextSource->prepareAsync();
679 } else {
680 err = UNKNOWN_ERROR;
681 }
682
683 break;
684 }
685
Wei Jia57aeffd2018-02-15 16:01:14 -0800686 case kWhatPlayNextDataSource:
687 {
688 ALOGV("kWhatPlayNextDataSource");
689 int64_t srcId;
690 CHECK(msg->findInt64("srcId", &srcId));
691 if (srcId != mNextSrcId) {
692 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
693 return;
694 }
695
696 mResetting = true;
697 stopPlaybackTimer("kWhatPlayNextDataSource");
698 stopRebufferingTimer(true);
699
700 mDeferredActions.push_back(
701 new FlushDecoderAction(
702 FLUSH_CMD_SHUTDOWN /* audio */,
703 FLUSH_CMD_SHUTDOWN /* video */));
704
705 mDeferredActions.push_back(
706 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
707
708 processDeferredActions();
709 break;
710 }
711
Wei Jia53692fa2017-12-11 10:33:46 -0800712 case kWhatGetBufferingSettings:
713 {
714 sp<AReplyToken> replyID;
715 CHECK(msg->senderAwaitsResponse(&replyID));
716
717 ALOGV("kWhatGetBufferingSettings");
718 BufferingSettings buffering;
719 status_t err = OK;
720 if (mSource != NULL) {
721 err = mSource->getBufferingSettings(&buffering);
722 } else {
723 err = INVALID_OPERATION;
724 }
725 sp<AMessage> response = new AMessage;
726 if (err == OK) {
727 writeToAMessage(response, buffering);
728 }
729 response->setInt32("err", err);
730 response->postReply(replyID);
731 break;
732 }
733
734 case kWhatSetBufferingSettings:
735 {
736 sp<AReplyToken> replyID;
737 CHECK(msg->senderAwaitsResponse(&replyID));
738
739 ALOGV("kWhatSetBufferingSettings");
740 BufferingSettings buffering;
741 readFromAMessage(msg, &buffering);
742 status_t err = OK;
743 if (mSource != NULL) {
744 err = mSource->setBufferingSettings(buffering);
745 } else {
746 err = INVALID_OPERATION;
747 }
748 sp<AMessage> response = new AMessage;
749 response->setInt32("err", err);
750 response->postReply(replyID);
751 break;
752 }
753
754 case kWhatPrepare:
755 {
756 ALOGV("onMessageReceived kWhatPrepare");
757
758 mSource->prepareAsync();
759 break;
760 }
761
762 case kWhatGetTrackInfo:
763 {
764 sp<AReplyToken> replyID;
765 CHECK(msg->senderAwaitsResponse(&replyID));
766
767 Parcel* reply;
768 CHECK(msg->findPointer("reply", (void**)&reply));
769
770 size_t inbandTracks = 0;
771 if (mSource != NULL) {
772 inbandTracks = mSource->getTrackCount();
773 }
774
775 size_t ccTracks = 0;
776 if (mCCDecoder != NULL) {
777 ccTracks = mCCDecoder->getTrackCount();
778 }
779
780 // total track count
781 reply->writeInt32(inbandTracks + ccTracks);
782
783 // write inband tracks
784 for (size_t i = 0; i < inbandTracks; ++i) {
785 writeTrackInfo(reply, mSource->getTrackInfo(i));
786 }
787
788 // write CC track
789 for (size_t i = 0; i < ccTracks; ++i) {
790 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
791 }
792
793 sp<AMessage> response = new AMessage;
794 response->postReply(replyID);
795 break;
796 }
797
798 case kWhatGetSelectedTrack:
799 {
800 status_t err = INVALID_OPERATION;
801 if (mSource != NULL) {
802 err = OK;
803
804 int32_t type32;
805 CHECK(msg->findInt32("type", (int32_t*)&type32));
806 media_track_type type = (media_track_type)type32;
807 ssize_t selectedTrack = mSource->getSelectedTrack(type);
808
809 Parcel* reply;
810 CHECK(msg->findPointer("reply", (void**)&reply));
811 reply->writeInt32(selectedTrack);
812 }
813
814 sp<AMessage> response = new AMessage;
815 response->setInt32("err", err);
816
817 sp<AReplyToken> replyID;
818 CHECK(msg->senderAwaitsResponse(&replyID));
819 response->postReply(replyID);
820 break;
821 }
822
823 case kWhatSelectTrack:
824 {
825 sp<AReplyToken> replyID;
826 CHECK(msg->senderAwaitsResponse(&replyID));
827
828 size_t trackIndex;
829 int32_t select;
830 int64_t timeUs;
831 CHECK(msg->findSize("trackIndex", &trackIndex));
832 CHECK(msg->findInt32("select", &select));
833 CHECK(msg->findInt64("timeUs", &timeUs));
834
835 status_t err = INVALID_OPERATION;
836
837 size_t inbandTracks = 0;
838 if (mSource != NULL) {
839 inbandTracks = mSource->getTrackCount();
840 }
841 size_t ccTracks = 0;
842 if (mCCDecoder != NULL) {
843 ccTracks = mCCDecoder->getTrackCount();
844 }
845
846 if (trackIndex < inbandTracks) {
847 err = mSource->selectTrack(trackIndex, select, timeUs);
848
849 if (!select && err == OK) {
850 int32_t type;
851 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
852 if (info != NULL
853 && info->findInt32("type", &type)
854 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
855 ++mTimedTextGeneration;
856 }
857 }
858 } else {
859 trackIndex -= inbandTracks;
860
861 if (trackIndex < ccTracks) {
862 err = mCCDecoder->selectTrack(trackIndex, select);
863 }
864 }
865
866 sp<AMessage> response = new AMessage;
867 response->setInt32("err", err);
868
869 response->postReply(replyID);
870 break;
871 }
872
873 case kWhatPollDuration:
874 {
875 int32_t generation;
876 CHECK(msg->findInt32("generation", &generation));
877
878 if (generation != mPollDurationGeneration) {
879 // stale
880 break;
881 }
882
883 int64_t durationUs;
884 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
885 sp<NuPlayer2Driver> driver = mDriver.promote();
886 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800887 driver->notifyDuration(mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800888 }
889 }
890
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -0800891 msg->post(1000000LL); // poll again in a second.
Wei Jia53692fa2017-12-11 10:33:46 -0800892 break;
893 }
894
895 case kWhatSetVideoSurface:
896 {
897
898 sp<RefBase> obj;
899 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800900 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800901
902 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800903 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jia53692fa2017-12-11 10:33:46 -0800904 (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
905 && mVideoDecoder != NULL) ? "have" : "no");
906
907 // Need to check mStarted before calling mSource->getFormat because NuPlayer2 might
908 // be in preparing state and it could take long time.
909 // When mStarted is true, mSource must have been set.
910 if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800911 // NOTE: mVideoDecoder's mNativeWindow is always non-null
912 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
913 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800914 break;
915 }
916
917 mDeferredActions.push_back(
918 new FlushDecoderAction(
919 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
920 FLUSH_CMD_SHUTDOWN /* video */));
921
Wei Jia28288fb2017-12-15 13:45:29 -0800922 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800923
924 if (obj != NULL) {
925 if (mStarted) {
926 // Issue a seek to refresh the video screen only if started otherwise
927 // the extractor may not yet be started and will assert.
928 // If the video decoder is not set (perhaps audio only in this case)
929 // do not perform a seek as it is not needed.
930 int64_t currentPositionUs = 0;
931 if (getCurrentPosition(&currentPositionUs) == OK) {
932 mDeferredActions.push_back(
933 new SeekAction(currentPositionUs,
934 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
935 }
936 }
937
938 // If there is a new surface texture, instantiate decoders
939 // again if possible.
940 mDeferredActions.push_back(
941 new SimpleAction(&NuPlayer2::performScanSources));
942
943 // After a flush without shutdown, decoder is paused.
944 // Don't resume it until source seek is done, otherwise it could
945 // start pulling stale data too soon.
946 mDeferredActions.push_back(
947 new ResumeDecoderAction(false /* needNotify */));
948 }
949
950 processDeferredActions();
951 break;
952 }
953
954 case kWhatSetAudioSink:
955 {
956 ALOGV("kWhatSetAudioSink");
957
958 sp<RefBase> obj;
959 CHECK(msg->findObject("sink", &obj));
960
Wei Jia33abcc72018-01-30 09:47:38 -0800961 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800962 break;
963 }
964
965 case kWhatStart:
966 {
967 ALOGV("kWhatStart");
968 if (mStarted) {
969 // do not resume yet if the source is still buffering
970 if (!mPausedForBuffering) {
971 onResume();
972 }
973 } else {
974 onStart();
975 }
976 mPausedByClient = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800977 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -0800978 break;
979 }
980
981 case kWhatConfigPlayback:
982 {
983 sp<AReplyToken> replyID;
984 CHECK(msg->senderAwaitsResponse(&replyID));
985 AudioPlaybackRate rate /* sanitized */;
986 readFromAMessage(msg, &rate);
987 status_t err = OK;
988 if (mRenderer != NULL) {
989 // AudioSink allows only 1.f and 0.f for offload mode.
990 // For other speed, switch to non-offload mode.
991 if (mOffloadAudio && ((rate.mSpeed != 0.f && rate.mSpeed != 1.f)
992 || rate.mPitch != 1.f)) {
993 int64_t currentPositionUs;
994 if (getCurrentPosition(&currentPositionUs) != OK) {
995 currentPositionUs = mPreviousSeekTimeUs;
996 }
997
998 // Set mPlaybackSettings so that the new audio decoder can
999 // be created correctly.
1000 mPlaybackSettings = rate;
1001 if (!mPaused) {
1002 mRenderer->pause();
1003 }
1004 restartAudio(
1005 currentPositionUs, true /* forceNonOffload */,
1006 true /* needsToCreateAudioDecoder */);
1007 if (!mPaused) {
1008 mRenderer->resume();
1009 }
1010 }
1011
1012 err = mRenderer->setPlaybackSettings(rate);
1013 }
1014 if (err == OK) {
1015 if (rate.mSpeed == 0.f) {
1016 onPause();
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001017 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001018 mPausedByClient = true;
1019 // save all other settings (using non-paused speed)
1020 // so we can restore them on start
1021 AudioPlaybackRate newRate = rate;
1022 newRate.mSpeed = mPlaybackSettings.mSpeed;
1023 mPlaybackSettings = newRate;
1024 } else { /* rate.mSpeed != 0.f */
1025 mPlaybackSettings = rate;
1026 if (mStarted) {
1027 // do not resume yet if the source is still buffering
1028 if (!mPausedForBuffering) {
1029 onResume();
1030 }
1031 } else if (mPrepared) {
1032 onStart();
1033 }
1034
1035 mPausedByClient = false;
1036 }
1037 }
1038
1039 if (mVideoDecoder != NULL) {
1040 sp<AMessage> params = new AMessage();
1041 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1042 mVideoDecoder->setParameters(params);
1043 }
1044
1045 sp<AMessage> response = new AMessage;
1046 response->setInt32("err", err);
1047 response->postReply(replyID);
1048 break;
1049 }
1050
1051 case kWhatGetPlaybackSettings:
1052 {
1053 sp<AReplyToken> replyID;
1054 CHECK(msg->senderAwaitsResponse(&replyID));
1055 AudioPlaybackRate rate = mPlaybackSettings;
1056 status_t err = OK;
1057 if (mRenderer != NULL) {
1058 err = mRenderer->getPlaybackSettings(&rate);
1059 }
1060 if (err == OK) {
1061 // get playback settings used by renderer, as it may be
1062 // slightly off due to audiosink not taking small changes.
1063 mPlaybackSettings = rate;
1064 if (mPaused) {
1065 rate.mSpeed = 0.f;
1066 }
1067 }
1068 sp<AMessage> response = new AMessage;
1069 if (err == OK) {
1070 writeToAMessage(response, rate);
1071 }
1072 response->setInt32("err", err);
1073 response->postReply(replyID);
1074 break;
1075 }
1076
1077 case kWhatConfigSync:
1078 {
1079 sp<AReplyToken> replyID;
1080 CHECK(msg->senderAwaitsResponse(&replyID));
1081
1082 ALOGV("kWhatConfigSync");
1083 AVSyncSettings sync;
1084 float videoFpsHint;
1085 readFromAMessage(msg, &sync, &videoFpsHint);
1086 status_t err = OK;
1087 if (mRenderer != NULL) {
1088 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1089 }
1090 if (err == OK) {
1091 mSyncSettings = sync;
1092 mVideoFpsHint = videoFpsHint;
1093 }
1094 sp<AMessage> response = new AMessage;
1095 response->setInt32("err", err);
1096 response->postReply(replyID);
1097 break;
1098 }
1099
1100 case kWhatGetSyncSettings:
1101 {
1102 sp<AReplyToken> replyID;
1103 CHECK(msg->senderAwaitsResponse(&replyID));
1104 AVSyncSettings sync = mSyncSettings;
1105 float videoFps = mVideoFpsHint;
1106 status_t err = OK;
1107 if (mRenderer != NULL) {
1108 err = mRenderer->getSyncSettings(&sync, &videoFps);
1109 if (err == OK) {
1110 mSyncSettings = sync;
1111 mVideoFpsHint = videoFps;
1112 }
1113 }
1114 sp<AMessage> response = new AMessage;
1115 if (err == OK) {
1116 writeToAMessage(response, sync, videoFps);
1117 }
1118 response->setInt32("err", err);
1119 response->postReply(replyID);
1120 break;
1121 }
1122
1123 case kWhatScanSources:
1124 {
1125 int32_t generation;
1126 CHECK(msg->findInt32("generation", &generation));
1127 if (generation != mScanSourcesGeneration) {
1128 // Drop obsolete msg.
1129 break;
1130 }
1131
1132 mScanSourcesPending = false;
1133
1134 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1135 mAudioDecoder != NULL, mVideoDecoder != NULL);
1136
1137 bool mHadAnySourcesBefore =
1138 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1139 bool rescan = false;
1140
1141 // initialize video before audio because successful initialization of
1142 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001143 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001144 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1145 rescan = true;
1146 }
1147 }
1148
1149 // Don't try to re-open audio sink if there's an existing decoder.
1150 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1151 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1152 rescan = true;
1153 }
1154 }
1155
1156 if (!mHadAnySourcesBefore
1157 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1158 // This is the first time we've found anything playable.
1159
1160 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
1161 schedulePollDuration();
1162 }
1163 }
1164
1165 status_t err;
1166 if ((err = mSource->feedMoreTSData()) != OK) {
1167 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1168 // We're not currently decoding anything (no audio or
1169 // video tracks found) and we just ran out of input data.
1170
1171 if (err == ERROR_END_OF_STREAM) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001172 notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001173 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001174 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001175 }
1176 }
1177 break;
1178 }
1179
1180 if (rescan) {
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08001181 msg->post(100000LL);
Wei Jia53692fa2017-12-11 10:33:46 -08001182 mScanSourcesPending = true;
1183 }
1184 break;
1185 }
1186
1187 case kWhatVideoNotify:
1188 case kWhatAudioNotify:
1189 {
1190 bool audio = msg->what() == kWhatAudioNotify;
1191
1192 int32_t currentDecoderGeneration =
1193 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1194 int32_t requesterGeneration = currentDecoderGeneration - 1;
1195 CHECK(msg->findInt32("generation", &requesterGeneration));
1196
1197 if (requesterGeneration != currentDecoderGeneration) {
1198 ALOGV("got message from old %s decoder, generation(%d:%d)",
1199 audio ? "audio" : "video", requesterGeneration,
1200 currentDecoderGeneration);
1201 sp<AMessage> reply;
1202 if (!(msg->findMessage("reply", &reply))) {
1203 return;
1204 }
1205
1206 reply->setInt32("err", INFO_DISCONTINUITY);
1207 reply->post();
1208 return;
1209 }
1210
1211 int32_t what;
1212 CHECK(msg->findInt32("what", &what));
1213
1214 if (what == DecoderBase::kWhatInputDiscontinuity) {
1215 int32_t formatChange;
1216 CHECK(msg->findInt32("formatChange", &formatChange));
1217
1218 ALOGV("%s discontinuity: formatChange %d",
1219 audio ? "audio" : "video", formatChange);
1220
1221 if (formatChange) {
1222 mDeferredActions.push_back(
1223 new FlushDecoderAction(
1224 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1225 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1226 }
1227
1228 mDeferredActions.push_back(
1229 new SimpleAction(
1230 &NuPlayer2::performScanSources));
1231
1232 processDeferredActions();
1233 } else if (what == DecoderBase::kWhatEOS) {
1234 int32_t err;
1235 CHECK(msg->findInt32("err", &err));
1236
1237 if (err == ERROR_END_OF_STREAM) {
1238 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1239 } else {
1240 ALOGV("got %s decoder EOS w/ error %d",
1241 audio ? "audio" : "video",
1242 err);
1243 }
1244
1245 mRenderer->queueEOS(audio, err);
1246 } else if (what == DecoderBase::kWhatFlushCompleted) {
1247 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1248
1249 handleFlushComplete(audio, true /* isDecoder */);
1250 finishFlushIfPossible();
1251 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1252 sp<AMessage> format;
1253 CHECK(msg->findMessage("format", &format));
1254
1255 sp<AMessage> inputFormat =
1256 mSource->getFormat(false /* audio */);
1257
1258 setVideoScalingMode(mVideoScalingMode);
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001259 updateVideoSize(mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001260 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1261 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1262 if (audio) {
1263 mAudioDecoder.clear();
1264 mAudioDecoderError = false;
1265 ++mAudioDecoderGeneration;
1266
1267 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1268 mFlushingAudio = SHUT_DOWN;
1269 } else {
1270 mVideoDecoder.clear();
1271 mVideoDecoderError = false;
1272 ++mVideoDecoderGeneration;
1273
1274 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1275 mFlushingVideo = SHUT_DOWN;
1276 }
1277
1278 finishFlushIfPossible();
1279 } else if (what == DecoderBase::kWhatResumeCompleted) {
1280 finishResume();
1281 } else if (what == DecoderBase::kWhatError) {
1282 status_t err;
1283 if (!msg->findInt32("err", &err) || err == OK) {
1284 err = UNKNOWN_ERROR;
1285 }
1286
1287 // Decoder errors can be due to Source (e.g. from streaming),
1288 // or from decoding corrupted bitstreams, or from other decoder
1289 // MediaCodec operations (e.g. from an ongoing reset or seek).
1290 // They may also be due to openAudioSink failure at
1291 // decoder start or after a format change.
1292 //
1293 // We try to gracefully shut down the affected decoder if possible,
1294 // rather than trying to force the shutdown with something
1295 // similar to performReset(). This method can lead to a hang
1296 // if MediaCodec functions block after an error, but they should
1297 // typically return INVALID_OPERATION instead of blocking.
1298
1299 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1300 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1301 err, audio ? "audio" : "video", *flushing);
1302
1303 switch (*flushing) {
1304 case NONE:
1305 mDeferredActions.push_back(
1306 new FlushDecoderAction(
1307 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1308 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1309 processDeferredActions();
1310 break;
1311 case FLUSHING_DECODER:
1312 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1313 break; // Wait for flush to complete.
1314 case FLUSHING_DECODER_SHUTDOWN:
1315 break; // Wait for flush to complete.
1316 case SHUTTING_DOWN_DECODER:
1317 break; // Wait for shutdown to complete.
1318 case FLUSHED:
1319 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1320 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1321 break;
1322 case SHUT_DOWN:
1323 finishFlushIfPossible(); // Should not occur.
1324 break; // Finish anyways.
1325 }
1326 if (mSource != nullptr) {
1327 if (audio) {
1328 if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001329 || mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
1330 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001331 // When both audio and video have error, or this stream has only audio
1332 // which has error, notify client of error.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001333 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001334 } else {
1335 // Only audio track has error. Video track could be still good to play.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001336 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001337 }
1338 mAudioDecoderError = true;
1339 } else {
1340 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
1341 || mAudioSink == NULL || mAudioDecoder == NULL) {
1342 // When both audio and video have error, or this stream has only video
1343 // which has error, notify client of error.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001344 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001345 } else {
1346 // Only video track has error. Audio track could be still good to play.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001347 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001348 }
1349 mVideoDecoderError = true;
1350 }
1351 }
1352 } else {
1353 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1354 what,
1355 what >> 24,
1356 (what >> 16) & 0xff,
1357 (what >> 8) & 0xff,
1358 what & 0xff);
1359 }
1360
1361 break;
1362 }
1363
1364 case kWhatRendererNotify:
1365 {
1366 int32_t requesterGeneration = mRendererGeneration - 1;
1367 CHECK(msg->findInt32("generation", &requesterGeneration));
1368 if (requesterGeneration != mRendererGeneration) {
1369 ALOGV("got message from old renderer, generation(%d:%d)",
1370 requesterGeneration, mRendererGeneration);
1371 return;
1372 }
1373
1374 int32_t what;
1375 CHECK(msg->findInt32("what", &what));
1376
1377 if (what == Renderer::kWhatEOS) {
1378 int32_t audio;
1379 CHECK(msg->findInt32("audio", &audio));
1380
1381 int32_t finalResult;
1382 CHECK(msg->findInt32("finalResult", &finalResult));
1383
1384 if (audio) {
1385 mAudioEOS = true;
1386 } else {
1387 mVideoEOS = true;
1388 }
1389
1390 if (finalResult == ERROR_END_OF_STREAM) {
1391 ALOGV("reached %s EOS", audio ? "audio" : "video");
1392 } else {
1393 ALOGE("%s track encountered an error (%d)",
1394 audio ? "audio" : "video", finalResult);
1395
1396 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001397 mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001398 }
1399
1400 if ((mAudioEOS || mAudioDecoder == NULL)
1401 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001402 notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001403 }
1404 } else if (what == Renderer::kWhatFlushComplete) {
1405 int32_t audio;
1406 CHECK(msg->findInt32("audio", &audio));
1407
1408 if (audio) {
1409 mAudioEOS = false;
1410 } else {
1411 mVideoEOS = false;
1412 }
1413
1414 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1415 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1416 || mFlushingAudio == SHUT_DOWN)) {
1417 // Flush has been handled by tear down.
1418 break;
1419 }
1420 handleFlushComplete(audio, false /* isDecoder */);
1421 finishFlushIfPossible();
1422 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jia57aeffd2018-02-15 16:01:14 -08001423 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001424 } else if (what == Renderer::kWhatMediaRenderingStart) {
1425 ALOGV("media rendering started");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001426 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001427 } else if (what == Renderer::kWhatAudioTearDown) {
1428 int32_t reason;
1429 CHECK(msg->findInt32("reason", &reason));
1430 ALOGV("Tear down audio with reason %d.", reason);
1431 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1432 // TimeoutWhenPaused is only for offload mode.
1433 ALOGW("Receive a stale message for teardown.");
1434 break;
1435 }
1436 int64_t positionUs;
1437 if (!msg->findInt64("positionUs", &positionUs)) {
1438 positionUs = mPreviousSeekTimeUs;
1439 }
1440
1441 restartAudio(
1442 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1443 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1444 }
1445 break;
1446 }
1447
1448 case kWhatMoreDataQueued:
1449 {
1450 break;
1451 }
1452
1453 case kWhatReset:
1454 {
1455 ALOGV("kWhatReset");
1456
1457 mResetting = true;
1458 stopPlaybackTimer("kWhatReset");
1459 stopRebufferingTimer(true);
1460
1461 mDeferredActions.push_back(
1462 new FlushDecoderAction(
1463 FLUSH_CMD_SHUTDOWN /* audio */,
1464 FLUSH_CMD_SHUTDOWN /* video */));
1465
1466 mDeferredActions.push_back(
1467 new SimpleAction(&NuPlayer2::performReset));
1468
1469 processDeferredActions();
1470 break;
1471 }
1472
1473 case kWhatNotifyTime:
1474 {
1475 ALOGV("kWhatNotifyTime");
1476 int64_t timerUs;
1477 CHECK(msg->findInt64("timerUs", &timerUs));
1478
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001479 notifyListener(mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001480 break;
1481 }
1482
1483 case kWhatSeek:
1484 {
1485 int64_t seekTimeUs;
1486 int32_t mode;
1487 int32_t needNotify;
1488 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1489 CHECK(msg->findInt32("mode", &mode));
1490 CHECK(msg->findInt32("needNotify", &needNotify));
1491
1492 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1493 (long long)seekTimeUs, mode, needNotify);
1494
1495 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001496 if (!mSourceStarted) {
1497 mSourceStarted = true;
1498 mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001499 }
Wei Jia083e9092018-02-12 11:46:04 -08001500 if (seekTimeUs > 0) {
1501 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1502 }
1503
Wei Jia53692fa2017-12-11 10:33:46 -08001504 if (needNotify) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001505 notifyDriverSeekComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001506 }
1507 break;
1508 }
1509
Wei Jia083e9092018-02-12 11:46:04 -08001510 // seeks can take a while, so we essentially paused
1511 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
1512
Wei Jia53692fa2017-12-11 10:33:46 -08001513 mDeferredActions.push_back(
1514 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1515 FLUSH_CMD_FLUSH /* video */));
1516
1517 mDeferredActions.push_back(
1518 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1519
1520 // After a flush without shutdown, decoder is paused.
1521 // Don't resume it until source seek is done, otherwise it could
1522 // start pulling stale data too soon.
1523 mDeferredActions.push_back(
1524 new ResumeDecoderAction(needNotify));
1525
1526 processDeferredActions();
1527 break;
1528 }
1529
1530 case kWhatPause:
1531 {
1532 onPause();
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001533 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001534 mPausedByClient = true;
1535 break;
1536 }
1537
1538 case kWhatSourceNotify:
1539 {
1540 onSourceNotify(msg);
1541 break;
1542 }
1543
1544 case kWhatClosedCaptionNotify:
1545 {
1546 onClosedCaptionNotify(msg);
1547 break;
1548 }
1549
1550 case kWhatPrepareDrm:
1551 {
1552 status_t status = onPrepareDrm(msg);
1553
1554 sp<AMessage> response = new AMessage;
1555 response->setInt32("status", status);
1556 sp<AReplyToken> replyID;
1557 CHECK(msg->senderAwaitsResponse(&replyID));
1558 response->postReply(replyID);
1559 break;
1560 }
1561
1562 case kWhatReleaseDrm:
1563 {
1564 status_t status = onReleaseDrm();
1565
1566 sp<AMessage> response = new AMessage;
1567 response->setInt32("status", status);
1568 sp<AReplyToken> replyID;
1569 CHECK(msg->senderAwaitsResponse(&replyID));
1570 response->postReply(replyID);
1571 break;
1572 }
1573
1574 default:
1575 TRESPASS();
1576 break;
1577 }
1578}
1579
1580void NuPlayer2::onResume() {
1581 if (!mPaused || mResetting) {
1582 ALOGD_IF(mResetting, "resetting, onResume discarded");
1583 return;
1584 }
1585 mPaused = false;
1586 if (mSource != NULL) {
1587 mSource->resume();
1588 } else {
1589 ALOGW("resume called when source is gone or not set");
1590 }
1591 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1592 // needed.
1593 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1594 instantiateDecoder(true /* audio */, &mAudioDecoder);
1595 }
1596 if (mRenderer != NULL) {
1597 mRenderer->resume();
1598 } else {
1599 ALOGW("resume called when renderer is gone or not set");
1600 }
1601
1602 startPlaybackTimer("onresume");
1603}
1604
Wei Jia083e9092018-02-12 11:46:04 -08001605void NuPlayer2::onStart() {
Wei Jia53692fa2017-12-11 10:33:46 -08001606 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1607
1608 if (!mSourceStarted) {
1609 mSourceStarted = true;
1610 mSource->start();
1611 }
Wei Jia53692fa2017-12-11 10:33:46 -08001612
1613 mOffloadAudio = false;
1614 mAudioEOS = false;
1615 mVideoEOS = false;
1616 mStarted = true;
1617 mPaused = false;
1618
1619 uint32_t flags = 0;
1620
1621 if (mSource->isRealTime()) {
1622 flags |= Renderer::FLAG_REAL_TIME;
1623 }
1624
1625 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1626 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1627 if (!hasAudio && !hasVideo) {
1628 ALOGE("no metadata for either audio or video source");
1629 mSource->stop();
1630 mSourceStarted = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001631 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001632 return;
1633 }
1634 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1635
1636 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1637
1638 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1639 if (mAudioSink != NULL) {
1640 streamType = mAudioSink->getAudioStreamType();
1641 }
1642
1643 mOffloadAudio =
1644 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
1645 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1646
1647 // Modular DRM: Disabling audio offload if the source is protected
1648 if (mOffloadAudio && mIsDrmProtected) {
1649 mOffloadAudio = false;
1650 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1651 }
1652
1653 if (mOffloadAudio) {
1654 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1655 }
1656
1657 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1658 ++mRendererGeneration;
1659 notify->setInt32("generation", mRendererGeneration);
1660 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1661 mRendererLooper = new ALooper;
1662 mRendererLooper->setName("NuPlayerRenderer");
1663 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1664 mRendererLooper->registerHandler(mRenderer);
1665
1666 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1667 if (err != OK) {
1668 mSource->stop();
1669 mSourceStarted = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001670 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001671 return;
1672 }
1673
1674 float rate = getFrameRate();
1675 if (rate > 0) {
1676 mRenderer->setVideoFrameRate(rate);
1677 }
1678
1679 if (mVideoDecoder != NULL) {
1680 mVideoDecoder->setRenderer(mRenderer);
1681 }
1682 if (mAudioDecoder != NULL) {
1683 mAudioDecoder->setRenderer(mRenderer);
1684 }
1685
1686 startPlaybackTimer("onstart");
1687
1688 postScanSources();
1689}
1690
1691void NuPlayer2::startPlaybackTimer(const char *where) {
1692 Mutex::Autolock autoLock(mPlayingTimeLock);
1693 if (mLastStartedPlayingTimeNs == 0) {
1694 mLastStartedPlayingTimeNs = systemTime();
1695 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1696 }
1697}
1698
1699void NuPlayer2::stopPlaybackTimer(const char *where) {
1700 Mutex::Autolock autoLock(mPlayingTimeLock);
1701
1702 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1703
1704 if (mLastStartedPlayingTimeNs != 0) {
1705 sp<NuPlayer2Driver> driver = mDriver.promote();
1706 if (driver != NULL) {
1707 int64_t now = systemTime();
1708 int64_t played = now - mLastStartedPlayingTimeNs;
1709 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1710
1711 if (played > 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001712 driver->notifyMorePlayingTimeUs(mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001713 }
1714 }
1715 mLastStartedPlayingTimeNs = 0;
1716 }
1717}
1718
1719void NuPlayer2::startRebufferingTimer() {
1720 Mutex::Autolock autoLock(mPlayingTimeLock);
1721 if (mLastStartedRebufferingTimeNs == 0) {
1722 mLastStartedRebufferingTimeNs = systemTime();
1723 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1724 }
1725}
1726
1727void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1728 Mutex::Autolock autoLock(mPlayingTimeLock);
1729
1730 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)", mLastStartedRebufferingTimeNs, exitingPlayback);
1731
1732 if (mLastStartedRebufferingTimeNs != 0) {
1733 sp<NuPlayer2Driver> driver = mDriver.promote();
1734 if (driver != NULL) {
1735 int64_t now = systemTime();
1736 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1737 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1738
1739 if (rebuffered > 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001740 driver->notifyMoreRebufferingTimeUs(mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001741 if (exitingPlayback) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001742 driver->notifyRebufferingWhenExit(mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001743 }
1744 }
1745 }
1746 mLastStartedRebufferingTimeNs = 0;
1747 }
1748}
1749
1750void NuPlayer2::onPause() {
1751
1752 stopPlaybackTimer("onPause");
1753
1754 if (mPaused) {
1755 return;
1756 }
1757 mPaused = true;
1758 if (mSource != NULL) {
1759 mSource->pause();
1760 } else {
1761 ALOGW("pause called when source is gone or not set");
1762 }
1763 if (mRenderer != NULL) {
1764 mRenderer->pause();
1765 } else {
1766 ALOGW("pause called when renderer is gone or not set");
1767 }
1768
1769}
1770
1771bool NuPlayer2::audioDecoderStillNeeded() {
1772 // Audio decoder is no longer needed if it's in shut/shutting down status.
1773 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1774}
1775
1776void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1777 // We wait for both the decoder flush and the renderer flush to complete
1778 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1779
1780 mFlushComplete[audio][isDecoder] = true;
1781 if (!mFlushComplete[audio][!isDecoder]) {
1782 return;
1783 }
1784
1785 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1786 switch (*state) {
1787 case FLUSHING_DECODER:
1788 {
1789 *state = FLUSHED;
1790 break;
1791 }
1792
1793 case FLUSHING_DECODER_SHUTDOWN:
1794 {
1795 *state = SHUTTING_DOWN_DECODER;
1796
1797 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1798 getDecoder(audio)->initiateShutdown();
1799 break;
1800 }
1801
1802 default:
1803 // decoder flush completes only occur in a flushing state.
1804 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1805 break;
1806 }
1807}
1808
1809void NuPlayer2::finishFlushIfPossible() {
1810 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1811 && mFlushingAudio != SHUT_DOWN) {
1812 return;
1813 }
1814
1815 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1816 && mFlushingVideo != SHUT_DOWN) {
1817 return;
1818 }
1819
1820 ALOGV("both audio and video are flushed now.");
1821
1822 mFlushingAudio = NONE;
1823 mFlushingVideo = NONE;
1824
1825 clearFlushComplete();
1826
1827 processDeferredActions();
1828}
1829
1830void NuPlayer2::postScanSources() {
1831 if (mScanSourcesPending) {
1832 return;
1833 }
1834
1835 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1836 msg->setInt32("generation", mScanSourcesGeneration);
1837 msg->post();
1838
1839 mScanSourcesPending = true;
1840}
1841
1842void NuPlayer2::tryOpenAudioSinkForOffload(
1843 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1844 // Note: This is called early in NuPlayer2 to determine whether offloading
1845 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1846
1847 status_t err = mRenderer->openAudioSink(
1848 format, true /* offloadOnly */, hasVideo,
1849 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
1850 if (err != OK) {
1851 // Any failure we turn off mOffloadAudio.
1852 mOffloadAudio = false;
1853 } else if (mOffloadAudio) {
1854 sendMetaDataToHal(mAudioSink, audioMeta);
1855 }
1856}
1857
1858void NuPlayer2::closeAudioSink() {
1859 mRenderer->closeAudioSink();
1860}
1861
1862void NuPlayer2::restartAudio(
1863 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1864 if (mAudioDecoder != NULL) {
1865 mAudioDecoder->pause();
1866 mAudioDecoder.clear();
1867 mAudioDecoderError = false;
1868 ++mAudioDecoderGeneration;
1869 }
1870 if (mFlushingAudio == FLUSHING_DECODER) {
1871 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1872 mFlushingAudio = FLUSHED;
1873 finishFlushIfPossible();
1874 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1875 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1876 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1877 mFlushingAudio = SHUT_DOWN;
1878 finishFlushIfPossible();
1879 needsToCreateAudioDecoder = false;
1880 }
1881 if (mRenderer == NULL) {
1882 return;
1883 }
1884 closeAudioSink();
1885 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1886 if (mVideoDecoder != NULL) {
Dichen Zhang8bd4d392019-02-13 10:38:06 -08001887 mDeferredActions.push_back(
1888 new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
1889 FLUSH_CMD_FLUSH /* video */));
1890 mDeferredActions.push_back(
1891 new SeekAction(currentPositionUs,
1892 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
1893 // After a flush without shutdown, decoder is paused.
1894 // Don't resume it until source seek is done, otherwise it could
1895 // start pulling stale data too soon.
1896 mDeferredActions.push_back(new ResumeDecoderAction(false));
1897 processDeferredActions();
1898 } else {
1899 performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
Wei Jia53692fa2017-12-11 10:33:46 -08001900 }
1901
Wei Jia53692fa2017-12-11 10:33:46 -08001902 if (forceNonOffload) {
1903 mRenderer->signalDisableOffloadAudio();
1904 mOffloadAudio = false;
1905 }
1906 if (needsToCreateAudioDecoder) {
1907 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1908 }
1909}
1910
1911void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
1912 if (mSource == NULL || mAudioSink == NULL) {
1913 return;
1914 }
1915
1916 if (mRenderer == NULL) {
1917 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1918 mOffloadAudio = false;
1919 return;
1920 }
1921
1922 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1923 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1924 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1925 const bool hasVideo = (videoFormat != NULL);
1926 bool canOffload = canOffloadStream(
1927 audioMeta, hasVideo, mSource->isStreaming(), streamType)
1928 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1929
1930 // Modular DRM: Disabling audio offload if the source is protected
1931 if (canOffload && mIsDrmProtected) {
1932 canOffload = false;
1933 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1934 }
1935
1936 if (canOffload) {
1937 if (!mOffloadAudio) {
1938 mRenderer->signalEnableOffloadAudio();
1939 }
1940 // open audio sink early under offload mode.
1941 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
1942 } else {
1943 if (mOffloadAudio) {
1944 mRenderer->signalDisableOffloadAudio();
1945 mOffloadAudio = false;
1946 }
1947 }
1948}
1949
1950status_t NuPlayer2::instantiateDecoder(
1951 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
1952 // The audio decoder could be cleared by tear down. If still in shut down
1953 // process, no need to create a new audio decoder.
1954 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
1955 return OK;
1956 }
1957
1958 sp<AMessage> format = mSource->getFormat(audio);
1959
1960 if (format == NULL) {
1961 return UNKNOWN_ERROR;
1962 } else {
1963 status_t err;
1964 if (format->findInt32("err", &err) && err) {
1965 return err;
1966 }
1967 }
1968
1969 format->setInt32("priority", 0 /* realtime */);
1970
1971 if (!audio) {
1972 AString mime;
1973 CHECK(format->findString("mime", &mime));
1974
1975 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
1976 if (mCCDecoder == NULL) {
1977 mCCDecoder = new CCDecoder(ccNotify);
1978 }
1979
1980 if (mSourceFlags & Source::FLAG_SECURE) {
1981 format->setInt32("secure", true);
1982 }
1983
1984 if (mSourceFlags & Source::FLAG_PROTECTED) {
1985 format->setInt32("protected", true);
1986 }
1987
1988 float rate = getFrameRate();
1989 if (rate > 0) {
1990 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
1991 }
1992 }
1993
1994 if (audio) {
1995 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1996 ++mAudioDecoderGeneration;
1997 notify->setInt32("generation", mAudioDecoderGeneration);
1998
1999 if (checkAudioModeChange) {
2000 determineAudioModeChange(format);
2001 }
2002 if (mOffloadAudio) {
2003 mSource->setOffloadAudio(true /* offload */);
2004
2005 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
2006 format->setInt32("has-video", hasVideo);
2007 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
2008 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2009 } else {
2010 mSource->setOffloadAudio(false /* offload */);
2011
2012 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
2013 ALOGV("instantiateDecoder audio Decoder");
2014 }
2015 mAudioDecoderError = false;
2016 } else {
2017 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2018 ++mVideoDecoderGeneration;
2019 notify->setInt32("generation", mVideoDecoderGeneration);
2020
2021 *decoder = new Decoder(
Wei Jia28288fb2017-12-15 13:45:29 -08002022 notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002023 mVideoDecoderError = false;
2024
2025 // enable FRC if high-quality AV sync is requested, even if not
2026 // directly queuing to display, as this will even improve textureview
2027 // playback.
2028 {
2029 if (property_get_bool("persist.sys.media.avsync", false)) {
2030 format->setInt32("auto-frc", 1);
2031 }
2032 }
2033 }
2034 (*decoder)->init();
2035
2036 // Modular DRM
2037 if (mIsDrmProtected) {
2038 format->setObject("crypto", mCrypto);
2039 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d", mCrypto.get(),
2040 (mSourceFlags & Source::FLAG_SECURE) != 0);
2041 }
2042
2043 (*decoder)->configure(format);
2044
2045 if (!audio) {
2046 sp<AMessage> params = new AMessage();
2047 float rate = getFrameRate();
2048 if (rate > 0) {
2049 params->setFloat("frame-rate-total", rate);
2050 }
2051
2052 sp<MetaData> fileMeta = getFileMeta();
2053 if (fileMeta != NULL) {
2054 int32_t videoTemporalLayerCount;
2055 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2056 && videoTemporalLayerCount > 0) {
2057 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2058 }
2059 }
2060
2061 if (params->countEntries() > 0) {
2062 (*decoder)->setParameters(params);
2063 }
2064 }
2065 return OK;
2066}
2067
2068void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002069 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002070 const sp<AMessage> &inputFormat,
2071 const sp<AMessage> &outputFormat) {
2072 if (inputFormat == NULL) {
2073 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002074 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002075 return;
2076 }
2077 int32_t err = OK;
2078 inputFormat->findInt32("err", &err);
2079 if (err == -EWOULDBLOCK) {
2080 ALOGW("Video meta is not available yet!");
2081 return;
2082 }
2083 if (err != OK) {
2084 ALOGW("Something is wrong with video meta!");
2085 return;
2086 }
2087
2088 int32_t displayWidth, displayHeight;
2089 if (outputFormat != NULL) {
2090 int32_t width, height;
2091 CHECK(outputFormat->findInt32("width", &width));
2092 CHECK(outputFormat->findInt32("height", &height));
2093
2094 int32_t cropLeft, cropTop, cropRight, cropBottom;
2095 CHECK(outputFormat->findRect(
2096 "crop",
2097 &cropLeft, &cropTop, &cropRight, &cropBottom));
2098
2099 displayWidth = cropRight - cropLeft + 1;
2100 displayHeight = cropBottom - cropTop + 1;
2101
2102 ALOGV("Video output format changed to %d x %d "
2103 "(crop: %d x %d @ (%d, %d))",
2104 width, height,
2105 displayWidth,
2106 displayHeight,
2107 cropLeft, cropTop);
2108 } else {
2109 CHECK(inputFormat->findInt32("width", &displayWidth));
2110 CHECK(inputFormat->findInt32("height", &displayHeight));
2111
2112 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2113 }
2114
2115 // Take into account sample aspect ratio if necessary:
2116 int32_t sarWidth, sarHeight;
2117 if (inputFormat->findInt32("sar-width", &sarWidth)
2118 && inputFormat->findInt32("sar-height", &sarHeight)
2119 && sarWidth > 0 && sarHeight > 0) {
2120 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2121
2122 displayWidth = (displayWidth * sarWidth) / sarHeight;
2123
2124 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2125 } else {
2126 int32_t width, height;
2127 if (inputFormat->findInt32("display-width", &width)
2128 && inputFormat->findInt32("display-height", &height)
2129 && width > 0 && height > 0
2130 && displayWidth > 0 && displayHeight > 0) {
2131 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2132 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2133 } else {
2134 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2135 }
2136 ALOGV("Video display width and height are overridden to %d x %d",
2137 displayWidth, displayHeight);
2138 }
2139 }
2140
2141 int32_t rotationDegrees;
2142 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2143 rotationDegrees = 0;
2144 }
2145
2146 if (rotationDegrees == 90 || rotationDegrees == 270) {
2147 int32_t tmp = displayWidth;
2148 displayWidth = displayHeight;
2149 displayHeight = tmp;
2150 }
2151
2152 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002153 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002154 MEDIA2_SET_VIDEO_SIZE,
2155 displayWidth,
2156 displayHeight);
2157}
2158
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002159void NuPlayer2::notifyListener(int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002160 if (mDriver == NULL) {
2161 return;
2162 }
2163
2164 sp<NuPlayer2Driver> driver = mDriver.promote();
2165
2166 if (driver == NULL) {
2167 return;
2168 }
2169
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002170 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002171}
2172
2173void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2174 ALOGV("[%s] flushDecoder needShutdown=%d",
2175 audio ? "audio" : "video", needShutdown);
2176
2177 const sp<DecoderBase> &decoder = getDecoder(audio);
2178 if (decoder == NULL) {
2179 ALOGI("flushDecoder %s without decoder present",
2180 audio ? "audio" : "video");
2181 return;
2182 }
2183
2184 // Make sure we don't continue to scan sources until we finish flushing.
2185 ++mScanSourcesGeneration;
2186 if (mScanSourcesPending) {
2187 if (!needShutdown) {
2188 mDeferredActions.push_back(
2189 new SimpleAction(&NuPlayer2::performScanSources));
2190 }
2191 mScanSourcesPending = false;
2192 }
2193
2194 decoder->signalFlush();
2195
2196 FlushStatus newStatus =
2197 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2198
2199 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2200 mFlushComplete[audio][true /* isDecoder */] = false;
2201 if (audio) {
2202 ALOGE_IF(mFlushingAudio != NONE,
2203 "audio flushDecoder() is called in state %d", mFlushingAudio);
2204 mFlushingAudio = newStatus;
2205 } else {
2206 ALOGE_IF(mFlushingVideo != NONE,
2207 "video flushDecoder() is called in state %d", mFlushingVideo);
2208 mFlushingVideo = newStatus;
2209 }
2210}
2211
2212void NuPlayer2::queueDecoderShutdown(
2213 bool audio, bool video, const sp<AMessage> &reply) {
2214 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2215
2216 mDeferredActions.push_back(
2217 new FlushDecoderAction(
2218 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2219 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2220
2221 mDeferredActions.push_back(
2222 new SimpleAction(&NuPlayer2::performScanSources));
2223
2224 mDeferredActions.push_back(new PostMessageAction(reply));
2225
2226 processDeferredActions();
2227}
2228
2229status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2230 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002231 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2232 status_t ret = native_window_set_scaling_mode(
2233 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002234 if (ret != OK) {
2235 ALOGE("Failed to set scaling mode (%d): %s",
2236 -ret, strerror(-ret));
2237 return ret;
2238 }
2239 }
2240 return OK;
2241}
2242
2243status_t NuPlayer2::getTrackInfo(Parcel* reply) const {
2244 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2245 msg->setPointer("reply", reply);
2246
2247 sp<AMessage> response;
2248 status_t err = msg->postAndAwaitResponse(&response);
2249 return err;
2250}
2251
2252status_t NuPlayer2::getSelectedTrack(int32_t type, Parcel* reply) const {
2253 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2254 msg->setPointer("reply", reply);
2255 msg->setInt32("type", type);
2256
2257 sp<AMessage> response;
2258 status_t err = msg->postAndAwaitResponse(&response);
2259 if (err == OK && response != NULL) {
2260 CHECK(response->findInt32("err", &err));
2261 }
2262 return err;
2263}
2264
2265status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2266 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2267 msg->setSize("trackIndex", trackIndex);
2268 msg->setInt32("select", select);
2269 msg->setInt64("timeUs", timeUs);
2270
2271 sp<AMessage> response;
2272 status_t err = msg->postAndAwaitResponse(&response);
2273
2274 if (err != OK) {
2275 return err;
2276 }
2277
2278 if (!response->findInt32("err", &err)) {
2279 err = OK;
2280 }
2281
2282 return err;
2283}
2284
2285status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2286 sp<Renderer> renderer = mRenderer;
2287 if (renderer == NULL) {
2288 return NO_INIT;
2289 }
2290
2291 return renderer->getCurrentPosition(mediaUs);
2292}
2293
2294void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2295 CHECK(mTrackStats != NULL);
2296
2297 mTrackStats->clear();
2298 if (mVideoDecoder != NULL) {
2299 mTrackStats->push_back(mVideoDecoder->getStats());
2300 }
2301 if (mAudioDecoder != NULL) {
2302 mTrackStats->push_back(mAudioDecoder->getStats());
2303 }
2304}
2305
2306sp<MetaData> NuPlayer2::getFileMeta() {
2307 return mSource->getFileFormatMeta();
2308}
2309
2310float NuPlayer2::getFrameRate() {
2311 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2312 if (meta == NULL) {
2313 return 0;
2314 }
2315 int32_t rate;
2316 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2317 // fall back to try file meta
2318 sp<MetaData> fileMeta = getFileMeta();
2319 if (fileMeta == NULL) {
2320 ALOGW("source has video meta but not file meta");
2321 return -1;
2322 }
2323 int32_t fileMetaRate;
2324 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2325 return -1;
2326 }
2327 return fileMetaRate;
2328 }
2329 return rate;
2330}
2331
2332void NuPlayer2::schedulePollDuration() {
2333 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2334 msg->setInt32("generation", mPollDurationGeneration);
2335 msg->post();
2336}
2337
2338void NuPlayer2::cancelPollDuration() {
2339 ++mPollDurationGeneration;
2340}
2341
2342void NuPlayer2::processDeferredActions() {
2343 while (!mDeferredActions.empty()) {
2344 // We won't execute any deferred actions until we're no longer in
2345 // an intermediate state, i.e. one more more decoders are currently
2346 // flushing or shutting down.
2347
2348 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2349 // We're currently flushing, postpone the reset until that's
2350 // completed.
2351
2352 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2353 mFlushingAudio, mFlushingVideo);
2354
2355 break;
2356 }
2357
2358 sp<Action> action = *mDeferredActions.begin();
2359 mDeferredActions.erase(mDeferredActions.begin());
2360
2361 action->execute(this);
2362 }
2363}
2364
2365void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2366 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2367 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2368
2369 if (mSource == NULL) {
2370 // This happens when reset occurs right before the loop mode
2371 // asynchronously seeks to the start of the stream.
2372 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2373 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2374 mAudioDecoder.get(), mVideoDecoder.get());
2375 return;
2376 }
2377 mPreviousSeekTimeUs = seekTimeUs;
2378 mSource->seekTo(seekTimeUs, mode);
2379 ++mTimedTextGeneration;
2380
2381 // everything's flushed, continue playback.
2382}
2383
2384void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2385 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2386
2387 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2388 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2389 return;
2390 }
2391
2392 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2393 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2394 }
2395
2396 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2397 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2398 }
2399}
2400
2401void NuPlayer2::performReset() {
2402 ALOGV("performReset");
2403
2404 CHECK(mAudioDecoder == NULL);
2405 CHECK(mVideoDecoder == NULL);
2406
2407 stopPlaybackTimer("performReset");
2408 stopRebufferingTimer(true);
2409
2410 cancelPollDuration();
2411
2412 ++mScanSourcesGeneration;
2413 mScanSourcesPending = false;
2414
2415 if (mRendererLooper != NULL) {
2416 if (mRenderer != NULL) {
2417 mRendererLooper->unregisterHandler(mRenderer->id());
2418 }
2419 mRendererLooper->stop();
2420 mRendererLooper.clear();
2421 }
2422 mRenderer.clear();
2423 ++mRendererGeneration;
2424
2425 if (mSource != NULL) {
2426 mSource->stop();
2427
2428 Mutex::Autolock autoLock(mSourceLock);
2429 mSource.clear();
2430 }
2431
2432 if (mDriver != NULL) {
2433 sp<NuPlayer2Driver> driver = mDriver.promote();
2434 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002435 driver->notifyResetComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002436 }
2437 }
2438
2439 mStarted = false;
2440 mPrepared = false;
2441 mResetting = false;
2442 mSourceStarted = false;
2443
2444 // Modular DRM
2445 if (mCrypto != NULL) {
2446 // decoders will be flushed before this so their mCrypto would go away on their own
2447 // TODO change to ALOGV
2448 ALOGD("performReset mCrypto: %p", mCrypto.get());
2449 mCrypto.clear();
2450 }
2451 mIsDrmProtected = false;
2452}
2453
Wei Jia57aeffd2018-02-15 16:01:14 -08002454void NuPlayer2::performPlayNextDataSource() {
2455 ALOGV("performPlayNextDataSource");
2456
2457 CHECK(mAudioDecoder == NULL);
2458 CHECK(mVideoDecoder == NULL);
2459
2460 stopPlaybackTimer("performPlayNextDataSource");
2461 stopRebufferingTimer(true);
2462
2463 cancelPollDuration();
2464
2465 ++mScanSourcesGeneration;
2466 mScanSourcesPending = false;
2467
2468 ++mRendererGeneration;
2469
2470 if (mSource != NULL) {
2471 mSource->stop();
2472 }
2473
2474 long previousSrcId;
2475 {
2476 Mutex::Autolock autoLock(mSourceLock);
2477 mSource = mNextSource;
2478 mNextSource = NULL;
2479 previousSrcId = mSrcId;
2480 mSrcId = mNextSrcId;
2481 ++mNextSrcId; // to distinguish the two sources.
2482 }
2483
2484 if (mDriver != NULL) {
2485 sp<NuPlayer2Driver> driver = mDriver.promote();
2486 if (driver != NULL) {
2487 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAYBACK_COMPLETE, 0);
2488 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_STARTED_AS_NEXT, 0);
2489 }
2490 }
2491
2492 mStarted = false;
2493 mPrepared = true; // TODO: what if it's not prepared
2494 mResetting = false;
2495 mSourceStarted = false;
2496
2497 // Modular DRM
2498 if (mCrypto != NULL) {
2499 // decoders will be flushed before this so their mCrypto would go away on their own
2500 // TODO change to ALOGV
2501 ALOGD("performReset mCrypto: %p", mCrypto.get());
2502 mCrypto.clear();
2503 }
2504 mIsDrmProtected = false;
2505
2506 if (mRenderer != NULL) {
2507 mRenderer->resume();
2508 }
2509
2510 onStart();
2511 mPausedByClient = false;
2512 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
2513}
2514
Wei Jia53692fa2017-12-11 10:33:46 -08002515void NuPlayer2::performScanSources() {
2516 ALOGV("performScanSources");
2517
2518 if (!mStarted) {
2519 return;
2520 }
2521
2522 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2523 postScanSources();
2524 }
2525}
2526
Wei Jia28288fb2017-12-15 13:45:29 -08002527void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002528 ALOGV("performSetSurface");
2529
Wei Jia28288fb2017-12-15 13:45:29 -08002530 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002531
2532 // XXX - ignore error from setVideoScalingMode for now
2533 setVideoScalingMode(mVideoScalingMode);
2534
2535 if (mDriver != NULL) {
2536 sp<NuPlayer2Driver> driver = mDriver.promote();
2537 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002538 driver->notifySetSurfaceComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002539 }
2540 }
2541}
2542
2543void NuPlayer2::performResumeDecoders(bool needNotify) {
2544 if (needNotify) {
2545 mResumePending = true;
2546 if (mVideoDecoder == NULL) {
2547 // if audio-only, we can notify seek complete now,
2548 // as the resume operation will be relatively fast.
2549 finishResume();
2550 }
2551 }
2552
2553 if (mVideoDecoder != NULL) {
2554 // When there is continuous seek, MediaPlayer will cache the seek
2555 // position, and send down new seek request when previous seek is
2556 // complete. Let's wait for at least one video output frame before
2557 // notifying seek complete, so that the video thumbnail gets updated
2558 // when seekbar is dragged.
2559 mVideoDecoder->signalResume(needNotify);
2560 }
2561
2562 if (mAudioDecoder != NULL) {
2563 mAudioDecoder->signalResume(false /* needNotify */);
2564 }
2565}
2566
2567void NuPlayer2::finishResume() {
2568 if (mResumePending) {
2569 mResumePending = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002570 notifyDriverSeekComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002571 }
2572}
2573
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002574void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002575 if (mDriver != NULL) {
2576 sp<NuPlayer2Driver> driver = mDriver.promote();
2577 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002578 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002579 }
2580 }
2581}
2582
2583void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2584 int32_t what;
2585 CHECK(msg->findInt32("what", &what));
2586
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002587 int64_t srcId;
2588 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002589 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002590 case Source::kWhatPrepared:
2591 {
2592 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
2593 if (mSource == NULL) {
2594 // This is a stale notification from a source that was
2595 // asynchronously preparing when the client called reset().
2596 // We handled the reset, the source is gone.
2597 break;
2598 }
2599
2600 int32_t err;
2601 CHECK(msg->findInt32("err", &err));
2602
2603 if (err != OK) {
2604 // shut down potential secure codecs in case client never calls reset
2605 mDeferredActions.push_back(
2606 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2607 FLUSH_CMD_SHUTDOWN /* video */));
2608 processDeferredActions();
2609 } else {
2610 mPrepared = true;
2611 }
2612
2613 sp<NuPlayer2Driver> driver = mDriver.promote();
2614 if (driver != NULL) {
2615 // notify duration first, so that it's definitely set when
2616 // the app received the "prepare complete" callback.
2617 int64_t durationUs;
2618 if (mSource->getDuration(&durationUs) == OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002619 driver->notifyDuration(srcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -08002620 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002621 driver->notifyPrepareCompleted(srcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -08002622 }
2623
2624 break;
2625 }
2626
2627 // Modular DRM
2628 case Source::kWhatDrmInfo:
2629 {
2630 Parcel parcel;
2631 sp<ABuffer> drmInfo;
2632 CHECK(msg->findBuffer("drmInfo", &drmInfo));
2633 parcel.setData(drmInfo->data(), drmInfo->size());
2634
2635 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p parcel size: %zu",
2636 drmInfo.get(), parcel.dataSize());
2637
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002638 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
Wei Jia53692fa2017-12-11 10:33:46 -08002639
2640 break;
2641 }
2642
2643 case Source::kWhatFlagsChanged:
2644 {
2645 uint32_t flags;
2646 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2647
2648 sp<NuPlayer2Driver> driver = mDriver.promote();
2649 if (driver != NULL) {
2650
2651 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2652 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2653 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2654 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2655 (flags & Source::FLAG_CAN_PAUSE) != 0,
2656 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2657 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2658 (flags & Source::FLAG_CAN_SEEK) != 0,
2659 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2660 (flags & Source::FLAG_SECURE) != 0,
2661 (flags & Source::FLAG_PROTECTED) != 0);
2662
2663 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2664 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002665 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002666 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002667 driver->notifyFlagsChanged(srcId, flags);
Wei Jia53692fa2017-12-11 10:33:46 -08002668 }
2669
2670 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2671 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2672 cancelPollDuration();
2673 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2674 && (flags & Source::FLAG_DYNAMIC_DURATION)
2675 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2676 schedulePollDuration();
2677 }
2678
2679 mSourceFlags = flags;
2680 break;
2681 }
2682
2683 case Source::kWhatVideoSizeChanged:
2684 {
2685 sp<AMessage> format;
2686 CHECK(msg->findMessage("format", &format));
2687
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002688 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002689 break;
2690 }
2691
2692 case Source::kWhatBufferingUpdate:
2693 {
2694 int32_t percentage;
2695 CHECK(msg->findInt32("percentage", &percentage));
2696
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002697 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002698 break;
2699 }
2700
2701 case Source::kWhatPauseOnBufferingStart:
2702 {
2703 // ignore if not playing
2704 if (mStarted) {
2705 ALOGI("buffer low, pausing...");
2706
2707 startRebufferingTimer();
2708 mPausedForBuffering = true;
2709 onPause();
2710 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002711 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002712 break;
2713 }
2714
2715 case Source::kWhatResumeOnBufferingEnd:
2716 {
2717 // ignore if not playing
2718 if (mStarted) {
2719 ALOGI("buffer ready, resuming...");
2720
2721 stopRebufferingTimer(false);
2722 mPausedForBuffering = false;
2723
2724 // do not resume yet if client didn't unpause
2725 if (!mPausedByClient) {
2726 onResume();
2727 }
2728 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002729 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002730 break;
2731 }
2732
2733 case Source::kWhatCacheStats:
2734 {
2735 int32_t kbps;
2736 CHECK(msg->findInt32("bandwidth", &kbps));
2737
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002738 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002739 break;
2740 }
2741
2742 case Source::kWhatSubtitleData:
2743 {
2744 sp<ABuffer> buffer;
2745 CHECK(msg->findBuffer("buffer", &buffer));
2746
2747 sendSubtitleData(buffer, 0 /* baseIndex */);
2748 break;
2749 }
2750
2751 case Source::kWhatTimedMetaData:
2752 {
2753 sp<ABuffer> buffer;
2754 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002755 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002756 } else {
2757 sendTimedMetaData(buffer);
2758 }
2759 break;
2760 }
2761
2762 case Source::kWhatTimedTextData:
2763 {
2764 int32_t generation;
2765 if (msg->findInt32("generation", &generation)
2766 && generation != mTimedTextGeneration) {
2767 break;
2768 }
2769
2770 sp<ABuffer> buffer;
2771 CHECK(msg->findBuffer("buffer", &buffer));
2772
2773 sp<NuPlayer2Driver> driver = mDriver.promote();
2774 if (driver == NULL) {
2775 break;
2776 }
2777
Wei Jia800fe372018-02-20 15:00:45 -08002778 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002779 int64_t timeUs, posUs;
2780 driver->getCurrentPosition(&posMs);
Chih-Hung Hsiehd42529d2018-12-11 13:53:10 -08002781 posUs = posMs * 1000LL;
Wei Jia53692fa2017-12-11 10:33:46 -08002782 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2783
2784 if (posUs < timeUs) {
2785 if (!msg->findInt32("generation", &generation)) {
2786 msg->setInt32("generation", mTimedTextGeneration);
2787 }
2788 msg->post(timeUs - posUs);
2789 } else {
2790 sendTimedTextData(buffer);
2791 }
2792 break;
2793 }
2794
2795 case Source::kWhatQueueDecoderShutdown:
2796 {
2797 int32_t audio, video;
2798 CHECK(msg->findInt32("audio", &audio));
2799 CHECK(msg->findInt32("video", &video));
2800
2801 sp<AMessage> reply;
2802 CHECK(msg->findMessage("reply", &reply));
2803
2804 queueDecoderShutdown(audio, video, reply);
2805 break;
2806 }
2807
2808 case Source::kWhatDrmNoLicense:
2809 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002810 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002811 break;
2812 }
2813
2814 default:
2815 TRESPASS();
2816 }
2817}
2818
2819void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2820 int32_t what;
2821 CHECK(msg->findInt32("what", &what));
2822
2823 switch (what) {
2824 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2825 {
2826 sp<ABuffer> buffer;
2827 CHECK(msg->findBuffer("buffer", &buffer));
2828
2829 size_t inbandTracks = 0;
2830 if (mSource != NULL) {
2831 inbandTracks = mSource->getTrackCount();
2832 }
2833
2834 sendSubtitleData(buffer, inbandTracks);
2835 break;
2836 }
2837
2838 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2839 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002840 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002841
2842 break;
2843 }
2844
2845 default:
2846 TRESPASS();
2847 }
2848
2849
2850}
2851
2852void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2853 int32_t trackIndex;
2854 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002855 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002856 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2857 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2858
2859 Parcel in;
2860 in.writeInt32(trackIndex + baseIndex);
2861 in.writeInt64(timeUs);
2862 in.writeInt64(durationUs);
2863 in.writeInt32(buffer->size());
2864 in.writeInt32(buffer->size());
2865 in.write(buffer->data(), buffer->size());
2866
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002867 notifyListener(mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &in);
Wei Jia53692fa2017-12-11 10:33:46 -08002868}
2869
2870void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2871 int64_t timeUs;
2872 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2873
2874 Parcel in;
2875 in.writeInt64(timeUs);
2876 in.writeInt32(buffer->size());
2877 in.writeInt32(buffer->size());
2878 in.write(buffer->data(), buffer->size());
2879
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002880 notifyListener(mSrcId, MEDIA2_META_DATA, 0, 0, &in);
Wei Jia53692fa2017-12-11 10:33:46 -08002881}
2882
2883void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2884 const void *data;
2885 size_t size = 0;
2886 int64_t timeUs;
2887 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
2888
2889 AString mime;
2890 CHECK(buffer->meta()->findString("mime", &mime));
2891 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2892
2893 data = buffer->data();
2894 size = buffer->size();
2895
2896 Parcel parcel;
2897 if (size > 0) {
2898 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2899 int32_t global = 0;
2900 if (buffer->meta()->findInt32("global", &global) && global) {
2901 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2902 } else {
2903 flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2904 }
2905 TextDescriptions::getParcelOfDescriptions(
2906 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2907 }
2908
2909 if ((parcel.dataSize() > 0)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002910 notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &parcel);
Wei Jia53692fa2017-12-11 10:33:46 -08002911 } else { // send an empty timed text
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002912 notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002913 }
2914}
2915
2916const char *NuPlayer2::getDataSourceType() {
2917 switch (mDataSourceType) {
2918 case DATA_SOURCE_TYPE_HTTP_LIVE:
2919 return "HTTPLive";
2920
2921 case DATA_SOURCE_TYPE_RTSP:
2922 return "RTSP";
2923
2924 case DATA_SOURCE_TYPE_GENERIC_URL:
2925 return "GenURL";
2926
2927 case DATA_SOURCE_TYPE_GENERIC_FD:
2928 return "GenFD";
2929
2930 case DATA_SOURCE_TYPE_MEDIA:
2931 return "Media";
2932
Wei Jia53692fa2017-12-11 10:33:46 -08002933 case DATA_SOURCE_TYPE_NONE:
2934 default:
2935 return "None";
2936 }
2937 }
2938
2939// Modular DRM begin
2940status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
2941{
2942 ALOGV("prepareDrm ");
2943
2944 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
2945 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
2946 // synchronous call so just passing the address but with local copies of "const" args
2947 uint8_t UUID[16];
2948 memcpy(UUID, uuid, sizeof(UUID));
2949 Vector<uint8_t> sessionId = drmSessionId;
2950 msg->setPointer("uuid", (void*)UUID);
2951 msg->setPointer("drmSessionId", (void*)&sessionId);
2952
2953 sp<AMessage> response;
2954 status_t status = msg->postAndAwaitResponse(&response);
2955
2956 if (status == OK && response != NULL) {
2957 CHECK(response->findInt32("status", &status));
2958 ALOGV("prepareDrm ret: %d ", status);
2959 } else {
2960 ALOGE("prepareDrm err: %d", status);
2961 }
2962
2963 return status;
2964}
2965
2966status_t NuPlayer2::releaseDrm()
2967{
2968 ALOGV("releaseDrm ");
2969
2970 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
2971
2972 sp<AMessage> response;
2973 status_t status = msg->postAndAwaitResponse(&response);
2974
2975 if (status == OK && response != NULL) {
2976 CHECK(response->findInt32("status", &status));
2977 ALOGV("releaseDrm ret: %d ", status);
2978 } else {
2979 ALOGE("releaseDrm err: %d", status);
2980 }
2981
2982 return status;
2983}
2984
2985status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
2986{
2987 // TODO change to ALOGV
2988 ALOGD("onPrepareDrm ");
2989
2990 status_t status = INVALID_OPERATION;
2991 if (mSource == NULL) {
2992 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
2993 return status;
2994 }
2995
2996 uint8_t *uuid;
2997 Vector<uint8_t> *drmSessionId;
2998 CHECK(msg->findPointer("uuid", (void**)&uuid));
2999 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3000
3001 status = OK;
3002 sp<AMediaCryptoWrapper> crypto = NULL;
3003
3004 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
3005 if (crypto == NULL) {
3006 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
3007 return status;
3008 }
3009 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
3010
3011 if (mCrypto != NULL) {
3012 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3013 mCrypto.clear();
3014 }
3015
3016 mCrypto = crypto;
3017 mIsDrmProtected = true;
3018 // TODO change to ALOGV
3019 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3020
3021 return status;
3022}
3023
3024status_t NuPlayer2::onReleaseDrm()
3025{
3026 // TODO change to ALOGV
3027 ALOGD("onReleaseDrm ");
3028
3029 if (!mIsDrmProtected) {
3030 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3031 }
3032
3033 mIsDrmProtected = false;
3034
3035 status_t status;
3036 if (mCrypto != NULL) {
3037 // notifying the source first before removing crypto from codec
3038 if (mSource != NULL) {
3039 mSource->releaseDrm();
3040 }
3041
3042 status=OK;
3043 // first making sure the codecs have released their crypto reference
3044 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3045 if (videoDecoder != NULL) {
3046 status = videoDecoder->releaseCrypto();
3047 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3048 }
3049
3050 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3051 if (audioDecoder != NULL) {
3052 status_t status_audio = audioDecoder->releaseCrypto();
3053 if (status == OK) { // otherwise, returning the first error
3054 status = status_audio;
3055 }
3056 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3057 }
3058
3059 // TODO change to ALOGV
3060 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3061 mCrypto.clear();
3062 } else { // mCrypto == NULL
3063 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3064 status = INVALID_OPERATION;
3065 }
3066
3067 return status;
3068}
3069// Modular DRM end
3070////////////////////////////////////////////////////////////////////////////////
3071
3072sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3073 sp<MetaData> meta = getFormatMeta(audio);
3074
3075 if (meta == NULL) {
3076 return NULL;
3077 }
3078
3079 sp<AMessage> msg = new AMessage;
3080
3081 if(convertMetaDataToMessage(meta, &msg) == OK) {
3082 return msg;
3083 }
3084 return NULL;
3085}
3086
3087void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3088 sp<AMessage> notify = dupNotify();
3089 notify->setInt32("what", kWhatFlagsChanged);
3090 notify->setInt32("flags", flags);
3091 notify->post();
3092}
3093
3094void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3095 sp<AMessage> notify = dupNotify();
3096 notify->setInt32("what", kWhatVideoSizeChanged);
3097 notify->setMessage("format", format);
3098 notify->post();
3099}
3100
3101void NuPlayer2::Source::notifyPrepared(status_t err) {
3102 ALOGV("Source::notifyPrepared %d", err);
3103 sp<AMessage> notify = dupNotify();
3104 notify->setInt32("what", kWhatPrepared);
3105 notify->setInt32("err", err);
3106 notify->post();
3107}
3108
3109void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3110{
3111 ALOGV("Source::notifyDrmInfo");
3112
3113 sp<AMessage> notify = dupNotify();
3114 notify->setInt32("what", kWhatDrmInfo);
3115 notify->setBuffer("drmInfo", drmInfoBuffer);
3116
3117 notify->post();
3118}
3119
Wei Jia53692fa2017-12-11 10:33:46 -08003120void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3121 TRESPASS();
3122}
3123
3124} // namespace android