fix(preview): seek_to retombe sur un seek complet quand le décode-avant bute sur l'EOF - #211
Merged
Merged
Conversation
…nt bute sur l'EOF Suite du pool de décodeurs (#209). Un décodeur réactivé depuis le pool est souvent laissé en FIN de flux (on venait d'y scruber près de la fin avant de le quitter). Quand on y revient et qu'on le repositionne un poil plus loin, le chemin rapide `decode_forward_to` bute sur l'EOF et rendait `null` — ce qui forçait `swap_clip_pooled` à JETER la paire poolée et à tout ROUVRIR : mesuré ~190 ms, les pires à-coups ressentis au franchissement (13 % des franchissements dans un scrub réel, cf. les logs `OPENSCREEN_CLIPSWITCH_TIMING`). Correctif dans `seek_to` (donc utile aussi à `seek_active`, pas seulement au pool) : quand le décode-avant atteint l'EOF avant la cible, on NE rend plus `null` — on retombe sur le seek keyframe complet en dessous, qui rembobine + réarme le décodeur et repart proprement. Si la cible est réellement au-delà de l'EOF, le seek complet rend `null` lui aussi : comportement inchangé pour ce cas. Appliqué aux deux backends (`pipeline_windows` + `pipeline_macos`). Effet mesuré (headless, GPU au repos) : les reseeks près de l'EOF passent de OPEN ~190 ms à POOL_HIT ~50-80 ms. Jamais pire que l'état d'avant (pire cas identique : même repli ouverture). Sûreté vérifiée (harnais avec lecture des pixels, pas seulement le compteur de générations) : sur 46 franchissements — sauts, retours locaux, éviction LRU 5 assets, ET près de l'EOF — **0 preview noire, 0 frame stale** ; chaque franchissement produit une frame fraîche valide. (Les "frames absentes" d'un premier jet étaient des faux positifs : un `pump` trop court qui expirait avant qu'un seek keyframe près de l'EOF, GPU chargé, ait fini.) cargo check OK.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… une image valide L'overlay reflétait l'état du `<video>` CACHÉ (source horloge/audio), pas la preview réelle — le canvas natif D3D, qui affiche déjà une image valide pendant que le `<video>` re-seek. À chaque scrub/seek, `loadState` passait à « loading » et le panneau « Loading preview… » venait recouvrir une bonne image, au milieu de l'écran, pour rien — plus gênant qu'utile. On n'affiche plus que l'erreur (`loadState === "error"`), qui, elle, signale un vrai échec de chargement (auquel cas le natif ne montre rien non plus). Le reste de `loadState` est conservé tel quel.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Suite du pool de décodeurs (#209).
Le défaut
Dans un scrub réel (logs
OPENSCREEN_CLIPSWITCH_TIMING), ~13 % des franchissements restaient à ~190 ms au lieu du POOL_HIT attendu. Cause : un décodeur réactivé depuis le pool est souvent laissé en fin de flux (on venait d'y scruber près de la fin avant de le quitter). Quand on y revient et qu'on le repositionne un peu plus loin, le chemin rapidedecode_forward_tobute sur l'EOF et rendaitnull→swap_clip_pooledjetait la paire poolée et rouvrait tout à neuf (~190 ms). Ce sont les pires à-coups ressentis au franchissement.Le correctif
Dans
seek_to(donc utile aussi àseek_active, pas seulement au pool) : quand le décode-avant atteint l'EOF avant la cible, on ne rend plusnull— on retombe sur le seek keyframe complet juste en dessous, qui rembobine + réarme le décodeur et repart proprement. Si la cible est réellement au-delà de l'EOF, le seek complet rendnulllui aussi : comportement inchangé pour ce cas. Appliqué aux deux backends (pipeline_windows+pipeline_macos).Mesures (headless, GPU au repos)
Les reseeks près de l'EOF passent de OPEN ~190 ms → POOL_HIT ~50-80 ms. Jamais pire que l'état d'avant (le pire cas reste le même repli sur ouverture).
Sûreté
La classe « frame sans texture → preview noire » a déjà mordu dans ce fichier. Vérifié avec un harnais qui lit les pixels (pas seulement le compteur de générations) : sur 46 franchissements — sauts, retours locaux, éviction LRU 5 assets, et près de l'EOF — 0 preview noire, 0 frame stale, chaque franchissement produit une frame fraîche valide.
(Un premier jet signalait des « frames absentes » : c'étaient des faux positifs d'un
pumptrop court qui expirait avant qu'un seek keyframe près de l'EOF, GPU alors chargé par l'app de test, ait fini. GPU au repos + fenêtre large → 0.)cargo checkOK (Windows) ; le backend macOS est identique, validé par la CI Rust.Portée honnête
C'est une robustesse marginale au-dessus de #209 : elle supprime les pires spikes (les ~190 ms), pas une transformation ressentie — le scrub reste dominé par le seek keyframe (~30-90 ms, quasi incompressible en H.264 sans proxy).