summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libmediaplayerservice/StagefrightPlayer.cpp23
-rw-r--r--media/libstagefright/AwesomePlayer.cpp98
-rw-r--r--media/libstagefright/Prefetcher.cpp27
-rw-r--r--media/libstagefright/include/AwesomePlayer.h12
-rw-r--r--media/libstagefright/include/Prefetcher.h4
5 files changed, 108 insertions, 56 deletions
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index f42d55b..1bfcf65 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -49,30 +49,11 @@ status_t StagefrightPlayer::setVideoSurface(const sp<ISurface> &surface) {
}
status_t StagefrightPlayer::prepare() {
- LOGV("prepare");
-
- int32_t width, height;
- if (mPlayer->getVideoDimensions(&width, &height) != OK) {
- width = height = 0;
- }
-
- sendEvent(MEDIA_SET_VIDEO_SIZE, width, height);
-
- return OK;
+ return mPlayer->prepare();
}
status_t StagefrightPlayer::prepareAsync() {
- LOGV("prepareAsync");
-
- status_t err = prepare();
-
- if (err != OK) {
- return err;
- }
-
- sendEvent(MEDIA_PREPARED);
-
- return OK;
+ return mPlayer->prepareAsync();
}
status_t StagefrightPlayer::start() {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 2b403f8..d25f7f6 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -37,21 +37,23 @@
namespace android {
struct AwesomeEvent : public TimedEventQueue::Event {
- AwesomeEvent(AwesomePlayer *player, int32_t code)
+ AwesomeEvent(
+ AwesomePlayer *player,
+ void (AwesomePlayer::*method)())
: mPlayer(player),
- mCode(code) {
+ mMethod(method) {
}
protected:
virtual ~AwesomeEvent() {}
virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
- mPlayer->onEvent(mCode);
+ (mPlayer->*mMethod)();
}
private:
AwesomePlayer *mPlayer;
- int32_t mCode;
+ void (AwesomePlayer::*mMethod)();
AwesomeEvent(const AwesomeEvent &);
AwesomeEvent &operator=(const AwesomeEvent &);
@@ -115,13 +117,16 @@ AwesomePlayer::AwesomePlayer()
DataSource::RegisterDefaultSniffers();
- mVideoEvent = new AwesomeEvent(this, 0);
+ mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
mVideoEventPending = false;
- mStreamDoneEvent = new AwesomeEvent(this, 1);
+ mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
mStreamDoneEventPending = false;
- mBufferingEvent = new AwesomeEvent(this, 2);
+ mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
mBufferingEventPending = false;
- mCheckAudioStatusEvent = new AwesomeEvent(this, 3);
+
+ mCheckAudioStatusEvent = new AwesomeEvent(
+ this, &AwesomePlayer::onCheckAudioStatus);
+
mAudioStatusEventPending = false;
mQueue.start();
@@ -287,12 +292,12 @@ void AwesomePlayer::reset_l() {
mPrefetcher.clear();
}
-void AwesomePlayer::notifyListener_l(int msg, int ext1) {
+void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
if (mListener != NULL) {
sp<MediaPlayerBase> listener = mListener.promote();
if (listener != NULL) {
- listener->sendEvent(msg, ext1);
+ listener->sendEvent(msg, ext1, ext2);
}
}
}
@@ -623,18 +628,7 @@ status_t AwesomePlayer::setVideoSource(sp<MediaSource> source) {
return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
}
-void AwesomePlayer::onEvent(int32_t code) {
- if (code == 1) {
- onStreamDone();
- return;
- } else if (code == 2) {
- onBufferingUpdate();
- return;
- } else if (code == 3) {
- onCheckAudioStatus();
- return;
- }
-
+void AwesomePlayer::onVideoEvent() {
Mutex::Autolock autoLock(mLock);
mVideoEventPending = false;
@@ -819,5 +813,65 @@ void AwesomePlayer::onCheckAudioStatus() {
postCheckAudioStatusEvent_l();
}
+status_t AwesomePlayer::prepare() {
+ Mutex::Autolock autoLock(mLock);
+
+ status_t err = prepareAsync_l();
+
+ if (err != OK) {
+ return err;
+ }
+
+ while (mAsyncPrepareEvent != NULL) {
+ mPreparedCondition.wait(mLock);
+ }
+
+ return OK;
+}
+
+status_t AwesomePlayer::prepareAsync() {
+ Mutex::Autolock autoLock(mLock);
+ return prepareAsync_l();
+}
+
+status_t AwesomePlayer::prepareAsync_l() {
+ if (mAsyncPrepareEvent != NULL) {
+ return UNKNOWN_ERROR; // async prepare already pending.
+ }
+
+ mAsyncPrepareEvent = new AwesomeEvent(
+ this, &AwesomePlayer::onPrepareAsyncEvent);
+
+ mQueue.postEvent(mAsyncPrepareEvent);
+
+ return OK;
+}
+
+void AwesomePlayer::onPrepareAsyncEvent() {
+ sp<Prefetcher> prefetcher;
+
+ {
+ Mutex::Autolock autoLock(mLock);
+ prefetcher = mPrefetcher;
+ }
+
+ if (prefetcher != NULL) {
+ prefetcher->prepare();
+ }
+
+ Mutex::Autolock autoLock(mLock);
+
+ if (mVideoWidth < 0 || mVideoHeight < 0) {
+ notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
+ } else {
+ notifyListener_l(MEDIA_SET_VIDEO_SIZE, mVideoWidth, mVideoHeight);
+ }
+
+ notifyListener_l(MEDIA_PREPARED);
+
+ mAsyncPrepareEvent = NULL;
+ mPreparedCondition.signal();
+}
+
} // namespace android
diff --git a/media/libstagefright/Prefetcher.cpp b/media/libstagefright/Prefetcher.cpp
index 862998a..835e167 100644
--- a/media/libstagefright/Prefetcher.cpp
+++ b/media/libstagefright/Prefetcher.cpp
@@ -171,7 +171,7 @@ void Prefetcher::threadFunc() {
}
}
-int64_t Prefetcher::getCachedDurationUs() {
+int64_t Prefetcher::getCachedDurationUs(bool *noMoreData) {
Mutex::Autolock autoLock(mLock);
int64_t minCacheDurationUs = -1;
@@ -197,9 +197,25 @@ int64_t Prefetcher::getCachedDurationUs() {
}
}
+ if (noMoreData) {
+ *noMoreData = minCacheDurationUs < 0;
+ }
+
return minCacheDurationUs < 0 ? 0 : minCacheDurationUs;
}
+status_t Prefetcher::prepare() {
+ // Buffer about 2 secs worth of data on prepare.
+
+ int64_t duration;
+ bool noMoreData;
+ do {
+ duration = getCachedDurationUs(&noMoreData);
+ } while (!noMoreData && duration < 2000000);
+
+ return OK;
+}
+
////////////////////////////////////////////////////////////////////////////////
PrefetchedSource::PrefetchedSource(
@@ -232,15 +248,6 @@ status_t PrefetchedSource::start(MetaData *params) {
mStarted = true;
- for (;;) {
- // Buffer 2 secs on startup.
- if (mReachedEOS || mCacheDurationUs > 2000000) {
- break;
- }
-
- mCondition.wait(mLock);
- }
-
return OK;
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 75e71e6..651b910 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -57,6 +57,10 @@ struct AwesomePlayer {
void reset();
+ status_t prepare();
+ status_t prepareAsync();
+ status_t prepareAsync_l();
+
status_t play();
status_t pause();
@@ -121,6 +125,9 @@ private:
sp<TimedEventQueue::Event> mCheckAudioStatusEvent;
bool mAudioStatusEventPending;
+ sp<TimedEventQueue::Event> mAsyncPrepareEvent;
+ Condition mPreparedCondition;
+
void postVideoEvent_l(int64_t delayUs = -1);
void postBufferingEvent_l();
void postStreamDoneEvent_l();
@@ -143,13 +150,14 @@ private:
status_t setAudioSource(sp<MediaSource> source);
status_t setVideoSource(sp<MediaSource> source);
- void onEvent(int32_t code);
void onStreamDone();
- void notifyListener_l(int msg, int ext1 = 0);
+ void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0);
+ void onVideoEvent();
void onBufferingUpdate();
void onCheckAudioStatus();
+ void onPrepareAsyncEvent();
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
diff --git a/media/libstagefright/include/Prefetcher.h b/media/libstagefright/include/Prefetcher.h
index 7a97785..d227864 100644
--- a/media/libstagefright/include/Prefetcher.h
+++ b/media/libstagefright/include/Prefetcher.h
@@ -34,7 +34,9 @@ struct Prefetcher : public RefBase {
// that will benefit from prefetching/caching the original one.
sp<MediaSource> addSource(const sp<MediaSource> &source);
- int64_t getCachedDurationUs();
+ int64_t getCachedDurationUs(bool *noMoreData = NULL);
+
+ status_t prepare();
protected:
virtual ~Prefetcher();