Loading include/media/IMediaPlayer.h +7 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,13 @@ public: 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; Loading media/libmediaplayerservice/nuplayer/GenericSource.cpp +14 −17 Original line number Diff line number Diff line Loading @@ -1254,10 +1254,7 @@ status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs, bool precise) { 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(); Loading Loading @@ -1294,12 +1291,6 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( 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)) { Loading Loading @@ -1339,10 +1330,6 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( meta->setBuffer("mpegUserData", mpegUserData); } if (actualTimeUs) { *actualTimeUs = timeUs; } mb->release(); mb = NULL; Loading Loading @@ -1468,9 +1455,19 @@ void NuPlayer::GenericSource::readBuffer( 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; Loading media/libmediaplayerservice/nuplayer/GenericSource.h +7 −5 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ struct NuPlayer::GenericSource : public NuPlayer::Source { 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); Loading Loading @@ -276,13 +276,15 @@ private: 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, Loading media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +1 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { 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(); Loading media/libmediaplayerservice/nuplayer/NuPlayer.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -70,16 +70,18 @@ private: }; 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); }; Loading Loading @@ -682,7 +684,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int64_t currentPositionUs = 0; if (getCurrentPosition(¤tPositionUs) == OK) { mDeferredActions.push_back( new SeekAction(currentPositionUs)); new SeekAction(currentPositionUs, false /* precise */)); } } Loading Loading @@ -1213,7 +1215,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { // 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; Loading @@ -1229,7 +1231,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 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 Loading Loading @@ -1318,13 +1320,13 @@ status_t NuPlayer::onInstantiateSecureDecoders() { 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; } Loading Loading @@ -1540,7 +1542,7 @@ void NuPlayer::restartAudio( mRenderer->flush(false /* audio */, false /* notifyComplete */); } performSeek(currentPositionUs); performSeek(currentPositionUs, false /* precise */); if (forceNonOffload) { mRenderer->signalDisableOffloadAudio(); Loading Loading @@ -1997,10 +1999,9 @@ void NuPlayer::processDeferredActions() { } } 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 Loading @@ -2011,7 +2012,7 @@ void NuPlayer::performSeek(int64_t seekTimeUs) { return; } mPreviousSeekTimeUs = seekTimeUs; mSource->seekTo(seekTimeUs); mSource->seekTo(seekTimeUs, precise); ++mTimedTextGeneration; // everything's flushed, continue playback. Loading Loading
include/media/IMediaPlayer.h +7 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,13 @@ public: 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; Loading
media/libmediaplayerservice/nuplayer/GenericSource.cpp +14 −17 Original line number Diff line number Diff line Loading @@ -1254,10 +1254,7 @@ status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs, bool precise) { 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(); Loading Loading @@ -1294,12 +1291,6 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( 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)) { Loading Loading @@ -1339,10 +1330,6 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( meta->setBuffer("mpegUserData", mpegUserData); } if (actualTimeUs) { *actualTimeUs = timeUs; } mb->release(); mb = NULL; Loading Loading @@ -1468,9 +1455,19 @@ void NuPlayer::GenericSource::readBuffer( 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; Loading
media/libmediaplayerservice/nuplayer/GenericSource.h +7 −5 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ struct NuPlayer::GenericSource : public NuPlayer::Source { 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); Loading Loading @@ -276,13 +276,15 @@ private: 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, Loading
media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +1 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { 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(); Loading
media/libmediaplayerservice/nuplayer/NuPlayer.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -70,16 +70,18 @@ private: }; 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); }; Loading Loading @@ -682,7 +684,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int64_t currentPositionUs = 0; if (getCurrentPosition(¤tPositionUs) == OK) { mDeferredActions.push_back( new SeekAction(currentPositionUs)); new SeekAction(currentPositionUs, false /* precise */)); } } Loading Loading @@ -1213,7 +1215,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { // 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; Loading @@ -1229,7 +1231,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 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 Loading Loading @@ -1318,13 +1320,13 @@ status_t NuPlayer::onInstantiateSecureDecoders() { 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; } Loading Loading @@ -1540,7 +1542,7 @@ void NuPlayer::restartAudio( mRenderer->flush(false /* audio */, false /* notifyComplete */); } performSeek(currentPositionUs); performSeek(currentPositionUs, false /* precise */); if (forceNonOffload) { mRenderer->signalDisableOffloadAudio(); Loading Loading @@ -1997,10 +1999,9 @@ void NuPlayer::processDeferredActions() { } } 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 Loading @@ -2011,7 +2012,7 @@ void NuPlayer::performSeek(int64_t seekTimeUs) { return; } mPreviousSeekTimeUs = seekTimeUs; mSource->seekTo(seekTimeUs); mSource->seekTo(seekTimeUs, precise); ++mTimedTextGeneration; // everything's flushed, continue playback. Loading