blob: ee25cc65430b1f2b169e5a9c19dd5b3201472abc [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);
735 mRenderer->pause();
736 break;
737 }
738
739 case kWhatResume:
740 {
741 CHECK(mRenderer != NULL);
742 mRenderer->resume();
743 break;
744 }
745
Andreas Huberb5f25f02013-02-05 10:14:26 -0800746 case kWhatSourceNotify:
747 {
Andreas Huber9575c962013-02-05 13:59:56 -0800748 onSourceNotify(msg);
Andreas Huberb5f25f02013-02-05 10:14:26 -0800749 break;
750 }
751
Andreas Huberf9334412010-12-15 15:17:42 -0800752 default:
753 TRESPASS();
754 break;
755 }
756}
757
Andreas Huber3831a062010-12-21 10:22:33 -0800758void NuPlayer::finishFlushIfPossible() {
759 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
760 return;
761 }
762
763 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
764 return;
765 }
766
Steve Block3856b092011-10-20 11:56:00 +0100767 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800768
Andreas Huber6e3d3112011-11-28 12:36:11 -0800769 if (mTimeDiscontinuityPending) {
770 mRenderer->signalTimeDiscontinuity();
771 mTimeDiscontinuityPending = false;
772 }
Andreas Huber3831a062010-12-21 10:22:33 -0800773
Andreas Huber22fc52f2011-01-05 16:24:27 -0800774 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800775 mAudioDecoder->signalResume();
776 }
777
Andreas Huber22fc52f2011-01-05 16:24:27 -0800778 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800779 mVideoDecoder->signalResume();
780 }
781
782 mFlushingAudio = NONE;
783 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800784
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800785 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800786}
787
788void NuPlayer::postScanSources() {
789 if (mScanSourcesPending) {
790 return;
791 }
792
793 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
794 msg->setInt32("generation", mScanSourcesGeneration);
795 msg->post();
796
797 mScanSourcesPending = true;
798}
799
Andreas Huber5bc087c2010-12-23 10:27:40 -0800800status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800801 if (*decoder != NULL) {
802 return OK;
803 }
804
Andreas Huber84066782011-08-16 09:34:26 -0700805 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800806
Andreas Huber84066782011-08-16 09:34:26 -0700807 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800808 return -EWOULDBLOCK;
809 }
810
Andreas Huber3fe62152011-09-16 15:09:22 -0700811 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -0700812 AString mime;
813 CHECK(format->findString("mime", &mime));
814 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Andreas Huber3fe62152011-09-16 15:09:22 -0700815 }
816
Andreas Huberf9334412010-12-15 15:17:42 -0800817 sp<AMessage> notify =
818 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
819 id());
820
Glenn Kasten11731182011-02-08 17:26:17 -0800821 *decoder = audio ? new Decoder(notify) :
822 new Decoder(notify, mNativeWindow);
Andreas Huberf9334412010-12-15 15:17:42 -0800823 looper()->registerHandler(*decoder);
824
Andreas Huber84066782011-08-16 09:34:26 -0700825 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -0800826
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800827 int64_t durationUs;
828 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
829 sp<NuPlayerDriver> driver = mDriver.promote();
830 if (driver != NULL) {
831 driver->notifyDuration(durationUs);
832 }
833 }
834
Andreas Huberf9334412010-12-15 15:17:42 -0800835 return OK;
836}
837
838status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
839 sp<AMessage> reply;
840 CHECK(msg->findMessage("reply", &reply));
841
Andreas Huber53df1a42010-12-22 10:03:04 -0800842 if ((audio && IsFlushingState(mFlushingAudio))
843 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800844 reply->setInt32("err", INFO_DISCONTINUITY);
845 reply->post();
846 return OK;
847 }
848
849 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -0800850
Andreas Huber3fe62152011-09-16 15:09:22 -0700851 bool dropAccessUnit;
852 do {
853 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800854
Andreas Huber3fe62152011-09-16 15:09:22 -0700855 if (err == -EWOULDBLOCK) {
856 return err;
857 } else if (err != OK) {
858 if (err == INFO_DISCONTINUITY) {
859 int32_t type;
860 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -0800861
Andreas Huber3fe62152011-09-16 15:09:22 -0700862 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -0800863 (audio &&
864 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
865 || (!audio &&
866 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -0800867
Andreas Huber6e3d3112011-11-28 12:36:11 -0800868 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
869
Steve Blockdf64d152012-01-04 20:05:49 +0000870 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800871 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -0800872
Andreas Huber3fe62152011-09-16 15:09:22 -0700873 if (audio) {
874 mSkipRenderingAudioUntilMediaTimeUs = -1;
875 } else {
876 mSkipRenderingVideoUntilMediaTimeUs = -1;
877 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800878
Andreas Huber6e3d3112011-11-28 12:36:11 -0800879 if (timeChange) {
880 sp<AMessage> extra;
881 if (accessUnit->meta()->findMessage("extra", &extra)
882 && extra != NULL) {
883 int64_t resumeAtMediaTimeUs;
884 if (extra->findInt64(
885 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +0000886 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800887 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700888
Andreas Huber6e3d3112011-11-28 12:36:11 -0800889 if (audio) {
890 mSkipRenderingAudioUntilMediaTimeUs =
891 resumeAtMediaTimeUs;
892 } else {
893 mSkipRenderingVideoUntilMediaTimeUs =
894 resumeAtMediaTimeUs;
895 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700896 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800897 }
898 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700899
Andreas Huber6e3d3112011-11-28 12:36:11 -0800900 mTimeDiscontinuityPending =
901 mTimeDiscontinuityPending || timeChange;
902
903 if (formatChange || timeChange) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800904 if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
905 // And we'll resume scanning sources once we're done
906 // flushing.
907 mDeferredActions.push_front(
908 new SimpleAction(
909 &NuPlayer::performScanSources));
910 }
911
Andreas Huber6e3d3112011-11-28 12:36:11 -0800912 flushDecoder(audio, formatChange);
913 } else {
914 // This stream is unaffected by the discontinuity
915
916 if (audio) {
917 mFlushingAudio = FLUSHED;
918 } else {
919 mFlushingVideo = FLUSHED;
920 }
921
922 finishFlushIfPossible();
923
924 return -EWOULDBLOCK;
925 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800926 }
927
Andreas Huber3fe62152011-09-16 15:09:22 -0700928 reply->setInt32("err", err);
929 reply->post();
930 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800931 }
932
Andreas Huber3fe62152011-09-16 15:09:22 -0700933 if (!audio) {
934 ++mNumFramesTotal;
935 }
936
937 dropAccessUnit = false;
938 if (!audio
939 && mVideoLateByUs > 100000ll
940 && mVideoIsAVC
941 && !IsAVCReferenceFrame(accessUnit)) {
942 dropAccessUnit = true;
943 ++mNumFramesDropped;
944 }
945 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800946
Steve Block3856b092011-10-20 11:56:00 +0100947 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800948
949#if 0
950 int64_t mediaTimeUs;
951 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +0100952 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800953 audio ? "audio" : "video",
954 mediaTimeUs / 1E6);
955#endif
956
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800957 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800958 reply->post();
959
960 return OK;
961}
962
963void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +0100964 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800965
966 sp<AMessage> reply;
967 CHECK(msg->findMessage("reply", &reply));
968
Andreas Huber18ac5402011-08-31 15:04:25 -0700969 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
970 // We're currently attempting to flush the decoder, in order
971 // to complete this, the decoder wants all its buffers back,
972 // so we don't want any output buffers it sent us (from before
973 // we initiated the flush) to be stuck in the renderer's queue.
974
Steve Block3856b092011-10-20 11:56:00 +0100975 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -0700976 " right back.", audio ? "audio" : "video");
977
978 reply->post();
979 return;
980 }
981
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800982 sp<ABuffer> buffer;
983 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -0800984
Andreas Huber32f3cef2011-03-02 15:34:46 -0800985 int64_t &skipUntilMediaTimeUs =
986 audio
987 ? mSkipRenderingAudioUntilMediaTimeUs
988 : mSkipRenderingVideoUntilMediaTimeUs;
989
990 if (skipUntilMediaTimeUs >= 0) {
991 int64_t mediaTimeUs;
992 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
993
994 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +0100995 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -0800996 audio ? "audio" : "video",
997 mediaTimeUs);
998
999 reply->post();
1000 return;
1001 }
1002
1003 skipUntilMediaTimeUs = -1;
1004 }
1005
Andreas Huberf9334412010-12-15 15:17:42 -08001006 mRenderer->queueBuffer(audio, buffer, reply);
1007}
1008
1009void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001010 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001011 return;
1012 }
1013
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001014 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001015
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001016 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001017 return;
1018 }
1019
Andreas Hubera4af2142011-10-26 15:23:31 -07001020 driver->notifyListener(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -08001021}
1022
Andreas Huber1aef2112011-01-04 14:01:29 -08001023void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001024 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001025 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001026 audio ? "audio" : "video");
1027 }
1028
Andreas Huber1aef2112011-01-04 14:01:29 -08001029 // Make sure we don't continue to scan sources until we finish flushing.
1030 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001031 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001032
1033 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1034 mRenderer->flush(audio);
1035
1036 FlushStatus newStatus =
1037 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1038
1039 if (audio) {
1040 CHECK(mFlushingAudio == NONE
1041 || mFlushingAudio == AWAITING_DISCONTINUITY);
1042
1043 mFlushingAudio = newStatus;
1044
1045 if (mFlushingVideo == NONE) {
1046 mFlushingVideo = (mVideoDecoder != NULL)
1047 ? AWAITING_DISCONTINUITY
1048 : FLUSHED;
1049 }
1050 } else {
1051 CHECK(mFlushingVideo == NONE
1052 || mFlushingVideo == AWAITING_DISCONTINUITY);
1053
1054 mFlushingVideo = newStatus;
1055
1056 if (mFlushingAudio == NONE) {
1057 mFlushingAudio = (mAudioDecoder != NULL)
1058 ? AWAITING_DISCONTINUITY
1059 : FLUSHED;
1060 }
1061 }
1062}
1063
Andreas Huber84066782011-08-16 09:34:26 -07001064sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1065 sp<MetaData> meta = getFormatMeta(audio);
1066
1067 if (meta == NULL) {
1068 return NULL;
1069 }
1070
1071 sp<AMessage> msg = new AMessage;
1072
1073 if(convertMetaDataToMessage(meta, &msg) == OK) {
1074 return msg;
1075 }
1076 return NULL;
1077}
1078
James Dong0d268a32012-08-31 12:18:27 -07001079status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1080 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001081 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001082 status_t ret = native_window_set_scaling_mode(
1083 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1084 if (ret != OK) {
1085 ALOGE("Failed to set scaling mode (%d): %s",
1086 -ret, strerror(-ret));
1087 return ret;
1088 }
1089 }
1090 return OK;
1091}
1092
Andreas Huberb7c8e912012-11-27 15:02:53 -08001093void NuPlayer::schedulePollDuration() {
1094 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1095 msg->setInt32("generation", mPollDurationGeneration);
1096 msg->post();
1097}
1098
1099void NuPlayer::cancelPollDuration() {
1100 ++mPollDurationGeneration;
1101}
1102
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001103void NuPlayer::processDeferredActions() {
1104 while (!mDeferredActions.empty()) {
1105 // We won't execute any deferred actions until we're no longer in
1106 // an intermediate state, i.e. one more more decoders are currently
1107 // flushing or shutting down.
1108
1109 if (mRenderer != NULL) {
1110 // There's an edge case where the renderer owns all output
1111 // buffers and is paused, therefore the decoder will not read
1112 // more input data and will never encounter the matching
1113 // discontinuity. To avoid this, we resume the renderer.
1114
1115 if (mFlushingAudio == AWAITING_DISCONTINUITY
1116 || mFlushingVideo == AWAITING_DISCONTINUITY) {
1117 mRenderer->resume();
1118 }
1119 }
1120
1121 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1122 // We're currently flushing, postpone the reset until that's
1123 // completed.
1124
1125 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1126 mFlushingAudio, mFlushingVideo);
1127
1128 break;
1129 }
1130
1131 sp<Action> action = *mDeferredActions.begin();
1132 mDeferredActions.erase(mDeferredActions.begin());
1133
1134 action->execute(this);
1135 }
1136}
1137
1138void NuPlayer::performSeek(int64_t seekTimeUs) {
1139 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1140 seekTimeUs,
1141 seekTimeUs / 1E6);
1142
1143 mSource->seekTo(seekTimeUs);
1144
1145 if (mDriver != NULL) {
1146 sp<NuPlayerDriver> driver = mDriver.promote();
1147 if (driver != NULL) {
1148 driver->notifyPosition(seekTimeUs);
1149 driver->notifySeekComplete();
1150 }
1151 }
1152
1153 // everything's flushed, continue playback.
1154}
1155
1156void NuPlayer::performDecoderFlush() {
1157 ALOGV("performDecoderFlush");
1158
1159 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1160 return;
1161 }
1162
1163 mTimeDiscontinuityPending = true;
1164
1165 if (mAudioDecoder != NULL) {
1166 flushDecoder(true /* audio */, false /* needShutdown */);
1167 }
1168
1169 if (mVideoDecoder != NULL) {
1170 flushDecoder(false /* audio */, false /* needShutdown */);
1171 }
1172}
1173
1174void NuPlayer::performDecoderShutdown() {
1175 ALOGV("performDecoderShutdown");
1176
1177 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1178 return;
1179 }
1180
1181 mTimeDiscontinuityPending = true;
1182
1183 if (mAudioDecoder != NULL) {
1184 flushDecoder(true /* audio */, true /* needShutdown */);
1185 }
1186
1187 if (mVideoDecoder != NULL) {
1188 flushDecoder(false /* audio */, true /* needShutdown */);
1189 }
1190}
1191
1192void NuPlayer::performReset() {
1193 ALOGV("performReset");
1194
1195 CHECK(mAudioDecoder == NULL);
1196 CHECK(mVideoDecoder == NULL);
1197
1198 cancelPollDuration();
1199
1200 ++mScanSourcesGeneration;
1201 mScanSourcesPending = false;
1202
1203 mRenderer.clear();
1204
1205 if (mSource != NULL) {
1206 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001207
1208 looper()->unregisterHandler(mSource->id());
1209
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001210 mSource.clear();
1211 }
1212
1213 if (mDriver != NULL) {
1214 sp<NuPlayerDriver> driver = mDriver.promote();
1215 if (driver != NULL) {
1216 driver->notifyResetComplete();
1217 }
1218 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001219
1220 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001221}
1222
1223void NuPlayer::performScanSources() {
1224 ALOGV("performScanSources");
1225
Andreas Huber57a339c2012-12-03 11:18:00 -08001226 if (!mStarted) {
1227 return;
1228 }
1229
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001230 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1231 postScanSources();
1232 }
1233}
1234
Andreas Huber57a339c2012-12-03 11:18:00 -08001235void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1236 ALOGV("performSetSurface");
1237
1238 mNativeWindow = wrapper;
1239
1240 // XXX - ignore error from setVideoScalingMode for now
1241 setVideoScalingMode(mVideoScalingMode);
1242
1243 if (mDriver != NULL) {
1244 sp<NuPlayerDriver> driver = mDriver.promote();
1245 if (driver != NULL) {
1246 driver->notifySetSurfaceComplete();
1247 }
1248 }
1249}
1250
Andreas Huber9575c962013-02-05 13:59:56 -08001251void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1252 int32_t what;
1253 CHECK(msg->findInt32("what", &what));
1254
1255 switch (what) {
1256 case Source::kWhatPrepared:
1257 {
Andreas Huberec0c5972013-02-05 14:47:13 -08001258 int32_t err;
1259 CHECK(msg->findInt32("err", &err));
1260
Andreas Huber9575c962013-02-05 13:59:56 -08001261 sp<NuPlayerDriver> driver = mDriver.promote();
1262 if (driver != NULL) {
Andreas Huberec0c5972013-02-05 14:47:13 -08001263 driver->notifyPrepareCompleted(err);
Andreas Huber9575c962013-02-05 13:59:56 -08001264 }
1265 break;
1266 }
1267
1268 case Source::kWhatFlagsChanged:
1269 {
1270 uint32_t flags;
1271 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1272
1273 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1274 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1275 cancelPollDuration();
1276 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1277 && (flags & Source::FLAG_DYNAMIC_DURATION)
1278 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1279 schedulePollDuration();
1280 }
1281
1282 mSourceFlags = flags;
1283 break;
1284 }
1285
1286 case Source::kWhatVideoSizeChanged:
1287 {
1288 int32_t width, height;
1289 CHECK(msg->findInt32("width", &width));
1290 CHECK(msg->findInt32("height", &height));
1291
1292 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
1293 break;
1294 }
1295
Roger Jönssonb50e83e2013-01-21 16:26:41 +01001296 case Source::kWhatBufferingStart:
1297 {
1298 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1299 break;
1300 }
1301
1302 case Source::kWhatBufferingEnd:
1303 {
1304 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1305 break;
1306 }
1307
Andreas Huber9575c962013-02-05 13:59:56 -08001308 default:
1309 TRESPASS();
1310 }
1311}
1312
Andreas Huberb5f25f02013-02-05 10:14:26 -08001313////////////////////////////////////////////////////////////////////////////////
1314
Andreas Huber9575c962013-02-05 13:59:56 -08001315void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1316 sp<AMessage> notify = dupNotify();
1317 notify->setInt32("what", kWhatFlagsChanged);
1318 notify->setInt32("flags", flags);
1319 notify->post();
1320}
1321
1322void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
1323 sp<AMessage> notify = dupNotify();
1324 notify->setInt32("what", kWhatVideoSizeChanged);
1325 notify->setInt32("width", width);
1326 notify->setInt32("height", height);
1327 notify->post();
1328}
1329
Andreas Huberec0c5972013-02-05 14:47:13 -08001330void NuPlayer::Source::notifyPrepared(status_t err) {
Andreas Huber9575c962013-02-05 13:59:56 -08001331 sp<AMessage> notify = dupNotify();
1332 notify->setInt32("what", kWhatPrepared);
Andreas Huberec0c5972013-02-05 14:47:13 -08001333 notify->setInt32("err", err);
Andreas Huber9575c962013-02-05 13:59:56 -08001334 notify->post();
1335}
1336
Andreas Huberb5f25f02013-02-05 10:14:26 -08001337void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1338 TRESPASS();
1339}
1340
Andreas Huberf9334412010-12-15 15:17:42 -08001341} // namespace android