blob: 62b8a72afd5038567f7e974679f5a45ae0302f1e [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
852 int32_t cropLeft, cropTop, cropRight, cropBottom;
853 if (!meta->findRect(
854 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
855 int32_t width, height;
856 CHECK(meta->findInt32(kKeyWidth, &width));
857 CHECK(meta->findInt32(kKeyHeight, &height));
858
859 cropLeft = cropTop = 0;
860 cropRight = width - 1;
861 cropBottom = height - 1;
862
863 LOGV("got dimensions only %d x %d", width, height);
864 } else {
865 LOGV("got crop rect %d, %d, %d, %d",
866 cropLeft, cropTop, cropRight, cropBottom);
867 }
868
869 int32_t displayWidth;
870 if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
871 LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
872 mDisplayWidth = displayWidth;
873 }
874 int32_t displayHeight;
875 if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
876 LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
877 mDisplayHeight = displayHeight;
878 }
879
880 int32_t usableWidth = cropRight - cropLeft + 1;
881 int32_t usableHeight = cropBottom - cropTop + 1;
882 if (mDisplayWidth != 0) {
883 usableWidth = mDisplayWidth;
884 }
885 if (mDisplayHeight != 0) {
886 usableHeight = mDisplayHeight;
887 }
888
889 int32_t rotationDegrees;
890 if (!mVideoTrack->getFormat()->findInt32(
891 kKeyRotation, &rotationDegrees)) {
892 rotationDegrees = 0;
893 }
894
895 if (rotationDegrees == 90 || rotationDegrees == 270) {
896 notifyListener_l(
897 MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
898 } else {
899 notifyListener_l(
900 MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
901 }
902}
903
904void PreviewPlayerBase::initRenderer_l() {
905 if (mNativeWindow == NULL) {
906 return;
907 }
908
909 sp<MetaData> meta = mVideoSource->getFormat();
910
911 int32_t format;
912 const char *component;
913 int32_t decodedWidth, decodedHeight;
914 CHECK(meta->findInt32(kKeyColorFormat, &format));
915 CHECK(meta->findCString(kKeyDecoderComponent, &component));
916 CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
917 CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
918
919 int32_t rotationDegrees;
920 if (!mVideoTrack->getFormat()->findInt32(
921 kKeyRotation, &rotationDegrees)) {
922 rotationDegrees = 0;
923 }
924
925 mVideoRenderer.clear();
926
927 // Must ensure that mVideoRenderer's destructor is actually executed
928 // before creating a new one.
929 IPCThreadState::self()->flushCommands();
930
931 if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) {
932 // Hardware decoders avoid the CPU color conversion by decoding
933 // directly to ANativeBuffers, so we must use a renderer that
934 // just pushes those buffers to the ANativeWindow.
935 mVideoRenderer =
936 new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
937 } else {
938 // Other decoders are instantiated locally and as a consequence
939 // allocate their buffers in local address space. This renderer
940 // then performs a color conversion and copy to get the data
941 // into the ANativeBuffer.
942 mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
943 }
944}
945
946status_t PreviewPlayerBase::pause() {
947 Mutex::Autolock autoLock(mLock);
948
949 mFlags &= ~CACHE_UNDERRUN;
950
951 return pause_l();
952}
953
954status_t PreviewPlayerBase::pause_l(bool at_eos) {
955 if (!(mFlags & PLAYING)) {
956 return OK;
957 }
958
959 cancelPlayerEvents(true /* keepBufferingGoing */);
960
961 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
962 if (at_eos) {
963 // If we played the audio stream to completion we
964 // want to make sure that all samples remaining in the audio
965 // track's queue are played out.
966 mAudioPlayer->pause(true /* playPendingSamples */);
967 } else {
968 mAudioPlayer->pause();
969 }
970
971 mFlags &= ~AUDIO_RUNNING;
972 }
973
974 mFlags &= ~PLAYING;
975
976 if (mDecryptHandle != NULL) {
977 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
978 Playback::PAUSE, 0);
979 }
980
981 uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
982 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
983 params |= IMediaPlayerService::kBatteryDataTrackAudio;
984 }
985 if (mVideoSource != NULL) {
986 params |= IMediaPlayerService::kBatteryDataTrackVideo;
987 }
988
989 addBatteryData(params);
990
991 return OK;
992}
993
994bool PreviewPlayerBase::isPlaying() const {
995 return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
996}
997
998void PreviewPlayerBase::setSurface(const sp<Surface> &surface) {
999 Mutex::Autolock autoLock(mLock);
1000
1001 mSurface = surface;
1002 setNativeWindow_l(surface);
1003}
1004
1005void PreviewPlayerBase::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1006 Mutex::Autolock autoLock(mLock);
1007
1008 mSurface.clear();
1009 if (surfaceTexture != NULL) {
1010 setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
1011 }
1012}
1013
1014void PreviewPlayerBase::shutdownVideoDecoder_l() {
1015 if (mVideoBuffer) {
1016 mVideoBuffer->release();
1017 mVideoBuffer = NULL;
1018 }
1019
1020 mVideoSource->stop();
1021
1022 // The following hack is necessary to ensure that the OMX
1023 // component is completely released by the time we may try
1024 // to instantiate it again.
1025 wp<MediaSource> tmp = mVideoSource;
1026 mVideoSource.clear();
1027 while (tmp.promote() != NULL) {
1028 usleep(1000);
1029 }
1030 IPCThreadState::self()->flushCommands();
1031}
1032
1033void PreviewPlayerBase::setNativeWindow_l(const sp<ANativeWindow> &native) {
1034 mNativeWindow = native;
1035
1036 if (mVideoSource == NULL) {
1037 return;
1038 }
1039
1040 LOGI("attempting to reconfigure to use new surface");
1041
1042 bool wasPlaying = (mFlags & PLAYING) != 0;
1043
1044 pause_l();
1045 mVideoRenderer.clear();
1046
1047 shutdownVideoDecoder_l();
1048
1049 CHECK_EQ(initVideoDecoder(), (status_t)OK);
1050
1051 if (mLastVideoTimeUs >= 0) {
1052 mSeeking = SEEK;
1053 mSeekNotificationSent = true;
1054 mSeekTimeUs = mLastVideoTimeUs;
1055 mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
1056 }
1057
1058 if (wasPlaying) {
1059 play_l();
1060 }
1061}
1062
1063void PreviewPlayerBase::setAudioSink(
1064 const sp<MediaPlayerBase::AudioSink> &audioSink) {
1065 Mutex::Autolock autoLock(mLock);
1066
1067 mAudioSink = audioSink;
1068}
1069
1070status_t PreviewPlayerBase::setLooping(bool shouldLoop) {
1071 Mutex::Autolock autoLock(mLock);
1072
1073 mFlags = mFlags & ~LOOPING;
1074
1075 if (shouldLoop) {
1076 mFlags |= LOOPING;
1077 }
1078
1079 return OK;
1080}
1081
1082status_t PreviewPlayerBase::getDuration(int64_t *durationUs) {
1083 Mutex::Autolock autoLock(mMiscStateLock);
1084
1085 if (mDurationUs < 0) {
1086 return UNKNOWN_ERROR;
1087 }
1088
1089 *durationUs = mDurationUs;
1090
1091 return OK;
1092}
1093
1094status_t PreviewPlayerBase::getPosition(int64_t *positionUs) {
1095 if (mRTSPController != NULL) {
1096 *positionUs = mRTSPController->getNormalPlayTimeUs();
1097 }
1098 else if (mSeeking != NO_SEEK) {
1099 *positionUs = mSeekTimeUs;
1100 } else if (mVideoSource != NULL
1101 && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
1102 Mutex::Autolock autoLock(mMiscStateLock);
1103 *positionUs = mVideoTimeUs;
1104 } else if (mAudioPlayer != NULL) {
1105 *positionUs = mAudioPlayer->getMediaTimeUs();
1106 } else {
1107 *positionUs = 0;
1108 }
1109
1110 return OK;
1111}
1112
1113status_t PreviewPlayerBase::seekTo(int64_t timeUs) {
1114 if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
1115 Mutex::Autolock autoLock(mLock);
1116 return seekTo_l(timeUs);
1117 }
1118
1119 return OK;
1120}
1121
1122// static
1123void PreviewPlayerBase::OnRTSPSeekDoneWrapper(void *cookie) {
1124 static_cast<PreviewPlayerBase *>(cookie)->onRTSPSeekDone();
1125}
1126
1127void PreviewPlayerBase::onRTSPSeekDone() {
1128 notifyListener_l(MEDIA_SEEK_COMPLETE);
1129 mSeekNotificationSent = true;
1130}
1131
1132status_t PreviewPlayerBase::seekTo_l(int64_t timeUs) {
1133 if (mRTSPController != NULL) {
1134 mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this);
1135 return OK;
1136 }
1137
1138 if (mFlags & CACHE_UNDERRUN) {
1139 mFlags &= ~CACHE_UNDERRUN;
1140 play_l();
1141 }
1142
1143 if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
1144 // Video playback completed before, there's no pending
1145 // video event right now. In order for this new seek
1146 // to be honored, we need to post one.
1147
1148 postVideoEvent_l();
1149 }
1150
1151 mSeeking = SEEK;
1152 mSeekNotificationSent = false;
1153 mSeekTimeUs = timeUs;
1154 mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
1155
1156 seekAudioIfNecessary_l();
1157
1158 if (!(mFlags & PLAYING)) {
1159 LOGV("seeking while paused, sending SEEK_COMPLETE notification"
1160 " immediately.");
1161
1162 notifyListener_l(MEDIA_SEEK_COMPLETE);
1163 mSeekNotificationSent = true;
1164
1165 if ((mFlags & PREPARED) && mVideoSource != NULL) {
1166 mFlags |= SEEK_PREVIEW;
1167 postVideoEvent_l();
1168 }
1169 }
1170
1171 return OK;
1172}
1173
1174void PreviewPlayerBase::seekAudioIfNecessary_l() {
1175 if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
1176 mAudioPlayer->seekTo(mSeekTimeUs);
1177
1178 mWatchForAudioSeekComplete = true;
1179 mWatchForAudioEOS = true;
1180
1181 if (mDecryptHandle != NULL) {
1182 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1183 Playback::PAUSE, 0);
1184 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1185 Playback::START, mSeekTimeUs / 1000);
1186 }
1187 }
1188}
1189
1190void PreviewPlayerBase::setAudioSource(sp<MediaSource> source) {
1191 CHECK(source != NULL);
1192
1193 mAudioTrack = source;
1194}
1195
1196status_t PreviewPlayerBase::initAudioDecoder() {
1197 sp<MetaData> meta = mAudioTrack->getFormat();
1198
1199 const char *mime;
1200 CHECK(meta->findCString(kKeyMIMEType, &mime));
1201
1202 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1203 mAudioSource = mAudioTrack;
1204 } else {
1205 mAudioSource = OMXCodec::Create(
1206 mClient.interface(), mAudioTrack->getFormat(),
1207 false, // createEncoder
1208 mAudioTrack);
1209 }
1210
1211 if (mAudioSource != NULL) {
1212 int64_t durationUs;
1213 if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1214 Mutex::Autolock autoLock(mMiscStateLock);
1215 if (mDurationUs < 0 || durationUs > mDurationUs) {
1216 mDurationUs = durationUs;
1217 }
1218 }
1219
1220 status_t err = mAudioSource->start();
1221
1222 if (err != OK) {
1223 mAudioSource.clear();
1224 return err;
1225 }
1226 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
1227 // For legacy reasons we're simply going to ignore the absence
1228 // of an audio decoder for QCELP instead of aborting playback
1229 // altogether.
1230 return OK;
1231 }
1232
1233 return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
1234}
1235
1236void PreviewPlayerBase::setVideoSource(sp<MediaSource> source) {
1237 CHECK(source != NULL);
1238
1239 mVideoTrack = source;
1240}
1241
1242status_t PreviewPlayerBase::initVideoDecoder(uint32_t flags) {
1243
1244 // Either the application or the DRM system can independently say
1245 // that there must be a hardware-protected path to an external video sink.
1246 // For now we always require a hardware-protected path to external video sink
1247 // if content is DRMed, but eventually this could be optional per DRM agent.
1248 // When the application wants protection, then
1249 // (USE_SURFACE_ALLOC && (mSurface != 0) &&
1250 // (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
1251 // will be true, but that part is already handled by SurfaceFlinger.
1252
1253#ifdef DEBUG_HDCP
1254 // For debugging, we allow a system property to control the protected usage.
1255 // In case of uninitialized or unexpected property, we default to "DRM only".
1256 bool setProtectionBit = false;
1257 char value[PROPERTY_VALUE_MAX];
1258 if (property_get("persist.sys.hdcp_checking", value, NULL)) {
1259 if (!strcmp(value, "never")) {
1260 // nop
1261 } else if (!strcmp(value, "always")) {
1262 setProtectionBit = true;
1263 } else if (!strcmp(value, "drm-only")) {
1264 if (mDecryptHandle != NULL) {
1265 setProtectionBit = true;
1266 }
1267 // property value is empty, or unexpected value
1268 } else {
1269 if (mDecryptHandle != NULL) {
1270 setProtectionBit = true;
1271 }
1272 }
1273 // can' read property value
1274 } else {
1275 if (mDecryptHandle != NULL) {
1276 setProtectionBit = true;
1277 }
1278 }
1279 // note that usage bit is already cleared, so no need to clear it in the "else" case
1280 if (setProtectionBit) {
1281 flags |= OMXCodec::kEnableGrallocUsageProtected;
1282 }
1283#else
1284 if (mDecryptHandle != NULL) {
1285 flags |= OMXCodec::kEnableGrallocUsageProtected;
1286 }
1287#endif
1288 LOGV("initVideoDecoder flags=0x%x", flags);
1289 mVideoSource = OMXCodec::Create(
1290 mClient.interface(), mVideoTrack->getFormat(),
1291 false, // createEncoder
1292 mVideoTrack,
1293 NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
1294
1295 if (mVideoSource != NULL) {
1296 int64_t durationUs;
1297 if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1298 Mutex::Autolock autoLock(mMiscStateLock);
1299 if (mDurationUs < 0 || durationUs > mDurationUs) {
1300 mDurationUs = durationUs;
1301 }
1302 }
1303
1304 status_t err = mVideoSource->start();
1305
1306 if (err != OK) {
1307 mVideoSource.clear();
1308 return err;
1309 }
1310 }
1311
1312 return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
1313}
1314
1315void PreviewPlayerBase::finishSeekIfNecessary(int64_t videoTimeUs) {
1316 if (mSeeking == SEEK_VIDEO_ONLY) {
1317 mSeeking = NO_SEEK;
1318 return;
1319 }
1320
1321 if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
1322 return;
1323 }
1324
1325 if (mAudioPlayer != NULL) {
1326 LOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
1327
1328 // If we don't have a video time, seek audio to the originally
1329 // requested seek time instead.
1330
1331 mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
1332 mWatchForAudioSeekComplete = true;
1333 mWatchForAudioEOS = true;
1334 } else if (!mSeekNotificationSent) {
1335 // If we're playing video only, report seek complete now,
1336 // otherwise audio player will notify us later.
1337 notifyListener_l(MEDIA_SEEK_COMPLETE);
1338 mSeekNotificationSent = true;
1339 }
1340
1341 mFlags |= FIRST_FRAME;
1342 mSeeking = NO_SEEK;
1343
1344 if (mDecryptHandle != NULL) {
1345 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1346 Playback::PAUSE, 0);
1347 mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1348 Playback::START, videoTimeUs / 1000);
1349 }
1350}
1351
1352void PreviewPlayerBase::onVideoEvent() {
1353 Mutex::Autolock autoLock(mLock);
1354 if (!mVideoEventPending) {
1355 // The event has been cancelled in reset_l() but had already
1356 // been scheduled for execution at that time.
1357 return;
1358 }
1359 mVideoEventPending = false;
1360
1361 if (mSeeking != NO_SEEK) {
1362 if (mVideoBuffer) {
1363 mVideoBuffer->release();
1364 mVideoBuffer = NULL;
1365 }
1366
1367 if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
1368 && !(mFlags & SEEK_PREVIEW)) {
1369 // We're going to seek the video source first, followed by
1370 // the audio source.
1371 // In order to avoid jumps in the DataSource offset caused by
1372 // the audio codec prefetching data from the old locations
1373 // while the video codec is already reading data from the new
1374 // locations, we'll "pause" the audio source, causing it to
1375 // stop reading input data until a subsequent seek.
1376
1377 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1378 mAudioPlayer->pause();
1379
1380 mFlags &= ~AUDIO_RUNNING;
1381 }
1382 mAudioSource->pause();
1383 }
1384 }
1385
1386 if (!mVideoBuffer) {
1387 MediaSource::ReadOptions options;
1388 if (mSeeking != NO_SEEK) {
1389 LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
1390
1391 options.setSeekTo(
1392 mSeekTimeUs,
1393 mSeeking == SEEK_VIDEO_ONLY
1394 ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
1395 : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
1396 }
1397 for (;;) {
1398 status_t err = mVideoSource->read(&mVideoBuffer, &options);
1399 options.clearSeekTo();
1400
1401 if (err != OK) {
1402 CHECK(mVideoBuffer == NULL);
1403
1404 if (err == INFO_FORMAT_CHANGED) {
1405 LOGV("VideoSource signalled format change.");
1406
1407 notifyVideoSize_l();
1408
1409 if (mVideoRenderer != NULL) {
1410 mVideoRendererIsPreview = false;
1411 initRenderer_l();
1412 }
1413 continue;
1414 }
1415
1416 // So video playback is complete, but we may still have
1417 // a seek request pending that needs to be applied
1418 // to the audio track.
1419 if (mSeeking != NO_SEEK) {
1420 LOGV("video stream ended while seeking!");
1421 }
1422 finishSeekIfNecessary(-1);
1423
1424 if (mAudioPlayer != NULL
1425 && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1426 startAudioPlayer_l();
1427 }
1428
1429 mFlags |= VIDEO_AT_EOS;
1430 postStreamDoneEvent_l(err);
1431 return;
1432 }
1433
1434 if (mVideoBuffer->range_length() == 0) {
1435 // Some decoders, notably the PV AVC software decoder
1436 // return spurious empty buffers that we just want to ignore.
1437
1438 mVideoBuffer->release();
1439 mVideoBuffer = NULL;
1440 continue;
1441 }
1442
1443 break;
1444 }
1445 }
1446
1447 int64_t timeUs;
1448 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1449
1450 mLastVideoTimeUs = timeUs;
1451
1452 if (mSeeking == SEEK_VIDEO_ONLY) {
1453 if (mSeekTimeUs > timeUs) {
1454 LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
1455 mSeekTimeUs, timeUs);
1456 }
1457 }
1458
1459 {
1460 Mutex::Autolock autoLock(mMiscStateLock);
1461 mVideoTimeUs = timeUs;
1462 }
1463
1464 SeekType wasSeeking = mSeeking;
1465 finishSeekIfNecessary(timeUs);
1466
1467 if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1468 status_t err = startAudioPlayer_l();
1469 if (err != OK) {
1470 LOGE("Startung the audio player failed w/ err %d", err);
1471 return;
1472 }
1473 }
1474
1475 TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
1476
1477 if (mFlags & FIRST_FRAME) {
1478 mFlags &= ~FIRST_FRAME;
1479 mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
1480 }
1481
1482 int64_t realTimeUs, mediaTimeUs;
1483 if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
1484 && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
1485 mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
1486 }
1487
1488 if (wasSeeking == SEEK_VIDEO_ONLY) {
1489 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1490
1491 int64_t latenessUs = nowUs - timeUs;
1492
1493 if (latenessUs > 0) {
1494 LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
1495 }
1496 }
1497
1498 if (wasSeeking == NO_SEEK) {
1499 // Let's display the first frame after seeking right away.
1500
1501 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1502
1503 int64_t latenessUs = nowUs - timeUs;
1504
1505 if (latenessUs > 500000ll
1506 && mRTSPController == NULL
1507 && mAudioPlayer != NULL
1508 && mAudioPlayer->getMediaTimeMapping(
1509 &realTimeUs, &mediaTimeUs)) {
1510 LOGI("we're much too late (%.2f secs), video skipping ahead",
1511 latenessUs / 1E6);
1512
1513 mVideoBuffer->release();
1514 mVideoBuffer = NULL;
1515
1516 mSeeking = SEEK_VIDEO_ONLY;
1517 mSeekTimeUs = mediaTimeUs;
1518
1519 postVideoEvent_l();
1520 return;
1521 }
1522
1523 if (latenessUs > 40000) {
1524 // We're more than 40ms late.
1525 LOGV("we're late by %lld us (%.2f secs), dropping frame",
1526 latenessUs, latenessUs / 1E6);
1527 mVideoBuffer->release();
1528 mVideoBuffer = NULL;
1529
1530 postVideoEvent_l();
1531 return;
1532 }
1533
1534 if (latenessUs < -10000) {
1535 // We're more than 10ms early.
1536
1537 postVideoEvent_l(10000);
1538 return;
1539 }
1540 }
1541
1542 if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
1543 mVideoRendererIsPreview = false;
1544
1545 initRenderer_l();
1546 }
1547
1548 if (mVideoRenderer != NULL) {
1549 mVideoRenderer->render(mVideoBuffer);
1550 }
1551
1552 mVideoBuffer->release();
1553 mVideoBuffer = NULL;
1554
1555 if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
1556 mFlags &= ~SEEK_PREVIEW;
1557 return;
1558 }
1559
1560 postVideoEvent_l();
1561}
1562
1563void PreviewPlayerBase::postVideoEvent_l(int64_t delayUs) {
1564 if (mVideoEventPending) {
1565 return;
1566 }
1567
1568 mVideoEventPending = true;
1569 mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
1570}
1571
1572void PreviewPlayerBase::postStreamDoneEvent_l(status_t status) {
1573 if (mStreamDoneEventPending) {
1574 return;
1575 }
1576 mStreamDoneEventPending = true;
1577
1578 mStreamDoneStatus = status;
1579 mQueue.postEvent(mStreamDoneEvent);
1580}
1581
1582void PreviewPlayerBase::postBufferingEvent_l() {
1583 if (mBufferingEventPending) {
1584 return;
1585 }
1586 mBufferingEventPending = true;
1587 mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
1588}
1589
1590void PreviewPlayerBase::postVideoLagEvent_l() {
1591 if (mVideoLagEventPending) {
1592 return;
1593 }
1594 mVideoLagEventPending = true;
1595 mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
1596}
1597
1598void PreviewPlayerBase::postCheckAudioStatusEvent_l(int64_t delayUs) {
1599 if (mAudioStatusEventPending) {
1600 return;
1601 }
1602 mAudioStatusEventPending = true;
1603 mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
1604}
1605
1606void PreviewPlayerBase::onCheckAudioStatus() {
1607 Mutex::Autolock autoLock(mLock);
1608 if (!mAudioStatusEventPending) {
1609 // Event was dispatched and while we were blocking on the mutex,
1610 // has already been cancelled.
1611 return;
1612 }
1613
1614 mAudioStatusEventPending = false;
1615
1616 if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
1617 mWatchForAudioSeekComplete = false;
1618
1619 if (!mSeekNotificationSent) {
1620 notifyListener_l(MEDIA_SEEK_COMPLETE);
1621 mSeekNotificationSent = true;
1622 }
1623
1624 mSeeking = NO_SEEK;
1625 }
1626
1627 status_t finalStatus;
1628 if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
1629 mWatchForAudioEOS = false;
1630 mFlags |= AUDIO_AT_EOS;
1631 mFlags |= FIRST_FRAME;
1632 postStreamDoneEvent_l(finalStatus);
1633 }
1634}
1635
1636status_t PreviewPlayerBase::prepare() {
1637 Mutex::Autolock autoLock(mLock);
1638 return prepare_l();
1639}
1640
1641status_t PreviewPlayerBase::prepare_l() {
1642 if (mFlags & PREPARED) {
1643 return OK;
1644 }
1645
1646 if (mFlags & PREPARING) {
1647 return UNKNOWN_ERROR;
1648 }
1649
1650 mIsAsyncPrepare = false;
1651 status_t err = prepareAsync_l();
1652
1653 if (err != OK) {
1654 return err;
1655 }
1656
1657 while (mFlags & PREPARING) {
1658 mPreparedCondition.wait(mLock);
1659 }
1660
1661 return mPrepareResult;
1662}
1663
1664status_t PreviewPlayerBase::prepareAsync() {
1665 Mutex::Autolock autoLock(mLock);
1666
1667 if (mFlags & PREPARING) {
1668 return UNKNOWN_ERROR; // async prepare already pending
1669 }
1670
1671 mIsAsyncPrepare = true;
1672 return prepareAsync_l();
1673}
1674
1675status_t PreviewPlayerBase::prepareAsync_l() {
1676 if (mFlags & PREPARING) {
1677 return UNKNOWN_ERROR; // async prepare already pending
1678 }
1679
1680 if (!mQueueStarted) {
1681 mQueue.start();
1682 mQueueStarted = true;
1683 }
1684
1685 mFlags |= PREPARING;
1686 mAsyncPrepareEvent = new AwesomeEvent(
1687 this, &PreviewPlayerBase::onPrepareAsyncEvent);
1688
1689 mQueue.postEvent(mAsyncPrepareEvent);
1690
1691 return OK;
1692}
1693
1694status_t PreviewPlayerBase::finishSetDataSource_l() {
1695 sp<DataSource> dataSource;
1696
1697 if (!strncasecmp("http://", mUri.string(), 7)
1698 || !strncasecmp("https://", mUri.string(), 8)) {
1699 mConnectingDataSource = HTTPBase::Create(
1700 (mFlags & INCOGNITO)
1701 ? HTTPBase::kFlagIncognito
1702 : 0);
1703
1704 mLock.unlock();
1705 status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
1706 mLock.lock();
1707
1708 if (err != OK) {
1709 mConnectingDataSource.clear();
1710
1711 LOGI("mConnectingDataSource->connect() returned %d", err);
1712 return err;
1713 }
1714
1715#if 0
1716 mCachedSource = new NuCachedSource2(
1717 new ThrottledSource(
1718 mConnectingDataSource, 50 * 1024 /* bytes/sec */));
1719#else
1720 mCachedSource = new NuCachedSource2(mConnectingDataSource);
1721#endif
1722 mConnectingDataSource.clear();
1723
1724 dataSource = mCachedSource;
1725
1726 String8 contentType = dataSource->getMIMEType();
1727
1728 if (strncasecmp(contentType.string(), "audio/", 6)) {
1729 // We're not doing this for streams that appear to be audio-only
1730 // streams to ensure that even low bandwidth streams start
1731 // playing back fairly instantly.
1732
1733 // We're going to prefill the cache before trying to instantiate
1734 // the extractor below, as the latter is an operation that otherwise
1735 // could block on the datasource for a significant amount of time.
1736 // During that time we'd be unable to abort the preparation phase
1737 // without this prefill.
1738
1739 mLock.unlock();
1740
1741 for (;;) {
1742 status_t finalStatus;
1743 size_t cachedDataRemaining =
1744 mCachedSource->approxDataRemaining(&finalStatus);
1745
1746 if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
1747 || (mFlags & PREPARE_CANCELLED)) {
1748 break;
1749 }
1750
1751 usleep(200000);
1752 }
1753
1754 mLock.lock();
1755 }
1756
1757 if (mFlags & PREPARE_CANCELLED) {
1758 LOGI("Prepare cancelled while waiting for initial cache fill.");
1759 return UNKNOWN_ERROR;
1760 }
1761 } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
1762 if (mLooper == NULL) {
1763 mLooper = new ALooper;
1764 mLooper->setName("rtsp");
1765 mLooper->start();
1766 }
1767 mRTSPController = new ARTSPController(mLooper);
1768 mConnectingRTSPController = mRTSPController;
1769
1770 mLock.unlock();
1771 status_t err = mRTSPController->connect(mUri.string());
1772 mLock.lock();
1773
1774 mConnectingRTSPController.clear();
1775
1776 LOGI("ARTSPController::connect returned %d", err);
1777
1778 if (err != OK) {
1779 mRTSPController.clear();
1780 return err;
1781 }
1782
1783 sp<MediaExtractor> extractor = mRTSPController.get();
1784 return setDataSource_l(extractor);
1785 } else {
1786 dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
1787 }
1788
1789 if (dataSource == NULL) {
1790 return UNKNOWN_ERROR;
1791 }
1792
1793 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
1794
1795 if (extractor == NULL) {
1796 return UNKNOWN_ERROR;
1797 }
1798
1799 dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
1800
1801 if (mDecryptHandle != NULL) {
1802 CHECK(mDrmManagerClient);
1803 if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
1804 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
1805 }
1806 }
1807
1808 return setDataSource_l(extractor);
1809}
1810
1811void PreviewPlayerBase::abortPrepare(status_t err) {
1812 CHECK(err != OK);
1813
1814 if (mIsAsyncPrepare) {
1815 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1816 }
1817
1818 mPrepareResult = err;
1819 mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
1820 mAsyncPrepareEvent = NULL;
1821 mPreparedCondition.broadcast();
1822}
1823
1824// static
1825bool PreviewPlayerBase::ContinuePreparation(void *cookie) {
1826 PreviewPlayerBase *me = static_cast<PreviewPlayerBase *>(cookie);
1827
1828 return (me->mFlags & PREPARE_CANCELLED) == 0;
1829}
1830
1831void PreviewPlayerBase::onPrepareAsyncEvent() {
1832 Mutex::Autolock autoLock(mLock);
1833
1834 if (mFlags & PREPARE_CANCELLED) {
1835 LOGI("prepare was cancelled before doing anything");
1836 abortPrepare(UNKNOWN_ERROR);
1837 return;
1838 }
1839
1840 if (mUri.size() > 0) {
1841 status_t err = finishSetDataSource_l();
1842
1843 if (err != OK) {
1844 abortPrepare(err);
1845 return;
1846 }
1847 }
1848
1849 if (mVideoTrack != NULL && mVideoSource == NULL) {
1850 status_t err = initVideoDecoder();
1851
1852 if (err != OK) {
1853 abortPrepare(err);
1854 return;
1855 }
1856 }
1857
1858 if (mAudioTrack != NULL && mAudioSource == NULL) {
1859 status_t err = initAudioDecoder();
1860
1861 if (err != OK) {
1862 abortPrepare(err);
1863 return;
1864 }
1865 }
1866
1867 mFlags |= PREPARING_CONNECTED;
1868
1869 if (mCachedSource != NULL || mRTSPController != NULL) {
1870 postBufferingEvent_l();
1871 } else {
1872 finishAsyncPrepare_l();
1873 }
1874}
1875
1876void PreviewPlayerBase::finishAsyncPrepare_l() {
1877 if (mIsAsyncPrepare) {
1878 if (mVideoSource == NULL) {
1879 notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
1880 } else {
1881 notifyVideoSize_l();
1882 }
1883
1884 notifyListener_l(MEDIA_PREPARED);
1885 }
1886
1887 mPrepareResult = OK;
1888 mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
1889 mFlags |= PREPARED;
1890 mAsyncPrepareEvent = NULL;
1891 mPreparedCondition.broadcast();
1892}
1893
1894uint32_t PreviewPlayerBase::flags() const {
1895 return mExtractorFlags;
1896}
1897
1898void PreviewPlayerBase::postAudioEOS(int64_t delayUs) {
1899 Mutex::Autolock autoLock(mLock);
1900 postCheckAudioStatusEvent_l(delayUs);
1901}
1902
1903void PreviewPlayerBase::postAudioSeekComplete() {
1904 Mutex::Autolock autoLock(mLock);
1905 postCheckAudioStatusEvent_l(0 /* delayUs */);
1906}
1907
1908status_t PreviewPlayerBase::setParameter(int key, const Parcel &request) {
1909 return OK;
1910}
1911
1912status_t PreviewPlayerBase::getParameter(int key, Parcel *reply) {
1913 return OK;
1914}
1915} // namespace android