summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorInsun Kang <insun@google.com>2012-06-18 16:51:48 +0900
committerInsun Kang <insun@google.com>2012-08-02 11:56:07 +0900
commit6472badc497a9e748411f8c8c9ed5d83ef335a85 (patch)
tree682bc926abcc04dff0783b1fa4ecb379d2908cb5 /media/libstagefright
parentbb6bc8491fe819f96e1902e56694715cb110ce94 (diff)
downloadframeworks_av-6472badc497a9e748411f8c8c9ed5d83ef335a85.zip
frameworks_av-6472badc497a9e748411f8c8c9ed5d83ef335a85.tar.gz
frameworks_av-6472badc497a9e748411f8c8c9ed5d83ef335a85.tar.bz2
Fix: status checking in TimedTextDriver.
o fixes seeking error when there's no enabled text track. o clean up status checking code for deselectTrack. o fixes a potential bug : pause->backward seek can trigger unwanted resume. Bug: 6682160 Change-Id: I03d8788b27fb9c0a6092be83ad3578ccf3266905 (cherry picked from commit 2dafb6071d4f14e0e208912500694912211aa26b)
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/timedtext/TimedTextDriver.cpp36
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.cpp75
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.h5
3 files changed, 84 insertions, 32 deletions
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
index 1a0dc7b..71da803 100644
--- a/media/libstagefright/timedtext/TimedTextDriver.cpp
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -145,21 +145,41 @@ status_t TimedTextDriver::selectTrack(size_t index) {
}
status_t TimedTextDriver::unselectTrack(size_t index) {
+ Mutex::Autolock autoLock(mLock);
if (mCurrentTrackIndex != index) {
return INVALID_OPERATION;
}
- status_t err = pause();
- if (err != OK) {
- return err;
+ switch (mState) {
+ case UNINITIALIZED:
+ return INVALID_OPERATION;
+ case PLAYING:
+ mPlayer->pause();
+ mState = UNINITIALIZED;
+ return OK;
+ case PAUSED:
+ mState = UNINITIALIZED;
+ return OK;
+ default:
+ TRESPASS();
}
- Mutex::Autolock autoLock(mLock);
- mState = UNINITIALIZED;
- return OK;
+ return UNKNOWN_ERROR;
}
status_t TimedTextDriver::seekToAsync(int64_t timeUs) {
- mPlayer->seekToAsync(timeUs);
- return OK;
+ Mutex::Autolock autoLock(mLock);
+ switch (mState) {
+ case UNINITIALIZED:
+ return INVALID_OPERATION;
+ case PAUSED:
+ mPlayer->seekToAsync(timeUs);
+ return OK;
+ case PLAYING:
+ mPlayer->seekToAsync(timeUs);
+ return OK;
+ defaut:
+ TRESPASS();
+ }
+ return UNKNOWN_ERROR;
}
status_t TimedTextDriver::addInBandTextSource(
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index b9cac78..df7eb39 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -41,6 +41,8 @@ static const int64_t kInvalidTimeUs = INT_MIN;
TimedTextPlayer::TimedTextPlayer(const wp<MediaPlayerBase> &listener)
: mListener(listener),
mSource(NULL),
+ mPendingSeekTimeUs(kInvalidTimeUs),
+ mPaused(false),
mSendSubtitleGeneration(0) {
}
@@ -53,9 +55,7 @@ TimedTextPlayer::~TimedTextPlayer() {
}
void TimedTextPlayer::start() {
- sp<AMessage> msg = new AMessage(kWhatSeek, id());
- msg->setInt64("seekTimeUs", kInvalidTimeUs);
- msg->post();
+ (new AMessage(kWhatStart, id()))->post();
}
void TimedTextPlayer::pause() {
@@ -81,11 +81,34 @@ void TimedTextPlayer::setDataSource(sp<TimedTextSource> source) {
void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatPause: {
- mSendSubtitleGeneration++;
+ mPaused = true;
break;
}
case kWhatResume: {
- doRead();
+ mPaused = false;
+ if (mPendingSeekTimeUs != kInvalidTimeUs) {
+ seekToAsync(mPendingSeekTimeUs);
+ mPendingSeekTimeUs = kInvalidTimeUs;
+ } else {
+ doRead();
+ }
+ break;
+ }
+ case kWhatStart: {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener == NULL) {
+ ALOGE("Listener is NULL when kWhatStart is received.");
+ break;
+ }
+ mPaused = false;
+ mPendingSeekTimeUs = kInvalidTimeUs;
+ int32_t positionMs = 0;
+ listener->getCurrentPosition(&positionMs);
+ int64_t seekTimeUs = positionMs * 1000ll;
+
+ notifyListener();
+ mSendSubtitleGeneration++;
+ doSeekAndRead(seekTimeUs);
break;
}
case kWhatRetryRead: {
@@ -110,7 +133,6 @@ void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
case kWhatSeek: {
- mSendSubtitleGeneration++;
int64_t seekTimeUs = kInvalidTimeUs;
// Clear a displayed timed text before seeking.
notifyListener();
@@ -123,6 +145,11 @@ void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
seekTimeUs = positionMs * 1000ll;
}
}
+ if (mPaused) {
+ mPendingSeekTimeUs = seekTimeUs;
+ break;
+ }
+ mSendSubtitleGeneration++;
doSeekAndRead(seekTimeUs);
break;
}
@@ -221,22 +248,20 @@ void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {
void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeUs) {
int64_t delayUs = delayUsFromCurrentTime(timeUs);
- sp<MediaPlayerBase> listener = mListener.promote();
- if (listener != NULL) {
- sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
- msg->setInt32("generation", mSendSubtitleGeneration);
- if (parcel != NULL) {
- msg->setObject("subtitle", parcel);
- }
- msg->setInt64("fireTimeUs", timeUs);
- msg->post(delayUs);
+ sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
+ msg->setInt32("generation", mSendSubtitleGeneration);
+ if (parcel != NULL) {
+ msg->setObject("subtitle", parcel);
}
+ msg->setInt64("fireTimeUs", timeUs);
+ msg->post(delayUs);
}
int64_t TimedTextPlayer::delayUsFromCurrentTime(int64_t fireTimeUs) {
sp<MediaPlayerBase> listener = mListener.promote();
if (listener == NULL) {
// TODO: it may be better to return kInvalidTimeUs
+ ALOGE("%s: Listener is NULL.", __FUNCTION__, fireTimeUs);
return 0;
}
int32_t positionMs = 0;
@@ -256,19 +281,23 @@ int64_t TimedTextPlayer::delayUsFromCurrentTime(int64_t fireTimeUs) {
void TimedTextPlayer::notifyError(int error) {
sp<MediaPlayerBase> listener = mListener.promote();
- if (listener != NULL) {
- listener->sendEvent(MEDIA_INFO, MEDIA_INFO_TIMED_TEXT_ERROR, error);
+ if (listener == NULL) {
+ ALOGE("%s(error=%d): Listener is NULL.", __FUNCTION__, error);
+ return;
}
+ listener->sendEvent(MEDIA_INFO, MEDIA_INFO_TIMED_TEXT_ERROR, error);
}
void TimedTextPlayer::notifyListener(const Parcel *parcel) {
sp<MediaPlayerBase> listener = mListener.promote();
- if (listener != NULL) {
- if (parcel != NULL && (parcel->dataSize() > 0)) {
- listener->sendEvent(MEDIA_TIMED_TEXT, 0, 0, parcel);
- } else { // send an empty timed text to clear the screen
- listener->sendEvent(MEDIA_TIMED_TEXT);
- }
+ if (listener == NULL) {
+ ALOGE("%s: Listener is NULL.", __FUNCTION__);
+ return;
+ }
+ if (parcel != NULL && (parcel->dataSize() > 0)) {
+ listener->sendEvent(MEDIA_TIMED_TEXT, 0, 0, parcel);
+ } else { // send an empty timed text to clear the screen
+ listener->sendEvent(MEDIA_TIMED_TEXT);
}
}
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h
index d8f83af..ec8ed25 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.h
+++ b/media/libstagefright/timedtext/TimedTextPlayer.h
@@ -50,8 +50,9 @@ protected:
private:
enum {
kWhatPause = 'paus',
- kWhatSeek = 'seek',
kWhatResume = 'resm',
+ kWhatStart = 'strt',
+ kWhatSeek = 'seek',
kWhatRetryRead = 'read',
kWhatSendSubtitle = 'send',
kWhatSetSource = 'ssrc',
@@ -64,6 +65,8 @@ private:
wp<MediaPlayerBase> mListener;
sp<TimedTextSource> mSource;
+ int64_t mPendingSeekTimeUs;
+ bool mPaused;
int32_t mSendSubtitleGeneration;
void doSeekAndRead(int64_t seekTimeUs);