NuPlayer: hook up seekTo for precise seeking.
Test: compiles
Bug: 32557491
Change-Id: Idda3c87658f43101b9fd0fe22d2399710fb80211
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 661eaa2..edcca64 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -65,6 +65,13 @@
virtual status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) = 0;
virtual status_t getSyncSettings(AVSyncSettings* sync /* nonnull */,
float* videoFps /* nonnull */) = 0;
+ // When |precise| is true, it's required that the first rendered media position after seekTo
+ // is precisely at |msec|, up to rounding error of granuality, e.g., video frame interval or
+ // audio length of decoding buffer. In this case, it might take a little long time to finish
+ // seekTo.
+ // When |precise| is false, |msec| is a hint to the mediaplayer which will try its best to
+ // fulfill the request, but it's not guaranteed. This option could result in fast finish of
+ // seekTo.
virtual status_t seekTo(int msec, bool precise = false) = 0;
virtual status_t getCurrentPosition(int* msec) = 0;
virtual status_t getDuration(int* msec) = 0;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index c0a5682..cdbc2f8 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1254,10 +1254,7 @@
sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
MediaBuffer* mb,
- media_track_type trackType,
- int64_t seekTimeUs,
- bool precise,
- int64_t *actualTimeUs) {
+ media_track_type trackType) {
bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
size_t outLength = mb->range_length();
@@ -1294,12 +1291,6 @@
CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
meta->setInt64("timeUs", timeUs);
- if (precise && seekTimeUs > timeUs) {
- sp<AMessage> extra = new AMessage;
- extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
- meta->setMessage("extra", extra);
- }
-
if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
int32_t layerId;
if (mb->meta_data()->findInt32(kKeyTemporalLayerId, &layerId)) {
@@ -1339,10 +1330,6 @@
meta->setBuffer("mpegUserData", mpegUserData);
}
- if (actualTimeUs) {
- *actualTimeUs = timeUs;
- }
-
mb->release();
mb = NULL;
@@ -1468,9 +1455,19 @@
queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
- sp<ABuffer> buffer = mediaBufferToABuffer(
- mbuf, trackType, seekTimeUs, precise,
- numBuffers == 0 ? actualTimeUs : NULL);
+ sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType);
+ if (numBuffers == 0 && actualTimeUs != nullptr) {
+ *actualTimeUs = timeUs;
+ }
+ if (seeking && buffer != nullptr) {
+ sp<AMessage> meta = buffer->meta();
+ if (meta != nullptr && precise && seekTimeUs > timeUs) {
+ sp<AMessage> extra = new AMessage;
+ extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
+ meta->setMessage("extra", extra);
+ }
+ }
+
track->mPackets->queueAccessUnit(buffer);
formatChange = false;
seeking = false;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index f9db6a5..368d11c 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -71,7 +71,7 @@
virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
virtual ssize_t getSelectedTrack(media_track_type type) const;
virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
- virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
+ virtual status_t seekTo(int64_t seekTimeUs, bool precise = false) override;
virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers);
@@ -276,13 +276,15 @@
sp<ABuffer> mediaBufferToABuffer(
MediaBuffer *mbuf,
- media_track_type trackType,
- int64_t seekTimeUs,
- bool precise,
- int64_t *actualTimeUs = NULL);
+ media_track_type trackType);
void postReadBuffer(media_track_type trackType);
void onReadBuffer(const sp<AMessage>& msg);
+ // |precise| is a modifier of |seekTimeUs|.
+ // When |precise| is true, the buffer read shall include an item indicating skipping
+ // rendering all buffers with timestamp earlier than |seekTimeUs|.
+ // When |precise| is false, the buffer read will not include the item as above in order
+ // to facilitate fast seek operation.
void readBuffer(
media_track_type trackType,
int64_t seekTimeUs = -1ll, bool precise = false,
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index be3b4f0..16c3c37 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -47,7 +47,7 @@
virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
virtual ssize_t getSelectedTrack(media_track_type /* type */) const;
virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
- virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
+ virtual status_t seekTo(int64_t seekTimeUs, bool precise = false) override;
protected:
virtual ~HTTPLiveSource();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index cbc32b1..90b7b7f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -70,16 +70,18 @@
};
struct NuPlayer::SeekAction : public Action {
- explicit SeekAction(int64_t seekTimeUs)
- : mSeekTimeUs(seekTimeUs) {
+ explicit SeekAction(int64_t seekTimeUs, bool precise)
+ : mSeekTimeUs(seekTimeUs),
+ mPrecise(precise) {
}
virtual void execute(NuPlayer *player) {
- player->performSeek(mSeekTimeUs);
+ player->performSeek(mSeekTimeUs, mPrecise);
}
private:
int64_t mSeekTimeUs;
+ bool mPrecise;
DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
};
@@ -682,7 +684,7 @@
int64_t currentPositionUs = 0;
if (getCurrentPosition(¤tPositionUs) == OK) {
mDeferredActions.push_back(
- new SeekAction(currentPositionUs));
+ new SeekAction(currentPositionUs, false /* precise */));
}
}
@@ -1213,7 +1215,7 @@
// only once if needed. After the player is started, any seek
// operation will go through normal path.
// Audio-only cases are handled separately.
- onStart(seekTimeUs);
+ onStart(seekTimeUs, precise);
if (mStarted) {
onPause();
mPausedByClient = true;
@@ -1229,7 +1231,7 @@
FLUSH_CMD_FLUSH /* video */));
mDeferredActions.push_back(
- new SeekAction(seekTimeUs));
+ new SeekAction(seekTimeUs, precise));
// After a flush without shutdown, decoder is paused.
// Don't resume it until source seek is done, otherwise it could
@@ -1318,13 +1320,13 @@
return OK;
}
-void NuPlayer::onStart(int64_t startPositionUs) {
+void NuPlayer::onStart(int64_t startPositionUs, bool precise) {
if (!mSourceStarted) {
mSourceStarted = true;
mSource->start();
}
if (startPositionUs > 0) {
- performSeek(startPositionUs);
+ performSeek(startPositionUs, precise);
if (mSource->getFormat(false /* audio */) == NULL) {
return;
}
@@ -1540,7 +1542,7 @@
mRenderer->flush(false /* audio */, false /* notifyComplete */);
}
- performSeek(currentPositionUs);
+ performSeek(currentPositionUs, false /* precise */);
if (forceNonOffload) {
mRenderer->signalDisableOffloadAudio();
@@ -1997,10 +1999,9 @@
}
}
-void NuPlayer::performSeek(int64_t seekTimeUs) {
- ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
- (long long)seekTimeUs,
- seekTimeUs / 1E6);
+void NuPlayer::performSeek(int64_t seekTimeUs, bool precise) {
+ ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), precise=%d",
+ (long long)seekTimeUs, seekTimeUs / 1E6, precise);
if (mSource == NULL) {
// This happens when reset occurs right before the loop mode
@@ -2011,7 +2012,7 @@
return;
}
mPreviousSeekTimeUs = seekTimeUs;
- mSource->seekTo(seekTimeUs);
+ mSource->seekTo(seekTimeUs, precise);
++mTimedTextGeneration;
// everything's flushed, continue playback.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 725f806..3ae2ada 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -245,7 +245,7 @@
void handleFlushComplete(bool audio, bool isDecoder);
void finishFlushIfPossible();
- void onStart(int64_t startPositionUs = -1);
+ void onStart(int64_t startPositionUs = -1, bool precise = false);
void onResume();
void onPause();
@@ -263,7 +263,7 @@
void processDeferredActions();
- void performSeek(int64_t seekTimeUs);
+ void performSeek(int64_t seekTimeUs, bool precise);
void performDecoderFlush(FlushCommand audio, FlushCommand video);
void performReset();
void performScanSources();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index b62fbfd..fe4fc63 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -104,6 +104,7 @@
return INVALID_OPERATION;
}
+ // Refer to comment of seekTo in IMediaPlayer.h for meaning of |precise|.
virtual status_t seekTo(int64_t /* seekTimeUs */, bool /* precise */ = false) {
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index f2d9cc0..b2962ed6 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -49,7 +49,7 @@
virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
virtual status_t getDuration(int64_t *durationUs);
- virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
+ virtual status_t seekTo(int64_t seekTimeUs, bool precise = false) override;
void onMessageReceived(const sp<AMessage> &msg);