Quality: Invalid frame index calculation can seek to -1 or out-of-range frames by Nam0101 · Pull Request #1790 · hacksider/Deep-Live-Cam · GitHub
Skip to content

Quality: Invalid frame index calculation can seek to -1 or out-of-range frames#1790

Open
Nam0101 wants to merge 1 commit into
hacksider:mainfrom
Nam0101:contribai/improve/quality/invalid-frame-index-calculation-can-seek
Open

Quality: Invalid frame index calculation can seek to -1 or out-of-range frames#1790
Nam0101 wants to merge 1 commit into
hacksider:mainfrom
Nam0101:contribai/improve/quality/invalid-frame-index-calculation-can-seek

Conversation

@Nam0101

@Nam0101 Nam0101 commented Apr 27, 2026

Copy link
Copy Markdown

✨ Code Quality

Problem

get_video_frame() computes the seek position as min(frame_total, frame_number - 1). With the default frame_number=0, this becomes -1 (invalid frame index). For large requested frame numbers, it can also become frame_total (also invalid, since last valid frame is frame_total - 1). This causes intermittent failed reads (has_frame=False) and breaks callers that expect a valid first frame by default.

Severity: high
File: modules/capturer.py

Solution

Clamp to a valid range explicitly and avoid negative/out-of-bounds indices:
frame_total = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
if frame_total <= 0: capture.release() return None
# keep 1-based API: frame_number=1 -> first frame target_index = 0 if frame_number <= 1 else min(frame_total - 1, frame_number - 1) capture.set(cv2.CAP_PROP_POS_FRAMES, target_index)

Changes

  • modules/capturer.py (modified)

Testing

  • Existing tests pass
  • Manual review completed
  • No new warnings/errors introduced


🤖 About this PR

This pull request was generated by ContribAI, an AI agent
that helps improve open source projects. The change was:

  1. Discovered by automated code analysis
  2. Generated by AI with context-aware code generation
  3. Self-reviewed by AI quality checks

If you have questions or feedback about this PR, please comment below.
We appreciate your time reviewing this contribution!

Closes #1789

Summary by Sourcery

Bug Fixes:

  • Prevent get_video_frame from seeking to negative or out-of-range frame indices, ensuring the default call returns a valid first frame and large frame requests clamp to the last valid frame.

…nge frames

`get_video_frame()` computes the seek position as `min(frame_total, frame_number - 1)`. With the default `frame_number=0`, this becomes `-1` (invalid frame index). For large requested frame numbers, it can also become `frame_total` (also invalid, since last valid frame is `frame_total - 1`). This causes intermittent failed reads (`has_frame=False`) and breaks callers that expect a valid first frame by default.


Affected files: capturer.py

Signed-off-by: Nguyen Van Nam <nam.nv205106@gmail.com>
@sourcery-ai

sourcery-ai Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The frame_number parameter is effectively 1-based after this change (0 and 1 both map to the first frame); consider either making the default explicitly 1 or clarifying/standardizing its semantics across callers to avoid confusion.
  • The target_index calculation can be simplified to a single clamp expression like target_index = max(0, min(frame_total - 1, frame_number - 1)), which makes the valid range and intent clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `frame_number` parameter is effectively 1-based after this change (0 and 1 both map to the first frame); consider either making the default explicitly `1` or clarifying/standardizing its semantics across callers to avoid confusion.
- The `target_index` calculation can be simplified to a single clamp expression like `target_index = max(0, min(frame_total - 1, frame_number - 1))`, which makes the valid range and intent clearer.

## Individual Comments

### Comment 1
<location path="modules/capturer.py" line_range="17" />
<code_context>

-    frame_total = capture.get(cv2.CAP_PROP_FRAME_COUNT)
-    capture.set(cv2.CAP_PROP_POS_FRAMES, min(frame_total, frame_number - 1))
+    frame_total = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
+    if frame_total <= 0:
+        capture.release()
</code_context>
<issue_to_address>
**issue:** Casting CAP_PROP_FRAME_COUNT to int directly can raise if the backend returns NaN.

Some OpenCV backends return NaN or other non-finite values for `CAP_PROP_FRAME_COUNT` on failure, and `int(float('nan'))` raises `ValueError`. To preserve the previous graceful `None` behavior instead of raising, read the raw value first, check for `None`/NaN/non-finite/negative (e.g. via `math.isfinite`), and only cast to `int` when it’s a valid non-negative frame count.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread modules/capturer.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue: Casting CAP_PROP_FRAME_COUNT to int directly can raise if the backend returns NaN.

Some OpenCV backends return NaN or other non-finite values for CAP_PROP_FRAME_COUNT on failure, and int(float('nan')) raises ValueError. To preserve the previous graceful None behavior instead of raising, read the raw value first, check for None/NaN/non-finite/negative (e.g. via math.isfinite), and only cast to int when it’s a valid non-negative frame count.

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.

fix: invalid frame index calculation can seek to -1 or out-of-range frames

1 participant