Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add developer CLI flags for tuning encoder internals
Browse files Browse the repository at this point in the history
Currently adds the following:
- `--deblock-strength`
- `--deblock-sharpness`
- `--ip-qidx-ratio`
- `--pb-qidx-ratio`
- `--b-qidx-ratio`
- `--temporal-rdo-strength`

These flags will be available only if the `devel` feature flag
is active, as they are intended to be used to ease development
and not to be tweaked by end users. rav1e continues to subscribe
to the philosophy that end users should not need to be cargo culting
their command lines to get optimal results, and we would prefer to
tune the encoder internals so that users do not have to.
shssoichiro committed Oct 28, 2022

Verified

This commit was signed with the committer’s verified signature.
codemonium Igor Artemenko
1 parent f869e16 commit f37702c
Showing 9 changed files with 212 additions and 24 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/rav1e.yml
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@ on:

jobs:
rustfmt-clippy:

runs-on: ubuntu-22.04

steps:
@@ -193,7 +192,7 @@ jobs:
- name: Check extra features
if: matrix.toolchain == 'stable' && matrix.conf == 'check-extra-feats'
run: |
cargo check --features=check_asm,capi,dump_lookahead_data,serialize,bench --all-targets
cargo check --features=check_asm,capi,dump_lookahead_data,serialize,bench,devel --all-targets
- name: Check extra features
if: matrix.toolchain == 'stable' && matrix.conf == 'check-unstable-feats'
run: |
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -24,6 +24,9 @@ default-run = "rav1e"

[features]
unstable = []
# Exposes extra flags for tuning compiler internals.
# Intended to be used by developers to find ideal internal settings.
devel = []
channel-api = ["crossbeam"]
decode_test = ["aom-sys"]
decode_test_dav1d = ["dav1d-sys"]
45 changes: 45 additions & 0 deletions src/api/config/encoder.rs
Original file line number Diff line number Diff line change
@@ -108,6 +108,50 @@ pub struct EncoderConfig {

/// Settings which affect the encoding speed vs. quality trade-off.
pub speed_settings: SpeedSettings,

/// Advanced settings which are intended for use by developers.
/// Non-developers should use the default values.
pub advanced_flags: AdvancedTuning,
}

/// Advanced settings that are intended for use by developers
/// for tuning compiler internals.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct AdvancedTuning {
/// Controls the strength of the deblock filter, as a multiplier to the default.
pub deblock_strength: f32,
/// Controls the sharpness of the deblock filter. Accepts a value from 0-7.
pub deblock_sharpness: u8,
/// Controls the ratio between intra frame and inter frame quantizers, as a multiplier.
/// Default is 1.0. Higher values create a higher quantizer difference, while lower values
/// create a lower quantizer difference. A value of 0.0 would mean that I and P quantizers
/// are the same.
pub ip_qidx_ratio: f32,
/// Controls the ratio between "P"-frame and "B"-frame quantizers, as a multiplier.
/// Default is 1.0. Higher values create a higher quantizer difference, while lower values
/// create a lower quantizer difference. A value of 0.0 would mean that P and B quantizers
/// are the same.
pub pb_qidx_ratio: f32,
/// Controls the ratio between frame quantizers in the levels of the pyramid betweem "B"-frames,
/// as a multiplier. Default is 1.0. Higher values create a higher quantizer difference,
/// while lower values create a lower quantizer difference. A value of 0.0 would mean that
/// B0 and B1 quantizers are the same.
pub b_qidx_ratio: f32,
/// Controls the strength of temporal RDO, as a multiplier to the default.
pub temporal_rdo_strength: f32,
}

impl Default for AdvancedTuning {
fn default() -> Self {
Self {
deblock_strength: 1.0,
deblock_sharpness: 0,
ip_qidx_ratio: 1.0,
pb_qidx_ratio: 1.0,
b_qidx_ratio: 1.0,
temporal_rdo_strength: 1.0,
}
}
}

/// Default preset for `EncoderConfig`: it is a balance between quality and
@@ -163,6 +207,7 @@ impl EncoderConfig {
tile_rows: 0,
tiles: 0,
speed_settings: SpeedSettings::from_preset(speed),
advanced_flags: Default::default(),
}
}

2 changes: 2 additions & 0 deletions src/api/test.rs
Original file line number Diff line number Diff line change
@@ -2164,6 +2164,7 @@ fn log_q_exp_overflow() {
},
..Default::default()
},
advanced_flags: Default::default(),
};
let config = Config::new().with_encoder_config(enc).with_threads(1);

@@ -2240,6 +2241,7 @@ fn guess_frame_subtypes_assert() {
},
..Default::default()
},
advanced_flags: Default::default(),
};
let config = Config::new().with_encoder_config(enc).with_threads(1);

62 changes: 61 additions & 1 deletion src/bin/common.rs
Original file line number Diff line number Diff line change
@@ -242,10 +242,53 @@ pub struct CliOptions {
#[clap(long, short, value_parser, help_heading = "DEBUGGING")]
pub reconstruction: Option<PathBuf>,

/// Controls the strength of the deblock filter, as a multiplier to the default.
#[cfg(feature = "devel")]
#[clap(long, value_parser = positive_float, default_value_t=1.0f32, help_heading = "ADVANCED")]
pub deblock_strength: f32,
/// Controls the sharpness of the deblock filter. Accepts a value from 0-7.
#[cfg(feature = "devel")]
#[clap(long, value_parser = clap::value_parser!(u8).range(0..=7), default_value_t=0, help_heading = "ADVANCED")]
pub deblock_sharpness: u8,
/// Controls the ratio between intra frame and inter frame quantizers, as a multiplier.
/// Higher values create a higher quantizer difference, while lower values
/// create a lower quantizer difference. A value of 0.0 would mean that I and P quantizers
/// are the same.
#[cfg(feature = "devel")]
#[clap(long, value_parser = positive_float, default_value_t=1.0f32, help_heading = "ADVANCED")]
pub ip_qidx_ratio: f32,
/// Controls the ratio between "P"-frame and "B"-frame quantizers, as a multiplier.
/// Default is 1.0. Higher values create a higher quantizer difference, while lower values
/// create a lower quantizer difference. A value of 0.0 would mean that P and B quantizers
/// are the same.
#[cfg(feature = "devel")]
#[clap(long, value_parser = positive_float, default_value_t=1.0f32, help_heading = "ADVANCED")]
pub pb_qidx_ratio: f32,
/// Controls the ratio between frame quantizers in the levels of the pyramid betweem "B"-frames,
/// as a multiplier. Default is 1.0. Higher values create a higher quantizer difference,
/// while lower values create a lower quantizer difference. A value of 0.0 would mean that
/// B0 and B1 quantizers are the same.
#[cfg(feature = "devel")]
#[clap(long, value_parser = positive_float, default_value_t=1.0f32, help_heading = "ADVANCED")]
pub b_qidx_ratio: f32,
/// Controls the strength of temporal RDO, as a multiplier to the default.
#[cfg(feature = "devel")]
#[clap(long, value_parser = positive_float, default_value_t=1.0f32, help_heading = "ADVANCED")]
pub temporal_rdo_strength: f32,

#[clap(subcommand)]
pub command: Option<Commands>,
}

#[cfg(feature = "devel")]
fn positive_float(input: &str) -> Result<f32, String> {
let value = input.parse::<f32>().map_err(|e| e.to_string())?;
if value < 0.0 {
return Err("Value must not be negative".to_string());
}
Ok(value)
}

fn get_version() -> &'static str {
static VERSION_STR: Lazy<String> = Lazy::new(|| {
format!(
@@ -299,7 +342,7 @@ pub enum Commands {
#[clap(long, short, value_parser)]
save_config: Option<PathBuf>,
/// Load the encoder configuration from a toml file
#[clap(long, short, value_parser, conflicts_with = "save-config")]
#[clap(long, short, value_parser, conflicts_with = "save_config")]
load_config: Option<PathBuf>,
},
}
@@ -484,6 +527,18 @@ pub fn parse_cli() -> Result<ParsedCliOptions, CliError> {
})
}

#[cfg(feature = "devel")]
const fn parse_advanced_flags(cli: &CliOptions) -> AdvancedTuning {
AdvancedTuning {
deblock_strength: cli.deblock_strength,
deblock_sharpness: cli.deblock_sharpness,
ip_qidx_ratio: cli.ip_qidx_ratio,
pb_qidx_ratio: cli.pb_qidx_ratio,
b_qidx_ratio: cli.b_qidx_ratio,
temporal_rdo_strength: cli.temporal_rdo_strength,
}
}

fn parse_config(matches: &CliOptions) -> Result<EncoderConfig, CliError> {
let maybe_quantizer = matches.quantizer;
let maybe_bitrate = matches.bitrate;
@@ -674,5 +729,10 @@ fn parse_config(matches: &CliOptions) -> Result<EncoderConfig, CliError> {
cfg.speed_settings.scene_detection_mode = SceneDetectionSpeed::None;
}

#[cfg(feature = "devel")]
{
cfg.advanced_flags = parse_advanced_flags(matches);
}

Ok(cfg)
}
20 changes: 18 additions & 2 deletions src/encoder.rs
Original file line number Diff line number Diff line change
@@ -470,7 +470,7 @@ impl<T: Pixel> FrameState<T> {
cdfs: CDFContext::new(0),
context_update_tile_id: 0,
max_tile_size_bytes: 0,
deblock: Default::default(),
deblock: DeblockState::new(&fi.config, fi.frame_type),
segmentation: Default::default(),
restoration: rs,
frame_me_stats: me_stats,
@@ -501,7 +501,7 @@ impl<T: Pixel> FrameState<T> {
cdfs: CDFContext::new(0),
context_update_tile_id: 0,
max_tile_size_bytes: 0,
deblock: Default::default(),
deblock: DeblockState::new(&fi.config, fi.frame_type),
segmentation: Default::default(),
restoration: rs,
frame_me_stats: FrameMEStats::new_arc_array(fi.w_in_b, fi.h_in_b),
@@ -543,6 +543,22 @@ pub struct DeblockState {
pub block_delta_multi: bool,
}

impl DeblockState {
pub fn new(config: &EncoderConfig, frame_type: FrameType) -> Self {
let mut state = DeblockState { ..Default::default() };
if frame_type == FrameType::INTER {
// Apply deblock strength only to inter frames
for level in &mut state.levels {
*level = ((*level as f32) * config.advanced_flags.deblock_strength)
.min(MAX_LOOP_FILTER as f32)
.round() as u8;
}
}
state.sharpness = config.advanced_flags.deblock_sharpness;
state
}
}

impl Default for DeblockState {
fn default() -> Self {
DeblockState {
1 change: 1 addition & 0 deletions src/fuzzing.rs
Original file line number Diff line number Diff line change
@@ -257,6 +257,7 @@ impl Arbitrary for ArbitraryEncoder {
switch_frame_interval: u.int_in_range(0..=3)?,
tune: *u.choose(&[Tune::Psnr, Tune::Psychovisual])?,
film_grain_params: None,
advanced_flags: Default::default(),
};

let frame_count =
Loading

0 comments on commit f37702c

Please sign in to comment.