Line data Source code
1 : /*
2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 : *
4 : * This source code is subject to the terms of the BSD 2 Clause License and
5 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 : * was not distributed with this source code in the LICENSE file, you can
7 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 : * Media Patent License 1.0 was not distributed with this source code in the
9 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 : */
11 :
12 : #include "av1/common/tile_common.h"
13 : #include "av1/common/onyxc_int.h"
14 : #include "aom_dsp/aom_dsp_common.h"
15 :
16 0 : void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) {
17 0 : tile->mi_row_start = row * cm->tile_height;
18 0 : tile->mi_row_end = AOMMIN(tile->mi_row_start + cm->tile_height, cm->mi_rows);
19 0 : }
20 :
21 0 : void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) {
22 0 : tile->mi_col_start = col * cm->tile_width;
23 0 : tile->mi_col_end = AOMMIN(tile->mi_col_start + cm->tile_width, cm->mi_cols);
24 0 : }
25 :
26 : #if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS
27 : void av1_tile_set_tg_boundary(TileInfo *tile, const AV1_COMMON *const cm,
28 : int row, int col) {
29 : if (row < cm->tile_rows - 1) {
30 : tile->tg_horz_boundary =
31 : col >= cm->tile_group_start_col[row][col]
32 : ? (row == cm->tile_group_start_row[row][col] ? 1 : 0)
33 : : (row == cm->tile_group_start_row[row + 1][col] ? 1 : 0);
34 : } else {
35 : assert(col >= cm->tile_group_start_col[row][col]);
36 : tile->tg_horz_boundary =
37 : (row == cm->tile_group_start_row[row][col] ? 1 : 0);
38 : }
39 : }
40 : #endif
41 0 : void av1_tile_init(TileInfo *tile, const AV1_COMMON *cm, int row, int col) {
42 0 : av1_tile_set_row(tile, cm, row);
43 0 : av1_tile_set_col(tile, cm, col);
44 : #if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS
45 : av1_tile_set_tg_boundary(tile, cm, row, col);
46 : #endif
47 0 : }
48 :
49 : #if !CONFIG_EXT_TILE
50 :
51 : #if CONFIG_EXT_PARTITION
52 : #define MIN_TILE_WIDTH_MAX_SB 2
53 : #define MAX_TILE_WIDTH_MAX_SB 32
54 : #else
55 : #define MIN_TILE_WIDTH_MAX_SB 4
56 : #define MAX_TILE_WIDTH_MAX_SB 64
57 : #endif // CONFIG_EXT_PARTITION
58 :
59 0 : static int get_min_log2_tile_cols(int max_sb_cols) {
60 0 : int min_log2 = 0;
61 0 : while ((MAX_TILE_WIDTH_MAX_SB << min_log2) < max_sb_cols) ++min_log2;
62 0 : return min_log2;
63 : }
64 :
65 0 : static int get_max_log2_tile_cols(int max_sb_cols) {
66 0 : int max_log2 = 1;
67 0 : while ((max_sb_cols >> max_log2) >= MIN_TILE_WIDTH_MAX_SB) ++max_log2;
68 0 : return max_log2 - 1;
69 : }
70 :
71 0 : void av1_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols,
72 : int *max_log2_tile_cols) {
73 0 : const int max_sb_cols =
74 0 : ALIGN_POWER_OF_TWO(mi_cols, MAX_MIB_SIZE_LOG2) >> MAX_MIB_SIZE_LOG2;
75 0 : *min_log2_tile_cols = get_min_log2_tile_cols(max_sb_cols);
76 0 : *max_log2_tile_cols = get_max_log2_tile_cols(max_sb_cols);
77 0 : assert(*min_log2_tile_cols <= *max_log2_tile_cols);
78 0 : }
79 : #endif // !CONFIG_EXT_TILE
80 :
81 0 : void av1_update_boundary_info(const struct AV1Common *cm,
82 : const TileInfo *const tile_info, int mi_row,
83 : int mi_col) {
84 : int row, col;
85 0 : for (row = mi_row; row < (mi_row + cm->mib_size); row++)
86 0 : for (col = mi_col; col < (mi_col + cm->mib_size); col++) {
87 0 : MODE_INFO *const mi = cm->mi + row * cm->mi_stride + col;
88 0 : mi->mbmi.boundary_info = 0;
89 :
90 : // If horizontal dependent tile is enabled, then the horizontal
91 : // tile boundary is not treated as real tile boundary for loop
92 : // filtering, only the horizontal tile group boundary is treated
93 : // as tile boundary.
94 : // Otherwise, tile group boundary is treated the same as tile boundary.
95 : // Loop filtering operation is done based on the
96 : // loopfilter_across_tiles_enabled flag for both tile boundary and tile
97 : // group boundary.
98 :
99 0 : if (cm->tile_cols * cm->tile_rows > 1) {
100 : #if CONFIG_DEPENDENT_HORZTILES
101 : #if CONFIG_TILE_GROUPS
102 : if (row == tile_info->mi_row_start &&
103 : (!cm->dependent_horz_tiles || tile_info->tg_horz_boundary))
104 : #else
105 : if (row == tile_info->mi_row_start && !cm->dependent_horz_tiles)
106 : #endif // CONFIG_TILE_GROUPS
107 : #else
108 0 : if (row == tile_info->mi_row_start)
109 : #endif // CONFIG_DEPENDENT_HORZTILES
110 :
111 0 : mi->mbmi.boundary_info |= TILE_ABOVE_BOUNDARY;
112 0 : if (col == tile_info->mi_col_start)
113 0 : mi->mbmi.boundary_info |= TILE_LEFT_BOUNDARY;
114 0 : if ((row + 1) >= tile_info->mi_row_end)
115 0 : mi->mbmi.boundary_info |= TILE_BOTTOM_BOUNDARY;
116 0 : if ((col + 1) >= tile_info->mi_col_end)
117 0 : mi->mbmi.boundary_info |= TILE_RIGHT_BOUNDARY;
118 : }
119 : // Frame boundary is treated as tile boundary
120 0 : if (row == 0)
121 0 : mi->mbmi.boundary_info |= FRAME_ABOVE_BOUNDARY | TILE_ABOVE_BOUNDARY;
122 0 : if (col == 0)
123 0 : mi->mbmi.boundary_info |= FRAME_LEFT_BOUNDARY | TILE_LEFT_BOUNDARY;
124 0 : if ((row + 1) >= cm->mi_rows)
125 0 : mi->mbmi.boundary_info |= FRAME_BOTTOM_BOUNDARY | TILE_BOTTOM_BOUNDARY;
126 0 : if ((col + 1) >= cm->mi_cols)
127 0 : mi->mbmi.boundary_info |= FRAME_RIGHT_BOUNDARY | TILE_RIGHT_BOUNDARY;
128 : }
129 0 : }
130 :
131 : #if CONFIG_LOOPFILTERING_ACROSS_TILES
132 0 : int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm) {
133 0 : return (!cm->loop_filter_across_tiles_enabled &&
134 0 : (cm->tile_cols * cm->tile_rows > 1));
135 : }
136 : #endif // CONFIG_LOOPFILTERING_ACROSS_TILES
|