blockd.c 8.44 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * 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.
Jingning Han's avatar
Jingning Han committed
10 11
 */

12
#include <math.h>
13

14
#include "aom_ports/system_state.h"
15

16
#include "av1/common/blockd.h"
17
#include "av1/common/onyxc_int.h"
Jingning Han's avatar
Jingning Han committed
18

19
PREDICTION_MODE av1_left_block_mode(const MODE_INFO *left_mi) {
Frederic Barbier's avatar
Frederic Barbier committed
20
  if (!left_mi) return DC_PRED;
21 22 23
#if CONFIG_INTRABC
  assert(!is_inter_block(&left_mi->mbmi) || is_intrabc_block(&left_mi->mbmi));
#else
Frederic Barbier's avatar
Frederic Barbier committed
24
  assert(!is_inter_block(&left_mi->mbmi));
25
#endif  // CONFIG_INTRABC
26
  return left_mi->mbmi.mode;
Jingning Han's avatar
Jingning Han committed
27 28
}

29
PREDICTION_MODE av1_above_block_mode(const MODE_INFO *above_mi) {
Frederic Barbier's avatar
Frederic Barbier committed
30
  if (!above_mi) return DC_PRED;
31 32 33
#if CONFIG_INTRABC
  assert(!is_inter_block(&above_mi->mbmi) || is_intrabc_block(&above_mi->mbmi));
#else
Frederic Barbier's avatar
Frederic Barbier committed
34
  assert(!is_inter_block(&above_mi->mbmi));
35
#endif  // CONFIG_INTRABC
36
  return above_mi->mbmi.mode;
Jingning Han's avatar
Jingning Han committed
37 38
}

Yaowu Xu's avatar
Yaowu Xu committed
39
void av1_foreach_transformed_block_in_plane(
Jingning Han's avatar
Jingning Han committed
40 41 42 43 44 45
    const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
    foreach_transformed_block_visitor visit, void *arg) {
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
  // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
  // transform size varies per plane, look it up in a common way.
46
  const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
47
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
48 49 50
  const uint8_t txw_unit = tx_size_wide_unit[tx_size];
  const uint8_t txh_unit = tx_size_high_unit[tx_size];
  const int step = txw_unit * txh_unit;
Jingning Han's avatar
Jingning Han committed
51 52 53 54 55
  int i = 0, r, c;

  // If mb_to_right_edge is < 0 we are in a situation in which
  // the current block size extends into the UMV and we won't
  // visit the sub blocks that are wholly within the UMV.
56 57
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
Jingning Han's avatar
Jingning Han committed
58

59 60 61 62 63 64 65 66
  int blk_row, blk_col;

  const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
  int mu_blocks_wide = block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
  int mu_blocks_high = block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
  mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
  mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);

Jingning Han's avatar
Jingning Han committed
67 68
  // Keep track of the row and column of the blocks we use so that we know
  // if we are in the unrestricted motion border.
69
  for (r = 0; r < max_blocks_high; r += mu_blocks_high) {
70
    const int unit_height = AOMMIN(mu_blocks_high + r, max_blocks_high);
Jingning Han's avatar
Jingning Han committed
71
    // Skip visiting the sub blocks that are wholly within the UMV.
72 73 74 75 76 77 78 79
    for (c = 0; c < max_blocks_wide; c += mu_blocks_wide) {
      const int unit_width = AOMMIN(mu_blocks_wide + c, max_blocks_wide);
      for (blk_row = r; blk_row < unit_height; blk_row += txh_unit) {
        for (blk_col = c; blk_col < unit_width; blk_col += txw_unit) {
          visit(plane, i, blk_row, blk_col, plane_bsize, tx_size, arg);
          i += step;
        }
      }
Jingning Han's avatar
Jingning Han committed
80 81 82 83
    }
  }
}

Angie Chiang's avatar
Angie Chiang committed
84
void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
85
                                   BLOCK_SIZE bsize, int mi_row, int mi_col,
Angie Chiang's avatar
Angie Chiang committed
86
                                   foreach_transformed_block_visitor visit,
87 88
                                   void *arg, const int num_planes) {
  for (int plane = 0; plane < num_planes; ++plane) {
89 90 91
    if (!is_chroma_reference(mi_row, mi_col, bsize,
                             xd->plane[plane].subsampling_x,
                             xd->plane[plane].subsampling_y))
92
      continue;
Angie Chiang's avatar
Angie Chiang committed
93
    av1_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg);
94
  }
Angie Chiang's avatar
Angie Chiang committed
95 96
}

Yaowu Xu's avatar
Yaowu Xu committed
97
void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
98 99
                      int plane, TX_SIZE tx_size, int has_eob, int aoff,
                      int loff) {
Jingning Han's avatar
Jingning Han committed
100 101
  ENTROPY_CONTEXT *const a = pd->above_context + aoff;
  ENTROPY_CONTEXT *const l = pd->left_context + loff;
102 103
  const int txs_wide = tx_size_wide_unit[tx_size];
  const int txs_high = tx_size_high_unit[tx_size];
104
  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
105
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han's avatar
Jingning Han committed
106 107 108 109

  // above
  if (has_eob && xd->mb_to_right_edge < 0) {
    int i;
110
    const int blocks_wide = max_block_wide(xd, plane_bsize, plane);
111
    int above_contexts = txs_wide;
Jingning Han's avatar
Jingning Han committed
112 113 114
    if (above_contexts + aoff > blocks_wide)
      above_contexts = blocks_wide - aoff;

clang-format's avatar
clang-format committed
115
    for (i = 0; i < above_contexts; ++i) a[i] = has_eob;
116
    for (i = above_contexts; i < txs_wide; ++i) a[i] = 0;
Jingning Han's avatar
Jingning Han committed
117
  } else {
118
    memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * txs_wide);
Jingning Han's avatar
Jingning Han committed
119 120 121 122 123
  }

  // left
  if (has_eob && xd->mb_to_bottom_edge < 0) {
    int i;
124
    const int blocks_high = max_block_high(xd, plane_bsize, plane);
125
    int left_contexts = txs_high;
clang-format's avatar
clang-format committed
126
    if (left_contexts + loff > blocks_high) left_contexts = blocks_high - loff;
Jingning Han's avatar
Jingning Han committed
127

clang-format's avatar
clang-format committed
128
    for (i = 0; i < left_contexts; ++i) l[i] = has_eob;
129
    for (i = left_contexts; i < txs_high; ++i) l[i] = 0;
Jingning Han's avatar
Jingning Han committed
130
  } else {
131
    memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * txs_high);
Jingning Han's avatar
Jingning Han committed
132 133
  }
}
134
void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col,
135
                            BLOCK_SIZE bsize, const int num_planes) {
136 137 138 139 140 141
  int i;
  int nplanes;
  int chroma_ref;
  chroma_ref =
      is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                          xd->plane[1].subsampling_y);
142
  nplanes = 1 + (num_planes - 1) * chroma_ref;
143 144
  for (i = 0; i < nplanes; i++) {
    struct macroblockd_plane *const pd = &xd->plane[i];
145
    const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
146 147 148 149 150 151 152
    const int txs_wide = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
    const int txs_high = block_size_high[plane_bsize] >> tx_size_high_log2[0];
    memset(pd->above_context, 0, sizeof(ENTROPY_CONTEXT) * txs_wide);
    memset(pd->left_context, 0, sizeof(ENTROPY_CONTEXT) * txs_high);
  }
}

153
#if CONFIG_LOOP_RESTORATION
154 155
void av1_reset_loop_restoration(MACROBLOCKD *xd, const int num_planes) {
  for (int p = 0; p < num_planes; ++p) {
156 157 158 159 160 161
    set_default_wiener(xd->wiener_info + p);
    set_default_sgrproj(xd->sgrproj_info + p);
  }
}
#endif  // CONFIG_LOOP_RESTORATION

162 163
void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y,
                            const int num_planes) {
Jingning Han's avatar
Jingning Han committed
164 165
  int i;

166
  for (i = 0; i < num_planes; i++) {
167
    xd->plane[i].plane_type = get_plane_type(i);
Jingning Han's avatar
Jingning Han committed
168 169 170 171
    xd->plane[i].subsampling_x = i ? ss_x : 0;
    xd->plane[i].subsampling_y = i ? ss_y : 0;
  }
}
172

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
#if CONFIG_EXT_INTRA_MOD2
const int16_t dr_intra_derivative[90] = {
  // More evenly spread out angles and limited to 10-bit
  // Values that are 0 will never be used
  //                    Approx angle
  0,    0, 0,        //
  1023, 0, 0,        // 3, ...
  547,  0, 0,        // 6, ...
  372,  0, 0, 0, 0,  // 9, ...
  273,  0, 0,        // 14, ...
  215,  0, 0,        // 17, ...
  178,  0, 0,        // 20, ...
  151,  0, 0,        // 23, ... (113 & 203 are base angles)
  132,  0, 0,        // 26, ...
  116,  0, 0,        // 29, ...
  102,  0, 0, 0,     // 32, ...
  90,   0, 0,        // 36, ...
  80,   0, 0,        // 39, ...
  71,   0, 0,        // 42, ...
  64,   0, 0,        // 45, ... (45 & 135 are base angles)
  57,   0, 0,        // 48, ...
  51,   0, 0,        // 51, ...
  45,   0, 0, 0,     // 54, ...
  40,   0, 0,        // 58, ...
  35,   0, 0,        // 61, ...
  31,   0, 0,        // 64, ...
  27,   0, 0,        // 67, ... (67 & 157 are base angles)
  23,   0, 0,        // 70, ...
  19,   0, 0,        // 73, ...
  15,   0, 0, 0, 0,  // 76, ...
  11,   0, 0,        // 81, ...
  7,    0, 0,        // 84, ...
  3,    0, 0,        // 87, ...
};
#else
208
const int16_t dr_intra_derivative[90] = {
clang-format's avatar
clang-format committed
209 210 211 212 213 214 215
  1,    14666, 7330, 4884, 3660, 2926, 2435, 2084, 1821, 1616, 1451, 1317, 1204,
  1108, 1026,  955,  892,  837,  787,  743,  703,  666,  633,  603,  574,  548,
  524,  502,   481,  461,  443,  426,  409,  394,  379,  365,  352,  339,  327,
  316,  305,   294,  284,  274,  265,  256,  247,  238,  230,  222,  214,  207,
  200,  192,   185,  179,  172,  166,  159,  153,  147,  141,  136,  130,  124,
  119,  113,   108,  103,  98,   93,   88,   83,   78,   73,   68,   63,   59,
  54,   49,    45,   40,   35,   31,   26,   22,   17,   13,   8,    4,
216
};
217
#endif  // CONFIG_EXT_INTRA_MOD2