-
Notifications
You must be signed in to change notification settings - Fork 566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Time-index conversion isues #1384
Conversation
@ferdnyc - This is really great thanks! |
After some further experimentation, I now believe I was wrong about this, at least for the "ideal" case where the frame-rate of the clip matches the project profile frame-rate, so that all operations are being done on a clip frame boundary. For the case where framerates don't match, it does seem that slicing can at times double a frame, but I'm not sure that's really a completely solvable problem. Frame-rate mismatches are a tricky thing to deal with at the best of times. This applies only to the Slice tool's "keep both sides" function, not to the Split Clip tool frame-shift issues that @peanutbutterandcrackers reported in #1369. I'm still seeing that — in my testing, the resulting clip both starts and ends one frame before the frames chosen. |
Oof, hokay. This is a tricky one. Yes, OpenShot can double a frame on slicing, even if the frame rates match between the clip and the project. It can also drop a frame. And the Split Clip tool will sometimes start with the frame before the selected one, when added to the timeline. But OpenShot isn't doing anything wrong, math-wise. The issue seems to have something to do with certain unpredictabilities in the way frame boundaries work, when decoding the video. Say I have a 25fps video, in a 25fps project. Each frame is therefore 0.04 seconds long (1/25 of a second). So, theoretically, frame 2 should start at 0.04s, frame 3 at 0.08s, and so on. That's the math OpenShot uses. But sometimes, when setting the Start of a clip to certain frame positions, the previous frame will "sneak in". For instance, if I set the Start position to 0.80s, which is supposed to be frame 20, the clip might actually start with frame 19, same as if I'd set Start=0.76. But if I set Start=0.84s, it's frame 21! The only way to get frame 20 to be the first frame, in those cases, is by setting Start to a value between 0.77 and 0.79 — but then you've misaligned the clip timing with the project/playhead time and frame boundaries, which can cause a whole host of other problems either immediately or down the road. And worst of all, there doesn't seem to be any completely-reliable way to predict which frames might be slightly "late", in order to automatically correct for it. For the "Slice: Keep both sides" functionality, it might be possible to have the resulting two clips overlapped by a half-frame on either side, or something. That may allow them to stay aligned to frame boundaries on the timeline, but still better protect OpenShot against late-frame issues. But for the "Split Clip" tool, I really don't know how to deal with this, except by disclaiming that frame-accuracy is a hard problem to solve and occasionally things may slip a frame here or there. But it doesn't appear that OpenShot is doing anything wrong with the math, for these instances. It's using all of the right numbers, it's just that sometimes reality doesn't exactly conform to the math. |
Yeah, this is a tricky issue indeed. Many things in OpenShot use a double precision floating point for time/position. And because that precision is far more precise than 0.04 seconds, it's possible to create some crazy rounding issues. And even rounding to the nearest 0.04 frame position would not help in cases where you change the framerate, breaking everything again. I'll continue to think about this one. =) |
Oh, BTW: Given that the remaining issues appear to be more complex than what I've tackled so far, and I'm now more confident that this commit does sort out the Marker and Keyframe positioning issues, it's probably good to go for merging (if it checks out with you, of course). I expect anything else to be done will take a large enough change that it wouldn't make sense to lump those commit(s) in here. |
@jonoomph - Can you test this when you have a chance? Possibly good for merging. |
Thanks for the PR, looks awesome! |
Merged |
@jonoomph : Do you have any thoughts on the 0- vs. 1-based frame indexing question? (See #1426, probably others.) The fact that every conversion from time index to frame# involves adding or subtracting a 1 has made me sympathetic to the idea that 0-based is more natural, so I've been toying with the idea of doing the work necessary to go through all of the code and convert to 0-based frame numbers throughout. There are really only two things that give me pause:
|
This is a
work-in-progressfirst-attempt PR, which I believe is complete as to the changes needed for the Marker/Keyframe positioning issue, but is certainly incomplete in terms of addressing all timing/frame-sync issues. (See below for considerable further discussion/developments, but long-and-short I think this fixes the problem of Markers being positioned off by 1 frame, and Keyframe tickmarks being drawn one frame off from where they actually are.)I'm posting where I'm at so that others might have a chance to test the changes so far, confirm that things seem to be moving in the right direction, and identify remaining issues stemming from time-index off-by-one errors.
The issues that have been reported with marker/keyframe positioning, clip boundaries, and etc. seem to mostly be manifestations of two issues:
Conversion between frame# and time index is performed inconsistently in the code.
Because time-indexes originate at 0 seconds, but frames are counted from 1, every conversion from time-based position to linear (counted) position, in either direction, has to account for this. And the code contains dozens of separate places where this conversion is performed, ad hoc.
pixelsPerSecond
, after computing that based on the zoom level. When the math is being done from a time index, or uses a time duration, frames-per-second is uninvolved and you get math such as:(point - 1)
was not being performed.This PR thus contains, so far, one commit which patches two files, attempting to ensure that the code will "Always compute time as (frame# - 1) / fps".
Interpolated parameters store keyframe positions as frame numbers
This issue is the source of much of the above complexity. While it's in some senses easier to store raw frame numbers, when positioning timeline elements, the problem is that frame number is dependent on the frame rate of the video, so altering the frames-per-second value changes the position of every frame except the first. Most users working with video want frame accuracy in operations, but they want positioning to be independent of frame rate so that, if they place a timeline element at the 1-second mark, that's automatically adjusted to frame 25 @ 24fps, frame 30 @ 29.97 fps, frame 31 @ 30fps, and frame 61 @ 60fps.
This PR does not address, or even attempt to address, this more-fundamental issue. (See bug #1034, and others, for reports of problems related to frame-based positioning.)
Other, possibly-related, issues
There are other time-indexing issues still present in the code.
This is because the
Start
parameter of the right clip is set to the same time-index as the left clip'sEnd
parameter, whenright.Start
should beleft.End + (1 / fps)
(or bothleft.End
andleft.Duration
should be decreased by1/fps
). My changes here don't address this, though with the keyframe-positioning updates I believe they may make the incorrect slice positioning more obvious.