Skip to content

Commit

Permalink
Remove the "Seek to exact frame" setting.
Browse files Browse the repository at this point in the history
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
stichnot committed May 19, 2012
1 parent 389ba60 commit 4d0bbbe
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 113 deletions.
3 changes: 2 additions & 1 deletion mythtv/libs/libmythtv/avformatdecoder.cpp
Expand Up @@ -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;

Expand Down
42 changes: 34 additions & 8 deletions mythtv/libs/libmythtv/decoderbase.cpp
Expand Up @@ -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),
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions mythtv/libs/libmythtv/decoderbase.h
Expand Up @@ -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.
Expand Down Expand Up @@ -270,7 +270,7 @@ class DecoderBase
vector<PosMapEntry> m_positionMap;
bool dontSyncPositionMap;

bool exactseeks;
uint64_t seeksnap;
bool livetv;
bool watchingrecording;

Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/importrecorder.cpp
Expand Up @@ -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);

Expand Down

0 comments on commit 4d0bbbe

Please sign in to comment.