blob: 0736fbeb20469cbc37d8944ed45b154807b0a7b3 [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());
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100180 size_t len = strlen(url);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800181
Andreas Huberb5f25f02013-02-05 10:14:26 -0800182 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
183
Andreas Huberafed0e12011-09-20 15:39:58 -0700184 sp<Source> source;
185 if (IsHTTPLiveURL(url)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800186 source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
Andreas Huberafed0e12011-09-20 15:39:58 -0700187 } else if (!strncasecmp(url, "rtsp://", 7)) {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800188 source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100189 } else if ((!strncasecmp(url, "http://", 7)
190 || !strncasecmp(url, "https://", 8))
191 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
192 || strstr(url, ".sdp?"))) {
193 source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700194 } else {
Andreas Huberb5f25f02013-02-05 10:14:26 -0800195 source = new GenericSource(notify, url, headers, mUIDValid, mUID);
Andreas Huber2bfdd422011-10-11 15:24:07 -0700196 }
197
Andreas Huberafed0e12011-09-20 15:39:58 -0700198 msg->setObject("source", source);
199 msg->post();
200}
201
202void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
203 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
204
Andreas Huberb5f25f02013-02-05 10:14:26 -0800205 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
206
207 sp<Source> source = new GenericSource(notify, fd, offset, length);
Andreas Huberafed0e12011-09-20 15:39:58 -0700208 msg->setObject("source", source);
Andreas Huberf9334412010-12-15 15:17:42 -0800209 msg->post();
210}
211
Andreas Huber57a339c2012-12-03 11:18:00 -0800212void NuPlayer::setVideoSurfaceTextureAsync(
Andy McFadden8ba01022012-12-18 09:46:54 -0800213 const sp<IGraphicBufferProducer> &bufferProducer) {
Glenn Kasten11731182011-02-08 17:26:17 -0800214 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
Andreas Huber57a339c2012-12-03 11:18:00 -0800215
Andy McFadden8ba01022012-12-18 09:46:54 -0800216 if (bufferProducer == NULL) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800217 msg->setObject("native-window", NULL);
218 } else {
219 msg->setObject(
220 "native-window",
221 new NativeWindowWrapper(
Andy McFadden8ba01022012-12-18 09:46:54 -0800222 new SurfaceTextureClient(bufferProducer)));
Andreas Huber57a339c2012-12-03 11:18:00 -0800223 }
224
Andreas Huberf9334412010-12-15 15:17:42 -0800225 msg->post();
226}
227
228void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
229 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
230 msg->setObject("sink", sink);
231 msg->post();
232}
233
234void NuPlayer::start() {
235 (new AMessage(kWhatStart, id()))->post();
236}
237
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800238void NuPlayer::pause() {
Andreas Huberb4082222011-01-20 15:23:04 -0800239 (new AMessage(kWhatPause, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800240}
241
242void NuPlayer::resume() {
Andreas Huberb4082222011-01-20 15:23:04 -0800243 (new AMessage(kWhatResume, id()))->post();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800244}
245
Andreas Huber1aef2112011-01-04 14:01:29 -0800246void NuPlayer::resetAsync() {
247 (new AMessage(kWhatReset, id()))->post();
248}
249
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800250void NuPlayer::seekToAsync(int64_t seekTimeUs) {
251 sp<AMessage> msg = new AMessage(kWhatSeek, id());
252 msg->setInt64("seekTimeUs", seekTimeUs);
253 msg->post();
254}
255
Andreas Huber53df1a42010-12-22 10:03:04 -0800256// static
Andreas Huber1aef2112011-01-04 14:01:29 -0800257bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
Andreas Huber53df1a42010-12-22 10:03:04 -0800258 switch (state) {
259 case FLUSHING_DECODER:
Andreas Huber1aef2112011-01-04 14:01:29 -0800260 if (needShutdown != NULL) {
261 *needShutdown = false;
Andreas Huber53df1a42010-12-22 10:03:04 -0800262 }
263 return true;
264
Andreas Huber1aef2112011-01-04 14:01:29 -0800265 case FLUSHING_DECODER_SHUTDOWN:
266 if (needShutdown != NULL) {
267 *needShutdown = true;
Andreas Huber53df1a42010-12-22 10:03:04 -0800268 }
269 return true;
270
271 default:
272 return false;
273 }
274}
275
Andreas Huberf9334412010-12-15 15:17:42 -0800276void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
277 switch (msg->what()) {
278 case kWhatSetDataSource:
279 {
Steve Block3856b092011-10-20 11:56:00 +0100280 ALOGV("kWhatSetDataSource");
Andreas Huberf9334412010-12-15 15:17:42 -0800281
282 CHECK(mSource == NULL);
283
Andreas Huber5bc087c2010-12-23 10:27:40 -0800284 sp<RefBase> obj;
285 CHECK(msg->findObject("source", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800286
Andreas Huber5bc087c2010-12-23 10:27:40 -0800287 mSource = static_cast<Source *>(obj.get());
Andreas Huberb5f25f02013-02-05 10:14:26 -0800288
289 looper()->registerHandler(mSource);
Andreas Huberf9334412010-12-15 15:17:42 -0800290 break;
291 }
292
Andreas Huberb7c8e912012-11-27 15:02:53 -0800293 case kWhatPollDuration:
294 {
295 int32_t generation;
296 CHECK(msg->findInt32("generation", &generation));
297
298 if (generation != mPollDurationGeneration) {
299 // stale
300 break;
301 }
302
303 int64_t durationUs;
304 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
305 sp<NuPlayerDriver> driver = mDriver.promote();
306 if (driver != NULL) {
307 driver->notifyDuration(durationUs);
308 }
309 }
310
311 msg->post(1000000ll); // poll again in a second.
312 break;
313 }
314
Glenn Kasten11731182011-02-08 17:26:17 -0800315 case kWhatSetVideoNativeWindow:
Andreas Huberf9334412010-12-15 15:17:42 -0800316 {
Steve Block3856b092011-10-20 11:56:00 +0100317 ALOGV("kWhatSetVideoNativeWindow");
Andreas Huberf9334412010-12-15 15:17:42 -0800318
Andreas Huber57a339c2012-12-03 11:18:00 -0800319 mDeferredActions.push_back(
320 new SimpleAction(&NuPlayer::performDecoderShutdown));
321
Andreas Huberf9334412010-12-15 15:17:42 -0800322 sp<RefBase> obj;
Glenn Kasten11731182011-02-08 17:26:17 -0800323 CHECK(msg->findObject("native-window", &obj));
Andreas Huberf9334412010-12-15 15:17:42 -0800324
Andreas Huber57a339c2012-12-03 11:18:00 -0800325 mDeferredActions.push_back(
326 new SetSurfaceAction(
327 static_cast<NativeWindowWrapper *>(obj.get())));
James Dong0d268a32012-08-31 12:18:27 -0700328
Andreas Huber57a339c2012-12-03 11:18:00 -0800329 if (obj != NULL) {
330 // If there is a new surface texture, instantiate decoders
331 // again if possible.
332 mDeferredActions.push_back(
333 new SimpleAction(&NuPlayer::performScanSources));
334 }
335
336 processDeferredActions();
Andreas Huberf9334412010-12-15 15:17:42 -0800337 break;
338 }
339
340 case kWhatSetAudioSink:
341 {
Steve Block3856b092011-10-20 11:56:00 +0100342 ALOGV("kWhatSetAudioSink");
Andreas Huberf9334412010-12-15 15:17:42 -0800343
344 sp<RefBase> obj;
345 CHECK(msg->findObject("sink", &obj));
346
347 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
348 break;
349 }
350
351 case kWhatStart:
352 {
Steve Block3856b092011-10-20 11:56:00 +0100353 ALOGV("kWhatStart");
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800354
Andreas Huber3fe62152011-09-16 15:09:22 -0700355 mVideoIsAVC = false;
Andreas Huber1aef2112011-01-04 14:01:29 -0800356 mAudioEOS = false;
357 mVideoEOS = false;
Andreas Huber32f3cef2011-03-02 15:34:46 -0800358 mSkipRenderingAudioUntilMediaTimeUs = -1;
359 mSkipRenderingVideoUntilMediaTimeUs = -1;
Andreas Huber3fe62152011-09-16 15:09:22 -0700360 mVideoLateByUs = 0;
361 mNumFramesTotal = 0;
362 mNumFramesDropped = 0;
Andreas Huber57a339c2012-12-03 11:18:00 -0800363 mStarted = true;
Andreas Huber1aef2112011-01-04 14:01:29 -0800364
Andreas Huber5bc087c2010-12-23 10:27:40 -0800365 mSource->start();
Andreas Huberf9334412010-12-15 15:17:42 -0800366
367 mRenderer = new Renderer(
368 mAudioSink,
369 new AMessage(kWhatRendererNotify, id()));
370
371 looper()->registerHandler(mRenderer);
372
Andreas Huber1aef2112011-01-04 14:01:29 -0800373 postScanSources();
Andreas Huberf9334412010-12-15 15:17:42 -0800374 break;
375 }
376
377 case kWhatScanSources:
378 {
Andreas Huber1aef2112011-01-04 14:01:29 -0800379 int32_t generation;
380 CHECK(msg->findInt32("generation", &generation));
381 if (generation != mScanSourcesGeneration) {
382 // Drop obsolete msg.
383 break;
384 }
385
Andreas Huber5bc087c2010-12-23 10:27:40 -0800386 mScanSourcesPending = false;
387
Steve Block3856b092011-10-20 11:56:00 +0100388 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800389 mAudioDecoder != NULL, mVideoDecoder != NULL);
390
Andreas Huberb7c8e912012-11-27 15:02:53 -0800391 bool mHadAnySourcesBefore =
392 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
393
Haynes Mathew George5d246ef2012-07-09 10:36:57 -0700394 if (mNativeWindow != NULL) {
395 instantiateDecoder(false, &mVideoDecoder);
396 }
Andreas Huberf9334412010-12-15 15:17:42 -0800397
398 if (mAudioSink != NULL) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800399 instantiateDecoder(true, &mAudioDecoder);
Andreas Huberf9334412010-12-15 15:17:42 -0800400 }
401
Andreas Huberb7c8e912012-11-27 15:02:53 -0800402 if (!mHadAnySourcesBefore
403 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
404 // This is the first time we've found anything playable.
405
406 uint32_t flags = mSource->flags();
407
408 if (flags & Source::FLAG_DYNAMIC_DURATION) {
409 schedulePollDuration();
410 }
411 }
412
Andreas Hubereac68ba2011-09-27 12:12:25 -0700413 status_t err;
414 if ((err = mSource->feedMoreTSData()) != OK) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800415 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
416 // We're not currently decoding anything (no audio or
417 // video tracks found) and we just ran out of input data.
Andreas Hubereac68ba2011-09-27 12:12:25 -0700418
419 if (err == ERROR_END_OF_STREAM) {
420 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
421 } else {
422 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
423 }
Andreas Huber1aef2112011-01-04 14:01:29 -0800424 }
Andreas Huberf9334412010-12-15 15:17:42 -0800425 break;
426 }
427
Andreas Huberfbe9d812012-08-31 14:05:27 -0700428 if ((mAudioDecoder == NULL && mAudioSink != NULL)
429 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
Andreas Huberf9334412010-12-15 15:17:42 -0800430 msg->post(100000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800431 mScanSourcesPending = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800432 }
433 break;
434 }
435
436 case kWhatVideoNotify:
437 case kWhatAudioNotify:
438 {
439 bool audio = msg->what() == kWhatAudioNotify;
440
441 sp<AMessage> codecRequest;
442 CHECK(msg->findMessage("codec-request", &codecRequest));
443
444 int32_t what;
445 CHECK(codecRequest->findInt32("what", &what));
446
447 if (what == ACodec::kWhatFillThisBuffer) {
448 status_t err = feedDecoderInputData(
449 audio, codecRequest);
450
Andreas Huber5bc087c2010-12-23 10:27:40 -0800451 if (err == -EWOULDBLOCK) {
Andreas Hubereac68ba2011-09-27 12:12:25 -0700452 if (mSource->feedMoreTSData() == OK) {
Andreas Huber1183a4a2011-11-03 11:00:21 -0700453 msg->post(10000ll);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800454 }
Andreas Huberf9334412010-12-15 15:17:42 -0800455 }
456 } else if (what == ACodec::kWhatEOS) {
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700457 int32_t err;
458 CHECK(codecRequest->findInt32("err", &err));
459
460 if (err == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100461 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700462 } else {
Steve Block3856b092011-10-20 11:56:00 +0100463 ALOGV("got %s decoder EOS w/ error %d",
Andreas Huberdc9bacd2011-09-26 10:53:29 -0700464 audio ? "audio" : "video",
465 err);
466 }
467
468 mRenderer->queueEOS(audio, err);
Andreas Huberf9334412010-12-15 15:17:42 -0800469 } else if (what == ACodec::kWhatFlushCompleted) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800470 bool needShutdown;
Andreas Huber53df1a42010-12-22 10:03:04 -0800471
Andreas Huberf9334412010-12-15 15:17:42 -0800472 if (audio) {
Andreas Huber1aef2112011-01-04 14:01:29 -0800473 CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800474 mFlushingAudio = FLUSHED;
475 } else {
Andreas Huber1aef2112011-01-04 14:01:29 -0800476 CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
Andreas Huberf9334412010-12-15 15:17:42 -0800477 mFlushingVideo = FLUSHED;
Andreas Huber3fe62152011-09-16 15:09:22 -0700478
479 mVideoLateByUs = 0;
Andreas Huberf9334412010-12-15 15:17:42 -0800480 }
481
Steve Block3856b092011-10-20 11:56:00 +0100482 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800483
Andreas Huber1aef2112011-01-04 14:01:29 -0800484 if (needShutdown) {
Steve Block3856b092011-10-20 11:56:00 +0100485 ALOGV("initiating %s decoder shutdown",
Andreas Huber53df1a42010-12-22 10:03:04 -0800486 audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800487
Andreas Huber53df1a42010-12-22 10:03:04 -0800488 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
Andreas Huberf9334412010-12-15 15:17:42 -0800489
Andreas Huber53df1a42010-12-22 10:03:04 -0800490 if (audio) {
491 mFlushingAudio = SHUTTING_DOWN_DECODER;
492 } else {
493 mFlushingVideo = SHUTTING_DOWN_DECODER;
494 }
Andreas Huberf9334412010-12-15 15:17:42 -0800495 }
Andreas Huber3831a062010-12-21 10:22:33 -0800496
497 finishFlushIfPossible();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800498 } else if (what == ACodec::kWhatOutputFormatChanged) {
Andreas Huber31e25082011-01-10 10:38:31 -0800499 if (audio) {
500 int32_t numChannels;
Andreas Huber516dacf2012-12-03 15:20:40 -0800501 CHECK(codecRequest->findInt32(
502 "channel-count", &numChannels));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800503
Andreas Huber31e25082011-01-10 10:38:31 -0800504 int32_t sampleRate;
505 CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
Andreas Huber2c2814b2010-12-15 17:18:20 -0800506
Steve Block3856b092011-10-20 11:56:00 +0100507 ALOGV("Audio output format changed to %d Hz, %d channels",
Andreas Huber31e25082011-01-10 10:38:31 -0800508 sampleRate, numChannels);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800509
Andreas Huber31e25082011-01-10 10:38:31 -0800510 mAudioSink->close();
Eric Laurent1948eb32012-04-13 16:50:19 -0700511
512 audio_output_flags_t flags;
513 int64_t durationUs;
Andreas Huber516dacf2012-12-03 15:20:40 -0800514 // FIXME: we should handle the case where the video decoder
515 // is created after we receive the format change indication.
516 // Current code will just make that we select deep buffer
517 // with video which should not be a problem as it should
Eric Laurent1948eb32012-04-13 16:50:19 -0700518 // not prevent from keeping A/V sync.
519 if (mVideoDecoder == NULL &&
520 mSource->getDuration(&durationUs) == OK &&
Andreas Huber516dacf2012-12-03 15:20:40 -0800521 durationUs
522 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
Eric Laurent1948eb32012-04-13 16:50:19 -0700523 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
524 } else {
525 flags = AUDIO_OUTPUT_FLAG_NONE;
526 }
527
Andreas Huber98065552012-05-03 11:33:01 -0700528 int32_t channelMask;
529 if (!codecRequest->findInt32("channel-mask", &channelMask)) {
530 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
531 }
532
Andreas Huber078cfcf2011-09-15 12:25:04 -0700533 CHECK_EQ(mAudioSink->open(
534 sampleRate,
535 numChannels,
Andreas Huber98065552012-05-03 11:33:01 -0700536 (audio_channel_mask_t)channelMask,
Andreas Huber078cfcf2011-09-15 12:25:04 -0700537 AUDIO_FORMAT_PCM_16_BIT,
Eric Laurent1948eb32012-04-13 16:50:19 -0700538 8 /* bufferCount */,
539 NULL,
540 NULL,
541 flags),
Andreas Huber078cfcf2011-09-15 12:25:04 -0700542 (status_t)OK);
Andreas Huber31e25082011-01-10 10:38:31 -0800543 mAudioSink->start();
Andreas Huber2c2814b2010-12-15 17:18:20 -0800544
Andreas Huber31e25082011-01-10 10:38:31 -0800545 mRenderer->signalAudioSinkChanged();
546 } else {
547 // video
Andreas Huber3831a062010-12-21 10:22:33 -0800548
Andreas Huber31e25082011-01-10 10:38:31 -0800549 int32_t width, height;
550 CHECK(codecRequest->findInt32("width", &width));
551 CHECK(codecRequest->findInt32("height", &height));
552
553 int32_t cropLeft, cropTop, cropRight, cropBottom;
554 CHECK(codecRequest->findRect(
555 "crop",
556 &cropLeft, &cropTop, &cropRight, &cropBottom));
557
Andreas Huber516dacf2012-12-03 15:20:40 -0800558 int32_t displayWidth = cropRight - cropLeft + 1;
559 int32_t displayHeight = cropBottom - cropTop + 1;
560
Steve Block3856b092011-10-20 11:56:00 +0100561 ALOGV("Video output format changed to %d x %d "
Andreas Hubercb67cd12011-08-26 16:02:19 -0700562 "(crop: %d x %d @ (%d, %d))",
Andreas Huber31e25082011-01-10 10:38:31 -0800563 width, height,
Andreas Huber516dacf2012-12-03 15:20:40 -0800564 displayWidth,
565 displayHeight,
Andreas Hubercb67cd12011-08-26 16:02:19 -0700566 cropLeft, cropTop);
Andreas Huber31e25082011-01-10 10:38:31 -0800567
Andreas Huber516dacf2012-12-03 15:20:40 -0800568 sp<AMessage> videoInputFormat =
569 mSource->getFormat(false /* audio */);
570
571 // Take into account sample aspect ratio if necessary:
572 int32_t sarWidth, sarHeight;
573 if (videoInputFormat->findInt32("sar-width", &sarWidth)
574 && videoInputFormat->findInt32(
575 "sar-height", &sarHeight)) {
576 ALOGV("Sample aspect ratio %d : %d",
577 sarWidth, sarHeight);
578
579 displayWidth = (displayWidth * sarWidth) / sarHeight;
580
581 ALOGV("display dimensions %d x %d",
582 displayWidth, displayHeight);
583 }
584
Andreas Huber31e25082011-01-10 10:38:31 -0800585 notifyListener(
Andreas Huber516dacf2012-12-03 15:20:40 -0800586 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
Andreas Huber31e25082011-01-10 10:38:31 -0800587 }
Andreas Huber3831a062010-12-21 10:22:33 -0800588 } else if (what == ACodec::kWhatShutdownCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100589 ALOGV("%s shutdown completed", audio ? "audio" : "video");
Andreas Huber3831a062010-12-21 10:22:33 -0800590 if (audio) {
591 mAudioDecoder.clear();
592
593 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
594 mFlushingAudio = SHUT_DOWN;
595 } else {
596 mVideoDecoder.clear();
597
598 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
599 mFlushingVideo = SHUT_DOWN;
600 }
601
602 finishFlushIfPossible();
Andreas Huberc92fd242011-08-16 13:48:44 -0700603 } else if (what == ACodec::kWhatError) {
Steve Block29357bc2012-01-06 19:20:56 +0000604 ALOGE("Received error from %s decoder, aborting playback.",
Andreas Huberc92fd242011-08-16 13:48:44 -0700605 audio ? "audio" : "video");
606
607 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
Andreas Huber57788222012-02-21 11:47:18 -0800608 } else if (what == ACodec::kWhatDrainThisBuffer) {
Andreas Huberf9334412010-12-15 15:17:42 -0800609 renderBuffer(audio, codecRequest);
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800610 } else if (what != ACodec::kWhatComponentAllocated
611 && what != ACodec::kWhatComponentConfigured
612 && what != ACodec::kWhatBuffersAllocated) {
613 ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
614 what,
615 what >> 24,
616 (what >> 16) & 0xff,
617 (what >> 8) & 0xff,
618 what & 0xff);
Andreas Huberf9334412010-12-15 15:17:42 -0800619 }
620
621 break;
622 }
623
624 case kWhatRendererNotify:
625 {
626 int32_t what;
627 CHECK(msg->findInt32("what", &what));
628
629 if (what == Renderer::kWhatEOS) {
630 int32_t audio;
631 CHECK(msg->findInt32("audio", &audio));
632
Andreas Huberc92fd242011-08-16 13:48:44 -0700633 int32_t finalResult;
634 CHECK(msg->findInt32("finalResult", &finalResult));
635
Andreas Huberf9334412010-12-15 15:17:42 -0800636 if (audio) {
637 mAudioEOS = true;
638 } else {
639 mVideoEOS = true;
640 }
641
Andreas Huberc92fd242011-08-16 13:48:44 -0700642 if (finalResult == ERROR_END_OF_STREAM) {
Steve Block3856b092011-10-20 11:56:00 +0100643 ALOGV("reached %s EOS", audio ? "audio" : "video");
Andreas Huberc92fd242011-08-16 13:48:44 -0700644 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000645 ALOGE("%s track encountered an error (%d)",
Andreas Huberc92fd242011-08-16 13:48:44 -0700646 audio ? "audio" : "video", finalResult);
647
648 notifyListener(
649 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
650 }
Andreas Huberf9334412010-12-15 15:17:42 -0800651
652 if ((mAudioEOS || mAudioDecoder == NULL)
653 && (mVideoEOS || mVideoDecoder == NULL)) {
654 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
655 }
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800656 } else if (what == Renderer::kWhatPosition) {
657 int64_t positionUs;
658 CHECK(msg->findInt64("positionUs", &positionUs));
659
Andreas Huber3fe62152011-09-16 15:09:22 -0700660 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
661
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800662 if (mDriver != NULL) {
663 sp<NuPlayerDriver> driver = mDriver.promote();
664 if (driver != NULL) {
665 driver->notifyPosition(positionUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700666
667 driver->notifyFrameStats(
668 mNumFramesTotal, mNumFramesDropped);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800669 }
670 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700671 } else if (what == Renderer::kWhatFlushComplete) {
Andreas Huberf9334412010-12-15 15:17:42 -0800672 int32_t audio;
673 CHECK(msg->findInt32("audio", &audio));
674
Steve Block3856b092011-10-20 11:56:00 +0100675 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
James Dongf57b4ea2012-07-20 13:38:36 -0700676 } else if (what == Renderer::kWhatVideoRenderingStart) {
677 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
Andreas Huberf9334412010-12-15 15:17:42 -0800678 }
679 break;
680 }
681
682 case kWhatMoreDataQueued:
683 {
684 break;
685 }
686
Andreas Huber1aef2112011-01-04 14:01:29 -0800687 case kWhatReset:
688 {
Steve Block3856b092011-10-20 11:56:00 +0100689 ALOGV("kWhatReset");
Andreas Huber1aef2112011-01-04 14:01:29 -0800690
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800691 mDeferredActions.push_back(
692 new SimpleAction(&NuPlayer::performDecoderShutdown));
Andreas Huberb7c8e912012-11-27 15:02:53 -0800693
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800694 mDeferredActions.push_back(
695 new SimpleAction(&NuPlayer::performReset));
Andreas Huberb58ce9f2011-11-28 16:27:35 -0800696
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800697 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800698 break;
699 }
700
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800701 case kWhatSeek:
702 {
703 int64_t seekTimeUs;
704 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
705
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800706 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800707
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800708 mDeferredActions.push_back(
709 new SimpleAction(&NuPlayer::performDecoderFlush));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800710
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800711 mDeferredActions.push_back(new SeekAction(seekTimeUs));
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800712
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800713 processDeferredActions();
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800714 break;
715 }
716
Andreas Huberb4082222011-01-20 15:23:04 -0800717 case kWhatPause:
718 {
719 CHECK(mRenderer != NULL);
720 mRenderer->pause();
721 break;
722 }
723
724 case kWhatResume:
725 {
726 CHECK(mRenderer != NULL);
727 mRenderer->resume();
728 break;
729 }
730
Andreas Huberb5f25f02013-02-05 10:14:26 -0800731 case kWhatSourceNotify:
732 {
733 TRESPASS(); // TBD
734 break;
735 }
736
Andreas Huberf9334412010-12-15 15:17:42 -0800737 default:
738 TRESPASS();
739 break;
740 }
741}
742
Andreas Huber3831a062010-12-21 10:22:33 -0800743void NuPlayer::finishFlushIfPossible() {
744 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
745 return;
746 }
747
748 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
749 return;
750 }
751
Steve Block3856b092011-10-20 11:56:00 +0100752 ALOGV("both audio and video are flushed now.");
Andreas Huber3831a062010-12-21 10:22:33 -0800753
Andreas Huber6e3d3112011-11-28 12:36:11 -0800754 if (mTimeDiscontinuityPending) {
755 mRenderer->signalTimeDiscontinuity();
756 mTimeDiscontinuityPending = false;
757 }
Andreas Huber3831a062010-12-21 10:22:33 -0800758
Andreas Huber22fc52f2011-01-05 16:24:27 -0800759 if (mAudioDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800760 mAudioDecoder->signalResume();
761 }
762
Andreas Huber22fc52f2011-01-05 16:24:27 -0800763 if (mVideoDecoder != NULL) {
Andreas Huber3831a062010-12-21 10:22:33 -0800764 mVideoDecoder->signalResume();
765 }
766
767 mFlushingAudio = NONE;
768 mFlushingVideo = NONE;
Andreas Huber3831a062010-12-21 10:22:33 -0800769
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800770 processDeferredActions();
Andreas Huber1aef2112011-01-04 14:01:29 -0800771}
772
773void NuPlayer::postScanSources() {
774 if (mScanSourcesPending) {
775 return;
776 }
777
778 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
779 msg->setInt32("generation", mScanSourcesGeneration);
780 msg->post();
781
782 mScanSourcesPending = true;
783}
784
Andreas Huber5bc087c2010-12-23 10:27:40 -0800785status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
Andreas Huberf9334412010-12-15 15:17:42 -0800786 if (*decoder != NULL) {
787 return OK;
788 }
789
Andreas Huber84066782011-08-16 09:34:26 -0700790 sp<AMessage> format = mSource->getFormat(audio);
Andreas Huberf9334412010-12-15 15:17:42 -0800791
Andreas Huber84066782011-08-16 09:34:26 -0700792 if (format == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800793 return -EWOULDBLOCK;
794 }
795
Andreas Huber3fe62152011-09-16 15:09:22 -0700796 if (!audio) {
Andreas Huber84066782011-08-16 09:34:26 -0700797 AString mime;
798 CHECK(format->findString("mime", &mime));
799 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
Andreas Huber3fe62152011-09-16 15:09:22 -0700800 }
801
Andreas Huberf9334412010-12-15 15:17:42 -0800802 sp<AMessage> notify =
803 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
804 id());
805
Glenn Kasten11731182011-02-08 17:26:17 -0800806 *decoder = audio ? new Decoder(notify) :
807 new Decoder(notify, mNativeWindow);
Andreas Huberf9334412010-12-15 15:17:42 -0800808 looper()->registerHandler(*decoder);
809
Andreas Huber84066782011-08-16 09:34:26 -0700810 (*decoder)->configure(format);
Andreas Huberf9334412010-12-15 15:17:42 -0800811
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800812 int64_t durationUs;
813 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
814 sp<NuPlayerDriver> driver = mDriver.promote();
815 if (driver != NULL) {
816 driver->notifyDuration(durationUs);
817 }
818 }
819
Andreas Huberf9334412010-12-15 15:17:42 -0800820 return OK;
821}
822
823status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
824 sp<AMessage> reply;
825 CHECK(msg->findMessage("reply", &reply));
826
Andreas Huber53df1a42010-12-22 10:03:04 -0800827 if ((audio && IsFlushingState(mFlushingAudio))
828 || (!audio && IsFlushingState(mFlushingVideo))) {
Andreas Huberf9334412010-12-15 15:17:42 -0800829 reply->setInt32("err", INFO_DISCONTINUITY);
830 reply->post();
831 return OK;
832 }
833
834 sp<ABuffer> accessUnit;
Andreas Huberf9334412010-12-15 15:17:42 -0800835
Andreas Huber3fe62152011-09-16 15:09:22 -0700836 bool dropAccessUnit;
837 do {
838 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800839
Andreas Huber3fe62152011-09-16 15:09:22 -0700840 if (err == -EWOULDBLOCK) {
841 return err;
842 } else if (err != OK) {
843 if (err == INFO_DISCONTINUITY) {
844 int32_t type;
845 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
Andreas Huber53df1a42010-12-22 10:03:04 -0800846
Andreas Huber3fe62152011-09-16 15:09:22 -0700847 bool formatChange =
Andreas Huber6e3d3112011-11-28 12:36:11 -0800848 (audio &&
849 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
850 || (!audio &&
851 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
Andreas Huber53df1a42010-12-22 10:03:04 -0800852
Andreas Huber6e3d3112011-11-28 12:36:11 -0800853 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
854
Steve Blockdf64d152012-01-04 20:05:49 +0000855 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800856 audio ? "audio" : "video", formatChange, timeChange);
Andreas Huber32f3cef2011-03-02 15:34:46 -0800857
Andreas Huber3fe62152011-09-16 15:09:22 -0700858 if (audio) {
859 mSkipRenderingAudioUntilMediaTimeUs = -1;
860 } else {
861 mSkipRenderingVideoUntilMediaTimeUs = -1;
862 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800863
Andreas Huber6e3d3112011-11-28 12:36:11 -0800864 if (timeChange) {
865 sp<AMessage> extra;
866 if (accessUnit->meta()->findMessage("extra", &extra)
867 && extra != NULL) {
868 int64_t resumeAtMediaTimeUs;
869 if (extra->findInt64(
870 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
Steve Blockdf64d152012-01-04 20:05:49 +0000871 ALOGI("suppressing rendering of %s until %lld us",
Andreas Huber6e3d3112011-11-28 12:36:11 -0800872 audio ? "audio" : "video", resumeAtMediaTimeUs);
Andreas Huber3fe62152011-09-16 15:09:22 -0700873
Andreas Huber6e3d3112011-11-28 12:36:11 -0800874 if (audio) {
875 mSkipRenderingAudioUntilMediaTimeUs =
876 resumeAtMediaTimeUs;
877 } else {
878 mSkipRenderingVideoUntilMediaTimeUs =
879 resumeAtMediaTimeUs;
880 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700881 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800882 }
883 }
Andreas Huber3fe62152011-09-16 15:09:22 -0700884
Andreas Huber6e3d3112011-11-28 12:36:11 -0800885 mTimeDiscontinuityPending =
886 mTimeDiscontinuityPending || timeChange;
887
888 if (formatChange || timeChange) {
Andreas Hubera1f8ab02012-11-30 10:53:22 -0800889 if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
890 // And we'll resume scanning sources once we're done
891 // flushing.
892 mDeferredActions.push_front(
893 new SimpleAction(
894 &NuPlayer::performScanSources));
895 }
896
Andreas Huber6e3d3112011-11-28 12:36:11 -0800897 flushDecoder(audio, formatChange);
898 } else {
899 // This stream is unaffected by the discontinuity
900
901 if (audio) {
902 mFlushingAudio = FLUSHED;
903 } else {
904 mFlushingVideo = FLUSHED;
905 }
906
907 finishFlushIfPossible();
908
909 return -EWOULDBLOCK;
910 }
Andreas Huber32f3cef2011-03-02 15:34:46 -0800911 }
912
Andreas Huber3fe62152011-09-16 15:09:22 -0700913 reply->setInt32("err", err);
914 reply->post();
915 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800916 }
917
Andreas Huber3fe62152011-09-16 15:09:22 -0700918 if (!audio) {
919 ++mNumFramesTotal;
920 }
921
922 dropAccessUnit = false;
923 if (!audio
924 && mVideoLateByUs > 100000ll
925 && mVideoIsAVC
926 && !IsAVCReferenceFrame(accessUnit)) {
927 dropAccessUnit = true;
928 ++mNumFramesDropped;
929 }
930 } while (dropAccessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800931
Steve Block3856b092011-10-20 11:56:00 +0100932 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800933
934#if 0
935 int64_t mediaTimeUs;
936 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
Steve Block3856b092011-10-20 11:56:00 +0100937 ALOGV("feeding %s input buffer at media time %.2f secs",
Andreas Huberf9334412010-12-15 15:17:42 -0800938 audio ? "audio" : "video",
939 mediaTimeUs / 1E6);
940#endif
941
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800942 reply->setBuffer("buffer", accessUnit);
Andreas Huberf9334412010-12-15 15:17:42 -0800943 reply->post();
944
945 return OK;
946}
947
948void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
Steve Block3856b092011-10-20 11:56:00 +0100949 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
Andreas Huberf9334412010-12-15 15:17:42 -0800950
951 sp<AMessage> reply;
952 CHECK(msg->findMessage("reply", &reply));
953
Andreas Huber18ac5402011-08-31 15:04:25 -0700954 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
955 // We're currently attempting to flush the decoder, in order
956 // to complete this, the decoder wants all its buffers back,
957 // so we don't want any output buffers it sent us (from before
958 // we initiated the flush) to be stuck in the renderer's queue.
959
Steve Block3856b092011-10-20 11:56:00 +0100960 ALOGV("we're still flushing the %s decoder, sending its output buffer"
Andreas Huber18ac5402011-08-31 15:04:25 -0700961 " right back.", audio ? "audio" : "video");
962
963 reply->post();
964 return;
965 }
966
Andreas Huber2d8bedd2012-02-21 14:38:23 -0800967 sp<ABuffer> buffer;
968 CHECK(msg->findBuffer("buffer", &buffer));
Andreas Huberf9334412010-12-15 15:17:42 -0800969
Andreas Huber32f3cef2011-03-02 15:34:46 -0800970 int64_t &skipUntilMediaTimeUs =
971 audio
972 ? mSkipRenderingAudioUntilMediaTimeUs
973 : mSkipRenderingVideoUntilMediaTimeUs;
974
975 if (skipUntilMediaTimeUs >= 0) {
976 int64_t mediaTimeUs;
977 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
978
979 if (mediaTimeUs < skipUntilMediaTimeUs) {
Steve Block3856b092011-10-20 11:56:00 +0100980 ALOGV("dropping %s buffer at time %lld as requested.",
Andreas Huber32f3cef2011-03-02 15:34:46 -0800981 audio ? "audio" : "video",
982 mediaTimeUs);
983
984 reply->post();
985 return;
986 }
987
988 skipUntilMediaTimeUs = -1;
989 }
990
Andreas Huberf9334412010-12-15 15:17:42 -0800991 mRenderer->queueBuffer(audio, buffer, reply);
992}
993
994void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800995 if (mDriver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -0800996 return;
997 }
998
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800999 sp<NuPlayerDriver> driver = mDriver.promote();
Andreas Huberf9334412010-12-15 15:17:42 -08001000
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001001 if (driver == NULL) {
Andreas Huberf9334412010-12-15 15:17:42 -08001002 return;
1003 }
1004
Andreas Hubera4af2142011-10-26 15:23:31 -07001005 driver->notifyListener(msg, ext1, ext2);
Andreas Huberf9334412010-12-15 15:17:42 -08001006}
1007
Andreas Huber1aef2112011-01-04 14:01:29 -08001008void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001009 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
Steve Blockdf64d152012-01-04 20:05:49 +00001010 ALOGI("flushDecoder %s without decoder present",
Andreas Huber6e3d3112011-11-28 12:36:11 -08001011 audio ? "audio" : "video");
1012 }
1013
Andreas Huber1aef2112011-01-04 14:01:29 -08001014 // Make sure we don't continue to scan sources until we finish flushing.
1015 ++mScanSourcesGeneration;
Andreas Huber43c3e6c2011-01-05 12:17:08 -08001016 mScanSourcesPending = false;
Andreas Huber1aef2112011-01-04 14:01:29 -08001017
1018 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1019 mRenderer->flush(audio);
1020
1021 FlushStatus newStatus =
1022 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1023
1024 if (audio) {
1025 CHECK(mFlushingAudio == NONE
1026 || mFlushingAudio == AWAITING_DISCONTINUITY);
1027
1028 mFlushingAudio = newStatus;
1029
1030 if (mFlushingVideo == NONE) {
1031 mFlushingVideo = (mVideoDecoder != NULL)
1032 ? AWAITING_DISCONTINUITY
1033 : FLUSHED;
1034 }
1035 } else {
1036 CHECK(mFlushingVideo == NONE
1037 || mFlushingVideo == AWAITING_DISCONTINUITY);
1038
1039 mFlushingVideo = newStatus;
1040
1041 if (mFlushingAudio == NONE) {
1042 mFlushingAudio = (mAudioDecoder != NULL)
1043 ? AWAITING_DISCONTINUITY
1044 : FLUSHED;
1045 }
1046 }
1047}
1048
Andreas Huber84066782011-08-16 09:34:26 -07001049sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1050 sp<MetaData> meta = getFormatMeta(audio);
1051
1052 if (meta == NULL) {
1053 return NULL;
1054 }
1055
1056 sp<AMessage> msg = new AMessage;
1057
1058 if(convertMetaDataToMessage(meta, &msg) == OK) {
1059 return msg;
1060 }
1061 return NULL;
1062}
1063
James Dong0d268a32012-08-31 12:18:27 -07001064status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1065 mVideoScalingMode = mode;
Andreas Huber57a339c2012-12-03 11:18:00 -08001066 if (mNativeWindow != NULL) {
James Dong0d268a32012-08-31 12:18:27 -07001067 status_t ret = native_window_set_scaling_mode(
1068 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1069 if (ret != OK) {
1070 ALOGE("Failed to set scaling mode (%d): %s",
1071 -ret, strerror(-ret));
1072 return ret;
1073 }
1074 }
1075 return OK;
1076}
1077
Andreas Huberb7c8e912012-11-27 15:02:53 -08001078void NuPlayer::schedulePollDuration() {
1079 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1080 msg->setInt32("generation", mPollDurationGeneration);
1081 msg->post();
1082}
1083
1084void NuPlayer::cancelPollDuration() {
1085 ++mPollDurationGeneration;
1086}
1087
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001088void NuPlayer::processDeferredActions() {
1089 while (!mDeferredActions.empty()) {
1090 // We won't execute any deferred actions until we're no longer in
1091 // an intermediate state, i.e. one more more decoders are currently
1092 // flushing or shutting down.
1093
1094 if (mRenderer != NULL) {
1095 // There's an edge case where the renderer owns all output
1096 // buffers and is paused, therefore the decoder will not read
1097 // more input data and will never encounter the matching
1098 // discontinuity. To avoid this, we resume the renderer.
1099
1100 if (mFlushingAudio == AWAITING_DISCONTINUITY
1101 || mFlushingVideo == AWAITING_DISCONTINUITY) {
1102 mRenderer->resume();
1103 }
1104 }
1105
1106 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1107 // We're currently flushing, postpone the reset until that's
1108 // completed.
1109
1110 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1111 mFlushingAudio, mFlushingVideo);
1112
1113 break;
1114 }
1115
1116 sp<Action> action = *mDeferredActions.begin();
1117 mDeferredActions.erase(mDeferredActions.begin());
1118
1119 action->execute(this);
1120 }
1121}
1122
1123void NuPlayer::performSeek(int64_t seekTimeUs) {
1124 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1125 seekTimeUs,
1126 seekTimeUs / 1E6);
1127
1128 mSource->seekTo(seekTimeUs);
1129
1130 if (mDriver != NULL) {
1131 sp<NuPlayerDriver> driver = mDriver.promote();
1132 if (driver != NULL) {
1133 driver->notifyPosition(seekTimeUs);
1134 driver->notifySeekComplete();
1135 }
1136 }
1137
1138 // everything's flushed, continue playback.
1139}
1140
1141void NuPlayer::performDecoderFlush() {
1142 ALOGV("performDecoderFlush");
1143
1144 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1145 return;
1146 }
1147
1148 mTimeDiscontinuityPending = true;
1149
1150 if (mAudioDecoder != NULL) {
1151 flushDecoder(true /* audio */, false /* needShutdown */);
1152 }
1153
1154 if (mVideoDecoder != NULL) {
1155 flushDecoder(false /* audio */, false /* needShutdown */);
1156 }
1157}
1158
1159void NuPlayer::performDecoderShutdown() {
1160 ALOGV("performDecoderShutdown");
1161
1162 if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1163 return;
1164 }
1165
1166 mTimeDiscontinuityPending = true;
1167
1168 if (mAudioDecoder != NULL) {
1169 flushDecoder(true /* audio */, true /* needShutdown */);
1170 }
1171
1172 if (mVideoDecoder != NULL) {
1173 flushDecoder(false /* audio */, true /* needShutdown */);
1174 }
1175}
1176
1177void NuPlayer::performReset() {
1178 ALOGV("performReset");
1179
1180 CHECK(mAudioDecoder == NULL);
1181 CHECK(mVideoDecoder == NULL);
1182
1183 cancelPollDuration();
1184
1185 ++mScanSourcesGeneration;
1186 mScanSourcesPending = false;
1187
1188 mRenderer.clear();
1189
1190 if (mSource != NULL) {
1191 mSource->stop();
Andreas Huberb5f25f02013-02-05 10:14:26 -08001192
1193 looper()->unregisterHandler(mSource->id());
1194
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001195 mSource.clear();
1196 }
1197
1198 if (mDriver != NULL) {
1199 sp<NuPlayerDriver> driver = mDriver.promote();
1200 if (driver != NULL) {
1201 driver->notifyResetComplete();
1202 }
1203 }
Andreas Huber57a339c2012-12-03 11:18:00 -08001204
1205 mStarted = false;
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001206}
1207
1208void NuPlayer::performScanSources() {
1209 ALOGV("performScanSources");
1210
Andreas Huber57a339c2012-12-03 11:18:00 -08001211 if (!mStarted) {
1212 return;
1213 }
1214
Andreas Hubera1f8ab02012-11-30 10:53:22 -08001215 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1216 postScanSources();
1217 }
1218}
1219
Andreas Huber57a339c2012-12-03 11:18:00 -08001220void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1221 ALOGV("performSetSurface");
1222
1223 mNativeWindow = wrapper;
1224
1225 // XXX - ignore error from setVideoScalingMode for now
1226 setVideoScalingMode(mVideoScalingMode);
1227
1228 if (mDriver != NULL) {
1229 sp<NuPlayerDriver> driver = mDriver.promote();
1230 if (driver != NULL) {
1231 driver->notifySetSurfaceComplete();
1232 }
1233 }
1234}
1235
Andreas Huberb5f25f02013-02-05 10:14:26 -08001236////////////////////////////////////////////////////////////////////////////////
1237
1238void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1239 TRESPASS();
1240}
1241
Andreas Huberf9334412010-12-15 15:17:42 -08001242} // namespace android