blockd.c 6.2 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"
Jingning Han's avatar
Jingning Han committed
17

Yaowu Xu's avatar
Yaowu Xu committed
18 19
PREDICTION_MODE av1_left_block_mode(const MODE_INFO *cur_mi,
                                    const MODE_INFO *left_mi, int b) {
Jingning Han's avatar
Jingning Han committed
20
  if (b == 0 || b == 2) {
clang-format's avatar
clang-format committed
21
    if (!left_mi || is_inter_block(&left_mi->mbmi)) return DC_PRED;
Jingning Han's avatar
Jingning Han committed
22 23 24 25 26 27 28 29

    return get_y_mode(left_mi, b + 1);
  } else {
    assert(b == 1 || b == 3);
    return cur_mi->bmi[b - 1].as_mode;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
30 31
PREDICTION_MODE av1_above_block_mode(const MODE_INFO *cur_mi,
                                     const MODE_INFO *above_mi, int b) {
Jingning Han's avatar
Jingning Han committed
32
  if (b == 0 || b == 1) {
clang-format's avatar
clang-format committed
33
    if (!above_mi || is_inter_block(&above_mi->mbmi)) return DC_PRED;
Jingning Han's avatar
Jingning Han committed
34 35 36 37 38 39 40 41

    return get_y_mode(above_mi, b + 2);
  } else {
    assert(b == 2 || b == 3);
    return cur_mi->bmi[b - 2].as_mode;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
42
void av1_foreach_transformed_block_in_plane(
Jingning Han's avatar
Jingning Han committed
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];
clang-format's avatar
clang-format committed
46
  const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han's avatar
Jingning Han committed
47 48 49
  // 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.
clang-format's avatar
clang-format committed
50
  const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
Jingning Han's avatar
Jingning Han committed
51
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
52 53 54 55 56
  const int num_4x4_w = block_size_wide[plane_bsize];
  const int num_4x4_h = block_size_high[plane_bsize];
  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
57 58 59 60 61
  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.
62
  int max_blocks_wide =
clang-format's avatar
clang-format committed
63
      num_4x4_w + (xd->mb_to_right_edge >= 0 ? 0 : xd->mb_to_right_edge >>
64 65
                                                       (3 + pd->subsampling_x));
  int max_blocks_high =
clang-format's avatar
clang-format committed
66 67
      num_4x4_h + (xd->mb_to_bottom_edge >= 0
                       ? 0
68 69 70 71 72 73 74
                       : xd->mb_to_bottom_edge >> (3 + pd->subsampling_y));
  const int extra_step =
      ((num_4x4_w - max_blocks_wide) >> tx_size_wide_log2[tx_size]) * step;

  // Scale to the transform block unit.
  max_blocks_wide >>= tx_size_wide_log2[0];
  max_blocks_high >>= tx_size_high_log2[0];
Jingning Han's avatar
Jingning Han committed
75 76 77

  // Keep track of the row and column of the blocks we use so that we know
  // if we are in the unrestricted motion border.
78
  for (r = 0; r < max_blocks_high; r += txh_unit) {
Jingning Han's avatar
Jingning Han committed
79
    // Skip visiting the sub blocks that are wholly within the UMV.
80
    for (c = 0; c < max_blocks_wide; c += txw_unit) {
81
      visit(plane, i, r, c, plane_bsize, tx_size, arg);
Jingning Han's avatar
Jingning Han committed
82 83 84 85 86 87
      i += step;
    }
    i += extra_step;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
88 89 90 91
void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
                                   BLOCK_SIZE bsize,
                                   foreach_transformed_block_visitor visit,
                                   void *arg) {
Jingning Han's avatar
Jingning Han committed
92 93
  int plane;
  for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Yaowu Xu's avatar
Yaowu Xu committed
94
    av1_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg);
Jingning Han's avatar
Jingning Han committed
95 96
}

97
#if !CONFIG_PVQ
Yaowu Xu's avatar
Yaowu Xu committed
98
void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
99
                      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];
Jingning Han's avatar
Jingning Han committed
104 105 106 107

  // above
  if (has_eob && xd->mb_to_right_edge < 0) {
    int i;
108 109
    const int blocks_wide =
        pd->n4_w + (xd->mb_to_right_edge >> (5 + pd->subsampling_x));
110
    int above_contexts = txs_wide;
Jingning Han's avatar
Jingning Han committed
111 112 113
    if (above_contexts + aoff > blocks_wide)
      above_contexts = blocks_wide - aoff;

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

  // left
  if (has_eob && xd->mb_to_bottom_edge < 0) {
    int i;
123 124
    const int blocks_high =
        pd->n4_h + (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
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
#endif
Jingning Han's avatar
Jingning Han committed
135

Yaowu Xu's avatar
Yaowu Xu committed
136
void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) {
Jingning Han's avatar
Jingning Han committed
137 138 139 140 141 142 143 144
  int i;

  for (i = 0; i < MAX_MB_PLANE; i++) {
    xd->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y;
    xd->plane[i].subsampling_x = i ? ss_x : 0;
    xd->plane[i].subsampling_y = i ? ss_y : 0;
  }
}
145 146

#if CONFIG_EXT_INTRA
147
const int16_t dr_intra_derivative[90] = {
clang-format's avatar
clang-format committed
148 149 150 151 152 153 154
  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,
155 156
};

Yaowu Xu's avatar
Yaowu Xu committed
157
int av1_is_intra_filter_switchable(int angle) {
158
  assert(angle > 0 && angle < 270);
clang-format's avatar
clang-format committed
159
  if (angle % 45 == 0) return 0;
160 161 162
  if (angle > 90 && angle < 180) {
    return 1;
  } else {
clang-format's avatar
clang-format committed
163 164 165
    return ((angle < 90 ? dr_intra_derivative[angle]
                        : dr_intra_derivative[270 - angle]) &
            0xFF) > 0;
166 167 168
  }
}
#endif  // CONFIG_EXT_INTRA