@@ -610,12 +610,13 @@ pub fn estimate_motion<T: Pixel>(
610
610
w,
611
611
h,
612
612
best. mv ,
613
+ ssdec,
613
614
) ;
614
615
}
615
616
616
617
sub_pixel_me (
617
618
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 ,
619
620
) ;
620
621
}
621
622
@@ -676,6 +677,7 @@ fn refine_subsampled_motion_estimate<T: Pixel>(
676
677
let y_hi = po. y + ( mv. row as isize / 8 + 2 ) . min ( mvy_max / 8 ) ;
677
678
let mut results = full_search (
678
679
fi, x_lo, x_hi, y_lo, y_hi, w, h, org_region, p_ref, po, 1 , lambda, pmv,
680
+ ssdec,
679
681
) ;
680
682
681
683
// Scale motion vectors to full res size
@@ -732,6 +734,7 @@ fn full_pixel_me<T: Pixel>(
732
734
mvy_max,
733
735
w,
734
736
h,
737
+ ssdec,
735
738
) ;
736
739
fullpel_diamond_search (
737
740
fi,
@@ -748,6 +751,7 @@ fn full_pixel_me<T: Pixel>(
748
751
mvy_max,
749
752
w,
750
753
h,
754
+ ssdec,
751
755
) ;
752
756
753
757
if results. rd . cost < best. rd . cost {
@@ -807,6 +811,7 @@ fn full_pixel_me<T: Pixel>(
807
811
h,
808
812
// Use 24, since it is the largest range that x264 uses.
809
813
24 ,
814
+ ssdec,
810
815
) ;
811
816
812
817
if !fi. config . speed_settings . motion . me_allow_full_search
@@ -841,6 +846,7 @@ fn full_pixel_me<T: Pixel>(
841
846
4 >> ssdec,
842
847
lambda,
843
848
[ MotionVector :: default ( ) ; 2 ] ,
849
+ ssdec,
844
850
) ;
845
851
846
852
if results. rd . cost < best. rd . cost {
@@ -857,6 +863,7 @@ fn sub_pixel_me<T: Pixel>(
857
863
p_ref : & Plane < T > , lambda : u32 , pmv : [ MotionVector ; 2 ] , mvx_min : isize ,
858
864
mvx_max : isize , mvy_min : isize , mvy_max : isize , w : usize , h : usize ,
859
865
use_satd : bool , best : & mut MotionSearchResult , ref_frame : RefType ,
866
+ ssdec : u8 ,
860
867
) {
861
868
subpel_diamond_search (
862
869
fi,
@@ -875,21 +882,22 @@ fn sub_pixel_me<T: Pixel>(
875
882
use_satd,
876
883
best,
877
884
ref_frame,
885
+ ssdec,
878
886
) ;
879
887
}
880
888
881
889
fn get_best_predictor < T : Pixel > (
882
890
fi : & FrameInvariants < T > , po : PlaneOffset , org_region : & PlaneRegion < T > ,
883
891
p_ref : & Plane < T > , predictors : & [ MotionVector ] , bit_depth : usize ,
884
892
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 ,
886
894
) -> MotionSearchResult {
887
895
let mut best: MotionSearchResult = MotionSearchResult :: empty ( ) ;
888
896
889
897
for & init_mv in predictors. iter ( ) {
890
898
let rd = get_fullpel_mv_rd (
891
899
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 ,
893
901
) ;
894
902
895
903
if rd. cost < best. rd . cost {
@@ -952,7 +960,7 @@ fn fullpel_diamond_search<T: Pixel>(
952
960
fi : & FrameInvariants < T > , po : PlaneOffset , org_region : & PlaneRegion < T > ,
953
961
p_ref : & Plane < T > , current : & mut MotionSearchResult , bit_depth : usize ,
954
962
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 ,
956
964
) {
957
965
// Define the initial and the final scale (log2) of the diamond.
958
966
let ( mut diamond_radius_log2, diamond_radius_end_log2) = ( 1u8 , 0u8 ) ;
@@ -964,7 +972,7 @@ fn fullpel_diamond_search<T: Pixel>(
964
972
let cand_mv = current. mv + ( offset << diamond_radius_log2) ;
965
973
let rd = get_fullpel_mv_rd (
966
974
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 ,
968
976
) ;
969
977
970
978
if rd. cost < best_cand. rd . cost {
@@ -1051,7 +1059,7 @@ fn hexagon_search<T: Pixel>(
1051
1059
fi : & FrameInvariants < T > , po : PlaneOffset , org_region : & PlaneRegion < T > ,
1052
1060
p_ref : & Plane < T > , current : & mut MotionSearchResult , bit_depth : usize ,
1053
1061
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 ,
1055
1063
) {
1056
1064
// The first iteration of hexagon search is implemented separate from
1057
1065
// subsequent iterations, which overlap with previous iterations.
@@ -1067,7 +1075,7 @@ fn hexagon_search<T: Pixel>(
1067
1075
let cand_mv = current. mv + HEXAGON_PATTERN [ i] ;
1068
1076
let rd = get_fullpel_mv_rd (
1069
1077
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 ,
1071
1079
) ;
1072
1080
1073
1081
if rd. cost < best_cand. rd . cost {
@@ -1099,7 +1107,7 @@ fn hexagon_search<T: Pixel>(
1099
1107
1100
1108
let rd = get_fullpel_mv_rd (
1101
1109
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 ,
1103
1111
) ;
1104
1112
1105
1113
if rd. cost < best_cand. rd . cost {
@@ -1116,7 +1124,7 @@ fn hexagon_search<T: Pixel>(
1116
1124
let cand_mv = current. mv + offset;
1117
1125
let rd = get_fullpel_mv_rd (
1118
1126
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 ,
1120
1128
) ;
1121
1129
1122
1130
if rd. cost < best_cand. rd . cost {
@@ -1166,6 +1174,7 @@ fn uneven_multi_hex_search<T: Pixel>(
1166
1174
p_ref : & Plane < T > , current : & mut MotionSearchResult , bit_depth : usize ,
1167
1175
pmv : [ MotionVector ; 2 ] , lambda : u32 , mvx_min : isize , mvx_max : isize ,
1168
1176
mvy_min : isize , mvy_max : isize , w : usize , h : usize , me_range : i16 ,
1177
+ ssdec : u8 ,
1169
1178
) {
1170
1179
assert ! ( !current. is_empty( ) ) ;
1171
1180
@@ -1196,7 +1205,7 @@ fn uneven_multi_hex_search<T: Pixel>(
1196
1205
let cand_mv = center + offset * i;
1197
1206
let rd = get_fullpel_mv_rd (
1198
1207
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 ,
1200
1209
) ;
1201
1210
1202
1211
if rd. cost < current. rd . cost {
@@ -1217,7 +1226,7 @@ fn uneven_multi_hex_search<T: Pixel>(
1217
1226
let cand_mv = center + offset * i;
1218
1227
let rd = get_fullpel_mv_rd (
1219
1228
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 ,
1221
1230
) ;
1222
1231
1223
1232
if rd. cost < current. rd . cost {
@@ -1237,7 +1246,7 @@ fn uneven_multi_hex_search<T: Pixel>(
1237
1246
let cand_mv = center + MotionVector { row, col } ;
1238
1247
let rd = get_fullpel_mv_rd (
1239
1248
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 ,
1241
1250
) ;
1242
1251
1243
1252
if rd. cost < current. rd . cost {
@@ -1279,7 +1288,7 @@ fn uneven_multi_hex_search<T: Pixel>(
1279
1288
let cand_mv = center + offset * i;
1280
1289
let rd = get_fullpel_mv_rd (
1281
1290
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 ,
1283
1292
) ;
1284
1293
1285
1294
if rd. cost < current. rd . cost {
@@ -1292,7 +1301,7 @@ fn uneven_multi_hex_search<T: Pixel>(
1292
1301
// Refine the search results using a 'normal' hexagon search.
1293
1302
hexagon_search (
1294
1303
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 ,
1296
1305
) ;
1297
1306
}
1298
1307
@@ -1306,7 +1315,7 @@ fn subpel_diamond_search<T: Pixel>(
1306
1315
_p_ref : & Plane < T > , bit_depth : usize , pmv : [ MotionVector ; 2 ] , lambda : u32 ,
1307
1316
mvx_min : isize , mvx_max : isize , mvy_min : isize , mvy_max : isize , w : usize ,
1308
1317
h : usize , use_satd : bool , current : & mut MotionSearchResult ,
1309
- ref_frame : RefType ,
1318
+ ref_frame : RefType , ssdec : u8 ,
1310
1319
) {
1311
1320
use crate :: util:: Aligned ;
1312
1321
@@ -1352,6 +1361,7 @@ fn subpel_diamond_search<T: Pixel>(
1352
1361
cand_mv,
1353
1362
& mut tmp_region,
1354
1363
ref_frame,
1364
+ ssdec,
1355
1365
) ;
1356
1366
1357
1367
if rd. cost < best_cand. rd . cost {
@@ -1380,7 +1390,7 @@ fn get_fullpel_mv_rd<T: Pixel>(
1380
1390
fi : & FrameInvariants < T > , po : PlaneOffset , org_region : & PlaneRegion < T > ,
1381
1391
p_ref : & Plane < T > , bit_depth : usize , pmv : [ MotionVector ; 2 ] , lambda : u32 ,
1382
1392
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 ,
1384
1394
) -> MVCandidateRD {
1385
1395
if ( cand_mv. col as isize ) < mvx_min
1386
1396
|| ( cand_mv. col as isize ) > mvx_max
@@ -1397,7 +1407,7 @@ fn get_fullpel_mv_rd<T: Pixel>(
1397
1407
} ) ;
1398
1408
compute_mv_rd (
1399
1409
fi, pmv, lambda, use_satd, bit_depth, w, h, cand_mv, org_region,
1400
- & plane_ref,
1410
+ & plane_ref, ssdec ,
1401
1411
)
1402
1412
}
1403
1413
@@ -1406,7 +1416,7 @@ fn get_subpel_mv_rd<T: Pixel>(
1406
1416
bit_depth : usize , pmv : [ MotionVector ; 2 ] , lambda : u32 , use_satd : bool ,
1407
1417
mvx_min : isize , mvx_max : isize , mvy_min : isize , mvy_max : isize , w : usize ,
1408
1418
h : usize , cand_mv : MotionVector , tmp_region : & mut PlaneRegionMut < T > ,
1409
- ref_frame : RefType ,
1419
+ ref_frame : RefType , ssdec : u8 ,
1410
1420
) -> MVCandidateRD {
1411
1421
if ( cand_mv. col as isize ) < mvx_min
1412
1422
|| ( cand_mv. col as isize ) > mvx_max
@@ -1429,7 +1439,7 @@ fn get_subpel_mv_rd<T: Pixel>(
1429
1439
let plane_ref = tmp_region. as_const ( ) ;
1430
1440
compute_mv_rd (
1431
1441
fi, pmv, lambda, use_satd, bit_depth, w, h, cand_mv, org_region,
1432
- & plane_ref,
1442
+ & plane_ref, ssdec ,
1433
1443
)
1434
1444
}
1435
1445
@@ -1438,16 +1448,18 @@ fn get_subpel_mv_rd<T: Pixel>(
1438
1448
fn compute_mv_rd < T : Pixel > (
1439
1449
fi : & FrameInvariants < T > , pmv : [ MotionVector ; 2 ] , lambda : u32 ,
1440
1450
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 ,
1442
1452
) -> MVCandidateRD {
1443
1453
let sad = if use_satd {
1444
1454
get_satd ( plane_org, plane_ref, w, h, bit_depth, fi. cpu_feature_level )
1445
1455
} else {
1446
1456
get_sad ( plane_org, plane_ref, w, h, bit_depth, fi. cpu_feature_level )
1447
1457
} ;
1448
1458
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 ) ;
1451
1463
let rate = rate1. min ( rate2 + 1 ) ;
1452
1464
1453
1465
MVCandidateRD { cost : 256 * sad as u64 + rate as u64 * lambda as u64 , sad }
@@ -1457,6 +1469,7 @@ fn full_search<T: Pixel>(
1457
1469
fi : & FrameInvariants < T > , x_lo : isize , x_hi : isize , y_lo : isize , y_hi : isize ,
1458
1470
w : usize , h : usize , org_region : & PlaneRegion < T > , p_ref : & Plane < T > ,
1459
1471
po : PlaneOffset , step : usize , lambda : u32 , pmv : [ MotionVector ; 2 ] ,
1472
+ ssdec : u8 ,
1460
1473
) -> MotionSearchResult {
1461
1474
let search_region = p_ref. region ( Area :: Rect {
1462
1475
x : x_lo,
@@ -1488,6 +1501,7 @@ fn full_search<T: Pixel>(
1488
1501
mv,
1489
1502
org_region,
1490
1503
& ref_window,
1504
+ ssdec,
1491
1505
) ;
1492
1506
1493
1507
if rd. cost < best. rd . cost {
0 commit comments