mv_cost_test.cc (4590B)
1 /* 2 * Copyright (c) 2022, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #include "av1/encoder/cost.h" 13 #include "av1/encoder/encodemv.h" 14 #include "gtest/gtest.h" 15 16 namespace { 17 18 void ReferenceBuildNmvComponentCostTable(int *mvcost, 19 const nmv_component *const mvcomp, 20 MvSubpelPrecision precision) { 21 int i, v; 22 int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; 23 int bits_cost[MV_OFFSET_BITS][2]; 24 int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE]; 25 int class0_hp_cost[2], hp_cost[2]; 26 av1_cost_tokens_from_cdf(sign_cost, mvcomp->sign_cdf, nullptr); 27 av1_cost_tokens_from_cdf(class_cost, mvcomp->classes_cdf, nullptr); 28 av1_cost_tokens_from_cdf(class0_cost, mvcomp->class0_cdf, nullptr); 29 for (i = 0; i < MV_OFFSET_BITS; ++i) { 30 av1_cost_tokens_from_cdf(bits_cost[i], mvcomp->bits_cdf[i], nullptr); 31 } 32 for (i = 0; i < CLASS0_SIZE; ++i) 33 av1_cost_tokens_from_cdf(class0_fp_cost[i], mvcomp->class0_fp_cdf[i], 34 nullptr); 35 av1_cost_tokens_from_cdf(fp_cost, mvcomp->fp_cdf, nullptr); 36 if (precision > MV_SUBPEL_LOW_PRECISION) { 37 av1_cost_tokens_from_cdf(class0_hp_cost, mvcomp->class0_hp_cdf, nullptr); 38 av1_cost_tokens_from_cdf(hp_cost, mvcomp->hp_cdf, nullptr); 39 } 40 mvcost[0] = 0; 41 for (v = 1; v <= MV_MAX; ++v) { 42 int z, c, o, d, e, f, cost = 0; 43 z = v - 1; 44 c = av1_get_mv_class(z, &o); 45 cost += class_cost[c]; 46 d = (o >> 3); /* int mv data */ 47 f = (o >> 1) & 3; /* fractional pel mv data */ 48 e = (o & 1); /* high precision mv data */ 49 if (c == MV_CLASS_0) { 50 cost += class0_cost[d]; 51 } else { 52 const int b = c + CLASS0_BITS - 1; /* number of bits */ 53 for (i = 0; i < b; ++i) cost += bits_cost[i][((d >> i) & 1)]; 54 } 55 if (precision > MV_SUBPEL_NONE) { 56 if (c == MV_CLASS_0) { 57 cost += class0_fp_cost[d][f]; 58 } else { 59 cost += fp_cost[f]; 60 } 61 if (precision > MV_SUBPEL_LOW_PRECISION) { 62 if (c == MV_CLASS_0) { 63 cost += class0_hp_cost[e]; 64 } else { 65 cost += hp_cost[e]; 66 } 67 } 68 } 69 mvcost[v] = cost + sign_cost[0]; 70 mvcost[-v] = cost + sign_cost[1]; 71 } 72 } 73 74 // Test using the default context, except for sign 75 static const nmv_component kTestComponentContext = { 76 { AOM_CDF11(28672, 30976, 31858, 32320, 32551, 32656, 32740, 32757, 32762, 77 32767) }, // class_cdf // fp 78 { { AOM_CDF4(16384, 24576, 26624) }, 79 { AOM_CDF4(12288, 21248, 24128) } }, // class0_fp_cdf 80 { AOM_CDF4(8192, 17408, 21248) }, // fp_cdf 81 { AOM_CDF2(70 * 128) }, // sign_cdf 82 { AOM_CDF2(160 * 128) }, // class0_hp_cdf 83 { AOM_CDF2(128 * 128) }, // hp_cdf 84 { AOM_CDF2(216 * 128) }, // class0_cdf 85 { { AOM_CDF2(128 * 136) }, 86 { AOM_CDF2(128 * 140) }, 87 { AOM_CDF2(128 * 148) }, 88 { AOM_CDF2(128 * 160) }, 89 { AOM_CDF2(128 * 176) }, 90 { AOM_CDF2(128 * 192) }, 91 { AOM_CDF2(128 * 224) }, 92 { AOM_CDF2(128 * 234) }, 93 { AOM_CDF2(128 * 234) }, 94 { AOM_CDF2(128 * 240) } }, // bits_cdf 95 }; 96 97 void TestMvComponentCostTable(MvSubpelPrecision precision) { 98 std::unique_ptr<int[]> mvcost_ref_buf(new int[MV_VALS]); 99 std::unique_ptr<int[]> mvcost_buf(new int[MV_VALS]); 100 int *mvcost_ref = mvcost_ref_buf.get() + MV_MAX; 101 int *mvcost = mvcost_buf.get() + MV_MAX; 102 103 ReferenceBuildNmvComponentCostTable(mvcost_ref, &kTestComponentContext, 104 precision); 105 av1_build_nmv_component_cost_table(mvcost, &kTestComponentContext, precision); 106 107 for (int v = 0; v <= MV_MAX; ++v) { 108 ASSERT_EQ(mvcost_ref[v], mvcost[v]) << "v = " << v; 109 ASSERT_EQ(mvcost_ref[-v], mvcost[-v]) << "v = " << v; 110 } 111 } 112 113 TEST(MvCostTest, BuildMvComponentCostTableTest1) { 114 TestMvComponentCostTable(MV_SUBPEL_NONE); 115 } 116 117 TEST(MvCostTest, BuildMvComponentCostTableTest2) { 118 TestMvComponentCostTable(MV_SUBPEL_LOW_PRECISION); 119 } 120 121 TEST(MvCostTest, BuildMvComponentCostTableTest3) { 122 TestMvComponentCostTable(MV_SUBPEL_HIGH_PRECISION); 123 } 124 125 } // namespace