Skip to content

Commit bab3903

Browse files
rom1vtdaede
authored andcommitted
Use TileRect to fix inter-prediction offsets
The inter prediction also suffered from the same confusion between absolute offsets and offsets relative to the current tile as intra prediction. Pass TileRect to convert from frame offsets to tile offsets.
1 parent 6b6c2ba commit bab3903

File tree

3 files changed

+34
-16
lines changed

3 files changed

+34
-16
lines changed

src/encoder.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,18 +1102,21 @@ pub fn motion_compensate<T: Pixel>(
11021102
) {
11031103
debug_assert!(!luma_mode.is_intra());
11041104

1105-
let PlaneConfig { xdec, ydec, .. } = ts.input.planes[1].cfg;
1105+
let PlaneConfig { xdec: u_xdec, ydec: u_ydec, .. } = ts.input.planes[1].cfg;
11061106

11071107
// Inter mode prediction can take place once for a whole partition,
11081108
// instead of each tx-block.
1109-
let num_planes = 1 + if !luma_only && has_chroma(tile_bo, bsize, xdec, ydec) { 2 } else { 0 };
1109+
let num_planes = 1 + if !luma_only && has_chroma(tile_bo, bsize, u_xdec, u_ydec) { 2 } else { 0 };
11101110

1111+
let luma_tile_rect = ts.tile_rect();
11111112
for p in 0..num_planes {
11121113
let plane_bsize = if p == 0 { bsize }
1113-
else { get_plane_block_size(bsize, xdec, ydec) };
1114+
else { get_plane_block_size(bsize, u_xdec, u_ydec) };
11141115

11151116
let rec = &mut ts.rec.planes[p];
11161117
let po = tile_bo.plane_offset(&rec.plane_cfg);
1118+
let &PlaneConfig { xdec, ydec, .. } = rec.plane_cfg;
1119+
let tile_rect = luma_tile_rect.decimated(xdec, ydec);
11171120

11181121
let area = Area::BlockStartingAt { bo: tile_bo };
11191122
if p > 0 && bsize < BlockSize::BLOCK_8X8 {
@@ -1126,10 +1129,10 @@ pub fn motion_compensate<T: Pixel>(
11261129
some_use_intra |= cw.bc.blocks[tile_bo.with_offset(-1,-1)].mode.is_intra(); };
11271130

11281131
if some_use_intra {
1129-
luma_mode.predict_inter(fi, p, po, &mut rec.subregion_mut(area), plane_bsize.width(),
1132+
luma_mode.predict_inter(fi, tile_rect, p, po, &mut rec.subregion_mut(area), plane_bsize.width(),
11301133
plane_bsize.height(), ref_frames, mvs);
11311134
} else {
1132-
assert!(xdec == 1 && ydec == 1);
1135+
assert!(u_xdec == 1 && u_ydec == 1);
11331136
// TODO: these are absolutely only valid for 4:2:0
11341137
if bsize == BlockSize::BLOCK_4X4 {
11351138
let mv0 = cw.bc.blocks[tile_bo.with_offset(-1,-1)].mv;
@@ -1144,30 +1147,30 @@ pub fn motion_compensate<T: Pixel>(
11441147
let area2 = Area::StartingAt { x: po2.x, y: po2.y };
11451148
let po3 = PlaneOffset { x: po.x+2, y: po.y+2 };
11461149
let area3 = Area::StartingAt { x: po3.x, y: po3.y };
1147-
luma_mode.predict_inter(fi, p, po, &mut rec.subregion_mut(area), 2, 2, rf0, mv0);
1148-
luma_mode.predict_inter(fi, p, po1, &mut rec.subregion_mut(area1), 2, 2, rf1, mv1);
1149-
luma_mode.predict_inter(fi, p, po2, &mut rec.subregion_mut(area2), 2, 2, rf2, mv2);
1150-
luma_mode.predict_inter(fi, p, po3, &mut rec.subregion_mut(area3), 2, 2, ref_frames, mvs);
1150+
luma_mode.predict_inter(fi, tile_rect, p, po, &mut rec.subregion_mut(area), 2, 2, rf0, mv0);
1151+
luma_mode.predict_inter(fi, tile_rect, p, po1, &mut rec.subregion_mut(area1), 2, 2, rf1, mv1);
1152+
luma_mode.predict_inter(fi, tile_rect, p, po2, &mut rec.subregion_mut(area2), 2, 2, rf2, mv2);
1153+
luma_mode.predict_inter(fi, tile_rect, p, po3, &mut rec.subregion_mut(area3), 2, 2, ref_frames, mvs);
11511154
}
11521155
if bsize == BlockSize::BLOCK_8X4 {
11531156
let mv1 = cw.bc.blocks[tile_bo.with_offset(0,-1)].mv;
11541157
let rf1 = cw.bc.blocks[tile_bo.with_offset(0,-1)].ref_frames;
1155-
luma_mode.predict_inter(fi, p, po, &mut rec.subregion_mut(area), 4, 2, rf1, mv1);
1158+
luma_mode.predict_inter(fi, tile_rect, p, po, &mut rec.subregion_mut(area), 4, 2, rf1, mv1);
11561159
let po3 = PlaneOffset { x: po.x, y: po.y+2 };
11571160
let area3 = Area::StartingAt { x: po3.x, y: po3.y };
1158-
luma_mode.predict_inter(fi, p, po3, &mut rec.subregion_mut(area3), 4, 2, ref_frames, mvs);
1161+
luma_mode.predict_inter(fi, tile_rect, p, po3, &mut rec.subregion_mut(area3), 4, 2, ref_frames, mvs);
11591162
}
11601163
if bsize == BlockSize::BLOCK_4X8 {
11611164
let mv2 = cw.bc.blocks[tile_bo.with_offset(-1,0)].mv;
11621165
let rf2 = cw.bc.blocks[tile_bo.with_offset(-1,0)].ref_frames;
1163-
luma_mode.predict_inter(fi, p, po, &mut rec.subregion_mut(area), 2, 4, rf2, mv2);
1166+
luma_mode.predict_inter(fi, tile_rect, p, po, &mut rec.subregion_mut(area), 2, 4, rf2, mv2);
11641167
let po3 = PlaneOffset { x: po.x+2, y: po.y };
11651168
let area3 = Area::StartingAt { x: po3.x, y: po3.y };
1166-
luma_mode.predict_inter(fi, p, po3, &mut rec.subregion_mut(area3), 2, 4, ref_frames, mvs);
1169+
luma_mode.predict_inter(fi, tile_rect, p, po3, &mut rec.subregion_mut(area3), 2, 4, ref_frames, mvs);
11671170
}
11681171
}
11691172
} else {
1170-
luma_mode.predict_inter(fi, p, po, &mut rec.subregion_mut(area), plane_bsize.width(),
1173+
luma_mode.predict_inter(fi, tile_rect, p, po, &mut rec.subregion_mut(area), plane_bsize.width(),
11711174
plane_bsize.height(), ref_frames, mvs);
11721175
}
11731176
}

src/me.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,16 @@ fn get_mv_rd_cost<T: Pixel>(
841841
let plane_org = p_org.region(Area::StartingAt { x: po.x, y: po.y });
842842

843843
if let Some(ref mut tmp_plane) = tmp_plane_opt {
844+
let tile_rect = TileRect {
845+
x: 0,
846+
y: 0,
847+
width: tmp_plane.cfg.width,
848+
height: tmp_plane.cfg.height
849+
};
850+
844851
PredictionMode::NEWMV.predict_inter(
845852
fi,
853+
tile_rect,
846854
0,
847855
po,
848856
&mut tmp_plane.as_region_mut(),
@@ -900,6 +908,12 @@ fn telescopic_subpel_search<T: Pixel>(
900908
}
901909

902910
let mut tmp_plane = Plane::new(blk_w, blk_h, 0, 0, 0, 0);
911+
let tile_rect = TileRect {
912+
x: 0,
913+
y: 0,
914+
width: tmp_plane.cfg.width,
915+
height: tmp_plane.cfg.height
916+
};
903917

904918
for step in steps {
905919
let center_mv_h = *best_mv;
@@ -925,6 +939,7 @@ fn telescopic_subpel_search<T: Pixel>(
925939
{
926940
mode.predict_inter(
927941
fi,
942+
tile_rect,
928943
0,
929944
po,
930945
&mut tmp_plane.as_region_mut(),

src/partition.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,12 +1166,12 @@ impl PredictionMode {
11661166
}
11671167

11681168
pub fn predict_inter<T: Pixel>(
1169-
self, fi: &FrameInvariants<T>, p: usize, po: PlaneOffset,
1169+
self, fi: &FrameInvariants<T>, tile_rect: TileRect, p: usize, po: PlaneOffset,
11701170
dst: &mut PlaneRegionMut<'_, T>, width: usize, height: usize,
11711171
ref_frames: [RefType; 2], mvs: [MotionVector; 2]
11721172
) {
11731173
assert!(!self.is_intra());
1174-
let frame_po = dst.to_frame_plane_offset(po);
1174+
let frame_po = tile_rect.to_frame_plane_offset(po);
11751175

11761176
let mode = FilterMode::REGULAR;
11771177
let is_compound =

0 commit comments

Comments
 (0)