diff --git a/av1an-core/src/encoder.rs b/av1an-core/src/encoder.rs index 11dcfbb9..c1db4912 100644 --- a/av1an-core/src/encoder.rs +++ b/av1an-core/src/encoder.rs @@ -439,7 +439,7 @@ impl Encoder { "--scenecut", "0", ], Encoder::x265 => into_vec![ - "-p", "slow", + "--preset", "slow", "--crf", "25", "-D", "10", "--level-idc", "5.0", diff --git a/av1an-core/src/lib.rs b/av1an-core/src/lib.rs index 1ec769c5..71e8422d 100644 --- a/av1an-core/src/lib.rs +++ b/av1an-core/src/lib.rs @@ -330,7 +330,7 @@ pub enum ChunkOrdering { #[must_use] pub fn determine_workers(args: &EncodeArgs) -> u64 { let res = args.input.resolution().unwrap(); - let tiles = args.input.calculate_tiles(); + let tiles = args.tiles; let megapixels = (res.0 * res.1) as f64 / 1e6; // encoder memory and chunk_method memory usage scales with resolution (megapixels), // approximately linearly. Expressed as GB/Megapixel diff --git a/av1an-core/src/settings.rs b/av1an-core/src/settings.rs index ceff5c71..87e80d17 100644 --- a/av1an-core/src/settings.rs +++ b/av1an-core/src/settings.rs @@ -55,6 +55,7 @@ pub struct EncodeArgs { pub passes: u8, pub video_params: Vec, + pub tiles: (u32, u32), // tile (cols, rows) count; log2 will be applied later for specific encoders pub encoder: Encoder, pub workers: usize, pub set_thread_affinity: Option, @@ -74,6 +75,7 @@ pub struct EncodeArgs { pub resume: bool, pub keep: bool, pub force: bool, + pub tile_auto: bool, pub concat: ConcatMethod, pub target_quality: Option, @@ -171,13 +173,17 @@ properly into a mkv file. Specify mkvmerge as the concatenation method by settin ); } + if self.tile_auto { + self.tiles = self.input.calculate_tiles(); + } + if !self.force { if self.video_params.is_empty() { - self.video_params = self.encoder.get_default_arguments(self.input.calculate_tiles()); + self.video_params = self.encoder.get_default_arguments(self.tiles); } else { // merge video_params with defaults, overriding defaults // TODO: consider using hashmap to store program arguments instead of string vector - let default_video_params = self.encoder.get_default_arguments(self.input.calculate_tiles()); + let default_video_params = self.encoder.get_default_arguments(self.tiles); let mut skip = false; let mut _default_params: Vec = Vec::new(); for param in default_video_params { diff --git a/av1an/src/main.rs b/av1an/src/main.rs index ce4bb28f..09281b7a 100644 --- a/av1an/src/main.rs +++ b/av1an/src/main.rs @@ -295,6 +295,12 @@ pub struct CliOpts { #[clap(short, long, value_parser = value_parser!(u8).range(1..=2), help_heading = "Encoding")] pub passes: Option, + /// Estimate tile count from source + /// + /// Worker estimation will consider tile count accordingly. + #[clap(long, help_heading = "Encoding")] + pub tile_auto: bool, + /// Audio encoding parameters (ffmpeg syntax) /// /// If not specified, "-c:a copy" is used. @@ -752,6 +758,8 @@ pub fn parse_cli(args: CliOpts) -> anyhow::Result> { Verbosity::Normal }, workers: args.workers, + tiles: (1, 1), // default value; will be adjusted if tile_auto set + tile_auto: args.tile_auto, set_thread_affinity: args.set_thread_affinity, zones: args.zones.clone(), scaler: { diff --git a/site/src/Cli/encoding.md b/site/src/Cli/encoding.md index f541ca11..a3a35460 100644 --- a/site/src/Cli/encoding.md +++ b/site/src/Cli/encoding.md @@ -29,6 +29,9 @@ [possible values: 1, 2] +--tile-auto + Estimate tile count based on resolution, and set encoder parameters, if applicable. + -a, --audio-params Audio encoding parameters (ffmpeg syntax)