summaryrefslogtreecommitdiff
path: root/third_party/aom/examples/encoder_util.c
blob: 1aa3a7eef4538b10a981188950c9832375819b42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

// Utility functions used by encoder binaries.

#include <assert.h>
#include <string.h>

#include "./encoder_util.h"
#include "aom/aom_integer.h"

#define mmin(a, b) ((a) < (b) ? (a) : (b))

static void find_mismatch_plane(const aom_image_t *const img1,
                                const aom_image_t *const img2, int plane,
                                int use_highbitdepth, int loc[4]) {
  const unsigned char *const p1 = img1->planes[plane];
  const int p1_stride = img1->stride[plane] >> use_highbitdepth;
  const unsigned char *const p2 = img2->planes[plane];
  const int p2_stride = img2->stride[plane] >> use_highbitdepth;
  const uint32_t bsize = 64;
  const int is_y_plane = (plane == AOM_PLANE_Y);
  const uint32_t bsizex = is_y_plane ? bsize : bsize >> img1->x_chroma_shift;
  const uint32_t bsizey = is_y_plane ? bsize : bsize >> img1->y_chroma_shift;
  const uint32_t c_w =
      is_y_plane ? img1->d_w
                 : (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
  const uint32_t c_h =
      is_y_plane ? img1->d_h
                 : (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
  assert(img1->d_w == img2->d_w && img1->d_h == img2->d_h);
  assert(img1->x_chroma_shift == img2->x_chroma_shift &&
         img1->y_chroma_shift == img2->y_chroma_shift);
  loc[0] = loc[1] = loc[2] = loc[3] = -1;
  int match = 1;
  uint32_t i, j;
  for (i = 0; match && i < c_h; i += bsizey) {
    for (j = 0; match && j < c_w; j += bsizex) {
      const int si =
          is_y_plane ? mmin(i + bsizey, c_h) - i : mmin(i + bsizey, c_h - i);
      const int sj =
          is_y_plane ? mmin(j + bsizex, c_w) - j : mmin(j + bsizex, c_w - j);
      int k, l;
      for (k = 0; match && k < si; ++k) {
        for (l = 0; match && l < sj; ++l) {
          const int row = i + k;
          const int col = j + l;
          const int offset1 = row * p1_stride + col;
          const int offset2 = row * p2_stride + col;
          const int val1 = use_highbitdepth
                               ? p1[2 * offset1] | (p1[2 * offset1 + 1] << 8)
                               : p1[offset1];
          const int val2 = use_highbitdepth
                               ? p2[2 * offset2] | (p2[2 * offset2 + 1] << 8)
                               : p2[offset2];
          if (val1 != val2) {
            loc[0] = row;
            loc[1] = col;
            loc[2] = val1;
            loc[3] = val2;
            match = 0;
            break;
          }
        }
      }
    }
  }
}

static void find_mismatch_helper(const aom_image_t *const img1,
                                 const aom_image_t *const img2,
                                 int use_highbitdepth, int yloc[4], int uloc[4],
                                 int vloc[4]) {
#if !CONFIG_HIGHBITDEPTH
  assert(!use_highbitdepth);
#endif  // !CONFIG_HIGHBITDEPTH
  find_mismatch_plane(img1, img2, AOM_PLANE_Y, use_highbitdepth, yloc);
  find_mismatch_plane(img1, img2, AOM_PLANE_U, use_highbitdepth, uloc);
  find_mismatch_plane(img1, img2, AOM_PLANE_V, use_highbitdepth, vloc);
}

#if CONFIG_HIGHBITDEPTH
void aom_find_mismatch_high(const aom_image_t *const img1,
                            const aom_image_t *const img2, int yloc[4],
                            int uloc[4], int vloc[4]) {
  find_mismatch_helper(img1, img2, 1, yloc, uloc, vloc);
}
#endif

void aom_find_mismatch(const aom_image_t *const img1,
                       const aom_image_t *const img2, int yloc[4], int uloc[4],
                       int vloc[4]) {
  find_mismatch_helper(img1, img2, 0, yloc, uloc, vloc);
}

int aom_compare_img(const aom_image_t *const img1,
                    const aom_image_t *const img2) {
  uint32_t l_w = img1->d_w;
  uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
  const uint32_t c_h =
      (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
  uint32_t i;
  int match = 1;

  match &= (img1->fmt == img2->fmt);
  match &= (img1->d_w == img2->d_w);
  match &= (img1->d_h == img2->d_h);
#if CONFIG_HIGHBITDEPTH
  if (img1->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
    l_w *= 2;
    c_w *= 2;
  }
#endif

  for (i = 0; i < img1->d_h; ++i)
    match &= (memcmp(img1->planes[AOM_PLANE_Y] + i * img1->stride[AOM_PLANE_Y],
                     img2->planes[AOM_PLANE_Y] + i * img2->stride[AOM_PLANE_Y],
                     l_w) == 0);

  for (i = 0; i < c_h; ++i)
    match &= (memcmp(img1->planes[AOM_PLANE_U] + i * img1->stride[AOM_PLANE_U],
                     img2->planes[AOM_PLANE_U] + i * img2->stride[AOM_PLANE_U],
                     c_w) == 0);

  for (i = 0; i < c_h; ++i)
    match &= (memcmp(img1->planes[AOM_PLANE_V] + i * img1->stride[AOM_PLANE_V],
                     img2->planes[AOM_PLANE_V] + i * img2->stride[AOM_PLANE_V],
                     c_w) == 0);

  return match;
}