Advanced Features¶
This guide covers VBC's advanced features: dynamic quality, auto-rotation, camera filtering, and more.
Dynamic Quality (Camera-Specific Quality)¶
Different cameras produce different quality levels. VBC can apply per-camera rules with explicit cq and optional rate.
Configuration¶
# conf/vbc.yaml
gpu_encoder:
common_args:
- "-cq 45" # Default for unknown cameras
general:
dynamic_quality:
"ILCE-7RM5":
cq: 38
rate:
bps: "0.8"
minrate: "0.7"
maxrate: "0.9"
"DC-GH7":
cq: 40
"DJI OsmoPocket3":
cq: 48
rate:
bps: "180M"
How It Works¶
- ExifTool analysis: VBC extracts full EXIF metadata
- Pattern matching: Searches all metadata for camera model strings
- Mode-aware override:
quality_mode=cqusesdynamic_quality.<pattern>.cqquality_mode=rateusesdynamic_quality.<pattern>.rate(if provided)- First match wins: Patterns are checked in config file order
Example¶
File: IMG_1234.MOV
EXIF: EXIF:Model = "ILCE-7RM5"
Result: CQ = 38 (specific match beats generic)
Schema note: legacy scalar format is rejected, e.g. "Sony": 40 is invalid.
CLI Override¶
# Override baseline CQ/CRF in encoder args
uv run vbc /videos --quality 40
# Dynamic Quality still active (from config)
uv run vbc /videos --config conf/vbc.yaml
Note: --quality overrides the base CQ/CRF value but does not disable dynamic_quality.
To disable dynamic quality, set general.dynamic_quality: {} or general.use_exif: false.
Debugging¶
Enable debug logging to see CQ decisions:
Look for:
Auto-Rotation¶
Automatically rotate videos based on filename patterns (useful for GoPro, drone footage).
Configuration¶
# conf/vbc.yaml
autorotate:
patterns:
"DJI_.*\\.MP4": 0 # DJI drones - no rotation
"GOPR\\d+\\.MP4": 180 # GoPro pattern - flip 180°
"IMG_\\d{4}\\.MOV": 90 # iPhone - rotate 90°
Regex syntax: Python re module (backslashes must be escaped).
How It Works¶
- Filename check: VBC checks each filename against all patterns
- First match: Uses angle from first matching pattern
- Rotation filter: Applies FFmpeg transpose/hflip+vflip filters
Rotation Angles¶
| Angle | FFmpeg Filter |
|---|---|
| 0 | None (no rotation) |
| 90 | transpose=1 (clockwise) |
| 180 | hflip,vflip (upside down) |
| 270 | transpose=2 (counter-clockwise) |
Manual Override¶
Camera Filtering¶
Process only files from specific camera models.
Configuration¶
Or via CLI:
How It Works¶
- EXIF extraction: Uses ExifTool to get camera model
- Substring match: Checks if any filter string is in camera model
- Skip non-matches: Files from other cameras are skipped
Example:
Filter: ["ILCE-7RM5", "DJI"]
File: IMG_1234.MOV
Camera: ILCE-7RM5 (Sony A7R V)
Match: "ILCE-7RM5" in "ILCE-7RM5" → Process ✓
File: VIDEO_5678.MP4
Camera: Canon EOS R5
Match: None → Skip ✗
Minimum Compression Ratio¶
Keep original file if compression savings are below threshold.
Configuration¶
Or via CLI:
How It Works¶
- Compress normally: FFmpeg creates compressed file
- Check ratio: Calculate
(1 - output_size/input_size) - Compare threshold: If savings <
min_compression_ratio: - Delete compressed file
- Copy original to output directory
- Write metadata/tags only when accepted: Deep metadata copy and VBC tags run only if ratio passes.
- Log decision: "MinRatio: kept original (X% < Y% minimum)"
Example:
Input: 100 MB
Output: 92 MB
Savings: 8% (1 - 92/100 = 0.08)
min_compression_ratio: 0.1 (10%)
Result: 8% < 10% → Keep original (copy 100 MB file)
Use Cases¶
- Already compressed: Files from efficient cameras (e.g., DJI with H.265)
- Tiny files: Small clips where AV1 overhead > savings
- Quality priority: Never accept worse compression
Skip AV1 Files¶
Avoid re-compressing files already in AV1 codec.
Configuration¶
Or via CLI:
How It Works¶
- FFprobe check: Extract codec from stream info
- AV1 detection: Check if
codec == "av1" - Skip: Don't queue for compression
Use case: Mixed library with some files already compressed to AV1.
Skip Already Encoded Files¶
VBC automatically detects files it has already encoded to prevent accidental re-compression (e.g., if output is used as input).
How It Works¶
- Tag Detection: Checks for
VBCEncoderorVBC Encodertags in metadata (via FFprobe or ExifTool). - Auto-Move: If found, the file is moved to the output directory and published as
JobCompleted. - Warning: At the end of processing, a yellow warning is displayed if any files were moved for this reason.
Note: This feature is always active and cannot be disabled.
Audio Consistency Check¶
Verify that audio handling in the output matches VBC's rules.
Behavior summary:
- Lossless (pcm_*, flac, alac, truehd, mlp, wavpack, ape, tta) → AAC 256 kbps
- AAC/MP3 → stream copy
- Other/unknown → AAC 192 kbps
- No audio → no audio
Usage¶
# Default output dir: <input_dir>_out
python vbc/utils/check_audio_consistency.py /path/to/videos
# Custom output dir
python vbc/utils/check_audio_consistency.py /path/to/videos --output-dir /path/to/videos_out
Output¶
The script prints summary counts (including how many input files had no audio), lists missing outputs, and reports any codec/bitrate mismatches.
Prefetch Factor¶
Controls submit-on-demand queue size.
Configuration¶
Formula:
Examples:
- prefetch_factor=1, threads=4 → 4 jobs queued
- prefetch_factor=2, threads=4 → 8 jobs queued
- User presses > (threads 4→5) → queue expands to 10 jobs
Trade-offs¶
| Factor | Pros | Cons |
|---|---|---|
| 1 (default) | Minimal memory, responsive to thread changes | Less parallelism |
| 2-3 | Better parallelism, smoother queue | Higher memory usage |
| 4+ | Maximum parallelism | Memory intensive, slow thread response |
Recommendation: Keep at 1 unless you need more parallelism and your system can sustain up to 8 threads.
Deep Metadata Copy¶
VBC uses ExifTool to preserve all metadata including GPS, camera settings, and custom tags.
Configuration¶
What's Copied¶
- GPS: Latitude, longitude, altitude
- Camera: Model, lens, focal length, ISO, aperture
- XMP: All XMP tags (Adobe, vendor-specific)
- QuickTime: All QuickTime metadata
- Custom VBC tags: Original filename, size, original bitrate, quality target, encoder, timestamp
ExifTool Config¶
VBC uses conf/exiftool.conf to define custom VBC tags:
# conf/exiftool.conf
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
VBC => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::VBC',
},
},
},
);
%Image::ExifTool::UserDefined::VBC = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-vbc', 2 => 'Image' },
NAMESPACE => { 'VBC' => 'http://ns.example.com/vbc/1.0/' },
WRITABLE => 'string',
VBCOriginalName => { },
VBCOriginalSize => { },
VBCQuality => { },
VBCOriginalBitrate => { },
VBCJsonNotes => { },
VBCEncoder => { },
VBCFinishedAt => { },
);
View VBC Tags¶
Output:
VBC Original Name : original_video.mp4
VBC Original Size : 125829120
VBC Original Bitrate : 35.9 Mbps
VBC Quality : 0.2
VBC Json Notes : {"rate_control":{"mode":"rate","target_expr":"0.2"}}
VBC Encoder : NVENC AV1 (GPU)
VBC Finished At : 2025-12-21T15:30:45+01:00
VBC Quality stores the configured compression target:
- cq mode: quality parameter label (e.g. CQ45)
- rate mode: configured bps value (e.g. 20M or 0.2)
Hardware Capability Detection¶
VBC automatically detects GPU limitations including: - 10-bit AV1 encoding not supported (older GPUs) - NVENC session limits exceeded (too many concurrent encodes)
Common HW_CAP Causes¶
Session Limits Exceeded:
- RTX 30-series: Max ~5 concurrent sessions
- RTX 40-series (e.g., 4090): Max 10-12 concurrent sessions
- VBC keyboard runtime controls (</>) clamp to 1-8 threads
- Startup --threads / general.threads accepts values >0 (practical upper bound is ThreadPoolExecutor(max_workers=16))
10-bit Encoding: - Older GPUs don't support 10-bit AV1 - RTX 40-series has full 10-bit support
Error Detection¶
FFmpeg outputs:
VBC:
1. Detects error string or exit code 187
2. Sets job status to HW_CAP_LIMIT
3. Creates .err marker
4. Increments hw_cap counter in UI
UI Display¶
┌─ COMPRESSION STATUS ───────────────────────────┐
│ Ignored: size:5 | err:2 | hw_cap:3 | av1:0 │
└────────────────────────────────────────────────┘
┌─ SUMMARY ──────────────────────────────────────┐
│ ✓ 42 success ✗ 2 errors ⚠ 3 hw_cap ⊘ 0 skip│
└────────────────────────────────────────────────┘
Workarounds¶
Option 1: Reduce thread count to GPU session limit
Option 2: Use CPU mode (no hardware limitations)
Option 3: Reduce quality for 10-bit issues
Option 4: Upgrade GPU (RTX 40-series has full 10-bit AV1 support and higher session limits)
Color Space Fix (FFmpeg 7.x)¶
FFmpeg 7.x has issues with "reserved" color space. VBC automatically fixes this.
Detection¶
FFprobe shows:
Fix Process¶
-
Remux: Use bitstream filter to set valid color space
-
Compress: Use fixed file as input
-
Cleanup: Delete temp file
Codecs Supported¶
- HEVC (h265):
hevc_metadatafilter - H.264:
h264_metadatafilter - Others: Proceed without fix (warning logged)
Debug Logging¶
Look for:
Detected reserved color space in video.mp4, applying fix...
Successfully fixed color space for video.mp4
Unicode Handling¶
Filenames with emoji or special Unicode can break table alignment.
Configuration¶
Effect:
- Filesystem: Filenames unchanged
- UI display: Non-ASCII replaced with ?
Example:
Disable:
Warning: May cause table misalignment in UI.
Next Steps¶
- CLI Reference - All command-line options
- Runtime Controls - Keyboard shortcuts
- Architecture - How features work internally