Set log level in FFmpeg + small fixes (#376)

* Small fixes/cleanup

* Set log level to fatal in ffmpeg

* Update dependencies
This commit is contained in:
redzic 2021-10-08 18:47:08 -05:00 committed by GitHub
parent f5c3b3c85a
commit 9b1a00775b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 43 deletions

24
Cargo.lock generated
View file

@ -257,9 +257,9 @@ dependencies = [
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitstream-io"
@ -299,9 +299,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cc"
version = "1.0.70"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
dependencies = [
"jobserver",
]
@ -440,9 +440,9 @@ dependencies = [
[[package]]
name = "ctrlc"
version = "3.2.0"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "377c9b002a72a0b2c1a18c62e2f3864bdfea4a015e3683a96e24aa45dd6c02d1"
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
dependencies = [
"nix",
"winapi",
@ -770,9 +770,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.22.2"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3bb9a13fa32bc5aeb64150cd3f32d6cf4c748f8f8a417cce5d2eb976a8370ba"
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
dependencies = [
"bitflags",
"cc",
@ -1008,9 +1008,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
@ -1365,9 +1365,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.78"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0"
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
dependencies = [
"proc-macro2",
"quote",

View file

@ -1,4 +1,4 @@
use crate::{into_vec, list_index_of_regex, regex};
use crate::{into_vec, list_index, regex};
use itertools::chain;
use regex::Regex;
use serde::{Deserialize, Serialize};
@ -321,13 +321,13 @@ impl Encoder {
}
}
/// Returns regex used for matching q/crf arguments in command line
fn q_regex(self) -> &'static Regex {
match &self {
Self::aom | Self::vpx => regex!(r"--cq-level=.+"),
Self::rav1e => regex!(r"--quantizer"),
Self::svt_av1 => regex!(r"(--qp|-q|--crf)"),
Self::x264 | Self::x265 => regex!(r"--crf"),
/// Returns function pointer used for matching q/crf arguments in command line
fn q_match_fn(self) -> fn(&str) -> bool {
match self {
Self::aom | Self::vpx => |p| p.starts_with("--cq-level="),
Self::rav1e => |p| p == "--quantizer",
Self::svt_av1 => |p| matches!(p, "--qp" | "-q" | "--crf"),
Self::x264 | Self::x265 => |p| p == "--crf",
}
}
@ -340,7 +340,7 @@ impl Encoder {
/// Returns changed q/crf in command line arguments
pub fn man_command(self, params: Vec<String>, q: usize) -> Vec<String> {
let index = list_index_of_regex(&params, self.q_regex())
let index = list_index(&params, self.q_match_fn())
.unwrap_or_else(|| panic!("No match found for params: {:#?}", params));
let mut new_params = params;

View file

@ -24,7 +24,6 @@ use crate::{
use chunk::Chunk;
use dashmap::DashMap;
use once_cell::sync::OnceCell;
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::{
collections::hash_map::DefaultHasher,
@ -145,19 +144,16 @@ fn init_done(done: DoneJson) -> &'static DoneJson {
DONE_JSON.get_or_init(|| done)
}
pub fn list_index_of_regex(params: &[impl AsRef<str>], re: &Regex) -> Option<usize> {
assert!(
!params.is_empty(),
"List index of regex got empty list of params"
);
pub fn list_index(params: &[impl AsRef<str>], is_match: fn(&str) -> bool) -> Option<usize> {
assert!(!params.is_empty(), "received empty list of parameters");
for (i, cmd) in params.iter().enumerate() {
if re.is_match(cmd.as_ref()) {
return Some(i);
params.iter().enumerate().find_map(|(idx, s)| {
if is_match(s.as_ref()) {
Some(idx)
} else {
None
}
}
None
})
}
#[derive(Serialize, Deserialize, Debug, strum::EnumString, strum::IntoStaticStr)]

View file

@ -23,6 +23,7 @@ use flexi_logger::{Duplicate, FileSpec, Logger};
use itertools::Itertools;
use path_abs::PathAbs;
use std::{
borrow::Cow,
cmp,
cmp::{Ordering, Reverse},
collections::HashSet,
@ -92,6 +93,7 @@ impl EncodeArgs {
/// Initialize logging routines and create temporary directories
pub fn initialize(&mut self) -> anyhow::Result<()> {
ffmpeg_next::init()?;
ffmpeg_next::util::log::set_level(ffmpeg_next::util::log::level::Level::Fatal);
info!("File hash: {}", hash_path(self.input.as_path()));
@ -336,7 +338,6 @@ impl EncodeArgs {
let [cmd, arg] = self.encoder.help_command();
String::from_utf8(Command::new(cmd).arg(arg).output().unwrap().stdout).unwrap()
};
let valid_params = valid_params(&help_text);
let invalid_params = invalid_params(&video_params, &valid_params);
@ -400,9 +401,7 @@ impl EncodeArgs {
}
let encoder_bin = self.encoder.bin();
let settings_valid = which::which(&encoder_bin).is_ok();
if !settings_valid {
if which::which(encoder_bin).is_err() {
bail!(
"Encoder {} not found. Is it installed in the system path?",
encoder_bin
@ -565,7 +564,7 @@ impl EncodeArgs {
fn create_vs_chunk(
&self,
index: usize,
vs_script: PathBuf,
vs_script: &Path,
frame_start: usize,
mut frame_end: usize,
) -> Chunk {
@ -614,16 +613,18 @@ impl EncodeArgs {
.map(|(start, end)| (*start, *end))
.collect();
let vs_script = match &self.input {
Input::VapourSynth(path) => path.clone(),
Input::Video(path) => create_vs_file(&self.temp, path, self.chunk_method).unwrap(),
let vs_script: Cow<Path> = match &self.input {
Input::VapourSynth(path) => Cow::Borrowed(path.as_ref()),
Input::Video(path) => {
Cow::Owned(create_vs_file(&self.temp, path, self.chunk_method).unwrap())
}
};
let chunk_queue: Vec<Chunk> = chunk_boundaries
.iter()
.enumerate()
.map(|(index, (frame_start, frame_end))| {
self.create_vs_chunk(index, vs_script.clone(), *frame_start, *frame_end)
self.create_vs_chunk(index, &vs_script, *frame_start, *frame_end)
})
.collect();

View file

@ -8,7 +8,7 @@
## Description
Target Quality has a really simple goal, instead of guessing what the CQ/CRF value to choose for desired level of video quality we set quality level we wan, quality goal is set in value of VMAF score we want to achieve and let the algorithm find CRF/CQ value that will result in that score, for each segment. Which simultaneously achieve 3 things, if compared to usual, single value CRF/CQ encode.
Target Quality has a really simple goal, instead of guessing what the CQ/CRF value to choose for desired level of video quality we set quality level we want, quality goal is set in value of VMAF score we want to achieve and let the algorithm find CRF/CQ value that will result in that score, for each segment. Which simultaneously achieve 3 things, if compared to usual, single value CRF/CQ encode.
- Ensuring better level of visual consistency than default rate controls
- Give enough bitrate to complex segments to match target quality.