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