blob: 8e27a279e0b4942be6d8a177cf5115be3d548ae5 [file] [log] [blame]
James Dongc9dedc42011-05-01 12:36:22 -07001/*
2 * Copyright (C) 2011 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#undef DEBUG_HDCP
18
19//#define LOG_NDEBUG 0
20#define LOG_TAG "PreviewPlayerBase"
21#include <utils/Log.h>
22
23#include <dlfcn.h>
24
25#include "include/ARTSPController.h"
26#include "PreviewPlayerBase.h"
27#include "AudioPlayerBase.h"
28#include "include/SoftwareRenderer.h"
29#include "include/NuCachedSource2.h"
30#include "include/ThrottledSource.h"
31#include "include/MPEG2TSExtractor.h"
32
33#include <binder/IPCThreadState.h>
34#include <binder/IServiceManager.h>
35#include <media/IMediaPlayerService.h>
36#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/foundation/ADebug.h>
38#include <media/stagefright/DataSource.h>
39#include <media/stagefright/FileSource.h>
40#include <media/stagefright/MediaBuffer.h>
41#include <media/stagefright/MediaDefs.h>
42#include <media/stagefright/MediaExtractor.h>
43#include <media/stagefright/MediaSource.h>
44#include <media/stagefright/MetaData.h>
45#include <media/stagefright/OMXCodec.h>
46
47#include <surfaceflinger/Surface.h>
48#include <gui/ISurfaceTexture.h>
49#include <gui/SurfaceTextureClient.h>
50#include <surfaceflinger/ISurfaceComposer.h>
51
52#include <media/stagefright/foundation/ALooper.h>
53#include <media/stagefright/foundation/AMessage.h>
54
55#include <cutils/properties.h>
56
57#define USE_SURFACE_ALLOC 1
58
59namespace android {
60
61static int64_t kLowWaterMarkUs = 2000000ll; // 2secs
62static int64_t kHighWaterMarkUs = 10000000ll; // 10secs
63static int64_t kHighWaterMarkRTSPUs = 4000000ll; // 4secs
64static const size_t kLowWaterMarkBytes = 40000;
65static const size_t kHighWaterMarkBytes = 200000;
66
67struct AwesomeEvent : public TimedEventQueue::Event {
68 AwesomeEvent(
69 PreviewPlayerBase *player,
70 void (PreviewPlayerBase::*method)())
71 : mPlayer(player),
72 mMethod(method) {
73 }
74
75protected:
76 virtual ~AwesomeEvent() {}
77
78 virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
79 (mPlayer->*mMethod)();
80 }
81
82private:
83 PreviewPlayerBase *mPlayer;
84 void (PreviewPlayerBase::*mMethod)();
85
86 AwesomeEvent(const AwesomeEvent &);
87 AwesomeEvent &operator=(const AwesomeEvent &);
88};
89
90struct AwesomeLocalRenderer : public AwesomeRenderer {
91 AwesomeLocalRenderer(
92 const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
93 : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
94 }
95
96 virtual void render(MediaBuffer *buffer) {
97 render((const uint8_t *)buffer->data() + buffer->range_offset(),
98 buffer->range_length());
99 }
100
101 void render(const void *data, size_t size) {
102 mTarget->render(data, size, NULL);
103 }
104
105protected:
106 virtual ~AwesomeLocalRenderer() {
107 delete mTarget;
108 mTarget = NULL;
109 }
110
111private:
112 SoftwareRenderer *mTarget;
113
114 AwesomeLocalRenderer(const AwesomeLocalRenderer &);
115 AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
116};
117
118struct AwesomeNativeWindowRenderer : public AwesomeRenderer {
119 AwesomeNativeWindowRenderer(
120 const sp<ANativeWindow> &nativeWindow,
121 int32_t rotationDegrees)
122 : mNativeWindow(nativeWindow) {
123 applyRotation(rotationDegrees);
124 }
125
126 virtual void render(MediaBuffer *buffer) {
127 status_t err = mNativeWindow->queueBuffer(
128 mNativeWindow.get(), buffer->graphicBuffer().get());
129 if (err != 0) {
130 LOGE("queueBuffer failed with error %s (%d)", strerror(-err),
131 -err);
132 return;
133 }
134
135 sp<MetaData> metaData = buffer->meta_data();
136 metaData->setInt32(kKeyRendered, 1);
137 }
138
139protected:
140 virtual ~AwesomeNativeWindowRenderer() {}
141
142private:
143 sp<ANativeWindow> mNativeWindow;
144
145 void applyRotation(int32_t rotationDegrees) {
146 uint32_t transform;
147 switch (rotationDegrees) {
148 case 0: transform = 0; break;
149 case 90: transform = HAL_TRANSFORM_ROT_90; break;
150 case 180: transform = HAL_TRANSFORM_ROT_180; break;
151 case 270: transform = HAL_TRANSFORM_ROT_270; break;
152 default: transform = 0; break;
153 }
154
155 if (transform) {
156 CHECK_EQ(0, native_window_set_buffers_transform(
157 mNativeWindow.get(), transform));
158 }
159 }
160
161 AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);
162 AwesomeNativeWindowRenderer &operator=(
163 const AwesomeNativeWindowRenderer &);
164};
165
166// To collect the decoder usage
167void addBatteryData(uint32_t params) {
168 sp<IBinder> binder =
169 defaultServiceManager()->getService(String16("media.player"));
170 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
171 CHECK(service.get() != NULL);
172
173 service->addBatteryData(params);
174}
175
176////////////////////////////////////////////////////////////////////////////////
177PreviewPlayerBase::PreviewPlayerBase()
178 : mQueueStarted(false),
179 mTimeSource(NULL),
180 mVideoRendererIsPreview(false),
181 mAudioPlayer(NULL),
182 mDisplayWidth(0),
183 mDisplayHeight(0),
184 mFlags(0),
185 mExtractorFlags(0),
186 mVideoBuffer(NULL),
187 mDecryptHandle(NULL),
188 mLastVideoTimeUs(-1) {
189 CHECK_EQ(mClient.connect(), (status_t)OK);
190
191 DataSource::RegisterDefaultSniffers();
192
193 mVideoEvent = new AwesomeEvent(this, &PreviewPlayerBase::onVideoEvent);
194 mVideoEventPending = false;
195 mStreamDoneEvent = new AwesomeEvent(this, &PreviewPlayerBase::onStreamDone);
196 mStreamDoneEventPending = false;
197 mBufferingEvent = new AwesomeEvent(this, &PreviewPlayerBase::onBufferingUpdate);
198 mBufferingEventPending = false;
199 mVideoLagEvent = new AwesomeEvent(this, &PreviewPlayerBase::onVideoLagUpdate);
200 mVideoEventPending = false;
201
202 mCheckAudioStatusEvent = new AwesomeEvent(
203 this, &PreviewPlayerBase::onCheckAudioStatus);
204
205 mAudioStatusEventPending = false;
206
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800207 mYV12ColorConverter = new YV12ColorConverter();
208 if (!mYV12ColorConverter->isLoaded() ||
209 mYV12ColorConverter->getDecoderOutputFormat() == OMX_COLOR_FormatYUV420Planar) {
210 delete mYV12ColorConverter;
211 mYV12ColorConverter = NULL;
212 }
213
James Dongc9dedc42011-05-01 12:36:22 -0700214 reset();
215}
216
217PreviewPlayerBase::~PreviewPlayerBase() {
218 if (mQueueStarted) {
219 mQueue.stop();
220 }
221
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800222 delete mYV12ColorConverter;
223
James Dongc9dedc42011-05-01 12:36:22 -0700224 reset();
225
226 mClient.disconnect();
227}
228
229void PreviewPlayerBase::cancelPlayerEvents(bool keepBufferingGoing) {
230 mQueue.cancelEvent(mVideoEvent->eventID());
231 mVideoEventPending = false;
232 mQueue.cancelEvent(mStreamDoneEvent->eventID());
233 mStreamDoneEventPending = false;
234 mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
235 mAudioStatusEventPending = false;
236 mQueue.cancelEvent(mVideoLagEvent->eventID());
237 mVideoLagEventPending = false;
238
239 if (!keepBufferingGoing) {
240 mQueue.cancelEvent(mBufferingEvent->eventID());
241 mBufferingEventPending = false;
242 }
243}
244
245void PreviewPlayerBase::setListener(const wp<MediaPlayerBase> &listener) {
246 Mutex::Autolock autoLock(mLock);
247 mListener = listener;
248}
249
250status_t PreviewPlayerBase::setDataSource(
251 const char *uri, const KeyedVector<String8, String8> *headers) {
252 Mutex::Autolock autoLock(mLock);
253 return setDataSource_l(uri, headers);
254}
255
256status_t PreviewPlayerBase::setDataSource_l(
257 const char *uri, const KeyedVector<String8, String8> *headers) {
258 reset_l();
259
260 mUri = uri;
261
262 if (headers) {
263 mUriHeaders = *headers;
264
265 ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
266 if (index >= 0) {
267 // Browser is in "incognito" mode, suppress logging URLs.
268
269 // This isn't something that should be passed to the server.
270 mUriHeaders.removeItemsAt(index);
271
272 mFlags |= INCOGNITO;
273 }
274 }
275
276 if (!(mFlags & INCOGNITO)) {
277 LOGI("setDataSource_l('%s')", mUri.string());
278 } else {
279 LOGI("setDataSource_l(URL suppressed)");
280 }
281
282 // The actual work will be done during preparation in the call to
283 // ::finishSetDataSource_l to avoid blocking the calling thread in
284 // setDataSource for any significant time.
285
286 return OK;
287}
288
289status_t PreviewPlayerBase::setDataSource(
290 int fd, int64_t offset, int64_t length) {
291 Mutex::Autolock autoLock(mLock);
292
293 reset_l();
294
295 sp<DataSource> dataSource = new FileSource(fd, offset, length);
296
297 status_t err = dataSource->initCheck();
298
299 if (err != OK) {
300 return err;
301 }
302
303 mFileSource = dataSource;
304
305 return setDataSource_l(dataSource);
306}
307
308status_t PreviewPlayerBase::setDataSource(const sp<IStreamSource> &source) {
309 return INVALID_OPERATION;
310}
311
312status_t PreviewPlayerBase::setDataSource_l(
313 const sp<DataSource> &dataSource) {
314 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
315
316 if (extractor == NULL) {
317 return UNKNOWN_ERROR;
318 }
319
320 dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
321 if (mDecryptHandle != NULL) {
322 CHECK(mDrmManagerClient);
323 if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
324 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
325 }
326 }
327
328 return setDataSource_l(extractor);
329}
330
331status_t PreviewPlayerBase::setDataSource_l(const sp<MediaExtractor> &extractor) {
332 // Attempt to approximate overall stream bitrate by summing all
333 // tracks' individual bitrates, if not all of them advertise bitrate,
334 // we have to fail.
335
336 int64_t totalBitRate = 0;
337
338 for (size_t i = 0; i < extractor->countTracks(); ++i) {
339 sp<MetaData> meta = extractor->getTrackMetaData(i);
340
341 int32_t bitrate;
342 if (!meta->findInt32(kKeyBitRate, &bitrate)) {
343 totalBitRate = -1;
344 break;
345 }
346
347 totalBitRate += bitrate;
348 }
349
350 mBitrate = totalBitRate;
351
352 LOGV("mBitrate = %lld bits/sec", mBitrate);
353
354 bool haveAudio = false;
355 bool haveVideo = false;
356 for (size_t i = 0; i < extractor->countTracks(); ++i) {
357 sp<MetaData> meta = extractor->getTrackMetaData(i);
358
359 const char *mime;
360 CHECK(meta->findCString(kKeyMIMEType, &mime));
361
362 if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
363 setVideoSource(extractor->getTrack(i));
364 haveVideo = true;
365
366 // Set the presentation/display size
367 int32_t displayWidth, displayHeight;
368 bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
369 if (success) {
370 success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
371 }
372 if (success) {
373 mDisplayWidth = displayWidth;
374 mDisplayHeight = displayHeight;
375 }
376
377 } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
378 setAudioSource(extractor->getTrack(i));
379 haveAudio = true;
380
381 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
382 // Only do this for vorbis audio, none of the other audio
383 // formats even support this ringtone specific hack and
384 // retrieving the metadata on some extractors may turn out
385 // to be very expensive.
386 sp<MetaData> fileMeta = extractor->getMetaData();
387 int32_t loop;
388 if (fileMeta != NULL
389 && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
390 mFlags |= AUTO_LOOPING;
391 }
392 }
393 }
394
395 if (haveAudio && haveVideo) {
396 break;
397 }
398 }
399
400 if (!haveAudio && !haveVideo) {
401 return UNKNOWN_ERROR;
402 }
403
404 mExtractorFlags = extractor->flags();
405
406 return OK;
407}
408
409void PreviewPlayerBase::reset() {
410 Mutex::Autolock autoLock(mLock);
411 reset_l();
412}
413
414void PreviewPlayerBase::reset_l() {
415 mDisplayWidth = 0;
416 mDisplayHeight = 0;
417
418 if (mDecryptHandle != NULL) {
419 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
420 Playback::STOP, 0);
421 mDecryptHandle = NULL;
422 mDrmManagerClient = NULL;
423 }
424
425 if (mFlags & PLAYING) {
426 uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
427 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
428 params |= IMediaPlayerService::kBatteryDataTrackAudio;
429 }
430 if (mVideoSource != NULL) {
431 params |= IMediaPlayerService::kBatteryDataTrackVideo;
432 }
433 addBatteryData(params);
434 }
435
436 if (mFlags & PREPARING) {
437 mFlags |= PREPARE_CANCELLED;
438 if (mConnectingDataSource != NULL) {
439 LOGI("interrupting the connection process");
440 mConnectingDataSource->disconnect();
441 } else if (mConnectingRTSPController != NULL) {
442 LOGI("interrupting the connection process");
443 mConnectingRTSPController->disconnect();
444 }
445
446 if (mFlags & PREPARING_CONNECTED) {
447 // We are basically done preparing, we're just buffering
448 // enough data to start playback, we can safely interrupt that.
449 finishAsyncPrepare_l();
450 }
451 }
452
453 while (mFlags & PREPARING) {
454 mPreparedCondition.wait(mLock);
455 }
456
457 cancelPlayerEvents();
458
459 mCachedSource.clear();
460 mAudioTrack.clear();
461 mVideoTrack.clear();
462
463 // Shutdown audio first, so that the respone to the reset request
464 // appears to happen instantaneously as far as the user is concerned
465 // If we did this later, audio would continue playing while we
466 // shutdown the video-related resources and the player appear to
467 // not be as responsive to a reset request.
468 if (mAudioPlayer == NULL && mAudioSource != NULL) {
469 // If we had an audio player, it would have effectively
470 // taken possession of the audio source and stopped it when
471 // _it_ is stopped. Otherwise this is still our responsibility.
472 mAudioSource->stop();
473 }
474 mAudioSource.clear();
475
476 mTimeSource = NULL;
477
478 delete mAudioPlayer;
479 mAudioPlayer = NULL;
480
481 mVideoRenderer.clear();
482
483 if (mRTSPController != NULL) {
484 mRTSPController->disconnect();
485 mRTSPController.clear();
486 }
487
488 if (mVideoSource != NULL) {
489 shutdownVideoDecoder_l();
490 }
491
492 mDurationUs = -1;
493 mFlags = 0;
494 mExtractorFlags = 0;
495 mTimeSourceDeltaUs = 0;
496 mVideoTimeUs = 0;
497
498 mSeeking = NO_SEEK;
499 mSeekNotificationSent = false;
500 mSeekTimeUs = 0;
501
502 mUri.setTo("");
503 mUriHeaders.clear();
504
505 mFileSource.clear();
506
507 mBitrate = -1;
508 mLastVideoTimeUs = -1;
509}
510
511void PreviewPlayerBase::notifyListener_l(int msg, int ext1, int ext2) {
512 if (mListener != NULL) {
513 sp<MediaPlayerBase> listener = mListener.promote();
514
515 if (listener != NULL) {
516 listener->sendEvent(msg, ext1, ext2);
517 }
518 }
519}
520
521bool PreviewPlayerBase::getBitrate(int64_t *bitrate) {
522 off64_t size;
523 if (mDurationUs >= 0 && mCachedSource != NULL
524 && mCachedSource->getSize(&size) == OK) {
525 *bitrate = size * 8000000ll / mDurationUs; // in bits/sec
526 return true;
527 }
528
529 if (mBitrate >= 0) {
530 *bitrate = mBitrate;
531 return true;
532 }
533
534 *bitrate = 0;
535
536 return false;
537}
538
539// Returns true iff cached duration is available/applicable.
540bool PreviewPlayerBase::getCachedDuration_l(int64_t *durationUs, bool *eos) {
541 int64_t bitrate;
542
543 if (mRTSPController != NULL) {
544 *durationUs = mRTSPController->getQueueDurationUs(eos);
545 return true;
546 } else if (mCachedSource != NULL && getBitrate(&bitrate)) {
547 status_t finalStatus;
548 size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
549 *durationUs = cachedDataRemaining * 8000000ll / bitrate;
550 *eos = (finalStatus != OK);
551 return true;
552 }
553
554 return false;
555}
556
557void PreviewPlayerBase::ensureCacheIsFetching_l() {
558 if (mCachedSource != NULL) {
559 mCachedSource->resumeFetchingIfNecessary();
560 }
561}
562
563void PreviewPlayerBase::onVideoLagUpdate() {
564 Mutex::Autolock autoLock(mLock);
565 if (!mVideoLagEventPending) {
566 return;
567 }
568 mVideoLagEventPending = false;
569
570 int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
571 int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
572
573 if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
574 LOGV("video late by %lld ms.", videoLateByUs / 1000ll);
575
576 notifyListener_l(
577 MEDIA_INFO,
578 MEDIA_INFO_VIDEO_TRACK_LAGGING,
579 videoLateByUs / 1000ll);
580 }
581
582 postVideoLagEvent_l();
583}
584
585void PreviewPlayerBase::onBufferingUpdate() {
586 Mutex::Autolock autoLock(mLock);
587 if (!mBufferingEventPending) {
588 return;
589 }
590 mBufferingEventPending = false;
591
592 if (mCachedSource != NULL) {
593 status_t finalStatus;
594 size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
595 bool eos = (finalStatus != OK);
596
597 if (eos) {
598 if (finalStatus == ERROR_END_OF_STREAM) {
599 notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
600 }
601 if (mFlags & PREPARING) {
602 LOGV("cache has reached EOS, prepare is done.");
603 finishAsyncPrepare_l();
604 }
605 } else {
606 int64_t bitrate;
607 if (getBitrate(&bitrate)) {
608 size_t cachedSize = mCachedSource->cachedSize();
609 int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
610
611 int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
612 if (percentage > 100) {
613 percentage = 100;
614 }
615
616 notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
617 } else {
618 // We don't know the bitrate of the stream, use absolute size
619 // limits to maintain the cache.
620
621 if ((mFlags & PLAYING) && !eos
622 && (cachedDataRemaining < kLowWaterMarkBytes)) {
623 LOGI("cache is running low (< %d) , pausing.",
624 kLowWaterMarkBytes);
625 mFlags |= CACHE_UNDERRUN;
626 pause_l();
627 ensureCacheIsFetching_l();
628 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
629 } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
630 if (mFlags & CACHE_UNDERRUN) {
631 LOGI("cache has filled up (> %d), resuming.",
632 kHighWaterMarkBytes);
633 mFlags &= ~CACHE_UNDERRUN;
634 play_l();
635 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
636 } else if (mFlags & PREPARING) {
637 LOGV("cache has filled up (> %d), prepare is done",
638 kHighWaterMarkBytes);
639 finishAsyncPrepare_l();
640 }
641 }
642 }
643 }
644 }
645
646 int64_t cachedDurationUs;
647 bool eos;
648 if (getCachedDuration_l(&cachedDurationUs, &eos)) {
649 LOGV("cachedDurationUs = %.2f secs, eos=%d",
650 cachedDurationUs / 1E6, eos);
651
652 int64_t highWaterMarkUs =
653 (mRTSPController != NULL) ? kHighWaterMarkRTSPUs : kHighWaterMarkUs;
654
655 if ((mFlags & PLAYING) && !eos
656 && (cachedDurationUs < kLowWaterMarkUs)) {
657 LOGI("cache is running low (%.2f secs) , pausing.",
658 cachedDurationUs / 1E6);
659 mFlags |= CACHE_UNDERRUN;
660 pause_l();
661 ensureCacheIsFetching_l();
662 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
663 } else if (eos || cachedDurationUs > highWaterMarkUs) {
664 if (mFlags & CACHE_UNDERRUN) {
665 LOGI("cache has filled up (%.2f secs), resuming.",
666 cachedDurationUs / 1E6);
667 mFlags &= ~CACHE_UNDERRUN;
668 play_l();
669 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
670 } else if (mFlags & PREPARING) {
671 LOGV("cache has filled up (%.2f secs), prepare is done",
672 cachedDurationUs / 1E6);
673 finishAsyncPrepare_l();
674 }
675 }
676 }
677
678 postBufferingEvent_l();
679}
680
681void PreviewPlayerBase::onStreamDone() {
682 // Posted whenever any stream finishes playing.
683
684 Mutex::Autolock autoLock(mLock);
685 if (!mStreamDoneEventPending) {
686 return;
687 }
688 mStreamDoneEventPending = false;
689
690 if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
691 LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
692
693 notifyListener_l(
694 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
695
696 pause_l(true /* at eos */);
697
698 mFlags |= AT_EOS;
699 return;
700 }
701
702 const bool allDone =
703 (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
704 && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
705
706 if (!allDone) {
707 return;
708 }
709
710 if (mFlags & (LOOPING | AUTO_LOOPING)) {
711 seekTo_l(0);
712
713 if (mVideoSource != NULL) {
714 postVideoEvent_l();
715 }
716 } else {
717 LOGV("MEDIA_PLAYBACK_COMPLETE");
718 notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
719
720 pause_l(true /* at eos */);
721
722 mFlags |= AT_EOS;
723 }
724}
725
726status_t PreviewPlayerBase::play() {
727 Mutex::Autolock autoLock(mLock);
728
729 mFlags &= ~CACHE_UNDERRUN;
730
731 return play_l();
732}
733
734status_t PreviewPlayerBase::play_l() {
735 mFlags &= ~SEEK_PREVIEW;
736
737 if (mFlags & PLAYING) {
738 return OK;
739 }
740
741 if (!(mFlags & PREPARED)) {
742 status_t err = prepare_l();
743
744 if (err != OK) {
745 return err;
746 }
747 }
748
749 mFlags |= PLAYING;
750 mFlags |= FIRST_FRAME;
751
752 if (mDecryptHandle != NULL) {
753 int64_t position;
754 getPosition(&position);
755 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
756 Playback::START, position / 1000);
757 }
758
759 if (mAudioSource != NULL) {
760 if (mAudioPlayer == NULL) {
761 if (mAudioSink != NULL) {
762 mAudioPlayer = new AudioPlayerBase(mAudioSink, this);
763 mAudioPlayer->setSource(mAudioSource);
764
765 mTimeSource = mAudioPlayer;
766
767 // If there was a seek request before we ever started,
768 // honor the request now.
769 // Make sure to do this before starting the audio player
770 // to avoid a race condition.
771 seekAudioIfNecessary_l();
772 }
773 }
774
775 CHECK(!(mFlags & AUDIO_RUNNING));
776
777 if (mVideoSource == NULL) {
778 status_t err = startAudioPlayer_l();
779
780 if (err != OK) {
781 delete mAudioPlayer;
782 mAudioPlayer = NULL;
783
784 mFlags &= ~(PLAYING | FIRST_FRAME);
785
786 if (mDecryptHandle != NULL) {
787 mDrmManagerClient->setPlaybackStatus(
788 mDecryptHandle, Playback::STOP, 0);
789 }
790
791 return err;
792 }
793 }
794 }
795
796 if (mTimeSource == NULL && mAudioPlayer == NULL) {
797 mTimeSource = &mSystemTimeSource;
798 }
799
800 if (mVideoSource != NULL) {
801 // Kick off video playback
802 postVideoEvent_l();
803
804 if (mAudioSource != NULL && mVideoSource != NULL) {
805 postVideoLagEvent_l();
806 }
807 }
808
809 if (mFlags & AT_EOS) {
810 // Legacy behaviour, if a stream finishes playing and then
811 // is started again, we play from the start...
812 seekTo_l(0);
813 }
814
815 uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
816 | IMediaPlayerService::kBatteryDataTrackDecoder;
817 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
818 params |= IMediaPlayerService::kBatteryDataTrackAudio;
819 }
820 if (mVideoSource != NULL) {
821 params |= IMediaPlayerService::kBatteryDataTrackVideo;
822 }
823 addBatteryData(params);
824
825 return OK;
826}
827
828status_t PreviewPlayerBase::startAudioPlayer_l() {
829 CHECK(!(mFlags & AUDIO_RUNNING));
830
831 if (mAudioSource == NULL || mAudioPlayer == NULL) {
832 return OK;
833 }
834
835 if (!(mFlags & AUDIOPLAYER_STARTED)) {
836 mFlags |= AUDIOPLAYER_STARTED;
837
838 // We've already started the MediaSource in order to enable
839 // the prefetcher to read its data.
840 status_t err = mAudioPlayer->start(
841 true /* sourceAlreadyStarted */);
842
843 if (err != OK) {
844 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
845 return err;
846 }
847 } else {
848 mAudioPlayer->resume();
849 }
850
851 mFlags |= AUDIO_RUNNING;
852
853 mWatchForAudioEOS = true;
854
855 return OK;
856}
857
858void PreviewPlayerBase::notifyVideoSize_l() {
859 sp<MetaData> meta = mVideoSource->getFormat();
860
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800861 int32_t vWidth, vHeight;
James Dongc9dedc42011-05-01 12:36:22 -0700862 int32_t cropLeft, cropTop, cropRight, cropBottom;
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800863
864 CHECK(meta->findInt32(kKeyWidth, &vWidth));
865 CHECK(meta->findInt32(kKeyHeight, &vHeight));
866
867 mGivenWidth = vWidth;
868 mGivenHeight = vHeight;
869
James Dongc9dedc42011-05-01 12:36:22 -0700870 if (!meta->findRect(
871 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
James Dongc9dedc42011-05-01 12:36:22 -0700872
873 cropLeft = cropTop = 0;
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800874 cropRight = vWidth - 1;
875 cropBottom = vHeight - 1;
James Dongc9dedc42011-05-01 12:36:22 -0700876
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800877 LOGD("got dimensions only %d x %d", vWidth, vHeight);
James Dongc9dedc42011-05-01 12:36:22 -0700878 } else {
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800879 LOGD("got crop rect %d, %d, %d, %d",
James Dongc9dedc42011-05-01 12:36:22 -0700880 cropLeft, cropTop, cropRight, cropBottom);
881 }
882
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +0800883 mCropRect.left = cropLeft;
884 mCropRect.right = cropRight;
885 mCropRect.top = cropTop;
886 mCropRect.bottom = cropBottom;
887
James Dongc9dedc42011-05-01 12:36:22 -0700888 int32_t displayWidth;
889 if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
890 LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
891 mDisplayWidth = displayWidth;
892 }
893 int32_t displayHeight;
894 if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
895 LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
896 mDisplayHeight = displayHeight;
897 }
898
899 int32_t usableWidth = cropRight - cropLeft + 1;
900 int32_t usableHeight = cropBottom - cropTop + 1;
901 if (mDisplayWidth != 0) {
902 usableWidth = mDisplayWidth;
903 }
904 if (mDisplayHeight != 0) {
905 usableHeight = mDisplayHeight;
906 }
907
908 int32_t rotationDegrees;
909 if (!mVideoTrack->getFormat()->findInt32(
910 kKeyRotation, &rotationDegrees)) {
911 rotationDegrees = 0;
912 }
913
914 if (rotationDegrees == 90 || rotationDegrees == 270) {
915 notifyListener_l(
916 MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
917 } else {
918 notifyListener_l(
919 MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
920 }
921}
922
923void PreviewPlayerBase::initRenderer_l() {
924 if (mNativeWindow == NULL) {
925 return;
926 }
927
928 sp<MetaData> meta = mVideoSource->getFormat();
929
930 int32_t format;
931 const char *component;
James Dongc9dedc42011-05-01 12:36:22 -0700932 CHECK(meta->findInt32(kKeyColorFormat, &format));
933 CHECK(meta->findCString(kKeyDecoderComponent, &component));
James Dongc9dedc42011-05-01 12:36:22 -0700934
935 int32_t rotationDegrees;
936 if (!mVideoTrack->getFormat()->findInt32(
937 kKeyRotation, &rotationDegrees)) {
938 rotationDegrees = 0;
939 }
940
941 mVideoRenderer.clear();
942
943 // Must ensure that mVideoRenderer's destructor is actually executed
944 // before creating a new one.
945 IPCThreadState::self()->flushCommands();
946
947 if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) {
948 // Hardware decoders avoid the CPU color conversion by decoding
949 // directly to ANativeBuffers, so we must use a renderer that
950 // just pushes those buffers to the ANativeWindow.
951 mVideoRenderer =
952 new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
953 } else {
954 // Other decoders are instantiated locally and as a consequence
955 // allocate their buffers in local address space. This renderer
956 // then performs a color conversion and copy to get the data
957 // into the ANativeBuffer.
958 mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
959 }
960}
961
962status_t PreviewPlayerBase::pause() {
963 Mutex::Autolock autoLock(mLock);
964
965 mFlags &= ~CACHE_UNDERRUN;
966
967 return pause_l();
968}
969
970status_t PreviewPlayerBase::pause_l(bool at_eos) {
971 if (!(mFlags & PLAYING)) {
972 return OK;
973 }
974
975 cancelPlayerEvents(true /* keepBufferingGoing */);
976
977 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
978 if (at_eos) {
979 // If we played the audio stream to completion we
980 // want to make sure that all samples remaining in the audio
981 // track's queue are played out.
982 mAudioPlayer->pause(true /* playPendingSamples */);
983 } else {
984 mAudioPlayer->pause();
985 }
986
987 mFlags &= ~AUDIO_RUNNING;
988 }
989
990 mFlags &= ~PLAYING;
991
992 if (mDecryptHandle != NULL) {
993 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
994 Playback::PAUSE, 0);
995 }
996
997 uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
998 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
999 params |= IMediaPlayerService::kBatteryDataTrackAudio;
1000 }
1001 if (mVideoSource != NULL) {
1002 params |= IMediaPlayerService::kBatteryDataTrackVideo;
1003 }
1004
1005 addBatteryData(params);
1006
1007 return OK;
1008}
1009
1010bool PreviewPlayerBase::isPlaying() const {
1011 return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
1012}
1013
1014void PreviewPlayerBase::setSurface(const sp<Surface> &surface) {
1015 Mutex::Autolock autoLock(mLock);
1016
1017 mSurface = surface;
1018 setNativeWindow_l(surface);
1019}
1020
1021void PreviewPlayerBase::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1022 Mutex::Autolock autoLock(mLock);
1023
1024 mSurface.clear();
1025 if (surfaceTexture != NULL) {
1026 setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
1027 }
1028}
1029
1030void PreviewPlayerBase::shutdownVideoDecoder_l() {
1031 if (mVideoBuffer) {
1032 mVideoBuffer->release();
1033 mVideoBuffer = NULL;
1034 }
1035
1036 mVideoSource->stop();
1037
1038 // The following hack is necessary to ensure that the OMX
1039 // component is completely released by the time we may try
1040 // to instantiate it again.
1041 wp<MediaSource> tmp = mVideoSource;
1042 mVideoSource.clear();
1043 while (tmp.promote() != NULL) {
1044 usleep(1000);
1045 }
1046 IPCThreadState::self()->flushCommands();
1047}
1048
1049void PreviewPlayerBase::setNativeWindow_l(const sp<ANativeWindow> &native) {
1050 mNativeWindow = native;
1051
1052 if (mVideoSource == NULL) {
1053 return;
1054 }
1055
1056 LOGI("attempting to reconfigure to use new surface");
1057
1058 bool wasPlaying = (mFlags & PLAYING) != 0;
1059
1060 pause_l();
1061 mVideoRenderer.clear();
1062
1063 shutdownVideoDecoder_l();
1064
1065 CHECK_EQ(initVideoDecoder(), (status_t)OK);
1066
1067 if (mLastVideoTimeUs >= 0) {
1068 mSeeking = SEEK;
1069 mSeekNotificationSent = true;
1070 mSeekTimeUs = mLastVideoTimeUs;
1071 mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
1072 }
1073
1074 if (wasPlaying) {
1075 play_l();
1076 }
1077}
1078
1079void PreviewPlayerBase::setAudioSink(
1080 const sp<MediaPlayerBase::AudioSink> &audioSink) {
1081 Mutex::Autolock autoLock(mLock);
1082
1083 mAudioSink = audioSink;
1084}
1085
1086status_t PreviewPlayerBase::setLooping(bool shouldLoop) {
1087 Mutex::Autolock autoLock(mLock);
1088
1089 mFlags = mFlags & ~LOOPING;
1090
1091 if (shouldLoop) {
1092 mFlags |= LOOPING;
1093 }
1094
1095 return OK;
1096}
1097
1098status_t PreviewPlayerBase::getDuration(int64_t *durationUs) {
1099 Mutex::Autolock autoLock(mMiscStateLock);
1100
1101 if (mDurationUs < 0) {
1102 return UNKNOWN_ERROR;
1103 }
1104
1105 *durationUs = mDurationUs;
1106
1107 return OK;
1108}
1109
1110status_t PreviewPlayerBase::getPosition(int64_t *positionUs) {
1111 if (mRTSPController != NULL) {
1112 *positionUs = mRTSPController->getNormalPlayTimeUs();
1113 }
1114 else if (mSeeking != NO_SEEK) {
1115 *positionUs = mSeekTimeUs;
1116 } else if (mVideoSource != NULL
1117 && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
1118 Mutex::Autolock autoLock(mMiscStateLock);
1119 *positionUs = mVideoTimeUs;
1120 } else if (mAudioPlayer != NULL) {
1121 *positionUs = mAudioPlayer->getMediaTimeUs();
1122 } else {
1123 *positionUs = 0;
1124 }
1125
1126 return OK;
1127}
1128
1129status_t PreviewPlayerBase::seekTo(int64_t timeUs) {
1130 if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
1131 Mutex::Autolock autoLock(mLock);
1132 return seekTo_l(timeUs);
1133 }
1134
1135 return OK;
1136}
1137
1138// static
1139void PreviewPlayerBase::OnRTSPSeekDoneWrapper(void *cookie) {
1140 static_cast<PreviewPlayerBase *>(cookie)->onRTSPSeekDone();
1141}
1142
1143void PreviewPlayerBase::onRTSPSeekDone() {
1144 notifyListener_l(MEDIA_SEEK_COMPLETE);
1145 mSeekNotificationSent = true;
1146}
1147
1148status_t PreviewPlayerBase::seekTo_l(int64_t timeUs) {
1149 if (mRTSPController != NULL) {
1150 mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this);
1151 return OK;
1152 }
1153
1154 if (mFlags & CACHE_UNDERRUN) {
1155 mFlags &= ~CACHE_UNDERRUN;
1156 play_l();
1157 }
1158
1159 if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
1160 // Video playback completed before, there's no pending
1161 // video event right now. In order for this new seek
1162 // to be honored, we need to post one.
1163
1164 postVideoEvent_l();
1165 }
1166
1167 mSeeking = SEEK;
1168 mSeekNotificationSent = false;
1169 mSeekTimeUs = timeUs;
1170 mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
1171
1172 seekAudioIfNecessary_l();
1173
1174 if (!(mFlags & PLAYING)) {
1175 LOGV("seeking while paused, sending SEEK_COMPLETE notification"
1176 " immediately.");
1177
1178 notifyListener_l(MEDIA_SEEK_COMPLETE);
1179 mSeekNotificationSent = true;
1180
1181 if ((mFlags & PREPARED) && mVideoSource != NULL) {
1182 mFlags |= SEEK_PREVIEW;
1183 postVideoEvent_l();
1184 }
1185 }
1186
1187 return OK;
1188}
1189
1190void PreviewPlayerBase::seekAudioIfNecessary_l() {
1191 if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
1192 mAudioPlayer->seekTo(mSeekTimeUs);
1193
1194 mWatchForAudioSeekComplete = true;
1195 mWatchForAudioEOS = true;
1196
1197 if (mDecryptHandle != NULL) {
1198 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1199 Playback::PAUSE, 0);
1200 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1201 Playback::START, mSeekTimeUs / 1000);
1202 }
1203 }
1204}
1205
1206void PreviewPlayerBase::setAudioSource(sp<MediaSource> source) {
1207 CHECK(source != NULL);
1208
1209 mAudioTrack = source;
1210}
1211
1212status_t PreviewPlayerBase::initAudioDecoder() {
1213 sp<MetaData> meta = mAudioTrack->getFormat();
1214
1215 const char *mime;
1216 CHECK(meta->findCString(kKeyMIMEType, &mime));
1217
1218 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1219 mAudioSource = mAudioTrack;
1220 } else {
1221 mAudioSource = OMXCodec::Create(
1222 mClient.interface(), mAudioTrack->getFormat(),
1223 false, // createEncoder
1224 mAudioTrack);
1225 }
1226
1227 if (mAudioSource != NULL) {
1228 int64_t durationUs;
1229 if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1230 Mutex::Autolock autoLock(mMiscStateLock);
1231 if (mDurationUs < 0 || durationUs > mDurationUs) {
1232 mDurationUs = durationUs;
1233 }
1234 }
1235
1236 status_t err = mAudioSource->start();
1237
1238 if (err != OK) {
1239 mAudioSource.clear();
1240 return err;
1241 }
1242 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
1243 // For legacy reasons we're simply going to ignore the absence
1244 // of an audio decoder for QCELP instead of aborting playback
1245 // altogether.
1246 return OK;
1247 }
1248
1249 return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
1250}
1251
1252void PreviewPlayerBase::setVideoSource(sp<MediaSource> source) {
1253 CHECK(source != NULL);
1254
1255 mVideoTrack = source;
1256}
1257
1258status_t PreviewPlayerBase::initVideoDecoder(uint32_t flags) {
1259
1260 // Either the application or the DRM system can independently say
1261 // that there must be a hardware-protected path to an external video sink.
1262 // For now we always require a hardware-protected path to external video sink
1263 // if content is DRMed, but eventually this could be optional per DRM agent.
1264 // When the application wants protection, then
1265 // (USE_SURFACE_ALLOC && (mSurface != 0) &&
1266 // (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
1267 // will be true, but that part is already handled by SurfaceFlinger.
1268
1269#ifdef DEBUG_HDCP
1270 // For debugging, we allow a system property to control the protected usage.
1271 // In case of uninitialized or unexpected property, we default to "DRM only".
1272 bool setProtectionBit = false;
1273 char value[PROPERTY_VALUE_MAX];
1274 if (property_get("persist.sys.hdcp_checking", value, NULL)) {
1275 if (!strcmp(value, "never")) {
1276 // nop
1277 } else if (!strcmp(value, "always")) {
1278 setProtectionBit = true;
1279 } else if (!strcmp(value, "drm-only")) {
1280 if (mDecryptHandle != NULL) {
1281 setProtectionBit = true;
1282 }
1283 // property value is empty, or unexpected value
1284 } else {
1285 if (mDecryptHandle != NULL) {
1286 setProtectionBit = true;
1287 }
1288 }
1289 // can' read property value
1290 } else {
1291 if (mDecryptHandle != NULL) {
1292 setProtectionBit = true;
1293 }
1294 }
1295 // note that usage bit is already cleared, so no need to clear it in the "else" case
1296 if (setProtectionBit) {
1297 flags |= OMXCodec::kEnableGrallocUsageProtected;
1298 }
1299#else
1300 if (mDecryptHandle != NULL) {
1301 flags |= OMXCodec::kEnableGrallocUsageProtected;
1302 }
1303#endif
1304 LOGV("initVideoDecoder flags=0x%x", flags);
1305 mVideoSource = OMXCodec::Create(
1306 mClient.interface(), mVideoTrack->getFormat(),
1307 false, // createEncoder
1308 mVideoTrack,
1309 NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
1310
1311 if (mVideoSource != NULL) {
1312 int64_t durationUs;
1313 if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1314 Mutex::Autolock autoLock(mMiscStateLock);
1315 if (mDurationUs < 0 || durationUs > mDurationUs) {
1316 mDurationUs = durationUs;
1317 }
1318 }
1319
1320 status_t err = mVideoSource->start();
1321
1322 if (err != OK) {
1323 mVideoSource.clear();
1324 return err;
1325 }
1326 }
1327
1328 return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
1329}
1330
1331void PreviewPlayerBase::finishSeekIfNecessary(int64_t videoTimeUs) {
1332 if (mSeeking == SEEK_VIDEO_ONLY) {
1333 mSeeking = NO_SEEK;
1334 return;
1335 }
1336
1337 if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
1338 return;
1339 }
1340
1341 if (mAudioPlayer != NULL) {
1342 LOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
1343
1344 // If we don't have a video time, seek audio to the originally
1345 // requested seek time instead.
1346
1347 mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
1348 mWatchForAudioSeekComplete = true;
1349 mWatchForAudioEOS = true;
1350 } else if (!mSeekNotificationSent) {
1351 // If we're playing video only, report seek complete now,
1352 // otherwise audio player will notify us later.
1353 notifyListener_l(MEDIA_SEEK_COMPLETE);
1354 mSeekNotificationSent = true;
1355 }
1356
1357 mFlags |= FIRST_FRAME;
1358 mSeeking = NO_SEEK;
1359
1360 if (mDecryptHandle != NULL) {
1361 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1362 Playback::PAUSE, 0);
1363 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1364 Playback::START, videoTimeUs / 1000);
1365 }
1366}
1367
1368void PreviewPlayerBase::onVideoEvent() {
1369 Mutex::Autolock autoLock(mLock);
1370 if (!mVideoEventPending) {
1371 // The event has been cancelled in reset_l() but had already
1372 // been scheduled for execution at that time.
1373 return;
1374 }
1375 mVideoEventPending = false;
1376
1377 if (mSeeking != NO_SEEK) {
1378 if (mVideoBuffer) {
1379 mVideoBuffer->release();
1380 mVideoBuffer = NULL;
1381 }
1382
1383 if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
1384 && !(mFlags & SEEK_PREVIEW)) {
1385 // We're going to seek the video source first, followed by
1386 // the audio source.
1387 // In order to avoid jumps in the DataSource offset caused by
1388 // the audio codec prefetching data from the old locations
1389 // while the video codec is already reading data from the new
1390 // locations, we'll "pause" the audio source, causing it to
1391 // stop reading input data until a subsequent seek.
1392
1393 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1394 mAudioPlayer->pause();
1395
1396 mFlags &= ~AUDIO_RUNNING;
1397 }
1398 mAudioSource->pause();
1399 }
1400 }
1401
1402 if (!mVideoBuffer) {
1403 MediaSource::ReadOptions options;
1404 if (mSeeking != NO_SEEK) {
1405 LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
1406
1407 options.setSeekTo(
1408 mSeekTimeUs,
1409 mSeeking == SEEK_VIDEO_ONLY
1410 ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
1411 : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
1412 }
1413 for (;;) {
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +08001414 status_t err = readYV12Buffer(mVideoSource, &mVideoBuffer, &options);
James Dongc9dedc42011-05-01 12:36:22 -07001415 options.clearSeekTo();
1416
1417 if (err != OK) {
1418 CHECK(mVideoBuffer == NULL);
1419
1420 if (err == INFO_FORMAT_CHANGED) {
1421 LOGV("VideoSource signalled format change.");
1422
1423 notifyVideoSize_l();
1424
1425 if (mVideoRenderer != NULL) {
1426 mVideoRendererIsPreview = false;
1427 initRenderer_l();
1428 }
1429 continue;
1430 }
1431
1432 // So video playback is complete, but we may still have
1433 // a seek request pending that needs to be applied
1434 // to the audio track.
1435 if (mSeeking != NO_SEEK) {
1436 LOGV("video stream ended while seeking!");
1437 }
1438 finishSeekIfNecessary(-1);
1439
1440 if (mAudioPlayer != NULL
1441 && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1442 startAudioPlayer_l();
1443 }
1444
1445 mFlags |= VIDEO_AT_EOS;
1446 postStreamDoneEvent_l(err);
1447 return;
1448 }
1449
1450 if (mVideoBuffer->range_length() == 0) {
1451 // Some decoders, notably the PV AVC software decoder
1452 // return spurious empty buffers that we just want to ignore.
1453
1454 mVideoBuffer->release();
1455 mVideoBuffer = NULL;
1456 continue;
1457 }
1458
1459 break;
1460 }
1461 }
1462
1463 int64_t timeUs;
1464 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1465
1466 mLastVideoTimeUs = timeUs;
1467
1468 if (mSeeking == SEEK_VIDEO_ONLY) {
1469 if (mSeekTimeUs > timeUs) {
1470 LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
1471 mSeekTimeUs, timeUs);
1472 }
1473 }
1474
1475 {
1476 Mutex::Autolock autoLock(mMiscStateLock);
1477 mVideoTimeUs = timeUs;
1478 }
1479
1480 SeekType wasSeeking = mSeeking;
1481 finishSeekIfNecessary(timeUs);
1482
1483 if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1484 status_t err = startAudioPlayer_l();
1485 if (err != OK) {
1486 LOGE("Startung the audio player failed w/ err %d", err);
1487 return;
1488 }
1489 }
1490
1491 TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
1492
1493 if (mFlags & FIRST_FRAME) {
1494 mFlags &= ~FIRST_FRAME;
1495 mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
1496 }
1497
1498 int64_t realTimeUs, mediaTimeUs;
1499 if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
1500 && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
1501 mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
1502 }
1503
1504 if (wasSeeking == SEEK_VIDEO_ONLY) {
1505 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1506
1507 int64_t latenessUs = nowUs - timeUs;
1508
1509 if (latenessUs > 0) {
1510 LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
1511 }
1512 }
1513
1514 if (wasSeeking == NO_SEEK) {
1515 // Let's display the first frame after seeking right away.
1516
1517 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1518
1519 int64_t latenessUs = nowUs - timeUs;
1520
1521 if (latenessUs > 500000ll
1522 && mRTSPController == NULL
1523 && mAudioPlayer != NULL
1524 && mAudioPlayer->getMediaTimeMapping(
1525 &realTimeUs, &mediaTimeUs)) {
1526 LOGI("we're much too late (%.2f secs), video skipping ahead",
1527 latenessUs / 1E6);
1528
1529 mVideoBuffer->release();
1530 mVideoBuffer = NULL;
1531
1532 mSeeking = SEEK_VIDEO_ONLY;
1533 mSeekTimeUs = mediaTimeUs;
1534
1535 postVideoEvent_l();
1536 return;
1537 }
1538
1539 if (latenessUs > 40000) {
1540 // We're more than 40ms late.
1541 LOGV("we're late by %lld us (%.2f secs), dropping frame",
1542 latenessUs, latenessUs / 1E6);
1543 mVideoBuffer->release();
1544 mVideoBuffer = NULL;
1545
1546 postVideoEvent_l();
1547 return;
1548 }
1549
1550 if (latenessUs < -10000) {
1551 // We're more than 10ms early.
1552
1553 postVideoEvent_l(10000);
1554 return;
1555 }
1556 }
1557
1558 if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
1559 mVideoRendererIsPreview = false;
1560
1561 initRenderer_l();
1562 }
1563
1564 if (mVideoRenderer != NULL) {
1565 mVideoRenderer->render(mVideoBuffer);
1566 }
1567
1568 mVideoBuffer->release();
1569 mVideoBuffer = NULL;
1570
1571 if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
1572 mFlags &= ~SEEK_PREVIEW;
1573 return;
1574 }
1575
1576 postVideoEvent_l();
1577}
1578
1579void PreviewPlayerBase::postVideoEvent_l(int64_t delayUs) {
1580 if (mVideoEventPending) {
1581 return;
1582 }
1583
1584 mVideoEventPending = true;
1585 mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
1586}
1587
1588void PreviewPlayerBase::postStreamDoneEvent_l(status_t status) {
1589 if (mStreamDoneEventPending) {
1590 return;
1591 }
1592 mStreamDoneEventPending = true;
1593
1594 mStreamDoneStatus = status;
1595 mQueue.postEvent(mStreamDoneEvent);
1596}
1597
1598void PreviewPlayerBase::postBufferingEvent_l() {
1599 if (mBufferingEventPending) {
1600 return;
1601 }
1602 mBufferingEventPending = true;
1603 mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
1604}
1605
1606void PreviewPlayerBase::postVideoLagEvent_l() {
1607 if (mVideoLagEventPending) {
1608 return;
1609 }
1610 mVideoLagEventPending = true;
1611 mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
1612}
1613
1614void PreviewPlayerBase::postCheckAudioStatusEvent_l(int64_t delayUs) {
1615 if (mAudioStatusEventPending) {
1616 return;
1617 }
1618 mAudioStatusEventPending = true;
1619 mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
1620}
1621
1622void PreviewPlayerBase::onCheckAudioStatus() {
1623 Mutex::Autolock autoLock(mLock);
1624 if (!mAudioStatusEventPending) {
1625 // Event was dispatched and while we were blocking on the mutex,
1626 // has already been cancelled.
1627 return;
1628 }
1629
1630 mAudioStatusEventPending = false;
1631
1632 if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
1633 mWatchForAudioSeekComplete = false;
1634
1635 if (!mSeekNotificationSent) {
1636 notifyListener_l(MEDIA_SEEK_COMPLETE);
1637 mSeekNotificationSent = true;
1638 }
1639
1640 mSeeking = NO_SEEK;
1641 }
1642
1643 status_t finalStatus;
1644 if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
1645 mWatchForAudioEOS = false;
1646 mFlags |= AUDIO_AT_EOS;
1647 mFlags |= FIRST_FRAME;
1648 postStreamDoneEvent_l(finalStatus);
1649 }
1650}
1651
1652status_t PreviewPlayerBase::prepare() {
1653 Mutex::Autolock autoLock(mLock);
1654 return prepare_l();
1655}
1656
1657status_t PreviewPlayerBase::prepare_l() {
1658 if (mFlags & PREPARED) {
1659 return OK;
1660 }
1661
1662 if (mFlags & PREPARING) {
1663 return UNKNOWN_ERROR;
1664 }
1665
1666 mIsAsyncPrepare = false;
1667 status_t err = prepareAsync_l();
1668
1669 if (err != OK) {
1670 return err;
1671 }
1672
1673 while (mFlags & PREPARING) {
1674 mPreparedCondition.wait(mLock);
1675 }
1676
1677 return mPrepareResult;
1678}
1679
1680status_t PreviewPlayerBase::prepareAsync() {
1681 Mutex::Autolock autoLock(mLock);
1682
1683 if (mFlags & PREPARING) {
1684 return UNKNOWN_ERROR; // async prepare already pending
1685 }
1686
1687 mIsAsyncPrepare = true;
1688 return prepareAsync_l();
1689}
1690
1691status_t PreviewPlayerBase::prepareAsync_l() {
1692 if (mFlags & PREPARING) {
1693 return UNKNOWN_ERROR; // async prepare already pending
1694 }
1695
1696 if (!mQueueStarted) {
1697 mQueue.start();
1698 mQueueStarted = true;
1699 }
1700
1701 mFlags |= PREPARING;
1702 mAsyncPrepareEvent = new AwesomeEvent(
1703 this, &PreviewPlayerBase::onPrepareAsyncEvent);
1704
1705 mQueue.postEvent(mAsyncPrepareEvent);
1706
1707 return OK;
1708}
1709
1710status_t PreviewPlayerBase::finishSetDataSource_l() {
1711 sp<DataSource> dataSource;
1712
1713 if (!strncasecmp("http://", mUri.string(), 7)
1714 || !strncasecmp("https://", mUri.string(), 8)) {
1715 mConnectingDataSource = HTTPBase::Create(
1716 (mFlags & INCOGNITO)
1717 ? HTTPBase::kFlagIncognito
1718 : 0);
1719
1720 mLock.unlock();
1721 status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
1722 mLock.lock();
1723
1724 if (err != OK) {
1725 mConnectingDataSource.clear();
1726
1727 LOGI("mConnectingDataSource->connect() returned %d", err);
1728 return err;
1729 }
1730
1731#if 0
1732 mCachedSource = new NuCachedSource2(
1733 new ThrottledSource(
1734 mConnectingDataSource, 50 * 1024 /* bytes/sec */));
1735#else
1736 mCachedSource = new NuCachedSource2(mConnectingDataSource);
1737#endif
1738 mConnectingDataSource.clear();
1739
1740 dataSource = mCachedSource;
1741
1742 String8 contentType = dataSource->getMIMEType();
1743
1744 if (strncasecmp(contentType.string(), "audio/", 6)) {
1745 // We're not doing this for streams that appear to be audio-only
1746 // streams to ensure that even low bandwidth streams start
1747 // playing back fairly instantly.
1748
1749 // We're going to prefill the cache before trying to instantiate
1750 // the extractor below, as the latter is an operation that otherwise
1751 // could block on the datasource for a significant amount of time.
1752 // During that time we'd be unable to abort the preparation phase
1753 // without this prefill.
1754
1755 mLock.unlock();
1756
1757 for (;;) {
1758 status_t finalStatus;
1759 size_t cachedDataRemaining =
1760 mCachedSource->approxDataRemaining(&finalStatus);
1761
1762 if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
1763 || (mFlags & PREPARE_CANCELLED)) {
1764 break;
1765 }
1766
1767 usleep(200000);
1768 }
1769
1770 mLock.lock();
1771 }
1772
1773 if (mFlags & PREPARE_CANCELLED) {
1774 LOGI("Prepare cancelled while waiting for initial cache fill.");
1775 return UNKNOWN_ERROR;
1776 }
1777 } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
1778 if (mLooper == NULL) {
1779 mLooper = new ALooper;
1780 mLooper->setName("rtsp");
1781 mLooper->start();
1782 }
1783 mRTSPController = new ARTSPController(mLooper);
1784 mConnectingRTSPController = mRTSPController;
1785
1786 mLock.unlock();
1787 status_t err = mRTSPController->connect(mUri.string());
1788 mLock.lock();
1789
1790 mConnectingRTSPController.clear();
1791
1792 LOGI("ARTSPController::connect returned %d", err);
1793
1794 if (err != OK) {
1795 mRTSPController.clear();
1796 return err;
1797 }
1798
1799 sp<MediaExtractor> extractor = mRTSPController.get();
1800 return setDataSource_l(extractor);
1801 } else {
1802 dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
1803 }
1804
1805 if (dataSource == NULL) {
1806 return UNKNOWN_ERROR;
1807 }
1808
1809 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
1810
1811 if (extractor == NULL) {
1812 return UNKNOWN_ERROR;
1813 }
1814
1815 dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
1816
1817 if (mDecryptHandle != NULL) {
1818 CHECK(mDrmManagerClient);
1819 if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
1820 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
1821 }
1822 }
1823
1824 return setDataSource_l(extractor);
1825}
1826
1827void PreviewPlayerBase::abortPrepare(status_t err) {
1828 CHECK(err != OK);
1829
1830 if (mIsAsyncPrepare) {
1831 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1832 }
1833
1834 mPrepareResult = err;
1835 mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
1836 mAsyncPrepareEvent = NULL;
1837 mPreparedCondition.broadcast();
1838}
1839
1840// static
1841bool PreviewPlayerBase::ContinuePreparation(void *cookie) {
1842 PreviewPlayerBase *me = static_cast<PreviewPlayerBase *>(cookie);
1843
1844 return (me->mFlags & PREPARE_CANCELLED) == 0;
1845}
1846
1847void PreviewPlayerBase::onPrepareAsyncEvent() {
1848 Mutex::Autolock autoLock(mLock);
1849
1850 if (mFlags & PREPARE_CANCELLED) {
1851 LOGI("prepare was cancelled before doing anything");
1852 abortPrepare(UNKNOWN_ERROR);
1853 return;
1854 }
1855
1856 if (mUri.size() > 0) {
1857 status_t err = finishSetDataSource_l();
1858
1859 if (err != OK) {
1860 abortPrepare(err);
1861 return;
1862 }
1863 }
1864
1865 if (mVideoTrack != NULL && mVideoSource == NULL) {
1866 status_t err = initVideoDecoder();
1867
1868 if (err != OK) {
1869 abortPrepare(err);
1870 return;
1871 }
1872 }
1873
1874 if (mAudioTrack != NULL && mAudioSource == NULL) {
1875 status_t err = initAudioDecoder();
1876
1877 if (err != OK) {
1878 abortPrepare(err);
1879 return;
1880 }
1881 }
1882
1883 mFlags |= PREPARING_CONNECTED;
1884
1885 if (mCachedSource != NULL || mRTSPController != NULL) {
1886 postBufferingEvent_l();
1887 } else {
1888 finishAsyncPrepare_l();
1889 }
1890}
1891
1892void PreviewPlayerBase::finishAsyncPrepare_l() {
1893 if (mIsAsyncPrepare) {
1894 if (mVideoSource == NULL) {
1895 notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
1896 } else {
1897 notifyVideoSize_l();
1898 }
1899
1900 notifyListener_l(MEDIA_PREPARED);
1901 }
1902
1903 mPrepareResult = OK;
1904 mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
1905 mFlags |= PREPARED;
1906 mAsyncPrepareEvent = NULL;
1907 mPreparedCondition.broadcast();
1908}
1909
1910uint32_t PreviewPlayerBase::flags() const {
1911 return mExtractorFlags;
1912}
1913
1914void PreviewPlayerBase::postAudioEOS(int64_t delayUs) {
1915 Mutex::Autolock autoLock(mLock);
1916 postCheckAudioStatusEvent_l(delayUs);
1917}
1918
1919void PreviewPlayerBase::postAudioSeekComplete() {
1920 Mutex::Autolock autoLock(mLock);
1921 postCheckAudioStatusEvent_l(0 /* delayUs */);
1922}
1923
1924status_t PreviewPlayerBase::setParameter(int key, const Parcel &request) {
1925 return OK;
1926}
1927
1928status_t PreviewPlayerBase::getParameter(int key, Parcel *reply) {
1929 return OK;
1930}
Chih-Chung Chang7efb8ef2011-07-22 09:01:36 +08001931
1932status_t PreviewPlayerBase::readYV12Buffer(sp<MediaSource> source, MediaBuffer **buffer,
1933 const MediaSource::ReadOptions *options) {
1934 status_t result = source->read(buffer, options);
1935 if (mYV12ColorConverter == NULL || *buffer == NULL) {
1936 return result;
1937 }
1938
1939 int width = mCropRect.right - mCropRect.left + 1;
1940 int height = mCropRect.bottom - mCropRect.top + 1;
1941
1942 MediaBuffer *origBuffer = *buffer;
1943 MediaBuffer *newBuffer = new MediaBuffer(width * height * 3 / 2);
1944
1945 LOGD("convertDecoderOutputToYV12: mGivenWidth = %d, mGivenHeight = %d",
1946 mGivenWidth, mGivenHeight);
1947 LOGD("width = %d, height = %d", width, height);
1948
1949 if (mYV12ColorConverter->convertDecoderOutputToYV12(
1950 (uint8_t *)origBuffer->data(), // ?? + origBuffer->range_offset(), // decoderBits
1951 mGivenWidth, // decoderWidth
1952 mGivenHeight, // decoderHeight
1953 mCropRect, // decoderRect
1954 (uint8_t *)newBuffer->data() + newBuffer->range_offset() /* dstBits */) < 0) {
1955 LOGE("convertDecoderOutputToYV12 failed");
1956 }
1957
1958 // Copy the timestamp
1959 int64_t timeUs;
1960 CHECK(origBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1961 newBuffer->meta_data()->setInt64(kKeyTime, timeUs);
1962
1963 origBuffer->release();
1964 *buffer = newBuffer;
1965
1966 return result;
1967}
1968
1969void PreviewPlayerBase::getVideoBufferSize(sp<MetaData> meta, int* width, int* height) {
1970 if (mYV12ColorConverter) {
1971 int32_t cropLeft, cropTop, cropRight, cropBottom;
1972 if (meta->findRect(
1973 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
1974 *width = cropRight - cropLeft + 1;
1975 *height = cropBottom - cropTop + 1;
1976 } else {
1977 CHECK(meta->findInt32(kKeyWidth, width));
1978 CHECK(meta->findInt32(kKeyHeight, height));
1979 }
1980 } else {
1981 CHECK(meta->findInt32(kKeyWidth, width));
1982 CHECK(meta->findInt32(kKeyHeight, height));
1983 }
1984}
1985
James Dongc9dedc42011-05-01 12:36:22 -07001986} // namespace android