blob: 462a9042b18d2920987d41754d950e2077daafa7 [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
426status_t NuPlayer2::getBufferingSettings(
427 BufferingSettings *buffering /* nonnull */) {
428 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
429 sp<AMessage> response;
430 status_t err = msg->postAndAwaitResponse(&response);
431 if (err == OK && response != NULL) {
432 CHECK(response->findInt32("err", &err));
433 if (err == OK) {
434 readFromAMessage(response, buffering);
435 }
436 }
437 return err;
438}
439
440status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
441 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
442 writeToAMessage(msg, buffering);
443 sp<AMessage> response;
444 status_t err = msg->postAndAwaitResponse(&response);
445 if (err == OK && response != NULL) {
446 CHECK(response->findInt32("err", &err));
447 }
448 return err;
449}
450
451void NuPlayer2::prepareAsync() {
452 ALOGV("prepareAsync");
453
454 (new AMessage(kWhatPrepare, this))->post();
455}
456
Wei Jia28288fb2017-12-15 13:45:29 -0800457void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800458 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
459
Wei Jia28288fb2017-12-15 13:45:29 -0800460 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800461 msg->setObject("surface", NULL);
462 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800463 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800464 }
465
466 msg->post();
467}
468
Wei Jia33abcc72018-01-30 09:47:38 -0800469void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800470 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
471 msg->setObject("sink", sink);
472 msg->post();
473}
474
475void NuPlayer2::start() {
476 (new AMessage(kWhatStart, this))->post();
477}
478
479status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
480 // do some cursory validation of the settings here. audio modes are
481 // only validated when set on the audiosink.
482 if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
483 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
484 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
485 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
486 return BAD_VALUE;
487 }
488 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
489 writeToAMessage(msg, rate);
490 sp<AMessage> response;
491 status_t err = msg->postAndAwaitResponse(&response);
492 if (err == OK && response != NULL) {
493 CHECK(response->findInt32("err", &err));
494 }
495 return err;
496}
497
498status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
499 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
500 sp<AMessage> response;
501 status_t err = msg->postAndAwaitResponse(&response);
502 if (err == OK && response != NULL) {
503 CHECK(response->findInt32("err", &err));
504 if (err == OK) {
505 readFromAMessage(response, rate);
506 }
507 }
508 return err;
509}
510
511status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
512 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
513 writeToAMessage(msg, sync, videoFpsHint);
514 sp<AMessage> response;
515 status_t err = msg->postAndAwaitResponse(&response);
516 if (err == OK && response != NULL) {
517 CHECK(response->findInt32("err", &err));
518 }
519 return err;
520}
521
522status_t NuPlayer2::getSyncSettings(
523 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
524 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
525 sp<AMessage> response;
526 status_t err = msg->postAndAwaitResponse(&response);
527 if (err == OK && response != NULL) {
528 CHECK(response->findInt32("err", &err));
529 if (err == OK) {
530 readFromAMessage(response, sync, videoFps);
531 }
532 }
533 return err;
534}
535
536void NuPlayer2::pause() {
537 (new AMessage(kWhatPause, this))->post();
538}
539
540void NuPlayer2::resetAsync() {
541 sp<Source> source;
542 {
543 Mutex::Autolock autoLock(mSourceLock);
544 source = mSource;
545 }
546
547 if (source != NULL) {
548 // During a reset, the data source might be unresponsive already, we need to
549 // disconnect explicitly so that reads exit promptly.
550 // We can't queue the disconnect request to the looper, as it might be
551 // queued behind a stuck read and never gets processed.
552 // Doing a disconnect outside the looper to allows the pending reads to exit
553 // (either successfully or with error).
554 source->disconnect();
555 }
556
557 (new AMessage(kWhatReset, this))->post();
558}
559
560status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
561 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
562 notify->setInt64("timerUs", mediaTimeUs);
563 mMediaClock->addTimer(notify, mediaTimeUs);
564 return OK;
565}
566
567void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
568 sp<AMessage> msg = new AMessage(kWhatSeek, this);
569 msg->setInt64("seekTimeUs", seekTimeUs);
570 msg->setInt32("mode", mode);
571 msg->setInt32("needNotify", needNotify);
572 msg->post();
573}
574
575
576void NuPlayer2::writeTrackInfo(
577 Parcel* reply, const sp<AMessage>& format) const {
578 if (format == NULL) {
579 ALOGE("NULL format");
580 return;
581 }
582 int32_t trackType;
583 if (!format->findInt32("type", &trackType)) {
584 ALOGE("no track type");
585 return;
586 }
587
588 AString mime;
589 if (!format->findString("mime", &mime)) {
590 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
591 // If we can't find the mimetype here it means that we wouldn't be needing
592 // the mimetype on the Java end. We still write a placeholder mime to keep the
593 // (de)serialization logic simple.
594 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
595 mime = "audio/";
596 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
597 mime = "video/";
598 } else {
599 ALOGE("unknown track type: %d", trackType);
600 return;
601 }
602 }
603
604 AString lang;
605 if (!format->findString("language", &lang)) {
606 ALOGE("no language");
607 return;
608 }
609
610 reply->writeInt32(2); // write something non-zero
611 reply->writeInt32(trackType);
612 reply->writeString16(String16(mime.c_str()));
613 reply->writeString16(String16(lang.c_str()));
614
615 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
616 int32_t isAuto, isDefault, isForced;
617 CHECK(format->findInt32("auto", &isAuto));
618 CHECK(format->findInt32("default", &isDefault));
619 CHECK(format->findInt32("forced", &isForced));
620
621 reply->writeInt32(isAuto);
622 reply->writeInt32(isDefault);
623 reply->writeInt32(isForced);
624 }
625}
626
627void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
628 switch (msg->what()) {
629 case kWhatSetDataSource:
630 {
631 ALOGV("kWhatSetDataSource");
632
633 CHECK(mSource == NULL);
634
635 status_t err = OK;
636 sp<RefBase> obj;
637 CHECK(msg->findObject("source", &obj));
638 if (obj != NULL) {
639 Mutex::Autolock autoLock(mSourceLock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800640 CHECK(msg->findInt64("srcId", &mSrcId));
Wei Jia53692fa2017-12-11 10:33:46 -0800641 mSource = static_cast<Source *>(obj.get());
642 } else {
643 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800644 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800645 }
646
647 CHECK(mDriver != NULL);
648 sp<NuPlayer2Driver> driver = mDriver.promote();
649 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800650 driver->notifySetDataSourceCompleted(mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800651 }
652 break;
653 }
654
Wei Jia72bf2a02018-02-06 15:29:23 -0800655 case kWhatPrepareNextDataSource:
656 {
657 ALOGV("kWhatPrepareNextDataSource");
658
659 status_t err = OK;
660 sp<RefBase> obj;
661 CHECK(msg->findObject("source", &obj));
662 if (obj != NULL) {
663 Mutex::Autolock autoLock(mSourceLock);
664 CHECK(msg->findInt64("srcId", &mNextSrcId));
665 mNextSource = static_cast<Source *>(obj.get());
666 mNextSource->prepareAsync();
667 } else {
668 err = UNKNOWN_ERROR;
669 }
670
671 break;
672 }
673
Wei Jia53692fa2017-12-11 10:33:46 -0800674 case kWhatGetBufferingSettings:
675 {
676 sp<AReplyToken> replyID;
677 CHECK(msg->senderAwaitsResponse(&replyID));
678
679 ALOGV("kWhatGetBufferingSettings");
680 BufferingSettings buffering;
681 status_t err = OK;
682 if (mSource != NULL) {
683 err = mSource->getBufferingSettings(&buffering);
684 } else {
685 err = INVALID_OPERATION;
686 }
687 sp<AMessage> response = new AMessage;
688 if (err == OK) {
689 writeToAMessage(response, buffering);
690 }
691 response->setInt32("err", err);
692 response->postReply(replyID);
693 break;
694 }
695
696 case kWhatSetBufferingSettings:
697 {
698 sp<AReplyToken> replyID;
699 CHECK(msg->senderAwaitsResponse(&replyID));
700
701 ALOGV("kWhatSetBufferingSettings");
702 BufferingSettings buffering;
703 readFromAMessage(msg, &buffering);
704 status_t err = OK;
705 if (mSource != NULL) {
706 err = mSource->setBufferingSettings(buffering);
707 } else {
708 err = INVALID_OPERATION;
709 }
710 sp<AMessage> response = new AMessage;
711 response->setInt32("err", err);
712 response->postReply(replyID);
713 break;
714 }
715
716 case kWhatPrepare:
717 {
718 ALOGV("onMessageReceived kWhatPrepare");
719
720 mSource->prepareAsync();
721 break;
722 }
723
724 case kWhatGetTrackInfo:
725 {
726 sp<AReplyToken> replyID;
727 CHECK(msg->senderAwaitsResponse(&replyID));
728
729 Parcel* reply;
730 CHECK(msg->findPointer("reply", (void**)&reply));
731
732 size_t inbandTracks = 0;
733 if (mSource != NULL) {
734 inbandTracks = mSource->getTrackCount();
735 }
736
737 size_t ccTracks = 0;
738 if (mCCDecoder != NULL) {
739 ccTracks = mCCDecoder->getTrackCount();
740 }
741
742 // total track count
743 reply->writeInt32(inbandTracks + ccTracks);
744
745 // write inband tracks
746 for (size_t i = 0; i < inbandTracks; ++i) {
747 writeTrackInfo(reply, mSource->getTrackInfo(i));
748 }
749
750 // write CC track
751 for (size_t i = 0; i < ccTracks; ++i) {
752 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
753 }
754
755 sp<AMessage> response = new AMessage;
756 response->postReply(replyID);
757 break;
758 }
759
760 case kWhatGetSelectedTrack:
761 {
762 status_t err = INVALID_OPERATION;
763 if (mSource != NULL) {
764 err = OK;
765
766 int32_t type32;
767 CHECK(msg->findInt32("type", (int32_t*)&type32));
768 media_track_type type = (media_track_type)type32;
769 ssize_t selectedTrack = mSource->getSelectedTrack(type);
770
771 Parcel* reply;
772 CHECK(msg->findPointer("reply", (void**)&reply));
773 reply->writeInt32(selectedTrack);
774 }
775
776 sp<AMessage> response = new AMessage;
777 response->setInt32("err", err);
778
779 sp<AReplyToken> replyID;
780 CHECK(msg->senderAwaitsResponse(&replyID));
781 response->postReply(replyID);
782 break;
783 }
784
785 case kWhatSelectTrack:
786 {
787 sp<AReplyToken> replyID;
788 CHECK(msg->senderAwaitsResponse(&replyID));
789
790 size_t trackIndex;
791 int32_t select;
792 int64_t timeUs;
793 CHECK(msg->findSize("trackIndex", &trackIndex));
794 CHECK(msg->findInt32("select", &select));
795 CHECK(msg->findInt64("timeUs", &timeUs));
796
797 status_t err = INVALID_OPERATION;
798
799 size_t inbandTracks = 0;
800 if (mSource != NULL) {
801 inbandTracks = mSource->getTrackCount();
802 }
803 size_t ccTracks = 0;
804 if (mCCDecoder != NULL) {
805 ccTracks = mCCDecoder->getTrackCount();
806 }
807
808 if (trackIndex < inbandTracks) {
809 err = mSource->selectTrack(trackIndex, select, timeUs);
810
811 if (!select && err == OK) {
812 int32_t type;
813 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
814 if (info != NULL
815 && info->findInt32("type", &type)
816 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
817 ++mTimedTextGeneration;
818 }
819 }
820 } else {
821 trackIndex -= inbandTracks;
822
823 if (trackIndex < ccTracks) {
824 err = mCCDecoder->selectTrack(trackIndex, select);
825 }
826 }
827
828 sp<AMessage> response = new AMessage;
829 response->setInt32("err", err);
830
831 response->postReply(replyID);
832 break;
833 }
834
835 case kWhatPollDuration:
836 {
837 int32_t generation;
838 CHECK(msg->findInt32("generation", &generation));
839
840 if (generation != mPollDurationGeneration) {
841 // stale
842 break;
843 }
844
845 int64_t durationUs;
846 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
847 sp<NuPlayer2Driver> driver = mDriver.promote();
848 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800849 driver->notifyDuration(mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800850 }
851 }
852
853 msg->post(1000000ll); // poll again in a second.
854 break;
855 }
856
857 case kWhatSetVideoSurface:
858 {
859
860 sp<RefBase> obj;
861 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800862 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800863
864 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800865 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jia53692fa2017-12-11 10:33:46 -0800866 (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
867 && mVideoDecoder != NULL) ? "have" : "no");
868
869 // Need to check mStarted before calling mSource->getFormat because NuPlayer2 might
870 // be in preparing state and it could take long time.
871 // When mStarted is true, mSource must have been set.
872 if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800873 // NOTE: mVideoDecoder's mNativeWindow is always non-null
874 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
875 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800876 break;
877 }
878
879 mDeferredActions.push_back(
880 new FlushDecoderAction(
881 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
882 FLUSH_CMD_SHUTDOWN /* video */));
883
Wei Jia28288fb2017-12-15 13:45:29 -0800884 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800885
886 if (obj != NULL) {
887 if (mStarted) {
888 // Issue a seek to refresh the video screen only if started otherwise
889 // the extractor may not yet be started and will assert.
890 // If the video decoder is not set (perhaps audio only in this case)
891 // do not perform a seek as it is not needed.
892 int64_t currentPositionUs = 0;
893 if (getCurrentPosition(&currentPositionUs) == OK) {
894 mDeferredActions.push_back(
895 new SeekAction(currentPositionUs,
896 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
897 }
898 }
899
900 // If there is a new surface texture, instantiate decoders
901 // again if possible.
902 mDeferredActions.push_back(
903 new SimpleAction(&NuPlayer2::performScanSources));
904
905 // After a flush without shutdown, decoder is paused.
906 // Don't resume it until source seek is done, otherwise it could
907 // start pulling stale data too soon.
908 mDeferredActions.push_back(
909 new ResumeDecoderAction(false /* needNotify */));
910 }
911
912 processDeferredActions();
913 break;
914 }
915
916 case kWhatSetAudioSink:
917 {
918 ALOGV("kWhatSetAudioSink");
919
920 sp<RefBase> obj;
921 CHECK(msg->findObject("sink", &obj));
922
Wei Jia33abcc72018-01-30 09:47:38 -0800923 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800924 break;
925 }
926
927 case kWhatStart:
928 {
929 ALOGV("kWhatStart");
930 if (mStarted) {
931 // do not resume yet if the source is still buffering
932 if (!mPausedForBuffering) {
933 onResume();
934 }
935 } else {
936 onStart();
937 }
938 mPausedByClient = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800939 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -0800940 break;
941 }
942
943 case kWhatConfigPlayback:
944 {
945 sp<AReplyToken> replyID;
946 CHECK(msg->senderAwaitsResponse(&replyID));
947 AudioPlaybackRate rate /* sanitized */;
948 readFromAMessage(msg, &rate);
949 status_t err = OK;
950 if (mRenderer != NULL) {
951 // AudioSink allows only 1.f and 0.f for offload mode.
952 // For other speed, switch to non-offload mode.
953 if (mOffloadAudio && ((rate.mSpeed != 0.f && rate.mSpeed != 1.f)
954 || rate.mPitch != 1.f)) {
955 int64_t currentPositionUs;
956 if (getCurrentPosition(&currentPositionUs) != OK) {
957 currentPositionUs = mPreviousSeekTimeUs;
958 }
959
960 // Set mPlaybackSettings so that the new audio decoder can
961 // be created correctly.
962 mPlaybackSettings = rate;
963 if (!mPaused) {
964 mRenderer->pause();
965 }
966 restartAudio(
967 currentPositionUs, true /* forceNonOffload */,
968 true /* needsToCreateAudioDecoder */);
969 if (!mPaused) {
970 mRenderer->resume();
971 }
972 }
973
974 err = mRenderer->setPlaybackSettings(rate);
975 }
976 if (err == OK) {
977 if (rate.mSpeed == 0.f) {
978 onPause();
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800979 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -0800980 mPausedByClient = true;
981 // save all other settings (using non-paused speed)
982 // so we can restore them on start
983 AudioPlaybackRate newRate = rate;
984 newRate.mSpeed = mPlaybackSettings.mSpeed;
985 mPlaybackSettings = newRate;
986 } else { /* rate.mSpeed != 0.f */
987 mPlaybackSettings = rate;
988 if (mStarted) {
989 // do not resume yet if the source is still buffering
990 if (!mPausedForBuffering) {
991 onResume();
992 }
993 } else if (mPrepared) {
994 onStart();
995 }
996
997 mPausedByClient = false;
998 }
999 }
1000
1001 if (mVideoDecoder != NULL) {
1002 sp<AMessage> params = new AMessage();
1003 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1004 mVideoDecoder->setParameters(params);
1005 }
1006
1007 sp<AMessage> response = new AMessage;
1008 response->setInt32("err", err);
1009 response->postReply(replyID);
1010 break;
1011 }
1012
1013 case kWhatGetPlaybackSettings:
1014 {
1015 sp<AReplyToken> replyID;
1016 CHECK(msg->senderAwaitsResponse(&replyID));
1017 AudioPlaybackRate rate = mPlaybackSettings;
1018 status_t err = OK;
1019 if (mRenderer != NULL) {
1020 err = mRenderer->getPlaybackSettings(&rate);
1021 }
1022 if (err == OK) {
1023 // get playback settings used by renderer, as it may be
1024 // slightly off due to audiosink not taking small changes.
1025 mPlaybackSettings = rate;
1026 if (mPaused) {
1027 rate.mSpeed = 0.f;
1028 }
1029 }
1030 sp<AMessage> response = new AMessage;
1031 if (err == OK) {
1032 writeToAMessage(response, rate);
1033 }
1034 response->setInt32("err", err);
1035 response->postReply(replyID);
1036 break;
1037 }
1038
1039 case kWhatConfigSync:
1040 {
1041 sp<AReplyToken> replyID;
1042 CHECK(msg->senderAwaitsResponse(&replyID));
1043
1044 ALOGV("kWhatConfigSync");
1045 AVSyncSettings sync;
1046 float videoFpsHint;
1047 readFromAMessage(msg, &sync, &videoFpsHint);
1048 status_t err = OK;
1049 if (mRenderer != NULL) {
1050 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1051 }
1052 if (err == OK) {
1053 mSyncSettings = sync;
1054 mVideoFpsHint = videoFpsHint;
1055 }
1056 sp<AMessage> response = new AMessage;
1057 response->setInt32("err", err);
1058 response->postReply(replyID);
1059 break;
1060 }
1061
1062 case kWhatGetSyncSettings:
1063 {
1064 sp<AReplyToken> replyID;
1065 CHECK(msg->senderAwaitsResponse(&replyID));
1066 AVSyncSettings sync = mSyncSettings;
1067 float videoFps = mVideoFpsHint;
1068 status_t err = OK;
1069 if (mRenderer != NULL) {
1070 err = mRenderer->getSyncSettings(&sync, &videoFps);
1071 if (err == OK) {
1072 mSyncSettings = sync;
1073 mVideoFpsHint = videoFps;
1074 }
1075 }
1076 sp<AMessage> response = new AMessage;
1077 if (err == OK) {
1078 writeToAMessage(response, sync, videoFps);
1079 }
1080 response->setInt32("err", err);
1081 response->postReply(replyID);
1082 break;
1083 }
1084
1085 case kWhatScanSources:
1086 {
1087 int32_t generation;
1088 CHECK(msg->findInt32("generation", &generation));
1089 if (generation != mScanSourcesGeneration) {
1090 // Drop obsolete msg.
1091 break;
1092 }
1093
1094 mScanSourcesPending = false;
1095
1096 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1097 mAudioDecoder != NULL, mVideoDecoder != NULL);
1098
1099 bool mHadAnySourcesBefore =
1100 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1101 bool rescan = false;
1102
1103 // initialize video before audio because successful initialization of
1104 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001105 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001106 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1107 rescan = true;
1108 }
1109 }
1110
1111 // Don't try to re-open audio sink if there's an existing decoder.
1112 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1113 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1114 rescan = true;
1115 }
1116 }
1117
1118 if (!mHadAnySourcesBefore
1119 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1120 // This is the first time we've found anything playable.
1121
1122 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
1123 schedulePollDuration();
1124 }
1125 }
1126
1127 status_t err;
1128 if ((err = mSource->feedMoreTSData()) != OK) {
1129 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1130 // We're not currently decoding anything (no audio or
1131 // video tracks found) and we just ran out of input data.
1132
1133 if (err == ERROR_END_OF_STREAM) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001134 notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001135 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001136 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001137 }
1138 }
1139 break;
1140 }
1141
1142 if (rescan) {
1143 msg->post(100000ll);
1144 mScanSourcesPending = true;
1145 }
1146 break;
1147 }
1148
1149 case kWhatVideoNotify:
1150 case kWhatAudioNotify:
1151 {
1152 bool audio = msg->what() == kWhatAudioNotify;
1153
1154 int32_t currentDecoderGeneration =
1155 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1156 int32_t requesterGeneration = currentDecoderGeneration - 1;
1157 CHECK(msg->findInt32("generation", &requesterGeneration));
1158
1159 if (requesterGeneration != currentDecoderGeneration) {
1160 ALOGV("got message from old %s decoder, generation(%d:%d)",
1161 audio ? "audio" : "video", requesterGeneration,
1162 currentDecoderGeneration);
1163 sp<AMessage> reply;
1164 if (!(msg->findMessage("reply", &reply))) {
1165 return;
1166 }
1167
1168 reply->setInt32("err", INFO_DISCONTINUITY);
1169 reply->post();
1170 return;
1171 }
1172
1173 int32_t what;
1174 CHECK(msg->findInt32("what", &what));
1175
1176 if (what == DecoderBase::kWhatInputDiscontinuity) {
1177 int32_t formatChange;
1178 CHECK(msg->findInt32("formatChange", &formatChange));
1179
1180 ALOGV("%s discontinuity: formatChange %d",
1181 audio ? "audio" : "video", formatChange);
1182
1183 if (formatChange) {
1184 mDeferredActions.push_back(
1185 new FlushDecoderAction(
1186 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1187 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1188 }
1189
1190 mDeferredActions.push_back(
1191 new SimpleAction(
1192 &NuPlayer2::performScanSources));
1193
1194 processDeferredActions();
1195 } else if (what == DecoderBase::kWhatEOS) {
1196 int32_t err;
1197 CHECK(msg->findInt32("err", &err));
1198
1199 if (err == ERROR_END_OF_STREAM) {
1200 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1201 } else {
1202 ALOGV("got %s decoder EOS w/ error %d",
1203 audio ? "audio" : "video",
1204 err);
1205 }
1206
1207 mRenderer->queueEOS(audio, err);
1208 } else if (what == DecoderBase::kWhatFlushCompleted) {
1209 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1210
1211 handleFlushComplete(audio, true /* isDecoder */);
1212 finishFlushIfPossible();
1213 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1214 sp<AMessage> format;
1215 CHECK(msg->findMessage("format", &format));
1216
1217 sp<AMessage> inputFormat =
1218 mSource->getFormat(false /* audio */);
1219
1220 setVideoScalingMode(mVideoScalingMode);
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001221 updateVideoSize(mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001222 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1223 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1224 if (audio) {
1225 mAudioDecoder.clear();
1226 mAudioDecoderError = false;
1227 ++mAudioDecoderGeneration;
1228
1229 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1230 mFlushingAudio = SHUT_DOWN;
1231 } else {
1232 mVideoDecoder.clear();
1233 mVideoDecoderError = false;
1234 ++mVideoDecoderGeneration;
1235
1236 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1237 mFlushingVideo = SHUT_DOWN;
1238 }
1239
1240 finishFlushIfPossible();
1241 } else if (what == DecoderBase::kWhatResumeCompleted) {
1242 finishResume();
1243 } else if (what == DecoderBase::kWhatError) {
1244 status_t err;
1245 if (!msg->findInt32("err", &err) || err == OK) {
1246 err = UNKNOWN_ERROR;
1247 }
1248
1249 // Decoder errors can be due to Source (e.g. from streaming),
1250 // or from decoding corrupted bitstreams, or from other decoder
1251 // MediaCodec operations (e.g. from an ongoing reset or seek).
1252 // They may also be due to openAudioSink failure at
1253 // decoder start or after a format change.
1254 //
1255 // We try to gracefully shut down the affected decoder if possible,
1256 // rather than trying to force the shutdown with something
1257 // similar to performReset(). This method can lead to a hang
1258 // if MediaCodec functions block after an error, but they should
1259 // typically return INVALID_OPERATION instead of blocking.
1260
1261 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1262 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1263 err, audio ? "audio" : "video", *flushing);
1264
1265 switch (*flushing) {
1266 case NONE:
1267 mDeferredActions.push_back(
1268 new FlushDecoderAction(
1269 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1270 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1271 processDeferredActions();
1272 break;
1273 case FLUSHING_DECODER:
1274 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1275 break; // Wait for flush to complete.
1276 case FLUSHING_DECODER_SHUTDOWN:
1277 break; // Wait for flush to complete.
1278 case SHUTTING_DOWN_DECODER:
1279 break; // Wait for shutdown to complete.
1280 case FLUSHED:
1281 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1282 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1283 break;
1284 case SHUT_DOWN:
1285 finishFlushIfPossible(); // Should not occur.
1286 break; // Finish anyways.
1287 }
1288 if (mSource != nullptr) {
1289 if (audio) {
1290 if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001291 || mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
1292 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001293 // When both audio and video have error, or this stream has only audio
1294 // which has error, notify client of error.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001295 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001296 } else {
1297 // Only audio track has error. Video track could be still good to play.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001298 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001299 }
1300 mAudioDecoderError = true;
1301 } else {
1302 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
1303 || mAudioSink == NULL || mAudioDecoder == NULL) {
1304 // When both audio and video have error, or this stream has only video
1305 // which has error, notify client of error.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001306 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001307 } else {
1308 // Only video track has error. Audio track could be still good to play.
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001309 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001310 }
1311 mVideoDecoderError = true;
1312 }
1313 }
1314 } else {
1315 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1316 what,
1317 what >> 24,
1318 (what >> 16) & 0xff,
1319 (what >> 8) & 0xff,
1320 what & 0xff);
1321 }
1322
1323 break;
1324 }
1325
1326 case kWhatRendererNotify:
1327 {
1328 int32_t requesterGeneration = mRendererGeneration - 1;
1329 CHECK(msg->findInt32("generation", &requesterGeneration));
1330 if (requesterGeneration != mRendererGeneration) {
1331 ALOGV("got message from old renderer, generation(%d:%d)",
1332 requesterGeneration, mRendererGeneration);
1333 return;
1334 }
1335
1336 int32_t what;
1337 CHECK(msg->findInt32("what", &what));
1338
1339 if (what == Renderer::kWhatEOS) {
1340 int32_t audio;
1341 CHECK(msg->findInt32("audio", &audio));
1342
1343 int32_t finalResult;
1344 CHECK(msg->findInt32("finalResult", &finalResult));
1345
1346 if (audio) {
1347 mAudioEOS = true;
1348 } else {
1349 mVideoEOS = true;
1350 }
1351
1352 if (finalResult == ERROR_END_OF_STREAM) {
1353 ALOGV("reached %s EOS", audio ? "audio" : "video");
1354 } else {
1355 ALOGE("%s track encountered an error (%d)",
1356 audio ? "audio" : "video", finalResult);
1357
1358 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001359 mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001360 }
1361
1362 if ((mAudioEOS || mAudioDecoder == NULL)
1363 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001364 notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001365 }
1366 } else if (what == Renderer::kWhatFlushComplete) {
1367 int32_t audio;
1368 CHECK(msg->findInt32("audio", &audio));
1369
1370 if (audio) {
1371 mAudioEOS = false;
1372 } else {
1373 mVideoEOS = false;
1374 }
1375
1376 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1377 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1378 || mFlushingAudio == SHUT_DOWN)) {
1379 // Flush has been handled by tear down.
1380 break;
1381 }
1382 handleFlushComplete(audio, false /* isDecoder */);
1383 finishFlushIfPossible();
1384 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001385 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001386 } else if (what == Renderer::kWhatMediaRenderingStart) {
1387 ALOGV("media rendering started");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001388 notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001389 } else if (what == Renderer::kWhatAudioTearDown) {
1390 int32_t reason;
1391 CHECK(msg->findInt32("reason", &reason));
1392 ALOGV("Tear down audio with reason %d.", reason);
1393 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1394 // TimeoutWhenPaused is only for offload mode.
1395 ALOGW("Receive a stale message for teardown.");
1396 break;
1397 }
1398 int64_t positionUs;
1399 if (!msg->findInt64("positionUs", &positionUs)) {
1400 positionUs = mPreviousSeekTimeUs;
1401 }
1402
1403 restartAudio(
1404 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1405 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1406 }
1407 break;
1408 }
1409
1410 case kWhatMoreDataQueued:
1411 {
1412 break;
1413 }
1414
1415 case kWhatReset:
1416 {
1417 ALOGV("kWhatReset");
1418
1419 mResetting = true;
1420 stopPlaybackTimer("kWhatReset");
1421 stopRebufferingTimer(true);
1422
1423 mDeferredActions.push_back(
1424 new FlushDecoderAction(
1425 FLUSH_CMD_SHUTDOWN /* audio */,
1426 FLUSH_CMD_SHUTDOWN /* video */));
1427
1428 mDeferredActions.push_back(
1429 new SimpleAction(&NuPlayer2::performReset));
1430
1431 processDeferredActions();
1432 break;
1433 }
1434
1435 case kWhatNotifyTime:
1436 {
1437 ALOGV("kWhatNotifyTime");
1438 int64_t timerUs;
1439 CHECK(msg->findInt64("timerUs", &timerUs));
1440
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001441 notifyListener(mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001442 break;
1443 }
1444
1445 case kWhatSeek:
1446 {
1447 int64_t seekTimeUs;
1448 int32_t mode;
1449 int32_t needNotify;
1450 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1451 CHECK(msg->findInt32("mode", &mode));
1452 CHECK(msg->findInt32("needNotify", &needNotify));
1453
1454 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1455 (long long)seekTimeUs, mode, needNotify);
1456
1457 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001458 if (!mSourceStarted) {
1459 mSourceStarted = true;
1460 mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001461 }
Wei Jia083e9092018-02-12 11:46:04 -08001462 if (seekTimeUs > 0) {
1463 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1464 }
1465
Wei Jia53692fa2017-12-11 10:33:46 -08001466 if (needNotify) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001467 notifyDriverSeekComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001468 }
1469 break;
1470 }
1471
Wei Jia083e9092018-02-12 11:46:04 -08001472 // seeks can take a while, so we essentially paused
1473 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
1474
Wei Jia53692fa2017-12-11 10:33:46 -08001475 mDeferredActions.push_back(
1476 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1477 FLUSH_CMD_FLUSH /* video */));
1478
1479 mDeferredActions.push_back(
1480 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1481
1482 // After a flush without shutdown, decoder is paused.
1483 // Don't resume it until source seek is done, otherwise it could
1484 // start pulling stale data too soon.
1485 mDeferredActions.push_back(
1486 new ResumeDecoderAction(needNotify));
1487
1488 processDeferredActions();
1489 break;
1490 }
1491
1492 case kWhatPause:
1493 {
1494 onPause();
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001495 notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001496 mPausedByClient = true;
1497 break;
1498 }
1499
1500 case kWhatSourceNotify:
1501 {
1502 onSourceNotify(msg);
1503 break;
1504 }
1505
1506 case kWhatClosedCaptionNotify:
1507 {
1508 onClosedCaptionNotify(msg);
1509 break;
1510 }
1511
1512 case kWhatPrepareDrm:
1513 {
1514 status_t status = onPrepareDrm(msg);
1515
1516 sp<AMessage> response = new AMessage;
1517 response->setInt32("status", status);
1518 sp<AReplyToken> replyID;
1519 CHECK(msg->senderAwaitsResponse(&replyID));
1520 response->postReply(replyID);
1521 break;
1522 }
1523
1524 case kWhatReleaseDrm:
1525 {
1526 status_t status = onReleaseDrm();
1527
1528 sp<AMessage> response = new AMessage;
1529 response->setInt32("status", status);
1530 sp<AReplyToken> replyID;
1531 CHECK(msg->senderAwaitsResponse(&replyID));
1532 response->postReply(replyID);
1533 break;
1534 }
1535
1536 default:
1537 TRESPASS();
1538 break;
1539 }
1540}
1541
1542void NuPlayer2::onResume() {
1543 if (!mPaused || mResetting) {
1544 ALOGD_IF(mResetting, "resetting, onResume discarded");
1545 return;
1546 }
1547 mPaused = false;
1548 if (mSource != NULL) {
1549 mSource->resume();
1550 } else {
1551 ALOGW("resume called when source is gone or not set");
1552 }
1553 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1554 // needed.
1555 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1556 instantiateDecoder(true /* audio */, &mAudioDecoder);
1557 }
1558 if (mRenderer != NULL) {
1559 mRenderer->resume();
1560 } else {
1561 ALOGW("resume called when renderer is gone or not set");
1562 }
1563
1564 startPlaybackTimer("onresume");
1565}
1566
Wei Jia083e9092018-02-12 11:46:04 -08001567void NuPlayer2::onStart() {
Wei Jia53692fa2017-12-11 10:33:46 -08001568 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1569
1570 if (!mSourceStarted) {
1571 mSourceStarted = true;
1572 mSource->start();
1573 }
Wei Jia53692fa2017-12-11 10:33:46 -08001574
1575 mOffloadAudio = false;
1576 mAudioEOS = false;
1577 mVideoEOS = false;
1578 mStarted = true;
1579 mPaused = false;
1580
1581 uint32_t flags = 0;
1582
1583 if (mSource->isRealTime()) {
1584 flags |= Renderer::FLAG_REAL_TIME;
1585 }
1586
1587 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1588 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1589 if (!hasAudio && !hasVideo) {
1590 ALOGE("no metadata for either audio or video source");
1591 mSource->stop();
1592 mSourceStarted = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001593 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001594 return;
1595 }
1596 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1597
1598 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1599
1600 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1601 if (mAudioSink != NULL) {
1602 streamType = mAudioSink->getAudioStreamType();
1603 }
1604
1605 mOffloadAudio =
1606 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
1607 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1608
1609 // Modular DRM: Disabling audio offload if the source is protected
1610 if (mOffloadAudio && mIsDrmProtected) {
1611 mOffloadAudio = false;
1612 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1613 }
1614
1615 if (mOffloadAudio) {
1616 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1617 }
1618
1619 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1620 ++mRendererGeneration;
1621 notify->setInt32("generation", mRendererGeneration);
1622 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1623 mRendererLooper = new ALooper;
1624 mRendererLooper->setName("NuPlayerRenderer");
1625 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1626 mRendererLooper->registerHandler(mRenderer);
1627
1628 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1629 if (err != OK) {
1630 mSource->stop();
1631 mSourceStarted = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001632 notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001633 return;
1634 }
1635
1636 float rate = getFrameRate();
1637 if (rate > 0) {
1638 mRenderer->setVideoFrameRate(rate);
1639 }
1640
1641 if (mVideoDecoder != NULL) {
1642 mVideoDecoder->setRenderer(mRenderer);
1643 }
1644 if (mAudioDecoder != NULL) {
1645 mAudioDecoder->setRenderer(mRenderer);
1646 }
1647
1648 startPlaybackTimer("onstart");
1649
1650 postScanSources();
1651}
1652
1653void NuPlayer2::startPlaybackTimer(const char *where) {
1654 Mutex::Autolock autoLock(mPlayingTimeLock);
1655 if (mLastStartedPlayingTimeNs == 0) {
1656 mLastStartedPlayingTimeNs = systemTime();
1657 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1658 }
1659}
1660
1661void NuPlayer2::stopPlaybackTimer(const char *where) {
1662 Mutex::Autolock autoLock(mPlayingTimeLock);
1663
1664 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1665
1666 if (mLastStartedPlayingTimeNs != 0) {
1667 sp<NuPlayer2Driver> driver = mDriver.promote();
1668 if (driver != NULL) {
1669 int64_t now = systemTime();
1670 int64_t played = now - mLastStartedPlayingTimeNs;
1671 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1672
1673 if (played > 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001674 driver->notifyMorePlayingTimeUs(mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001675 }
1676 }
1677 mLastStartedPlayingTimeNs = 0;
1678 }
1679}
1680
1681void NuPlayer2::startRebufferingTimer() {
1682 Mutex::Autolock autoLock(mPlayingTimeLock);
1683 if (mLastStartedRebufferingTimeNs == 0) {
1684 mLastStartedRebufferingTimeNs = systemTime();
1685 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1686 }
1687}
1688
1689void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1690 Mutex::Autolock autoLock(mPlayingTimeLock);
1691
1692 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)", mLastStartedRebufferingTimeNs, exitingPlayback);
1693
1694 if (mLastStartedRebufferingTimeNs != 0) {
1695 sp<NuPlayer2Driver> driver = mDriver.promote();
1696 if (driver != NULL) {
1697 int64_t now = systemTime();
1698 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1699 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1700
1701 if (rebuffered > 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001702 driver->notifyMoreRebufferingTimeUs(mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001703 if (exitingPlayback) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08001704 driver->notifyRebufferingWhenExit(mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001705 }
1706 }
1707 }
1708 mLastStartedRebufferingTimeNs = 0;
1709 }
1710}
1711
1712void NuPlayer2::onPause() {
1713
1714 stopPlaybackTimer("onPause");
1715
1716 if (mPaused) {
1717 return;
1718 }
1719 mPaused = true;
1720 if (mSource != NULL) {
1721 mSource->pause();
1722 } else {
1723 ALOGW("pause called when source is gone or not set");
1724 }
1725 if (mRenderer != NULL) {
1726 mRenderer->pause();
1727 } else {
1728 ALOGW("pause called when renderer is gone or not set");
1729 }
1730
1731}
1732
1733bool NuPlayer2::audioDecoderStillNeeded() {
1734 // Audio decoder is no longer needed if it's in shut/shutting down status.
1735 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1736}
1737
1738void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1739 // We wait for both the decoder flush and the renderer flush to complete
1740 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1741
1742 mFlushComplete[audio][isDecoder] = true;
1743 if (!mFlushComplete[audio][!isDecoder]) {
1744 return;
1745 }
1746
1747 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1748 switch (*state) {
1749 case FLUSHING_DECODER:
1750 {
1751 *state = FLUSHED;
1752 break;
1753 }
1754
1755 case FLUSHING_DECODER_SHUTDOWN:
1756 {
1757 *state = SHUTTING_DOWN_DECODER;
1758
1759 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1760 getDecoder(audio)->initiateShutdown();
1761 break;
1762 }
1763
1764 default:
1765 // decoder flush completes only occur in a flushing state.
1766 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1767 break;
1768 }
1769}
1770
1771void NuPlayer2::finishFlushIfPossible() {
1772 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1773 && mFlushingAudio != SHUT_DOWN) {
1774 return;
1775 }
1776
1777 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1778 && mFlushingVideo != SHUT_DOWN) {
1779 return;
1780 }
1781
1782 ALOGV("both audio and video are flushed now.");
1783
1784 mFlushingAudio = NONE;
1785 mFlushingVideo = NONE;
1786
1787 clearFlushComplete();
1788
1789 processDeferredActions();
1790}
1791
1792void NuPlayer2::postScanSources() {
1793 if (mScanSourcesPending) {
1794 return;
1795 }
1796
1797 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1798 msg->setInt32("generation", mScanSourcesGeneration);
1799 msg->post();
1800
1801 mScanSourcesPending = true;
1802}
1803
1804void NuPlayer2::tryOpenAudioSinkForOffload(
1805 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1806 // Note: This is called early in NuPlayer2 to determine whether offloading
1807 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1808
1809 status_t err = mRenderer->openAudioSink(
1810 format, true /* offloadOnly */, hasVideo,
1811 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
1812 if (err != OK) {
1813 // Any failure we turn off mOffloadAudio.
1814 mOffloadAudio = false;
1815 } else if (mOffloadAudio) {
1816 sendMetaDataToHal(mAudioSink, audioMeta);
1817 }
1818}
1819
1820void NuPlayer2::closeAudioSink() {
1821 mRenderer->closeAudioSink();
1822}
1823
1824void NuPlayer2::restartAudio(
1825 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1826 if (mAudioDecoder != NULL) {
1827 mAudioDecoder->pause();
1828 mAudioDecoder.clear();
1829 mAudioDecoderError = false;
1830 ++mAudioDecoderGeneration;
1831 }
1832 if (mFlushingAudio == FLUSHING_DECODER) {
1833 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1834 mFlushingAudio = FLUSHED;
1835 finishFlushIfPossible();
1836 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1837 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1838 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1839 mFlushingAudio = SHUT_DOWN;
1840 finishFlushIfPossible();
1841 needsToCreateAudioDecoder = false;
1842 }
1843 if (mRenderer == NULL) {
1844 return;
1845 }
1846 closeAudioSink();
1847 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1848 if (mVideoDecoder != NULL) {
1849 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1850 }
1851
1852 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1853
1854 if (forceNonOffload) {
1855 mRenderer->signalDisableOffloadAudio();
1856 mOffloadAudio = false;
1857 }
1858 if (needsToCreateAudioDecoder) {
1859 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1860 }
1861}
1862
1863void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
1864 if (mSource == NULL || mAudioSink == NULL) {
1865 return;
1866 }
1867
1868 if (mRenderer == NULL) {
1869 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1870 mOffloadAudio = false;
1871 return;
1872 }
1873
1874 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1875 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1876 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1877 const bool hasVideo = (videoFormat != NULL);
1878 bool canOffload = canOffloadStream(
1879 audioMeta, hasVideo, mSource->isStreaming(), streamType)
1880 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1881
1882 // Modular DRM: Disabling audio offload if the source is protected
1883 if (canOffload && mIsDrmProtected) {
1884 canOffload = false;
1885 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1886 }
1887
1888 if (canOffload) {
1889 if (!mOffloadAudio) {
1890 mRenderer->signalEnableOffloadAudio();
1891 }
1892 // open audio sink early under offload mode.
1893 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
1894 } else {
1895 if (mOffloadAudio) {
1896 mRenderer->signalDisableOffloadAudio();
1897 mOffloadAudio = false;
1898 }
1899 }
1900}
1901
1902status_t NuPlayer2::instantiateDecoder(
1903 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
1904 // The audio decoder could be cleared by tear down. If still in shut down
1905 // process, no need to create a new audio decoder.
1906 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
1907 return OK;
1908 }
1909
1910 sp<AMessage> format = mSource->getFormat(audio);
1911
1912 if (format == NULL) {
1913 return UNKNOWN_ERROR;
1914 } else {
1915 status_t err;
1916 if (format->findInt32("err", &err) && err) {
1917 return err;
1918 }
1919 }
1920
1921 format->setInt32("priority", 0 /* realtime */);
1922
1923 if (!audio) {
1924 AString mime;
1925 CHECK(format->findString("mime", &mime));
1926
1927 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
1928 if (mCCDecoder == NULL) {
1929 mCCDecoder = new CCDecoder(ccNotify);
1930 }
1931
1932 if (mSourceFlags & Source::FLAG_SECURE) {
1933 format->setInt32("secure", true);
1934 }
1935
1936 if (mSourceFlags & Source::FLAG_PROTECTED) {
1937 format->setInt32("protected", true);
1938 }
1939
1940 float rate = getFrameRate();
1941 if (rate > 0) {
1942 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
1943 }
1944 }
1945
1946 if (audio) {
1947 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1948 ++mAudioDecoderGeneration;
1949 notify->setInt32("generation", mAudioDecoderGeneration);
1950
1951 if (checkAudioModeChange) {
1952 determineAudioModeChange(format);
1953 }
1954 if (mOffloadAudio) {
1955 mSource->setOffloadAudio(true /* offload */);
1956
1957 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1958 format->setInt32("has-video", hasVideo);
1959 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
1960 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
1961 } else {
1962 mSource->setOffloadAudio(false /* offload */);
1963
1964 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
1965 ALOGV("instantiateDecoder audio Decoder");
1966 }
1967 mAudioDecoderError = false;
1968 } else {
1969 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
1970 ++mVideoDecoderGeneration;
1971 notify->setInt32("generation", mVideoDecoderGeneration);
1972
1973 *decoder = new Decoder(
Wei Jia28288fb2017-12-15 13:45:29 -08001974 notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08001975 mVideoDecoderError = false;
1976
1977 // enable FRC if high-quality AV sync is requested, even if not
1978 // directly queuing to display, as this will even improve textureview
1979 // playback.
1980 {
1981 if (property_get_bool("persist.sys.media.avsync", false)) {
1982 format->setInt32("auto-frc", 1);
1983 }
1984 }
1985 }
1986 (*decoder)->init();
1987
1988 // Modular DRM
1989 if (mIsDrmProtected) {
1990 format->setObject("crypto", mCrypto);
1991 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d", mCrypto.get(),
1992 (mSourceFlags & Source::FLAG_SECURE) != 0);
1993 }
1994
1995 (*decoder)->configure(format);
1996
1997 if (!audio) {
1998 sp<AMessage> params = new AMessage();
1999 float rate = getFrameRate();
2000 if (rate > 0) {
2001 params->setFloat("frame-rate-total", rate);
2002 }
2003
2004 sp<MetaData> fileMeta = getFileMeta();
2005 if (fileMeta != NULL) {
2006 int32_t videoTemporalLayerCount;
2007 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2008 && videoTemporalLayerCount > 0) {
2009 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2010 }
2011 }
2012
2013 if (params->countEntries() > 0) {
2014 (*decoder)->setParameters(params);
2015 }
2016 }
2017 return OK;
2018}
2019
2020void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002021 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002022 const sp<AMessage> &inputFormat,
2023 const sp<AMessage> &outputFormat) {
2024 if (inputFormat == NULL) {
2025 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002026 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002027 return;
2028 }
2029 int32_t err = OK;
2030 inputFormat->findInt32("err", &err);
2031 if (err == -EWOULDBLOCK) {
2032 ALOGW("Video meta is not available yet!");
2033 return;
2034 }
2035 if (err != OK) {
2036 ALOGW("Something is wrong with video meta!");
2037 return;
2038 }
2039
2040 int32_t displayWidth, displayHeight;
2041 if (outputFormat != NULL) {
2042 int32_t width, height;
2043 CHECK(outputFormat->findInt32("width", &width));
2044 CHECK(outputFormat->findInt32("height", &height));
2045
2046 int32_t cropLeft, cropTop, cropRight, cropBottom;
2047 CHECK(outputFormat->findRect(
2048 "crop",
2049 &cropLeft, &cropTop, &cropRight, &cropBottom));
2050
2051 displayWidth = cropRight - cropLeft + 1;
2052 displayHeight = cropBottom - cropTop + 1;
2053
2054 ALOGV("Video output format changed to %d x %d "
2055 "(crop: %d x %d @ (%d, %d))",
2056 width, height,
2057 displayWidth,
2058 displayHeight,
2059 cropLeft, cropTop);
2060 } else {
2061 CHECK(inputFormat->findInt32("width", &displayWidth));
2062 CHECK(inputFormat->findInt32("height", &displayHeight));
2063
2064 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2065 }
2066
2067 // Take into account sample aspect ratio if necessary:
2068 int32_t sarWidth, sarHeight;
2069 if (inputFormat->findInt32("sar-width", &sarWidth)
2070 && inputFormat->findInt32("sar-height", &sarHeight)
2071 && sarWidth > 0 && sarHeight > 0) {
2072 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2073
2074 displayWidth = (displayWidth * sarWidth) / sarHeight;
2075
2076 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2077 } else {
2078 int32_t width, height;
2079 if (inputFormat->findInt32("display-width", &width)
2080 && inputFormat->findInt32("display-height", &height)
2081 && width > 0 && height > 0
2082 && displayWidth > 0 && displayHeight > 0) {
2083 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2084 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2085 } else {
2086 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2087 }
2088 ALOGV("Video display width and height are overridden to %d x %d",
2089 displayWidth, displayHeight);
2090 }
2091 }
2092
2093 int32_t rotationDegrees;
2094 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2095 rotationDegrees = 0;
2096 }
2097
2098 if (rotationDegrees == 90 || rotationDegrees == 270) {
2099 int32_t tmp = displayWidth;
2100 displayWidth = displayHeight;
2101 displayHeight = tmp;
2102 }
2103
2104 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002105 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002106 MEDIA2_SET_VIDEO_SIZE,
2107 displayWidth,
2108 displayHeight);
2109}
2110
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002111void NuPlayer2::notifyListener(int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002112 if (mDriver == NULL) {
2113 return;
2114 }
2115
2116 sp<NuPlayer2Driver> driver = mDriver.promote();
2117
2118 if (driver == NULL) {
2119 return;
2120 }
2121
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002122 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002123}
2124
2125void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2126 ALOGV("[%s] flushDecoder needShutdown=%d",
2127 audio ? "audio" : "video", needShutdown);
2128
2129 const sp<DecoderBase> &decoder = getDecoder(audio);
2130 if (decoder == NULL) {
2131 ALOGI("flushDecoder %s without decoder present",
2132 audio ? "audio" : "video");
2133 return;
2134 }
2135
2136 // Make sure we don't continue to scan sources until we finish flushing.
2137 ++mScanSourcesGeneration;
2138 if (mScanSourcesPending) {
2139 if (!needShutdown) {
2140 mDeferredActions.push_back(
2141 new SimpleAction(&NuPlayer2::performScanSources));
2142 }
2143 mScanSourcesPending = false;
2144 }
2145
2146 decoder->signalFlush();
2147
2148 FlushStatus newStatus =
2149 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2150
2151 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2152 mFlushComplete[audio][true /* isDecoder */] = false;
2153 if (audio) {
2154 ALOGE_IF(mFlushingAudio != NONE,
2155 "audio flushDecoder() is called in state %d", mFlushingAudio);
2156 mFlushingAudio = newStatus;
2157 } else {
2158 ALOGE_IF(mFlushingVideo != NONE,
2159 "video flushDecoder() is called in state %d", mFlushingVideo);
2160 mFlushingVideo = newStatus;
2161 }
2162}
2163
2164void NuPlayer2::queueDecoderShutdown(
2165 bool audio, bool video, const sp<AMessage> &reply) {
2166 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2167
2168 mDeferredActions.push_back(
2169 new FlushDecoderAction(
2170 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2171 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2172
2173 mDeferredActions.push_back(
2174 new SimpleAction(&NuPlayer2::performScanSources));
2175
2176 mDeferredActions.push_back(new PostMessageAction(reply));
2177
2178 processDeferredActions();
2179}
2180
2181status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2182 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002183 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2184 status_t ret = native_window_set_scaling_mode(
2185 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002186 if (ret != OK) {
2187 ALOGE("Failed to set scaling mode (%d): %s",
2188 -ret, strerror(-ret));
2189 return ret;
2190 }
2191 }
2192 return OK;
2193}
2194
2195status_t NuPlayer2::getTrackInfo(Parcel* reply) const {
2196 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2197 msg->setPointer("reply", reply);
2198
2199 sp<AMessage> response;
2200 status_t err = msg->postAndAwaitResponse(&response);
2201 return err;
2202}
2203
2204status_t NuPlayer2::getSelectedTrack(int32_t type, Parcel* reply) const {
2205 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2206 msg->setPointer("reply", reply);
2207 msg->setInt32("type", type);
2208
2209 sp<AMessage> response;
2210 status_t err = msg->postAndAwaitResponse(&response);
2211 if (err == OK && response != NULL) {
2212 CHECK(response->findInt32("err", &err));
2213 }
2214 return err;
2215}
2216
2217status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2218 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2219 msg->setSize("trackIndex", trackIndex);
2220 msg->setInt32("select", select);
2221 msg->setInt64("timeUs", timeUs);
2222
2223 sp<AMessage> response;
2224 status_t err = msg->postAndAwaitResponse(&response);
2225
2226 if (err != OK) {
2227 return err;
2228 }
2229
2230 if (!response->findInt32("err", &err)) {
2231 err = OK;
2232 }
2233
2234 return err;
2235}
2236
2237status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2238 sp<Renderer> renderer = mRenderer;
2239 if (renderer == NULL) {
2240 return NO_INIT;
2241 }
2242
2243 return renderer->getCurrentPosition(mediaUs);
2244}
2245
2246void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2247 CHECK(mTrackStats != NULL);
2248
2249 mTrackStats->clear();
2250 if (mVideoDecoder != NULL) {
2251 mTrackStats->push_back(mVideoDecoder->getStats());
2252 }
2253 if (mAudioDecoder != NULL) {
2254 mTrackStats->push_back(mAudioDecoder->getStats());
2255 }
2256}
2257
2258sp<MetaData> NuPlayer2::getFileMeta() {
2259 return mSource->getFileFormatMeta();
2260}
2261
2262float NuPlayer2::getFrameRate() {
2263 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2264 if (meta == NULL) {
2265 return 0;
2266 }
2267 int32_t rate;
2268 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2269 // fall back to try file meta
2270 sp<MetaData> fileMeta = getFileMeta();
2271 if (fileMeta == NULL) {
2272 ALOGW("source has video meta but not file meta");
2273 return -1;
2274 }
2275 int32_t fileMetaRate;
2276 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2277 return -1;
2278 }
2279 return fileMetaRate;
2280 }
2281 return rate;
2282}
2283
2284void NuPlayer2::schedulePollDuration() {
2285 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2286 msg->setInt32("generation", mPollDurationGeneration);
2287 msg->post();
2288}
2289
2290void NuPlayer2::cancelPollDuration() {
2291 ++mPollDurationGeneration;
2292}
2293
2294void NuPlayer2::processDeferredActions() {
2295 while (!mDeferredActions.empty()) {
2296 // We won't execute any deferred actions until we're no longer in
2297 // an intermediate state, i.e. one more more decoders are currently
2298 // flushing or shutting down.
2299
2300 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2301 // We're currently flushing, postpone the reset until that's
2302 // completed.
2303
2304 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2305 mFlushingAudio, mFlushingVideo);
2306
2307 break;
2308 }
2309
2310 sp<Action> action = *mDeferredActions.begin();
2311 mDeferredActions.erase(mDeferredActions.begin());
2312
2313 action->execute(this);
2314 }
2315}
2316
2317void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2318 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2319 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2320
2321 if (mSource == NULL) {
2322 // This happens when reset occurs right before the loop mode
2323 // asynchronously seeks to the start of the stream.
2324 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2325 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2326 mAudioDecoder.get(), mVideoDecoder.get());
2327 return;
2328 }
2329 mPreviousSeekTimeUs = seekTimeUs;
2330 mSource->seekTo(seekTimeUs, mode);
2331 ++mTimedTextGeneration;
2332
2333 // everything's flushed, continue playback.
2334}
2335
2336void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2337 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2338
2339 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2340 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2341 return;
2342 }
2343
2344 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2345 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2346 }
2347
2348 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2349 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2350 }
2351}
2352
2353void NuPlayer2::performReset() {
2354 ALOGV("performReset");
2355
2356 CHECK(mAudioDecoder == NULL);
2357 CHECK(mVideoDecoder == NULL);
2358
2359 stopPlaybackTimer("performReset");
2360 stopRebufferingTimer(true);
2361
2362 cancelPollDuration();
2363
2364 ++mScanSourcesGeneration;
2365 mScanSourcesPending = false;
2366
2367 if (mRendererLooper != NULL) {
2368 if (mRenderer != NULL) {
2369 mRendererLooper->unregisterHandler(mRenderer->id());
2370 }
2371 mRendererLooper->stop();
2372 mRendererLooper.clear();
2373 }
2374 mRenderer.clear();
2375 ++mRendererGeneration;
2376
2377 if (mSource != NULL) {
2378 mSource->stop();
2379
2380 Mutex::Autolock autoLock(mSourceLock);
2381 mSource.clear();
2382 }
2383
2384 if (mDriver != NULL) {
2385 sp<NuPlayer2Driver> driver = mDriver.promote();
2386 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002387 driver->notifyResetComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002388 }
2389 }
2390
2391 mStarted = false;
2392 mPrepared = false;
2393 mResetting = false;
2394 mSourceStarted = false;
2395
2396 // Modular DRM
2397 if (mCrypto != NULL) {
2398 // decoders will be flushed before this so their mCrypto would go away on their own
2399 // TODO change to ALOGV
2400 ALOGD("performReset mCrypto: %p", mCrypto.get());
2401 mCrypto.clear();
2402 }
2403 mIsDrmProtected = false;
2404}
2405
2406void NuPlayer2::performScanSources() {
2407 ALOGV("performScanSources");
2408
2409 if (!mStarted) {
2410 return;
2411 }
2412
2413 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2414 postScanSources();
2415 }
2416}
2417
Wei Jia28288fb2017-12-15 13:45:29 -08002418void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002419 ALOGV("performSetSurface");
2420
Wei Jia28288fb2017-12-15 13:45:29 -08002421 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002422
2423 // XXX - ignore error from setVideoScalingMode for now
2424 setVideoScalingMode(mVideoScalingMode);
2425
2426 if (mDriver != NULL) {
2427 sp<NuPlayer2Driver> driver = mDriver.promote();
2428 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002429 driver->notifySetSurfaceComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002430 }
2431 }
2432}
2433
2434void NuPlayer2::performResumeDecoders(bool needNotify) {
2435 if (needNotify) {
2436 mResumePending = true;
2437 if (mVideoDecoder == NULL) {
2438 // if audio-only, we can notify seek complete now,
2439 // as the resume operation will be relatively fast.
2440 finishResume();
2441 }
2442 }
2443
2444 if (mVideoDecoder != NULL) {
2445 // When there is continuous seek, MediaPlayer will cache the seek
2446 // position, and send down new seek request when previous seek is
2447 // complete. Let's wait for at least one video output frame before
2448 // notifying seek complete, so that the video thumbnail gets updated
2449 // when seekbar is dragged.
2450 mVideoDecoder->signalResume(needNotify);
2451 }
2452
2453 if (mAudioDecoder != NULL) {
2454 mAudioDecoder->signalResume(false /* needNotify */);
2455 }
2456}
2457
2458void NuPlayer2::finishResume() {
2459 if (mResumePending) {
2460 mResumePending = false;
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002461 notifyDriverSeekComplete(mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002462 }
2463}
2464
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002465void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002466 if (mDriver != NULL) {
2467 sp<NuPlayer2Driver> driver = mDriver.promote();
2468 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002469 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002470 }
2471 }
2472}
2473
2474void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2475 int32_t what;
2476 CHECK(msg->findInt32("what", &what));
2477
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002478 int64_t srcId;
2479 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002480 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002481 case Source::kWhatPrepared:
2482 {
2483 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
2484 if (mSource == NULL) {
2485 // This is a stale notification from a source that was
2486 // asynchronously preparing when the client called reset().
2487 // We handled the reset, the source is gone.
2488 break;
2489 }
2490
2491 int32_t err;
2492 CHECK(msg->findInt32("err", &err));
2493
2494 if (err != OK) {
2495 // shut down potential secure codecs in case client never calls reset
2496 mDeferredActions.push_back(
2497 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2498 FLUSH_CMD_SHUTDOWN /* video */));
2499 processDeferredActions();
2500 } else {
2501 mPrepared = true;
2502 }
2503
2504 sp<NuPlayer2Driver> driver = mDriver.promote();
2505 if (driver != NULL) {
2506 // notify duration first, so that it's definitely set when
2507 // the app received the "prepare complete" callback.
2508 int64_t durationUs;
2509 if (mSource->getDuration(&durationUs) == OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002510 driver->notifyDuration(srcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -08002511 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002512 driver->notifyPrepareCompleted(srcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -08002513 }
2514
2515 break;
2516 }
2517
2518 // Modular DRM
2519 case Source::kWhatDrmInfo:
2520 {
2521 Parcel parcel;
2522 sp<ABuffer> drmInfo;
2523 CHECK(msg->findBuffer("drmInfo", &drmInfo));
2524 parcel.setData(drmInfo->data(), drmInfo->size());
2525
2526 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p parcel size: %zu",
2527 drmInfo.get(), parcel.dataSize());
2528
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002529 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
Wei Jia53692fa2017-12-11 10:33:46 -08002530
2531 break;
2532 }
2533
2534 case Source::kWhatFlagsChanged:
2535 {
2536 uint32_t flags;
2537 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2538
2539 sp<NuPlayer2Driver> driver = mDriver.promote();
2540 if (driver != NULL) {
2541
2542 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2543 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2544 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2545 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2546 (flags & Source::FLAG_CAN_PAUSE) != 0,
2547 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2548 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2549 (flags & Source::FLAG_CAN_SEEK) != 0,
2550 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2551 (flags & Source::FLAG_SECURE) != 0,
2552 (flags & Source::FLAG_PROTECTED) != 0);
2553
2554 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2555 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002556 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002557 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002558 driver->notifyFlagsChanged(srcId, flags);
Wei Jia53692fa2017-12-11 10:33:46 -08002559 }
2560
2561 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2562 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2563 cancelPollDuration();
2564 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2565 && (flags & Source::FLAG_DYNAMIC_DURATION)
2566 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2567 schedulePollDuration();
2568 }
2569
2570 mSourceFlags = flags;
2571 break;
2572 }
2573
2574 case Source::kWhatVideoSizeChanged:
2575 {
2576 sp<AMessage> format;
2577 CHECK(msg->findMessage("format", &format));
2578
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002579 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002580 break;
2581 }
2582
2583 case Source::kWhatBufferingUpdate:
2584 {
2585 int32_t percentage;
2586 CHECK(msg->findInt32("percentage", &percentage));
2587
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002588 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002589 break;
2590 }
2591
2592 case Source::kWhatPauseOnBufferingStart:
2593 {
2594 // ignore if not playing
2595 if (mStarted) {
2596 ALOGI("buffer low, pausing...");
2597
2598 startRebufferingTimer();
2599 mPausedForBuffering = true;
2600 onPause();
2601 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002602 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002603 break;
2604 }
2605
2606 case Source::kWhatResumeOnBufferingEnd:
2607 {
2608 // ignore if not playing
2609 if (mStarted) {
2610 ALOGI("buffer ready, resuming...");
2611
2612 stopRebufferingTimer(false);
2613 mPausedForBuffering = false;
2614
2615 // do not resume yet if client didn't unpause
2616 if (!mPausedByClient) {
2617 onResume();
2618 }
2619 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002620 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002621 break;
2622 }
2623
2624 case Source::kWhatCacheStats:
2625 {
2626 int32_t kbps;
2627 CHECK(msg->findInt32("bandwidth", &kbps));
2628
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002629 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002630 break;
2631 }
2632
2633 case Source::kWhatSubtitleData:
2634 {
2635 sp<ABuffer> buffer;
2636 CHECK(msg->findBuffer("buffer", &buffer));
2637
2638 sendSubtitleData(buffer, 0 /* baseIndex */);
2639 break;
2640 }
2641
2642 case Source::kWhatTimedMetaData:
2643 {
2644 sp<ABuffer> buffer;
2645 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002646 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002647 } else {
2648 sendTimedMetaData(buffer);
2649 }
2650 break;
2651 }
2652
2653 case Source::kWhatTimedTextData:
2654 {
2655 int32_t generation;
2656 if (msg->findInt32("generation", &generation)
2657 && generation != mTimedTextGeneration) {
2658 break;
2659 }
2660
2661 sp<ABuffer> buffer;
2662 CHECK(msg->findBuffer("buffer", &buffer));
2663
2664 sp<NuPlayer2Driver> driver = mDriver.promote();
2665 if (driver == NULL) {
2666 break;
2667 }
2668
2669 int posMs;
2670 int64_t timeUs, posUs;
2671 driver->getCurrentPosition(&posMs);
2672 posUs = (int64_t) posMs * 1000ll;
2673 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2674
2675 if (posUs < timeUs) {
2676 if (!msg->findInt32("generation", &generation)) {
2677 msg->setInt32("generation", mTimedTextGeneration);
2678 }
2679 msg->post(timeUs - posUs);
2680 } else {
2681 sendTimedTextData(buffer);
2682 }
2683 break;
2684 }
2685
2686 case Source::kWhatQueueDecoderShutdown:
2687 {
2688 int32_t audio, video;
2689 CHECK(msg->findInt32("audio", &audio));
2690 CHECK(msg->findInt32("video", &video));
2691
2692 sp<AMessage> reply;
2693 CHECK(msg->findMessage("reply", &reply));
2694
2695 queueDecoderShutdown(audio, video, reply);
2696 break;
2697 }
2698
2699 case Source::kWhatDrmNoLicense:
2700 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002701 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002702 break;
2703 }
2704
2705 default:
2706 TRESPASS();
2707 }
2708}
2709
2710void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2711 int32_t what;
2712 CHECK(msg->findInt32("what", &what));
2713
2714 switch (what) {
2715 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2716 {
2717 sp<ABuffer> buffer;
2718 CHECK(msg->findBuffer("buffer", &buffer));
2719
2720 size_t inbandTracks = 0;
2721 if (mSource != NULL) {
2722 inbandTracks = mSource->getTrackCount();
2723 }
2724
2725 sendSubtitleData(buffer, inbandTracks);
2726 break;
2727 }
2728
2729 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2730 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002731 notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002732
2733 break;
2734 }
2735
2736 default:
2737 TRESPASS();
2738 }
2739
2740
2741}
2742
2743void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2744 int32_t trackIndex;
2745 int64_t timeUs, durationUs;
2746 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
2747 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2748 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2749
2750 Parcel in;
2751 in.writeInt32(trackIndex + baseIndex);
2752 in.writeInt64(timeUs);
2753 in.writeInt64(durationUs);
2754 in.writeInt32(buffer->size());
2755 in.writeInt32(buffer->size());
2756 in.write(buffer->data(), buffer->size());
2757
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002758 notifyListener(mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &in);
Wei Jia53692fa2017-12-11 10:33:46 -08002759}
2760
2761void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2762 int64_t timeUs;
2763 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2764
2765 Parcel in;
2766 in.writeInt64(timeUs);
2767 in.writeInt32(buffer->size());
2768 in.writeInt32(buffer->size());
2769 in.write(buffer->data(), buffer->size());
2770
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002771 notifyListener(mSrcId, MEDIA2_META_DATA, 0, 0, &in);
Wei Jia53692fa2017-12-11 10:33:46 -08002772}
2773
2774void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2775 const void *data;
2776 size_t size = 0;
2777 int64_t timeUs;
2778 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
2779
2780 AString mime;
2781 CHECK(buffer->meta()->findString("mime", &mime));
2782 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2783
2784 data = buffer->data();
2785 size = buffer->size();
2786
2787 Parcel parcel;
2788 if (size > 0) {
2789 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2790 int32_t global = 0;
2791 if (buffer->meta()->findInt32("global", &global) && global) {
2792 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2793 } else {
2794 flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2795 }
2796 TextDescriptions::getParcelOfDescriptions(
2797 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2798 }
2799
2800 if ((parcel.dataSize() > 0)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002801 notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &parcel);
Wei Jia53692fa2017-12-11 10:33:46 -08002802 } else { // send an empty timed text
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002803 notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002804 }
2805}
2806
2807const char *NuPlayer2::getDataSourceType() {
2808 switch (mDataSourceType) {
2809 case DATA_SOURCE_TYPE_HTTP_LIVE:
2810 return "HTTPLive";
2811
2812 case DATA_SOURCE_TYPE_RTSP:
2813 return "RTSP";
2814
2815 case DATA_SOURCE_TYPE_GENERIC_URL:
2816 return "GenURL";
2817
2818 case DATA_SOURCE_TYPE_GENERIC_FD:
2819 return "GenFD";
2820
2821 case DATA_SOURCE_TYPE_MEDIA:
2822 return "Media";
2823
Wei Jia53692fa2017-12-11 10:33:46 -08002824 case DATA_SOURCE_TYPE_NONE:
2825 default:
2826 return "None";
2827 }
2828 }
2829
2830// Modular DRM begin
2831status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
2832{
2833 ALOGV("prepareDrm ");
2834
2835 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
2836 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
2837 // synchronous call so just passing the address but with local copies of "const" args
2838 uint8_t UUID[16];
2839 memcpy(UUID, uuid, sizeof(UUID));
2840 Vector<uint8_t> sessionId = drmSessionId;
2841 msg->setPointer("uuid", (void*)UUID);
2842 msg->setPointer("drmSessionId", (void*)&sessionId);
2843
2844 sp<AMessage> response;
2845 status_t status = msg->postAndAwaitResponse(&response);
2846
2847 if (status == OK && response != NULL) {
2848 CHECK(response->findInt32("status", &status));
2849 ALOGV("prepareDrm ret: %d ", status);
2850 } else {
2851 ALOGE("prepareDrm err: %d", status);
2852 }
2853
2854 return status;
2855}
2856
2857status_t NuPlayer2::releaseDrm()
2858{
2859 ALOGV("releaseDrm ");
2860
2861 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
2862
2863 sp<AMessage> response;
2864 status_t status = msg->postAndAwaitResponse(&response);
2865
2866 if (status == OK && response != NULL) {
2867 CHECK(response->findInt32("status", &status));
2868 ALOGV("releaseDrm ret: %d ", status);
2869 } else {
2870 ALOGE("releaseDrm err: %d", status);
2871 }
2872
2873 return status;
2874}
2875
2876status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
2877{
2878 // TODO change to ALOGV
2879 ALOGD("onPrepareDrm ");
2880
2881 status_t status = INVALID_OPERATION;
2882 if (mSource == NULL) {
2883 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
2884 return status;
2885 }
2886
2887 uint8_t *uuid;
2888 Vector<uint8_t> *drmSessionId;
2889 CHECK(msg->findPointer("uuid", (void**)&uuid));
2890 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
2891
2892 status = OK;
2893 sp<AMediaCryptoWrapper> crypto = NULL;
2894
2895 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
2896 if (crypto == NULL) {
2897 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
2898 return status;
2899 }
2900 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
2901
2902 if (mCrypto != NULL) {
2903 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
2904 mCrypto.clear();
2905 }
2906
2907 mCrypto = crypto;
2908 mIsDrmProtected = true;
2909 // TODO change to ALOGV
2910 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
2911
2912 return status;
2913}
2914
2915status_t NuPlayer2::onReleaseDrm()
2916{
2917 // TODO change to ALOGV
2918 ALOGD("onReleaseDrm ");
2919
2920 if (!mIsDrmProtected) {
2921 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
2922 }
2923
2924 mIsDrmProtected = false;
2925
2926 status_t status;
2927 if (mCrypto != NULL) {
2928 // notifying the source first before removing crypto from codec
2929 if (mSource != NULL) {
2930 mSource->releaseDrm();
2931 }
2932
2933 status=OK;
2934 // first making sure the codecs have released their crypto reference
2935 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
2936 if (videoDecoder != NULL) {
2937 status = videoDecoder->releaseCrypto();
2938 ALOGV("onReleaseDrm: video decoder ret: %d", status);
2939 }
2940
2941 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
2942 if (audioDecoder != NULL) {
2943 status_t status_audio = audioDecoder->releaseCrypto();
2944 if (status == OK) { // otherwise, returning the first error
2945 status = status_audio;
2946 }
2947 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
2948 }
2949
2950 // TODO change to ALOGV
2951 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
2952 mCrypto.clear();
2953 } else { // mCrypto == NULL
2954 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
2955 status = INVALID_OPERATION;
2956 }
2957
2958 return status;
2959}
2960// Modular DRM end
2961////////////////////////////////////////////////////////////////////////////////
2962
2963sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
2964 sp<MetaData> meta = getFormatMeta(audio);
2965
2966 if (meta == NULL) {
2967 return NULL;
2968 }
2969
2970 sp<AMessage> msg = new AMessage;
2971
2972 if(convertMetaDataToMessage(meta, &msg) == OK) {
2973 return msg;
2974 }
2975 return NULL;
2976}
2977
2978void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
2979 sp<AMessage> notify = dupNotify();
2980 notify->setInt32("what", kWhatFlagsChanged);
2981 notify->setInt32("flags", flags);
2982 notify->post();
2983}
2984
2985void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
2986 sp<AMessage> notify = dupNotify();
2987 notify->setInt32("what", kWhatVideoSizeChanged);
2988 notify->setMessage("format", format);
2989 notify->post();
2990}
2991
2992void NuPlayer2::Source::notifyPrepared(status_t err) {
2993 ALOGV("Source::notifyPrepared %d", err);
2994 sp<AMessage> notify = dupNotify();
2995 notify->setInt32("what", kWhatPrepared);
2996 notify->setInt32("err", err);
2997 notify->post();
2998}
2999
3000void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3001{
3002 ALOGV("Source::notifyDrmInfo");
3003
3004 sp<AMessage> notify = dupNotify();
3005 notify->setInt32("what", kWhatDrmInfo);
3006 notify->setBuffer("drmInfo", drmInfoBuffer);
3007
3008 notify->post();
3009}
3010
Wei Jia53692fa2017-12-11 10:33:46 -08003011void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3012 TRESPASS();
3013}
3014
3015} // namespace android