Fix subtask annotation on multi-episode-per-file (LeRobot v3) videos: clip-relative frame timestamps#229
Conversation
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Code Review
This pull request updates the video decoding logic to report frame timestamps relative to the clip start, adjusting the test assertions accordingly. The reviewer pointed out that while timestamp_s is rebased, pts remains absolute, which introduces an inconsistency. Additionally, they noted that a frame slightly before clip_from could yield a negative timestamp, and suggested clamping both timestamp_s and pts to be non-negative to prevent this.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Rebase pts to the clip start alongside timestamp_s and clamp both to non-negative, matching VideoFrameSequence/VideoFrameArray.
Tomás Duarte (tomas-duarte)
left a comment
There was a problem hiding this comment.
Hello Binh Pham (@pham-tuan-binh), thank you a lot for the bug report and the PR!
This looks good, it's a pretty straightforward change.
Besides the small comment I left on the diff, I'm just not 100% sure on subtracting clip_from instead of the first frame's time. As is, you can run into potentially weird timing issues if the first frame you get doesn't exactly match the clip timestamp; i.e. you might not get 0.0 on the first frame. I'm also thinking we should perhaps sync dts as well, otherwise stuff might break in unexpected ways?
On another note, rebasing our wrapper timestamp_s, then rebasing pts might be unnecessary, as _frame_timestamp_s is essentially how the frame.time property is computed anyway. Then again, this was already there.
Tomorrow, I will take a more thorough look at what to do, and will look at how libavfilter implements the trim and setpts filters we know from ffmpeg.
If we wanted, though, we could also merge this sooner and do an improvement pass on the video internals later, I guess.
|
I ended up tweaking and merging this with #230, as I could not push a new commit onto this PR branch, even though it's supposedly editable... |
Behavior
When a
VideoFileis decoded with a clip window (from_timestamp_s/to_timestamp_s),iter_encoded_framesreturns timestamps relative to thewhole video file, not to the clip.
This is what
test_iter_frames_respects_clip_boundsasserts today: a clipstarting at
from_timestamp_s=0.2yields frame timestamps[0.2, 0.4, 0.6]instead of
[0.0, 0.2, 0.4].Impact
A LeRobot v3 dataset bundles multiple episodes into one video file, so each
episode is a clip with
from_timestamp > 0. With the current behavior, decodingan episode returns video-wide timestamps, not episode timestamps.
robotics.subtask_annotationrelies on episode-relative time, so on v3 datasetsit produces segments on the video clock (which don't match the episode's
timestampcolumn) — dropping segments for every episode except the first onein each video file.
Fix
Rebase yielded timestamps to the clip start in
iter_encoded_frames(subtractclip_fromonce)._frame_timestamp_sstays absolute. No-op for unclipped videos(
clip_from == 0), and bringsVideoFilein line with the in-memory sources.Updated
test_iter_frames_respects_clip_boundsto expect[0.0, 0.2, 0.4].Question
Is this behavior expected? That a segmented video would return absolute timestamp instead of relative timestamps?