1 /* 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12 #include <math.h> 13 #include <stddef.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <sys/types.h> 18 19 #include "third_party/googletest/src/include/gtest/gtest.h" 20 #include "test/acm_random.h" 21 #include "vpx/vpx_integer.h" 22 #include "vpx_mem/vpx_mem.h" 23 extern "C" { 24 #include "vp8/encoder/onyx_int.h" 25 } 26 27 using libvpx_test::ACMRandom; 28 29 namespace { 30 31 TEST(Vp8RoiMapTest, ParameterCheck) { 32 ACMRandom rnd(ACMRandom::DeterministicSeed()); 33 int delta_q[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 }; 34 int delta_lf[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 }; 35 unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 }; 36 37 const int internalq_trans[] = { 38 0, 1, 2, 3, 4, 5, 7, 8, 39 9, 10, 12, 13, 15, 17, 18, 19, 40 20, 21, 23, 24, 25, 26, 27, 28, 41 29, 30, 31, 33, 35, 37, 39, 41, 42 43, 45, 47, 49, 51, 53, 55, 57, 43 59, 61, 64, 67, 70, 73, 76, 79, 44 82, 85, 88, 91, 94, 97, 100, 103, 45 106, 109, 112, 115, 118, 121, 124, 127, 46 }; 47 48 // Initialize elements of cpi with valid defaults. 49 VP8_COMP cpi; 50 cpi.mb.e_mbd.mb_segement_abs_delta = SEGMENT_DELTADATA; 51 cpi.cyclic_refresh_mode_enabled = 0; 52 cpi.mb.e_mbd.segmentation_enabled = 0; 53 cpi.mb.e_mbd.update_mb_segmentation_map = 0; 54 cpi.mb.e_mbd.update_mb_segmentation_data = 0; 55 cpi.common.mb_rows = 240 >> 4; 56 cpi.common.mb_cols = 320 >> 4; 57 const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols); 58 vpx_memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data)); 59 60 // Segment map 61 cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1)); 62 63 // Allocate memory for the source memory map. 64 unsigned char *roi_map = 65 reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1)); 66 vpx_memset(&roi_map[mbs >> 2], 1, (mbs >> 2)); 67 vpx_memset(&roi_map[mbs >> 1], 2, (mbs >> 2)); 68 vpx_memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2)); 69 70 // Do a test call with valid parameters. 71 int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, 72 cpi.common.mb_cols, delta_q, delta_lf, 73 threshold); 74 EXPECT_EQ(0, roi_retval) 75 << "vp8_set_roimap roi failed with default test parameters"; 76 77 // Check that the values in the cpi structure get set as expected. 78 if (roi_retval == 0) { 79 // Check that the segment map got set. 80 const int mapcompare = memcmp(roi_map, cpi.segmentation_map, mbs); 81 EXPECT_EQ(0, mapcompare) << "segment map error"; 82 83 // Check the q deltas (note the need to translate into 84 // the interanl range of 0-127. 85 for (int i = 0; i < MAX_MB_SEGMENTS; ++i) { 86 const int transq = internalq_trans[abs(delta_q[i])]; 87 if (abs(cpi.segment_feature_data[MB_LVL_ALT_Q][i]) != transq) { 88 EXPECT_EQ(transq, cpi.segment_feature_data[MB_LVL_ALT_Q][i]) 89 << "segment delta_q error"; 90 break; 91 } 92 } 93 94 // Check the loop filter deltas 95 for (int i = 0; i < MAX_MB_SEGMENTS; ++i) { 96 if (cpi.segment_feature_data[MB_LVL_ALT_LF][i] != delta_lf[i]) { 97 EXPECT_EQ(delta_lf[i], cpi.segment_feature_data[MB_LVL_ALT_LF][i]) 98 << "segment delta_lf error"; 99 break; 100 } 101 } 102 103 // Check the breakout thresholds 104 for (int i = 0; i < MAX_MB_SEGMENTS; ++i) { 105 unsigned int breakout = 106 static_cast<unsigned int>(cpi.segment_encode_breakout[i]); 107 108 if (threshold[i] != breakout) { 109 EXPECT_EQ(threshold[i], breakout) 110 << "breakout threshold error"; 111 break; 112 } 113 } 114 115 // Segmentation, and segmentation update flages should be set. 116 EXPECT_EQ(1, cpi.mb.e_mbd.segmentation_enabled) 117 << "segmentation_enabled error"; 118 EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_map) 119 << "update_mb_segmentation_map error"; 120 EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data) 121 << "update_mb_segmentation_data error"; 122 123 124 // Try a range of delta q and lf parameters (some legal, some not) 125 for (int i = 0; i < 1000; ++i) { 126 int rand_deltas[4]; 127 int deltas_valid; 128 rand_deltas[0] = rnd(160) - 80; 129 rand_deltas[1] = rnd(160) - 80; 130 rand_deltas[2] = rnd(160) - 80; 131 rand_deltas[3] = rnd(160) - 80; 132 133 deltas_valid = ((abs(rand_deltas[0]) <= 63) && 134 (abs(rand_deltas[1]) <= 63) && 135 (abs(rand_deltas[2]) <= 63) && 136 (abs(rand_deltas[3]) <= 63)) ? 0 : -1; 137 138 // Test with random delta q values. 139 roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, 140 cpi.common.mb_cols, rand_deltas, 141 delta_lf, threshold); 142 EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error"; 143 144 // One delta_q error shown at a time 145 if (deltas_valid != roi_retval) 146 break; 147 148 // Test with random loop filter values. 149 roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, 150 cpi.common.mb_cols, delta_q, 151 rand_deltas, threshold); 152 EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error"; 153 154 // One delta loop filter error shown at a time 155 if (deltas_valid != roi_retval) 156 break; 157 } 158 159 // Test that we report and error if cyclic refresh is enabled. 160 cpi.cyclic_refresh_mode_enabled = 1; 161 roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, 162 cpi.common.mb_cols, delta_q, 163 delta_lf, threshold); 164 EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error"; 165 cpi.cyclic_refresh_mode_enabled = 0; 166 167 // Test invalid number of rows or colums. 168 roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1, 169 cpi.common.mb_cols, delta_q, 170 delta_lf, threshold); 171 EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error"; 172 173 roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, 174 cpi.common.mb_cols - 1, delta_q, 175 delta_lf, threshold); 176 EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error"; 177 } 178 179 // Free allocated memory 180 if (cpi.segmentation_map) 181 vpx_free(cpi.segmentation_map); 182 if (roi_map) 183 vpx_free(roi_map); 184 }; 185 186 } // namespace 187