Permalink
Browse files

Remove the "Seek to exact frame" setting.

Instead, use more adaptive, sensible behavior.  When doing relative
seeks, snap to the nearest keyframe if its distance from the target
frame is within 10% of the total seek distance.  When seeking within
the cutlist editor, use a value of 50% instead.

Exact frame seeking is used for absolute seeks (bookmark seek, skips
based on cutlist/commskiplist, preview generation), and for keyframe
and single-frame seeking in the cutlist editor.
  • Loading branch information...
1 parent 389ba60 commit 4d0bbbe1e54aaa91abbd233b7e5a1a48103462f2 @stichnot stichnot committed May 19, 2012
@@ -576,7 +576,8 @@ bool AvFormatDecoder::DoFastForward(long long desiredFrame, bool discardFrames)
long double seekts = desiredFrame * AV_TIME_BASE / fps;
ts += (long long)seekts;
- bool exactseeks = DecoderBase::getExactSeeks();
+ // XXX figure out how to do snapping in this case
+ bool exactseeks = !DecoderBase::getSeekSnap();
int flags = (dorewind || exactseeks) ? AVSEEK_FLAG_BACKWARD : 0;
@@ -38,7 +38,7 @@ DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo)
m_positionMapLock(QMutex::Recursive),
dontSyncPositionMap(false),
- exactseeks(false), livetv(false), watchingrecording(false),
+ seeksnap(-1), livetv(false), watchingrecording(false),
hasKeyFrameAdjustTable(false), lowbuffers(false),
getrawframes(false), getrawvideo(false),
@@ -522,7 +522,8 @@ bool DecoderBase::DoRewind(long long desiredFrame, bool discardFrames)
// Do any Extra frame-by-frame seeking for exactseeks mode
// And flush pre-seek frame if we are allowed to and need to..
- int normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0;
+ int normalframes = desiredFrame - (framesPlayed - 1) > seeksnap
+ ? desiredFrame - framesPlayed : 0;
normalframes = max(normalframes, 0);
SeekReset(lastKey, normalframes, true, discardFrames);
@@ -555,8 +556,21 @@ bool DecoderBase::DoRewindSeek(long long desiredFrame)
PosMapEntry e;
{
QMutexLocker locker(&m_positionMapLock);
- int pos_idx = min(pre_idx, post_idx);
- e = m_positionMap[pos_idx];
+ PosMapEntry e_pre = m_positionMap[pre_idx];
+ PosMapEntry e_post = m_positionMap[post_idx];
+ int pos_idx = pre_idx;
+ e = e_pre;
+ if (((uint64_t) (GetKey(e_post) - desiredFrame)) <= seeksnap &&
+ framesPlayed - 1 > GetKey(e_post) &&
+ GetKey(e_post) - desiredFrame <= desiredFrame - GetKey(e_pre))
+ {
+ // Snap to the right if e_post is within snap distance and
+ // is at least as close a snap as e_pre. Take into
+ // account that if framesPlayed has already reached
+ // e_post, we should only snap to the left.
+ pos_idx = post_idx;
+ e = e_post;
+ }
lastKey = GetKey(e);
// ??? Don't rewind past the beginning of the file
@@ -722,7 +736,8 @@ bool DecoderBase::DoFastForward(long long desiredFrame, bool discardFrames)
// Do any Extra frame-by-frame seeking for exactseeks mode
// And flush pre-seek frame if we are allowed to and need to..
- int normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0;
+ int normalframes = desiredFrame - (framesPlayed - 1) > seeksnap
+ ? desiredFrame - framesPlayed : 0;
normalframes = max(normalframes, 0);
SeekReset(lastKey, normalframes, needflush, discardFrames);
@@ -755,12 +770,23 @@ void DecoderBase::DoFastForwardSeek(long long desiredFrame, bool &needflush)
FindPosition(desiredFrame, hasKeyFrameAdjustTable, pre_idx, post_idx);
// if exactseeks, use keyframe <= desiredFrame
- uint pos_idx = (exactseeks) ? pre_idx : max(pre_idx, post_idx);
- PosMapEntry e;
+ PosMapEntry e, e_pre, e_post;
{
QMutexLocker locker(&m_positionMapLock);
- e = m_positionMap[pos_idx];
+ e_pre = m_positionMap[pre_idx];
+ e_post = m_positionMap[post_idx];
+ }
+ e = e_pre;
+ if (((uint64_t) (GetKey(e_post) - desiredFrame)) <= seeksnap &&
+ (framesPlayed - 1 >= GetKey(e_pre) ||
+ GetKey(e_post) - desiredFrame < desiredFrame - GetKey(e_pre)))
+ {
+ // Snap to the right if e_post is within snap distance and is
+ // a closer snap than e_pre. Take into account that if
+ // framesPlayed has already reached e_pre, we should only snap
+ // to the right.
+ e = e_post;
}
lastKey = GetKey(e);
@@ -113,8 +113,8 @@ class DecoderBase
virtual void SetEof(bool eof) { ateof = eof; }
bool GetEof(void) const { return ateof; }
- void setExactSeeks(bool exact) { exactseeks = exact; }
- bool getExactSeeks(void) const { return exactseeks; }
+ void setSeekSnap(uint64_t snap) { seeksnap = snap; }
+ uint64_t getSeekSnap(void) const { return seeksnap; }
void setLiveTVMode(bool live) { livetv = live; }
// Must be done while player is paused.
@@ -270,7 +270,7 @@ class DecoderBase
vector<PosMapEntry> m_positionMap;
bool dontSyncPositionMap;
- bool exactseeks;
+ uint64_t seeksnap;
bool livetv;
bool watchingrecording;
@@ -113,7 +113,7 @@ void ImportRecorder::run(void)
ctx->SetPlayingInfo(curRecording);
ctx->SetRingBuffer(rb);
ctx->SetPlayer(cfp);
- cfp->SetPlayerInfo(NULL, NULL, true, ctx);
+ cfp->SetPlayerInfo(NULL, NULL, ctx);
cfp->RebuildSeekTable(false);
Oops, something went wrong.

0 comments on commit 4d0bbbe

Please sign in to comment.