Skip to content

Decode video frames at the publish rate, not the stream rate - #106

Merged
leandropineda merged 1 commit into
fix/video-capture-recoveryfrom
perf/video-decode-throttle
Jul 29, 2026
Merged

Decode video frames at the publish rate, not the stream rate#106
leandropineda merged 1 commit into
fix/video-capture-recoveryfrom
perf/video-decode-throttle

Conversation

@leandropineda

Copy link
Copy Markdown
Member

Stacked on #105.

Two costs in the capture loop:

  • it held capture_mutex across every grab(), so get_frame_jpg() waited on the lock at each publish — with a blocking network grab in between, publishing starved for seconds;
  • retrieve() ran per publish on frames grab() had already decoded, paying the YUV→BGR conversion and copy twice (4.5ms vs 7.1ms per frame at 1080p — 13.5% vs 21.3% of a core at 30fps).

Now only the capture thread touches self.capture, so the loop takes no lock: it drains with grab() and converts into a buffer at twice the publish rate. get_frame_jpg() encodes the buffer and never touches the capture. Frame size comes from the frame instead of two CAP_PROP queries per publish.

Tests: 1 new case (grabs >> retrieves; publishing doesn't touch the capture). Suite: 149 passed, flake8/black clean.

The grab loop held capture_mutex across every grab(), so get_frame_jpg()
had to wait for the lock on each publish -- with a blocking network grab
in between, that starved publishing for seconds at a time. And retrieve()
ran once per publish on a capture whose every frame had already been
decoded, paying the YUV->BGR conversion and copy again (4.5ms vs 7.1ms
per frame at 1080p: 13.5% vs 21.3% of a core at 30fps).

Only the capture thread touches self.capture now, so the grab loop takes
no lock: it drains the stream with grab() and converts a frame into a
buffer at twice the publish rate. get_frame_jpg() encodes whatever is in
the buffer and never touches the capture. Frame size comes from the frame
itself instead of two CAP_PROP queries per publish.

Tests: 1 new case in test_video.py (grabs >> retrieves, publishing does
not touch the capture).

@miguelgarcia miguelgarcia left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one comment, then LGTM

Comment thread inorbit_edge/video.py
@leandropineda
leandropineda merged commit 3247ba7 into fix/video-capture-recovery Jul 29, 2026
@leandropineda
leandropineda deleted the perf/video-decode-throttle branch July 29, 2026 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants