Initial vid-repair scaffold
This commit is contained in:
72
vid-repair-core/src/scan/decode.rs
Normal file
72
vid-repair-core/src/scan/decode.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::rules::RuleSet;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DecodeOutput {
|
||||
pub lines: Vec<String>,
|
||||
pub early_stop: bool,
|
||||
}
|
||||
|
||||
pub fn run_decode(path: &Path, ffmpeg_path: &str, ruleset: &RuleSet) -> Result<DecodeOutput> {
|
||||
let mut child = Command::new(ffmpeg_path)
|
||||
.arg("-v")
|
||||
.arg("error")
|
||||
.arg("-i")
|
||||
.arg(path)
|
||||
.arg("-f")
|
||||
.arg("null")
|
||||
.arg("-")
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::null())
|
||||
.spawn()
|
||||
.with_context(|| format!("Failed to run ffmpeg decode for {}", path.display()))?;
|
||||
|
||||
let stderr = child.stderr.take().context("Failed to capture ffmpeg stderr")?;
|
||||
let reader = BufReader::new(stderr);
|
||||
|
||||
let early_stop = Arc::new(AtomicBool::new(false));
|
||||
let early_stop_flag = early_stop.clone();
|
||||
|
||||
let mut lines = Vec::new();
|
||||
|
||||
for line in reader.lines() {
|
||||
let line = line.unwrap_or_default();
|
||||
if line.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(line.clone());
|
||||
|
||||
if should_stop(&line, ruleset) {
|
||||
early_stop_flag.store(true, Ordering::SeqCst);
|
||||
let _ = child.kill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let _ = child.wait();
|
||||
|
||||
Ok(DecodeOutput {
|
||||
lines,
|
||||
early_stop: early_stop.load(Ordering::SeqCst),
|
||||
})
|
||||
}
|
||||
|
||||
fn should_stop(line: &str, ruleset: &RuleSet) -> bool {
|
||||
for rule in &ruleset.rules {
|
||||
if !rule.rule.stop_scan {
|
||||
continue;
|
||||
}
|
||||
|
||||
if rule.patterns.iter().any(|re| re.is_match(line)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
Reference in New Issue
Block a user