command: add sub-snap flag to the seek command - #18409
Open
feldgendler wants to merge 2 commits into
Open
Conversation
Return the PTS of the most recent packet read from the demuxer, in the subtitle timebase. It is only meaningful compared against itself, as a measure of how far the decoder has advanced. The next commit uses it to wait until a region has actually been decoded.
On a relative seek, snap to the start of the next or previous primary subtitle event if it is within the requested amount; otherwise, or when subtitles are hidden or disabled, do an ordinary relative seek. Unlike sub-seek, it never jumps farther than the given amount. The adjacent event is found with SD_CTRL_SUB_STEP, which only sees what the decoder has already read, so "no event within the amount" has to be told apart from "not decoded yet"; only the latter is waited for. handle_sub_snap() drives the decoder from the playloop instead of blocking the core. A backward snap needs the region behind the play position, which cannot be read ahead, so the demuxer alone is rewound while playback stays put. That is done only while paused, since the demuxer is shared with the other streams. Repeated presses accumulate into one chain instead of each recomputing a target, because input is drained in batches and a seek queued with MPSEEK_FLAG_DELAY can still be pending. The chain starts from the target of a pending seek rather than from the play position, so that it composes with seeks issued in the same batch instead of replacing them. Tested with SRT and embedded ASS, with --sub-delay and --sub-speed set both ways, and with unrelated seeks queued in the same batch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
seek <amount> sub-snapis a relative seek that lands on the start of the next or previous primary subtitle event when one falls within<amount>seconds, and does an ordinary relative seek otherwise. It is meant to replace the plain relative seek on the arrow keys rather than to sit beside it as one more binding: because it never travels farther than the amount asked for, it does exactly what the seek it replaces would have done wherever no subtitle is in range.Seeking back a few seconds during dialogue is nearly always an attempt to hear or read one line again. A plain
seek -5lands mid-sentence, so the line has to come round a second time before it is heard whole, andsub-seek -1jumps to whatever event happens to be previous, which across a silent stretch can be a minute away — which is also why it cannot serve as the everyday seek key. Withsub-snapbound to left and right there is nothing to decide before pressing: in dialogue it replays the line from its start, elsewhere it seeks. My own arrow keys have been bound to it since I wrote it and I have not wanted the plain seek back. Language learners are the obvious audience, since repeating individual lines is most of the activity, but this is what anyone rewinding to catch a mumbled line is reaching for.A script can approximate this with
sub-seekfollowed by a correction seek, but the correction is a second visible jump, and it cannot tell "there is no event within the amount" from "the decoder has not read that far yet". Only the latter is worth waiting for; conflating them makes holding the key down in a gap stall instead of seeking.SD_CTRL_SUB_STEPsees only what has been decoded, and how far that reaches is not exposed to scripts. Key repeat is the other half of it: input is drained in batches, so a script doing a property round-trip per press collapses a burst into one step.The wait is driven from the playloop by
handle_sub_snap()rather than blocking the core. A backward snap needs the region behind the play position, which cannot be read ahead, so the demuxer alone is rewound while playback stays put, and only while paused, since it is shared with the other streams. Repeated presses accumulate into one chain, and the chain starts from the target of a pending seek instead of the play position, so it composes with seeks issued in the same batch rather than replacing them.The manual gives the limits. Like
sub-seek, this only works with events already displayed or within the prefetch range, except that a backward snap also looks behind the play position while paused. It is ignored for the other seek modes and with--play-dir=backward. Whenever the event is not available it falls back to an ordinary relative seek, so it never blocks or waits visibly — it just stops snapping.Tested with external SRT, embedded ASS and PGS from a Blu-ray rip: bursts of one to four presses from several start positions, forward and backward, on a short file and a ten-minute one;
--sub-delayboth signs and--sub-speedat 0.5 and 2; subtitles hidden, disabled, and present only as a secondary track;--play-dir=backward; twenty-five presses of key-repeat scrubbing through a gap, compared against a plain seek; and unrelated seeks queued in the same input batch, checked against the result without the flag.Written with AI assistance, and reviewed with AI tooling. I take full responsibility for the code: I understand what it changes and why, I have tested it myself, I will respond to review in my own words, and it can be submitted under the same license as the files it touches.