Track rebuffering time in nuplayer
track the time the player spends rebuffering content so that it
can be logged through media.metrics for later analysis. records
time rebuffering, number of rebuffering events, and whether player
was rebuffering at exit time (e.g. did user get impatient and quit)
Bug: 69616719
Test: playback on deliberately lossy network
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6c4b823..d1e5d45 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1311,6 +1311,7 @@
mResetting = true;
stopPlaybackTimer("kWhatReset");
+ stopRebufferingTimer(true);
mDeferredActions.push_back(
new FlushDecoderAction(
@@ -1604,6 +1605,37 @@
}
}
+void NuPlayer::startRebufferingTimer() {
+ Mutex::Autolock autoLock(mPlayingTimeLock);
+ if (mLastStartedRebufferingTimeNs == 0) {
+ mLastStartedRebufferingTimeNs = systemTime();
+ ALOGV("startRebufferingTimer() time %20" PRId64 "", mLastStartedRebufferingTimeNs);
+ }
+}
+
+void NuPlayer::stopRebufferingTimer(bool exitingPlayback) {
+ Mutex::Autolock autoLock(mPlayingTimeLock);
+
+ ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)", mLastStartedRebufferingTimeNs, exitingPlayback);
+
+ if (mLastStartedRebufferingTimeNs != 0) {
+ sp<NuPlayerDriver> driver = mDriver.promote();
+ if (driver != NULL) {
+ int64_t now = systemTime();
+ int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
+ ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
+
+ if (rebuffered > 0) {
+ driver->notifyMoreRebufferingTimeUs((rebuffered+500)/1000);
+ if (exitingPlayback) {
+ driver->notifyRebufferingWhenExit(true);
+ }
+ }
+ }
+ mLastStartedRebufferingTimeNs = 0;
+ }
+}
+
void NuPlayer::onPause() {
stopPlaybackTimer("onPause");
@@ -2250,6 +2282,7 @@
CHECK(mVideoDecoder == NULL);
stopPlaybackTimer("performReset");
+ stopRebufferingTimer(true);
cancelPollDuration();
@@ -2503,6 +2536,7 @@
if (mStarted) {
ALOGI("buffer low, pausing...");
+ startRebufferingTimer();
mPausedForBuffering = true;
onPause();
}
@@ -2516,6 +2550,7 @@
if (mStarted) {
ALOGI("buffer ready, resuming...");
+ stopRebufferingTimer(false);
mPausedForBuffering = false;
// do not resume yet if client didn't unpause
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 492b8d4..fda69e8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -183,6 +183,10 @@
void stopPlaybackTimer(const char *where);
void startPlaybackTimer(const char *where);
+ int64_t mLastStartedRebufferingTimeNs;
+ void startRebufferingTimer();
+ void stopRebufferingTimer(bool exitingPlayback);
+
int64_t mPreviousSeekTimeUs;
List<sp<Action> > mDeferredActions;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index bd54df0..ebf57c6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -56,6 +56,10 @@
static const char *kPlayerError = "android.media.mediaplayer.err";
static const char *kPlayerErrorCode = "android.media.mediaplayer.errcode";
static const char *kPlayerDataSourceType = "android.media.mediaplayer.dataSource";
+//
+static const char *kPlayerRebuffering = "android.media.mediaplayer.rebufferingMs";
+static const char *kPlayerRebufferingCount = "android.media.mediaplayer.rebuffers";
+static const char *kPlayerRebufferingAtExit = "android.media.mediaplayer.rebufferExit";
NuPlayerDriver::NuPlayerDriver(pid_t pid)
@@ -67,6 +71,9 @@
mPositionUs(-1),
mSeekInProgress(false),
mPlayingTimeUs(0),
+ mRebufferingTimeUs(0),
+ mRebufferingEvents(0),
+ mRebufferingAtExit(false),
mLooper(new ALooper),
mMediaClock(new MediaClock),
mPlayer(new NuPlayer(pid, mMediaClock)),
@@ -582,6 +589,12 @@
mAnalyticsItem->setInt64(kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
+ if (mRebufferingEvents != 0) {
+ mAnalyticsItem->setInt64(kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
+ mAnalyticsItem->setInt32(kPlayerRebufferingCount, mRebufferingEvents);
+ mAnalyticsItem->setInt32(kPlayerRebufferingAtExit, mRebufferingAtExit);
+ }
+
mAnalyticsItem->setCString(kPlayerDataSourceType, mPlayer->getDataSourceType());
}
@@ -661,6 +674,9 @@
mPositionUs = -1;
mLooping = false;
mPlayingTimeUs = 0;
+ mRebufferingTimeUs = 0;
+ mRebufferingEvents = 0;
+ mRebufferingAtExit = false;
return OK;
}
@@ -811,6 +827,17 @@
mPlayingTimeUs += playingUs;
}
+void NuPlayerDriver::notifyMoreRebufferingTimeUs(int64_t rebufferingUs) {
+ Mutex::Autolock autoLock(mLock);
+ mRebufferingTimeUs += rebufferingUs;
+ mRebufferingEvents++;
+}
+
+void NuPlayerDriver::notifyRebufferingWhenExit(bool status) {
+ Mutex::Autolock autoLock(mLock);
+ mRebufferingAtExit = status;
+}
+
void NuPlayerDriver::notifySeekComplete() {
ALOGV("notifySeekComplete(%p)", this);
Mutex::Autolock autoLock(mLock);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 6ca6344..13b46c3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -84,6 +84,8 @@
void notifySetSurfaceComplete();
void notifyDuration(int64_t durationUs);
void notifyMorePlayingTimeUs(int64_t timeUs);
+ void notifyMoreRebufferingTimeUs(int64_t timeUs);
+ void notifyRebufferingWhenExit(bool status);
void notifySeekComplete();
void notifySeekComplete_l();
void notifyListener(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
@@ -126,6 +128,9 @@
int64_t mPositionUs;
bool mSeekInProgress;
int64_t mPlayingTimeUs;
+ int64_t mRebufferingTimeUs;
+ int32_t mRebufferingEvents;
+ bool mRebufferingAtExit;
// <<<
sp<ALooper> mLooper;