blob: 9585abaf85f444912861115f75c3e540266a0ea9 [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 Huber3fe62152011-09-16 15:09:22 -0700115 mVideoIsAVC(false),
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700116 mAudioEOS(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800117 mVideoEOS(false),
Andreas Huber5bc087c2010-12-23 10:27:40 -0800118 mScanSourcesPending(false),
Andreas Huber1aef2112011-01-04 14:01:29 -0800119 mScanSourcesGeneration(0),
Andreas Huberb7c8e912012-11-27 15:02:53 -0800120 mPollDurationGeneration(0),
Andreas Huber6e3d3112011-11-28 12:36:11 -0800121 mTimeDiscontinuityPending(false),
Andreas Huberf9334412010-12-15 15:17:42 -0800122 mFlushingAudio(NONE),
Andreas Huber1aef2112011-01-04 14:01:29 -0800123 mFlushingVideo(NONE),
Andreas Huber3fe62152011-09-16 15:09:22 -0700124 mSkipRenderingAudioUntilMediaTimeUs(-1ll),
125 mSkipRenderingVideoUntilMediaTimeUs(-1ll),
126 mVideoLateByUs(0ll),
127 mNumFramesTotal(0ll),
James Dong0d268a32012-08-31 12:18:27 -0700128 mNumFramesDropped(0ll),
Andreas Huber57a339c2012-12-03 11:18:00 -0800129 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
130 mStarted(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800131}
132
133NuPlayer::~NuPlayer() {
134}
135
Andreas Huber9b80c2b2011-06-30 15:47:02 -0700136void NuPlayer::setUID(uid_t uid) {
137 mUIDValid = true;
138 mUID = uid;
139}
140
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800141void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
142 mDriver = driver;
Andreas Huberf9334412010-12-15 15:17:42 -0800143}
144
145void NuPlayer::setDataSource(const sp<IStreamSource> &source) {
146 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
147
Andreas Huberb5f25f02013-02-05 10:14:26 -0800148 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
149
Andreas Huber84066782011-08-16 09:34:26 -0700150 char prop[PROPERTY_VALUE_MAX];
151 if (property_get("media.stagefright.use-mp4source", prop, NULL)
152 && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800153 msg->setObject("source", new MP4Source(notify, source));
Andreas Huber84066782011-08-16 09:34:26 -0700154 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800155 msg->setObject("source", new StreamingSource(notify, source));
Andreas Huber84066782011-08-16 09:34:26 -0700156 }
157
Andreas Huber5bc087c2010-12-23 10:27:40 -0800158 msg->post();
159}
Andreas Huberf9334412010-12-15 15:17:42 -0800160
Andreas Huberafed0e12011-09-20 15:39:58 -0700161static bool IsHTTPLiveURL(const char *url) {
162 if (!strncasecmp("http://", url, 7)
163 || !strncasecmp("https://", url, 8)) {
164 size_t len = strlen(url);
165 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
166 return true;
167 }
168
169 if (strstr(url,"m3u8")) {
170 return true;
171 }
172 }
173
174 return false;
175}
176
Andreas Huber5bc087c2010-12-23 10:27:40 -0800177void NuPlayer::setDataSource(
178 const char *url, const KeyedVector<String8, String8> *headers) {
179 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
180
Andreas Huberb5f25f02013-02-05 10:14:26 -0800181 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
182
Andreas Huberafed0e12011-09-20 15:39:58 -0700183 sp<Source> source;
184 if (IsHTTPLiveURL(url)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800185 source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
Andreas Huberafed0e12011-09-20 15:39:58 -0700186 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800187 source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700188 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800189 source = new GenericSource(notify, url, headers, mUIDValid, mUID);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700190 }
191
Andreas Huberafed0e12011-09-20 15:39:58 -0700192 msg->setObject("source", source);
193 msg->post();
194}
195
196void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
197 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
198
Andreas Huberb5f25f02013-02-05 10:14:26 -0800199 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
200
201 sp<Source> source = new GenericSource(notify, fd, offset, length);
Andreas Huberafed0e12011-09-20 15:39:58 -0700202 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800203 msg->post();
204}
205
Andreas Huber57a339c2012-12-03 11:18:00 -0800206void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800207 const sp<IGraphicBufferProducer> &bufferProducer) {
Glenn Kasten11731182011-02-08 17:26:17 -0800208 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
Andreas Huber57a339c2012-12-03 11:18:00 -0800209
Andy McFadden8ba01022012-12-18 09:46:54 -0800210 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800211 msg->setObject("native-window", NULL);
212 } else {
213 msg->setObject(
214 "native-window",
215 new NativeWindowWrapper(
Andy McFadden8ba01022012-12-18 09:46:54 -0800216 new SurfaceTextureClient(bufferProducer)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800217 }
218
Andreas Huberf9334412010-12-15 15:17:42 -0800219 msg->post();
220}
221
222void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
223 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
224 msg->setObject("sink", sink);
225 msg->post();
226}
227
228void NuPlayer::start() {
229 (new AMessage(kWhatStart, id()))->post();
230}
231
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800232void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800233 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800234}
235
236void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800237 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800238}
239
Andreas Huber1aef2112011-01-04 14:01:29 -0800240void NuPlayer::resetAsync() {
241 (new AMessage(kWhatReset, id()))->post();
242}
243
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800244void NuPlayer::seekToAsync(int64_t seekTimeUs) {
245 sp<AMessage> msg = new AMessage(kWhatSeek, id());
246 msg->setInt64("seekTimeUs", seekTimeUs);
247 msg->post();
248}
249
Andreas Huber53df1a42010-12-22 10:03:04 -0800250// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800251bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800252 switch (state) {
253 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800254 if (needShutdown != NULL) {
255 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800256 }
257 return true;
258
Andreas Huber1aef2112011-01-04 14:01:29 -0800259 case FLUSHING_DECODER_SHUTDOWN:
260 if (needShutdown != NULL) {
261 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800262 }
263 return true;
264
265 default:
266 return false;
267 }
268}
269
Andreas Huberf9334412010-12-15 15:17:42 -0800270void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
271 switch (msg->what()) {
272 case kWhatSetDataSource:
273 {
Steve Block3856b092011-10-20 11:56:00 +0100274 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800275
276 CHECK(mSource == NULL);
277
Andreas Huber5bc087c2010-12-23 10:27:40 -0800278 sp<RefBase> obj;
279 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800280
Andreas Huber5bc087c2010-12-23 10:27:40 -0800281 mSource = static_cast<Source *>(obj.get());
Andreas Huberb5f25f02013-02-05 10:14:26 -0800282
283 looper()->registerHandler(mSource);
Andreas Huberf9334412010-12-15 15:17:42 -0800284 break;
285 }
286
Andreas Huberb7c8e912012-11-27 15:02:53 -0800287 case kWhatPollDuration:
288 {
289 int32_t generation;
290 CHECK(msg->findInt32("generation", &generation));
291
292 if (generation != mPollDurationGeneration) {
293 // stale
294 break;
295 }
296
297 int64_t durationUs;
298 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
299 sp<NuPlayerDriver> driver = mDriver.promote();
300 if (driver != NULL) {
301 driver->notifyDuration(durationUs);
302 }
303 }
304
305 msg->post(1000000ll); // poll again in a second.
306 break;
307 }
308
Glenn Kasten11731182011-02-08 17:26:17 -0800309 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800310 {
Steve Block3856b092011-10-20 11:56:00 +0100311 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800312
Andreas Huber57a339c2012-12-03 11:18:00 -0800313 mDeferredActions.push_back(
314 new SimpleAction(&NuPlayer::performDecoderShutdown));
315
Andreas Huberf9334412010-12-15 15:17:42 -0800316 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800317 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800318
Andreas Huber57a339c2012-12-03 11:18:00 -0800319 mDeferredActions.push_back(
320 new SetSurfaceAction(
321 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700322
Andreas Huber57a339c2012-12-03 11:18:00 -0800323 if (obj != NULL) {
324 // If there is a new surface texture, instantiate decoders
325 // again if possible.
326 mDeferredActions.push_back(
327 new SimpleAction(&NuPlayer::performScanSources));
328 }
329
330 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800331 break;
332 }
333
334 case kWhatSetAudioSink:
335 {
Steve Block3856b092011-10-20 11:56:00 +0100336 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800337
338 sp<RefBase> obj;
339 CHECK(msg->findObject("sink", &obj));
340
341 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
342 break;
343 }
344
345 case kWhatStart:
346 {
Steve Block3856b092011-10-20 11:56:00 +0100347 ALOGV("kWhatStart");
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800348
Andreas Huber3fe62152011-09-16 15:09:22 -0700349 mVideoIsAVC = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800350 mAudioEOS = false;
351 mVideoEOS = false;
Andreas Huber32f3cef2011-03-02 15:34:46 -0800352 mSkipRenderingAudioUntilMediaTimeUs = -1;
353 mSkipRenderingVideoUntilMediaTimeUs = -1;
Andreas Huber3fe62152011-09-16 15:09:22 -0700354 mVideoLateByUs = 0;
355 mNumFramesTotal = 0;
356 mNumFramesDropped = 0;
Andreas Huber57a339c2012-12-03 11:18:00 -0800357 mStarted = true;
Andreas Huber1aef2112011-01-04 14:01:29 -0800358
Andreas Huber5bc087c2010-12-23 10:27:40 -0800359 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800360
361 mRenderer = new Renderer(
362 mAudioSink,
363 new AMessage(kWhatRendererNotify, id()));
364
365 looper()->registerHandler(mRenderer);
366
Andreas Huber1aef2112011-01-04 14:01:29 -0800367 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800368 break;
369 }
370
371 case kWhatScanSources:
372 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800373 int32_t generation;
374 CHECK(msg->findInt32("generation", &generation));
375 if (generation != mScanSourcesGeneration) {
376 // Drop obsolete msg.
377 break;
378 }
379
Andreas Huber5bc087c2010-12-23 10:27:40 -0800380 mScanSourcesPending = false;
381
Steve Block3856b092011-10-20 11:56:00 +0100382 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800383 mAudioDecoder != NULL, mVideoDecoder != NULL);
384
Andreas Huberb7c8e912012-11-27 15:02:53 -0800385 bool mHadAnySourcesBefore =
386 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
387
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700388 if (mNativeWindow != NULL) {
389 instantiateDecoder(false, &mVideoDecoder);
390 }
Andreas Huberf9334412010-12-15 15:17:42 -0800391
392 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800393 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800394 }
395
Andreas Huberb7c8e912012-11-27 15:02:53 -0800396 if (!mHadAnySourcesBefore
397 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
398 // This is the first time we've found anything playable.
399
400 uint32_t flags = mSource->flags();
401
402 if (flags & Source::FLAG_DYNAMIC_DURATION) {
403 schedulePollDuration();
404 }
405 }
406
Andreas Hubereac68ba2011-09-27 12:12:25 -0700407 status_t err;
408 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800409 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
410 // We're not currently decoding anything (no audio or
411 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700412
413 if (err == ERROR_END_OF_STREAM) {
414 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
415 } else {
416 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
417 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800418 }
Andreas Huberf9334412010-12-15 15:17:42 -0800419 break;
420 }
421
Andreas Huberfbe9d812012-08-31 14:05:27 -0700422 if ((mAudioDecoder == NULL && mAudioSink != NULL)
423 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800424 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800425 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800426 }
427 break;
428 }
429
430 case kWhatVideoNotify:
431 case kWhatAudioNotify:
432 {
433 bool audio = msg->what() == kWhatAudioNotify;
434
435 sp<AMessage> codecRequest;
436 CHECK(msg->findMessage("codec-request", &codecRequest));
437
438 int32_t what;
439 CHECK(codecRequest->findInt32("what", &what));
440
441 if (what == ACodec::kWhatFillThisBuffer) {
442 status_t err = feedDecoderInputData(
443 audio, codecRequest);
444
Andreas Huber5bc087c2010-12-23 10:27:40 -0800445 if (err == -EWOULDBLOCK) {
Andreas Hubereac68ba2011-09-27 12:12:25 -0700446 if (mSource->feedMoreTSData() == OK) {
Andreas Huber1183a4a2011-11-03 11:00:21 -0700447 msg->post(10000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800448 }
Andreas Huberf9334412010-12-15 15:17:42 -0800449 }
450 } else if (what == ACodec::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700451 int32_t err;
452 CHECK(codecRequest->findInt32("err", &err));
453
454 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100455 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700456 } else {
Steve Block3856b092011-10-20 11:56:00 +0100457 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700458 audio ? "audio" : "video",
459 err);
460 }
461
462 mRenderer->queueEOS(audio, err);
Andreas Huberf9334412010-12-15 15:17:42 -0800463 } else if (what == ACodec::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800464 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800465
Andreas Huberf9334412010-12-15 15:17:42 -0800466 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800467 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800468 mFlushingAudio = FLUSHED;
469 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800470 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800471 mFlushingVideo = FLUSHED;
Andreas Huber3fe62152011-09-16 15:09:22 -0700472
473 mVideoLateByUs = 0;
Andreas Huberf9334412010-12-15 15:17:42 -0800474 }
475
Steve Block3856b092011-10-20 11:56:00 +0100476 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800477
Andreas Huber1aef2112011-01-04 14:01:29 -0800478 if (needShutdown) {
Steve Block3856b092011-10-20 11:56:00 +0100479 ALOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800480 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800481
Andreas Huber53df1a42010-12-22 10:03:04 -0800482 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800483
Andreas Huber53df1a42010-12-22 10:03:04 -0800484 if (audio) {
485 mFlushingAudio = SHUTTING_DOWN_DECODER;
486 } else {
487 mFlushingVideo = SHUTTING_DOWN_DECODER;
488 }
Andreas Huberf9334412010-12-15 15:17:42 -0800489 }
Andreas Huber3831a062010-12-21 10:22:33 -0800490
491 finishFlushIfPossible();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800492 } else if (what == ACodec::kWhatOutputFormatChanged) {
Andreas Huber31e25082011-01-10 10:38:31 -0800493 if (audio) {
494 int32_t numChannels;
Andreas Huber516dacf2012-12-03 15:20:40 -0800495 CHECK(codecRequest->findInt32(
496 "channel-count", &numChannels));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800497
Andreas Huber31e25082011-01-10 10:38:31 -0800498 int32_t sampleRate;
499 CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800500
Steve Block3856b092011-10-20 11:56:00 +0100501 ALOGV("Audio output format changed to %d Hz, %d channels",
Andreas Huber31e25082011-01-10 10:38:31 -0800502 sampleRate, numChannels);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800503
Andreas Huber31e25082011-01-10 10:38:31 -0800504 mAudioSink->close();
Eric Laurent1948eb32012-04-13 16:50:19 -0700505
506 audio_output_flags_t flags;
507 int64_t durationUs;
Andreas Huber516dacf2012-12-03 15:20:40 -0800508 // FIXME: we should handle the case where the video decoder
509 // is created after we receive the format change indication.
510 // Current code will just make that we select deep buffer
511 // with video which should not be a problem as it should
Eric Laurent1948eb32012-04-13 16:50:19 -0700512 // not prevent from keeping A/V sync.
513 if (mVideoDecoder == NULL &&
514 mSource->getDuration(&durationUs) == OK &&
Andreas Huber516dacf2012-12-03 15:20:40 -0800515 durationUs
516 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
Eric Laurent1948eb32012-04-13 16:50:19 -0700517 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
518 } else {
519 flags = AUDIO_OUTPUT_FLAG_NONE;
520 }
521
Andreas Huber98065552012-05-03 11:33:01 -0700522 int32_t channelMask;
523 if (!codecRequest->findInt32("channel-mask", &channelMask)) {
524 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
525 }
526
Andreas Huber078cfcf2011-09-15 12:25:04 -0700527 CHECK_EQ(mAudioSink->open(
528 sampleRate,
529 numChannels,
Andreas Huber98065552012-05-03 11:33:01 -0700530 (audio_channel_mask_t)channelMask,
Andreas Huber078cfcf2011-09-15 12:25:04 -0700531 AUDIO_FORMAT_PCM_16_BIT,
Eric Laurent1948eb32012-04-13 16:50:19 -0700532 8 /* bufferCount */,
533 NULL,
534 NULL,
535 flags),
Andreas Huber078cfcf2011-09-15 12:25:04 -0700536 (status_t)OK);
Andreas Huber31e25082011-01-10 10:38:31 -0800537 mAudioSink->start();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800538
Andreas Huber31e25082011-01-10 10:38:31 -0800539 mRenderer->signalAudioSinkChanged();
540 } else {
541 // video
Andreas Huber3831a062010-12-21 10:22:33 -0800542
Andreas Huber31e25082011-01-10 10:38:31 -0800543 int32_t width, height;
544 CHECK(codecRequest->findInt32("width", &width));
545 CHECK(codecRequest->findInt32("height", &height));
546
547 int32_t cropLeft, cropTop, cropRight, cropBottom;
548 CHECK(codecRequest->findRect(
549 "crop",
550 &cropLeft, &cropTop, &cropRight, &cropBottom));
551
Andreas Huber516dacf2012-12-03 15:20:40 -0800552 int32_t displayWidth = cropRight - cropLeft + 1;
553 int32_t displayHeight = cropBottom - cropTop + 1;
554
Steve Block3856b092011-10-20 11:56:00 +0100555 ALOGV("Video output format changed to %d x %d "
Andreas Hubercb67cd12011-08-26 16:02:19 -0700556 "(crop: %d x %d @ (%d, %d))",
Andreas Huber31e25082011-01-10 10:38:31 -0800557 width, height,
Andreas Huber516dacf2012-12-03 15:20:40 -0800558 displayWidth,
559 displayHeight,
Andreas Hubercb67cd12011-08-26 16:02:19 -0700560 cropLeft, cropTop);
Andreas Huber31e25082011-01-10 10:38:31 -0800561
Andreas Huber516dacf2012-12-03 15:20:40 -0800562 sp<AMessage> videoInputFormat =
563 mSource->getFormat(false /* audio */);
564
565 // Take into account sample aspect ratio if necessary:
566 int32_t sarWidth, sarHeight;
567 if (videoInputFormat->findInt32("sar-width", &sarWidth)
568 && videoInputFormat->findInt32(
569 "sar-height", &sarHeight)) {
570 ALOGV("Sample aspect ratio %d : %d",
571 sarWidth, sarHeight);
572
573 displayWidth = (displayWidth * sarWidth) / sarHeight;
574
575 ALOGV("display dimensions %d x %d",
576 displayWidth, displayHeight);
577 }
578
Andreas Huber31e25082011-01-10 10:38:31 -0800579 notifyListener(
Andreas Huber516dacf2012-12-03 15:20:40 -0800580 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
Andreas Huber31e25082011-01-10 10:38:31 -0800581 }
Andreas Huber3831a062010-12-21 10:22:33 -0800582 } else if (what == ACodec::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100583 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800584 if (audio) {
585 mAudioDecoder.clear();
586
587 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
588 mFlushingAudio = SHUT_DOWN;
589 } else {
590 mVideoDecoder.clear();
591
592 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
593 mFlushingVideo = SHUT_DOWN;
594 }
595
596 finishFlushIfPossible();
Andreas Huberc92fd242011-08-16 13:48:44 -0700597 } else if (what == ACodec::kWhatError) {
Steve Block29357bc2012-01-06 19:20:56 +0000598 ALOGE("Received error from %s decoder, aborting playback.",
Andreas Huberc92fd242011-08-16 13:48:44 -0700599 audio ? "audio" : "video");
600
601 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
Andreas Huber57788222012-02-21 11:47:18 -0800602 } else if (what == ACodec::kWhatDrainThisBuffer) {
Andreas Huberf9334412010-12-15 15:17:42 -0800603 renderBuffer(audio, codecRequest);
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800604 } else if (what != ACodec::kWhatComponentAllocated
605 && what != ACodec::kWhatComponentConfigured
606 && what != ACodec::kWhatBuffersAllocated) {
607 ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
608 what,
609 what >> 24,
610 (what >> 16) & 0xff,
611 (what >> 8) & 0xff,
612 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800613 }
614
615 break;
616 }
617
618 case kWhatRendererNotify:
619 {
620 int32_t what;
621 CHECK(msg->findInt32("what", &what));
622
623 if (what == Renderer::kWhatEOS) {
624 int32_t audio;
625 CHECK(msg->findInt32("audio", &audio));
626
Andreas Huberc92fd242011-08-16 13:48:44 -0700627 int32_t finalResult;
628 CHECK(msg->findInt32("finalResult", &finalResult));
629
Andreas Huberf9334412010-12-15 15:17:42 -0800630 if (audio) {
631 mAudioEOS = true;
632 } else {
633 mVideoEOS = true;
634 }
635
Andreas Huberc92fd242011-08-16 13:48:44 -0700636 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100637 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700638 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000639 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700640 audio ? "audio" : "video", finalResult);
641
642 notifyListener(
643 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
644 }
Andreas Huberf9334412010-12-15 15:17:42 -0800645
646 if ((mAudioEOS || mAudioDecoder == NULL)
647 && (mVideoEOS || mVideoDecoder == NULL)) {
648 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
649 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800650 } else if (what == Renderer::kWhatPosition) {
651 int64_t positionUs;
652 CHECK(msg->findInt64("positionUs", &positionUs));
653
Andreas Huber3fe62152011-09-16 15:09:22 -0700654 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
655
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800656 if (mDriver != NULL) {
657 sp<NuPlayerDriver> driver = mDriver.promote();
658 if (driver != NULL) {
659 driver->notifyPosition(positionUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700660
661 driver->notifyFrameStats(
662 mNumFramesTotal, mNumFramesDropped);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800663 }
664 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700665 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800666 int32_t audio;
667 CHECK(msg->findInt32("audio", &audio));
668
Steve Block3856b092011-10-20 11:56:00 +0100669 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
James Dongf57b4ea2012-07-20 13:38:36 -0700670 } else if (what == Renderer::kWhatVideoRenderingStart) {
671 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Andreas Huberf9334412010-12-15 15:17:42 -0800672 }
673 break;
674 }
675
676 case kWhatMoreDataQueued:
677 {
678 break;
679 }
680
Andreas Huber1aef2112011-01-04 14:01:29 -0800681 case kWhatReset:
682 {
Steve Block3856b092011-10-20 11:56:00 +0100683 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800684
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800685 mDeferredActions.push_back(
686 new SimpleAction(&NuPlayer::performDecoderShutdown));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800687
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800688 mDeferredActions.push_back(
689 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800690
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800691 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800692 break;
693 }
694
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800695 case kWhatSeek:
696 {
697 int64_t seekTimeUs;
698 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
699
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800700 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800701
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800702 mDeferredActions.push_back(
703 new SimpleAction(&NuPlayer::performDecoderFlush));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800704
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800705 mDeferredActions.push_back(new SeekAction(seekTimeUs));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800706
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800707 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800708 break;
709 }
710
Andreas Huberb4082222011-01-20 15:23:04 -0800711 case kWhatPause:
712 {
713 CHECK(mRenderer != NULL);
714 mRenderer->pause();
715 break;
716 }
717
718 case kWhatResume:
719 {
720 CHECK(mRenderer != NULL);
721 mRenderer->resume();
722 break;
723 }
724
Andreas Huberb5f25f02013-02-05 10:14:26 -0800725 case kWhatSourceNotify:
726 {
727 TRESPASS(); // TBD
728 break;
729 }
730
Andreas Huberf9334412010-12-15 15:17:42 -0800731 default:
732 TRESPASS();
733 break;
734 }
735}
736
Andreas Huber3831a062010-12-21 10:22:33 -0800737void NuPlayer::finishFlushIfPossible() {
738 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
739 return;
740 }
741
742 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
743 return;
744 }
745
Steve Block3856b092011-10-20 11:56:00 +0100746 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800747
Andreas Huber6e3d3112011-11-28 12:36:11 -0800748 if (mTimeDiscontinuityPending) {
749 mRenderer->signalTimeDiscontinuity();
750 mTimeDiscontinuityPending = false;
751 }
Andreas Huber3831a062010-12-21 10:22:33 -0800752
Andreas Huber22fc52f2011-01-05 16:24:27 -0800753 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800754 mAudioDecoder->signalResume();
755 }
756
Andreas Huber22fc52f2011-01-05 16:24:27 -0800757 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800758 mVideoDecoder->signalResume();
759 }
760
761 mFlushingAudio = NONE;
762 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800763
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800764 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800765}
766
767void NuPlayer::postScanSources() {
768 if (mScanSourcesPending) {
769 return;
770 }
771
772 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
773 msg->setInt32("generation", mScanSourcesGeneration);
774 msg->post();
775
776 mScanSourcesPending = true;
777}
778
Andreas Huber5bc087c2010-12-23 10:27:40 -0800779status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800780 if (*decoder != NULL) {
781 return OK;
782 }
783
Andreas Huber84066782011-08-16 09:34:26 -0700784 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800785
Andreas Huber84066782011-08-16 09:34:26 -0700786 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800787 return -EWOULDBLOCK;
788 }
789
Andreas Huber3fe62152011-09-16 15:09:22 -0700790 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -0700791 AString mime;
792 CHECK(format->findString("mime", &mime));
793 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Andreas Huber3fe62152011-09-16 15:09:22 -0700794 }
795
Andreas Huberf9334412010-12-15 15:17:42 -0800796 sp<AMessage> notify =
797 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
798 id());
799
Glenn Kasten11731182011-02-08 17:26:17 -0800800 *decoder = audio ? new Decoder(notify) :
801 new Decoder(notify, mNativeWindow);
Andreas Huberf9334412010-12-15 15:17:42 -0800802 looper()->registerHandler(*decoder);
803
Andreas Huber84066782011-08-16 09:34:26 -0700804 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -0800805
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800806 int64_t durationUs;
807 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
808 sp<NuPlayerDriver> driver = mDriver.promote();
809 if (driver != NULL) {
810 driver->notifyDuration(durationUs);
811 }
812 }
813
Andreas Huberf9334412010-12-15 15:17:42 -0800814 return OK;
815}
816
817status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
818 sp<AMessage> reply;
819 CHECK(msg->findMessage("reply", &reply));
820
Andreas Huber53df1a42010-12-22 10:03:04 -0800821 if ((audio && IsFlushingState(mFlushingAudio))
822 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800823 reply->setInt32("err", INFO_DISCONTINUITY);
824 reply->post();
825 return OK;
826 }
827
828 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -0800829
Andreas Huber3fe62152011-09-16 15:09:22 -0700830 bool dropAccessUnit;
831 do {
832 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800833
Andreas Huber3fe62152011-09-16 15:09:22 -0700834 if (err == -EWOULDBLOCK) {
835 return err;
836 } else if (err != OK) {
837 if (err == INFO_DISCONTINUITY) {
838 int32_t type;
839 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -0800840
Andreas Huber3fe62152011-09-16 15:09:22 -0700841 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -0800842 (audio &&
843 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
844 || (!audio &&
845 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -0800846
Andreas Huber6e3d3112011-11-28 12:36:11 -0800847 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
848
Steve Blockdf64d152012-01-04 20:05:49 +0000849 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800850 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -0800851
Andreas Huber3fe62152011-09-16 15:09:22 -0700852 if (audio) {
853 mSkipRenderingAudioUntilMediaTimeUs = -1;
854 } else {
855 mSkipRenderingVideoUntilMediaTimeUs = -1;
856 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800857
Andreas Huber6e3d3112011-11-28 12:36:11 -0800858 if (timeChange) {
859 sp<AMessage> extra;
860 if (accessUnit->meta()->findMessage("extra", &extra)
861 && extra != NULL) {
862 int64_t resumeAtMediaTimeUs;
863 if (extra->findInt64(
864 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +0000865 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800866 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700867
Andreas Huber6e3d3112011-11-28 12:36:11 -0800868 if (audio) {
869 mSkipRenderingAudioUntilMediaTimeUs =
870 resumeAtMediaTimeUs;
871 } else {
872 mSkipRenderingVideoUntilMediaTimeUs =
873 resumeAtMediaTimeUs;
874 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700875 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800876 }
877 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700878
Andreas Huber6e3d3112011-11-28 12:36:11 -0800879 mTimeDiscontinuityPending =
880 mTimeDiscontinuityPending || timeChange;
881
882 if (formatChange || timeChange) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800883 if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
884 // And we'll resume scanning sources once we're done
885 // flushing.
886 mDeferredActions.push_front(
887 new SimpleAction(
888 &NuPlayer::performScanSources));
889 }
890
Andreas Huber6e3d3112011-11-28 12:36:11 -0800891 flushDecoder(audio, formatChange);
892 } else {
893 // This stream is unaffected by the discontinuity
894
895 if (audio) {
896 mFlushingAudio = FLUSHED;
897 } else {
898 mFlushingVideo = FLUSHED;
899 }
900
901 finishFlushIfPossible();
902
903 return -EWOULDBLOCK;
904 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800905 }
906
Andreas Huber3fe62152011-09-16 15:09:22 -0700907 reply->setInt32("err", err);
908 reply->post();
909 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800910 }
911
Andreas Huber3fe62152011-09-16 15:09:22 -0700912 if (!audio) {
913 ++mNumFramesTotal;
914 }
915
916 dropAccessUnit = false;
917 if (!audio
918 && mVideoLateByUs > 100000ll
919 && mVideoIsAVC
920 && !IsAVCReferenceFrame(accessUnit)) {
921 dropAccessUnit = true;
922 ++mNumFramesDropped;
923 }
924 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800925
Steve Block3856b092011-10-20 11:56:00 +0100926 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800927
928#if 0
929 int64_t mediaTimeUs;
930 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +0100931 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800932 audio ? "audio" : "video",
933 mediaTimeUs / 1E6);
934#endif
935
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800936 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800937 reply->post();
938
939 return OK;
940}
941
942void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +0100943 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800944
945 sp<AMessage> reply;
946 CHECK(msg->findMessage("reply", &reply));
947
Andreas Huber18ac5402011-08-31 15:04:25 -0700948 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
949 // We're currently attempting to flush the decoder, in order
950 // to complete this, the decoder wants all its buffers back,
951 // so we don't want any output buffers it sent us (from before
952 // we initiated the flush) to be stuck in the renderer's queue.
953
Steve Block3856b092011-10-20 11:56:00 +0100954 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -0700955 " right back.", audio ? "audio" : "video");
956
957 reply->post();
958 return;
959 }
960
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800961 sp<ABuffer> buffer;
962 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -0800963
Andreas Huber32f3cef2011-03-02 15:34:46 -0800964 int64_t &skipUntilMediaTimeUs =
965 audio
966 ? mSkipRenderingAudioUntilMediaTimeUs
967 : mSkipRenderingVideoUntilMediaTimeUs;
968
969 if (skipUntilMediaTimeUs >= 0) {
970 int64_t mediaTimeUs;
971 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
972
973 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +0100974 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -0800975 audio ? "audio" : "video",
976 mediaTimeUs);
977
978 reply->post();
979 return;
980 }
981
982 skipUntilMediaTimeUs = -1;
983 }
984
Andreas Huberf9334412010-12-15 15:17:42 -0800985 mRenderer->queueBuffer(audio, buffer, reply);
986}
987
988void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800989 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800990 return;
991 }
992
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800993 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -0800994
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800995 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800996 return;
997 }
998
Andreas Hubera4af2142011-10-26 15:23:31 -0700999 driver->notifyListener(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -08001000}
1001
Andreas Huber1aef2112011-01-04 14:01:29 -08001002void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001003 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001004 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001005 audio ? "audio" : "video");
1006 }
1007
Andreas Huber1aef2112011-01-04 14:01:29 -08001008 // Make sure we don't continue to scan sources until we finish flushing.
1009 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001010 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001011
1012 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1013 mRenderer->flush(audio);
1014
1015 FlushStatus newStatus =
1016 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1017
1018 if (audio) {
1019 CHECK(mFlushingAudio == NONE
1020 || mFlushingAudio == AWAITING_DISCONTINUITY);
1021
1022 mFlushingAudio = newStatus;
1023
1024 if (mFlushingVideo == NONE) {
1025 mFlushingVideo = (mVideoDecoder != NULL)
1026 ? AWAITING_DISCONTINUITY
1027 : FLUSHED;
1028 }
1029 } else {
1030 CHECK(mFlushingVideo == NONE
1031 || mFlushingVideo == AWAITING_DISCONTINUITY);
1032
1033 mFlushingVideo = newStatus;
1034
1035 if (mFlushingAudio == NONE) {
1036 mFlushingAudio = (mAudioDecoder != NULL)
1037 ? AWAITING_DISCONTINUITY
1038 : FLUSHED;
1039 }
1040 }
1041}
1042
Andreas Huber84066782011-08-16 09:34:26 -07001043sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1044 sp<MetaData> meta = getFormatMeta(audio);
1045
1046 if (meta == NULL) {
1047 return NULL;
1048 }
1049
1050 sp<AMessage> msg = new AMessage;
1051
1052 if(convertMetaDataToMessage(meta, &msg) == OK) {
1053 return msg;
1054 }
1055 return NULL;
1056}
1057
James Dong0d268a32012-08-31 12:18:27 -07001058status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1059 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001060 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001061 status_t ret = native_window_set_scaling_mode(
1062 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1063 if (ret != OK) {
1064 ALOGE("Failed to set scaling mode (%d): %s",
1065 -ret, strerror(-ret));
1066 return ret;
1067 }
1068 }
1069 return OK;
1070}
1071
Andreas Huberb7c8e912012-11-27 15:02:53 -08001072void NuPlayer::schedulePollDuration() {
1073 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1074 msg->setInt32("generation", mPollDurationGeneration);
1075 msg->post();
1076}
1077
1078void NuPlayer::cancelPollDuration() {
1079 ++mPollDurationGeneration;
1080}
1081
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001082void NuPlayer::processDeferredActions() {
1083 while (!mDeferredActions.empty()) {
1084 // We won't execute any deferred actions until we're no longer in
1085 // an intermediate state, i.e. one more more decoders are currently
1086 // flushing or shutting down.
1087
1088 if (mRenderer != NULL) {
1089 // There's an edge case where the renderer owns all output
1090 // buffers and is paused, therefore the decoder will not read
1091 // more input data and will never encounter the matching
1092 // discontinuity. To avoid this, we resume the renderer.
1093
1094 if (mFlushingAudio == AWAITING_DISCONTINUITY
1095 || mFlushingVideo == AWAITING_DISCONTINUITY) {
1096 mRenderer->resume();
1097 }
1098 }
1099
1100 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1101 // We're currently flushing, postpone the reset until that's
1102 // completed.
1103
1104 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1105 mFlushingAudio, mFlushingVideo);
1106
1107 break;
1108 }
1109
1110 sp<Action> action = *mDeferredActions.begin();
1111 mDeferredActions.erase(mDeferredActions.begin());
1112
1113 action->execute(this);
1114 }
1115}
1116
1117void NuPlayer::performSeek(int64_t seekTimeUs) {
1118 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1119 seekTimeUs,
1120 seekTimeUs / 1E6);
1121
1122 mSource->seekTo(seekTimeUs);
1123
1124 if (mDriver != NULL) {
1125 sp<NuPlayerDriver> driver = mDriver.promote();
1126 if (driver != NULL) {
1127 driver->notifyPosition(seekTimeUs);
1128 driver->notifySeekComplete();
1129 }
1130 }
1131
1132 // everything's flushed, continue playback.
1133}
1134
1135void NuPlayer::performDecoderFlush() {
1136 ALOGV("performDecoderFlush");
1137
1138 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1139 return;
1140 }
1141
1142 mTimeDiscontinuityPending = true;
1143
1144 if (mAudioDecoder != NULL) {
1145 flushDecoder(true /* audio */, false /* needShutdown */);
1146 }
1147
1148 if (mVideoDecoder != NULL) {
1149 flushDecoder(false /* audio */, false /* needShutdown */);
1150 }
1151}
1152
1153void NuPlayer::performDecoderShutdown() {
1154 ALOGV("performDecoderShutdown");
1155
1156 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1157 return;
1158 }
1159
1160 mTimeDiscontinuityPending = true;
1161
1162 if (mAudioDecoder != NULL) {
1163 flushDecoder(true /* audio */, true /* needShutdown */);
1164 }
1165
1166 if (mVideoDecoder != NULL) {
1167 flushDecoder(false /* audio */, true /* needShutdown */);
1168 }
1169}
1170
1171void NuPlayer::performReset() {
1172 ALOGV("performReset");
1173
1174 CHECK(mAudioDecoder == NULL);
1175 CHECK(mVideoDecoder == NULL);
1176
1177 cancelPollDuration();
1178
1179 ++mScanSourcesGeneration;
1180 mScanSourcesPending = false;
1181
1182 mRenderer.clear();
1183
1184 if (mSource != NULL) {
1185 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001186
1187 looper()->unregisterHandler(mSource->id());
1188
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001189 mSource.clear();
1190 }
1191
1192 if (mDriver != NULL) {
1193 sp<NuPlayerDriver> driver = mDriver.promote();
1194 if (driver != NULL) {
1195 driver->notifyResetComplete();
1196 }
1197 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001198
1199 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001200}
1201
1202void NuPlayer::performScanSources() {
1203 ALOGV("performScanSources");
1204
Andreas Huber57a339c2012-12-03 11:18:00 -08001205 if (!mStarted) {
1206 return;
1207 }
1208
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001209 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1210 postScanSources();
1211 }
1212}
1213
Andreas Huber57a339c2012-12-03 11:18:00 -08001214void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1215 ALOGV("performSetSurface");
1216
1217 mNativeWindow = wrapper;
1218
1219 // XXX - ignore error from setVideoScalingMode for now
1220 setVideoScalingMode(mVideoScalingMode);
1221
1222 if (mDriver != NULL) {
1223 sp<NuPlayerDriver> driver = mDriver.promote();
1224 if (driver != NULL) {
1225 driver->notifySetSurfaceComplete();
1226 }
1227 }
1228}
1229
Andreas Huberb5f25f02013-02-05 10:14:26 -08001230////////////////////////////////////////////////////////////////////////////////
1231
1232void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1233 TRESPASS();
1234}
1235
Andreas Huberf9334412010-12-15 15:17:42 -08001236} // namespace android