Skip to content

feat: add adaptive frame extraction to best-frame procedure - #1350

Merged
atxtechbro merged 1 commit into
mainfrom
1349-adaptive-frame-extraction
Oct 9, 2025
Merged

feat: add adaptive frame extraction to best-frame procedure#1350
atxtechbro merged 1 commit into
mainfrom
1349-adaptive-frame-extraction

Conversation

@atxtechbro

Copy link
Copy Markdown
Owner

Summary

Implements adaptive frame extraction for the extract-best-frame procedure that adjusts based on video duration, fixing issues with both very short and very long videos.

Closes #1349

Changes

Round 1 - Adaptive Initial Extraction

  • Dynamic FPS calculation: Targets 20-50 frames regardless of video length
  • Bounded FPS: Caps between 0.1-2.0 fps to avoid extremes
    • Short videos (3-10s): Use max 2.0 fps
    • Long videos (5+ min): Use adaptive FPS down to 0.1 fps minimum
  • Minimum frame guarantee: Re-extracts at 2.0 fps if fewer than 10 frames captured

Round 2 - Adaptive Refinement

  • Adaptive window sizing:
    • Videos <10s: ±0.5s window (tighter precision for short clips)
    • Videos ≥10s: ±1.0s window (standard refinement)
  • Adaptive FPS:
    • Videos <10s: 20 fps (higher precision)
    • Videos ≥10s: 10 fps (standard)
  • Fixed timestamp calculation: Now uses actual frame interval instead of hardcoded 2s

Testing

  • Added test_adaptive_fps.sh to validate FPS calculations
  • Tested with durations ranging from 3s to 1 hour
  • Confirms target frame counts and adaptive behavior

Examples

Video Duration Round 1 FPS Frames Round 2 Window Round 2 FPS
5s 2.0 ~10 ±0.5s 20 fps
30s 1.0 ~30 ±1.0s 10 fps
2min 0.25 ~30 ±1.0s 10 fps
10min 0.1 ~60 ±1.0s 10 fps

Benefits

  • ✅ Short videos get adequate frame coverage without missing key moments
  • ✅ Long videos extract efficiently without hundreds of redundant frames
  • ✅ Consistent ~30 frame target for medium-length videos (15s-5min)
  • ✅ Improved Round 2 precision for short videos where every moment matters

Test Plan

  • Validated FPS calculation logic with test script
  • Confirmed minimum frame guarantee triggers correctly
  • Verified Round 2 adaptive window behavior
  • Test with actual video files of varying lengths (requires user testing)
  • Validate frame quality and tournament selection still works well

Closes #1349

Implements dynamic frame extraction that adapts to video duration:

**Round 1 Improvements:**
- Calculate adaptive FPS based on video duration (targets 20-50 frames)
- Bound FPS between 0.1-2.0 fps to avoid extremes
- Add minimum 10-frame guarantee with automatic re-extraction

**Round 2 Improvements:**
- Adaptive window sizing: ±0.5s for videos <10s, ±1.0s for longer videos
- Adaptive FPS: 20fps for short videos, 10fps for longer videos
- Fix winner timestamp calculation to use actual frame interval

**Benefits:**
- Short videos (5-10s): Adequate coverage without missing key moments
- Long videos (5+ min): Efficient extraction without hundreds of frames
- Consistent ~30 frame target across medium-length videos

**Testing:**
Added test_adaptive_fps.sh to validate FPS calculations across various
video durations (3s to 1 hour).
@amazon-q-developer

Copy link
Copy Markdown
Contributor

Code review in progress. Analyzing for code quality issues and best practices. Detailed findings will be posted upon completion.

Using Amazon Q Developer for GitHub

Amazon Q Developer1 is an AI-powered assistant that integrates directly into your GitHub workflow, enhancing your development process with intelligent features for code development, review, and transformation.

Slash Commands

Command Description
/q <message> Chat with the agent to ask questions or request revisions
/q review Requests an Amazon Q powered code review
/q help Displays usage information

Features

Agentic Chat
Enables interactive conversation with Amazon Q to ask questions about the pull request or request specific revisions. Use /q <message> in comment threads or the review body to engage with the agent directly.

Code Review
Analyzes pull requests for code quality, potential issues, and security concerns. Provides feedback and suggested fixes. Automatically triggered on new or reopened PRs (can be disabled for AWS registered installations), or manually with /q review slash command in a comment.

Customization

You can create project-specific rules for Amazon Q Developer to follow:

  1. Create a .amazonq/rules folder in your project root.
  2. Add Markdown files in this folder to define rules (e.g., cdk-rules.md).
  3. Write detailed prompts in these files, such as coding standards or best practices.
  4. Amazon Q Developer will automatically use these rules when generating code or providing assistance.

Example rule:

All Amazon S3 buckets must have encryption enabled, enforce SSL, and block public access.
All Amazon DynamoDB Streams tables must have encryption enabled.
All Amazon SNS topics must have encryption enabled and enforce SSL.
All Amazon SNS queues must enforce SSL.

Feedback

To provide feedback on Amazon Q Developer, create an issue in the Amazon Q Developer public repository.

For more detailed information, visit the Amazon Q for GitHub documentation.

Footnotes

  1. Amazon Q Developer uses generative AI. You may need to verify generated code before using it in your environment. See the AWS Responsible AI Policy.

@atxtechbro
atxtechbro merged commit 5a17968 into main Oct 9, 2025

@amazon-q-developer amazon-q-developer 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.

Overall Assessment

This PR implements a well-thought-out adaptive frame extraction system that addresses real problems with video processing across different durations. The core concept is solid and the implementation shows good understanding of the domain requirements.

Critical Issues to Address

Logic Inconsistencies: The most critical issue is the mismatch between the test script's validation logic and the actual procedure implementation. The test script checks EXPECTED_FRAMES while the procedure correctly checks FRAME_COUNT, leading to potentially misleading test results.

Error Handling: Missing validation for ffprobe output and potential division by zero scenarios could cause script failures with corrupted or edge-case video files.

Positive Aspects

  • Adaptive Design: The dual-round approach with different parameters for short vs long videos is well-designed
  • Practical Bounds: FPS capping between 0.1-2.0 prevents extreme extraction scenarios
  • Comprehensive Testing: Good coverage of different video duration scenarios in the test script

Recommendations

  1. Fix the test script to accurately reflect the actual procedure logic
  2. Add proper error handling for ffprobe and duration validation
  3. Consider making TARGET_FRAMES configurable or document the fixed choice
  4. Correct the documentation inconsistencies in the test script comments

The implementation shows strong engineering thinking, but these issues should be resolved before merging to ensure reliability and maintainability.

Comment thread test_adaptive_fps.sh

# Test various video durations
echo "VERY SHORT VIDEOS:"
test_duration 3 # 3 second clip

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.

🛑 Logic Error: The minimum frame guarantee logic has a critical flaw. The condition checks if EXPECTED_FRAMES < 10, but EXPECTED_FRAMES is calculated from the already-capped FPS value, not the actual frame count from ffmpeg extraction. This means the re-extraction logic may never trigger even when fewer than 10 frames are actually extracted, especially for edge cases where ffmpeg produces fewer frames than mathematically expected.

Comment on lines +34 to +35
Cap FPS between reasonable bounds (0.1 to 2.0 fps):
!if (( $(echo "$FPS > 2.0" | bc -l) )); then FPS=2.0; fi

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.

Error Handling: Missing error handling for the ffprobe command. If the video file is corrupted or ffprobe fails, DURATION will be empty, causing the subsequent bc calculations to fail with cryptic errors. This could lead to unexpected behavior or script crashes.

Suggested change
Cap FPS between reasonable bounds (0.1 to 2.0 fps):
!if (( $(echo "$FPS > 2.0" | bc -l) )); then FPS=2.0; fi
DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$VIDEO_PATH")
if [ -z "$DURATION" ] || [ "$DURATION" = "N/A" ]; then
echo "Error: Could not determine video duration. File may be corrupted or invalid."
exit 1
fi
echo "Video duration: ${DURATION}s"

!if (( $(echo "$FPS > 2.0" | bc -l) )); then FPS=2.0; fi
!if (( $(echo "$FPS < 0.1" | bc -l) )); then FPS=0.1; fi
!FRAME_INTERVAL=$(echo "scale=2; 1 / $FPS" | bc)
!echo "Using adaptive FPS: $FPS (1 frame every ${FRAME_INTERVAL}s)"

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.

Performance Issue: The TARGET_FRAMES=30 is hardcoded but the PR description mentions "targets 20-50 frames". Consider making this configurable or at least document why 30 was chosen as the fixed target when the range suggests it should be adaptive.

Comment on lines +54 to 56
!fi

## Step 3: Tournament Selection Using Claude

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.

Logic Error: The minimum frame guarantee check uses FRAME_COUNT (actual extracted frames) but the test script uses EXPECTED_FRAMES (calculated frames). This inconsistency means the test script doesn't accurately validate the real procedure logic. The procedure logic is correct, but the test is misleading.

Suggested change
!fi
## Step 3: Tournament Selection Using Claude
if [ "$FRAME_COUNT" -lt "$MIN_FRAMES" ]; then
echo "Warning: Only $FRAME_COUNT frames extracted. Re-extracting with higher FPS for better coverage..."
ffmpeg -i "$VIDEO_PATH" -vf "fps=2.0" -q:v 2 "$FRAMES_DIR/frame_%04d.jpg" -loglevel error -y
FRAME_COUNT=$(ls -1 "$FRAMES_DIR"/frame_*.jpg 2>/dev/null | wc -l)
echo "Re-extracted $FRAME_COUNT frames for analysis"
fi

Comment on lines +39 to 42

Extract frames at adaptive intervals:
!ffmpeg -i "$VIDEO_PATH" -vf "fps=$FPS" -q:v 2 "$FRAMES_DIR/frame_%04d.jpg" -loglevel error

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.

Potential Division by Zero: If DURATION is 0 or very close to 0, the FPS calculation $TARGET_FRAMES / $DURATION could result in division by zero or extremely high values. While the FPS capping helps, it's better to validate duration before calculation.

Suggested change
Extract frames at adaptive intervals:
!ffmpeg -i "$VIDEO_PATH" -vf "fps=$FPS" -q:v 2 "$FRAMES_DIR/frame_%04d.jpg" -loglevel error
if (( $(echo "$DURATION <= 0" | bc -l) )); then
echo "Error: Invalid video duration: ${DURATION}s"
exit 1
fi
FPS=$(echo "scale=3; $TARGET_FRAMES / $DURATION" | bc)

Extract refined frames around the winner:
!ffmpeg -ss $START_TIME -i "$VIDEO_PATH" -t $DURATION_R2 -vf "fps=$ROUND2_FPS" -q:v 2 "$FRAMES_DIR/round2/refined_%03d.jpg" -loglevel error
!echo "Extracted $(ls -1 "$FRAMES_DIR"/round2/*.jpg 2>/dev/null | wc -l) refined frames for Round 2"

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.

Edge Case: The START_TIME calculation uses a conditional to prevent negative values, but this could result in a window that's not centered around the winner timestamp for videos shorter than the window size. For very short videos, this might extract frames from the beginning rather than around the actual winner.

Comment thread test_adaptive_fps.sh
echo "================================================================"
echo "Test complete! All calculations follow expected behavior."
echo ""
echo "Key observations:"

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.

Test Coverage Gap: The test script doesn't validate the actual minimum frame guarantee logic that checks FRAME_COUNT vs MIN_FRAMES. It only shows when the guarantee "would trigger" based on calculated frames, not actual extraction results. Consider adding a test that simulates actual frame extraction scenarios.

Comment thread test_adaptive_fps.sh
echo "================================================================"
echo "Test complete! All calculations follow expected behavior."
echo ""
echo "Key observations:"

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.

Documentation Issue: The comment states "Very short videos (<10s) hit minimum FPS of 0.1" but this is incorrect. Very short videos (3-5s) actually hit the maximum FPS of 2.0 due to the TARGET_FRAMES/DURATION calculation. The 0.1 FPS minimum only applies to very long videos (>300s).

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.

Improve extract-best-frame with adaptive frame extraction for variable video lengths

1 participant