# VMAF Optimisation Pipeline - Setup Guide ## Quick Start ### Prerequisites - Python 3.8+ - FFmpeg with VMAF support (`ffmpeg -filters 2>&1 | grep libvmaf`) - ab-av1 binary (v0.10.3+) ### Installation **On Linux (Server/WSL):** ```bash # Clone repository git clone https://gitea.theflagroup.com/bnair/VMAFOptimiser.git /opt/Optmiser # Download ab-av1 cd /opt/Optmiser/bin wget https://github.com/alexheretic/ab-av1/releases/download/v0.10.3/ab-av1-x86_64-unknown-linux-musl chmod +x ab-av1 # Set up directories mkdir -p /opt/Optmiser/tmp /opt/Optmiser/logs /opt/Optmiser/.lock ``` **On Windows:** ```powershell # Clone repository git clone https://gitea.theflagroup.com/bnair/VMAFOptimiser.git C:\Optmiser # Install dependencies winget install ffmpeg # Install Rust and ab-av1 # Download from https://rust-lang.org/ cargo install ab-av1 # Set up directories mkdir C:\Optmiser\tmp, C:\Optmiser\logs ``` **On macOS:** ```bash # Clone repository git clone https://gitea.theflagroup.com/bnair/VMAFOptimiser.git /opt/Optmiser # Install dependencies brew install ffmpeg # Install Rust and ab-av1 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh cargo install ab-av1 # Set up directories mkdir -p /opt/Optmiser/tmp /opt/Optmiser/logs /opt/Optmiser/.lock ``` ## Running the Optimiser ### Choose Your Script **Linux / WSL / macOS:** ```bash # Interactive mode (shows prompts) ./run_optimisation.sh # Direct execution with parameters ./run_optimisation.sh --directory /mnt/Media/Movies --vmaf 95 --preset 6 --workers 1 # For 50% CPU mode on server ./run_optimisation.sh --directory /mnt/Media/Movies --vmaf 95 --workers 1 --cpu-limit 50 ``` **Windows:** ```powershell # Interactive mode (shows prompts) .\run_optimisation.ps1 # Direct execution with parameters .\run_optimisation.ps1 -directory "D:\Movies" --vmaf 95 --preset 6 --workers 1 # For hardware acceleration (AMD GPU) .\run_optimisation.ps1 -directory "D:\Movies" --vmaf 95 --hwaccel auto ``` ## Script Parameters All wrapper scripts (`run_optimisation.sh` on Linux, `run_optimisation.ps1` on Windows) accept these parameters: | Parameter | Description | Default | |------------|-------------|---------| | `--directory ` | Root directory to scan | Current directory | | `--vmaf ` | Target VMAF score | 95.0 | | `--preset ` | SVT-AV1 Preset (4=best, 6=balanced, 8=fast) | 6 | | `--workers ` | Concurrent files to process | 1 | | `--samples ` | Samples for CRF search | 4 | | `--encoder ` | Video encoder: svt-av1, av1_amf, av1_nvenc, av1_qsv | svt-av1 | | `--hwaccel ` | Hardware decode acceleration (auto, d3d11va, vaapi) | none | | `--use-hardware-worker` | Use 1 HW encoder worker + rest CPU workers | false | | `--plex-url ` | Plex server URL for library refresh | none | | `--plex-token ` | Plex auth token | none | | `--log-dir ` | Log directory | /opt/Optmiser/logs | ## Multi-Machine Setup ### How Lock Files Prevent Conflicts Each video file has a lock file: `/opt/Optmiser/.lock/{video_filename}` **Process:** 1. Machine A: Checks for lock → Not found, creates lock 2. Machine A: Starts encoding 3. Machine B: Checks for lock → Found, skips file 4. Machine A: Finishes, removes lock 5. Machine B: Can now process that file **Result:** Different machines automatically process different files simultaneously! ### Setup for Multiple Machines **Machine 1 - Linux Server (Intel i9-12900H):** ```bash cd /opt/Optmiser git pull origin main ./run_optimisation.sh /mnt/Media/movies --vmaf 95 ``` **Machine 2 - Windows PC (AMD RX 7900 XT):** ```powershell cd C:\Optmiser git pull origin main .\run_optimisation.ps1 D:\Media\movies --vmaf 95 --hwaccel auto ``` **Machine 3 - Another Linux PC:** ```bash cd /opt/Optmiser git pull origin main ./run_optimisation.sh /home/user/Media/tv --vmaf 95 ``` All three can run simultaneously! ## Hardware Acceleration ### Hardware Decoding vs Hardware Encoding There are two types of hardware acceleration: 1. **Hardware Decoding (`--hwaccel`)**: Uses GPU to decode source video faster. Doesn't affect quality. 2. **Hardware Encoding (`--encoder`)**: Uses GPU to encode output video. Much faster but requires quality compensation. ### Hardware Encoders | Encoder | GPU | Platform | Notes | |---------|-----|----------|-------| | `svt-av1` | CPU | All | Default. Best quality, slowest. | | `av1_amf` | AMD | Windows/Linux | RX 7000 series, ~3-10x faster than CPU | | `av1_nvenc` | NVIDIA | Windows/Linux | RTX 40 series, very fast | | `av1_qsv` | Intel | Windows/Linux | Arc GPUs, Intel iGPU with AV1 | ### FFmpeg with Hardware Encoder Support **Windows (pre-built with HW encoders):** ```powershell # Most Windows FFmpeg builds include hardware encoders # Verify with: ffmpeg -encoders 2>&1 | findstr av1 # Should show: av1_amf, av1_nvenc, av1_qsv (depending on your GPU) # If missing, download from: https://github.com/BtbN/FFmpeg-Builds/releases # Choose: ffmpeg-master-latest-win64-gpl.zip (includes all encoders) ``` **Linux (may need custom build):** ```bash # Check available encoders ffmpeg -encoders 2>&1 | grep av1 # For AMD (av1_amf) - requires AMF SDK # Install AMD GPU drivers with AMF support sudo apt install amdgpu-pro # For NVIDIA (av1_nvenc) - requires NVIDIA drivers sudo apt install nvidia-driver-535 # or newer # For Intel (av1_qsv) - requires Intel Media SDK sudo apt install intel-media-va-driver-non-free # If your distro's ffmpeg lacks HW encoders, use static build: wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz ``` ### Using Hardware Workers (1 GPU + 3 CPU) For mixed encoding with your RX 7900 XT: ```powershell # Windows - 4 workers: 1 uses GPU (av1_amf), 3 use CPU (svt-av1) .\run_optimisation.ps1 ` -Directory "Z:\" ` -Vmaf 94 ` -Workers 4 ` -Encoder av1_amf ` -Hwaccel auto ` -UseHardwareWorker ` -LogDir "C:\Users\bnair\Documents\VMAFOptimiser\logs" ``` ```bash # Linux - same concept ./run_optimisation.sh \ --directory /media \ --vmaf 94 \ --workers 4 \ --encoder av1_amf \ --hwaccel auto \ --use-hardware-worker ``` **How it works:** - First worker to start claims the GPU and uses `av1_amf` - Remaining 3 workers use `svt-av1` (CPU) - GPU worker applies +2 VMAF offset automatically to match CPU quality ### Quality Compensation Hardware encoders produce lower quality at the same settings. The script automatically compensates: | Target VMAF | CPU (svt-av1) | GPU (av1_amf) | |-------------|---------------|---------------| | 94 | Searches for VMAF 94 | Searches for VMAF 96 | | 93 | Searches for VMAF 93 | Searches for VMAF 95 | | 92 | Searches for VMAF 92 | Searches for VMAF 94 | This offset (`HW_ENCODER_VMAF_OFFSET = 2.0`) can be adjusted in `optimize_library.py`. ### Automatic Detection When `--hwaccel auto` is specified, the wrapper scripts automatically select the best available hardware acceleration: | Platform | Auto Selection | Notes | |-----------|----------------|--------| | Windows | d3d11va | Direct3D Video Acceleration | | macOS | videotoolbox | VideoToolbox framework | | Linux/WSL | vaapi | Video Acceleration via VA-API | ### GPU vs iGPU Priority - **Discrete GPU takes priority:** If a discrete GPU (like AMD RX 7900 XT) is present, it's selected over integrated GPU - **For AMD RX 7900 XT:** Hardware encoding provides ~3-10x speedup over CPU - **Note:** GPU encoding may need slightly lower VMAF targets to match CPU quality ## Customization ### Changing VMAF Targets Edit `optimize_library.py`: ```python # More aggressive (smaller files, lower quality) TARGETS = [92.0, 90.0, 88.0] # Conservative (larger files, higher quality) TARGETS = [95.0, 94.0, 93.0] ``` ### Changing Savings Threshold ```python # More aggressive (encode more) MIN_SAVINGS_PERCENT = 8.0 # Less aggressive (encode fewer) MIN_SAVINGS_PERCENT = 15.0 ``` ### Changing Encoder Preset ```python # Faster encodes (larger files, lower quality) PRESET = 8 # Better quality (slower encodes, smaller files) PRESET = 4 ``` ## Platform-Specific Tips ### For Linux Servers (Intel i9-12900H) 1. **Use 50% CPU mode** if running other services: ```bash ./run_optimisation.sh --directory /media --vmaf 95 --workers 1 --cpu-limit 50 ``` 2. **Run during off-peak hours** to minimize user impact 3. **Monitor CPU temperature:** ```bash watch -n 2 'sensors | grep "Package id"' ``` 4. **Use higher preset for faster encodes:** ```bash ./run_optimisation.sh --vmaf 93 --preset 8 ``` ### For Windows PCs (AMD RX 7900 XT) 1. **Enable hardware acceleration** for massive speedup: ```powershell .\run_optimisation.ps1 --directory "D:\Movies" --hwaccel auto ``` 2. **Test small sample first** to verify settings: ```powershell .\run_optimisation.ps1 --directory "D:\Media\sample" --thorough --vmaf 95 ``` 3. **Monitor GPU usage** (Task Manager or third-party tools) 4. **Consider quality compensation** - GPU encoding may need slightly lower VMAF targets to match CPU quality ### For WSL (Ubuntu/Debian) 1. **Access Windows drives** via `/mnt/c/`: ```bash ls /mnt/c/Media/movies ``` 2. **Increase memory limits** if encoding 4K content: ```bash # Edit ~/.wslconfig [wsl2] memory=16GB ``` ## Running in Docker (Optional) ```bash # Build image docker build -t vmaf-optimiser . # Run with mount docker run -v /path/to/media:/media vmaf-optimiser /media ``` ## Troubleshooting ### Issue: Scripts not found **Solution:** Ensure you're in the correct directory with the scripts installed. ### Issue: "ab-av1: command not found" **Solution:** Install ab-av1 via cargo: ```bash cargo install ab-av1 ``` ### Issue: FFmpeg VMAF not available **Solution:** Recompile FFmpeg with VMAF support or download a pre-built version that includes libvmaf. ### Issue: Out of Memory **Solution:** Reduce workers or increase swap: ```bash # Increase swap sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # Use more conservative settings ./run_optimisation.sh --workers 1 --vmaf 93 ``` ### Issue: Multiple machines encoding same file **Solution:** This is prevented by lock files. If you see duplicates, check `/opt/Optmiser/.lock/` for stale locks. ### Issue: Encoding fails **Solution:** Check logs: ```bash cat /opt/Optmiser/logs/failed_encodes.jsonl | jq '.' ``` ### Issue: "unexpected argument" error **Solution:** Use correct flags for your ab-av1 version. The wrapper scripts now validate support at runtime. ## Git Workflow ### Initial Setup ```bash cd /opt/Optmiser git init git remote add origin https://gitea.theflagroup.com/bnair/VMAFOptimiser.git git branch -M main git add . git commit -m "Initial commit: VMAF optimisation pipeline" git push -u origin main ``` ### Daily Updates ```bash cd /opt/Optmiser git pull origin main # Run optimisation ./run_optimisation.sh /media tv_movies # Review changes git diff ``` ### Committing Changes ```bash cd /opt/Optmiser git status # Add changed files git add optimize_library.py run_optimisation.sh run_optimisation.ps1 # Commit with message git commit -m "feat: add Windows and Linux wrapper scripts" # Push git push ``` ### Viewing Logs ```bash # Watch logs in real-time tail -f /opt/Optmiser/logs/tv_movies.jsonl | jq '.' # Check files logged for review cat /opt/Optmiser/logs/low_savings_skips.jsonl | jq '.[] | select(.recommendations=="logged_for_review")' # Statistics jq -r '.status' /opt/Optmiser/logs/tv_movies.jsonl | sort | uniq -c # Find what CRF/VMAF combinations are being used most jq -r '[.vmaf, .crf] | @tsv' /opt/Optmiser/logs/tv_movies.jsonl | sort | uniq -c ``` ### View History ```bash cd /opt/Optmiser git log --oneline git log --graph --all ``` ## FAQ **Q: Can I run this on multiple machines at once?** A: Yes! Each machine will process different files due to lock file mechanism. **Q: Should I use Windows or WSL?** A: WSL is recommended for Linux compatibility. Use Windows native if you need direct hardware access or performance. **Q: Will hardware encoding work better than CPU?** A: For AMD RX 7900 XT, hardware AV1 encoding is ~3-10x faster than CPU. However, GPU encoding may need slightly lower VMAF targets to match CPU quality. **Q: What VMAF target should I use?** A: Start with VMAF 94 or 95. Drop to 92-90 if you need more savings. **Q: How do I know which files are being processed?** A: Check `.lock/` directory: `ls -la /opt/Optmiser/.lock/` **Q: Can I pause/resume?** A: Pause by stopping the script (Ctrl+C). Resume by running again - it skips processed files. **Q: What happens if encoding fails?** A: Error is logged to `failed_encodes.jsonl`. Original file is NOT modified. **Q: How much CPU does encoding use?** A: Full CPU by default. Use `--workers 1` for single-threaded, or limit with `--cpu-limit 50` for 50% (12 threads on 24-core). **Q: What are the log files?** A: - `tv_movies.jsonl` - Successful TV & Movie encodes - `content.jsonl` - Successful Content folder encodes - `low_savings_skips.jsonl` - Files with <12% savings + 15% estimates - `failed_searches.jsonl` - Files that couldn't hit any VMAF target - `failed_encodes.jsonl` - Encoding errors **Q: How do I see real-time progress?** A: The script streams all ab-av1 output in real-time, showing ETA, encoding speed, and frame count. --- **Last Updated:** December 31, 2025 **Version:** 2.0 with Windows and Linux Wrapper Scripts