Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions crates/compositor/src/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,45 @@ struct PrefetchedClip {
/// Ouvre + positionne la paire de décodeurs d'un clip (même travail que
/// `Player::set_active_clip`, mais autonome — sans instance `Player` existante, pour pouvoir
/// tourner sur un thread dédié pendant que le `Player` réel joue encore le clip actif).
/// Ouvre le décodeur webcam, ou un remplaçant quand le clip n'a pas de caméra.
///
/// La question « ce chemin désigne-t-il une vraie caméra ? » a déjà une réponse dans ce
/// crate : `webcam_is_real`. Elle couvre le chemin vide, le chemin composé d'espaces, et le
/// cas où l'appelant renvoie le chemin de l'écran lui-même — ce que fait `ExportDialog.tsx`
/// et ce que contiennent les scènes plus anciennes. Un simple `is_empty()` en raterait deux
/// sur trois, et le commentaire de `webcam_is_real` rappelle que c'est exactement cet oubli
/// qui avait mis l'enregistrement d'écran dans la vignette caméra (#265).
///
/// Sans caméra, le remplaçant est l'écran : le moteur veut une paire de décodeurs toujours
/// valide plutôt qu'un `Option` à dérouler sur tout le chemin chaud, et rien ne le dessine
/// puisque la composition ne pose une vignette que si le document déclare une caméra.
///
/// Avec une caméra déclarée dont le fichier ne s'ouvre pas, c'est l'inverse : la vignette
/// EST dessinée et affiche l'écran. Ce cas-là méritait une trace, et n'en avait aucune.
///
/// ponytail: on garde le remplaçant plutôt que de passer `wdec` en `Option<Decoder>`, ce qui
/// toucherait 22 sites dont le pool de décodeurs et la boucle de composition `unsafe`. À faire
/// si quelqu'un mesure que le décodeur inutile coûte (VRAM des pools D3D11VA, une ouverture
/// par clip) — l'avertissement ci-dessous dit enfin à quelle fréquence le cas visible arrive.
unsafe fn open_webcam_or_stand_in(
screen_path: &str,
webcam_path: &str,
gpu: &Gpu,
) -> Result<Decoder> {
if !webcam_is_real(webcam_path, screen_path) {
return Decoder::open(screen_path, gpu);
}
match Decoder::open(webcam_path, gpu) {
Ok(d) => Ok(d),
Err(e) => {
eprintln!(
"WARNING: caméra déclarée mais illisible ({webcam_path}) : {e}. La vignette caméra affichera l'enregistrement d'écran ; le média est à relier."
);
Decoder::open(screen_path, gpu)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}
}

unsafe fn open_and_seek_clip(
screen_path: &str,
webcam_path: &str,
Expand All @@ -85,10 +124,7 @@ unsafe fn open_and_seek_clip(
) -> Result<PrefetchedClip> {
let source_time_sec = source_time_sec.max(0.0);
let mut sdec = Decoder::open(screen_path, gpu)?;
let mut wdec = match Decoder::open(webcam_path, gpu) {
Ok(d) => d,
Err(_) => Decoder::open(screen_path, gpu)?,
};
let mut wdec = open_webcam_or_stand_in(screen_path, webcam_path, gpu)?;
let sf = sdec.seek_to(source_time_sec)?;
let mut wf = wdec.seek_to(webcam_seek_time(source_time_sec, webcam_offset_sec))?;
if wf.is_null() {
Expand Down Expand Up @@ -225,10 +261,7 @@ pub struct Player {

impl Player {
pub unsafe fn open(screen: &str, webcam: &str, gpu: &Gpu) -> Result<Player> {
let wdec = match Decoder::open(webcam, gpu) {
Ok(d) => d,
Err(_) => Decoder::open(screen, gpu)?,
};
let wdec = open_webcam_or_stand_in(screen, webcam, gpu)?;
Ok(Player {
sdec: Decoder::open(screen, gpu)?,
wdec,
Expand Down
Loading