blob: b13e562c1e6a5c1e8744d79bda5ecad1d1a84217 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <math.h>
12
13#include "aom_ports/system_state.h"
14
15#include "av1/common/blockd.h"
16
Yaowu Xuf883b422016-08-30 14:01:10 -070017PREDICTION_MODE av1_left_block_mode(const MODE_INFO *cur_mi,
18 const MODE_INFO *left_mi, int b) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070019 if (b == 0 || b == 2) {
20 if (!left_mi || is_inter_block(&left_mi->mbmi)) return DC_PRED;
21
22 return get_y_mode(left_mi, b + 1);
23 } else {
24 assert(b == 1 || b == 3);
25 return cur_mi->bmi[b - 1].as_mode;
26 }
27}
28
Yaowu Xuf883b422016-08-30 14:01:10 -070029PREDICTION_MODE av1_above_block_mode(const MODE_INFO *cur_mi,
30 const MODE_INFO *above_mi, int b) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070031 if (b == 0 || b == 1) {
32 if (!above_mi || is_inter_block(&above_mi->mbmi)) return DC_PRED;
33
34 return get_y_mode(above_mi, b + 2);
35 } else {
36 assert(b == 2 || b == 3);
37 return cur_mi->bmi[b - 2].as_mode;
38 }
39}
40
Yaowu Xuf883b422016-08-30 14:01:10 -070041void av1_foreach_transformed_block_in_plane(
Yaowu Xuc27fc142016-08-22 16:08:15 -070042 const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
43 foreach_transformed_block_visitor visit, void *arg) {
44 const struct macroblockd_plane *const pd = &xd->plane[plane];
45 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
46 // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
47 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
48 // transform size varies per plane, look it up in a common way.
49 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
50 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
51 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
52 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
53 const uint8_t num_4x4_tw = num_4x4_blocks_wide_txsize_lookup[tx_size];
54 const uint8_t num_4x4_th = num_4x4_blocks_high_txsize_lookup[tx_size];
55 const int step = num_4x4_tw * num_4x4_th;
56 int i = 0, r, c;
57
58 // If mb_to_right_edge is < 0 we are in a situation in which
59 // the current block size extends into the UMV and we won't
60 // visit the sub blocks that are wholly within the UMV.
61 const int max_blocks_wide =
62 num_4x4_w + (xd->mb_to_right_edge >= 0 ? 0 : xd->mb_to_right_edge >>
63 (5 + pd->subsampling_x));
64 const int max_blocks_high =
65 num_4x4_h + (xd->mb_to_bottom_edge >= 0
66 ? 0
67 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
68 const int extra_step = ((num_4x4_w - max_blocks_wide) >>
69 num_4x4_blocks_wide_txsize_log2_lookup[tx_size]) *
70 step;
71
72 // Keep track of the row and column of the blocks we use so that we know
73 // if we are in the unrestricted motion border.
74 for (r = 0; r < max_blocks_high; r += num_4x4_th) {
75 // Skip visiting the sub blocks that are wholly within the UMV.
76 for (c = 0; c < max_blocks_wide; c += num_4x4_tw) {
77 visit(plane, i, r, c, plane_bsize, tx_size, arg);
78 i += step;
79 }
80 i += extra_step;
81 }
82}
83
Yaowu Xuf883b422016-08-30 14:01:10 -070084void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
85 BLOCK_SIZE bsize,
86 foreach_transformed_block_visitor visit,
87 void *arg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070088 int plane;
89 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -070090 av1_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -070091}
92
Yaowu Xuf883b422016-08-30 14:01:10 -070093void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
94 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob,
95 int aoff, int loff) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070096 ENTROPY_CONTEXT *const a = pd->above_context + aoff;
97 ENTROPY_CONTEXT *const l = pd->left_context + loff;
98 const int tx_w_in_blocks = num_4x4_blocks_wide_txsize_lookup[tx_size];
99 const int tx_h_in_blocks = num_4x4_blocks_high_txsize_lookup[tx_size];
100
101 // above
102 if (has_eob && xd->mb_to_right_edge < 0) {
103 int i;
104 const int blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize] +
105 (xd->mb_to_right_edge >> (5 + pd->subsampling_x));
106 int above_contexts = tx_w_in_blocks;
107 if (above_contexts + aoff > blocks_wide)
108 above_contexts = blocks_wide - aoff;
109
110 for (i = 0; i < above_contexts; ++i) a[i] = has_eob;
111 for (i = above_contexts; i < tx_w_in_blocks; ++i) a[i] = 0;
112 } else {
113 memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_w_in_blocks);
114 }
115
116 // left
117 if (has_eob && xd->mb_to_bottom_edge < 0) {
118 int i;
119 const int blocks_high = num_4x4_blocks_high_lookup[plane_bsize] +
120 (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
121 int left_contexts = tx_h_in_blocks;
122 if (left_contexts + loff > blocks_high) left_contexts = blocks_high - loff;
123
124 for (i = 0; i < left_contexts; ++i) l[i] = has_eob;
125 for (i = left_contexts; i < tx_h_in_blocks; ++i) l[i] = 0;
126 } else {
127 memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_h_in_blocks);
128 }
129}
130
Yaowu Xuf883b422016-08-30 14:01:10 -0700131void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700132 int i;
133
134 for (i = 0; i < MAX_MB_PLANE; i++) {
135 xd->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y;
136 xd->plane[i].subsampling_x = i ? ss_x : 0;
137 xd->plane[i].subsampling_y = i ? ss_y : 0;
138 }
139}
140
141#if CONFIG_EXT_INTRA
142const int16_t dr_intra_derivative[90] = {
143 1, 14666, 7330, 4884, 3660, 2926, 2435, 2084, 1821, 1616, 1451, 1317, 1204,
144 1108, 1026, 955, 892, 837, 787, 743, 703, 666, 633, 603, 574, 548,
145 524, 502, 481, 461, 443, 426, 409, 394, 379, 365, 352, 339, 327,
146 316, 305, 294, 284, 274, 265, 256, 247, 238, 230, 222, 214, 207,
147 200, 192, 185, 179, 172, 166, 159, 153, 147, 141, 136, 130, 124,
148 119, 113, 108, 103, 98, 93, 88, 83, 78, 73, 68, 63, 59,
149 54, 49, 45, 40, 35, 31, 26, 22, 17, 13, 8, 4,
150};
151
152// Returns whether filter selection is needed for a given
153// intra prediction angle.
Yaowu Xuf883b422016-08-30 14:01:10 -0700154int av1_is_intra_filter_switchable(int angle) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700155 assert(angle > 0 && angle < 270);
156 if (angle % 45 == 0) return 0;
157 if (angle > 90 && angle < 180) {
158 return 1;
159 } else {
160 return ((angle < 90 ? dr_intra_derivative[angle]
161 : dr_intra_derivative[270 - angle]) &
162 0xFF) > 0;
163 }
164}
165#endif // CONFIG_EXT_INTRA