Fix some clippy warnings, use enums instead of strings (#309)

This commit is contained in:
redzic 2021-07-18 21:04:08 -05:00 committed by GitHub
parent c2ec5a929f
commit 0b7391c434
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 264 deletions

View file

@ -1,6 +1,7 @@
use std::path::Path;
use av1an_cli::Args;
use av1an_core::vapoursynth;
use av1an_pyo3::{hash_path, is_vapoursynth, Project};
use clap::Clap;
@ -31,7 +32,7 @@ pub fn main() {
.to_owned()
},
ffmpeg: if let Some(s) = args.ffmpeg {
shlex::split(&s).unwrap_or_else(|| Vec::new())
shlex::split(&s).unwrap_or_else(Vec::new)
} else {
Vec::new()
},
@ -44,7 +45,7 @@ pub fn main() {
args.encoder.get_default_pass()
},
video_params: if let Some(params) = args.video_params {
shlex::split(&params).unwrap_or_else(|| Vec::new())
shlex::split(&params).unwrap_or_else(Vec::new)
} else {
Vec::new()
},
@ -59,16 +60,16 @@ pub fn main() {
)
},
audio_params: if let Some(params) = args.audio_params {
shlex::split(&params).unwrap_or_else(|| Vec::new())
shlex::split(&params).unwrap_or_else(|| vec!["-c:a".into(), "copy".into()])
} else {
vec!["-c:a".into(), "copy".into()]
},
ffmpeg_pipe: Vec::new(),
chunk_method: args
.chunk_method
.map(|cm| <&'static str>::from(cm).to_owned()),
.unwrap_or_else(|| vapoursynth::select_chunk_method().unwrap()),
concat: <&'static str>::from(args.concat).to_owned(),
encoder: <&'static str>::from(args.encoder).to_owned(),
encoder: args.encoder,
extra_splits_len: Some(args.extra_split),
input: args.input.to_str().unwrap().to_owned(),
keep: args.keep,
@ -85,7 +86,7 @@ pub fn main() {
scenes: args
.scenes
.map(|scenes| scenes.to_str().unwrap().to_owned()),
split_method: <&'static str>::from(args.split_method).to_owned(),
split_method: args.split_method,
target_quality: args.target_quality,
target_quality_method: Some(args.target_quality_method),
vmaf: args.vmaf,

View file

@ -5,7 +5,7 @@ extern crate log;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt::Error;
use std::fmt::{Display, Error};
use std::fs;
use std::path::Path;
use std::process::{Command, Stdio};
@ -39,6 +39,12 @@ pub enum Encoder {
x265,
}
impl Display for Encoder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(<&'static str>::from(self))
}
}
macro_rules! into_vec {
($($x:expr),* $(,)?) => {
vec![
@ -109,7 +115,7 @@ impl Encoder {
}
}
pub fn compose_1_2_pass(&self, params: Vec<String>, fpf: String) -> Vec<String> {
pub fn compose_1_2_pass(&self, params: Vec<String>, fpf: &str) -> Vec<String> {
match &self {
// Aomenc
Self::aom => chain!(
@ -221,7 +227,7 @@ impl Encoder {
}
}
pub fn compose_2_2_pass(&self, params: Vec<String>, fpf: String, output: String) -> Vec<String> {
pub fn compose_2_2_pass(&self, params: Vec<String>, fpf: &str, output: String) -> Vec<String> {
match &self {
Self::aom => chain!(
into_vec!["aomenc", "--passes=2", "--pass=2"],
@ -295,7 +301,7 @@ impl Encoder {
}
}
pub fn get_default_arguments(&self) -> Vec<&str> {
pub fn get_default_arguments(&self) -> Vec<String> {
match &self {
Encoder::aom => into_vec![
"--threads=8",
@ -413,7 +419,7 @@ impl Encoder {
}
pub fn man_command(&self, params: Vec<String>, q: usize) -> Vec<String> {
let index = list_index_of_regex(params.clone(), self.q_regex_str()).unwrap();
let index = list_index_of_regex(&params, self.q_regex_str()).unwrap();
let mut new_params = params;
let (replace_index, replace_q) = self.replace_q(index, q);
@ -658,17 +664,17 @@ impl Encoder {
}
// Function unwrap cow strings that take in a vec of strings and returns a vec of strings.
pub fn decow_strings(&self, args: Vec<Cow<str>>) -> Vec<String> {
pub fn decow_strings(&self, args: &[Cow<str>]) -> Vec<String> {
args.iter().map(|s| s.to_string()).collect::<Vec<String>>()
}
pub fn probe_cmd(
&self,
temp: String,
name: String,
name: &str,
q: String,
ffmpeg_pipe: Vec<String>,
probing_rate: String,
probing_rate: &str,
n_threads: String,
video_params: Vec<String>,
probe_slow: bool,
@ -709,11 +715,11 @@ impl Encoder {
];
args = self.remove_patterns(args, patterns);
let ps = self.construct_target_quality_command_probe_slow(q);
params = self.decow_strings(ps);
params = self.decow_strings(&ps);
params.append(&mut args)
} else {
let ps = self.construct_target_quality_command(n_threads, q);
params = self.decow_strings(ps);
params = self.decow_strings(&ps);
}
let output: Vec<String> = match &self {
@ -745,7 +751,7 @@ pub fn compose_ffmpeg_pipe(params: Vec<String>) -> Vec<String> {
p
}
pub fn list_index_of_regex(params: Vec<String>, regex_str: &str) -> Option<usize> {
pub fn list_index_of_regex(params: &[String], regex_str: &str) -> Option<usize> {
let re = Regex::new(regex_str).unwrap();
assert!(
@ -779,12 +785,16 @@ pub enum SplitMethod {
None,
}
#[derive(PartialEq, Eq, Serialize, Deserialize, Debug, strum::EnumString, strum::IntoStaticStr)]
#[derive(
PartialEq, Eq, Copy, Clone, Serialize, Deserialize, Debug, strum::EnumString, strum::IntoStaticStr,
)]
pub enum ChunkMethod {
#[strum(serialize = "select")]
Select,
#[strum(serialize = "hybrid")]
Hybrid,
#[strum(serialize = "segment")]
Segment,
#[strum(serialize = "ffms2")]
FFMS2,
#[strum(serialize = "lsmash")]

View file

@ -870,9 +870,7 @@ fn run(args: &[&str]) -> Result<(), Error> {
pub fn select_chunk_method() -> Result<ChunkMethod, Error> {
// Create a new VSScript environment.
let environment = Environment::new().context("Couldn't create the VSScript environment")?;
let core = environment
.get_core()
.context("Couldn't get the VapourSynth core")?;
let core = environment.get_core()?;
let plugins = core.plugins();
let plugins: HashSet<&str> = plugins

View file

@ -173,13 +173,13 @@ pub fn plot_vmaf(source: &Path, output: &Path) -> Result<(), Error> {
}
pub fn run_vmaf_on_chunk(
encoded: PathBuf,
pipe_cmd: Vec<String>,
stat_file: PathBuf,
model: String,
res: String,
encoded: &Path,
pipe_cmd: &[String],
stat_file: &Path,
model: &str,
res: &str,
sample_rate: usize,
vmaf_filter: String,
vmaf_filter: &str,
threads: usize,
) -> Result<(), Error> {
// Select filter for sampling from the source

View file

@ -1,4 +1,4 @@
use av1an_core::vapoursynth;
use av1an_core::{vapoursynth, SplitMethod};
use av1an_core::{ChunkMethod, Encoder};
use anyhow::anyhow;
@ -24,7 +24,6 @@ use std::io::Write;
use std::iter;
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::FromStr;
use std::time::Instant;
use std::{collections::hash_map::DefaultHasher, path::PathBuf};
@ -44,13 +43,10 @@ pub fn hash_path(path: &str) -> String {
format!("{:x}", s.finish())[..7].to_string()
}
fn create_vs_file(temp: &str, source: &str, chunk_method: &str) -> anyhow::Result<String> {
fn create_vs_file(temp: &str, source: &str, chunk_method: ChunkMethod) -> anyhow::Result<String> {
// only for python code, remove if being called by rust
let temp = Path::new(temp);
let source = Path::new(source).canonicalize()?;
let chunk_method = ChunkMethod::from_str(chunk_method)
// TODO implement this in the FromStr implementation itself
.unwrap();
let load_script_path = temp.join("split").join("loadscript.vpy");
@ -157,92 +153,11 @@ fn log(msg: &str) -> anyhow::Result<()> {
Ok(())
}
fn get_default_cq_range(encoder: &str) -> anyhow::Result<(usize, usize)> {
Ok(Encoder::from_str(&encoder).unwrap().get_default_cq_range())
}
fn get_default_arguments(encoder: &str) -> anyhow::Result<Vec<String>> {
let encoder = Encoder::from_str(&encoder).unwrap();
let default_arguments = encoder.get_default_arguments();
Ok(
default_arguments
.iter()
.map(|&s| s.to_string())
.collect::<Vec<String>>(),
)
}
fn help_command(encoder: &str) -> anyhow::Result<Vec<String>> {
let encoder = Encoder::from_str(&encoder).unwrap();
let help_command = encoder.help_command();
Ok(
help_command
.iter()
.map(|&s| s.to_string())
.collect::<Vec<String>>(),
)
}
fn encoder_bin(encoder: &str) -> anyhow::Result<String> {
Ok(Encoder::from_str(&encoder).unwrap().encoder_bin().into())
}
fn output_extension(encoder: &str) -> anyhow::Result<String> {
Ok(
Encoder::from_str(&encoder)
.unwrap()
.output_extension()
.into(),
)
}
fn compose_ffmpeg_pipe(params: Vec<String>) -> anyhow::Result<Vec<String>> {
let res = av1an_core::compose_ffmpeg_pipe(params);
Ok(res)
}
fn compose_1_1_pass(
encoder: String,
params: Vec<String>,
output: String,
) -> anyhow::Result<Vec<String>> {
let enc = Encoder::from_str(&encoder).unwrap();
Ok(enc.compose_1_1_pass(params, output))
}
fn compose_1_2_pass(
encoder: String,
params: Vec<String>,
fpf: String,
) -> anyhow::Result<Vec<String>> {
let enc = Encoder::from_str(&encoder).unwrap();
Ok(enc.compose_1_2_pass(params, fpf))
}
fn compose_2_2_pass(
encoder: String,
params: Vec<String>,
fpf: String,
output: String,
) -> anyhow::Result<Vec<String>> {
let enc = Encoder::from_str(&encoder).unwrap();
Ok(enc.compose_2_2_pass(params, fpf, output))
}
fn man_command(encoder: String, params: Vec<String>, q: usize) -> Vec<String> {
let enc = Encoder::from_str(&encoder).unwrap();
enc.man_command(params, q)
}
fn match_line(encoder: &str, line: &str) -> anyhow::Result<usize> {
let enc = Encoder::from_str(encoder).unwrap();
Ok(enc.match_line(line).unwrap())
}
fn weighted_search(
num1: f64,
vmaf1: f64,
@ -255,30 +170,6 @@ fn weighted_search(
))
}
fn probe_cmd(
encoder: String,
temp: String,
name: String,
q: String,
ffmpeg_pipe: Vec<String>,
probing_rate: String,
n_threads: String,
video_params: Vec<String>,
probe_slow: bool,
) -> anyhow::Result<(Vec<String>, Vec<String>)> {
let encoder = Encoder::from_str(&encoder).unwrap();
Ok(encoder.probe_cmd(
temp,
name,
q,
ffmpeg_pipe,
probing_rate,
n_threads,
video_params,
probe_slow,
))
}
pub fn get_percentile(scores: Vec<f64>, percent: f64) -> anyhow::Result<f64> {
// pyo3 doesn't seem to support `mut` in function declarations, so this is necessary
let mut scores = scores;
@ -421,7 +312,7 @@ impl<'a> Queue<'a> {
.map(|(rx, queue)| {
s.spawn(move |_| {
while let Ok(mut chunk) = rx.recv() {
if let Err(_) = queue.encode_chunk(&mut chunk) {
if queue.encode_chunk(&mut chunk).is_err() {
return Err(());
}
}
@ -441,7 +332,6 @@ impl<'a> Queue<'a> {
Ok(())
}
#[must_use]
fn encode_chunk(&self, chunk: &mut Chunk) -> Result<(), String> {
let st_time = Instant::now();
@ -537,7 +427,7 @@ struct TargetQuality {
target: f32,
min_q: u32,
max_q: u32,
encoder: String,
encoder: Encoder,
ffmpeg_pipe: Vec<String>,
temp: String,
workers: usize,
@ -565,7 +455,7 @@ impl TargetQuality {
target: project.target_quality.unwrap(),
min_q: project.min_q.unwrap(),
max_q: project.max_q.unwrap(),
encoder: project.encoder.clone(),
encoder: project.encoder,
ffmpeg_pipe: project.ffmpeg_pipe.clone(),
temp: project.temp.clone(),
workers: project.workers,
@ -691,18 +581,16 @@ impl TargetQuality {
self.n_threads
};
let cmd = probe_cmd(
self.encoder.clone(),
let cmd = self.encoder.probe_cmd(
self.temp.clone(),
chunk.name(),
&chunk.name(),
q.clone(),
self.ffmpeg_pipe.clone(),
self.probing_rate.to_string(),
&self.probing_rate.to_string(),
n_threads.to_string(),
self.video_params.clone(),
self.probe_slow,
)
.unwrap();
);
let future = async {
let mut ffmpeg_gen_pipe = tokio::process::Command::new(chunk.ffmpeg_gen_cmd[0].clone())
@ -735,7 +623,7 @@ impl TargetQuality {
process_pipe(
&mut pipe,
(&chunk).index,
chunk.index,
&mut [&mut ffmpeg_gen_pipe, &mut ffmpeg_pipe],
)
.await
@ -778,7 +666,6 @@ impl TargetQuality {
}
}
#[must_use]
async fn process_pipe(
pipe: &mut tokio::process::Child,
chunk_index: usize,
@ -849,7 +736,6 @@ fn save_chunk_queue(temp: &str, chunk_queue: Vec<Chunk>) {
.unwrap();
}
#[derive(Default)]
pub struct Project {
pub frames: usize,
pub is_vs: bool,
@ -861,15 +747,15 @@ pub struct Project {
pub output_ivf: bool,
pub webm: bool,
pub chunk_method: Option<String>,
pub chunk_method: ChunkMethod,
pub scenes: Option<String>,
pub split_method: String,
pub split_method: SplitMethod,
pub extra_splits_len: Option<usize>,
pub min_scene_len: usize,
pub passes: u8,
pub video_params: Vec<String>,
pub encoder: String,
pub encoder: Encoder,
pub workers: usize,
// FFmpeg params
@ -904,7 +790,7 @@ pub struct Project {
static HELP_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"\s+(-\w+|(?:--\w+(?:-\w+)*))").unwrap());
// TODO refactor to make types generic
fn invalid_params<'a>(params: &[String], valid_options: &HashSet<String>) -> Vec<String> {
fn invalid_params(params: &[String], valid_options: &HashSet<String>) -> Vec<String> {
params
.iter()
.filter_map(|param| {
@ -946,12 +832,8 @@ impl Project {
.collect::<Result<Vec<_>, _>>()
.unwrap();
queue_files.retain(|file| file.is_file());
queue_files.retain(
|file| match Path::new(&file).extension().map(|x| x == "mkv") {
Some(true) => true,
_ => false,
},
);
queue_files
.retain(|file| matches!(Path::new(&file).extension().map(|x| x == "mkv"), Some(true)));
av1an_core::concat::sort_files_by_filename(&mut queue_files);
queue_files
@ -965,32 +847,26 @@ impl Project {
.join(format!("{}_fpf", c.name()));
let mut enc_cmd = if self.passes == 1 {
compose_1_1_pass(self.encoder.clone(), self.video_params.clone(), c.output()).unwrap()
self
.encoder
.compose_1_1_pass(self.video_params.clone(), c.output())
} else if current_pass == 1 {
self.encoder.compose_1_2_pass(
self.video_params.clone(),
&fpf_file.to_str().unwrap().to_owned(),
)
} else {
if current_pass == 1 {
compose_1_2_pass(
self.encoder.clone(),
self.video_params.clone(),
fpf_file.to_str().unwrap().to_owned(),
)
.unwrap()
} else {
compose_2_2_pass(
self.encoder.clone(),
self.video_params.clone(),
fpf_file.to_str().unwrap().to_owned(),
c.output(),
)
.unwrap()
}
self.encoder.compose_2_2_pass(
self.video_params.clone(),
&fpf_file.to_str().unwrap().to_owned(),
c.output(),
)
};
if let Some(per_shot_target_quality_cq) = c.per_shot_target_quality_cq {
enc_cmd = man_command(
self.encoder.clone(),
enc_cmd,
per_shot_target_quality_cq as usize,
);
enc_cmd = self
.encoder
.man_command(enc_cmd, per_shot_target_quality_cq as usize);
}
let mut encoder_history: VecDeque<String> = VecDeque::with_capacity(20);
@ -1044,13 +920,13 @@ impl Project {
let line = std::str::from_utf8(&buf);
if let Ok(line) = line {
let new = match_line(&self.encoder, &line).unwrap();
if let Some(new) = self.encoder.match_line(line) {
encoder_history.push_back(line.to_owned());
encoder_history.push_back(line.to_owned());
if new > frame {
update_bar((new - frame) as u64).unwrap();
frame = new;
if new > frame {
update_bar((new - frame) as u64).unwrap();
frame = new;
}
}
}
@ -1091,42 +967,29 @@ impl Project {
self.frames = if self.is_vs {
vapoursynth::num_frames(Path::new(&self.input)).unwrap()
} else {
if ["ffms2", "lsmash"].contains(&self.chunk_method.as_ref().unwrap().as_str()) {
let vs = if self.is_vs {
self.input.clone()
} else {
create_vs_file(
&self.temp,
&self.input,
&self.chunk_method.as_ref().unwrap(),
)
.unwrap()
};
let fr = vapoursynth::num_frames(Path::new(&vs)).unwrap();
if fr > 0 {
fr
} else {
panic!("vapoursynth reported 0 frames")
}
} else if matches!(self.chunk_method, ChunkMethod::FFMS2 | ChunkMethod::LSMASH) {
let vs = if self.is_vs {
self.input.clone()
} else {
ffmpeg_get_frame_count(&self.input)
create_vs_file(&self.temp, &self.input, self.chunk_method).unwrap()
};
let fr = vapoursynth::num_frames(Path::new(&vs)).unwrap();
if fr > 0 {
fr
} else {
panic!("vapoursynth reported 0 frames")
}
} else {
ffmpeg_get_frame_count(&self.input)
};
self.frames
}
fn select_best_chunking_method(&mut self) {
let chunk_method = av1an_core::vapoursynth::select_chunk_method().unwrap();
self.chunk_method = Some(<&'static str>::from(chunk_method).to_string());
}
/// returns a list of valid parameters
#[must_use]
fn valid_encoder_params(&self) -> HashSet<String> {
let help = help_command(&self.encoder).unwrap();
let help = self.encoder.help_command();
let help_text = String::from_utf8(
Command::new(&help[0])
@ -1183,14 +1046,14 @@ impl Project {
}
pub fn startup_check(&mut self) -> anyhow::Result<()> {
if ["rav1e", "aom", "svt_av1", "vpx"].contains(&self.encoder.as_str()) && self.output_ivf {
if matches!(
self.encoder,
Encoder::rav1e | Encoder::aom | Encoder::svt_av1 | Encoder::libvpx
) && self.output_ivf
{
panic!(".ivf only supports VP8, VP9, and AV1");
}
if self.chunk_method.is_none() {
self.select_best_chunking_method();
}
assert!(
Path::new(&self.input).exists(),
"Input file {:?} does not exist!",
@ -1213,19 +1076,19 @@ impl Project {
println!("Target quality with less than 4 probes is experimental and not recommended");
}
if let Ok((min, max)) = get_default_cq_range(&self.encoder) {
match self.min_q {
None => {
self.min_q = Some(min as u32);
}
Some(min_q) => assert!(min_q > 1),
}
if let None = self.max_q {
self.max_q = Some(max as u32);
let (min, max) = self.encoder.get_default_cq_range();
match self.min_q {
None => {
self.min_q = Some(min as u32);
}
Some(min_q) => assert!(min_q > 1),
}
let encoder_bin = encoder_bin(&self.encoder).unwrap();
if self.max_q.is_none() {
self.max_q = Some(max as u32);
}
let encoder_bin = self.encoder.encoder_bin();
let settings_valid = which::which(&encoder_bin).is_ok();
if !settings_valid {
@ -1236,7 +1099,7 @@ impl Project {
}
if self.video_params.is_empty() {
self.video_params = get_default_arguments(&self.encoder).unwrap();
self.video_params = self.encoder.get_default_arguments();
}
self.validate_inputs();
@ -1256,12 +1119,11 @@ impl Project {
}
fn create_encoding_queue(&mut self, splits: Vec<usize>) -> Vec<Chunk> {
let mut chunks = match self.chunk_method.as_ref().unwrap().as_str() {
"ffms2" | "lsmash" => self.create_video_queue_vs(splits),
"hybrid" => self.create_video_queue_hybrid(splits),
"select" => self.create_video_queue_select(splits),
"segment" => self.create_video_queue_segment(splits),
_ => unreachable!(),
let mut chunks = match self.chunk_method {
ChunkMethod::FFMS2 | ChunkMethod::LSMASH => self.create_video_queue_vs(splits),
ChunkMethod::Hybrid => self.create_video_queue_hybrid(splits),
ChunkMethod::Select => self.create_video_queue_select(splits),
ChunkMethod::Segment => self.create_video_queue_segment(splits),
};
chunks.sort_unstable_by_key(|chunk| Reverse(chunk.size));
@ -1270,8 +1132,8 @@ impl Project {
}
fn calc_split_locations(&self) -> Vec<usize> {
match self.split_method.as_str() {
"av-scenechange" => av_scenechange_detect(
match self.split_method {
SplitMethod::AvScenechange => av_scenechange_detect(
&self.input,
self.frames,
self.min_scene_len,
@ -1279,8 +1141,7 @@ impl Project {
self.is_vs,
)
.unwrap(),
"none" => Vec::with_capacity(0),
_ => unreachable!(),
SplitMethod::None => Vec::with_capacity(0),
}
}
@ -1354,7 +1215,8 @@ impl Project {
"yuv4mpegpipe".into(),
"-".into(),
];
let output_ext = output_extension(&self.encoder).unwrap();
let output_ext = self.encoder.output_extension().to_owned();
// use the number of frames to prioritize which chunks encode first, since we don't have file size
let size = frames;
@ -1396,13 +1258,13 @@ impl Project {
frame_end.to_string(),
];
let output_ext = output_extension(&self.encoder).unwrap();
let output_ext = self.encoder.output_extension();
Chunk {
temp: self.temp.clone(),
index,
ffmpeg_gen_cmd: vspipe_cmd_gen,
output_ext,
output_ext: output_ext.to_owned(),
// use the number of frames to prioritize which chunks encode first, since we don't have file size
size: frames,
frames,
@ -1426,12 +1288,7 @@ impl Project {
let vs_script = if self.is_vs {
self.input.clone()
} else {
create_vs_file(
&self.temp,
&self.input,
&self.chunk_method.as_ref().unwrap(),
)
.unwrap()
create_vs_file(&self.temp, &self.input, self.chunk_method).unwrap()
};
let chunk_queue: Vec<Chunk> = chunk_boundaries
@ -1566,7 +1423,7 @@ impl Project {
"-".into(),
];
let output_ext = output_extension(&self.encoder).unwrap();
let output_ext = self.encoder.output_extension().to_owned();
let file_size = File::open(file).unwrap().metadata().unwrap().len();
Chunk {
@ -1662,7 +1519,7 @@ impl Project {
}
if self.workers == 0 {
self.workers = determine_workers(Encoder::from_str(&self.encoder).unwrap()).unwrap() as usize;
self.workers = determine_workers(self.encoder).unwrap() as usize;
}
self.workers = cmp::min(self.workers, chunk_queue.len());
println!(
@ -1680,7 +1537,7 @@ impl Project {
let temp = self.temp.clone();
let input = self.input.clone();
let output_file = self.output_file.clone();
let encoder = self.encoder.clone();
let encoder = self.encoder;
let vmaf = self.vmaf;
let keep = self.keep;
@ -1708,11 +1565,7 @@ impl Project {
av1an_core::concat::concatenate_mkvmerge(temp.clone(), output_file.clone()).unwrap()
}
"ffmpeg" => {
av1an_core::ffmpeg::concatenate_ffmpeg(
temp.clone(),
output_file.clone(),
Encoder::from_str(&encoder).unwrap(),
);
av1an_core::ffmpeg::concatenate_ffmpeg(temp.clone(), output_file.clone(), encoder);
}
_ => unreachable!(),
}
@ -1741,13 +1594,13 @@ fn run_vmaf_on_chunk(
let stat_file = PathBuf::from(stat_file);
av1an_core::vmaf::run_vmaf_on_chunk(
encoded,
pipe_cmd,
stat_file,
model,
res,
&encoded,
&pipe_cmd,
&stat_file,
&model,
&res,
sample_rate,
vmaf_filter,
&vmaf_filter,
threads,
)
.unwrap()