NuPlayerDriver: fix current position for stop and pause.
When start() is called after EOS, it means restarting from the beginning of the stream.
Fix racing conditon on accessing some members.
Report seekTo position before any notifyPosition is called.
Bug: 17031731
Bug: 17178928
Change-Id: I008b827288cf28d39e2a943373fe1e5d7d6c2595
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index c0091bf..60beb9d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -36,8 +36,8 @@
mAsyncResult(UNKNOWN_ERROR),
mDurationUs(-1),
mPositionUs(-1),
- mNotifyTimeRealUs(0),
- mPauseStartedTimeUs(0),
+ mNotifyTimeRealUs(-1),
+ mPauseStartedTimeUs(-1),
mNumFramesTotal(0),
mNumFramesDropped(0),
mLooper(new ALooper),
@@ -240,7 +240,14 @@
}
case STATE_RUNNING:
+ {
+ if (mAtEOS) {
+ mPlayer->seekToAsync(0);
+ mAtEOS = false;
+ mPositionUs = -1;
+ }
break;
+ }
case STATE_PAUSED:
case STATE_STOPPED_AND_PREPARED:
@@ -255,6 +262,7 @@
}
mState = STATE_RUNNING;
+ mPauseStartedTimeUs = -1;
return OK;
}
@@ -268,7 +276,7 @@
// fall through
case STATE_PAUSED:
- notifyListener(MEDIA_STOPPED);
+ notifyListener_l(MEDIA_STOPPED);
// fall through
case STATE_PREPARED:
@@ -281,7 +289,7 @@
default:
return INVALID_OPERATION;
}
- mPauseStartedTimeUs = ALooper::GetNowUs();
+ setPauseStartedTimeIfNeeded();
return OK;
}
@@ -295,7 +303,7 @@
return OK;
case STATE_RUNNING:
- notifyListener(MEDIA_PAUSED);
+ notifyListener_l(MEDIA_PAUSED);
mPlayer->pause();
break;
@@ -303,7 +311,7 @@
return INVALID_OPERATION;
}
- mPauseStartedTimeUs = ALooper::GetNowUs();
+ setPauseStartedTimeIfNeeded();
mState = STATE_PAUSED;
return OK;
@@ -334,7 +342,7 @@
{
mAtEOS = false;
// seeks can take a while, so we essentially paused
- notifyListener(MEDIA_PAUSED);
+ notifyListener_l(MEDIA_PAUSED);
mPlayer->seekToAsync(seekTimeUs);
break;
}
@@ -343,6 +351,8 @@
return INVALID_OPERATION;
}
+ mPositionUs = seekTimeUs;
+ mNotifyTimeRealUs = -1;
return OK;
}
@@ -351,10 +361,11 @@
if (mPositionUs < 0) {
*msec = 0;
+ } else if (mNotifyTimeRealUs == -1) {
+ *msec = mPositionUs / 1000;
} else {
int64_t nowUs =
- (mState != STATE_RUNNING ?
- mPauseStartedTimeUs : ALooper::GetNowUs());
+ (isPlaying() ? ALooper::GetNowUs() : mPauseStartedTimeUs);
*msec = (mPositionUs + nowUs - mNotifyTimeRealUs + 500ll) / 1000;
}
@@ -388,7 +399,7 @@
{
CHECK(mIsAsyncPrepare);
- notifyListener(MEDIA_PREPARED);
+ notifyListener_l(MEDIA_PREPARED);
break;
}
@@ -397,7 +408,7 @@
}
if (mState != STATE_STOPPED) {
- notifyListener(MEDIA_STOPPED);
+ notifyListener_l(MEDIA_STOPPED);
}
mState = STATE_RESET_IN_PROGRESS;
@@ -552,10 +563,7 @@
// no need to notify listener
return;
}
- // note: notifyListener called with lock released
- mLock.unlock();
- notifyListener(wasSeeking ? MEDIA_SEEK_COMPLETE : MEDIA_PREPARED);
- mLock.lock();
+ notifyListener_l(wasSeeking ? MEDIA_SEEK_COMPLETE : MEDIA_PREPARED);
}
void NuPlayerDriver::notifyFrameStats(
@@ -587,11 +595,19 @@
void NuPlayerDriver::notifyListener(
int msg, int ext1, int ext2, const Parcel *in) {
+ Mutex::Autolock autoLock(mLock);
+ notifyListener_l(msg, ext1, ext2, in);
+}
+
+void NuPlayerDriver::notifyListener_l(
+ int msg, int ext1, int ext2, const Parcel *in) {
switch (msg) {
case MEDIA_PLAYBACK_COMPLETE:
{
if (mLooping) {
+ mLock.unlock();
mPlayer->seekToAsync(0);
+ mLock.lock();
break;
}
// fall through
@@ -600,6 +616,7 @@
case MEDIA_ERROR:
{
mAtEOS = true;
+ setPauseStartedTimeIfNeeded();
break;
}
@@ -607,7 +624,9 @@
break;
}
+ mLock.unlock();
sendEvent(msg, ext1, ext2, in);
+ mLock.lock();
}
void NuPlayerDriver::notifySetDataSourceCompleted(status_t err) {
@@ -637,12 +656,12 @@
if (err == OK) {
if (mIsAsyncPrepare) {
- notifyListener(MEDIA_PREPARED);
+ notifyListener_l(MEDIA_PREPARED);
}
mState = STATE_PREPARED;
} else {
if (mIsAsyncPrepare) {
- notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
}
mState = STATE_UNPREPARED;
}
@@ -656,4 +675,10 @@
mPlayerFlags = flags;
}
+void NuPlayerDriver::setPauseStartedTimeIfNeeded() {
+ if (mPauseStartedTimeUs == -1) {
+ mPauseStartedTimeUs = ALooper::GetNowUs();
+ }
+}
+
} // namespace android