LR-VIEW-PHOTOGRID: the background face search skips videos, as the grid's thumbnails do

needs_search sent each video to the image decoders to look for faces; the
decode failed and the photo was left alone only for the session
(scan_failed is in memory), so every launch tried each video again,
silently. Photo::is_video now keeps videos out of the search, as it keeps
them out of the grid's thumbnails. The face search was not part of the
issue this PR fixes; it follows the same rule.

Test: cmd::face_recognize::imp::tests::a_video_is_not_searched_for_faces

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
insideTheFlux
2026-10-23 20:24:07 -07:00
co-authored by Claude Opus 5.5
parent f867bcc5f9
commit f53d55900f
2 changed files with 22 additions and 3 deletions
+20 -2
View File
@@ -345,10 +345,12 @@ mod imp {
current_with(s, cmd, true)
}
/// Whether the background scan should look for faces in this photo: it is in the library, has no face regions at all
/// (nothing from XMP, nothing drawn or named, no earlier detection) and has not been searched yet.
/// Whether the background scan should look for faces in this photo: it is in the library, is not a video (the image
/// decoders can't read one, [`Photo::is_video`]), has no face regions at all (nothing from XMP, nothing drawn or
/// named, no earlier detection) and has not been searched yet.
fn needs_search(s: &Session, photo: &Photo) -> bool {
photo.in_library()
&& !photo.is_video()
&& !photo.meta.regions.iter().any(|r| r.kind == RegionKind::Face)
&& !s.faces.scanned.contains(photo.id.0)
&& !s.faces.scan_failed.contains(&photo.id.0)
@@ -971,6 +973,22 @@ mod imp {
let _ = std::fs::remove_dir_all(&d);
}
/// A video went to the image decoders to be searched for faces and failed, once each launch: it is skipped, as the
/// grid's thumbnails skip it (issue #2682 is about those).
#[test]
fn a_video_is_not_searched_for_faces() {
let (mut s, d) = loaded("video");
let (a, _) = two_photos(&s);
let id = s.catalog.alloc_photo_id();
let path = d.join("clip.mp4").to_string_lossy().into_owned();
let clip = Photo::new(id, lightcraft_catalog::Source::File { path }, "clip.mp4", "VIDEO", 1920, 1080, "2026-10-24T00:00:00");
s.catalog.apply(Op::AddPhoto { photo: Box::new(clip) }).unwrap();
assert!(needs_search(&s, s.catalog.photo(a).unwrap()), "a photo is searched");
assert!(!needs_search(&s, s.catalog.photo(id).unwrap()));
assert!(!pending(&s, &[], true).contains(&id));
let _ = std::fs::remove_dir_all(&d);
}
#[test]
fn only_the_background_scan_looks_for_faces_and_only_in_photos_without_any() {
let (mut s, d) = loaded("search");
+2 -1
View File
@@ -6,7 +6,8 @@
- A video in the library (an MP4 or MOV brought in from a Lightroom catalog) no longer asks the image decoders for a
grid thumbnail (issue #2682). They can't read one, so each video failed with "unrecognised image format", showed a
"!" and was tried again whenever the library changed, filling the log. Its cell now keeps the plain placeholder until
LightCraft can show video frames. A video is recognised by its type, by the format `VIDEO` that Lightroom catalogs
LightCraft can show video frames. The background face search skips videos too, instead of failing on each one at
every launch. A video is recognised by its type, by the format `VIDEO` that Lightroom catalogs
give videos, or by its extension (`.mp4`, `.mov`, `.m4v`, `.avi`, `.mts`, `.m2ts`, `.3gp`, `.mkv`, `.webm`, `.wmv`,
`.mpg`, `.mpeg`).