blob: 30eb4b9f1c28086b7b3bcc02bc55173ffe736ee7 [file] [log] [blame]
Andreas Huberf9334412010-12-15 15:17:42 -08001/*
2 * Copyright (C) 2010 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 "NuPlayer"
19#include <utils/Log.h>
20
21#include "NuPlayer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080022
23#include "HTTPLiveSource.h"
Andreas Huberf9334412010-12-15 15:17:42 -080024#include "NuPlayerDecoder.h"
Andreas Huber43c3e6c2011-01-05 12:17:08 -080025#include "NuPlayerDriver.h"
Andreas Huberf9334412010-12-15 15:17:42 -080026#include "NuPlayerRenderer.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080027#include "NuPlayerSource.h"
Andreas Huber2bfdd422011-10-11 15:24:07 -070028#include "RTSPSource.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080029#include "StreamingSource.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070030#include "GenericSource.h"
Andreas Huber84066782011-08-16 09:34:26 -070031#include "mp4/MP4Source.h"
Andreas Huber5bc087c2010-12-23 10:27:40 -080032
33#include "ATSParser.h"
Andreas Huberf9334412010-12-15 15:17:42 -080034
Andreas Huber84066782011-08-16 09:34:26 -070035#include <cutils/properties.h> // for property_get
Andreas Huber3831a062010-12-21 10:22:33 -080036#include <media/stagefright/foundation/hexdump.h>
Andreas Huberf9334412010-12-15 15:17:42 -080037#include <media/stagefright/foundation/ABuffer.h>
38#include <media/stagefright/foundation/ADebug.h>
39#include <media/stagefright/foundation/AMessage.h>
40#include <media/stagefright/ACodec.h>
Andreas Huber3fe62152011-09-16 15:09:22 -070041#include <media/stagefright/MediaDefs.h>
Andreas Huberf9334412010-12-15 15:17:42 -080042#include <media/stagefright/MediaErrors.h>
43#include <media/stagefright/MetaData.h>
Andy McFadden8ba01022012-12-18 09:46:54 -080044#include <gui/IGraphicBufferProducer.h>
Andreas Huberf9334412010-12-15 15:17:42 -080045
Andreas Huber3fe62152011-09-16 15:09:22 -070046#include "avc_utils.h"
47
Andreas Huber84066782011-08-16 09:34:26 -070048#include "ESDS.h"
49#include <media/stagefright/Utils.h>
50
Andreas Huberf9334412010-12-15 15:17:42 -080051namespace android {
52
Andreas Hubera1f8ab02012-11-30 10:53:22 -080053struct NuPlayer::Action : public RefBase {
54 Action() {}
55
56 virtual void execute(NuPlayer *player) = 0;
57
58private:
59 DISALLOW_EVIL_CONSTRUCTORS(Action);
60};
61
62struct NuPlayer::SeekAction : public Action {
63 SeekAction(int64_t seekTimeUs)
64 : mSeekTimeUs(seekTimeUs) {
65 }
66
67 virtual void execute(NuPlayer *player) {
68 player->performSeek(mSeekTimeUs);
69 }
70
71private:
72 int64_t mSeekTimeUs;
73
74 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
75};
76
Andreas Huber57a339c2012-12-03 11:18:00 -080077struct NuPlayer::SetSurfaceAction : public Action {
78 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
79 : mWrapper(wrapper) {
80 }
81
82 virtual void execute(NuPlayer *player) {
83 player->performSetSurface(mWrapper);
84 }
85
86private:
87 sp<NativeWindowWrapper> mWrapper;
88
89 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
90};
91
Andreas Hubera1f8ab02012-11-30 10:53:22 -080092// Use this if there's no state necessary to save in order to execute
93// the action.
94struct NuPlayer::SimpleAction : public Action {
95 typedef void (NuPlayer::*ActionFunc)();
96
97 SimpleAction(ActionFunc func)
98 : mFunc(func) {
99 }
100
101 virtual void execute(NuPlayer *player) {
102 (player->*mFunc)();
103 }
104
105private:
106 ActionFunc mFunc;
107
108 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
109};
110
Andreas Huberf9334412010-12-15 15:17:42 -0800111////////////////////////////////////////////////////////////////////////////////
112
113NuPlayer::NuPlayer()
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700114 : mUIDValid(false),
Andreas Huber9575c962013-02-05 13:59:56 -0800115 mSourceFlags(0),
Andreas Huber3fe62152011-09-16 15:09:22 -0700116 mVideoIsAVC(false),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700117 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800118 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800119 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800120 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800121 mPollDurationGeneration(0),
Andreas Huber6e3d3112011-11-28 12:36:11 -0800122 mTimeDiscontinuityPending(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800123 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800124 mFlushingVideo(NONE),
Andreas Huber3fe62152011-09-16 15:09:22 -0700125 mSkipRenderingAudioUntilMediaTimeUs(-1ll),
126 mSkipRenderingVideoUntilMediaTimeUs(-1ll),
127 mVideoLateByUs(0ll),
128 mNumFramesTotal(0ll),
James Dong0d268a32012-08-31 12:18:27 -0700129 mNumFramesDropped(0ll),
Andreas Huber57a339c2012-12-03 11:18:00 -0800130 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
131 mStarted(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800132}
133
134NuPlayer::~NuPlayer() {
135}
136
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700137void NuPlayer::setUID(uid_t uid) {
138 mUIDValid = true;
139 mUID = uid;
140}
141
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800142void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
143 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800144}
145
Andreas Huber9575c962013-02-05 13:59:56 -0800146void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
Andreas Huberf9334412010-12-15 15:17:42 -0800147 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
148
Andreas Huberb5f25f02013-02-05 10:14:26 -0800149 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
150
Andreas Huber84066782011-08-16 09:34:26 -0700151 char prop[PROPERTY_VALUE_MAX];
152 if (property_get("media.stagefright.use-mp4source", prop, NULL)
153 && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800154 msg->setObject("source", new MP4Source(notify, source));
Andreas Huber84066782011-08-16 09:34:26 -0700155 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800156 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber84066782011-08-16 09:34:26 -0700157 }
158
Andreas Huber5bc087c2010-12-23 10:27:40 -0800159 msg->post();
160}
Andreas Huberf9334412010-12-15 15:17:42 -0800161
Andreas Huberafed0e12011-09-20 15:39:58 -0700162static bool IsHTTPLiveURL(const char *url) {
163 if (!strncasecmp("http://", url, 7)
164 || !strncasecmp("https://", url, 8)) {
165 size_t len = strlen(url);
166 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
167 return true;
168 }
169
170 if (strstr(url,"m3u8")) {
171 return true;
172 }
173 }
174
175 return false;
176}
177
Andreas Huber9575c962013-02-05 13:59:56 -0800178void NuPlayer::setDataSourceAsync(
Andreas Huber5bc087c2010-12-23 10:27:40 -0800179 const char *url, const KeyedVector<String8, String8> *headers) {
180 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100181 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800182
Andreas Huberb5f25f02013-02-05 10:14:26 -0800183 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
184
Andreas Huberafed0e12011-09-20 15:39:58 -0700185 sp<Source> source;
186 if (IsHTTPLiveURL(url)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800187 source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
Andreas Huberafed0e12011-09-20 15:39:58 -0700188 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800189 source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100190 } else if ((!strncasecmp(url, "http://", 7)
191 || !strncasecmp(url, "https://", 8))
192 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
193 || strstr(url, ".sdp?"))) {
194 source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700195 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800196 source = new GenericSource(notify, url, headers, mUIDValid, mUID);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700197 }
198
Andreas Huberafed0e12011-09-20 15:39:58 -0700199 msg->setObject("source", source);
200 msg->post();
201}
202
Andreas Huber9575c962013-02-05 13:59:56 -0800203void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700204 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
205
Andreas Huberb5f25f02013-02-05 10:14:26 -0800206 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
207
208 sp<Source> source = new GenericSource(notify, fd, offset, length);
Andreas Huberafed0e12011-09-20 15:39:58 -0700209 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800210 msg->post();
211}
212
Andreas Huber9575c962013-02-05 13:59:56 -0800213void NuPlayer::prepareAsync() {
214 (new AMessage(kWhatPrepare, id()))->post();
215}
216
Andreas Huber57a339c2012-12-03 11:18:00 -0800217void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800218 const sp<IGraphicBufferProducer> &bufferProducer) {
Glenn Kasten11731182011-02-08 17:26:17 -0800219 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
Andreas Huber57a339c2012-12-03 11:18:00 -0800220
Andy McFadden8ba01022012-12-18 09:46:54 -0800221 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800222 msg->setObject("native-window", NULL);
223 } else {
224 msg->setObject(
225 "native-window",
226 new NativeWindowWrapper(
Andy McFadden8ba01022012-12-18 09:46:54 -0800227 new SurfaceTextureClient(bufferProducer)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800228 }
229
Andreas Huberf9334412010-12-15 15:17:42 -0800230 msg->post();
231}
232
233void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
234 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
235 msg->setObject("sink", sink);
236 msg->post();
237}
238
239void NuPlayer::start() {
240 (new AMessage(kWhatStart, id()))->post();
241}
242
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800243void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800244 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800245}
246
247void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800248 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800249}
250
Andreas Huber1aef2112011-01-04 14:01:29 -0800251void NuPlayer::resetAsync() {
252 (new AMessage(kWhatReset, id()))->post();
253}
254
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800255void NuPlayer::seekToAsync(int64_t seekTimeUs) {
256 sp<AMessage> msg = new AMessage(kWhatSeek, id());
257 msg->setInt64("seekTimeUs", seekTimeUs);
258 msg->post();
259}
260
Andreas Huber53df1a42010-12-22 10:03:04 -0800261// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800262bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800263 switch (state) {
264 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800265 if (needShutdown != NULL) {
266 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800267 }
268 return true;
269
Andreas Huber1aef2112011-01-04 14:01:29 -0800270 case FLUSHING_DECODER_SHUTDOWN:
271 if (needShutdown != NULL) {
272 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800273 }
274 return true;
275
276 default:
277 return false;
278 }
279}
280
Andreas Huberf9334412010-12-15 15:17:42 -0800281void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
282 switch (msg->what()) {
283 case kWhatSetDataSource:
284 {
Steve Block3856b092011-10-20 11:56:00 +0100285 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800286
287 CHECK(mSource == NULL);
288
Andreas Huber5bc087c2010-12-23 10:27:40 -0800289 sp<RefBase> obj;
290 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800291
Andreas Huber5bc087c2010-12-23 10:27:40 -0800292 mSource = static_cast<Source *>(obj.get());
Andreas Huberb5f25f02013-02-05 10:14:26 -0800293
294 looper()->registerHandler(mSource);
Andreas Huber9575c962013-02-05 13:59:56 -0800295
296 CHECK(mDriver != NULL);
297 sp<NuPlayerDriver> driver = mDriver.promote();
298 if (driver != NULL) {
299 driver->notifySetDataSourceCompleted(OK);
300 }
301 break;
302 }
303
304 case kWhatPrepare:
305 {
306 mSource->prepareAsync();
Andreas Huberf9334412010-12-15 15:17:42 -0800307 break;
308 }
309
Andreas Huberb7c8e912012-11-27 15:02:53 -0800310 case kWhatPollDuration:
311 {
312 int32_t generation;
313 CHECK(msg->findInt32("generation", &generation));
314
315 if (generation != mPollDurationGeneration) {
316 // stale
317 break;
318 }
319
320 int64_t durationUs;
321 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
322 sp<NuPlayerDriver> driver = mDriver.promote();
323 if (driver != NULL) {
324 driver->notifyDuration(durationUs);
325 }
326 }
327
328 msg->post(1000000ll); // poll again in a second.
329 break;
330 }
331
Glenn Kasten11731182011-02-08 17:26:17 -0800332 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800333 {
Steve Block3856b092011-10-20 11:56:00 +0100334 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800335
Andreas Huber57a339c2012-12-03 11:18:00 -0800336 mDeferredActions.push_back(
337 new SimpleAction(&NuPlayer::performDecoderShutdown));
338
Andreas Huberf9334412010-12-15 15:17:42 -0800339 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800340 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800341
Andreas Huber57a339c2012-12-03 11:18:00 -0800342 mDeferredActions.push_back(
343 new SetSurfaceAction(
344 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700345
Andreas Huber57a339c2012-12-03 11:18:00 -0800346 if (obj != NULL) {
347 // If there is a new surface texture, instantiate decoders
348 // again if possible.
349 mDeferredActions.push_back(
350 new SimpleAction(&NuPlayer::performScanSources));
351 }
352
353 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800354 break;
355 }
356
357 case kWhatSetAudioSink:
358 {
Steve Block3856b092011-10-20 11:56:00 +0100359 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800360
361 sp<RefBase> obj;
362 CHECK(msg->findObject("sink", &obj));
363
364 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
365 break;
366 }
367
368 case kWhatStart:
369 {
Steve Block3856b092011-10-20 11:56:00 +0100370 ALOGV("kWhatStart");
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800371
Andreas Huber3fe62152011-09-16 15:09:22 -0700372 mVideoIsAVC = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800373 mAudioEOS = false;
374 mVideoEOS = false;
Andreas Huber32f3cef2011-03-02 15:34:46 -0800375 mSkipRenderingAudioUntilMediaTimeUs = -1;
376 mSkipRenderingVideoUntilMediaTimeUs = -1;
Andreas Huber3fe62152011-09-16 15:09:22 -0700377 mVideoLateByUs = 0;
378 mNumFramesTotal = 0;
379 mNumFramesDropped = 0;
Andreas Huber57a339c2012-12-03 11:18:00 -0800380 mStarted = true;
Andreas Huber1aef2112011-01-04 14:01:29 -0800381
Andreas Huber5bc087c2010-12-23 10:27:40 -0800382 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800383
384 mRenderer = new Renderer(
385 mAudioSink,
386 new AMessage(kWhatRendererNotify, id()));
387
388 looper()->registerHandler(mRenderer);
389
Andreas Huber1aef2112011-01-04 14:01:29 -0800390 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800391 break;
392 }
393
394 case kWhatScanSources:
395 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800396 int32_t generation;
397 CHECK(msg->findInt32("generation", &generation));
398 if (generation != mScanSourcesGeneration) {
399 // Drop obsolete msg.
400 break;
401 }
402
Andreas Huber5bc087c2010-12-23 10:27:40 -0800403 mScanSourcesPending = false;
404
Steve Block3856b092011-10-20 11:56:00 +0100405 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800406 mAudioDecoder != NULL, mVideoDecoder != NULL);
407
Andreas Huberb7c8e912012-11-27 15:02:53 -0800408 bool mHadAnySourcesBefore =
409 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
410
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700411 if (mNativeWindow != NULL) {
412 instantiateDecoder(false, &mVideoDecoder);
413 }
Andreas Huberf9334412010-12-15 15:17:42 -0800414
415 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800416 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800417 }
418
Andreas Huberb7c8e912012-11-27 15:02:53 -0800419 if (!mHadAnySourcesBefore
420 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
421 // This is the first time we've found anything playable.
422
Andreas Huber9575c962013-02-05 13:59:56 -0800423 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800424 schedulePollDuration();
425 }
426 }
427
Andreas Hubereac68ba2011-09-27 12:12:25 -0700428 status_t err;
429 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800430 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
431 // We're not currently decoding anything (no audio or
432 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700433
434 if (err == ERROR_END_OF_STREAM) {
435 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
436 } else {
437 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
438 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800439 }
Andreas Huberf9334412010-12-15 15:17:42 -0800440 break;
441 }
442
Andreas Huberfbe9d812012-08-31 14:05:27 -0700443 if ((mAudioDecoder == NULL && mAudioSink != NULL)
444 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800445 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800446 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800447 }
448 break;
449 }
450
451 case kWhatVideoNotify:
452 case kWhatAudioNotify:
453 {
454 bool audio = msg->what() == kWhatAudioNotify;
455
456 sp<AMessage> codecRequest;
457 CHECK(msg->findMessage("codec-request", &codecRequest));
458
459 int32_t what;
460 CHECK(codecRequest->findInt32("what", &what));
461
462 if (what == ACodec::kWhatFillThisBuffer) {
463 status_t err = feedDecoderInputData(
464 audio, codecRequest);
465
Andreas Huber5bc087c2010-12-23 10:27:40 -0800466 if (err == -EWOULDBLOCK) {
Andreas Hubereac68ba2011-09-27 12:12:25 -0700467 if (mSource->feedMoreTSData() == OK) {
Andreas Huber1183a4a2011-11-03 11:00:21 -0700468 msg->post(10000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800469 }
Andreas Huberf9334412010-12-15 15:17:42 -0800470 }
471 } else if (what == ACodec::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700472 int32_t err;
473 CHECK(codecRequest->findInt32("err", &err));
474
475 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100476 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700477 } else {
Steve Block3856b092011-10-20 11:56:00 +0100478 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700479 audio ? "audio" : "video",
480 err);
481 }
482
483 mRenderer->queueEOS(audio, err);
Andreas Huberf9334412010-12-15 15:17:42 -0800484 } else if (what == ACodec::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800485 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800486
Andreas Huberf9334412010-12-15 15:17:42 -0800487 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800488 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800489 mFlushingAudio = FLUSHED;
490 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800491 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800492 mFlushingVideo = FLUSHED;
Andreas Huber3fe62152011-09-16 15:09:22 -0700493
494 mVideoLateByUs = 0;
Andreas Huberf9334412010-12-15 15:17:42 -0800495 }
496
Steve Block3856b092011-10-20 11:56:00 +0100497 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800498
Andreas Huber1aef2112011-01-04 14:01:29 -0800499 if (needShutdown) {
Steve Block3856b092011-10-20 11:56:00 +0100500 ALOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800501 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800502
Andreas Huber53df1a42010-12-22 10:03:04 -0800503 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800504
Andreas Huber53df1a42010-12-22 10:03:04 -0800505 if (audio) {
506 mFlushingAudio = SHUTTING_DOWN_DECODER;
507 } else {
508 mFlushingVideo = SHUTTING_DOWN_DECODER;
509 }
Andreas Huberf9334412010-12-15 15:17:42 -0800510 }
Andreas Huber3831a062010-12-21 10:22:33 -0800511
512 finishFlushIfPossible();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800513 } else if (what == ACodec::kWhatOutputFormatChanged) {
Andreas Huber31e25082011-01-10 10:38:31 -0800514 if (audio) {
515 int32_t numChannels;
Andreas Huber516dacf2012-12-03 15:20:40 -0800516 CHECK(codecRequest->findInt32(
517 "channel-count", &numChannels));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800518
Andreas Huber31e25082011-01-10 10:38:31 -0800519 int32_t sampleRate;
520 CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800521
Steve Block3856b092011-10-20 11:56:00 +0100522 ALOGV("Audio output format changed to %d Hz, %d channels",
Andreas Huber31e25082011-01-10 10:38:31 -0800523 sampleRate, numChannels);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800524
Andreas Huber31e25082011-01-10 10:38:31 -0800525 mAudioSink->close();
Eric Laurent1948eb32012-04-13 16:50:19 -0700526
527 audio_output_flags_t flags;
528 int64_t durationUs;
Andreas Huber516dacf2012-12-03 15:20:40 -0800529 // FIXME: we should handle the case where the video decoder
530 // is created after we receive the format change indication.
531 // Current code will just make that we select deep buffer
532 // with video which should not be a problem as it should
Eric Laurent1948eb32012-04-13 16:50:19 -0700533 // not prevent from keeping A/V sync.
534 if (mVideoDecoder == NULL &&
535 mSource->getDuration(&durationUs) == OK &&
Andreas Huber516dacf2012-12-03 15:20:40 -0800536 durationUs
537 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
Eric Laurent1948eb32012-04-13 16:50:19 -0700538 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
539 } else {
540 flags = AUDIO_OUTPUT_FLAG_NONE;
541 }
542
Andreas Huber98065552012-05-03 11:33:01 -0700543 int32_t channelMask;
544 if (!codecRequest->findInt32("channel-mask", &channelMask)) {
545 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
546 }
547
Andreas Huber078cfcf2011-09-15 12:25:04 -0700548 CHECK_EQ(mAudioSink->open(
549 sampleRate,
550 numChannels,
Andreas Huber98065552012-05-03 11:33:01 -0700551 (audio_channel_mask_t)channelMask,
Andreas Huber078cfcf2011-09-15 12:25:04 -0700552 AUDIO_FORMAT_PCM_16_BIT,
Eric Laurent1948eb32012-04-13 16:50:19 -0700553 8 /* bufferCount */,
554 NULL,
555 NULL,
556 flags),
Andreas Huber078cfcf2011-09-15 12:25:04 -0700557 (status_t)OK);
Andreas Huber31e25082011-01-10 10:38:31 -0800558 mAudioSink->start();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800559
Andreas Huber31e25082011-01-10 10:38:31 -0800560 mRenderer->signalAudioSinkChanged();
561 } else {
562 // video
Andreas Huber3831a062010-12-21 10:22:33 -0800563
Andreas Huber31e25082011-01-10 10:38:31 -0800564 int32_t width, height;
565 CHECK(codecRequest->findInt32("width", &width));
566 CHECK(codecRequest->findInt32("height", &height));
567
568 int32_t cropLeft, cropTop, cropRight, cropBottom;
569 CHECK(codecRequest->findRect(
570 "crop",
571 &cropLeft, &cropTop, &cropRight, &cropBottom));
572
Andreas Huber516dacf2012-12-03 15:20:40 -0800573 int32_t displayWidth = cropRight - cropLeft + 1;
574 int32_t displayHeight = cropBottom - cropTop + 1;
575
Steve Block3856b092011-10-20 11:56:00 +0100576 ALOGV("Video output format changed to %d x %d "
Andreas Hubercb67cd12011-08-26 16:02:19 -0700577 "(crop: %d x %d @ (%d, %d))",
Andreas Huber31e25082011-01-10 10:38:31 -0800578 width, height,
Andreas Huber516dacf2012-12-03 15:20:40 -0800579 displayWidth,
580 displayHeight,
Andreas Hubercb67cd12011-08-26 16:02:19 -0700581 cropLeft, cropTop);
Andreas Huber31e25082011-01-10 10:38:31 -0800582
Andreas Huber516dacf2012-12-03 15:20:40 -0800583 sp<AMessage> videoInputFormat =
584 mSource->getFormat(false /* audio */);
585
586 // Take into account sample aspect ratio if necessary:
587 int32_t sarWidth, sarHeight;
588 if (videoInputFormat->findInt32("sar-width", &sarWidth)
589 && videoInputFormat->findInt32(
590 "sar-height", &sarHeight)) {
591 ALOGV("Sample aspect ratio %d : %d",
592 sarWidth, sarHeight);
593
594 displayWidth = (displayWidth * sarWidth) / sarHeight;
595
596 ALOGV("display dimensions %d x %d",
597 displayWidth, displayHeight);
598 }
599
Andreas Huber31e25082011-01-10 10:38:31 -0800600 notifyListener(
Andreas Huber516dacf2012-12-03 15:20:40 -0800601 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
Andreas Huber31e25082011-01-10 10:38:31 -0800602 }
Andreas Huber3831a062010-12-21 10:22:33 -0800603 } else if (what == ACodec::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100604 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800605 if (audio) {
606 mAudioDecoder.clear();
607
608 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
609 mFlushingAudio = SHUT_DOWN;
610 } else {
611 mVideoDecoder.clear();
612
613 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
614 mFlushingVideo = SHUT_DOWN;
615 }
616
617 finishFlushIfPossible();
Andreas Huberc92fd242011-08-16 13:48:44 -0700618 } else if (what == ACodec::kWhatError) {
Steve Block29357bc2012-01-06 19:20:56 +0000619 ALOGE("Received error from %s decoder, aborting playback.",
Andreas Huberc92fd242011-08-16 13:48:44 -0700620 audio ? "audio" : "video");
621
622 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
Andreas Huber57788222012-02-21 11:47:18 -0800623 } else if (what == ACodec::kWhatDrainThisBuffer) {
Andreas Huberf9334412010-12-15 15:17:42 -0800624 renderBuffer(audio, codecRequest);
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800625 } else if (what != ACodec::kWhatComponentAllocated
626 && what != ACodec::kWhatComponentConfigured
627 && what != ACodec::kWhatBuffersAllocated) {
628 ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
629 what,
630 what >> 24,
631 (what >> 16) & 0xff,
632 (what >> 8) & 0xff,
633 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800634 }
635
636 break;
637 }
638
639 case kWhatRendererNotify:
640 {
641 int32_t what;
642 CHECK(msg->findInt32("what", &what));
643
644 if (what == Renderer::kWhatEOS) {
645 int32_t audio;
646 CHECK(msg->findInt32("audio", &audio));
647
Andreas Huberc92fd242011-08-16 13:48:44 -0700648 int32_t finalResult;
649 CHECK(msg->findInt32("finalResult", &finalResult));
650
Andreas Huberf9334412010-12-15 15:17:42 -0800651 if (audio) {
652 mAudioEOS = true;
653 } else {
654 mVideoEOS = true;
655 }
656
Andreas Huberc92fd242011-08-16 13:48:44 -0700657 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100658 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700659 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000660 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700661 audio ? "audio" : "video", finalResult);
662
663 notifyListener(
664 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
665 }
Andreas Huberf9334412010-12-15 15:17:42 -0800666
667 if ((mAudioEOS || mAudioDecoder == NULL)
668 && (mVideoEOS || mVideoDecoder == NULL)) {
669 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
670 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800671 } else if (what == Renderer::kWhatPosition) {
672 int64_t positionUs;
673 CHECK(msg->findInt64("positionUs", &positionUs));
674
Andreas Huber3fe62152011-09-16 15:09:22 -0700675 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
676
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800677 if (mDriver != NULL) {
678 sp<NuPlayerDriver> driver = mDriver.promote();
679 if (driver != NULL) {
680 driver->notifyPosition(positionUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700681
682 driver->notifyFrameStats(
683 mNumFramesTotal, mNumFramesDropped);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800684 }
685 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700686 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800687 int32_t audio;
688 CHECK(msg->findInt32("audio", &audio));
689
Steve Block3856b092011-10-20 11:56:00 +0100690 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
James Dongf57b4ea2012-07-20 13:38:36 -0700691 } else if (what == Renderer::kWhatVideoRenderingStart) {
692 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Andreas Huberf9334412010-12-15 15:17:42 -0800693 }
694 break;
695 }
696
697 case kWhatMoreDataQueued:
698 {
699 break;
700 }
701
Andreas Huber1aef2112011-01-04 14:01:29 -0800702 case kWhatReset:
703 {
Steve Block3856b092011-10-20 11:56:00 +0100704 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800705
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800706 mDeferredActions.push_back(
707 new SimpleAction(&NuPlayer::performDecoderShutdown));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800708
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800709 mDeferredActions.push_back(
710 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800711
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800712 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800713 break;
714 }
715
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800716 case kWhatSeek:
717 {
718 int64_t seekTimeUs;
719 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
720
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800721 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800722
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800723 mDeferredActions.push_back(
724 new SimpleAction(&NuPlayer::performDecoderFlush));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800725
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800726 mDeferredActions.push_back(new SeekAction(seekTimeUs));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800727
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800728 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800729 break;
730 }
731
Andreas Huberb4082222011-01-20 15:23:04 -0800732 case kWhatPause:
733 {
734 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +0100735 mSource->pause();
Andreas Huberb4082222011-01-20 15:23:04 -0800736 mRenderer->pause();
737 break;
738 }
739
740 case kWhatResume:
741 {
742 CHECK(mRenderer != NULL);
Roger Jönssonfba60da2013-01-21 17:15:45 +0100743 mSource->resume();
Andreas Huberb4082222011-01-20 15:23:04 -0800744 mRenderer->resume();
745 break;
746 }
747
Andreas Huberb5f25f02013-02-05 10:14:26 -0800748 case kWhatSourceNotify:
749 {
Andreas Huber9575c962013-02-05 13:59:56 -0800750 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800751 break;
752 }
753
Andreas Huberf9334412010-12-15 15:17:42 -0800754 default:
755 TRESPASS();
756 break;
757 }
758}
759
Andreas Huber3831a062010-12-21 10:22:33 -0800760void NuPlayer::finishFlushIfPossible() {
761 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
762 return;
763 }
764
765 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
766 return;
767 }
768
Steve Block3856b092011-10-20 11:56:00 +0100769 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800770
Andreas Huber6e3d3112011-11-28 12:36:11 -0800771 if (mTimeDiscontinuityPending) {
772 mRenderer->signalTimeDiscontinuity();
773 mTimeDiscontinuityPending = false;
774 }
Andreas Huber3831a062010-12-21 10:22:33 -0800775
Andreas Huber22fc52f2011-01-05 16:24:27 -0800776 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800777 mAudioDecoder->signalResume();
778 }
779
Andreas Huber22fc52f2011-01-05 16:24:27 -0800780 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800781 mVideoDecoder->signalResume();
782 }
783
784 mFlushingAudio = NONE;
785 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800786
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800787 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800788}
789
790void NuPlayer::postScanSources() {
791 if (mScanSourcesPending) {
792 return;
793 }
794
795 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
796 msg->setInt32("generation", mScanSourcesGeneration);
797 msg->post();
798
799 mScanSourcesPending = true;
800}
801
Andreas Huber5bc087c2010-12-23 10:27:40 -0800802status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800803 if (*decoder != NULL) {
804 return OK;
805 }
806
Andreas Huber84066782011-08-16 09:34:26 -0700807 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800808
Andreas Huber84066782011-08-16 09:34:26 -0700809 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800810 return -EWOULDBLOCK;
811 }
812
Andreas Huber3fe62152011-09-16 15:09:22 -0700813 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -0700814 AString mime;
815 CHECK(format->findString("mime", &mime));
816 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Andreas Huber3fe62152011-09-16 15:09:22 -0700817 }
818
Andreas Huberf9334412010-12-15 15:17:42 -0800819 sp<AMessage> notify =
820 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
821 id());
822
Glenn Kasten11731182011-02-08 17:26:17 -0800823 *decoder = audio ? new Decoder(notify) :
824 new Decoder(notify, mNativeWindow);
Andreas Huberf9334412010-12-15 15:17:42 -0800825 looper()->registerHandler(*decoder);
826
Andreas Huber84066782011-08-16 09:34:26 -0700827 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -0800828
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800829 int64_t durationUs;
830 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
831 sp<NuPlayerDriver> driver = mDriver.promote();
832 if (driver != NULL) {
833 driver->notifyDuration(durationUs);
834 }
835 }
836
Andreas Huberf9334412010-12-15 15:17:42 -0800837 return OK;
838}
839
840status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
841 sp<AMessage> reply;
842 CHECK(msg->findMessage("reply", &reply));
843
Andreas Huber53df1a42010-12-22 10:03:04 -0800844 if ((audio && IsFlushingState(mFlushingAudio))
845 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800846 reply->setInt32("err", INFO_DISCONTINUITY);
847 reply->post();
848 return OK;
849 }
850
851 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -0800852
Andreas Huber3fe62152011-09-16 15:09:22 -0700853 bool dropAccessUnit;
854 do {
855 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800856
Andreas Huber3fe62152011-09-16 15:09:22 -0700857 if (err == -EWOULDBLOCK) {
858 return err;
859 } else if (err != OK) {
860 if (err == INFO_DISCONTINUITY) {
861 int32_t type;
862 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -0800863
Andreas Huber3fe62152011-09-16 15:09:22 -0700864 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -0800865 (audio &&
866 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
867 || (!audio &&
868 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -0800869
Andreas Huber6e3d3112011-11-28 12:36:11 -0800870 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
871
Steve Blockdf64d152012-01-04 20:05:49 +0000872 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800873 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -0800874
Andreas Huber3fe62152011-09-16 15:09:22 -0700875 if (audio) {
876 mSkipRenderingAudioUntilMediaTimeUs = -1;
877 } else {
878 mSkipRenderingVideoUntilMediaTimeUs = -1;
879 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800880
Andreas Huber6e3d3112011-11-28 12:36:11 -0800881 if (timeChange) {
882 sp<AMessage> extra;
883 if (accessUnit->meta()->findMessage("extra", &extra)
884 && extra != NULL) {
885 int64_t resumeAtMediaTimeUs;
886 if (extra->findInt64(
887 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +0000888 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800889 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700890
Andreas Huber6e3d3112011-11-28 12:36:11 -0800891 if (audio) {
892 mSkipRenderingAudioUntilMediaTimeUs =
893 resumeAtMediaTimeUs;
894 } else {
895 mSkipRenderingVideoUntilMediaTimeUs =
896 resumeAtMediaTimeUs;
897 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700898 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800899 }
900 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700901
Andreas Huber6e3d3112011-11-28 12:36:11 -0800902 mTimeDiscontinuityPending =
903 mTimeDiscontinuityPending || timeChange;
904
905 if (formatChange || timeChange) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800906 if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
907 // And we'll resume scanning sources once we're done
908 // flushing.
909 mDeferredActions.push_front(
910 new SimpleAction(
911 &NuPlayer::performScanSources));
912 }
913
Andreas Huber6e3d3112011-11-28 12:36:11 -0800914 flushDecoder(audio, formatChange);
915 } else {
916 // This stream is unaffected by the discontinuity
917
918 if (audio) {
919 mFlushingAudio = FLUSHED;
920 } else {
921 mFlushingVideo = FLUSHED;
922 }
923
924 finishFlushIfPossible();
925
926 return -EWOULDBLOCK;
927 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800928 }
929
Andreas Huber3fe62152011-09-16 15:09:22 -0700930 reply->setInt32("err", err);
931 reply->post();
932 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800933 }
934
Andreas Huber3fe62152011-09-16 15:09:22 -0700935 if (!audio) {
936 ++mNumFramesTotal;
937 }
938
939 dropAccessUnit = false;
940 if (!audio
941 && mVideoLateByUs > 100000ll
942 && mVideoIsAVC
943 && !IsAVCReferenceFrame(accessUnit)) {
944 dropAccessUnit = true;
945 ++mNumFramesDropped;
946 }
947 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800948
Steve Block3856b092011-10-20 11:56:00 +0100949 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800950
951#if 0
952 int64_t mediaTimeUs;
953 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +0100954 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800955 audio ? "audio" : "video",
956 mediaTimeUs / 1E6);
957#endif
958
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800959 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800960 reply->post();
961
962 return OK;
963}
964
965void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +0100966 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800967
968 sp<AMessage> reply;
969 CHECK(msg->findMessage("reply", &reply));
970
Andreas Huber18ac5402011-08-31 15:04:25 -0700971 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
972 // We're currently attempting to flush the decoder, in order
973 // to complete this, the decoder wants all its buffers back,
974 // so we don't want any output buffers it sent us (from before
975 // we initiated the flush) to be stuck in the renderer's queue.
976
Steve Block3856b092011-10-20 11:56:00 +0100977 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -0700978 " right back.", audio ? "audio" : "video");
979
980 reply->post();
981 return;
982 }
983
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800984 sp<ABuffer> buffer;
985 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -0800986
Andreas Huber32f3cef2011-03-02 15:34:46 -0800987 int64_t &skipUntilMediaTimeUs =
988 audio
989 ? mSkipRenderingAudioUntilMediaTimeUs
990 : mSkipRenderingVideoUntilMediaTimeUs;
991
992 if (skipUntilMediaTimeUs >= 0) {
993 int64_t mediaTimeUs;
994 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
995
996 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +0100997 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -0800998 audio ? "audio" : "video",
999 mediaTimeUs);
1000
1001 reply->post();
1002 return;
1003 }
1004
1005 skipUntilMediaTimeUs = -1;
1006 }
1007
Andreas Huberf9334412010-12-15 15:17:42 -08001008 mRenderer->queueBuffer(audio, buffer, reply);
1009}
1010
1011void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001012 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001013 return;
1014 }
1015
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001016 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001017
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001018 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001019 return;
1020 }
1021
Andreas Hubera4af2142011-10-26 15:23:31 -07001022 driver->notifyListener(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -08001023}
1024
Andreas Huber1aef2112011-01-04 14:01:29 -08001025void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001026 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001027 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001028 audio ? "audio" : "video");
1029 }
1030
Andreas Huber1aef2112011-01-04 14:01:29 -08001031 // Make sure we don't continue to scan sources until we finish flushing.
1032 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001033 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001034
1035 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1036 mRenderer->flush(audio);
1037
1038 FlushStatus newStatus =
1039 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1040
1041 if (audio) {
1042 CHECK(mFlushingAudio == NONE
1043 || mFlushingAudio == AWAITING_DISCONTINUITY);
1044
1045 mFlushingAudio = newStatus;
1046
1047 if (mFlushingVideo == NONE) {
1048 mFlushingVideo = (mVideoDecoder != NULL)
1049 ? AWAITING_DISCONTINUITY
1050 : FLUSHED;
1051 }
1052 } else {
1053 CHECK(mFlushingVideo == NONE
1054 || mFlushingVideo == AWAITING_DISCONTINUITY);
1055
1056 mFlushingVideo = newStatus;
1057
1058 if (mFlushingAudio == NONE) {
1059 mFlushingAudio = (mAudioDecoder != NULL)
1060 ? AWAITING_DISCONTINUITY
1061 : FLUSHED;
1062 }
1063 }
1064}
1065
Andreas Huber84066782011-08-16 09:34:26 -07001066sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1067 sp<MetaData> meta = getFormatMeta(audio);
1068
1069 if (meta == NULL) {
1070 return NULL;
1071 }
1072
1073 sp<AMessage> msg = new AMessage;
1074
1075 if(convertMetaDataToMessage(meta, &msg) == OK) {
1076 return msg;
1077 }
1078 return NULL;
1079}
1080
James Dong0d268a32012-08-31 12:18:27 -07001081status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1082 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001083 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001084 status_t ret = native_window_set_scaling_mode(
1085 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1086 if (ret != OK) {
1087 ALOGE("Failed to set scaling mode (%d): %s",
1088 -ret, strerror(-ret));
1089 return ret;
1090 }
1091 }
1092 return OK;
1093}
1094
Andreas Huberb7c8e912012-11-27 15:02:53 -08001095void NuPlayer::schedulePollDuration() {
1096 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1097 msg->setInt32("generation", mPollDurationGeneration);
1098 msg->post();
1099}
1100
1101void NuPlayer::cancelPollDuration() {
1102 ++mPollDurationGeneration;
1103}
1104
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001105void NuPlayer::processDeferredActions() {
1106 while (!mDeferredActions.empty()) {
1107 // We won't execute any deferred actions until we're no longer in
1108 // an intermediate state, i.e. one more more decoders are currently
1109 // flushing or shutting down.
1110
1111 if (mRenderer != NULL) {
1112 // There's an edge case where the renderer owns all output
1113 // buffers and is paused, therefore the decoder will not read
1114 // more input data and will never encounter the matching
1115 // discontinuity. To avoid this, we resume the renderer.
1116
1117 if (mFlushingAudio == AWAITING_DISCONTINUITY
1118 || mFlushingVideo == AWAITING_DISCONTINUITY) {
1119 mRenderer->resume();
1120 }
1121 }
1122
1123 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1124 // We're currently flushing, postpone the reset until that's
1125 // completed.
1126
1127 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1128 mFlushingAudio, mFlushingVideo);
1129
1130 break;
1131 }
1132
1133 sp<Action> action = *mDeferredActions.begin();
1134 mDeferredActions.erase(mDeferredActions.begin());
1135
1136 action->execute(this);
1137 }
1138}
1139
1140void NuPlayer::performSeek(int64_t seekTimeUs) {
1141 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1142 seekTimeUs,
1143 seekTimeUs / 1E6);
1144
1145 mSource->seekTo(seekTimeUs);
1146
1147 if (mDriver != NULL) {
1148 sp<NuPlayerDriver> driver = mDriver.promote();
1149 if (driver != NULL) {
1150 driver->notifyPosition(seekTimeUs);
1151 driver->notifySeekComplete();
1152 }
1153 }
1154
1155 // everything's flushed, continue playback.
1156}
1157
1158void NuPlayer::performDecoderFlush() {
1159 ALOGV("performDecoderFlush");
1160
1161 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1162 return;
1163 }
1164
1165 mTimeDiscontinuityPending = true;
1166
1167 if (mAudioDecoder != NULL) {
1168 flushDecoder(true /* audio */, false /* needShutdown */);
1169 }
1170
1171 if (mVideoDecoder != NULL) {
1172 flushDecoder(false /* audio */, false /* needShutdown */);
1173 }
1174}
1175
1176void NuPlayer::performDecoderShutdown() {
1177 ALOGV("performDecoderShutdown");
1178
1179 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1180 return;
1181 }
1182
1183 mTimeDiscontinuityPending = true;
1184
1185 if (mAudioDecoder != NULL) {
1186 flushDecoder(true /* audio */, true /* needShutdown */);
1187 }
1188
1189 if (mVideoDecoder != NULL) {
1190 flushDecoder(false /* audio */, true /* needShutdown */);
1191 }
1192}
1193
1194void NuPlayer::performReset() {
1195 ALOGV("performReset");
1196
1197 CHECK(mAudioDecoder == NULL);
1198 CHECK(mVideoDecoder == NULL);
1199
1200 cancelPollDuration();
1201
1202 ++mScanSourcesGeneration;
1203 mScanSourcesPending = false;
1204
1205 mRenderer.clear();
1206
1207 if (mSource != NULL) {
1208 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001209
1210 looper()->unregisterHandler(mSource->id());
1211
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001212 mSource.clear();
1213 }
1214
1215 if (mDriver != NULL) {
1216 sp<NuPlayerDriver> driver = mDriver.promote();
1217 if (driver != NULL) {
1218 driver->notifyResetComplete();
1219 }
1220 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001221
1222 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001223}
1224
1225void NuPlayer::performScanSources() {
1226 ALOGV("performScanSources");
1227
Andreas Huber57a339c2012-12-03 11:18:00 -08001228 if (!mStarted) {
1229 return;
1230 }
1231
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001232 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1233 postScanSources();
1234 }
1235}
1236
Andreas Huber57a339c2012-12-03 11:18:00 -08001237void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1238 ALOGV("performSetSurface");
1239
1240 mNativeWindow = wrapper;
1241
1242 // XXX - ignore error from setVideoScalingMode for now
1243 setVideoScalingMode(mVideoScalingMode);
1244
1245 if (mDriver != NULL) {
1246 sp<NuPlayerDriver> driver = mDriver.promote();
1247 if (driver != NULL) {
1248 driver->notifySetSurfaceComplete();
1249 }
1250 }
1251}
1252
Andreas Huber9575c962013-02-05 13:59:56 -08001253void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1254 int32_t what;
1255 CHECK(msg->findInt32("what", &what));
1256
1257 switch (what) {
1258 case Source::kWhatPrepared:
1259 {
Andreas Huberec0c5972013-02-05 14:47:13 -08001260 int32_t err;
1261 CHECK(msg->findInt32("err", &err));
1262
Andreas Huber9575c962013-02-05 13:59:56 -08001263 sp<NuPlayerDriver> driver = mDriver.promote();
1264 if (driver != NULL) {
Andreas Huberec0c5972013-02-05 14:47:13 -08001265 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08001266 }
1267 break;
1268 }
1269
1270 case Source::kWhatFlagsChanged:
1271 {
1272 uint32_t flags;
1273 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1274
1275 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1276 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1277 cancelPollDuration();
1278 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1279 && (flags & Source::FLAG_DYNAMIC_DURATION)
1280 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1281 schedulePollDuration();
1282 }
1283
1284 mSourceFlags = flags;
1285 break;
1286 }
1287
1288 case Source::kWhatVideoSizeChanged:
1289 {
1290 int32_t width, height;
1291 CHECK(msg->findInt32("width", &width));
1292 CHECK(msg->findInt32("height", &height));
1293
1294 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
1295 break;
1296 }
1297
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001298 case Source::kWhatBufferingStart:
1299 {
1300 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1301 break;
1302 }
1303
1304 case Source::kWhatBufferingEnd:
1305 {
1306 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1307 break;
1308 }
1309
Andreas Huber9575c962013-02-05 13:59:56 -08001310 default:
1311 TRESPASS();
1312 }
1313}
1314
Andreas Huberb5f25f02013-02-05 10:14:26 -08001315////////////////////////////////////////////////////////////////////////////////
1316
Andreas Huber9575c962013-02-05 13:59:56 -08001317void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1318 sp<AMessage> notify = dupNotify();
1319 notify->setInt32("what", kWhatFlagsChanged);
1320 notify->setInt32("flags", flags);
1321 notify->post();
1322}
1323
1324void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
1325 sp<AMessage> notify = dupNotify();
1326 notify->setInt32("what", kWhatVideoSizeChanged);
1327 notify->setInt32("width", width);
1328 notify->setInt32("height", height);
1329 notify->post();
1330}
1331
Andreas Huberec0c5972013-02-05 14:47:13 -08001332void NuPlayer::Source::notifyPrepared(status_t err) {
Andreas Huber9575c962013-02-05 13:59:56 -08001333 sp<AMessage> notify = dupNotify();
1334 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08001335 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08001336 notify->post();
1337}
1338
Andreas Huberb5f25f02013-02-05 10:14:26 -08001339void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1340 TRESPASS();
1341}
1342
Andreas Huberf9334412010-12-15 15:17:42 -08001343} // namespace android