Skip to content

Commit 3bf1c46

Browse files
committed
Enforce skip == true, if all tx blocks are zeros
1 parent b074992 commit 3bf1c46

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

src/encoder.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ pub fn encode_block_post_cdef<T: Pixel>(
14851485
skip: bool, cfl: CFLParams, tx_size: TxSize, tx_type: TxType,
14861486
mode_context: usize, mv_stack: &[CandidateMV], rdo_type: RDOType,
14871487
need_recon_pixel: bool, record_stats: bool,
1488-
) -> i64 {
1488+
) -> (bool, i64) {
14891489
let is_inter = !luma_mode.is_intra();
14901490
if is_inter {
14911491
assert!(luma_mode == chroma_mode);
@@ -1758,13 +1758,14 @@ pub fn write_tx_blocks<T: Pixel>(
17581758
chroma_mode: PredictionMode, tile_bo: TileBlockOffset, bsize: BlockSize,
17591759
tx_size: TxSize, tx_type: TxType, skip: bool, cfl: CFLParams,
17601760
luma_only: bool, rdo_type: RDOType, need_recon_pixel: bool,
1761-
) -> i64 {
1761+
) -> (bool, i64) {
17621762
let bw = bsize.width_mi() / tx_size.width_mi();
17631763
let bh = bsize.height_mi() / tx_size.height_mi();
17641764
let qidx = get_qidx(fi, ts, cw, tile_bo);
17651765

17661766
let PlaneConfig { xdec, ydec, .. } = ts.input.planes[1].cfg;
17671767
let mut ac: AlignedArray<[i16; 32 * 32]> = AlignedArray::uninitialized();
1768+
let mut partition_has_coeff: bool = false;
17681769
let mut tx_dist: i64 = 0;
17691770
let do_chroma = has_chroma(tile_bo, bsize, xdec, ydec);
17701771

@@ -1785,7 +1786,7 @@ pub fn write_tx_blocks<T: Pixel>(
17851786
});
17861787

17871788
let po = tx_bo.plane_offset(&ts.input.planes[0].cfg);
1788-
let (_, dist) = encode_tx_block(
1789+
let (has_coeff, dist) = encode_tx_block(
17891790
fi,
17901791
ts,
17911792
cw,
@@ -1806,6 +1807,7 @@ pub fn write_tx_blocks<T: Pixel>(
18061807
rdo_type,
18071808
need_recon_pixel,
18081809
);
1810+
partition_has_coeff |= has_coeff;
18091811
assert!(
18101812
!fi.use_tx_domain_distortion || need_recon_pixel || skip || dist >= 0
18111813
);
@@ -1814,7 +1816,7 @@ pub fn write_tx_blocks<T: Pixel>(
18141816
}
18151817

18161818
if luma_only {
1817-
return tx_dist;
1819+
return (partition_has_coeff, tx_dist);
18181820
};
18191821

18201822
let uv_tx_size = bsize.largest_chroma_tx_size(xdec, ydec);
@@ -1870,7 +1872,7 @@ pub fn write_tx_blocks<T: Pixel>(
18701872
let mut po = tile_bo.plane_offset(&ts.input.planes[p].cfg);
18711873
po.x += (bx * uv_tx_size.width()) as isize;
18721874
po.y += (by * uv_tx_size.height()) as isize;
1873-
let (_, dist) = encode_tx_block(
1875+
let (has_coeff, dist) = encode_tx_block(
18741876
fi,
18751877
ts,
18761878
cw,
@@ -1891,6 +1893,7 @@ pub fn write_tx_blocks<T: Pixel>(
18911893
rdo_type,
18921894
need_recon_pixel,
18931895
);
1896+
partition_has_coeff |= has_coeff;
18941897
assert!(
18951898
!fi.use_tx_domain_distortion
18961899
|| need_recon_pixel
@@ -1903,7 +1906,7 @@ pub fn write_tx_blocks<T: Pixel>(
19031906
}
19041907
}
19051908

1906-
tx_dist
1909+
(partition_has_coeff, tx_dist)
19071910
}
19081911

19091912
// FIXME: For now, assume tx_mode is LARGEST_TX, so var-tx is not implemented yet,
@@ -1914,14 +1917,18 @@ pub fn write_tx_tree<T: Pixel>(
19141917
tile_bo: TileBlockOffset, bsize: BlockSize, tx_size: TxSize,
19151918
tx_type: TxType, skip: bool, luma_only: bool, rdo_type: RDOType,
19161919
need_recon_pixel: bool,
1917-
) -> i64 {
1920+
) -> (bool, i64) {
1921+
if skip {
1922+
return (false, -1);
1923+
}
19181924
let bw = bsize.width_mi() / tx_size.width_mi();
19191925
let bh = bsize.height_mi() / tx_size.height_mi();
19201926
let qidx = get_qidx(fi, ts, cw, tile_bo);
19211927

19221928
let PlaneConfig { xdec, ydec, .. } = ts.input.planes[1].cfg;
19231929
let ac = &[0i16; 0];
19241930
let mut tx_dist: i64 = 0;
1931+
let mut partition_has_coeff: bool = false;
19251932

19261933
ts.qc.update(
19271934
qidx,
@@ -1954,13 +1961,14 @@ pub fn write_tx_tree<T: Pixel>(
19541961
rdo_type,
19551962
need_recon_pixel,
19561963
);
1964+
partition_has_coeff |= has_coeff;
19571965
assert!(
19581966
!fi.use_tx_domain_distortion || need_recon_pixel || skip || dist >= 0
19591967
);
19601968
tx_dist += dist;
19611969

19621970
if luma_only {
1963-
return tx_dist;
1971+
return (partition_has_coeff, tx_dist);
19641972
};
19651973

19661974
let uv_tx_size = bsize.largest_chroma_tx_size(xdec, ydec);
@@ -2008,7 +2016,7 @@ pub fn write_tx_tree<T: Pixel>(
20082016
let mut po = tile_bo.plane_offset(&ts.input.planes[p].cfg);
20092017
po.x += (bx * uv_tx_size.width()) as isize;
20102018
po.y += (by * uv_tx_size.height()) as isize;
2011-
let (_, dist) = encode_tx_block(
2019+
let (has_coeff, dist) = encode_tx_block(
20122020
fi,
20132021
ts,
20142022
cw,
@@ -2029,6 +2037,7 @@ pub fn write_tx_tree<T: Pixel>(
20292037
rdo_type,
20302038
need_recon_pixel,
20312039
);
2040+
partition_has_coeff |= has_coeff;
20322041
assert!(
20332042
!fi.use_tx_domain_distortion
20342043
|| need_recon_pixel
@@ -2041,7 +2050,7 @@ pub fn write_tx_tree<T: Pixel>(
20412050
}
20422051
}
20432052

2044-
tx_dist
2053+
(partition_has_coeff, tx_dist)
20452054
}
20462055

20472056
pub fn encode_block_with_modes<T: Pixel>(
@@ -2055,7 +2064,7 @@ pub fn encode_block_with_modes<T: Pixel>(
20552064
let cfl = mode_decision.pred_cfl_params;
20562065
let ref_frames = mode_decision.ref_frames;
20572066
let mvs = mode_decision.mvs;
2058-
let skip = mode_decision.skip;
2067+
let mut skip = mode_decision.skip;
20592068
let mut cdef_coded = cw.bc.cdef_coded;
20602069
let (tx_size, tx_type) = (mode_decision.tx_size, mode_decision.tx_type);
20612070

@@ -2075,6 +2084,9 @@ pub fn encode_block_with_modes<T: Pixel>(
20752084
let mode_context =
20762085
cw.find_mvrefs(tile_bo, ref_frames, &mut mv_stack, bsize, fi, is_compound);
20772086

2087+
if !mode_decision.skip && !mode_decision.has_coeff {
2088+
skip = true;
2089+
}
20782090
cdef_coded = encode_block_pre_cdef(
20792091
&fi.sequence,
20802092
ts,

src/rdo.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub struct RDOPartitionOutput {
9494
pub ref_frames: [RefType; 2],
9595
pub mvs: [MotionVector; 2],
9696
pub skip: bool,
97+
pub has_coeff: bool,
9798
pub tx_size: TxSize,
9899
pub tx_type: TxType,
99100
pub sidx: u8,
@@ -564,6 +565,7 @@ struct EncodingSettings {
564565
mode_chroma: PredictionMode,
565566
cfl_params: CFLParams,
566567
skip: bool,
568+
has_coeff: bool,
567569
rd: f64,
568570
ref_frames: [RefType; 2],
569571
mvs: [MotionVector; 2],
@@ -579,6 +581,7 @@ impl Default for EncodingSettings {
579581
mode_chroma: PredictionMode::DC_PRED,
580582
cfl_params: CFLParams::default(),
581583
skip: false,
584+
has_coeff: false,
582585
rd: std::f64::MAX,
583586
ref_frames: [INTRA_FRAME, NONE_FRAME],
584587
mvs: [MotionVector::default(); 2],
@@ -655,7 +658,7 @@ fn luma_chroma_mode_rdo<T: Pixel>(
655658
luma_mode_is_intra && tx_size.block_size() != bsize;
656659

657660
encode_block_pre_cdef(&fi.sequence, ts, cw, wr, bsize, tile_bo, skip);
658-
let tx_dist = encode_block_post_cdef(
661+
let (has_coeff, tx_dist) = encode_block_post_cdef(
659662
fi,
660663
ts,
661664
cw,
@@ -701,6 +704,7 @@ fn luma_chroma_mode_rdo<T: Pixel>(
701704
best.ref_frames = ref_frames;
702705
best.mvs = mvs;
703706
best.skip = skip;
707+
best.has_coeff = has_coeff;
704708
best.tx_size = tx_size;
705709
best.tx_type = tx_type;
706710
best.sidx = sidx;
@@ -1100,6 +1104,7 @@ pub fn rdo_mode_decision<T: Pixel>(
11001104
let chroma_mode = PredictionMode::UV_CFL_PRED;
11011105
let cw_checkpoint = cw.checkpoint();
11021106
let wr: &mut dyn Writer = &mut WriterCounter::new();
1107+
11031108
write_tx_blocks(
11041109
fi,
11051110
ts,
@@ -1132,7 +1137,7 @@ pub fn rdo_mode_decision<T: Pixel>(
11321137
tile_bo,
11331138
best.skip,
11341139
);
1135-
let _ = encode_block_post_cdef(
1140+
let (has_coeff, _) = encode_block_post_cdef(
11361141
fi,
11371142
ts,
11381143
cw,
@@ -1163,6 +1168,7 @@ pub fn rdo_mode_decision<T: Pixel>(
11631168
if rd < best.rd {
11641169
best.rd = rd;
11651170
best.mode_chroma = chroma_mode;
1171+
best.has_coeff = has_coeff;
11661172
best.cfl_params = cfl;
11671173
}
11681174

@@ -1186,6 +1192,7 @@ pub fn rdo_mode_decision<T: Pixel>(
11861192
mvs: best.mvs,
11871193
rd_cost: best.rd,
11881194
skip: best.skip,
1195+
has_coeff: best.has_coeff,
11891196
tx_size: best.tx_size,
11901197
tx_type: best.tx_type,
11911198
sidx: best.sidx,
@@ -1305,7 +1312,7 @@ pub fn rdo_tx_type_decision<T: Pixel>(
13051312

13061313
let wr: &mut dyn Writer = &mut WriterCounter::new();
13071314
let tell = wr.tell_frac();
1308-
let tx_dist = if is_inter {
1315+
let (_, tx_dist) = if is_inter {
13091316
write_tx_tree(
13101317
fi,
13111318
ts,

0 commit comments

Comments
 (0)