Skip to content

Commit 7baa93f

Browse files
committed
Do not round in get_mv_rate except for original resolution
1 parent 9d50709 commit 7baa93f

File tree

1 file changed

+36
-22
lines changed

1 file changed

+36
-22
lines changed

src/me.rs

+36-22
Original file line numberDiff line numberDiff line change
@@ -610,12 +610,13 @@ pub fn estimate_motion<T: Pixel>(
610610
w,
611611
h,
612612
best.mv,
613+
ssdec,
613614
);
614615
}
615616

616617
sub_pixel_me(
617618
fi, po, org_region, p_ref, lambda, pmv, mvx_min, mvx_max, mvy_min,
618-
mvy_max, w, h, use_satd, &mut best, ref_frame,
619+
mvy_max, w, h, use_satd, &mut best, ref_frame, ssdec,
619620
);
620621
}
621622

@@ -676,6 +677,7 @@ fn refine_subsampled_motion_estimate<T: Pixel>(
676677
let y_hi = po.y + (mv.row as isize / 8 + 2).min(mvy_max / 8);
677678
let mut results = full_search(
678679
fi, x_lo, x_hi, y_lo, y_hi, w, h, org_region, p_ref, po, 1, lambda, pmv,
680+
ssdec,
679681
);
680682

681683
// Scale motion vectors to full res size
@@ -732,6 +734,7 @@ fn full_pixel_me<T: Pixel>(
732734
mvy_max,
733735
w,
734736
h,
737+
ssdec,
735738
);
736739
fullpel_diamond_search(
737740
fi,
@@ -748,6 +751,7 @@ fn full_pixel_me<T: Pixel>(
748751
mvy_max,
749752
w,
750753
h,
754+
ssdec,
751755
);
752756

753757
if results.rd.cost < best.rd.cost {
@@ -807,6 +811,7 @@ fn full_pixel_me<T: Pixel>(
807811
h,
808812
// Use 24, since it is the largest range that x264 uses.
809813
24,
814+
ssdec,
810815
);
811816

812817
if !fi.config.speed_settings.motion.me_allow_full_search
@@ -841,6 +846,7 @@ fn full_pixel_me<T: Pixel>(
841846
4 >> ssdec,
842847
lambda,
843848
[MotionVector::default(); 2],
849+
ssdec,
844850
);
845851

846852
if results.rd.cost < best.rd.cost {
@@ -857,6 +863,7 @@ fn sub_pixel_me<T: Pixel>(
857863
p_ref: &Plane<T>, lambda: u32, pmv: [MotionVector; 2], mvx_min: isize,
858864
mvx_max: isize, mvy_min: isize, mvy_max: isize, w: usize, h: usize,
859865
use_satd: bool, best: &mut MotionSearchResult, ref_frame: RefType,
866+
ssdec: u8,
860867
) {
861868
subpel_diamond_search(
862869
fi,
@@ -875,21 +882,22 @@ fn sub_pixel_me<T: Pixel>(
875882
use_satd,
876883
best,
877884
ref_frame,
885+
ssdec,
878886
);
879887
}
880888

881889
fn get_best_predictor<T: Pixel>(
882890
fi: &FrameInvariants<T>, po: PlaneOffset, org_region: &PlaneRegion<T>,
883891
p_ref: &Plane<T>, predictors: &[MotionVector], bit_depth: usize,
884892
pmv: [MotionVector; 2], lambda: u32, mvx_min: isize, mvx_max: isize,
885-
mvy_min: isize, mvy_max: isize, w: usize, h: usize,
893+
mvy_min: isize, mvy_max: isize, w: usize, h: usize, ssdec: u8,
886894
) -> MotionSearchResult {
887895
let mut best: MotionSearchResult = MotionSearchResult::empty();
888896

889897
for &init_mv in predictors.iter() {
890898
let rd = get_fullpel_mv_rd(
891899
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
892-
mvx_max, mvy_min, mvy_max, w, h, init_mv,
900+
mvx_max, mvy_min, mvy_max, w, h, init_mv, ssdec,
893901
);
894902

895903
if rd.cost < best.rd.cost {
@@ -952,7 +960,7 @@ fn fullpel_diamond_search<T: Pixel>(
952960
fi: &FrameInvariants<T>, po: PlaneOffset, org_region: &PlaneRegion<T>,
953961
p_ref: &Plane<T>, current: &mut MotionSearchResult, bit_depth: usize,
954962
pmv: [MotionVector; 2], lambda: u32, mvx_min: isize, mvx_max: isize,
955-
mvy_min: isize, mvy_max: isize, w: usize, h: usize,
963+
mvy_min: isize, mvy_max: isize, w: usize, h: usize, ssdec: u8,
956964
) {
957965
// Define the initial and the final scale (log2) of the diamond.
958966
let (mut diamond_radius_log2, diamond_radius_end_log2) = (1u8, 0u8);
@@ -964,7 +972,7 @@ fn fullpel_diamond_search<T: Pixel>(
964972
let cand_mv = current.mv + (offset << diamond_radius_log2);
965973
let rd = get_fullpel_mv_rd(
966974
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
967-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
975+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
968976
);
969977

970978
if rd.cost < best_cand.rd.cost {
@@ -1051,7 +1059,7 @@ fn hexagon_search<T: Pixel>(
10511059
fi: &FrameInvariants<T>, po: PlaneOffset, org_region: &PlaneRegion<T>,
10521060
p_ref: &Plane<T>, current: &mut MotionSearchResult, bit_depth: usize,
10531061
pmv: [MotionVector; 2], lambda: u32, mvx_min: isize, mvx_max: isize,
1054-
mvy_min: isize, mvy_max: isize, w: usize, h: usize,
1062+
mvy_min: isize, mvy_max: isize, w: usize, h: usize, ssdec: u8,
10551063
) {
10561064
// The first iteration of hexagon search is implemented separate from
10571065
// subsequent iterations, which overlap with previous iterations.
@@ -1067,7 +1075,7 @@ fn hexagon_search<T: Pixel>(
10671075
let cand_mv = current.mv + HEXAGON_PATTERN[i];
10681076
let rd = get_fullpel_mv_rd(
10691077
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1070-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1078+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
10711079
);
10721080

10731081
if rd.cost < best_cand.rd.cost {
@@ -1099,7 +1107,7 @@ fn hexagon_search<T: Pixel>(
10991107

11001108
let rd = get_fullpel_mv_rd(
11011109
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1102-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1110+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
11031111
);
11041112

11051113
if rd.cost < best_cand.rd.cost {
@@ -1116,7 +1124,7 @@ fn hexagon_search<T: Pixel>(
11161124
let cand_mv = current.mv + offset;
11171125
let rd = get_fullpel_mv_rd(
11181126
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1119-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1127+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
11201128
);
11211129

11221130
if rd.cost < best_cand.rd.cost {
@@ -1166,6 +1174,7 @@ fn uneven_multi_hex_search<T: Pixel>(
11661174
p_ref: &Plane<T>, current: &mut MotionSearchResult, bit_depth: usize,
11671175
pmv: [MotionVector; 2], lambda: u32, mvx_min: isize, mvx_max: isize,
11681176
mvy_min: isize, mvy_max: isize, w: usize, h: usize, me_range: i16,
1177+
ssdec: u8,
11691178
) {
11701179
assert!(!current.is_empty());
11711180

@@ -1196,7 +1205,7 @@ fn uneven_multi_hex_search<T: Pixel>(
11961205
let cand_mv = center + offset * i;
11971206
let rd = get_fullpel_mv_rd(
11981207
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1199-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1208+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
12001209
);
12011210

12021211
if rd.cost < current.rd.cost {
@@ -1217,7 +1226,7 @@ fn uneven_multi_hex_search<T: Pixel>(
12171226
let cand_mv = center + offset * i;
12181227
let rd = get_fullpel_mv_rd(
12191228
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1220-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1229+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
12211230
);
12221231

12231232
if rd.cost < current.rd.cost {
@@ -1237,7 +1246,7 @@ fn uneven_multi_hex_search<T: Pixel>(
12371246
let cand_mv = center + MotionVector { row, col };
12381247
let rd = get_fullpel_mv_rd(
12391248
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1240-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1249+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
12411250
);
12421251

12431252
if rd.cost < current.rd.cost {
@@ -1279,7 +1288,7 @@ fn uneven_multi_hex_search<T: Pixel>(
12791288
let cand_mv = center + offset * i;
12801289
let rd = get_fullpel_mv_rd(
12811290
fi, po, org_region, p_ref, bit_depth, pmv, lambda, false, mvx_min,
1282-
mvx_max, mvy_min, mvy_max, w, h, cand_mv,
1291+
mvx_max, mvy_min, mvy_max, w, h, cand_mv, ssdec,
12831292
);
12841293

12851294
if rd.cost < current.rd.cost {
@@ -1292,7 +1301,7 @@ fn uneven_multi_hex_search<T: Pixel>(
12921301
// Refine the search results using a 'normal' hexagon search.
12931302
hexagon_search(
12941303
fi, po, org_region, p_ref, current, bit_depth, pmv, lambda, mvx_min,
1295-
mvx_max, mvy_min, mvy_max, w, h,
1304+
mvx_max, mvy_min, mvy_max, w, h, ssdec,
12961305
);
12971306
}
12981307

@@ -1306,7 +1315,7 @@ fn subpel_diamond_search<T: Pixel>(
13061315
_p_ref: &Plane<T>, bit_depth: usize, pmv: [MotionVector; 2], lambda: u32,
13071316
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize, w: usize,
13081317
h: usize, use_satd: bool, current: &mut MotionSearchResult,
1309-
ref_frame: RefType,
1318+
ref_frame: RefType, ssdec: u8,
13101319
) {
13111320
use crate::util::Aligned;
13121321

@@ -1352,6 +1361,7 @@ fn subpel_diamond_search<T: Pixel>(
13521361
cand_mv,
13531362
&mut tmp_region,
13541363
ref_frame,
1364+
ssdec,
13551365
);
13561366

13571367
if rd.cost < best_cand.rd.cost {
@@ -1380,7 +1390,7 @@ fn get_fullpel_mv_rd<T: Pixel>(
13801390
fi: &FrameInvariants<T>, po: PlaneOffset, org_region: &PlaneRegion<T>,
13811391
p_ref: &Plane<T>, bit_depth: usize, pmv: [MotionVector; 2], lambda: u32,
13821392
use_satd: bool, mvx_min: isize, mvx_max: isize, mvy_min: isize,
1383-
mvy_max: isize, w: usize, h: usize, cand_mv: MotionVector,
1393+
mvy_max: isize, w: usize, h: usize, cand_mv: MotionVector, ssdec: u8,
13841394
) -> MVCandidateRD {
13851395
if (cand_mv.col as isize) < mvx_min
13861396
|| (cand_mv.col as isize) > mvx_max
@@ -1397,7 +1407,7 @@ fn get_fullpel_mv_rd<T: Pixel>(
13971407
});
13981408
compute_mv_rd(
13991409
fi, pmv, lambda, use_satd, bit_depth, w, h, cand_mv, org_region,
1400-
&plane_ref,
1410+
&plane_ref, ssdec,
14011411
)
14021412
}
14031413

@@ -1406,7 +1416,7 @@ fn get_subpel_mv_rd<T: Pixel>(
14061416
bit_depth: usize, pmv: [MotionVector; 2], lambda: u32, use_satd: bool,
14071417
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize, w: usize,
14081418
h: usize, cand_mv: MotionVector, tmp_region: &mut PlaneRegionMut<T>,
1409-
ref_frame: RefType,
1419+
ref_frame: RefType, ssdec: u8,
14101420
) -> MVCandidateRD {
14111421
if (cand_mv.col as isize) < mvx_min
14121422
|| (cand_mv.col as isize) > mvx_max
@@ -1429,7 +1439,7 @@ fn get_subpel_mv_rd<T: Pixel>(
14291439
let plane_ref = tmp_region.as_const();
14301440
compute_mv_rd(
14311441
fi, pmv, lambda, use_satd, bit_depth, w, h, cand_mv, org_region,
1432-
&plane_ref,
1442+
&plane_ref, ssdec,
14331443
)
14341444
}
14351445

@@ -1438,16 +1448,18 @@ fn get_subpel_mv_rd<T: Pixel>(
14381448
fn compute_mv_rd<T: Pixel>(
14391449
fi: &FrameInvariants<T>, pmv: [MotionVector; 2], lambda: u32,
14401450
use_satd: bool, bit_depth: usize, w: usize, h: usize, cand_mv: MotionVector,
1441-
plane_org: &PlaneRegion<'_, T>, plane_ref: &PlaneRegion<'_, T>,
1451+
plane_org: &PlaneRegion<'_, T>, plane_ref: &PlaneRegion<'_, T>, ssdec: u8,
14421452
) -> MVCandidateRD {
14431453
let sad = if use_satd {
14441454
get_satd(plane_org, plane_ref, w, h, bit_depth, fi.cpu_feature_level)
14451455
} else {
14461456
get_sad(plane_org, plane_ref, w, h, bit_depth, fi.cpu_feature_level)
14471457
};
14481458

1449-
let rate1 = get_mv_rate(cand_mv, pmv[0], fi.allow_high_precision_mv);
1450-
let rate2 = get_mv_rate(cand_mv, pmv[1], fi.allow_high_precision_mv);
1459+
let rate1 =
1460+
get_mv_rate(cand_mv, pmv[0], fi.allow_high_precision_mv || ssdec > 0);
1461+
let rate2 =
1462+
get_mv_rate(cand_mv, pmv[1], fi.allow_high_precision_mv || ssdec > 0);
14511463
let rate = rate1.min(rate2 + 1);
14521464

14531465
MVCandidateRD { cost: 256 * sad as u64 + rate as u64 * lambda as u64, sad }
@@ -1457,6 +1469,7 @@ fn full_search<T: Pixel>(
14571469
fi: &FrameInvariants<T>, x_lo: isize, x_hi: isize, y_lo: isize, y_hi: isize,
14581470
w: usize, h: usize, org_region: &PlaneRegion<T>, p_ref: &Plane<T>,
14591471
po: PlaneOffset, step: usize, lambda: u32, pmv: [MotionVector; 2],
1472+
ssdec: u8,
14601473
) -> MotionSearchResult {
14611474
let search_region = p_ref.region(Area::Rect {
14621475
x: x_lo,
@@ -1488,6 +1501,7 @@ fn full_search<T: Pixel>(
14881501
mv,
14891502
org_region,
14901503
&ref_window,
1504+
ssdec,
14911505
);
14921506

14931507
if rd.cost < best.rd.cost {

0 commit comments

Comments
 (0)