14 KiB
Quality Checking Feature
Overview
encoderPro now includes intelligent quality analysis that detects source video quality and warns you if encoding will degrade quality to a noticeable degree. This prevents accidental quality loss when re-encoding high-quality source material.
Key Features
1. Automatic Quality Detection
- Analyzes source video bitrate, resolution, codec, and FPS
- Calculates quality score (0-100) based on bitrate per pixel
- Detects HDR content
- Accounts for codec efficiency (H.265 vs H.264 vs AV1)
2. Pre-Encoding Quality Comparison
- Estimates target encoding bitrate based on your CRF settings
- Compares source quality to estimated target quality
- Warns if quality drop exceeds configurable thresholds
- Provides detailed quality metrics for decision making
3. Processed File Tracking
- Database tracks all processed files
- Automatically skips already-encoded files on re-runs
- Maintains processing history with quality metrics
- Supports manual reset for re-processing
4. Configurable Behavior
- Enable/disable quality checking
- Adjustable warning and error thresholds
- Option to skip degraded files automatically
- User prompts for manual confirmation
Configuration
Add this section to your config.yaml:
quality_check:
# Enable pre-encoding quality analysis
enabled: true
# Warning threshold - warn if quality will drop by this many points (0-100 scale)
warn_threshold: 10.0
# Error threshold - fail/skip if quality will drop by this many points
error_threshold: 20.0
# Automatically skip files where encoding would degrade quality
skip_on_degradation: false
# Prompt user for confirmation when warnings detected (CLI only)
prompt_on_warning: true
Configuration Options Explained
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Enable/disable quality checking entirely |
warn_threshold |
float | 10.0 |
Quality score drop that triggers a warning |
error_threshold |
float | 20.0 |
Quality score drop that triggers an error |
skip_on_degradation |
boolean | false |
Auto-skip files with quality degradation |
prompt_on_warning |
boolean | true |
Ask user for confirmation on warnings |
How Quality Scores Work
Quality Score (0-100)
The quality checker calculates a score based on bits per pixel per frame:
Quality Score = f(bitrate, resolution, fps, codec_efficiency)
Score Ranges:
- 95-100: Near-lossless / Exceptional quality
- 85-95: Excellent / Archival quality
- 70-85: Good / Visually transparent
- 50-70: Acceptable / Minor compression visible
- 0-50: Poor / Heavy compression artifacts
Codec Efficiency Multipliers
The quality checker accounts for codec efficiency:
| Codec | Multiplier | Notes |
|---|---|---|
| AV1 | 1.8x | Most efficient codec |
| H.265/HEVC | 1.5x | ~50% better than H.264 |
| H.264/AVC | 1.0x | Baseline reference |
| MPEG-2 | 0.5x | Older, less efficient |
| MPEG-4 | 0.7x | Older codec |
Example: A video at 5 Mbps H.265 has similar quality to 7.5 Mbps H.264.
Bits Per Pixel Ranges
| BPP Range | Quality | Typical Use Case |
|---|---|---|
| > 0.5 | Near-lossless (95-100) | Professional archival |
| 0.3 - 0.5 | Excellent (85-95) | High-quality archival |
| 0.2 - 0.3 | Good (70-85) | Sweet spot for home media |
| 0.1 - 0.2 | Acceptable (50-70) | Streaming services |
| < 0.1 | Poor (0-50) | Heavy compression |
Usage Examples
Example 1: Analyze Video Quality
python3 quality_checker.py /movies/example.mkv
Output:
Video Quality Analysis:
Resolution: 1920x1080
Bitrate: 8.5 Mbps
Codec: h264
FPS: 23.98
HDR: No
Quality Score: 72.3/100
Example 2: Check Before Encoding
from quality_checker import QualityChecker
from pathlib import Path
checker = QualityChecker()
# Define your encoding profile
profile = {
'encoder': 'nvidia_nvenc_h265',
'quality': 21 # CRF value
}
# Check quality before encoding
result = checker.check_before_encode(
Path('/movies/example.mkv'),
profile,
warn_threshold=10.0,
error_threshold=20.0
)
if result['ok']:
print("✅ Safe to encode")
elif result['warning']:
print(f"⚠️ Warning: {result['message']}")
elif result['error']:
print(f"❌ Error: {result['message']}")
Example 3: Batch Analysis
See example_quality_check.py for comprehensive examples including:
- Single file analysis
- Quality degradation checks
- Comprehensive pre-encode checks
- Batch directory analysis
Understanding Quality Degradation
What Causes Quality Degradation?
Encoding can degrade quality when:
-
Source is already high quality
- Source: 95/100 (near-lossless BluRay rip at 25 Mbps)
- Target: 75/100 (H.265 CRF 21 at 8 Mbps)
- Drop: 20 points ⚠️
-
Target bitrate is too low
- Source: 4K movie at 40 Mbps
- Target: 4K at 10 Mbps (too aggressive)
- Result: Visible compression artifacts
-
Re-encoding already compressed content
- Source: Web-DL already at CRF 23
- Target: Re-encode at CRF 21
- Result: Quality loss from generation loss
When to Proceed Despite Warnings
Safe to proceed:
- Source quality 50-70 (already compressed)
- Quality drop < 10 points
- Testing settings on sample files
- Source is a screen recording or low-quality capture
Consider skipping:
- Source quality > 90 (near-lossless)
- Quality drop > 20 points
- Archival content you want to preserve
- BluRay remuxes or untouched sources
Real-World Examples
Example 1: BluRay Remux (Skip Recommended)
Source Quality Analysis:
Resolution: 1920x1080
Bitrate: 28.5 Mbps (H.264)
Quality Score: 96/100 (Near-lossless)
Target Settings (CRF 21 H.265):
Estimated Bitrate: 7.2 Mbps
Target Quality: 73/100
⚠️ WARNING: Quality will drop by 23 points
❌ Recommendation: SKIP - Source is too high quality
Action: Skip encoding or use CRF 18-19 for archival quality.
Example 2: Web-DL (Safe to Encode)
Source Quality Analysis:
Resolution: 1920x1080
Bitrate: 6.2 Mbps (H.264)
Quality Score: 68/100 (Good)
Target Settings (CRF 21 H.265):
Estimated Bitrate: 5.8 Mbps
Target Quality: 71/100
✅ OK: Quality will improve by 3 points
✅ Recommendation: PROCEED - Safe to encode
Action: Proceed with encoding. Will remove subtitles without quality loss.
Example 3: Already Encoded (Warning)
Source Quality Analysis:
Resolution: 1920x1080
Bitrate: 4.8 Mbps (H.265)
Quality Score: 65/100 (Acceptable)
Target Settings (CRF 21 H.265):
Estimated Bitrate: 5.2 Mbps
Target Quality: 68/100
⚠️ WARNING: Re-encoding already compressed H.265
⚠️ Recommendation: Consider CRF 19-20 to avoid generation loss
Action: Consider lower CRF or skip. Source is already H.265.
Example 4: Low Quality Source (Safe)
Source Quality Analysis:
Resolution: 1920x1080
Bitrate: 2.8 Mbps (H.264)
Quality Score: 52/100 (Acceptable)
Target Settings (CRF 21 H.265):
Estimated Bitrate: 5.8 Mbps
Target Quality: 71/100
✅ OK: Quality will improve by 19 points
✅ Recommendation: PROCEED - Encoding will improve quality
Action: Proceed. H.265 encoding will improve perceived quality.
HDR Content Detection
The quality checker automatically detects HDR content:
HDR Detection Criteria
-
Transfer characteristics:
- SMPTE 2084 (HDR10)
- ARIB STD-B67 (HLG)
-
Color primaries:
- BT.2020 color space
-
Metadata tags:
- Any tag containing "HDR"
HDR Warning
If HDR content is detected and hdr_handling is not set to preserve:
⚠️ HDR content detected but HDR handling is not set to 'preserve'
Action: Update your profile:
profiles:
your_profile:
hdr_handling: preserve
Processed File Tracking
How It Works
- First run: All files scanned and added to database as
pending - Encoding: Files marked as
processing→completedorfailed - Second run: Completed files automatically skipped
- Re-processing: Reset state to
pendingif needed
Database Schema
CREATE TABLE files (
id INTEGER PRIMARY KEY,
filepath TEXT UNIQUE NOT NULL,
state TEXT NOT NULL, -- pending/processing/completed/failed/skipped
profile_name TEXT,
encoder_used TEXT,
encode_time_seconds REAL,
fps REAL,
original_size INTEGER,
encoded_size INTEGER,
source_quality_score REAL, -- NEW
target_quality_score REAL, -- NEW
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Manually Reset Files
# Reset specific file
python3 dbmanage.py --reset-file /movies/example.mkv
# Reset all files
python3 dbmanage.py --reset-all
# Reset only failed files
python3 dbmanage.py --reset-failed
Command-Line Options
Check Quality Only (No Encoding)
# Analyze single file
python3 quality_checker.py /movies/example.mkv
# Batch analyze directory
python3 example_quality_check.py /movies/
Override Quality Check
# Disable quality check for this run
python3 reencode.py -c config.yaml --no-quality-check
# Force encode despite warnings
python3 reencode.py -c config.yaml --force
Skip Processed Files
# Skip already completed files (default behavior)
python3 reencode.py -c config.yaml
# Re-process all files (ignore database)
python3 reencode.py -c config.yaml --reprocess-all
Best Practices
1. Start with Quality Analysis
Before encoding your entire library:
# Analyze quality distribution
python3 example_quality_check.py /movies/ > quality_report.txt
Review the report to understand your source quality distribution.
2. Use Appropriate Thresholds
Conservative (Preserve Quality):
quality_check:
warn_threshold: 5.0 # Warn on small drops
error_threshold: 10.0 # Error on moderate drops
skip_on_degradation: true
Balanced (Recommended):
quality_check:
warn_threshold: 10.0
error_threshold: 20.0
skip_on_degradation: false
Aggressive (Maximum Compression):
quality_check:
warn_threshold: 20.0
error_threshold: 30.0
skip_on_degradation: false
3. Quality-Based Profiles
Use resolution rules to apply different profiles based on source quality:
advanced:
resolution_rules:
enabled: true
quality_rules:
- min_quality: 90 # Near-lossless sources
profile: quality_gpu # Use high-quality preset
- min_quality: 70
profile: sweetspot_gpu # Balanced
- min_quality: 50
profile: balanced_gpu # Already compressed
- min_quality: 0
profile: fast_gpu # Low quality sources
4. Monitor Processing Logs
Quality checks are logged:
2025-01-15 10:30:22 - INFO - Analyzing quality: example.mkv
2025-01-15 10:30:23 - INFO - Source quality: 72.3/100
2025-01-15 10:30:23 - INFO - Target quality: 75.1/100
2025-01-15 10:30:23 - INFO - ✅ Quality check passed
Review logs to identify patterns and adjust settings.
Troubleshooting
Quality Check Fails
Problem: Failed to analyze source video quality
Solutions:
- Check ffprobe is installed:
ffprobe -version - Verify file is readable:
ls -la /path/to/file.mkv - Check file is valid video:
ffprobe /path/to/file.mkv - Disable quality check temporarily:
quality_check: enabled: false
Inaccurate Quality Scores
Problem: Quality scores don't match expectations
Explanation:
- Quality scores are estimates based on bitrate per pixel
- Different content has different complexity
- Simple animation: Lower bitrate, high quality
- Grain-heavy film: Higher bitrate needed
- Scores are relative, not absolute
Solution: Use thresholds as guidelines, not absolute rules.
Too Many Warnings
Problem: Getting warnings on files you want to encode
Solutions:
-
Increase thresholds:
quality_check: warn_threshold: 15.0 # From 10.0 -
Disable warnings:
quality_check: prompt_on_warning: false -
Disable quality check:
quality_check: enabled: false
API Reference
See quality_checker.py for full API documentation.
QualityChecker Class
class QualityChecker:
def analyze_quality(self, filepath: Path) -> Optional[VideoQuality]:
"""Analyze video quality metrics"""
def will_degrade_quality(
self,
source_quality: VideoQuality,
target_bitrate: int,
target_codec: str,
threshold: float = 10.0
) -> Tuple[bool, str]:
"""Check if encoding will significantly degrade quality"""
def check_before_encode(
self,
filepath: Path,
profile: Dict,
warn_threshold: float = 10.0,
error_threshold: float = 20.0
) -> Dict:
"""Comprehensive quality check before encoding"""
def estimate_target_bitrate(
self,
profile: Dict,
resolution: Tuple[int, int],
fps: float
) -> int:
"""Estimate target bitrate based on profile settings"""
Summary
The quality checking feature provides:
✅ Intelligent quality analysis - Understand your source material ✅ Degradation detection - Avoid accidental quality loss ✅ Processed file tracking - Skip already-encoded files ✅ Configurable behavior - Customize to your needs ✅ HDR detection - Preserve HDR metadata ✅ Detailed logging - Monitor quality decisions
Best Use Cases:
- Large mixed-quality libraries
- Preserving high-quality sources
- Avoiding re-encoding already compressed files
- Understanding quality impact before encoding
When to Disable:
- All sources are known low quality
- Testing encoding settings
- Processing screen recordings
- Time-sensitive batch jobs