blob: 018324eebe2f3fd8fae66cfe9c419afd2237f355 [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "NuPlayer2"
19
20#include <inttypes.h>
21
22#include <utils/Log.h>
23
24#include "NuPlayer2.h"
25
Wei Jia2409c872018-02-02 10:34:33 -080026#include "HTTPLiveSource2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080027#include "NuPlayer2CCDecoder.h"
28#include "NuPlayer2Decoder.h"
29#include "NuPlayer2DecoderBase.h"
30#include "NuPlayer2DecoderPassThrough.h"
31#include "NuPlayer2Driver.h"
32#include "NuPlayer2Renderer.h"
33#include "NuPlayer2Source.h"
Wei Jia2409c872018-02-02 10:34:33 -080034#include "RTSPSource2.h"
35#include "GenericSource2.h"
Dongwon Kanga0e816a2018-09-10 19:46:49 -070036#include "TextDescriptions2.h"
Wei Jia53692fa2017-12-11 10:33:46 -080037
38#include "ATSParser.h"
39
40#include <cutils/properties.h>
41
42#include <media/AudioParameter.h>
43#include <media/AudioResamplerPublic.h>
44#include <media/AVSyncSettings.h>
Wei Jiac2636032018-02-01 09:15:25 -080045#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080046#include <media/MediaCodecBuffer.h>
Wei Jia28288fb2017-12-15 13:45:29 -080047#include <media/NdkWrapper.h>
Wei Jia53692fa2017-12-11 10:33:46 -080048
49#include <media/stagefright/foundation/hexdump.h>
50#include <media/stagefright/foundation/ABuffer.h>
51#include <media/stagefright/foundation/ADebug.h>
52#include <media/stagefright/foundation/AMessage.h>
53#include <media/stagefright/foundation/avc_utils.h>
54#include <media/stagefright/MediaBuffer.h>
55#include <media/stagefright/MediaClock.h>
56#include <media/stagefright/MediaDefs.h>
57#include <media/stagefright/MediaErrors.h>
58#include <media/stagefright/MetaData.h>
59
Wei Jia53692fa2017-12-11 10:33:46 -080060#include "ESDS.h"
61#include <media/stagefright/Utils.h>
62
Wei Jia28288fb2017-12-15 13:45:29 -080063#include <system/window.h>
64
Wei Jia53692fa2017-12-11 10:33:46 -080065namespace android {
66
Wei Jia33abcc72018-01-30 09:47:38 -080067static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
Wei Jia53692fa2017-12-11 10:33:46 -080068 const sp<MetaData>& meta) {
69 int32_t sampleRate = 0;
70 int32_t bitRate = 0;
71 int32_t channelMask = 0;
72 int32_t delaySamples = 0;
73 int32_t paddingSamples = 0;
74
75 AudioParameter param = AudioParameter();
76
77 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
78 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
79 }
80 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
81 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
82 }
83 if (meta->findInt32(kKeyBitRate, &bitRate)) {
84 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
85 }
86 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
87 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
88 }
89 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
90 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
91 }
92
93 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
94 "delaySample %d, paddingSample %d", bitRate, sampleRate,
95 channelMask, delaySamples, paddingSamples);
96
97 sink->setParameters(param.toString());
98 return OK;
99}
100
101
102struct NuPlayer2::Action : public RefBase {
103 Action() {}
104
105 virtual void execute(NuPlayer2 *player) = 0;
106
107private:
108 DISALLOW_EVIL_CONSTRUCTORS(Action);
109};
110
111struct NuPlayer2::SeekAction : public Action {
112 explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
113 : mSeekTimeUs(seekTimeUs),
114 mMode(mode) {
115 }
116
117 virtual void execute(NuPlayer2 *player) {
118 player->performSeek(mSeekTimeUs, mMode);
119 }
120
121private:
122 int64_t mSeekTimeUs;
123 MediaPlayer2SeekMode mMode;
124
125 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
126};
127
128struct NuPlayer2::ResumeDecoderAction : public Action {
129 explicit ResumeDecoderAction(bool needNotify)
130 : mNeedNotify(needNotify) {
131 }
132
133 virtual void execute(NuPlayer2 *player) {
134 player->performResumeDecoders(mNeedNotify);
135 }
136
137private:
138 bool mNeedNotify;
139
140 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
141};
142
143struct NuPlayer2::SetSurfaceAction : public Action {
Wei Jia28288fb2017-12-15 13:45:29 -0800144 explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
145 : mNativeWindow(nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800146 }
147
148 virtual void execute(NuPlayer2 *player) {
Wei Jia28288fb2017-12-15 13:45:29 -0800149 player->performSetSurface(mNativeWindow);
Wei Jia53692fa2017-12-11 10:33:46 -0800150 }
151
152private:
Wei Jia28288fb2017-12-15 13:45:29 -0800153 sp<ANativeWindowWrapper> mNativeWindow;
Wei Jia53692fa2017-12-11 10:33:46 -0800154
155 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
156};
157
158struct NuPlayer2::FlushDecoderAction : public Action {
159 FlushDecoderAction(FlushCommand audio, FlushCommand video)
160 : mAudio(audio),
161 mVideo(video) {
162 }
163
164 virtual void execute(NuPlayer2 *player) {
165 player->performDecoderFlush(mAudio, mVideo);
166 }
167
168private:
169 FlushCommand mAudio;
170 FlushCommand mVideo;
171
172 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
173};
174
175struct NuPlayer2::PostMessageAction : public Action {
176 explicit PostMessageAction(const sp<AMessage> &msg)
177 : mMessage(msg) {
178 }
179
180 virtual void execute(NuPlayer2 *) {
181 mMessage->post();
182 }
183
184private:
185 sp<AMessage> mMessage;
186
187 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
188};
189
190// Use this if there's no state necessary to save in order to execute
191// the action.
192struct NuPlayer2::SimpleAction : public Action {
193 typedef void (NuPlayer2::*ActionFunc)();
194
195 explicit SimpleAction(ActionFunc func)
196 : mFunc(func) {
197 }
198
199 virtual void execute(NuPlayer2 *player) {
200 (player->*mFunc)();
201 }
202
203private:
204 ActionFunc mFunc;
205
206 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
207};
208
209////////////////////////////////////////////////////////////////////////////////
210
Wei Jia003fdb52018-02-06 14:44:32 -0800211NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock)
212 : mPID(pid),
213 mUID(uid),
Wei Jia53692fa2017-12-11 10:33:46 -0800214 mMediaClock(mediaClock),
Wei Jia53692fa2017-12-11 10:33:46 -0800215 mOffloadAudio(false),
216 mAudioDecoderGeneration(0),
217 mVideoDecoderGeneration(0),
218 mRendererGeneration(0),
219 mLastStartedPlayingTimeNs(0),
220 mPreviousSeekTimeUs(0),
221 mAudioEOS(false),
222 mVideoEOS(false),
223 mScanSourcesPending(false),
224 mScanSourcesGeneration(0),
225 mPollDurationGeneration(0),
226 mTimedTextGeneration(0),
227 mFlushingAudio(NONE),
228 mFlushingVideo(NONE),
229 mResumePending(false),
230 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
231 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
232 mVideoFpsHint(-1.f),
233 mStarted(false),
234 mPrepared(false),
235 mResetting(false),
236 mSourceStarted(false),
237 mAudioDecoderError(false),
238 mVideoDecoderError(false),
239 mPaused(false),
240 mPausedByClient(true),
241 mPausedForBuffering(false),
Wei Jiaf01e3122018-10-18 11:49:44 -0700242 mIsDrmProtected(false) {
Wei Jia53692fa2017-12-11 10:33:46 -0800243 CHECK(mediaClock != NULL);
244 clearFlushComplete();
245}
246
247NuPlayer2::~NuPlayer2() {
248}
249
Wei Jia53692fa2017-12-11 10:33:46 -0800250void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
251 mDriver = driver;
252}
253
Wei Jia53692fa2017-12-11 10:33:46 -0800254static bool IsHTTPLiveURL(const char *url) {
255 if (!strncasecmp("http://", url, 7)
256 || !strncasecmp("https://", url, 8)
257 || !strncasecmp("file://", url, 7)) {
258 size_t len = strlen(url);
259 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
260 return true;
261 }
262
263 if (strstr(url,"m3u8")) {
264 return true;
265 }
266 }
267
268 return false;
269}
270
Wei Jia72bf2a02018-02-06 15:29:23 -0800271status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
272 sp<Source> *source,
273 DATA_SOURCE_TYPE *dataSourceType) {
274 status_t err = NO_ERROR;
Wei Jia53692fa2017-12-11 10:33:46 -0800275 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
Wei Jia72bf2a02018-02-06 15:29:23 -0800276 notify->setInt64("srcId", dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800277
Wei Jiac2636032018-02-01 09:15:25 -0800278 switch (dsd->mType) {
279 case DataSourceDesc::TYPE_URL:
280 {
281 const char *url = dsd->mUrl.c_str();
282 size_t len = strlen(url);
Wei Jia53692fa2017-12-11 10:33:46 -0800283
Wei Jiac2636032018-02-01 09:15:25 -0800284 const sp<MediaHTTPService> &httpService = dsd->mHttpService;
285 KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
Wei Jia53692fa2017-12-11 10:33:46 -0800286
Wei Jiac2636032018-02-01 09:15:25 -0800287 if (IsHTTPLiveURL(url)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800288 *source = new HTTPLiveSource2(notify, httpService, url, headers);
289 ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
290 *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
Wei Jiac2636032018-02-01 09:15:25 -0800291 } else if (!strncasecmp(url, "rtsp://", 7)) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800292 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800293 notify, httpService, url, headers, mUID);
Wei Jia72bf2a02018-02-06 15:29:23 -0800294 ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
295 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800296 } else if ((!strncasecmp(url, "http://", 7)
297 || !strncasecmp(url, "https://", 8))
298 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
299 || strstr(url, ".sdp?"))) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800300 *source = new RTSPSource2(
Wei Jia003fdb52018-02-06 14:44:32 -0800301 notify, httpService, url, headers, mUID, true);
Wei Jia72bf2a02018-02-06 15:29:23 -0800302 ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
303 *dataSourceType = DATA_SOURCE_TYPE_RTSP;
Wei Jiac2636032018-02-01 09:15:25 -0800304 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800305 ALOGV("createNuPlayer2Source GenericSource2 %s", url);
Wei Jiac2636032018-02-01 09:15:25 -0800306
Wei Jia2409c872018-02-02 10:34:33 -0800307 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800308 new GenericSource2(notify, mUID, mMediaClock);
Wei Jiac2636032018-02-01 09:15:25 -0800309
Robert Shih49fb89d2018-01-31 17:53:19 -0800310 err = genericSource->setDataSource(url, headers);
Wei Jiac2636032018-02-01 09:15:25 -0800311
312 if (err == OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800313 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800314 } else {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800315 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800316 ALOGE("Failed to create NuPlayer2Source!");
Wei Jiac2636032018-02-01 09:15:25 -0800317 }
318
319 // regardless of success/failure
Wei Jia72bf2a02018-02-06 15:29:23 -0800320 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
Wei Jiac2636032018-02-01 09:15:25 -0800321 }
322 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800323 }
324
Wei Jiac2636032018-02-01 09:15:25 -0800325 case DataSourceDesc::TYPE_FD:
326 {
Wei Jia2409c872018-02-02 10:34:33 -0800327 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800328 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia53692fa2017-12-11 10:33:46 -0800329
Wei Jia72bf2a02018-02-06 15:29:23 -0800330 ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
331 dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
332 genericSource.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800333
Wei Jia72bf2a02018-02-06 15:29:23 -0800334 err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
Wei Jia53692fa2017-12-11 10:33:46 -0800335
Wei Jiac2636032018-02-01 09:15:25 -0800336 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800337 ALOGE("Failed to create NuPlayer2Source!");
338 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800339 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800340 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800341 }
Wei Jia53692fa2017-12-11 10:33:46 -0800342
Wei Jia72bf2a02018-02-06 15:29:23 -0800343 *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
Wei Jiac2636032018-02-01 09:15:25 -0800344 break;
345 }
Wei Jia53692fa2017-12-11 10:33:46 -0800346
Wei Jiac2636032018-02-01 09:15:25 -0800347 case DataSourceDesc::TYPE_CALLBACK:
348 {
Wei Jia2409c872018-02-02 10:34:33 -0800349 sp<GenericSource2> genericSource =
Wei Jia003fdb52018-02-06 14:44:32 -0800350 new GenericSource2(notify, mUID, mMediaClock);
Wei Jia72bf2a02018-02-06 15:29:23 -0800351 err = genericSource->setDataSource(dsd->mCallbackSource);
Wei Jia53692fa2017-12-11 10:33:46 -0800352
Wei Jiac2636032018-02-01 09:15:25 -0800353 if (err != OK) {
Wei Jia72bf2a02018-02-06 15:29:23 -0800354 ALOGE("Failed to create NuPlayer2Source!");
355 *source = NULL;
Wei Jiac2636032018-02-01 09:15:25 -0800356 } else {
Wei Jia72bf2a02018-02-06 15:29:23 -0800357 *source = genericSource;
Wei Jiac2636032018-02-01 09:15:25 -0800358 }
359
Wei Jia72bf2a02018-02-06 15:29:23 -0800360 *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
Wei Jiac2636032018-02-01 09:15:25 -0800361 break;
362 }
363
364 default:
Wei Jia72bf2a02018-02-06 15:29:23 -0800365 err = BAD_TYPE;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800366 *source = NULL;
Wei Jia72bf2a02018-02-06 15:29:23 -0800367 *dataSourceType = DATA_SOURCE_TYPE_NONE;
Wei Jiac2636032018-02-01 09:15:25 -0800368 ALOGE("invalid data source type!");
369 break;
Wei Jia53692fa2017-12-11 10:33:46 -0800370 }
371
Wei Jia72bf2a02018-02-06 15:29:23 -0800372 return err;
373}
374
375void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
376 DATA_SOURCE_TYPE dataSourceType;
377 sp<Source> source;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800378 createNuPlayer2Source(dsd, &source, &dataSourceType);
Wei Jia72bf2a02018-02-06 15:29:23 -0800379
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800380 // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
381 // and expects notifySetDataSourceCompleted regardless of success or failure.
382 // This will be changed since setDataSource should be asynchronous at JAVA level.
383 // When it succeeds, app will get onInfo notification. Otherwise, onError
384 // will be called.
385 /*
Wei Jia72bf2a02018-02-06 15:29:23 -0800386 if (err != OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800387 notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
Wei Jia72bf2a02018-02-06 15:29:23 -0800388 return;
389 }
390
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800391 // Now, source != NULL.
392 */
393
Wei Jiaf01e3122018-10-18 11:49:44 -0700394 mCurrentSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800395
396 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
Wei Jia53692fa2017-12-11 10:33:46 -0800397 msg->setObject("source", source);
Wei Jia72bf2a02018-02-06 15:29:23 -0800398 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700399 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
400 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia72bf2a02018-02-06 15:29:23 -0800401 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 Jiaf01e3122018-10-18 11:49:44 -0700418 mNextSourceInfo.mDataSourceType = dataSourceType;
Wei Jia72bf2a02018-02-06 15:29:23 -0800419
420 sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
421 msg->setObject("source", source);
422 msg->setInt64("srcId", dsd->mId);
Wei Jiaf01e3122018-10-18 11:49:44 -0700423 msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
424 msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
Wei Jia53692fa2017-12-11 10:33:46 -0800425 msg->post();
Wei Jia53692fa2017-12-11 10:33:46 -0800426}
427
Wei Jia57aeffd2018-02-15 16:01:14 -0800428void NuPlayer2::playNextDataSource(int64_t srcId) {
429 disconnectSource();
430
431 sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
432 msg->setInt64("srcId", srcId);
433 msg->post();
434}
435
Wei Jia53692fa2017-12-11 10:33:46 -0800436status_t NuPlayer2::getBufferingSettings(
437 BufferingSettings *buffering /* nonnull */) {
438 sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
439 sp<AMessage> response;
440 status_t err = msg->postAndAwaitResponse(&response);
441 if (err == OK && response != NULL) {
442 CHECK(response->findInt32("err", &err));
443 if (err == OK) {
444 readFromAMessage(response, buffering);
445 }
446 }
447 return err;
448}
449
450status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
451 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
452 writeToAMessage(msg, buffering);
453 sp<AMessage> response;
454 status_t err = msg->postAndAwaitResponse(&response);
455 if (err == OK && response != NULL) {
456 CHECK(response->findInt32("err", &err));
457 }
458 return err;
459}
460
461void NuPlayer2::prepareAsync() {
462 ALOGV("prepareAsync");
463
464 (new AMessage(kWhatPrepare, this))->post();
465}
466
Wei Jia28288fb2017-12-15 13:45:29 -0800467void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -0800468 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
469
Wei Jia28288fb2017-12-15 13:45:29 -0800470 if (nww == NULL || nww->getANativeWindow() == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800471 msg->setObject("surface", NULL);
472 } else {
Wei Jia28288fb2017-12-15 13:45:29 -0800473 msg->setObject("surface", nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800474 }
475
476 msg->post();
477}
478
Wei Jia33abcc72018-01-30 09:47:38 -0800479void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
Wei Jia53692fa2017-12-11 10:33:46 -0800480 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
481 msg->setObject("sink", sink);
482 msg->post();
483}
484
485void NuPlayer2::start() {
486 (new AMessage(kWhatStart, this))->post();
487}
488
489status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
490 // do some cursory validation of the settings here. audio modes are
491 // only validated when set on the audiosink.
Wei Jia700a7c22018-09-14 18:04:35 -0700492 if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
Wei Jia53692fa2017-12-11 10:33:46 -0800493 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
494 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
495 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
496 return BAD_VALUE;
497 }
498 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
499 writeToAMessage(msg, rate);
500 sp<AMessage> response;
501 status_t err = msg->postAndAwaitResponse(&response);
502 if (err == OK && response != NULL) {
503 CHECK(response->findInt32("err", &err));
504 }
505 return err;
506}
507
508status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
509 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
510 sp<AMessage> response;
511 status_t err = msg->postAndAwaitResponse(&response);
512 if (err == OK && response != NULL) {
513 CHECK(response->findInt32("err", &err));
514 if (err == OK) {
515 readFromAMessage(response, rate);
516 }
517 }
518 return err;
519}
520
521status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
522 sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
523 writeToAMessage(msg, sync, videoFpsHint);
524 sp<AMessage> response;
525 status_t err = msg->postAndAwaitResponse(&response);
526 if (err == OK && response != NULL) {
527 CHECK(response->findInt32("err", &err));
528 }
529 return err;
530}
531
532status_t NuPlayer2::getSyncSettings(
533 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
534 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
535 sp<AMessage> response;
536 status_t err = msg->postAndAwaitResponse(&response);
537 if (err == OK && response != NULL) {
538 CHECK(response->findInt32("err", &err));
539 if (err == OK) {
540 readFromAMessage(response, sync, videoFps);
541 }
542 }
543 return err;
544}
545
546void NuPlayer2::pause() {
547 (new AMessage(kWhatPause, this))->post();
548}
549
550void NuPlayer2::resetAsync() {
Wei Jia57aeffd2018-02-15 16:01:14 -0800551 disconnectSource();
552 (new AMessage(kWhatReset, this))->post();
553}
554
555void NuPlayer2::disconnectSource() {
Wei Jia53692fa2017-12-11 10:33:46 -0800556 sp<Source> source;
557 {
558 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700559 source = mCurrentSourceInfo.mSource;
Wei Jia53692fa2017-12-11 10:33:46 -0800560 }
561
562 if (source != NULL) {
563 // During a reset, the data source might be unresponsive already, we need to
564 // disconnect explicitly so that reads exit promptly.
565 // We can't queue the disconnect request to the looper, as it might be
566 // queued behind a stuck read and never gets processed.
567 // Doing a disconnect outside the looper to allows the pending reads to exit
568 // (either successfully or with error).
569 source->disconnect();
570 }
571
Wei Jia53692fa2017-12-11 10:33:46 -0800572}
573
574status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
575 sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
576 notify->setInt64("timerUs", mediaTimeUs);
577 mMediaClock->addTimer(notify, mediaTimeUs);
578 return OK;
579}
580
581void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
582 sp<AMessage> msg = new AMessage(kWhatSeek, this);
583 msg->setInt64("seekTimeUs", seekTimeUs);
584 msg->setInt32("mode", mode);
585 msg->setInt32("needNotify", needNotify);
586 msg->post();
587}
588
Wei Jia53692fa2017-12-11 10:33:46 -0800589void NuPlayer2::writeTrackInfo(
Dongwon Kang9f631982018-07-10 12:34:41 -0700590 PlayerMessage* reply, const sp<AMessage>& format) const {
Wei Jia53692fa2017-12-11 10:33:46 -0800591 if (format == NULL) {
592 ALOGE("NULL format");
593 return;
594 }
595 int32_t trackType;
596 if (!format->findInt32("type", &trackType)) {
597 ALOGE("no track type");
598 return;
599 }
600
601 AString mime;
602 if (!format->findString("mime", &mime)) {
603 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
604 // If we can't find the mimetype here it means that we wouldn't be needing
605 // the mimetype on the Java end. We still write a placeholder mime to keep the
606 // (de)serialization logic simple.
607 if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
608 mime = "audio/";
609 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
610 mime = "video/";
611 } else {
612 ALOGE("unknown track type: %d", trackType);
613 return;
614 }
615 }
616
617 AString lang;
618 if (!format->findString("language", &lang)) {
619 ALOGE("no language");
620 return;
621 }
622
Dongwon Kang9f631982018-07-10 12:34:41 -0700623 reply->add_values()->set_int32_value(trackType);
624 reply->add_values()->set_string_value(mime.c_str());
625 reply->add_values()->set_string_value(lang.c_str());
Wei Jia53692fa2017-12-11 10:33:46 -0800626
627 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
628 int32_t isAuto, isDefault, isForced;
629 CHECK(format->findInt32("auto", &isAuto));
630 CHECK(format->findInt32("default", &isDefault));
631 CHECK(format->findInt32("forced", &isForced));
632
Dongwon Kang9f631982018-07-10 12:34:41 -0700633 reply->add_values()->set_int32_value(isAuto);
634 reply->add_values()->set_int32_value(isDefault);
635 reply->add_values()->set_int32_value(isForced);
Wei Jia53692fa2017-12-11 10:33:46 -0800636 }
637}
638
639void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
640 switch (msg->what()) {
641 case kWhatSetDataSource:
642 {
643 ALOGV("kWhatSetDataSource");
644
Wei Jiaf01e3122018-10-18 11:49:44 -0700645 CHECK(mCurrentSourceInfo.mSource == NULL);
Wei Jia53692fa2017-12-11 10:33:46 -0800646
647 status_t err = OK;
648 sp<RefBase> obj;
649 CHECK(msg->findObject("source", &obj));
650 if (obj != NULL) {
651 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700652 CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
653 CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
654 CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
655 mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800656 } else {
657 err = UNKNOWN_ERROR;
Wei Jia083e9092018-02-12 11:46:04 -0800658 ALOGE("kWhatSetDataSource, source should not be NULL");
Wei Jia53692fa2017-12-11 10:33:46 -0800659 }
660
661 CHECK(mDriver != NULL);
662 sp<NuPlayer2Driver> driver = mDriver.promote();
663 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700664 driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -0800665 }
666 break;
667 }
668
Wei Jia72bf2a02018-02-06 15:29:23 -0800669 case kWhatPrepareNextDataSource:
670 {
671 ALOGV("kWhatPrepareNextDataSource");
672
673 status_t err = OK;
674 sp<RefBase> obj;
675 CHECK(msg->findObject("source", &obj));
676 if (obj != NULL) {
677 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -0700678 CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
679 CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
680 CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
681 mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
682 mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
Wei Jia72bf2a02018-02-06 15:29:23 -0800683 } else {
684 err = UNKNOWN_ERROR;
685 }
686
687 break;
688 }
689
Wei Jia57aeffd2018-02-15 16:01:14 -0800690 case kWhatPlayNextDataSource:
691 {
692 ALOGV("kWhatPlayNextDataSource");
693 int64_t srcId;
694 CHECK(msg->findInt64("srcId", &srcId));
Wei Jiaf01e3122018-10-18 11:49:44 -0700695 if (srcId != mNextSourceInfo.mSrcId) {
Wei Jia57aeffd2018-02-15 16:01:14 -0800696 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
697 return;
698 }
699
700 mResetting = true;
701 stopPlaybackTimer("kWhatPlayNextDataSource");
702 stopRebufferingTimer(true);
703
704 mDeferredActions.push_back(
705 new FlushDecoderAction(
706 FLUSH_CMD_SHUTDOWN /* audio */,
707 FLUSH_CMD_SHUTDOWN /* video */));
708
709 mDeferredActions.push_back(
710 new SimpleAction(&NuPlayer2::performPlayNextDataSource));
711
712 processDeferredActions();
713 break;
714 }
715
Wei Jia53692fa2017-12-11 10:33:46 -0800716 case kWhatGetBufferingSettings:
717 {
718 sp<AReplyToken> replyID;
719 CHECK(msg->senderAwaitsResponse(&replyID));
720
721 ALOGV("kWhatGetBufferingSettings");
722 BufferingSettings buffering;
723 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700724 if (mCurrentSourceInfo.mSource != NULL) {
725 err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800726 } else {
727 err = INVALID_OPERATION;
728 }
729 sp<AMessage> response = new AMessage;
730 if (err == OK) {
731 writeToAMessage(response, buffering);
732 }
733 response->setInt32("err", err);
734 response->postReply(replyID);
735 break;
736 }
737
738 case kWhatSetBufferingSettings:
739 {
740 sp<AReplyToken> replyID;
741 CHECK(msg->senderAwaitsResponse(&replyID));
742
743 ALOGV("kWhatSetBufferingSettings");
744 BufferingSettings buffering;
745 readFromAMessage(msg, &buffering);
746 status_t err = OK;
Wei Jiaf01e3122018-10-18 11:49:44 -0700747 if (mCurrentSourceInfo.mSource != NULL) {
748 err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
Wei Jia53692fa2017-12-11 10:33:46 -0800749 } else {
750 err = INVALID_OPERATION;
751 }
752 sp<AMessage> response = new AMessage;
753 response->setInt32("err", err);
754 response->postReply(replyID);
755 break;
756 }
757
758 case kWhatPrepare:
759 {
760 ALOGV("onMessageReceived kWhatPrepare");
761
Wei Jiaf01e3122018-10-18 11:49:44 -0700762 mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800763 break;
764 }
765
766 case kWhatGetTrackInfo:
767 {
768 sp<AReplyToken> replyID;
769 CHECK(msg->senderAwaitsResponse(&replyID));
770
Dongwon Kang9f631982018-07-10 12:34:41 -0700771 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800772 CHECK(msg->findPointer("reply", (void**)&reply));
773
774 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700775 if (mCurrentSourceInfo.mSource != NULL) {
776 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800777 }
778
779 size_t ccTracks = 0;
780 if (mCCDecoder != NULL) {
781 ccTracks = mCCDecoder->getTrackCount();
782 }
783
784 // total track count
Dongwon Kang9f631982018-07-10 12:34:41 -0700785 reply->add_values()->set_int32_value(inbandTracks + ccTracks);
Wei Jia53692fa2017-12-11 10:33:46 -0800786
787 // write inband tracks
788 for (size_t i = 0; i < inbandTracks; ++i) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700789 writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
Wei Jia53692fa2017-12-11 10:33:46 -0800790 }
791
792 // write CC track
793 for (size_t i = 0; i < ccTracks; ++i) {
794 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
795 }
796
797 sp<AMessage> response = new AMessage;
798 response->postReply(replyID);
799 break;
800 }
801
802 case kWhatGetSelectedTrack:
803 {
804 status_t err = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -0700805 if (mCurrentSourceInfo.mSource != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -0800806 err = OK;
807
808 int32_t type32;
809 CHECK(msg->findInt32("type", (int32_t*)&type32));
810 media_track_type type = (media_track_type)type32;
Wei Jiaf01e3122018-10-18 11:49:44 -0700811 ssize_t selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
Wei Jia53692fa2017-12-11 10:33:46 -0800812
Dongwon Kang9f631982018-07-10 12:34:41 -0700813 PlayerMessage* reply;
Wei Jia53692fa2017-12-11 10:33:46 -0800814 CHECK(msg->findPointer("reply", (void**)&reply));
Dongwon Kang9f631982018-07-10 12:34:41 -0700815 reply->add_values()->set_int32_value(selectedTrack);
Wei Jia53692fa2017-12-11 10:33:46 -0800816 }
817
818 sp<AMessage> response = new AMessage;
819 response->setInt32("err", err);
820
821 sp<AReplyToken> replyID;
822 CHECK(msg->senderAwaitsResponse(&replyID));
823 response->postReply(replyID);
824 break;
825 }
826
827 case kWhatSelectTrack:
828 {
829 sp<AReplyToken> replyID;
830 CHECK(msg->senderAwaitsResponse(&replyID));
831
832 size_t trackIndex;
833 int32_t select;
834 int64_t timeUs;
835 CHECK(msg->findSize("trackIndex", &trackIndex));
836 CHECK(msg->findInt32("select", &select));
837 CHECK(msg->findInt64("timeUs", &timeUs));
838
839 status_t err = INVALID_OPERATION;
840
841 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -0700842 if (mCurrentSourceInfo.mSource != NULL) {
843 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -0800844 }
845 size_t ccTracks = 0;
846 if (mCCDecoder != NULL) {
847 ccTracks = mCCDecoder->getTrackCount();
848 }
849
850 if (trackIndex < inbandTracks) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700851 err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800852
853 if (!select && err == OK) {
854 int32_t type;
Wei Jiaf01e3122018-10-18 11:49:44 -0700855 sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
Wei Jia53692fa2017-12-11 10:33:46 -0800856 if (info != NULL
857 && info->findInt32("type", &type)
858 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
859 ++mTimedTextGeneration;
860 }
861 }
862 } else {
863 trackIndex -= inbandTracks;
864
865 if (trackIndex < ccTracks) {
866 err = mCCDecoder->selectTrack(trackIndex, select);
867 }
868 }
869
870 sp<AMessage> response = new AMessage;
871 response->setInt32("err", err);
872
873 response->postReply(replyID);
874 break;
875 }
876
877 case kWhatPollDuration:
878 {
879 int32_t generation;
880 CHECK(msg->findInt32("generation", &generation));
881
882 if (generation != mPollDurationGeneration) {
883 // stale
884 break;
885 }
886
887 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -0700888 if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jia53692fa2017-12-11 10:33:46 -0800889 sp<NuPlayer2Driver> driver = mDriver.promote();
890 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -0700891 driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -0800892 }
893 }
894
895 msg->post(1000000ll); // poll again in a second.
896 break;
897 }
898
899 case kWhatSetVideoSurface:
900 {
901
902 sp<RefBase> obj;
903 CHECK(msg->findObject("surface", &obj));
Wei Jia28288fb2017-12-15 13:45:29 -0800904 sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800905
906 ALOGD("onSetVideoSurface(%p, %s video decoder)",
Wei Jia28288fb2017-12-15 13:45:29 -0800907 (nww == NULL ? NULL : nww->getANativeWindow()),
Wei Jiaf01e3122018-10-18 11:49:44 -0700908 (mCurrentSourceInfo.mSource != NULL && mStarted
909 && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
Wei Jia53692fa2017-12-11 10:33:46 -0800910 && mVideoDecoder != NULL) ? "have" : "no");
911
Wei Jiaf01e3122018-10-18 11:49:44 -0700912 // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
913 // because NuPlayer2 might be in preparing state and it could take long time.
914 // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
915 if (mCurrentSourceInfo.mSource == NULL || !mStarted
916 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
Wei Jia28288fb2017-12-15 13:45:29 -0800917 // NOTE: mVideoDecoder's mNativeWindow is always non-null
918 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
919 performSetSurface(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800920 break;
921 }
922
923 mDeferredActions.push_back(
924 new FlushDecoderAction(
925 (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
926 FLUSH_CMD_SHUTDOWN /* video */));
927
Wei Jia28288fb2017-12-15 13:45:29 -0800928 mDeferredActions.push_back(new SetSurfaceAction(nww));
Wei Jia53692fa2017-12-11 10:33:46 -0800929
930 if (obj != NULL) {
931 if (mStarted) {
932 // Issue a seek to refresh the video screen only if started otherwise
933 // the extractor may not yet be started and will assert.
934 // If the video decoder is not set (perhaps audio only in this case)
935 // do not perform a seek as it is not needed.
936 int64_t currentPositionUs = 0;
937 if (getCurrentPosition(&currentPositionUs) == OK) {
938 mDeferredActions.push_back(
939 new SeekAction(currentPositionUs,
940 MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
941 }
942 }
943
944 // If there is a new surface texture, instantiate decoders
945 // again if possible.
946 mDeferredActions.push_back(
947 new SimpleAction(&NuPlayer2::performScanSources));
948
949 // After a flush without shutdown, decoder is paused.
950 // Don't resume it until source seek is done, otherwise it could
951 // start pulling stale data too soon.
952 mDeferredActions.push_back(
953 new ResumeDecoderAction(false /* needNotify */));
954 }
955
956 processDeferredActions();
957 break;
958 }
959
960 case kWhatSetAudioSink:
961 {
962 ALOGV("kWhatSetAudioSink");
963
964 sp<RefBase> obj;
965 CHECK(msg->findObject("sink", &obj));
966
Wei Jia33abcc72018-01-30 09:47:38 -0800967 mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
Wei Jia53692fa2017-12-11 10:33:46 -0800968 break;
969 }
970
971 case kWhatStart:
972 {
973 ALOGV("kWhatStart");
974 if (mStarted) {
975 // do not resume yet if the source is still buffering
976 if (!mPausedForBuffering) {
977 onResume();
978 }
979 } else {
Wei Jia6376cd52018-09-26 11:42:55 -0700980 onStart(true /* play */);
Wei Jia53692fa2017-12-11 10:33:46 -0800981 }
982 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -0700983 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -0800984 break;
985 }
986
987 case kWhatConfigPlayback:
988 {
989 sp<AReplyToken> replyID;
990 CHECK(msg->senderAwaitsResponse(&replyID));
991 AudioPlaybackRate rate /* sanitized */;
992 readFromAMessage(msg, &rate);
993 status_t err = OK;
994 if (mRenderer != NULL) {
995 // AudioSink allows only 1.f and 0.f for offload mode.
996 // For other speed, switch to non-offload mode.
Wei Jia700a7c22018-09-14 18:04:35 -0700997 if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
Wei Jia53692fa2017-12-11 10:33:46 -0800998 int64_t currentPositionUs;
999 if (getCurrentPosition(&currentPositionUs) != OK) {
1000 currentPositionUs = mPreviousSeekTimeUs;
1001 }
1002
1003 // Set mPlaybackSettings so that the new audio decoder can
1004 // be created correctly.
1005 mPlaybackSettings = rate;
1006 if (!mPaused) {
1007 mRenderer->pause();
1008 }
1009 restartAudio(
1010 currentPositionUs, true /* forceNonOffload */,
1011 true /* needsToCreateAudioDecoder */);
1012 if (!mPaused) {
1013 mRenderer->resume();
1014 }
1015 }
1016
1017 err = mRenderer->setPlaybackSettings(rate);
1018 }
1019 if (err == OK) {
Wei Jia700a7c22018-09-14 18:04:35 -07001020 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001021
Wei Jia700a7c22018-09-14 18:04:35 -07001022 if (mVideoDecoder != NULL) {
1023 sp<AMessage> params = new AMessage();
1024 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
1025 mVideoDecoder->setParameters(params);
Wei Jia53692fa2017-12-11 10:33:46 -08001026 }
1027 }
1028
Wei Jia53692fa2017-12-11 10:33:46 -08001029 sp<AMessage> response = new AMessage;
1030 response->setInt32("err", err);
1031 response->postReply(replyID);
1032 break;
1033 }
1034
1035 case kWhatGetPlaybackSettings:
1036 {
1037 sp<AReplyToken> replyID;
1038 CHECK(msg->senderAwaitsResponse(&replyID));
1039 AudioPlaybackRate rate = mPlaybackSettings;
1040 status_t err = OK;
1041 if (mRenderer != NULL) {
1042 err = mRenderer->getPlaybackSettings(&rate);
1043 }
1044 if (err == OK) {
1045 // get playback settings used by renderer, as it may be
1046 // slightly off due to audiosink not taking small changes.
1047 mPlaybackSettings = rate;
Wei Jia53692fa2017-12-11 10:33:46 -08001048 }
1049 sp<AMessage> response = new AMessage;
1050 if (err == OK) {
1051 writeToAMessage(response, rate);
1052 }
1053 response->setInt32("err", err);
1054 response->postReply(replyID);
1055 break;
1056 }
1057
1058 case kWhatConfigSync:
1059 {
1060 sp<AReplyToken> replyID;
1061 CHECK(msg->senderAwaitsResponse(&replyID));
1062
1063 ALOGV("kWhatConfigSync");
1064 AVSyncSettings sync;
1065 float videoFpsHint;
1066 readFromAMessage(msg, &sync, &videoFpsHint);
1067 status_t err = OK;
1068 if (mRenderer != NULL) {
1069 err = mRenderer->setSyncSettings(sync, videoFpsHint);
1070 }
1071 if (err == OK) {
1072 mSyncSettings = sync;
1073 mVideoFpsHint = videoFpsHint;
1074 }
1075 sp<AMessage> response = new AMessage;
1076 response->setInt32("err", err);
1077 response->postReply(replyID);
1078 break;
1079 }
1080
1081 case kWhatGetSyncSettings:
1082 {
1083 sp<AReplyToken> replyID;
1084 CHECK(msg->senderAwaitsResponse(&replyID));
1085 AVSyncSettings sync = mSyncSettings;
1086 float videoFps = mVideoFpsHint;
1087 status_t err = OK;
1088 if (mRenderer != NULL) {
1089 err = mRenderer->getSyncSettings(&sync, &videoFps);
1090 if (err == OK) {
1091 mSyncSettings = sync;
1092 mVideoFpsHint = videoFps;
1093 }
1094 }
1095 sp<AMessage> response = new AMessage;
1096 if (err == OK) {
1097 writeToAMessage(response, sync, videoFps);
1098 }
1099 response->setInt32("err", err);
1100 response->postReply(replyID);
1101 break;
1102 }
1103
1104 case kWhatScanSources:
1105 {
1106 int32_t generation;
1107 CHECK(msg->findInt32("generation", &generation));
1108 if (generation != mScanSourcesGeneration) {
1109 // Drop obsolete msg.
1110 break;
1111 }
1112
1113 mScanSourcesPending = false;
1114
1115 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1116 mAudioDecoder != NULL, mVideoDecoder != NULL);
1117
1118 bool mHadAnySourcesBefore =
1119 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1120 bool rescan = false;
1121
1122 // initialize video before audio because successful initialization of
1123 // video may change deep buffer mode of audio.
Wei Jia28288fb2017-12-15 13:45:29 -08001124 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001125 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1126 rescan = true;
1127 }
1128 }
1129
1130 // Don't try to re-open audio sink if there's an existing decoder.
1131 if (mAudioSink != NULL && mAudioDecoder == NULL) {
1132 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1133 rescan = true;
1134 }
1135 }
1136
1137 if (!mHadAnySourcesBefore
1138 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1139 // This is the first time we've found anything playable.
1140
Wei Jiaf01e3122018-10-18 11:49:44 -07001141 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Wei Jia53692fa2017-12-11 10:33:46 -08001142 schedulePollDuration();
1143 }
1144 }
1145
1146 status_t err;
Wei Jiaf01e3122018-10-18 11:49:44 -07001147 if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
Wei Jia53692fa2017-12-11 10:33:46 -08001148 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1149 // We're not currently decoding anything (no audio or
1150 // video tracks found) and we just ran out of input data.
1151
1152 if (err == ERROR_END_OF_STREAM) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001153 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001154 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001155 notifyListener(
1156 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001157 }
1158 }
1159 break;
1160 }
1161
1162 if (rescan) {
1163 msg->post(100000ll);
1164 mScanSourcesPending = true;
1165 }
1166 break;
1167 }
1168
1169 case kWhatVideoNotify:
1170 case kWhatAudioNotify:
1171 {
1172 bool audio = msg->what() == kWhatAudioNotify;
1173
1174 int32_t currentDecoderGeneration =
1175 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1176 int32_t requesterGeneration = currentDecoderGeneration - 1;
1177 CHECK(msg->findInt32("generation", &requesterGeneration));
1178
1179 if (requesterGeneration != currentDecoderGeneration) {
1180 ALOGV("got message from old %s decoder, generation(%d:%d)",
1181 audio ? "audio" : "video", requesterGeneration,
1182 currentDecoderGeneration);
1183 sp<AMessage> reply;
1184 if (!(msg->findMessage("reply", &reply))) {
1185 return;
1186 }
1187
1188 reply->setInt32("err", INFO_DISCONTINUITY);
1189 reply->post();
1190 return;
1191 }
1192
1193 int32_t what;
1194 CHECK(msg->findInt32("what", &what));
1195
1196 if (what == DecoderBase::kWhatInputDiscontinuity) {
1197 int32_t formatChange;
1198 CHECK(msg->findInt32("formatChange", &formatChange));
1199
1200 ALOGV("%s discontinuity: formatChange %d",
1201 audio ? "audio" : "video", formatChange);
1202
1203 if (formatChange) {
1204 mDeferredActions.push_back(
1205 new FlushDecoderAction(
1206 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1207 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1208 }
1209
1210 mDeferredActions.push_back(
1211 new SimpleAction(
1212 &NuPlayer2::performScanSources));
1213
1214 processDeferredActions();
1215 } else if (what == DecoderBase::kWhatEOS) {
1216 int32_t err;
1217 CHECK(msg->findInt32("err", &err));
1218
1219 if (err == ERROR_END_OF_STREAM) {
1220 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1221 } else {
1222 ALOGV("got %s decoder EOS w/ error %d",
1223 audio ? "audio" : "video",
1224 err);
1225 }
1226
1227 mRenderer->queueEOS(audio, err);
1228 } else if (what == DecoderBase::kWhatFlushCompleted) {
1229 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1230
1231 handleFlushComplete(audio, true /* isDecoder */);
1232 finishFlushIfPossible();
1233 } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1234 sp<AMessage> format;
1235 CHECK(msg->findMessage("format", &format));
1236
1237 sp<AMessage> inputFormat =
Wei Jiaf01e3122018-10-18 11:49:44 -07001238 mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001239
1240 setVideoScalingMode(mVideoScalingMode);
Wei Jiaf01e3122018-10-18 11:49:44 -07001241 updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
Wei Jia53692fa2017-12-11 10:33:46 -08001242 } else if (what == DecoderBase::kWhatShutdownCompleted) {
1243 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1244 if (audio) {
1245 mAudioDecoder.clear();
1246 mAudioDecoderError = false;
1247 ++mAudioDecoderGeneration;
1248
1249 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1250 mFlushingAudio = SHUT_DOWN;
1251 } else {
1252 mVideoDecoder.clear();
1253 mVideoDecoderError = false;
1254 ++mVideoDecoderGeneration;
1255
1256 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1257 mFlushingVideo = SHUT_DOWN;
1258 }
1259
1260 finishFlushIfPossible();
1261 } else if (what == DecoderBase::kWhatResumeCompleted) {
1262 finishResume();
1263 } else if (what == DecoderBase::kWhatError) {
1264 status_t err;
1265 if (!msg->findInt32("err", &err) || err == OK) {
1266 err = UNKNOWN_ERROR;
1267 }
1268
1269 // Decoder errors can be due to Source (e.g. from streaming),
1270 // or from decoding corrupted bitstreams, or from other decoder
1271 // MediaCodec operations (e.g. from an ongoing reset or seek).
1272 // They may also be due to openAudioSink failure at
1273 // decoder start or after a format change.
1274 //
1275 // We try to gracefully shut down the affected decoder if possible,
1276 // rather than trying to force the shutdown with something
1277 // similar to performReset(). This method can lead to a hang
1278 // if MediaCodec functions block after an error, but they should
1279 // typically return INVALID_OPERATION instead of blocking.
1280
1281 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1282 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1283 err, audio ? "audio" : "video", *flushing);
1284
1285 switch (*flushing) {
1286 case NONE:
1287 mDeferredActions.push_back(
1288 new FlushDecoderAction(
1289 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1290 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1291 processDeferredActions();
1292 break;
1293 case FLUSHING_DECODER:
1294 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1295 break; // Wait for flush to complete.
1296 case FLUSHING_DECODER_SHUTDOWN:
1297 break; // Wait for flush to complete.
1298 case SHUTTING_DOWN_DECODER:
1299 break; // Wait for shutdown to complete.
1300 case FLUSHED:
1301 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1302 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
1303 break;
1304 case SHUT_DOWN:
1305 finishFlushIfPossible(); // Should not occur.
1306 break; // Finish anyways.
1307 }
Wei Jiaf01e3122018-10-18 11:49:44 -07001308 if (mCurrentSourceInfo.mSource != nullptr) {
Wei Jia53692fa2017-12-11 10:33:46 -08001309 if (audio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001310 if (mVideoDecoderError
1311 || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
1312 || mNativeWindow == NULL
1313 || mNativeWindow->getANativeWindow() == NULL
Wei Jia28288fb2017-12-15 13:45:29 -08001314 || mVideoDecoder == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001315 // When both audio and video have error, or this stream has only audio
1316 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001317 notifyListener(
1318 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1319 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001320 } else {
1321 // Only audio track has error. Video track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001322 notifyListener(
1323 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1324 MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001325 }
1326 mAudioDecoderError = true;
1327 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07001328 if (mAudioDecoderError
1329 || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
Wei Jia53692fa2017-12-11 10:33:46 -08001330 || mAudioSink == NULL || mAudioDecoder == NULL) {
1331 // When both audio and video have error, or this stream has only video
1332 // which has error, notify client of error.
Wei Jiaf01e3122018-10-18 11:49:44 -07001333 notifyListener(
1334 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1335 MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001336 } else {
1337 // Only video track has error. Audio track could be still good to play.
Wei Jiaf01e3122018-10-18 11:49:44 -07001338 notifyListener(
1339 mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1340 MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001341 }
1342 mVideoDecoderError = true;
1343 }
1344 }
1345 } else {
1346 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1347 what,
1348 what >> 24,
1349 (what >> 16) & 0xff,
1350 (what >> 8) & 0xff,
1351 what & 0xff);
1352 }
1353
1354 break;
1355 }
1356
1357 case kWhatRendererNotify:
1358 {
1359 int32_t requesterGeneration = mRendererGeneration - 1;
1360 CHECK(msg->findInt32("generation", &requesterGeneration));
1361 if (requesterGeneration != mRendererGeneration) {
1362 ALOGV("got message from old renderer, generation(%d:%d)",
1363 requesterGeneration, mRendererGeneration);
1364 return;
1365 }
1366
1367 int32_t what;
1368 CHECK(msg->findInt32("what", &what));
1369
1370 if (what == Renderer::kWhatEOS) {
1371 int32_t audio;
1372 CHECK(msg->findInt32("audio", &audio));
1373
1374 int32_t finalResult;
1375 CHECK(msg->findInt32("finalResult", &finalResult));
1376
1377 if (audio) {
1378 mAudioEOS = true;
1379 } else {
1380 mVideoEOS = true;
1381 }
1382
1383 if (finalResult == ERROR_END_OF_STREAM) {
1384 ALOGV("reached %s EOS", audio ? "audio" : "video");
1385 } else {
1386 ALOGE("%s track encountered an error (%d)",
1387 audio ? "audio" : "video", finalResult);
1388
1389 notifyListener(
Wei Jiaf01e3122018-10-18 11:49:44 -07001390 mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1391 MEDIA2_ERROR_UNKNOWN, finalResult);
Wei Jia53692fa2017-12-11 10:33:46 -08001392 }
1393
1394 if ((mAudioEOS || mAudioDecoder == NULL)
1395 && (mVideoEOS || mVideoDecoder == NULL)) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001396 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001397 }
1398 } else if (what == Renderer::kWhatFlushComplete) {
1399 int32_t audio;
1400 CHECK(msg->findInt32("audio", &audio));
1401
1402 if (audio) {
1403 mAudioEOS = false;
1404 } else {
1405 mVideoEOS = false;
1406 }
1407
1408 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1409 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1410 || mFlushingAudio == SHUT_DOWN)) {
1411 // Flush has been handled by tear down.
1412 break;
1413 }
1414 handleFlushComplete(audio, false /* isDecoder */);
1415 finishFlushIfPossible();
1416 } else if (what == Renderer::kWhatVideoRenderingStart) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001417 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
1418 MEDIA2_INFO_VIDEO_RENDERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001419 } else if (what == Renderer::kWhatMediaRenderingStart) {
1420 ALOGV("media rendering started");
Wei Jiaf01e3122018-10-18 11:49:44 -07001421 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001422 } else if (what == Renderer::kWhatAudioTearDown) {
1423 int32_t reason;
1424 CHECK(msg->findInt32("reason", &reason));
1425 ALOGV("Tear down audio with reason %d.", reason);
1426 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1427 // TimeoutWhenPaused is only for offload mode.
1428 ALOGW("Receive a stale message for teardown.");
1429 break;
1430 }
1431 int64_t positionUs;
1432 if (!msg->findInt64("positionUs", &positionUs)) {
1433 positionUs = mPreviousSeekTimeUs;
1434 }
1435
1436 restartAudio(
1437 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1438 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1439 }
1440 break;
1441 }
1442
1443 case kWhatMoreDataQueued:
1444 {
1445 break;
1446 }
1447
1448 case kWhatReset:
1449 {
1450 ALOGV("kWhatReset");
1451
1452 mResetting = true;
1453 stopPlaybackTimer("kWhatReset");
1454 stopRebufferingTimer(true);
1455
1456 mDeferredActions.push_back(
1457 new FlushDecoderAction(
1458 FLUSH_CMD_SHUTDOWN /* audio */,
1459 FLUSH_CMD_SHUTDOWN /* video */));
1460
1461 mDeferredActions.push_back(
1462 new SimpleAction(&NuPlayer2::performReset));
1463
1464 processDeferredActions();
1465 break;
1466 }
1467
1468 case kWhatNotifyTime:
1469 {
1470 ALOGV("kWhatNotifyTime");
1471 int64_t timerUs;
1472 CHECK(msg->findInt64("timerUs", &timerUs));
1473
Wei Jiaf01e3122018-10-18 11:49:44 -07001474 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001475 break;
1476 }
1477
1478 case kWhatSeek:
1479 {
1480 int64_t seekTimeUs;
1481 int32_t mode;
1482 int32_t needNotify;
1483 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1484 CHECK(msg->findInt32("mode", &mode));
1485 CHECK(msg->findInt32("needNotify", &needNotify));
1486
1487 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1488 (long long)seekTimeUs, mode, needNotify);
1489
1490 if (!mStarted) {
Wei Jia083e9092018-02-12 11:46:04 -08001491 if (!mSourceStarted) {
1492 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001493 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001494 }
Wei Jia083e9092018-02-12 11:46:04 -08001495 if (seekTimeUs > 0) {
1496 performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
1497 }
1498
Wei Jia53692fa2017-12-11 10:33:46 -08001499 if (needNotify) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001500 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08001501 }
1502 break;
1503 }
1504
Wei Jia083e9092018-02-12 11:46:04 -08001505 // seeks can take a while, so we essentially paused
Wei Jiaf01e3122018-10-18 11:49:44 -07001506 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia083e9092018-02-12 11:46:04 -08001507
Wei Jia53692fa2017-12-11 10:33:46 -08001508 mDeferredActions.push_back(
1509 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1510 FLUSH_CMD_FLUSH /* video */));
1511
1512 mDeferredActions.push_back(
1513 new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
1514
1515 // After a flush without shutdown, decoder is paused.
1516 // Don't resume it until source seek is done, otherwise it could
1517 // start pulling stale data too soon.
1518 mDeferredActions.push_back(
1519 new ResumeDecoderAction(needNotify));
1520
1521 processDeferredActions();
1522 break;
1523 }
1524
1525 case kWhatPause:
1526 {
Wei Jia6376cd52018-09-26 11:42:55 -07001527 if (!mStarted) {
1528 onStart(false /* play */);
1529 }
Wei Jia53692fa2017-12-11 10:33:46 -08001530 onPause();
Wei Jiaf01e3122018-10-18 11:49:44 -07001531 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001532 mPausedByClient = true;
1533 break;
1534 }
1535
1536 case kWhatSourceNotify:
1537 {
1538 onSourceNotify(msg);
1539 break;
1540 }
1541
1542 case kWhatClosedCaptionNotify:
1543 {
1544 onClosedCaptionNotify(msg);
1545 break;
1546 }
1547
1548 case kWhatPrepareDrm:
1549 {
1550 status_t status = onPrepareDrm(msg);
1551
1552 sp<AMessage> response = new AMessage;
1553 response->setInt32("status", status);
1554 sp<AReplyToken> replyID;
1555 CHECK(msg->senderAwaitsResponse(&replyID));
1556 response->postReply(replyID);
1557 break;
1558 }
1559
1560 case kWhatReleaseDrm:
1561 {
1562 status_t status = onReleaseDrm();
1563
1564 sp<AMessage> response = new AMessage;
1565 response->setInt32("status", status);
1566 sp<AReplyToken> replyID;
1567 CHECK(msg->senderAwaitsResponse(&replyID));
1568 response->postReply(replyID);
1569 break;
1570 }
1571
1572 default:
1573 TRESPASS();
1574 break;
1575 }
1576}
1577
1578void NuPlayer2::onResume() {
1579 if (!mPaused || mResetting) {
1580 ALOGD_IF(mResetting, "resetting, onResume discarded");
1581 return;
1582 }
1583 mPaused = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001584 if (mCurrentSourceInfo.mSource != NULL) {
1585 mCurrentSourceInfo.mSource->resume();
Wei Jia53692fa2017-12-11 10:33:46 -08001586 } else {
1587 ALOGW("resume called when source is gone or not set");
1588 }
1589 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1590 // needed.
1591 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1592 instantiateDecoder(true /* audio */, &mAudioDecoder);
1593 }
1594 if (mRenderer != NULL) {
1595 mRenderer->resume();
1596 } else {
1597 ALOGW("resume called when renderer is gone or not set");
1598 }
1599
1600 startPlaybackTimer("onresume");
1601}
1602
Wei Jia6376cd52018-09-26 11:42:55 -07001603void NuPlayer2::onStart(bool play) {
Wei Jia53692fa2017-12-11 10:33:46 -08001604 ALOGV("onStart: mCrypto: %p", mCrypto.get());
1605
1606 if (!mSourceStarted) {
1607 mSourceStarted = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001608 mCurrentSourceInfo.mSource->start();
Wei Jia53692fa2017-12-11 10:33:46 -08001609 }
Wei Jia53692fa2017-12-11 10:33:46 -08001610
1611 mOffloadAudio = false;
1612 mAudioEOS = false;
1613 mVideoEOS = false;
1614 mStarted = true;
1615 mPaused = false;
1616
1617 uint32_t flags = 0;
1618
Wei Jiaf01e3122018-10-18 11:49:44 -07001619 if (mCurrentSourceInfo.mSource->isRealTime()) {
Wei Jia53692fa2017-12-11 10:33:46 -08001620 flags |= Renderer::FLAG_REAL_TIME;
1621 }
1622
Wei Jiaf01e3122018-10-18 11:49:44 -07001623 bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
1624 bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08001625 if (!hasAudio && !hasVideo) {
1626 ALOGE("no metadata for either audio or video source");
Wei Jiaf01e3122018-10-18 11:49:44 -07001627 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001628 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001629 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
1630 MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
Wei Jia53692fa2017-12-11 10:33:46 -08001631 return;
1632 }
1633 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
1634
Wei Jiaf01e3122018-10-18 11:49:44 -07001635 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001636
1637 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1638 if (mAudioSink != NULL) {
1639 streamType = mAudioSink->getAudioStreamType();
1640 }
1641
1642 mOffloadAudio =
Wei Jiaf01e3122018-10-18 11:49:44 -07001643 canOffloadStream(audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001644 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1645
1646 // Modular DRM: Disabling audio offload if the source is protected
1647 if (mOffloadAudio && mIsDrmProtected) {
1648 mOffloadAudio = false;
1649 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1650 }
1651
1652 if (mOffloadAudio) {
1653 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1654 }
1655
1656 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1657 ++mRendererGeneration;
1658 notify->setInt32("generation", mRendererGeneration);
1659 mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1660 mRendererLooper = new ALooper;
1661 mRendererLooper->setName("NuPlayerRenderer");
1662 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1663 mRendererLooper->registerHandler(mRenderer);
1664
1665 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1666 if (err != OK) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001667 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08001668 mSourceStarted = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07001669 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
Wei Jia53692fa2017-12-11 10:33:46 -08001670 return;
1671 }
1672
1673 float rate = getFrameRate();
1674 if (rate > 0) {
1675 mRenderer->setVideoFrameRate(rate);
1676 }
1677
Wei Jia6376cd52018-09-26 11:42:55 -07001678 // Renderer is created in paused state.
1679 if (play) {
1680 mRenderer->resume();
1681 }
1682
Wei Jia53692fa2017-12-11 10:33:46 -08001683 if (mVideoDecoder != NULL) {
1684 mVideoDecoder->setRenderer(mRenderer);
1685 }
1686 if (mAudioDecoder != NULL) {
1687 mAudioDecoder->setRenderer(mRenderer);
1688 }
1689
1690 startPlaybackTimer("onstart");
Wei Jiaf01e3122018-10-18 11:49:44 -07001691 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08001692
1693 postScanSources();
1694}
1695
1696void NuPlayer2::startPlaybackTimer(const char *where) {
1697 Mutex::Autolock autoLock(mPlayingTimeLock);
1698 if (mLastStartedPlayingTimeNs == 0) {
1699 mLastStartedPlayingTimeNs = systemTime();
1700 ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1701 }
1702}
1703
1704void NuPlayer2::stopPlaybackTimer(const char *where) {
1705 Mutex::Autolock autoLock(mPlayingTimeLock);
1706
1707 ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
1708
1709 if (mLastStartedPlayingTimeNs != 0) {
1710 sp<NuPlayer2Driver> driver = mDriver.promote();
1711 if (driver != NULL) {
1712 int64_t now = systemTime();
1713 int64_t played = now - mLastStartedPlayingTimeNs;
1714 ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
1715
1716 if (played > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001717 driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001718 }
1719 }
1720 mLastStartedPlayingTimeNs = 0;
1721 }
1722}
1723
1724void NuPlayer2::startRebufferingTimer() {
1725 Mutex::Autolock autoLock(mPlayingTimeLock);
1726 if (mLastStartedRebufferingTimeNs == 0) {
1727 mLastStartedRebufferingTimeNs = systemTime();
1728 ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
1729 }
1730}
1731
1732void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
1733 Mutex::Autolock autoLock(mPlayingTimeLock);
1734
Wei Jiaf01e3122018-10-18 11:49:44 -07001735 ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
1736 mLastStartedRebufferingTimeNs, exitingPlayback);
Wei Jia53692fa2017-12-11 10:33:46 -08001737
1738 if (mLastStartedRebufferingTimeNs != 0) {
1739 sp<NuPlayer2Driver> driver = mDriver.promote();
1740 if (driver != NULL) {
1741 int64_t now = systemTime();
1742 int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1743 ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
1744
1745 if (rebuffered > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001746 driver->notifyMoreRebufferingTimeUs(
1747 mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
Wei Jia53692fa2017-12-11 10:33:46 -08001748 if (exitingPlayback) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001749 driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
Wei Jia53692fa2017-12-11 10:33:46 -08001750 }
1751 }
1752 }
1753 mLastStartedRebufferingTimeNs = 0;
1754 }
1755}
1756
1757void NuPlayer2::onPause() {
1758
1759 stopPlaybackTimer("onPause");
1760
1761 if (mPaused) {
1762 return;
1763 }
1764 mPaused = true;
Wei Jiaf01e3122018-10-18 11:49:44 -07001765 if (mCurrentSourceInfo.mSource != NULL) {
1766 mCurrentSourceInfo.mSource->pause();
Wei Jia53692fa2017-12-11 10:33:46 -08001767 } else {
1768 ALOGW("pause called when source is gone or not set");
1769 }
1770 if (mRenderer != NULL) {
1771 mRenderer->pause();
1772 } else {
1773 ALOGW("pause called when renderer is gone or not set");
1774 }
1775
1776}
1777
1778bool NuPlayer2::audioDecoderStillNeeded() {
1779 // Audio decoder is no longer needed if it's in shut/shutting down status.
1780 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1781}
1782
1783void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
1784 // We wait for both the decoder flush and the renderer flush to complete
1785 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1786
1787 mFlushComplete[audio][isDecoder] = true;
1788 if (!mFlushComplete[audio][!isDecoder]) {
1789 return;
1790 }
1791
1792 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1793 switch (*state) {
1794 case FLUSHING_DECODER:
1795 {
1796 *state = FLUSHED;
1797 break;
1798 }
1799
1800 case FLUSHING_DECODER_SHUTDOWN:
1801 {
1802 *state = SHUTTING_DOWN_DECODER;
1803
1804 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1805 getDecoder(audio)->initiateShutdown();
1806 break;
1807 }
1808
1809 default:
1810 // decoder flush completes only occur in a flushing state.
1811 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1812 break;
1813 }
1814}
1815
1816void NuPlayer2::finishFlushIfPossible() {
1817 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1818 && mFlushingAudio != SHUT_DOWN) {
1819 return;
1820 }
1821
1822 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1823 && mFlushingVideo != SHUT_DOWN) {
1824 return;
1825 }
1826
1827 ALOGV("both audio and video are flushed now.");
1828
1829 mFlushingAudio = NONE;
1830 mFlushingVideo = NONE;
1831
1832 clearFlushComplete();
1833
1834 processDeferredActions();
1835}
1836
1837void NuPlayer2::postScanSources() {
1838 if (mScanSourcesPending) {
1839 return;
1840 }
1841
1842 sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1843 msg->setInt32("generation", mScanSourcesGeneration);
1844 msg->post();
1845
1846 mScanSourcesPending = true;
1847}
1848
1849void NuPlayer2::tryOpenAudioSinkForOffload(
1850 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1851 // Note: This is called early in NuPlayer2 to determine whether offloading
1852 // is possible; otherwise the decoders call the renderer openAudioSink directly.
1853
1854 status_t err = mRenderer->openAudioSink(
1855 format, true /* offloadOnly */, hasVideo,
Wei Jiaf01e3122018-10-18 11:49:44 -07001856 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
Wei Jia53692fa2017-12-11 10:33:46 -08001857 if (err != OK) {
1858 // Any failure we turn off mOffloadAudio.
1859 mOffloadAudio = false;
1860 } else if (mOffloadAudio) {
1861 sendMetaDataToHal(mAudioSink, audioMeta);
1862 }
1863}
1864
1865void NuPlayer2::closeAudioSink() {
1866 mRenderer->closeAudioSink();
1867}
1868
1869void NuPlayer2::restartAudio(
1870 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1871 if (mAudioDecoder != NULL) {
1872 mAudioDecoder->pause();
1873 mAudioDecoder.clear();
1874 mAudioDecoderError = false;
1875 ++mAudioDecoderGeneration;
1876 }
1877 if (mFlushingAudio == FLUSHING_DECODER) {
1878 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1879 mFlushingAudio = FLUSHED;
1880 finishFlushIfPossible();
1881 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1882 || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1883 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1884 mFlushingAudio = SHUT_DOWN;
1885 finishFlushIfPossible();
1886 needsToCreateAudioDecoder = false;
1887 }
1888 if (mRenderer == NULL) {
1889 return;
1890 }
1891 closeAudioSink();
1892 mRenderer->flush(true /* audio */, false /* notifyComplete */);
1893 if (mVideoDecoder != NULL) {
1894 mRenderer->flush(false /* audio */, false /* notifyComplete */);
1895 }
1896
1897 performSeek(currentPositionUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1898
1899 if (forceNonOffload) {
1900 mRenderer->signalDisableOffloadAudio();
1901 mOffloadAudio = false;
1902 }
1903 if (needsToCreateAudioDecoder) {
1904 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1905 }
1906}
1907
1908void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
Wei Jiaf01e3122018-10-18 11:49:44 -07001909 if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08001910 return;
1911 }
1912
1913 if (mRenderer == NULL) {
1914 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1915 mOffloadAudio = false;
1916 return;
1917 }
1918
Wei Jiaf01e3122018-10-18 11:49:44 -07001919 sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
1920 sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08001921 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1922 const bool hasVideo = (videoFormat != NULL);
1923 bool canOffload = canOffloadStream(
Wei Jiaf01e3122018-10-18 11:49:44 -07001924 audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
Wei Jia53692fa2017-12-11 10:33:46 -08001925 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1926
1927 // Modular DRM: Disabling audio offload if the source is protected
1928 if (canOffload && mIsDrmProtected) {
1929 canOffload = false;
1930 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1931 }
1932
1933 if (canOffload) {
1934 if (!mOffloadAudio) {
1935 mRenderer->signalEnableOffloadAudio();
1936 }
1937 // open audio sink early under offload mode.
1938 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
1939 } else {
1940 if (mOffloadAudio) {
1941 mRenderer->signalDisableOffloadAudio();
1942 mOffloadAudio = false;
1943 }
1944 }
1945}
1946
1947status_t NuPlayer2::instantiateDecoder(
1948 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
1949 // The audio decoder could be cleared by tear down. If still in shut down
1950 // process, no need to create a new audio decoder.
1951 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
1952 return OK;
1953 }
1954
Wei Jiaf01e3122018-10-18 11:49:44 -07001955 sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
Wei Jia53692fa2017-12-11 10:33:46 -08001956
1957 if (format == NULL) {
1958 return UNKNOWN_ERROR;
1959 } else {
1960 status_t err;
1961 if (format->findInt32("err", &err) && err) {
1962 return err;
1963 }
1964 }
1965
1966 format->setInt32("priority", 0 /* realtime */);
1967
1968 if (!audio) {
1969 AString mime;
1970 CHECK(format->findString("mime", &mime));
1971
1972 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
1973 if (mCCDecoder == NULL) {
1974 mCCDecoder = new CCDecoder(ccNotify);
1975 }
1976
Wei Jiaf01e3122018-10-18 11:49:44 -07001977 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
Wei Jia53692fa2017-12-11 10:33:46 -08001978 format->setInt32("secure", true);
1979 }
1980
Wei Jiaf01e3122018-10-18 11:49:44 -07001981 if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
Wei Jia53692fa2017-12-11 10:33:46 -08001982 format->setInt32("protected", true);
1983 }
1984
1985 float rate = getFrameRate();
1986 if (rate > 0) {
1987 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
1988 }
1989 }
1990
1991 if (audio) {
1992 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1993 ++mAudioDecoderGeneration;
1994 notify->setInt32("generation", mAudioDecoderGeneration);
1995
1996 if (checkAudioModeChange) {
1997 determineAudioModeChange(format);
1998 }
1999 if (mOffloadAudio) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002000 mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002001
Wei Jiaf01e3122018-10-18 11:49:44 -07002002 const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
Wei Jia53692fa2017-12-11 10:33:46 -08002003 format->setInt32("has-video", hasVideo);
Wei Jiaf01e3122018-10-18 11:49:44 -07002004 *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002005 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2006 } else {
Wei Jiaf01e3122018-10-18 11:49:44 -07002007 mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
Wei Jia53692fa2017-12-11 10:33:46 -08002008
Wei Jiaf01e3122018-10-18 11:49:44 -07002009 *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
Wei Jia53692fa2017-12-11 10:33:46 -08002010 ALOGV("instantiateDecoder audio Decoder");
2011 }
2012 mAudioDecoderError = false;
2013 } else {
2014 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2015 ++mVideoDecoderGeneration;
2016 notify->setInt32("generation", mVideoDecoderGeneration);
2017
2018 *decoder = new Decoder(
Wei Jiaf01e3122018-10-18 11:49:44 -07002019 notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
2020 mCCDecoder);
Wei Jia53692fa2017-12-11 10:33:46 -08002021 mVideoDecoderError = false;
2022
2023 // enable FRC if high-quality AV sync is requested, even if not
2024 // directly queuing to display, as this will even improve textureview
2025 // playback.
2026 {
2027 if (property_get_bool("persist.sys.media.avsync", false)) {
2028 format->setInt32("auto-frc", 1);
2029 }
2030 }
2031 }
2032 (*decoder)->init();
2033
2034 // Modular DRM
2035 if (mIsDrmProtected) {
2036 format->setObject("crypto", mCrypto);
Wei Jiaf01e3122018-10-18 11:49:44 -07002037 ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
2038 mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002039 }
2040
2041 (*decoder)->configure(format);
2042
2043 if (!audio) {
2044 sp<AMessage> params = new AMessage();
2045 float rate = getFrameRate();
2046 if (rate > 0) {
2047 params->setFloat("frame-rate-total", rate);
2048 }
2049
2050 sp<MetaData> fileMeta = getFileMeta();
2051 if (fileMeta != NULL) {
2052 int32_t videoTemporalLayerCount;
2053 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2054 && videoTemporalLayerCount > 0) {
2055 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2056 }
2057 }
2058
2059 if (params->countEntries() > 0) {
2060 (*decoder)->setParameters(params);
2061 }
2062 }
2063 return OK;
2064}
2065
2066void NuPlayer2::updateVideoSize(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002067 int64_t srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002068 const sp<AMessage> &inputFormat,
2069 const sp<AMessage> &outputFormat) {
2070 if (inputFormat == NULL) {
2071 ALOGW("Unknown video size, reporting 0x0!");
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002072 notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002073 return;
2074 }
2075 int32_t err = OK;
2076 inputFormat->findInt32("err", &err);
2077 if (err == -EWOULDBLOCK) {
2078 ALOGW("Video meta is not available yet!");
2079 return;
2080 }
2081 if (err != OK) {
2082 ALOGW("Something is wrong with video meta!");
2083 return;
2084 }
2085
2086 int32_t displayWidth, displayHeight;
2087 if (outputFormat != NULL) {
2088 int32_t width, height;
2089 CHECK(outputFormat->findInt32("width", &width));
2090 CHECK(outputFormat->findInt32("height", &height));
2091
2092 int32_t cropLeft, cropTop, cropRight, cropBottom;
2093 CHECK(outputFormat->findRect(
2094 "crop",
2095 &cropLeft, &cropTop, &cropRight, &cropBottom));
2096
2097 displayWidth = cropRight - cropLeft + 1;
2098 displayHeight = cropBottom - cropTop + 1;
2099
2100 ALOGV("Video output format changed to %d x %d "
2101 "(crop: %d x %d @ (%d, %d))",
2102 width, height,
2103 displayWidth,
2104 displayHeight,
2105 cropLeft, cropTop);
2106 } else {
2107 CHECK(inputFormat->findInt32("width", &displayWidth));
2108 CHECK(inputFormat->findInt32("height", &displayHeight));
2109
2110 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2111 }
2112
2113 // Take into account sample aspect ratio if necessary:
2114 int32_t sarWidth, sarHeight;
2115 if (inputFormat->findInt32("sar-width", &sarWidth)
2116 && inputFormat->findInt32("sar-height", &sarHeight)
2117 && sarWidth > 0 && sarHeight > 0) {
2118 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2119
2120 displayWidth = (displayWidth * sarWidth) / sarHeight;
2121
2122 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2123 } else {
2124 int32_t width, height;
2125 if (inputFormat->findInt32("display-width", &width)
2126 && inputFormat->findInt32("display-height", &height)
2127 && width > 0 && height > 0
2128 && displayWidth > 0 && displayHeight > 0) {
2129 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2130 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2131 } else {
2132 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2133 }
2134 ALOGV("Video display width and height are overridden to %d x %d",
2135 displayWidth, displayHeight);
2136 }
2137 }
2138
2139 int32_t rotationDegrees;
2140 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2141 rotationDegrees = 0;
2142 }
2143
2144 if (rotationDegrees == 90 || rotationDegrees == 270) {
2145 int32_t tmp = displayWidth;
2146 displayWidth = displayHeight;
2147 displayHeight = tmp;
2148 }
2149
2150 notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002151 srcId,
Wei Jia53692fa2017-12-11 10:33:46 -08002152 MEDIA2_SET_VIDEO_SIZE,
2153 displayWidth,
2154 displayHeight);
2155}
2156
Dongwon Kang41929fb2018-09-09 08:29:56 -07002157void NuPlayer2::notifyListener(
2158 int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
Wei Jia53692fa2017-12-11 10:33:46 -08002159 if (mDriver == NULL) {
2160 return;
2161 }
2162
2163 sp<NuPlayer2Driver> driver = mDriver.promote();
2164
2165 if (driver == NULL) {
2166 return;
2167 }
2168
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002169 driver->notifyListener(srcId, msg, ext1, ext2, in);
Wei Jia53692fa2017-12-11 10:33:46 -08002170}
2171
2172void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
2173 ALOGV("[%s] flushDecoder needShutdown=%d",
2174 audio ? "audio" : "video", needShutdown);
2175
2176 const sp<DecoderBase> &decoder = getDecoder(audio);
2177 if (decoder == NULL) {
2178 ALOGI("flushDecoder %s without decoder present",
2179 audio ? "audio" : "video");
2180 return;
2181 }
2182
2183 // Make sure we don't continue to scan sources until we finish flushing.
2184 ++mScanSourcesGeneration;
2185 if (mScanSourcesPending) {
2186 if (!needShutdown) {
2187 mDeferredActions.push_back(
2188 new SimpleAction(&NuPlayer2::performScanSources));
2189 }
2190 mScanSourcesPending = false;
2191 }
2192
2193 decoder->signalFlush();
2194
2195 FlushStatus newStatus =
2196 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2197
2198 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2199 mFlushComplete[audio][true /* isDecoder */] = false;
2200 if (audio) {
2201 ALOGE_IF(mFlushingAudio != NONE,
2202 "audio flushDecoder() is called in state %d", mFlushingAudio);
2203 mFlushingAudio = newStatus;
2204 } else {
2205 ALOGE_IF(mFlushingVideo != NONE,
2206 "video flushDecoder() is called in state %d", mFlushingVideo);
2207 mFlushingVideo = newStatus;
2208 }
2209}
2210
2211void NuPlayer2::queueDecoderShutdown(
2212 bool audio, bool video, const sp<AMessage> &reply) {
2213 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2214
2215 mDeferredActions.push_back(
2216 new FlushDecoderAction(
2217 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2218 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2219
2220 mDeferredActions.push_back(
2221 new SimpleAction(&NuPlayer2::performScanSources));
2222
2223 mDeferredActions.push_back(new PostMessageAction(reply));
2224
2225 processDeferredActions();
2226}
2227
2228status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
2229 mVideoScalingMode = mode;
Wei Jia28288fb2017-12-15 13:45:29 -08002230 if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
2231 status_t ret = native_window_set_scaling_mode(
2232 mNativeWindow->getANativeWindow(), mVideoScalingMode);
Wei Jia53692fa2017-12-11 10:33:46 -08002233 if (ret != OK) {
2234 ALOGE("Failed to set scaling mode (%d): %s",
2235 -ret, strerror(-ret));
2236 return ret;
2237 }
2238 }
2239 return OK;
2240}
2241
Dongwon Kang9f631982018-07-10 12:34:41 -07002242status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002243 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2244 msg->setPointer("reply", reply);
2245
2246 sp<AMessage> response;
2247 status_t err = msg->postAndAwaitResponse(&response);
2248 return err;
2249}
2250
Dongwon Kang9f631982018-07-10 12:34:41 -07002251status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
Wei Jia53692fa2017-12-11 10:33:46 -08002252 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2253 msg->setPointer("reply", reply);
2254 msg->setInt32("type", type);
2255
2256 sp<AMessage> response;
2257 status_t err = msg->postAndAwaitResponse(&response);
2258 if (err == OK && response != NULL) {
2259 CHECK(response->findInt32("err", &err));
2260 }
2261 return err;
2262}
2263
2264status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2265 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2266 msg->setSize("trackIndex", trackIndex);
2267 msg->setInt32("select", select);
2268 msg->setInt64("timeUs", timeUs);
2269
2270 sp<AMessage> response;
2271 status_t err = msg->postAndAwaitResponse(&response);
2272
2273 if (err != OK) {
2274 return err;
2275 }
2276
2277 if (!response->findInt32("err", &err)) {
2278 err = OK;
2279 }
2280
2281 return err;
2282}
2283
2284status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
2285 sp<Renderer> renderer = mRenderer;
2286 if (renderer == NULL) {
2287 return NO_INIT;
2288 }
2289
2290 return renderer->getCurrentPosition(mediaUs);
2291}
2292
2293void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
2294 CHECK(mTrackStats != NULL);
2295
2296 mTrackStats->clear();
2297 if (mVideoDecoder != NULL) {
2298 mTrackStats->push_back(mVideoDecoder->getStats());
2299 }
2300 if (mAudioDecoder != NULL) {
2301 mTrackStats->push_back(mAudioDecoder->getStats());
2302 }
2303}
2304
2305sp<MetaData> NuPlayer2::getFileMeta() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002306 return mCurrentSourceInfo.mSource->getFileFormatMeta();
Wei Jia53692fa2017-12-11 10:33:46 -08002307}
2308
2309float NuPlayer2::getFrameRate() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002310 sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
Wei Jia53692fa2017-12-11 10:33:46 -08002311 if (meta == NULL) {
2312 return 0;
2313 }
2314 int32_t rate;
2315 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2316 // fall back to try file meta
2317 sp<MetaData> fileMeta = getFileMeta();
2318 if (fileMeta == NULL) {
2319 ALOGW("source has video meta but not file meta");
2320 return -1;
2321 }
2322 int32_t fileMetaRate;
2323 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2324 return -1;
2325 }
2326 return fileMetaRate;
2327 }
2328 return rate;
2329}
2330
2331void NuPlayer2::schedulePollDuration() {
2332 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2333 msg->setInt32("generation", mPollDurationGeneration);
2334 msg->post();
2335}
2336
2337void NuPlayer2::cancelPollDuration() {
2338 ++mPollDurationGeneration;
2339}
2340
2341void NuPlayer2::processDeferredActions() {
2342 while (!mDeferredActions.empty()) {
2343 // We won't execute any deferred actions until we're no longer in
2344 // an intermediate state, i.e. one more more decoders are currently
2345 // flushing or shutting down.
2346
2347 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2348 // We're currently flushing, postpone the reset until that's
2349 // completed.
2350
2351 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2352 mFlushingAudio, mFlushingVideo);
2353
2354 break;
2355 }
2356
2357 sp<Action> action = *mDeferredActions.begin();
2358 mDeferredActions.erase(mDeferredActions.begin());
2359
2360 action->execute(this);
2361 }
2362}
2363
2364void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
2365 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2366 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2367
Wei Jiaf01e3122018-10-18 11:49:44 -07002368 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002369 // This happens when reset occurs right before the loop mode
2370 // asynchronously seeks to the start of the stream.
2371 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
Wei Jiaf01e3122018-10-18 11:49:44 -07002372 "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
Wei Jia53692fa2017-12-11 10:33:46 -08002373 mAudioDecoder.get(), mVideoDecoder.get());
2374 return;
2375 }
2376 mPreviousSeekTimeUs = seekTimeUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002377 mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
Wei Jia53692fa2017-12-11 10:33:46 -08002378 ++mTimedTextGeneration;
2379
2380 // everything's flushed, continue playback.
2381}
2382
2383void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2384 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2385
2386 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2387 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2388 return;
2389 }
2390
2391 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2392 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2393 }
2394
2395 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2396 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2397 }
2398}
2399
2400void NuPlayer2::performReset() {
2401 ALOGV("performReset");
2402
2403 CHECK(mAudioDecoder == NULL);
2404 CHECK(mVideoDecoder == NULL);
2405
2406 stopPlaybackTimer("performReset");
2407 stopRebufferingTimer(true);
2408
2409 cancelPollDuration();
2410
2411 ++mScanSourcesGeneration;
2412 mScanSourcesPending = false;
2413
2414 if (mRendererLooper != NULL) {
2415 if (mRenderer != NULL) {
2416 mRendererLooper->unregisterHandler(mRenderer->id());
2417 }
2418 mRendererLooper->stop();
2419 mRendererLooper.clear();
2420 }
2421 mRenderer.clear();
2422 ++mRendererGeneration;
2423
Wei Jiaf01e3122018-10-18 11:49:44 -07002424 if (mCurrentSourceInfo.mSource != NULL) {
2425 mCurrentSourceInfo.mSource->stop();
Wei Jia53692fa2017-12-11 10:33:46 -08002426
2427 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002428 mCurrentSourceInfo.mSource.clear();
Wei Jia53692fa2017-12-11 10:33:46 -08002429 }
2430
2431 if (mDriver != NULL) {
2432 sp<NuPlayer2Driver> driver = mDriver.promote();
2433 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002434 driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002435 }
2436 }
2437
2438 mStarted = false;
2439 mPrepared = false;
2440 mResetting = false;
2441 mSourceStarted = false;
2442
2443 // Modular DRM
2444 if (mCrypto != NULL) {
2445 // decoders will be flushed before this so their mCrypto would go away on their own
2446 // TODO change to ALOGV
2447 ALOGD("performReset mCrypto: %p", mCrypto.get());
2448 mCrypto.clear();
2449 }
2450 mIsDrmProtected = false;
2451}
2452
Wei Jia57aeffd2018-02-15 16:01:14 -08002453void NuPlayer2::performPlayNextDataSource() {
2454 ALOGV("performPlayNextDataSource");
2455
2456 CHECK(mAudioDecoder == NULL);
2457 CHECK(mVideoDecoder == NULL);
2458
2459 stopPlaybackTimer("performPlayNextDataSource");
2460 stopRebufferingTimer(true);
2461
2462 cancelPollDuration();
2463
2464 ++mScanSourcesGeneration;
2465 mScanSourcesPending = false;
2466
2467 ++mRendererGeneration;
2468
Wei Jiaf01e3122018-10-18 11:49:44 -07002469 if (mCurrentSourceInfo.mSource != NULL) {
2470 mCurrentSourceInfo.mSource->stop();
Wei Jia57aeffd2018-02-15 16:01:14 -08002471 }
2472
2473 long previousSrcId;
2474 {
2475 Mutex::Autolock autoLock(mSourceLock);
Wei Jiaf01e3122018-10-18 11:49:44 -07002476 mCurrentSourceInfo.mSource = mNextSourceInfo.mSource;
2477 mNextSourceInfo.mSource = NULL;
2478 previousSrcId = mCurrentSourceInfo.mSrcId;
2479 mCurrentSourceInfo.mSrcId = mNextSourceInfo.mSrcId;
2480 ++mNextSourceInfo.mSrcId; // to distinguish the two sources.
Wei Jia57aeffd2018-02-15 16:01:14 -08002481 }
2482
2483 if (mDriver != NULL) {
2484 sp<NuPlayer2Driver> driver = mDriver.promote();
2485 if (driver != NULL) {
Wei Jiacad5a3a2018-07-31 17:03:56 -07002486 notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
Wei Jiaf01e3122018-10-18 11:49:44 -07002487 notifyListener(
2488 mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002489 }
2490 }
2491
2492 mStarted = false;
2493 mPrepared = true; // TODO: what if it's not prepared
2494 mResetting = false;
2495 mSourceStarted = false;
2496
2497 // Modular DRM
2498 if (mCrypto != NULL) {
2499 // decoders will be flushed before this so their mCrypto would go away on their own
2500 // TODO change to ALOGV
2501 ALOGD("performReset mCrypto: %p", mCrypto.get());
2502 mCrypto.clear();
2503 }
2504 mIsDrmProtected = false;
2505
2506 if (mRenderer != NULL) {
2507 mRenderer->resume();
2508 }
2509
Wei Jia6376cd52018-09-26 11:42:55 -07002510 onStart(true /* play */);
Wei Jia57aeffd2018-02-15 16:01:14 -08002511 mPausedByClient = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002512 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
Wei Jia57aeffd2018-02-15 16:01:14 -08002513}
2514
Wei Jia53692fa2017-12-11 10:33:46 -08002515void NuPlayer2::performScanSources() {
2516 ALOGV("performScanSources");
2517
2518 if (!mStarted) {
2519 return;
2520 }
2521
2522 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2523 postScanSources();
2524 }
2525}
2526
Wei Jia28288fb2017-12-15 13:45:29 -08002527void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
Wei Jia53692fa2017-12-11 10:33:46 -08002528 ALOGV("performSetSurface");
2529
Wei Jia28288fb2017-12-15 13:45:29 -08002530 mNativeWindow = nww;
Wei Jia53692fa2017-12-11 10:33:46 -08002531
2532 // XXX - ignore error from setVideoScalingMode for now
2533 setVideoScalingMode(mVideoScalingMode);
2534
2535 if (mDriver != NULL) {
2536 sp<NuPlayer2Driver> driver = mDriver.promote();
2537 if (driver != NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002538 driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002539 }
2540 }
2541}
2542
2543void NuPlayer2::performResumeDecoders(bool needNotify) {
2544 if (needNotify) {
2545 mResumePending = true;
2546 if (mVideoDecoder == NULL) {
2547 // if audio-only, we can notify seek complete now,
2548 // as the resume operation will be relatively fast.
2549 finishResume();
2550 }
2551 }
2552
2553 if (mVideoDecoder != NULL) {
2554 // When there is continuous seek, MediaPlayer will cache the seek
2555 // position, and send down new seek request when previous seek is
2556 // complete. Let's wait for at least one video output frame before
2557 // notifying seek complete, so that the video thumbnail gets updated
2558 // when seekbar is dragged.
2559 mVideoDecoder->signalResume(needNotify);
2560 }
2561
2562 if (mAudioDecoder != NULL) {
2563 mAudioDecoder->signalResume(false /* needNotify */);
2564 }
2565}
2566
2567void NuPlayer2::finishResume() {
2568 if (mResumePending) {
2569 mResumePending = false;
Wei Jiaf01e3122018-10-18 11:49:44 -07002570 notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002571 }
2572}
2573
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002574void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
Wei Jia53692fa2017-12-11 10:33:46 -08002575 if (mDriver != NULL) {
2576 sp<NuPlayer2Driver> driver = mDriver.promote();
2577 if (driver != NULL) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002578 driver->notifySeekComplete(srcId);
Wei Jia53692fa2017-12-11 10:33:46 -08002579 }
2580 }
2581}
2582
2583void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
2584 int32_t what;
2585 CHECK(msg->findInt32("what", &what));
2586
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002587 int64_t srcId;
2588 CHECK(msg->findInt64("srcId", &srcId));
Wei Jia53692fa2017-12-11 10:33:46 -08002589 switch (what) {
Wei Jia53692fa2017-12-11 10:33:46 -08002590 case Source::kWhatPrepared:
2591 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002592 ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p",
2593 mCurrentSourceInfo.mSource.get());
2594 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002595 // This is a stale notification from a source that was
2596 // asynchronously preparing when the client called reset().
2597 // We handled the reset, the source is gone.
2598 break;
2599 }
2600
2601 int32_t err;
2602 CHECK(msg->findInt32("err", &err));
2603
2604 if (err != OK) {
2605 // shut down potential secure codecs in case client never calls reset
2606 mDeferredActions.push_back(
2607 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2608 FLUSH_CMD_SHUTDOWN /* video */));
2609 processDeferredActions();
2610 } else {
2611 mPrepared = true;
2612 }
2613
2614 sp<NuPlayer2Driver> driver = mDriver.promote();
2615 if (driver != NULL) {
2616 // notify duration first, so that it's definitely set when
2617 // the app received the "prepare complete" callback.
2618 int64_t durationUs;
Wei Jiaf01e3122018-10-18 11:49:44 -07002619 if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002620 driver->notifyDuration(srcId, durationUs);
Wei Jia53692fa2017-12-11 10:33:46 -08002621 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002622 driver->notifyPrepareCompleted(srcId, err);
Wei Jia53692fa2017-12-11 10:33:46 -08002623 }
2624
2625 break;
2626 }
2627
2628 // Modular DRM
2629 case Source::kWhatDrmInfo:
2630 {
Dongwon Kang41929fb2018-09-09 08:29:56 -07002631 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002632 sp<ABuffer> drmInfo;
2633 CHECK(msg->findBuffer("drmInfo", &drmInfo));
Dongwon Kang41929fb2018-09-09 08:29:56 -07002634 playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002635
Dongwon Kang41929fb2018-09-09 08:29:56 -07002636 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p playerMsg size: %d",
2637 drmInfo.get(), playerMsg.ByteSize());
Wei Jia53692fa2017-12-11 10:33:46 -08002638
Dongwon Kang41929fb2018-09-09 08:29:56 -07002639 notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002640
2641 break;
2642 }
2643
2644 case Source::kWhatFlagsChanged:
2645 {
2646 uint32_t flags;
2647 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2648
2649 sp<NuPlayer2Driver> driver = mDriver.promote();
2650 if (driver != NULL) {
2651
2652 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2653 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2654 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2655 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2656 (flags & Source::FLAG_CAN_PAUSE) != 0,
2657 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2658 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2659 (flags & Source::FLAG_CAN_SEEK) != 0,
2660 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2661 (flags & Source::FLAG_SECURE) != 0,
2662 (flags & Source::FLAG_PROTECTED) != 0);
2663
2664 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
2665 driver->notifyListener(
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002666 srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002667 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002668 driver->notifyFlagsChanged(srcId, flags);
Wei Jia53692fa2017-12-11 10:33:46 -08002669 }
2670
Wei Jiaf01e3122018-10-18 11:49:44 -07002671 if (srcId == mCurrentSourceInfo.mSrcId) {
2672 if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2673 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2674 cancelPollDuration();
2675 } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2676 && (flags & Source::FLAG_DYNAMIC_DURATION)
2677 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2678 schedulePollDuration();
2679 }
Wei Jia53692fa2017-12-11 10:33:46 -08002680
Wei Jiaf01e3122018-10-18 11:49:44 -07002681 mCurrentSourceInfo.mSourceFlags = flags;
2682 } else if (srcId == mNextSourceInfo.mSrcId) {
2683 // TODO: handle duration polling for next source.
2684 mNextSourceInfo.mSourceFlags = flags;
2685 }
Wei Jia53692fa2017-12-11 10:33:46 -08002686 break;
2687 }
2688
2689 case Source::kWhatVideoSizeChanged:
2690 {
2691 sp<AMessage> format;
2692 CHECK(msg->findMessage("format", &format));
2693
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002694 updateVideoSize(srcId, format);
Wei Jia53692fa2017-12-11 10:33:46 -08002695 break;
2696 }
2697
2698 case Source::kWhatBufferingUpdate:
2699 {
2700 int32_t percentage;
2701 CHECK(msg->findInt32("percentage", &percentage));
2702
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002703 notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002704 break;
2705 }
2706
2707 case Source::kWhatPauseOnBufferingStart:
2708 {
2709 // ignore if not playing
2710 if (mStarted) {
2711 ALOGI("buffer low, pausing...");
2712
2713 startRebufferingTimer();
2714 mPausedForBuffering = true;
2715 onPause();
2716 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002717 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002718 break;
2719 }
2720
2721 case Source::kWhatResumeOnBufferingEnd:
2722 {
2723 // ignore if not playing
2724 if (mStarted) {
2725 ALOGI("buffer ready, resuming...");
2726
2727 stopRebufferingTimer(false);
2728 mPausedForBuffering = false;
2729
2730 // do not resume yet if client didn't unpause
2731 if (!mPausedByClient) {
2732 onResume();
2733 }
2734 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002735 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002736 break;
2737 }
2738
2739 case Source::kWhatCacheStats:
2740 {
2741 int32_t kbps;
2742 CHECK(msg->findInt32("bandwidth", &kbps));
2743
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002744 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
Wei Jia53692fa2017-12-11 10:33:46 -08002745 break;
2746 }
2747
2748 case Source::kWhatSubtitleData:
2749 {
2750 sp<ABuffer> buffer;
2751 CHECK(msg->findBuffer("buffer", &buffer));
2752
2753 sendSubtitleData(buffer, 0 /* baseIndex */);
2754 break;
2755 }
2756
2757 case Source::kWhatTimedMetaData:
2758 {
2759 sp<ABuffer> buffer;
2760 if (!msg->findBuffer("buffer", &buffer)) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002761 notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002762 } else {
2763 sendTimedMetaData(buffer);
2764 }
2765 break;
2766 }
2767
2768 case Source::kWhatTimedTextData:
2769 {
2770 int32_t generation;
2771 if (msg->findInt32("generation", &generation)
2772 && generation != mTimedTextGeneration) {
2773 break;
2774 }
2775
2776 sp<ABuffer> buffer;
2777 CHECK(msg->findBuffer("buffer", &buffer));
2778
2779 sp<NuPlayer2Driver> driver = mDriver.promote();
2780 if (driver == NULL) {
2781 break;
2782 }
2783
Wei Jia800fe372018-02-20 15:00:45 -08002784 int64_t posMs;
Wei Jia53692fa2017-12-11 10:33:46 -08002785 int64_t timeUs, posUs;
2786 driver->getCurrentPosition(&posMs);
Wei Jia800fe372018-02-20 15:00:45 -08002787 posUs = posMs * 1000ll;
Wei Jia53692fa2017-12-11 10:33:46 -08002788 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2789
2790 if (posUs < timeUs) {
2791 if (!msg->findInt32("generation", &generation)) {
2792 msg->setInt32("generation", mTimedTextGeneration);
2793 }
2794 msg->post(timeUs - posUs);
2795 } else {
2796 sendTimedTextData(buffer);
2797 }
2798 break;
2799 }
2800
2801 case Source::kWhatQueueDecoderShutdown:
2802 {
2803 int32_t audio, video;
2804 CHECK(msg->findInt32("audio", &audio));
2805 CHECK(msg->findInt32("video", &video));
2806
2807 sp<AMessage> reply;
2808 CHECK(msg->findMessage("reply", &reply));
2809
2810 queueDecoderShutdown(audio, video, reply);
2811 break;
2812 }
2813
2814 case Source::kWhatDrmNoLicense:
2815 {
Wei Jiad2bb1bd2018-02-08 09:47:37 -08002816 notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
Wei Jia53692fa2017-12-11 10:33:46 -08002817 break;
2818 }
2819
2820 default:
2821 TRESPASS();
2822 }
2823}
2824
2825void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
2826 int32_t what;
2827 CHECK(msg->findInt32("what", &what));
2828
2829 switch (what) {
2830 case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
2831 {
2832 sp<ABuffer> buffer;
2833 CHECK(msg->findBuffer("buffer", &buffer));
2834
2835 size_t inbandTracks = 0;
Wei Jiaf01e3122018-10-18 11:49:44 -07002836 if (mCurrentSourceInfo.mSource != NULL) {
2837 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
Wei Jia53692fa2017-12-11 10:33:46 -08002838 }
2839
2840 sendSubtitleData(buffer, inbandTracks);
2841 break;
2842 }
2843
2844 case NuPlayer2::CCDecoder::kWhatTrackAdded:
2845 {
Wei Jiaf01e3122018-10-18 11:49:44 -07002846 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002847
2848 break;
2849 }
2850
2851 default:
2852 TRESPASS();
2853 }
2854
2855
2856}
2857
2858void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2859 int32_t trackIndex;
2860 int64_t timeUs, durationUs;
Robert Shihd83d4f42018-02-24 19:02:46 -08002861 CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
Wei Jia53692fa2017-12-11 10:33:46 -08002862 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2863 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2864
Dongwon Kang41929fb2018-09-09 08:29:56 -07002865 PlayerMessage playerMsg;
2866 playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
2867 playerMsg.add_values()->set_int64_value(timeUs);
2868 playerMsg.add_values()->set_int64_value(durationUs);
2869 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002870
Wei Jiaf01e3122018-10-18 11:49:44 -07002871 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002872}
2873
2874void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
2875 int64_t timeUs;
2876 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2877
Dongwon Kang41929fb2018-09-09 08:29:56 -07002878 PlayerMessage playerMsg;
2879 playerMsg.add_values()->set_int64_value(timeUs);
2880 playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
Wei Jia53692fa2017-12-11 10:33:46 -08002881
Wei Jiaf01e3122018-10-18 11:49:44 -07002882 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002883}
2884
2885void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
2886 const void *data;
2887 size_t size = 0;
2888 int64_t timeUs;
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002889 int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
Wei Jia53692fa2017-12-11 10:33:46 -08002890
2891 AString mime;
2892 CHECK(buffer->meta()->findString("mime", &mime));
2893 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2894
2895 data = buffer->data();
2896 size = buffer->size();
2897
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002898 PlayerMessage playerMsg;
Wei Jia53692fa2017-12-11 10:33:46 -08002899 if (size > 0) {
2900 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2901 int32_t global = 0;
2902 if (buffer->meta()->findInt32("global", &global) && global) {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002903 flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002904 } else {
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002905 flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
Wei Jia53692fa2017-12-11 10:33:46 -08002906 }
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002907 TextDescriptions2::getPlayerMessageOfDescriptions(
2908 (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002909 }
2910
Dongwon Kanga0e816a2018-09-10 19:46:49 -07002911 if (playerMsg.values_size() > 0) {
Wei Jiaf01e3122018-10-18 11:49:44 -07002912 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
Wei Jia53692fa2017-12-11 10:33:46 -08002913 } else { // send an empty timed text
Wei Jiaf01e3122018-10-18 11:49:44 -07002914 notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
Wei Jia53692fa2017-12-11 10:33:46 -08002915 }
2916}
2917
2918const char *NuPlayer2::getDataSourceType() {
Wei Jiaf01e3122018-10-18 11:49:44 -07002919 switch (mCurrentSourceInfo.mDataSourceType) {
Wei Jia53692fa2017-12-11 10:33:46 -08002920 case DATA_SOURCE_TYPE_HTTP_LIVE:
2921 return "HTTPLive";
2922
2923 case DATA_SOURCE_TYPE_RTSP:
2924 return "RTSP";
2925
2926 case DATA_SOURCE_TYPE_GENERIC_URL:
2927 return "GenURL";
2928
2929 case DATA_SOURCE_TYPE_GENERIC_FD:
2930 return "GenFD";
2931
2932 case DATA_SOURCE_TYPE_MEDIA:
2933 return "Media";
2934
Wei Jia53692fa2017-12-11 10:33:46 -08002935 case DATA_SOURCE_TYPE_NONE:
2936 default:
2937 return "None";
2938 }
2939 }
2940
2941// Modular DRM begin
2942status_t NuPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
2943{
2944 ALOGV("prepareDrm ");
2945
2946 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
2947 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
2948 // synchronous call so just passing the address but with local copies of "const" args
2949 uint8_t UUID[16];
2950 memcpy(UUID, uuid, sizeof(UUID));
2951 Vector<uint8_t> sessionId = drmSessionId;
2952 msg->setPointer("uuid", (void*)UUID);
2953 msg->setPointer("drmSessionId", (void*)&sessionId);
2954
2955 sp<AMessage> response;
2956 status_t status = msg->postAndAwaitResponse(&response);
2957
2958 if (status == OK && response != NULL) {
2959 CHECK(response->findInt32("status", &status));
2960 ALOGV("prepareDrm ret: %d ", status);
2961 } else {
2962 ALOGE("prepareDrm err: %d", status);
2963 }
2964
2965 return status;
2966}
2967
2968status_t NuPlayer2::releaseDrm()
2969{
2970 ALOGV("releaseDrm ");
2971
2972 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
2973
2974 sp<AMessage> response;
2975 status_t status = msg->postAndAwaitResponse(&response);
2976
2977 if (status == OK && response != NULL) {
2978 CHECK(response->findInt32("status", &status));
2979 ALOGV("releaseDrm ret: %d ", status);
2980 } else {
2981 ALOGE("releaseDrm err: %d", status);
2982 }
2983
2984 return status;
2985}
2986
2987status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
2988{
2989 // TODO change to ALOGV
2990 ALOGD("onPrepareDrm ");
2991
2992 status_t status = INVALID_OPERATION;
Wei Jiaf01e3122018-10-18 11:49:44 -07002993 if (mCurrentSourceInfo.mSource == NULL) {
Wei Jia53692fa2017-12-11 10:33:46 -08002994 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
2995 return status;
2996 }
2997
2998 uint8_t *uuid;
2999 Vector<uint8_t> *drmSessionId;
3000 CHECK(msg->findPointer("uuid", (void**)&uuid));
3001 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3002
3003 status = OK;
3004 sp<AMediaCryptoWrapper> crypto = NULL;
3005
Wei Jiaf01e3122018-10-18 11:49:44 -07003006 status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
Wei Jia53692fa2017-12-11 10:33:46 -08003007 if (crypto == NULL) {
Wei Jiaf01e3122018-10-18 11:49:44 -07003008 ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
Wei Jia53692fa2017-12-11 10:33:46 -08003009 return status;
3010 }
Wei Jiaf01e3122018-10-18 11:49:44 -07003011 ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
Wei Jia53692fa2017-12-11 10:33:46 -08003012
3013 if (mCrypto != NULL) {
3014 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
3015 mCrypto.clear();
3016 }
3017
3018 mCrypto = crypto;
3019 mIsDrmProtected = true;
3020 // TODO change to ALOGV
3021 ALOGD("onPrepareDrm: mCrypto: %p", mCrypto.get());
3022
3023 return status;
3024}
3025
3026status_t NuPlayer2::onReleaseDrm()
3027{
3028 // TODO change to ALOGV
3029 ALOGD("onReleaseDrm ");
3030
3031 if (!mIsDrmProtected) {
3032 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3033 }
3034
3035 mIsDrmProtected = false;
3036
3037 status_t status;
3038 if (mCrypto != NULL) {
3039 // notifying the source first before removing crypto from codec
Wei Jiaf01e3122018-10-18 11:49:44 -07003040 if (mCurrentSourceInfo.mSource != NULL) {
3041 mCurrentSourceInfo.mSource->releaseDrm();
Wei Jia53692fa2017-12-11 10:33:46 -08003042 }
3043
3044 status=OK;
3045 // first making sure the codecs have released their crypto reference
3046 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3047 if (videoDecoder != NULL) {
3048 status = videoDecoder->releaseCrypto();
3049 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3050 }
3051
3052 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3053 if (audioDecoder != NULL) {
3054 status_t status_audio = audioDecoder->releaseCrypto();
3055 if (status == OK) { // otherwise, returning the first error
3056 status = status_audio;
3057 }
3058 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3059 }
3060
3061 // TODO change to ALOGV
3062 ALOGD("onReleaseDrm: mCrypto: %p", mCrypto.get());
3063 mCrypto.clear();
3064 } else { // mCrypto == NULL
3065 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3066 status = INVALID_OPERATION;
3067 }
3068
3069 return status;
3070}
3071// Modular DRM end
3072////////////////////////////////////////////////////////////////////////////////
3073
3074sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
3075 sp<MetaData> meta = getFormatMeta(audio);
3076
3077 if (meta == NULL) {
3078 return NULL;
3079 }
3080
3081 sp<AMessage> msg = new AMessage;
3082
3083 if(convertMetaDataToMessage(meta, &msg) == OK) {
3084 return msg;
3085 }
3086 return NULL;
3087}
3088
3089void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
3090 sp<AMessage> notify = dupNotify();
3091 notify->setInt32("what", kWhatFlagsChanged);
3092 notify->setInt32("flags", flags);
3093 notify->post();
3094}
3095
3096void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3097 sp<AMessage> notify = dupNotify();
3098 notify->setInt32("what", kWhatVideoSizeChanged);
3099 notify->setMessage("format", format);
3100 notify->post();
3101}
3102
3103void NuPlayer2::Source::notifyPrepared(status_t err) {
3104 ALOGV("Source::notifyPrepared %d", err);
3105 sp<AMessage> notify = dupNotify();
3106 notify->setInt32("what", kWhatPrepared);
3107 notify->setInt32("err", err);
3108 notify->post();
3109}
3110
3111void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3112{
3113 ALOGV("Source::notifyDrmInfo");
3114
3115 sp<AMessage> notify = dupNotify();
3116 notify->setInt32("what", kWhatDrmInfo);
3117 notify->setBuffer("drmInfo", drmInfoBuffer);
3118
3119 notify->post();
3120}
3121
Wei Jia53692fa2017-12-11 10:33:46 -08003122void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3123 TRESPASS();
3124}
3125
Wei Jiaf01e3122018-10-18 11:49:44 -07003126NuPlayer2::SourceInfo::SourceInfo()
3127 : mDataSourceType(DATA_SOURCE_TYPE_NONE),
3128 mSrcId(0),
3129 mSourceFlags(0),
3130 mStartTimeUs(0),
3131 mEndTimeUs(INT64_MAX) {
3132}
3133
Wei Jia53692fa2017-12-11 10:33:46 -08003134} // namespace android