11b362b15af34006e6a11974088a46d42b903418eJohann/*
21b362b15af34006e6a11974088a46d42b903418eJohann *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
31b362b15af34006e6a11974088a46d42b903418eJohann *
41b362b15af34006e6a11974088a46d42b903418eJohann *  Use of this source code is governed by a BSD-style license
51b362b15af34006e6a11974088a46d42b903418eJohann *  that can be found in the LICENSE file in the root of the source
61b362b15af34006e6a11974088a46d42b903418eJohann *  tree. An additional intellectual property rights grant can be found
71b362b15af34006e6a11974088a46d42b903418eJohann *  in the file PATENTS.  All contributing project authors may
81b362b15af34006e6a11974088a46d42b903418eJohann *  be found in the AUTHORS file in the root of the source tree.
91b362b15af34006e6a11974088a46d42b903418eJohann */
101b362b15af34006e6a11974088a46d42b903418eJohann
111b362b15af34006e6a11974088a46d42b903418eJohann#include <math.h>
121b362b15af34006e6a11974088a46d42b903418eJohann#include <stddef.h>
131b362b15af34006e6a11974088a46d42b903418eJohann#include <stdio.h>
141b362b15af34006e6a11974088a46d42b903418eJohann#include <stdlib.h>
151b362b15af34006e6a11974088a46d42b903418eJohann#include <string.h>
161b362b15af34006e6a11974088a46d42b903418eJohann#include <sys/types.h>
171b362b15af34006e6a11974088a46d42b903418eJohann
181b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/googletest/src/include/gtest/gtest.h"
193df0563f1b24dac6c0bd122fc922a48211269061hkuang#include "test/acm_random.h"
20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp8/encoder/onyx_int.h"
211b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx/vpx_integer.h"
221b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h"
231b362b15af34006e6a11974088a46d42b903418eJohann
243df0563f1b24dac6c0bd122fc922a48211269061hkuangusing libvpx_test::ACMRandom;
253df0563f1b24dac6c0bd122fc922a48211269061hkuang
261b362b15af34006e6a11974088a46d42b903418eJohannnamespace {
271b362b15af34006e6a11974088a46d42b903418eJohann
286ac915abcdb404a00d927fe6308a47fcf09d9519hkuangTEST(VP8RoiMapTest, ParameterCheck) {
293df0563f1b24dac6c0bd122fc922a48211269061hkuang  ACMRandom rnd(ACMRandom::DeterministicSeed());
301b362b15af34006e6a11974088a46d42b903418eJohann  int delta_q[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
311b362b15af34006e6a11974088a46d42b903418eJohann  int delta_lf[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
321b362b15af34006e6a11974088a46d42b903418eJohann  unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };
331b362b15af34006e6a11974088a46d42b903418eJohann
341b362b15af34006e6a11974088a46d42b903418eJohann  const int internalq_trans[] = {
357bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0,  1,  2,  3,  4,  5,  7,   8,   9,   10,  12,  13,  15,  17,  18,  19,
367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    20, 21, 23, 24, 25, 26, 27,  28,  29,  30,  31,  33,  35,  37,  39,  41,
377bc9febe8749e98a3812a0dc4380ceae75c29450Johann    43, 45, 47, 49, 51, 53, 55,  57,  59,  61,  64,  67,  70,  73,  76,  79,
387bc9febe8749e98a3812a0dc4380ceae75c29450Johann    82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127,
391b362b15af34006e6a11974088a46d42b903418eJohann  };
401b362b15af34006e6a11974088a46d42b903418eJohann
411b362b15af34006e6a11974088a46d42b903418eJohann  // Initialize elements of cpi with valid defaults.
421b362b15af34006e6a11974088a46d42b903418eJohann  VP8_COMP cpi;
431b362b15af34006e6a11974088a46d42b903418eJohann  cpi.mb.e_mbd.mb_segement_abs_delta = SEGMENT_DELTADATA;
441b362b15af34006e6a11974088a46d42b903418eJohann  cpi.cyclic_refresh_mode_enabled = 0;
451b362b15af34006e6a11974088a46d42b903418eJohann  cpi.mb.e_mbd.segmentation_enabled = 0;
461b362b15af34006e6a11974088a46d42b903418eJohann  cpi.mb.e_mbd.update_mb_segmentation_map = 0;
471b362b15af34006e6a11974088a46d42b903418eJohann  cpi.mb.e_mbd.update_mb_segmentation_data = 0;
481b362b15af34006e6a11974088a46d42b903418eJohann  cpi.common.mb_rows = 240 >> 4;
491b362b15af34006e6a11974088a46d42b903418eJohann  cpi.common.mb_cols = 320 >> 4;
501b362b15af34006e6a11974088a46d42b903418eJohann  const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols);
51da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));
521b362b15af34006e6a11974088a46d42b903418eJohann
531b362b15af34006e6a11974088a46d42b903418eJohann  // Segment map
541b362b15af34006e6a11974088a46d42b903418eJohann  cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
551b362b15af34006e6a11974088a46d42b903418eJohann
561b362b15af34006e6a11974088a46d42b903418eJohann  // Allocate memory for the source memory map.
571b362b15af34006e6a11974088a46d42b903418eJohann  unsigned char *roi_map =
587bc9febe8749e98a3812a0dc4380ceae75c29450Johann      reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
59da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
60da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  memset(&roi_map[mbs - (mbs >> 2)], 3, (mbs >> 2));
621b362b15af34006e6a11974088a46d42b903418eJohann
631b362b15af34006e6a11974088a46d42b903418eJohann  // Do a test call with valid parameters.
647bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int roi_retval =
657bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
667bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     delta_q, delta_lf, threshold);
671b362b15af34006e6a11974088a46d42b903418eJohann  EXPECT_EQ(0, roi_retval)
687bc9febe8749e98a3812a0dc4380ceae75c29450Johann      << "vp8_set_roimap roi failed with default test parameters";
691b362b15af34006e6a11974088a46d42b903418eJohann
701b362b15af34006e6a11974088a46d42b903418eJohann  // Check that the values in the cpi structure get set as expected.
711b362b15af34006e6a11974088a46d42b903418eJohann  if (roi_retval == 0) {
721b362b15af34006e6a11974088a46d42b903418eJohann    // Check that the segment map got set.
731b362b15af34006e6a11974088a46d42b903418eJohann    const int mapcompare = memcmp(roi_map, cpi.segmentation_map, mbs);
741b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(0, mapcompare) << "segment map error";
751b362b15af34006e6a11974088a46d42b903418eJohann
761b362b15af34006e6a11974088a46d42b903418eJohann    // Check the q deltas (note the need to translate into
771b362b15af34006e6a11974088a46d42b903418eJohann    // the interanl range of 0-127.
781b362b15af34006e6a11974088a46d42b903418eJohann    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
791b362b15af34006e6a11974088a46d42b903418eJohann      const int transq = internalq_trans[abs(delta_q[i])];
801b362b15af34006e6a11974088a46d42b903418eJohann      if (abs(cpi.segment_feature_data[MB_LVL_ALT_Q][i]) != transq) {
817bc9febe8749e98a3812a0dc4380ceae75c29450Johann        EXPECT_EQ(transq, cpi.segment_feature_data[MB_LVL_ALT_Q][i])
827bc9febe8749e98a3812a0dc4380ceae75c29450Johann            << "segment delta_q  error";
837bc9febe8749e98a3812a0dc4380ceae75c29450Johann        break;
841b362b15af34006e6a11974088a46d42b903418eJohann      }
851b362b15af34006e6a11974088a46d42b903418eJohann    }
861b362b15af34006e6a11974088a46d42b903418eJohann
871b362b15af34006e6a11974088a46d42b903418eJohann    // Check the loop filter deltas
881b362b15af34006e6a11974088a46d42b903418eJohann    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
891b362b15af34006e6a11974088a46d42b903418eJohann      if (cpi.segment_feature_data[MB_LVL_ALT_LF][i] != delta_lf[i]) {
901b362b15af34006e6a11974088a46d42b903418eJohann        EXPECT_EQ(delta_lf[i], cpi.segment_feature_data[MB_LVL_ALT_LF][i])
917bc9febe8749e98a3812a0dc4380ceae75c29450Johann            << "segment delta_lf error";
921b362b15af34006e6a11974088a46d42b903418eJohann        break;
931b362b15af34006e6a11974088a46d42b903418eJohann      }
941b362b15af34006e6a11974088a46d42b903418eJohann    }
951b362b15af34006e6a11974088a46d42b903418eJohann
961b362b15af34006e6a11974088a46d42b903418eJohann    // Check the breakout thresholds
971b362b15af34006e6a11974088a46d42b903418eJohann    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
981b362b15af34006e6a11974088a46d42b903418eJohann      unsigned int breakout =
997bc9febe8749e98a3812a0dc4380ceae75c29450Johann          static_cast<unsigned int>(cpi.segment_encode_breakout[i]);
1001b362b15af34006e6a11974088a46d42b903418eJohann
1011b362b15af34006e6a11974088a46d42b903418eJohann      if (threshold[i] != breakout) {
1027bc9febe8749e98a3812a0dc4380ceae75c29450Johann        EXPECT_EQ(threshold[i], breakout) << "breakout threshold error";
1031b362b15af34006e6a11974088a46d42b903418eJohann        break;
1041b362b15af34006e6a11974088a46d42b903418eJohann      }
1051b362b15af34006e6a11974088a46d42b903418eJohann    }
1061b362b15af34006e6a11974088a46d42b903418eJohann
1071b362b15af34006e6a11974088a46d42b903418eJohann    // Segmentation, and segmentation update flages should be set.
1081b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(1, cpi.mb.e_mbd.segmentation_enabled)
1097bc9febe8749e98a3812a0dc4380ceae75c29450Johann        << "segmentation_enabled error";
1101b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_map)
1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann        << "update_mb_segmentation_map error";
1121b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
1137bc9febe8749e98a3812a0dc4380ceae75c29450Johann        << "update_mb_segmentation_data error";
1141b362b15af34006e6a11974088a46d42b903418eJohann
1151b362b15af34006e6a11974088a46d42b903418eJohann    // Try a range of delta q and lf parameters (some legal, some not)
1161b362b15af34006e6a11974088a46d42b903418eJohann    for (int i = 0; i < 1000; ++i) {
1171b362b15af34006e6a11974088a46d42b903418eJohann      int rand_deltas[4];
1181b362b15af34006e6a11974088a46d42b903418eJohann      int deltas_valid;
1193df0563f1b24dac6c0bd122fc922a48211269061hkuang      rand_deltas[0] = rnd(160) - 80;
1203df0563f1b24dac6c0bd122fc922a48211269061hkuang      rand_deltas[1] = rnd(160) - 80;
1213df0563f1b24dac6c0bd122fc922a48211269061hkuang      rand_deltas[2] = rnd(160) - 80;
1223df0563f1b24dac6c0bd122fc922a48211269061hkuang      rand_deltas[3] = rnd(160) - 80;
1231b362b15af34006e6a11974088a46d42b903418eJohann
1247bc9febe8749e98a3812a0dc4380ceae75c29450Johann      deltas_valid =
1257bc9febe8749e98a3812a0dc4380ceae75c29450Johann          ((abs(rand_deltas[0]) <= 63) && (abs(rand_deltas[1]) <= 63) &&
1267bc9febe8749e98a3812a0dc4380ceae75c29450Johann           (abs(rand_deltas[2]) <= 63) && (abs(rand_deltas[3]) <= 63))
1277bc9febe8749e98a3812a0dc4380ceae75c29450Johann              ? 0
1287bc9febe8749e98a3812a0dc4380ceae75c29450Johann              : -1;
1291b362b15af34006e6a11974088a46d42b903418eJohann
1301b362b15af34006e6a11974088a46d42b903418eJohann      // Test with random delta q values.
1317bc9febe8749e98a3812a0dc4380ceae75c29450Johann      roi_retval =
1327bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
1337bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         rand_deltas, delta_lf, threshold);
1341b362b15af34006e6a11974088a46d42b903418eJohann      EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";
1351b362b15af34006e6a11974088a46d42b903418eJohann
1361b362b15af34006e6a11974088a46d42b903418eJohann      // One delta_q error shown at a time
1377bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (deltas_valid != roi_retval) break;
1381b362b15af34006e6a11974088a46d42b903418eJohann
1391b362b15af34006e6a11974088a46d42b903418eJohann      // Test with random loop filter values.
1407bc9febe8749e98a3812a0dc4380ceae75c29450Johann      roi_retval =
1417bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
1427bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         delta_q, rand_deltas, threshold);
1431b362b15af34006e6a11974088a46d42b903418eJohann      EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";
1441b362b15af34006e6a11974088a46d42b903418eJohann
1451b362b15af34006e6a11974088a46d42b903418eJohann      // One delta loop filter error shown at a time
1467bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (deltas_valid != roi_retval) break;
1471b362b15af34006e6a11974088a46d42b903418eJohann    }
1481b362b15af34006e6a11974088a46d42b903418eJohann
1491b362b15af34006e6a11974088a46d42b903418eJohann    // Test that we report and error if cyclic refresh is enabled.
1501b362b15af34006e6a11974088a46d42b903418eJohann    cpi.cyclic_refresh_mode_enabled = 1;
1517bc9febe8749e98a3812a0dc4380ceae75c29450Johann    roi_retval =
1527bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
1537bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       delta_q, delta_lf, threshold);
1541b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
1551b362b15af34006e6a11974088a46d42b903418eJohann    cpi.cyclic_refresh_mode_enabled = 0;
1561b362b15af34006e6a11974088a46d42b903418eJohann
1571b362b15af34006e6a11974088a46d42b903418eJohann    // Test invalid number of rows or colums.
1587bc9febe8749e98a3812a0dc4380ceae75c29450Johann    roi_retval =
1597bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
1607bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       cpi.common.mb_cols, delta_q, delta_lf, threshold);
1611b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";
1621b362b15af34006e6a11974088a46d42b903418eJohann
1637bc9febe8749e98a3812a0dc4380ceae75c29450Johann    roi_retval =
1647bc9febe8749e98a3812a0dc4380ceae75c29450Johann        vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
1657bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       cpi.common.mb_cols - 1, delta_q, delta_lf, threshold);
1661b362b15af34006e6a11974088a46d42b903418eJohann    EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
1671b362b15af34006e6a11974088a46d42b903418eJohann  }
1681b362b15af34006e6a11974088a46d42b903418eJohann
1691b362b15af34006e6a11974088a46d42b903418eJohann  // Free allocated memory
1707bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cpi.segmentation_map) vpx_free(cpi.segmentation_map);
1717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (roi_map) vpx_free(roi_map);
1721b362b15af34006e6a11974088a46d42b903418eJohann};
1731b362b15af34006e6a11974088a46d42b903418eJohann
1741b362b15af34006e6a11974088a46d42b903418eJohann}  // namespace
175