You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(preview): pool de décodeurs — plus de réouverture au franchissement de clip au scrub
Mesuré (headless, offscreen) : franchir un clip cross-média coûtait ~120 ms de blocage
synchrone sur le thread de rendu — 2× `Decoder::open` (avformat + init D3D11VA + avcodec_open2,
~39 ms) puis 2× seek keyframe + décode-avant (~81 ms). C'est le plus gros à-coup du scrub
(les pics p99 100-167 ms de la sonde), ~13× le readback. Et jusqu'ici on JETAIT les décodeurs
sortants (`apply_prefetched`), donc revenir sur un clip (motif A→B→A ultra-fréquent) rouvrait
tout à neuf + reseek keyframe complet.
On garde désormais un petit pool LRU (cap 3) de paires INACTIVES, ouvertes à leur dernière
position. Au franchissement cross-média (chemin scrub `active_clip_request`, hors lecture libre
déjà préchargée) : si la cible est en pool → reseek au lieu de rouvrir ; sinon ouverture neuve.
Dans les deux cas la paire QUITTÉE part en pool (dédup par clé + éviction LRU) au lieu d'être
fermée.
Effet mesuré, borné honnêtement :
- scrub qui SAUTE loin : POOL_HIT ~50-120 ms (open éliminé, seek keyframe restant) vs ~120 ms.
- scrub PRÈS d'une frontière (le cas ressenti : on traîne la tête à travers la coupe) :
le décodeur poolé est à ~1 frame → chemin rapide `decode_forward` → POOL_HIT ~5-9 ms,
soit ~20× moins que les ~120 ms d'avant.
Sûreté (la classe « frame sans texture → preview noire définitive » a déjà mordu ici) :
- la paire poolée est reseekée AVANT installation ; échec du seek → on la jette et on ouvre
à neuf (chemin connu sûr), jamais une frame vide (`seek_pair` rend `false`).
- le cache de SRV (keyé sur l'adresse de texture) reste vidé à chaque franchissement comme
avant — over-clear est sûr et bon marché, ce qui écarte tout « image du clip précédent ».
- lecture libre inchangée : `apply_prefetched`/`advance_to_next_scene_clip` droppent toujours
(déjà préchargé, pas de stall) ; seul le scrub alimente/consulte le pool.
Vérifié headless (harness bench-clipswitch, OPENSCREEN_CLIPSWITCH_TIMING=1) sur 3 phases —
sauts, retours locaux, et cyclage de 5 assets distincts (force l'éviction LRU) : le pool reste
borné à 3 et AUCUN franchissement, éviction comprise, ne produit de frame noire. cargo check OK.
0 commit comments