diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index bedd20d..29eadbf 100644
a
|
b
|
bool AvFormatDecoder::DoFastForward(long long desiredFrame, bool discardFrames) |
569 | 569 | long double seekts = desiredFrame * AV_TIME_BASE / fps; |
570 | 570 | ts += (long long)seekts; |
571 | 571 | |
572 | | bool exactseeks = DecoderBase::getExactSeeks(); |
| 572 | //bool exactseeks = DecoderBase::getExactSeeks(); |
| 573 | // XXX figure out how to do snapping in this case |
| 574 | bool exactseeks = !DecoderBase::getSeekSnap(); |
573 | 575 | |
574 | 576 | int flags = (dorewind || exactseeks) ? AVSEEK_FLAG_BACKWARD : 0; |
575 | 577 | |
diff --git a/mythtv/libs/libmythtv/decoderbase.cpp b/mythtv/libs/libmythtv/decoderbase.cpp
index 8e8d844..33729da 100644
a
|
b
|
DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo) |
39 | 39 | m_positionMapLock(QMutex::Recursive), |
40 | 40 | dontSyncPositionMap(false), |
41 | 41 | |
42 | | exactseeks(false), livetv(false), watchingrecording(false), |
| 42 | seeksnap(-1), livetv(false), watchingrecording(false), |
43 | 43 | |
44 | 44 | hasKeyFrameAdjustTable(false), lowbuffers(false), |
45 | 45 | getrawframes(false), getrawvideo(false), |
… |
… |
bool DecoderBase::DoRewind(long long desiredFrame, bool discardFrames) |
516 | 516 | |
517 | 517 | // Do any Extra frame-by-frame seeking for exactseeks mode |
518 | 518 | // And flush pre-seek frame if we are allowed to and need to.. |
519 | | int normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0; |
| 519 | int normalframes = desiredFrame - (framesPlayed - 1) > seeksnap |
| 520 | ? desiredFrame - framesPlayed : 0; |
520 | 521 | normalframes = max(normalframes, 0); |
521 | 522 | SeekReset(lastKey, normalframes, true, discardFrames); |
522 | 523 | |
… |
… |
bool DecoderBase::DoRewindSeek(long long desiredFrame) |
568 | 569 | PosMapEntry e; |
569 | 570 | { |
570 | 571 | QMutexLocker locker(&m_positionMapLock); |
571 | | int pos_idx = min(pre_idx, post_idx); |
572 | | e = m_positionMap[pos_idx]; |
| 572 | PosMapEntry e_pre = m_positionMap[pre_idx]; |
| 573 | PosMapEntry e_post = m_positionMap[post_idx]; |
| 574 | int pos_idx = pre_idx; |
| 575 | e = e_pre; |
| 576 | if (((uint64_t) (GetKey(e_post) - desiredFrame)) <= seeksnap && |
| 577 | framesPlayed - 1 > GetKey(e_post) && |
| 578 | GetKey(e_post) - desiredFrame <= desiredFrame - GetKey(e_pre)) |
| 579 | { |
| 580 | // Snap to the right if e_post is within snap distance and |
| 581 | // is at least as close a snap as e_pre. Take into |
| 582 | // account that if framesPlayed has already reached |
| 583 | // e_post, we should only snap to the left. |
| 584 | pos_idx = post_idx; |
| 585 | e = e_post; |
| 586 | } |
573 | 587 | lastKey = GetKey(e); |
574 | 588 | |
575 | 589 | // ??? Don't rewind past the beginning of the file |
… |
… |
bool DecoderBase::DoFastForward(long long desiredFrame, bool discardFrames) |
731 | 745 | |
732 | 746 | // Do any Extra frame-by-frame seeking for exactseeks mode |
733 | 747 | // And flush pre-seek frame if we are allowed to and need to.. |
734 | | int normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0; |
| 748 | int normalframes = desiredFrame - (framesPlayed - 1) > seeksnap |
| 749 | ? desiredFrame - framesPlayed : 0; |
735 | 750 | normalframes = max(normalframes, 0); |
736 | 751 | SeekReset(lastKey, normalframes, needflush, discardFrames); |
737 | 752 | |
… |
… |
void DecoderBase::DoFastForwardSeek(long long desiredFrame, bool &needflush) |
789 | 804 | FindPosition(desiredFrame, hasKeyFrameAdjustTable, pre_idx, post_idx); |
790 | 805 | |
791 | 806 | // if exactseeks, use keyframe <= desiredFrame |
792 | | uint pos_idx = (exactseeks) ? pre_idx : max(pre_idx, post_idx); |
793 | 807 | |
794 | | PosMapEntry e; |
| 808 | PosMapEntry e, e_pre, e_post; |
795 | 809 | { |
796 | 810 | QMutexLocker locker(&m_positionMapLock); |
797 | | e = m_positionMap[pos_idx]; |
| 811 | e_pre = m_positionMap[pre_idx]; |
| 812 | e_post = m_positionMap[post_idx]; |
| 813 | } |
| 814 | e = e_pre; |
| 815 | if (((uint64_t) (GetKey(e_post) - desiredFrame)) <= seeksnap && |
| 816 | (framesPlayed - 1 >= GetKey(e_pre) || |
| 817 | GetKey(e_post) - desiredFrame < desiredFrame - GetKey(e_pre))) |
| 818 | { |
| 819 | // Snap to the right if e_post is within snap distance and is |
| 820 | // a closer snap than e_pre. Take into account that if |
| 821 | // framesPlayed has already reached e_pre, we should only snap |
| 822 | // to the right. |
| 823 | e = e_post; |
798 | 824 | } |
799 | 825 | lastKey = GetKey(e); |
800 | 826 | |
diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h
index fe16fe9..e7253e3 100644
a
|
b
|
class DecoderBase |
97 | 97 | virtual void SetEof(bool eof) { ateof = eof; } |
98 | 98 | bool GetEof(void) { return ateof; } |
99 | 99 | |
100 | | void setExactSeeks(bool exact) { exactseeks = exact; } |
101 | | bool getExactSeeks(void) const { return exactseeks; } |
| 100 | void setSeekSnap(uint64_t snap) { seeksnap = snap; } |
| 101 | uint64_t getSeekSnap(void) const { return seeksnap; } |
102 | 102 | void setLiveTVMode(bool live) { livetv = live; } |
103 | 103 | |
104 | 104 | // Must be done while player is paused. |
… |
… |
class DecoderBase |
255 | 255 | vector<PosMapEntry> m_positionMap; |
256 | 256 | bool dontSyncPositionMap; |
257 | 257 | |
258 | | bool exactseeks; |
| 258 | uint64_t seeksnap; |
259 | 259 | bool livetv; |
260 | 260 | bool watchingrecording; |
261 | 261 | |
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
index b2a991b..62547af 100644
a
|
b
|
MythPlayer::MythPlayer(bool muted) |
147 | 147 | // Bookmark stuff |
148 | 148 | bookmarkseek(0), |
149 | 149 | // Seek |
150 | | fftime(0), exactseeks(false), |
| 150 | fftime(0), seeksnap(-1), |
151 | 151 | // Playback misc. |
152 | 152 | videobuf_retries(0), framesPlayed(0), |
153 | 153 | totalFrames(0), totalLength(0), |
… |
… |
int MythPlayer::OpenFile(uint retries, bool allow_libmpeg2) |
966 | 966 | return -1; |
967 | 967 | } |
968 | 968 | |
969 | | decoder->setExactSeeks(exactseeks); |
| 969 | decoder->setSeekSnap(seeksnap); |
970 | 970 | decoder->setLiveTVMode(livetv); |
971 | 971 | decoder->setWatchingRecording(watchingrecording); |
972 | 972 | decoder->setTranscoding(transcoding); |
… |
… |
void MythPlayer::JumpToProgram(void) |
2431 | 2431 | nextpos = 0; |
2432 | 2432 | |
2433 | 2433 | if (nextpos > 10) |
2434 | | DoFastForward(nextpos, true, false); |
| 2434 | DoFastForward(nextpos, true, -1); |
2435 | 2435 | |
2436 | 2436 | player_ctx->SetPlayerChangingBuffers(false); |
2437 | 2437 | LOG(VB_PLAYBACK, LOG_INFO, LOC + "JumpToProgram - end"); |
… |
… |
void MythPlayer::InitialSeek(void) |
2475 | 2475 | // TODO handle initial commskip and/or cutlist skip as well |
2476 | 2476 | if (bookmarkseek > 30) |
2477 | 2477 | { |
2478 | | DoFastForward(bookmarkseek, true, false); |
| 2478 | DoFastForward(bookmarkseek, true, -1); |
2479 | 2479 | if (clearSavedPosition && !player_ctx->IsPIP()) |
2480 | 2480 | SetBookmark(true); |
2481 | 2481 | } |
… |
… |
void MythPlayer::EventLoop(void) |
2666 | 2666 | if (!msg.isEmpty()) |
2667 | 2667 | SetOSDStatus(msg, kOSDTimeout_Med); |
2668 | 2668 | if (jump) |
2669 | | DoJumpToFrame(jumpto, true, true); |
| 2669 | DoJumpToFrame(jumpto, true, 0); |
2670 | 2670 | } |
2671 | 2671 | commBreakMap.SkipCommercials(0); |
2672 | 2672 | return; |
… |
… |
void MythPlayer::EventLoop(void) |
2684 | 2684 | if (!msg.isEmpty()) |
2685 | 2685 | SetOSDStatus(msg, kOSDTimeout_Med); |
2686 | 2686 | if (jump) |
2687 | | DoJumpToFrame(jumpto, true, true); |
| 2687 | DoJumpToFrame(jumpto, true, 0); |
2688 | 2688 | } |
2689 | 2689 | |
2690 | 2690 | // Handle cutlist skipping |
… |
… |
void MythPlayer::EventLoop(void) |
2701 | 2701 | } |
2702 | 2702 | else |
2703 | 2703 | { |
2704 | | DoJumpToFrame(jumpto, true, true); |
| 2704 | DoJumpToFrame(jumpto, true, 0); |
2705 | 2705 | } |
2706 | 2706 | } |
2707 | 2707 | } |
… |
… |
void MythPlayer::ChangeSpeed(void) |
3202 | 3202 | { |
3203 | 3203 | videoOutput->SetPrebuffering(ffrew_skip == 1); |
3204 | 3204 | if (decoder) |
3205 | | decoder->setExactSeeks(exactseeks && ffrew_skip == 1); |
| 3205 | decoder->setSeekSnap(ffrew_skip == 1 ? seeksnap : -1); |
3206 | 3206 | if (play_speed != 0.0f && !(last_speed == 0.0f && ffrew_skip == 1)) |
3207 | 3207 | DoJumpToFrame(framesPlayed + fftime - rewindtime); |
3208 | 3208 | } |
… |
… |
void MythPlayer::ChangeSpeed(void) |
3250 | 3250 | } |
3251 | 3251 | |
3252 | 3252 | bool MythPlayer::DoRewind(uint64_t frames, bool override_seeks, |
3253 | | bool seeks_wanted) |
| 3253 | uint64_t seeksnap_wanted) |
3254 | 3254 | { |
3255 | 3255 | if (player_ctx->buffer && !player_ctx->buffer->IsSeekingAllowed()) |
3256 | 3256 | return false; |
3257 | 3257 | |
3258 | 3258 | uint64_t number = frames + 1; |
3259 | 3259 | uint64_t desiredFrame = (framesPlayed > number) ? framesPlayed - number : 0; |
… |
… |
bool MythPlayer::DoRewind(uint64_t frames, bool override_seeks, |
3259 | 3259 | if (desiredFrame < video_frame_rate) |
3260 | 3260 | limitKeyRepeat = true; |
3261 | 3261 | |
3262 | | WaitForSeek(desiredFrame, override_seeks, seeks_wanted); |
| 3262 | WaitForSeek(desiredFrame, override_seeks, seeksnap_wanted); |
3263 | 3263 | rewindtime = 0; |
3264 | 3264 | ClearAfterSeek(); |
3265 | 3265 | return true; |
… |
… |
bool MythPlayer::IsNearEnd(void) |
3402 | 3402 | } |
3403 | 3403 | |
3404 | 3404 | bool MythPlayer::DoFastForward(uint64_t frames, bool override_seeks, |
3405 | | bool seeks_wanted) |
| 3405 | uint64_t seeksnap_wanted) |
3406 | 3406 | { |
3407 | 3407 | if (player_ctx->buffer && !player_ctx->buffer->IsSeekingAllowed()) |
3408 | 3408 | return false; |
3409 | 3409 | |
3410 | 3410 | uint64_t number = frames - 1; |
3411 | 3411 | uint64_t desiredFrame = framesPlayed + number; |
… |
… |
bool MythPlayer::DoFastForward(uint64_t frames, bool override_seeks, |
3414 | 3414 | desiredFrame = endcheck; |
3415 | 3415 | } |
3416 | 3416 | |
3417 | | WaitForSeek(desiredFrame, override_seeks, seeks_wanted); |
| 3417 | WaitForSeek(desiredFrame, override_seeks, seeksnap_wanted); |
3418 | 3418 | fftime = 0; |
3419 | 3419 | ClearAfterSeek(false); |
3420 | 3420 | return true; |
3421 | 3421 | } |
3422 | 3422 | |
3423 | 3423 | void MythPlayer::DoJumpToFrame(uint64_t frame, bool override_seeks, |
3424 | | bool seeks_wanted) |
| 3424 | uint64_t seeksnap_wanted) |
3425 | 3425 | { |
3426 | 3426 | if (frame > framesPlayed) |
3427 | | DoFastForward(frame - framesPlayed, override_seeks, seeks_wanted); |
| 3427 | DoFastForward(frame - framesPlayed, override_seeks, seeksnap_wanted); |
3428 | 3428 | else if (frame <= framesPlayed) |
3429 | | DoRewind(framesPlayed - frame, override_seeks, seeks_wanted); |
| 3429 | DoRewind(framesPlayed - frame, override_seeks, seeksnap_wanted); |
3430 | 3430 | } |
3431 | 3431 | |
3432 | 3432 | void MythPlayer::WaitForSeek(uint64_t frame, bool override_seeks, |
3433 | | bool seeks_wanted) |
| 3433 | uint64_t seeksnap_wanted) |
3434 | 3434 | { |
3435 | 3435 | if (!decoder) |
3436 | 3436 | return; |
3437 | 3437 | |
3438 | | bool after = exactseeks && (ffrew_skip == 1); |
3439 | | bool before = override_seeks ? seeks_wanted : |
3440 | | (allpaused && !deleteMap.IsEditing()) ? true: after; |
3441 | | decoder->setExactSeeks(before); |
| 3438 | uint64_t after = (ffrew_skip == 1) ? seeksnap : -1; |
| 3439 | uint64_t before = override_seeks ? seeksnap_wanted : |
| 3440 | (allpaused && !deleteMap.IsEditing()) ? 0: after; |
| 3441 | decoder->setSeekSnap(before); |
3442 | 3442 | |
3443 | 3443 | bool islivetvcur = (livetv && player_ctx->tvchain && |
3444 | 3444 | !player_ctx->tvchain->HasNext()); |
… |
… |
void MythPlayer::WaitForSeek(uint64_t frame, bool override_seeks, |
3480 | 3480 | osd->HideWindow("osd_message"); |
3481 | 3481 | osdLock.unlock(); |
3482 | 3482 | } |
3483 | | decoder->setExactSeeks(after); |
| 3483 | decoder->setSeekSnap(after); |
3484 | 3484 | } |
3485 | 3485 | |
3486 | 3486 | /** \fn MythPlayer::ClearAfterSeek(bool) |
… |
… |
void MythPlayer::ClearAfterSeek(bool clearvideobuffers) |
3519 | 3519 | } |
3520 | 3520 | |
3521 | 3521 | void MythPlayer::SetPlayerInfo(TV *tv, QWidget *widget, |
3522 | | bool frame_exact_seek, PlayerContext *ctx) |
| 3522 | uint64_t frame_seek_snap, PlayerContext *ctx) |
3523 | 3523 | { |
3524 | 3524 | deleteMap.SetPlayerContext(ctx); |
3525 | 3525 | m_tv = tv; |
3526 | 3526 | parentWidget = widget; |
3527 | | exactseeks = frame_exact_seek; |
| 3527 | seeksnap = frame_seek_snap; |
3528 | 3528 | player_ctx = ctx; |
3529 | 3529 | livetv = ctx->tvchain; |
3530 | 3530 | } |
… |
… |
bool MythPlayer::HandleProgramEditorActions(QStringList &actions, |
3607 | 3607 | { |
3608 | 3608 | QString action = actions[i]; |
3609 | 3609 | handled = true; |
| 3610 | int seekamount = deleteMap.GetSeekAmount(); |
3610 | 3611 | if (action == ACTION_LEFT) |
3611 | 3612 | { |
3612 | 3613 | if (deleteMap.GetSeekAmount() > 0) |
3613 | 3614 | { |
3614 | | DoRewind(deleteMap.GetSeekAmount(), true, true); |
| 3615 | DoRewind(seekamount, true, seekamount > 1 ? seekamount / 2 : 0); |
3615 | 3616 | } |
3616 | 3617 | else |
3617 | 3618 | HandleArbSeek(false); |
… |
… |
bool MythPlayer::HandleProgramEditorActions(QStringList &actions, |
3620 | 3621 | { |
3621 | 3622 | if (deleteMap.GetSeekAmount() > 0) |
3622 | 3623 | { |
3623 | | DoFastForward(deleteMap.GetSeekAmount(), true, true); |
| 3624 | DoFastForward(seekamount, true, seekamount > 1 ? seekamount / 2 : 0); |
3624 | 3625 | } |
3625 | 3626 | else |
3626 | 3627 | HandleArbSeek(true); |
… |
… |
bool MythPlayer::HandleProgramEditorActions(QStringList &actions, |
3651 | 3652 | #define FFREW_MULTICOUNT 10 |
3652 | 3653 | else if (action == ACTION_BIGJUMPREW) |
3653 | 3654 | { |
3654 | | if (deleteMap.GetSeekAmount() > 0) |
3655 | | DoRewind(deleteMap.GetSeekAmount() * FFREW_MULTICOUNT, |
3656 | | true, true); |
| 3655 | if (seekamount > 0) |
| 3656 | DoRewind(seekamount * FFREW_MULTICOUNT, |
| 3657 | true, seekamount > 1 ? seekamount * FFREW_MULTICOUNT / 2: 0); |
3657 | 3658 | else |
3658 | 3659 | { |
3659 | 3660 | int fps = (int)ceil(video_frame_rate); |
3660 | | DoRewind(fps * FFREW_MULTICOUNT / 2, true, true); |
| 3661 | DoRewind(fps * FFREW_MULTICOUNT / 2, true, 0); |
3661 | 3662 | } |
3662 | 3663 | } |
3663 | 3664 | else if (action == ACTION_BIGJUMPFWD) |
3664 | 3665 | { |
3665 | | if (deleteMap.GetSeekAmount() > 0) |
3666 | | DoFastForward(deleteMap.GetSeekAmount() * FFREW_MULTICOUNT, |
3667 | | true, true); |
| 3666 | if (seekamount > 0) |
| 3667 | DoFastForward(seekamount * FFREW_MULTICOUNT, |
| 3668 | true, seekamount > 1 ? seekamount * FFREW_MULTICOUNT / 2: 0); |
3668 | 3669 | else |
3669 | 3670 | { |
3670 | 3671 | int fps = (int)ceil(video_frame_rate); |
3671 | | DoFastForward(fps * FFREW_MULTICOUNT / 2, true, true); |
| 3672 | DoFastForward(fps * FFREW_MULTICOUNT / 2, true, 0); |
3672 | 3673 | } |
3673 | 3674 | } |
3674 | 3675 | else if (action == ACTION_SELECT) |
… |
… |
void MythPlayer::HandleArbSeek(bool right) |
3769 | 3770 | long long framenum = deleteMap.GetNearestMark(framesPlayed, |
3770 | 3771 | totalFrames, right); |
3771 | 3772 | if (right && (framenum > (int64_t)framesPlayed)) |
3772 | | DoFastForward(framenum - framesPlayed, true, true); |
| 3773 | DoFastForward(framenum - framesPlayed, true, 0); |
3773 | 3774 | else if (!right && ((int64_t)framesPlayed > framenum)) |
3774 | | DoRewind(framesPlayed - framenum, true, true); |
| 3775 | DoRewind(framesPlayed - framenum, true, 0); |
3775 | 3776 | } |
3776 | 3777 | else |
3777 | 3778 | { |
… |
… |
void MythPlayer::HandleArbSeek(bool right) |
3782 | 3783 | // the position map uses MARK_GOP_BYFRAME. (see DecoderBase) |
3783 | 3784 | float editKeyFrameDist = keyframedist <= 2 ? 18 : keyframedist; |
3784 | 3785 | |
3785 | | DoFastForward((long long)(editKeyFrameDist * 1.1), true, false); |
| 3786 | DoFastForward((long long)(editKeyFrameDist * 1.1), true, -1); |
3786 | 3787 | } |
3787 | 3788 | else |
3788 | 3789 | { |
3789 | | DoRewind(2, true, false); |
| 3790 | DoRewind(2, true, -1); |
3790 | 3791 | } |
3791 | 3792 | } |
3792 | 3793 | } |
… |
… |
VideoFrame* MythPlayer::GetRawVideoFrame(long long frameNumber) |
4115 | 4116 | |
4116 | 4117 | if (frameNumber >= 0) |
4117 | 4118 | { |
4118 | | DoJumpToFrame(frameNumber, true, true); |
| 4119 | DoJumpToFrame(frameNumber, true, 0); |
4119 | 4120 | ClearAfterSeek(); |
4120 | 4121 | } |
4121 | 4122 | |
… |
… |
void MythPlayer::InitForTranscode(bool copyaudio, bool copyvideo) |
4200 | 4201 | if (copyaudio && decoder) |
4201 | 4202 | decoder->SetRawAudioState(true); |
4202 | 4203 | |
4203 | | SetExactSeeks(true); |
| 4204 | SetSeekSnap(0); |
4204 | 4205 | if (decoder) |
4205 | 4206 | { |
4206 | | decoder->setExactSeeks(exactseeks); |
| 4207 | decoder->setSeekSnap(seeksnap); |
4207 | 4208 | decoder->SetLowBuffers(true); |
4208 | 4209 | } |
4209 | 4210 | } |
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h
index 8415fca..6e7f026 100644
a
|
b
|
class MTV_PUBLIC MythPlayer |
116 | 116 | bool InitVideo(void); |
117 | 117 | |
118 | 118 | // Public Sets |
119 | | void SetPlayerInfo(TV *tv, QWidget *widget, bool frame_exact_seek, |
| 119 | void SetPlayerInfo(TV *tv, QWidget *widget, uint64_t frame_seek_snap, |
120 | 120 | PlayerContext *ctx); |
121 | 121 | void SetNullVideo(void) { using_null_videoout = true; } |
122 | | void SetExactSeeks(bool exact) { exactseeks = exact; } |
| 122 | void SetSeekSnap(uint64_t snap) { seeksnap = snap; } |
123 | 123 | void SetLength(int len) { totalLength = len; } |
124 | 124 | void SetFramesPlayed(uint64_t played); |
125 | 125 | void SetVideoFilters(const QString &override); |
… |
… |
class MTV_PUBLIC MythPlayer |
490 | 490 | // These actually execute commands requested by public members |
491 | 491 | virtual void ChangeSpeed(void); |
492 | 492 | bool DoFastForward(uint64_t frames, bool override_seeks = false, |
493 | | bool seeks_wanted = false); |
| 493 | uint64_t seeksnap_wanted = -1); |
494 | 494 | bool DoRewind(uint64_t frames, bool override_seeks = false, |
495 | | bool seeks_wanted = false); |
| 495 | uint64_t seeksnap_wanted = -1); |
496 | 496 | void DoJumpToFrame(uint64_t frame, bool override_seeks = false, |
497 | | bool seeks_wanted = false); |
| 497 | uint64_t seeksnap_wanted = -1); |
498 | 498 | |
499 | 499 | // Private seeking stuff |
500 | 500 | void WaitForSeek(uint64_t frame, bool override_seeks = false, |
501 | | bool seeks_wanted = false); |
| 501 | uint64_t seeksnap_wanted = -1); |
502 | 502 | void ClearAfterSeek(bool clearvideobuffers = true); |
503 | 503 | |
504 | 504 | // Private chapter stuff |
… |
… |
class MTV_PUBLIC MythPlayer |
588 | 588 | /// If fftime>0, number of frames to seek forward. |
589 | 589 | /// If fftime<0, number of frames to seek backward. |
590 | 590 | long long fftime; |
591 | | /// Iff true we ignore seek amount and try to seek to an |
592 | | /// exact frame ignoring key frame restrictions. |
593 | | bool exactseeks; |
| 591 | /// When seeking, snap to a key frame if the target is within |
| 592 | /// seeksnap frames. Use seeksnap=0 for exact seeks, |
| 593 | /// seeksnap=-1 for completely non-exact seeks. |
| 594 | uint64_t seeksnap; |
594 | 595 | |
595 | 596 | // Playback misc. |
596 | 597 | /// How often we have tried to wait for a video output buffer and failed |
diff --git a/mythtv/programs/mythcommflag/PrePostRollFlagger.cpp b/mythtv/programs/mythcommflag/PrePostRollFlagger.cpp
index cc9f921..b21c8c9 100644
a
|
b
|
PrePostRollFlagger::PrePostRollFlagger(SkipType commDetectMethod, |
26 | 26 | void PrePostRollFlagger::Init() |
27 | 27 | { |
28 | 28 | ClassicCommDetector::Init(); |
29 | | player->SetExactSeeks(true); |
| 29 | player->SetSeekSnap(0); |
30 | 30 | } |
31 | 31 | |
32 | 32 | bool PrePostRollFlagger::go() |
… |
… |
long long PrePostRollFlagger::findBreakInrange(long long startFrame, |
230 | 230 | player->DiscardVideoFrame(player->GetRawVideoFrame(0)); |
231 | 231 | |
232 | 232 | long long tmpStartFrame = startFrame; |
233 | | player->SetExactSeeks(true); |
| 233 | player->SetSeekSnap(0); |
234 | 234 | VideoFrame* f = player->GetRawVideoFrame(tmpStartFrame); |
235 | 235 | float aspect = player->GetVideoAspect(); |
236 | 236 | currentFrameNumber = f->frameNumber; |