Commit 5f4cfe7a authored by Yushin Cho's avatar Yushin Cho

Add a enable/disable switch for using segmantation

By default, segmentation is turned off.
Note that there is an existing similar flag 'segmentation.enabled' under
SegmentationState struct under TileState, and the new one from this commit is
the master switch and later will be controllable by CLI.

By not using any segment, this temporarilly fixes the ongoing desync issues caused by quantizer rdo and
heuristic quantizer choice at speed 0,1,2.
parent e6a07019
Pipeline #1793 failed with stages
in 31 minutes and 7 seconds
......@@ -568,6 +568,7 @@ pub struct FrameInvariants<T: Pixel> {
/// Target CPU feature level.
pub cpu_feature_level: crate::cpu_features::CpuFeatureLevel,
pub activity_mask: ActivityMask,
pub enable_segmentation: bool,
}
pub(crate) const fn pos_to_lvl(pos: u64, pyramid_depth: u64) -> u64 {
......@@ -739,6 +740,7 @@ impl<T: Pixel> FrameInvariants<T> {
block_importances: vec![0.; w_in_imp_b * h_in_imp_b].into_boxed_slice(),
cpu_feature_level: Default::default(),
activity_mask: Default::default(),
enable_segmentation: false,
}
}
......@@ -3427,9 +3429,10 @@ pub fn encode_frame<T: Pixel>(
debug_assert!(!fi.invalid);
let mut packet = Vec::new();
fs.segmentation = get_initial_segmentation(fi);
segmentation_optimize(fi, fs);
if fi.enable_segmentation {
fs.segmentation = get_initial_segmentation(fi);
segmentation_optimize(fi, fs);
}
let tile_group = encode_tile_group(fi, fs, inter_cfg);
write_obus(&mut packet, fi, fs, inter_cfg).unwrap();
......
......@@ -949,7 +949,9 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
fn write_segment_data<T: Pixel>(
&mut self, fi: &FrameInvariants<T>, segmentation: &SegmentationState,
) -> io::Result<()> {
self.write_bit(segmentation.enabled)?;
assert_eq!(fi.enable_segmentation, segmentation.enabled);
self.write_bit(fi.enable_segmentation)?;
if segmentation.enabled {
if fi.primary_ref_frame == PRIMARY_REF_NONE {
assert_eq!(segmentation.update_map, true);
......
......@@ -566,7 +566,7 @@ fn luma_chroma_mode_rdo<T: Pixel>(
// If skip is true, sidx is not coded.
// The sidx is coded for both quantizer_rdo and heuristic quantizer selection.
let sidx_range = if skip {
let sidx_range = if skip || !fi.enable_segmentation {
0..=0
} else if !fi.config.speed_settings.quantizer_rdo {
let importance =
......
......@@ -16,49 +16,53 @@ use crate::FrameState;
pub fn segmentation_optimize<T: Pixel>(
fi: &FrameInvariants<T>, fs: &mut FrameState<T>,
) {
assert!(fi.enable_segmentation);
fs.segmentation.enabled = true;
fs.segmentation.update_map = true;
// We don't change the values between frames.
fs.segmentation.update_data = fi.primary_ref_frame == PRIMARY_REF_NONE;
if fs.segmentation.enabled {
fs.segmentation.update_map = true;
if !fs.segmentation.update_data {
return;
}
// We don't change the values between frames.
fs.segmentation.update_data = fi.primary_ref_frame == PRIMARY_REF_NONE;
// A series of AWCY runs with deltas 13, 15, 17, 18, 19, 20, 21, 22, 23
// showed this to be the optimal one.
const TEMPORAL_RDO_QI_DELTA: i16 = 21;
if !fs.segmentation.update_data {
return;
}
// Avoid going into lossless mode by never bringing qidx below 1.
// Because base_q_idx changes more frequently than the segmentation
// data, it is still possible for a segment to enter lossless, so
// enforcement elsewhere is needed.
let offset_lower_limit = 1 - fi.base_q_idx as i16;
// A series of AWCY runs with deltas 13, 15, 17, 18, 19, 20, 21, 22, 23
// showed this to be the optimal one.
const TEMPORAL_RDO_QI_DELTA: i16 = 21;
// Fill in 3 slots with 0, delta, -delta. The slot IDs are also used in
// luma_chroma_mode_rdo() so if you change things here make sure to check
// that place too.
for i in 0..3 {
fs.segmentation.features[i][SegLvl::SEG_LVL_ALT_Q as usize] = true;
fs.segmentation.data[i][SegLvl::SEG_LVL_ALT_Q as usize] = match i {
0 => 0,
1 => TEMPORAL_RDO_QI_DELTA,
2 => (-TEMPORAL_RDO_QI_DELTA).max(offset_lower_limit),
_ => unreachable!(),
};
}
// Avoid going into lossless mode by never bringing qidx below 1.
// Because base_q_idx changes more frequently than the segmentation
// data, it is still possible for a segment to enter lossless, so
// enforcement elsewhere is needed.
let offset_lower_limit = 1 - fi.base_q_idx as i16;
/* Figure out parameters */
fs.segmentation.preskip = false;
fs.segmentation.last_active_segid = 0;
if fs.segmentation.enabled {
for i in 0..8 {
for j in 0..SegLvl::SEG_LVL_MAX as usize {
if fs.segmentation.features[i][j] {
fs.segmentation.last_active_segid = i as u8;
if j >= SegLvl::SEG_LVL_REF_FRAME as usize {
fs.segmentation.preskip = true;
// Fill in 3 slots with 0, delta, -delta. The slot IDs are also used in
// luma_chroma_mode_rdo() so if you change things here make sure to check
// that place too.
for i in 0..3 {
fs.segmentation.features[i][SegLvl::SEG_LVL_ALT_Q as usize] = true;
fs.segmentation.data[i][SegLvl::SEG_LVL_ALT_Q as usize] = match i {
0 => 0,
1 => TEMPORAL_RDO_QI_DELTA,
2 => (-TEMPORAL_RDO_QI_DELTA).max(offset_lower_limit),
_ => unreachable!(),
};
}
/* Figure out parameters */
fs.segmentation.preskip = false;
fs.segmentation.last_active_segid = 0;
if fs.segmentation.enabled {
for i in 0..8 {
for j in 0..SegLvl::SEG_LVL_MAX as usize {
if fs.segmentation.features[i][j] {
fs.segmentation.last_active_segid = i as u8;
if j >= SegLvl::SEG_LVL_REF_FRAME as usize {
fs.segmentation.preskip = true;
}
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment