set_roi.cc 5.95 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "third_party/googletest/src/include/gtest/gtest.h"
Yaowu Xu's avatar
Yaowu Xu committed
19
#include "test/acm_random.h"
20
#include "vp8/encoder/onyx_int.h"
21 22 23
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"

Yaowu Xu's avatar
Yaowu Xu committed
24 25
using libvpx_test::ACMRandom;

26 27
namespace {

28
TEST(VP8RoiMapTest, ParameterCheck) {
Yaowu Xu's avatar
Yaowu Xu committed
29
  ACMRandom rnd(ACMRandom::DeterministicSeed());
30 31 32 33 34
  int delta_q[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
  int delta_lf[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
  unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };

  const int internalq_trans[] = {
clang-format's avatar
clang-format committed
35 36 37 38
    0,  1,  2,  3,  4,  5,  7,   8,   9,   10,  12,  13,  15,  17,  18,  19,
    20, 21, 23, 24, 25, 26, 27,  28,  29,  30,  31,  33,  35,  37,  39,  41,
    43, 45, 47, 49, 51, 53, 55,  57,  59,  61,  64,  67,  70,  73,  76,  79,
    82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127,
39 40 41 42 43 44 45 46 47 48 49 50
  };

  // Initialize elements of cpi with valid defaults.
  VP8_COMP cpi;
  cpi.mb.e_mbd.mb_segement_abs_delta = SEGMENT_DELTADATA;
  cpi.cyclic_refresh_mode_enabled = 0;
  cpi.mb.e_mbd.segmentation_enabled = 0;
  cpi.mb.e_mbd.update_mb_segmentation_map = 0;
  cpi.mb.e_mbd.update_mb_segmentation_data = 0;
  cpi.common.mb_rows = 240 >> 4;
  cpi.common.mb_cols = 320 >> 4;
  const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols);
James Zern's avatar
James Zern committed
51
  memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));
52 53 54 55 56 57

  // Segment map
  cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));

  // Allocate memory for the source memory map.
  unsigned char *roi_map =
clang-format's avatar
clang-format committed
58
      reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
James Zern's avatar
James Zern committed
59 60
  memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
  memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
clang-format's avatar
clang-format committed
61
  memset(&roi_map[mbs - (mbs >> 2)], 3, (mbs >> 2));
62 63

  // Do a test call with valid parameters.
clang-format's avatar
clang-format committed
64 65 66
  int roi_retval =
      vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
                     delta_q, delta_lf, threshold);
67
  EXPECT_EQ(0, roi_retval)
clang-format's avatar
clang-format committed
68
      << "vp8_set_roimap roi failed with default test parameters";
69 70 71 72 73 74 75 76 77 78 79 80

  // Check that the values in the cpi structure get set as expected.
  if (roi_retval == 0) {
    // Check that the segment map got set.
    const int mapcompare = memcmp(roi_map, cpi.segmentation_map, mbs);
    EXPECT_EQ(0, mapcompare) << "segment map error";

    // Check the q deltas (note the need to translate into
    // the interanl range of 0-127.
    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
      const int transq = internalq_trans[abs(delta_q[i])];
      if (abs(cpi.segment_feature_data[MB_LVL_ALT_Q][i]) != transq) {
clang-format's avatar
clang-format committed
81 82 83
        EXPECT_EQ(transq, cpi.segment_feature_data[MB_LVL_ALT_Q][i])
            << "segment delta_q  error";
        break;
84 85 86 87 88 89 90
      }
    }

    // Check the loop filter deltas
    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
      if (cpi.segment_feature_data[MB_LVL_ALT_LF][i] != delta_lf[i]) {
        EXPECT_EQ(delta_lf[i], cpi.segment_feature_data[MB_LVL_ALT_LF][i])
clang-format's avatar
clang-format committed
91
            << "segment delta_lf error";
92 93 94 95 96 97 98
        break;
      }
    }

    // Check the breakout thresholds
    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
      unsigned int breakout =
clang-format's avatar
clang-format committed
99
          static_cast<unsigned int>(cpi.segment_encode_breakout[i]);
100 101

      if (threshold[i] != breakout) {
clang-format's avatar
clang-format committed
102
        EXPECT_EQ(threshold[i], breakout) << "breakout threshold error";
103 104 105 106 107 108
        break;
      }
    }

    // Segmentation, and segmentation update flages should be set.
    EXPECT_EQ(1, cpi.mb.e_mbd.segmentation_enabled)
clang-format's avatar
clang-format committed
109
        << "segmentation_enabled error";
110
    EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_map)
clang-format's avatar
clang-format committed
111
        << "update_mb_segmentation_map error";
112
    EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
clang-format's avatar
clang-format committed
113
        << "update_mb_segmentation_data error";
114 115 116 117 118

    // Try a range of delta q and lf parameters (some legal, some not)
    for (int i = 0; i < 1000; ++i) {
      int rand_deltas[4];
      int deltas_valid;
Yaowu Xu's avatar
Yaowu Xu committed
119 120 121 122
      rand_deltas[0] = rnd(160) - 80;
      rand_deltas[1] = rnd(160) - 80;
      rand_deltas[2] = rnd(160) - 80;
      rand_deltas[3] = rnd(160) - 80;
123

clang-format's avatar
clang-format committed
124 125 126 127 128
      deltas_valid =
          ((abs(rand_deltas[0]) <= 63) && (abs(rand_deltas[1]) <= 63) &&
           (abs(rand_deltas[2]) <= 63) && (abs(rand_deltas[3]) <= 63))
              ? 0
              : -1;
129 130

      // Test with random delta q values.
clang-format's avatar
clang-format committed
131 132 133
      roi_retval =
          vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
                         rand_deltas, delta_lf, threshold);
134 135 136
      EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";

      // One delta_q error shown at a time
clang-format's avatar
clang-format committed
137
      if (deltas_valid != roi_retval) break;
138 139

      // Test with random loop filter values.
clang-format's avatar
clang-format committed
140 141 142
      roi_retval =
          vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
                         delta_q, rand_deltas, threshold);
143 144 145
      EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";

      // One delta loop filter error shown at a time
clang-format's avatar
clang-format committed
146
      if (deltas_valid != roi_retval) break;
147 148 149
    }

    // Test invalid number of rows or colums.
clang-format's avatar
clang-format committed
150 151 152
    roi_retval =
        vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
                       cpi.common.mb_cols, delta_q, delta_lf, threshold);
153 154
    EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";

clang-format's avatar
clang-format committed
155 156 157
    roi_retval =
        vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
                       cpi.common.mb_cols - 1, delta_q, delta_lf, threshold);
158 159 160 161
    EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
  }

  // Free allocated memory
clang-format's avatar
clang-format committed
162 163
  if (cpi.segmentation_map) vpx_free(cpi.segmentation_map);
  if (roi_map) vpx_free(roi_map);
164 165 166
};

}  // namespace