deepshrink_ffmpeg/
caps.rs1use std::path::Path;
9use std::process::Command;
10
11pub fn has_encoder(ffmpeg: &Path, name: &str) -> bool {
16 Command::new(ffmpeg)
17 .args(["-hide_banner", "-encoders"])
18 .output()
19 .map(|o| {
20 let text = String::from_utf8_lossy(&o.stdout);
21 encoder_listed(&text, name)
22 })
23 .unwrap_or(false)
24}
25
26pub fn has_filter(ffmpeg: &Path, name: &str) -> bool {
29 Command::new(ffmpeg)
30 .args(["-hide_banner", "-filters"])
31 .output()
32 .map(|o| filter_listed(&String::from_utf8_lossy(&o.stdout), name))
33 .unwrap_or(false)
34}
35
36pub(crate) fn filter_listed(listing: &str, name: &str) -> bool {
38 listing.lines().any(|line| {
39 let mut cols = line.split_whitespace();
40 let flags = cols.next().unwrap_or("");
41 flags.len() <= 3 && flags.chars().all(|c| "TSC.".contains(c)) && cols.next() == Some(name)
42 })
43}
44
45pub(crate) fn encoder_listed(listing: &str, name: &str) -> bool {
48 listing.lines().any(|line| {
49 let mut cols = line.split_whitespace();
51 let flags = cols.next().unwrap_or("");
52 flags.len() == 6 && cols.next() == Some(name)
54 })
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn filters_table_is_parsed_by_exact_name() {
63 let listing = " TS colorspace V->V Convert between colorspaces.\n \
64 .S tonemap V->V Conversion to/from different dynamic ranges.\n";
65 assert!(filter_listed(listing, "tonemap"));
66 assert!(filter_listed(listing, "colorspace"));
67 assert!(!filter_listed(listing, "zscale"));
68 assert!(!filter_listed(listing, "V->V"));
69 }
70
71 const LISTING: &str = "Encoders:
72 V..... libx264 libx264 H.264 / AVC (codec h264)
73 V..... libsvtav1 SVT-AV1 encoder (codec av1)
74 A....D aac AAC (Advanced Audio Coding)
75";
76
77 #[test]
78 fn finds_a_listed_encoder() {
79 assert!(encoder_listed(LISTING, "libsvtav1"));
80 assert!(encoder_listed(LISTING, "libx264"));
81 assert!(encoder_listed(LISTING, "aac"));
82 }
83
84 #[test]
85 fn rejects_absent_and_description_only_matches() {
86 assert!(!encoder_listed(LISTING, "libaom-av1"));
87 assert!(!encoder_listed(LISTING, "av1"));
89 assert!(!encoder_listed(LISTING, "Encoders:"));
90 }
91}