Files
vid_convert/docs/superpowers/specs/2026-03-22-av1-opus-design.md

144 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Spec : Migration AV1-SVT + Opus
**Date :** 2026-03-22
**Objectif :** Remplacer le pipeline H.265/AAC par AV1-SVT/Opus avec sélection automatique du CRF via `ab-av1 crf-search`. Passer la sortie en MKV. Simplifier la structure (suppression du chunking, de l'entrelacement automatique, du remux MP4).
---
## Contexte
`vid_convert.py` est un script Python standalone de conversion vidéo pour l'archivage de demux DVD/BluRay. Il orchestre FFmpeg, mkvmerge et des outils tiers pour produire un fichier optimisé qualité/poids.
**Sources attendues :** demux HEVC (H.265) en conteneur MKV ou MP4, ou fichiers DVD (MPEG-2, SD).
État actuel : H.265 (libx265), AAC-LC (libfdk_aac), encodage en chunks de 300s, sortie MP4.
---
## Changements
### 1. Codec vidéo : libx265 → libsvtav1
- Encodeur : `libsvtav1`
- Pixel format : `yuv420p10le` (10 bits, inchangé)
- Paramètres SVT-AV1 via `-svtav1-params` (remplace `-x265-params`)
- Suppression de la logique de chunks (300s) : encodage en une seule passe
- Sortie intermédiaire : `{file}_video.mkv` (une seule piste vidéo, remplace les multiples `{file}_video_t*.mkv`)
### 2. Sélection du CRF via ab-av1
Nouvelle fonction `find_crf(file, enc_options)` :
- Commande : `ab-av1 crf-search --input {file} --encoder libsvtav1 --vmaf 96 --enc {enc_options}`
- Cible VMAF : **96** (codé en dur)
- **Pour les sources HDR10**, ajouter `--vmaf-model path=/usr/share/vmaf/model/vmaf_4k_v0.6.1.json` si disponible, afin d'utiliser un modèle VMAF calibré HDR. Si le modèle est absent, `ab-av1` utilise le modèle par défaut (acceptable, légère imprécision sur HDR).
- **Parsing de la sortie :** `ab-av1 crf-search` émet une ligne finale du type `crf 32 VMAF 96.21 ...`. On extrait le CRF en cherchant une ligne contenant à la fois `crf` et `VMAF` et en lisant le token suivant `crf`.
- Fallback à CRF 32 si la commande échoue ou si le parsing ne trouve rien.
**`enc_options`** est une chaîne de paramètres SVT-AV1 au format `key=value:key=value`, construite dans le `main` :
| Flag CLI | Option SVT-AV1 |
|---|---|
| (base) | `preset=3:tune=0` (VQ, qualité perçue — défaut pour tous les contenus) |
| `--animation` | aucun changement de tune (VQ reste optimal) |
| `--interlaced` | aucun paramètre SVT-AV1 (yadif géré côté FFmpeg) |
Les métadonnées HDR (mastering display, HDR10+) sont passées **séparément** à `convert_video` via `-svtav1-params`, et non via `enc_options`. `enc_options` ne contient que les options de qualité/preset.
### 3. Codec audio : libfdk_aac → libopus
- Encodeur : `libopus` (doit être compilé dans FFmpeg — vérifier avec `ffmpeg -codecs | grep opus`)
- Mode VBR (`-vbr on`)
- Bitrate adaptatif :
- ≤ 2 canaux : 128k
- 6 canaux (5.1) : 320k
- 8 canaux (7.1) : 450k
- Multicanal : `-mapping_family 1`
- Workaround `5.1(side)``5.1` conservé
- Normalisation de volume (`volumedetect` + filtre `volume=`) inchangée
### 4. HDR10 statique
Les métadonnées mastering display et content-light sont passées via `-svtav1-params` :
```
mastering-display=G(x,y)B(x,y)R(x,y)WP(x,y)L(max,min):content-light=maxcll,maxfall
```
La logique de calcul des coordonnées chromatiques (depuis `side_data_list`) est conservée.
### 5. HDR10+
- **Extraction :** `hdr10plus_parser` (binaire inclus)
- **Conteneur source :** si le fichier source est en MKV, la commande d'extraction doit omettre `-vbsf hevc_mp4toannexb` (ce bitstream filter est uniquement nécessaire pour les sources HEVC en MP4). `get_infos` détecte le conteneur via `ffprobe format_name` et adapte la commande.
- **Injection :** via `hdr10plus-json={path}` dans `-svtav1-params` (SVT-AV1 natif)
### 6. Dolby Vision
- `get_infos` détecte la présence d'un stream DV (entrée `DOVI` dans `side_data_list`)
- **Profile 8** (dual-layer, cas le plus fréquent) : fallback automatique vers HDR10 — la couche HDR10 est encodée normalement, l'enhancement layer DV est perdu
- **Profile 5** (RPU uniquement, sans couche HDR10 indépendante) : avertissement loggé ; la couche de base est traitée telle quelle (HDR10 si les métadonnées sont présentes dans le stream, sinon SDR)
- Dans tous les cas, un message indique : `"Dolby Vision détecté (Profile X). Encodage sans couche DV."`
- Pas d'intégration `dovi_tool`
### 7. Entrelacement
- `is_interlaced()` supprimée
- Nouvel argument CLI `--interlaced` (flag booléen)
- Le filtre `yadif` dans `convert_video` n'est appliqué que si `--interlaced` est passé
### 8. Assemblage MKV simplifié
- `create_mkv` assemble : `{file}_video.mkv` + N `{file}_audio_*.mka` + N `{file}_subtitle_*.mkv``NEW_{filename}.mkv`
- Le fichier de sortie est directement nommé `NEW_{filename}.mkv` (suppression du nom intermédiaire `_FINAL.mkv`)
- Nettoyage des fichiers temporaires : `{file}_video.mkv`, `{file}_audio_*.mka`, `{file}_subtitle_*.mkv` supprimés après assemblage
- `mkv_to_mp4` supprimée
### 9. Corrections
- Ligne 308 : `infos = get_infos(file)` décommenté
- `interlaced = False` orphelin supprimé
- `-t` / `--starttime` supprimé
---
## Arguments CLI finaux
| Argument | Description |
|---|---|
| `f_input` | Fichier source |
| `-d` / `--debug` | Logging DEBUG |
| `-s` / `--stabilise` | Stabilisation vidéo (vidstab) |
| `-a` / `--animation` | Tuning animation (tune=0) |
| `-c` / `--vhs` | Restauration VHS (hqdn3d + unsharp) |
| `--interlaced` | Forcer le désentrelacement (yadif) |
---
## Flux d'exécution
```
get_infos → [stabilization] → cropping → volume_audio → find_crf
→ extract_subs (×N) → convert_audio (×N) → convert_video → create_mkv
```
`stabilization` n'est exécutée que si `--stabilise` est passé, avant le crop.
---
## Dépendances
| Outil | Usage | Changement |
|---|---|---|
| `ffmpeg` + `ffprobe` | Encodage, analyse | Inchangé (libopus requis) |
| `ab-av1` | Sélection CRF | **Nouveau** |
| `hdr10plus_parser` | Extraction HDR10+ | Inchangé |
| `mkvmerge` | Assemblage final | Inchangé |
| `libfdk_aac` | Audio AAC | **Supprimé** |
| `libopus` | Audio Opus | **Nouveau** (dans FFmpeg) |
---
## Hors scope
- Dolby Vision Profile 5 avec `dovi_tool`
- DV Profile 10 pour AV1 (expérimental, non viable)
- Interface utilisateur, tests automatisés