/src/avm/av2/av2_iface_common.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 3-Clause Clear License |
5 | | * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear |
6 | | * License was not distributed with this source code in the LICENSE file, you |
7 | | * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the |
8 | | * Alliance for Open Media Patent License 1.0 was not distributed with this |
9 | | * source code in the PATENTS file, you can obtain it at |
10 | | * aomedia.org/license/patent-license/. |
11 | | */ |
12 | | #ifndef AVM_AV2_AV2_IFACE_COMMON_H_ |
13 | | #define AVM_AV2_AV2_IFACE_COMMON_H_ |
14 | | |
15 | | #include <assert.h> |
16 | | |
17 | | #include "avm_ports/mem.h" |
18 | | #include "avm_scale/yv12config.h" |
19 | | #include "av2/common/enums.h" |
20 | | |
21 | | /* Constant value specifying size of subgop*/ |
22 | | #define MAX_SUBGOP_SIZE 32 |
23 | | typedef struct { |
24 | | int disp_frame_idx; |
25 | | int is_filtered; |
26 | | int immediate_output_picture; |
27 | | int show_existing_frame; |
28 | | int pyramid_level; |
29 | | int qindex; |
30 | | |
31 | | int refresh_frame_flags; |
32 | | int num_references; |
33 | | int ref_frame_pyr_level[INTER_REFS_PER_FRAME]; |
34 | | int ref_frame_disp_order[INTER_REFS_PER_FRAME]; |
35 | | int is_valid_ref_frame[INTER_REFS_PER_FRAME]; |
36 | | unsigned int ref_frame_map[REF_FRAMES]; |
37 | | } SubGOPStepData; |
38 | | |
39 | | typedef struct { |
40 | | int num_steps; |
41 | | int step_idx_enc; |
42 | | int step_idx_dec; |
43 | | SubGOPStepData step[MAX_SUBGOP_SIZE]; |
44 | | } SubGOPData; |
45 | | |
46 | | static void yuvconfig2image(avm_image_t *img, const YV12_BUFFER_CONFIG *yv12, |
47 | 361 | void *user_priv) { |
48 | | /* avm_img_wrap() doesn't allow specifying independent strides for |
49 | | * the Y, U, and V planes, nor other alignment adjustments that |
50 | | * might be representable by a YV12_BUFFER_CONFIG, so we just |
51 | | * initialize all the fields. |
52 | | */ |
53 | 361 | int bps; |
54 | 361 | if (!yv12->subsampling_y) { |
55 | 62 | if (!yv12->subsampling_x) { |
56 | 28 | img->fmt = AVM_IMG_FMT_I444; |
57 | 28 | bps = 24; |
58 | 34 | } else { |
59 | 34 | img->fmt = AVM_IMG_FMT_I422; |
60 | 34 | bps = 16; |
61 | 34 | } |
62 | 299 | } else { |
63 | 299 | img->fmt = AVM_IMG_FMT_I420; |
64 | 299 | bps = 12; |
65 | 299 | } |
66 | 361 | img->cp = yv12->color_primaries; |
67 | 361 | img->tc = yv12->transfer_characteristics; |
68 | 361 | img->mc = yv12->matrix_coefficients; |
69 | 361 | img->monochrome = yv12->monochrome; |
70 | 361 | img->csp = yv12->chroma_sample_position; |
71 | 361 | img->range = yv12->color_range; |
72 | 361 | img->bit_depth = 8; |
73 | 361 | img->w = yv12->y_width; |
74 | 361 | img->h = yv12->y_height; |
75 | 361 | img->d_w = yv12->y_crop_width; |
76 | 361 | img->d_h = yv12->y_crop_height; |
77 | 361 | img->r_w = yv12->render_width; |
78 | 361 | img->r_h = yv12->render_height; |
79 | 361 | img->x_chroma_shift = yv12->subsampling_x; |
80 | 361 | img->y_chroma_shift = yv12->subsampling_y; |
81 | 361 | bps *= 2; |
82 | | // avm_image_t uses byte strides and a pointer to the first byte |
83 | | // of the image. |
84 | 361 | img->fmt = (avm_img_fmt_t)(img->fmt | AVM_IMG_FMT_HIGHBITDEPTH); |
85 | 361 | img->bit_depth = yv12->bit_depth; |
86 | 361 | img->planes[AVM_PLANE_Y] = (uint8_t *)yv12->y_buffer; |
87 | 361 | img->planes[AVM_PLANE_U] = (uint8_t *)yv12->u_buffer; |
88 | 361 | img->planes[AVM_PLANE_V] = (uint8_t *)yv12->v_buffer; |
89 | 361 | img->stride[AVM_PLANE_Y] = 2 * yv12->y_stride; |
90 | 361 | img->stride[AVM_PLANE_U] = 2 * yv12->uv_stride; |
91 | 361 | img->stride[AVM_PLANE_V] = 2 * yv12->uv_stride; |
92 | 361 | img->bps = bps; |
93 | 361 | img->user_priv = user_priv; |
94 | 361 | img->img_data = yv12->buffer_alloc; |
95 | 361 | img->img_data_owner = 0; |
96 | 361 | img->self_allocd = 0; |
97 | 361 | img->sz = yv12->frame_size; |
98 | 361 | assert(!yv12->metadata); |
99 | 361 | img->metadata = NULL; |
100 | 361 | img->w_conf_win_enabled_flag = yv12->w_conf_win_enabled_flag; |
101 | 361 | if (img->w_conf_win_enabled_flag) { |
102 | 50 | img->w_conf_win_left_offset = yv12->w_win_left_offset; |
103 | 50 | img->w_conf_win_right_offset = yv12->w_win_right_offset; |
104 | 50 | img->w_conf_win_top_offset = yv12->w_win_top_offset; |
105 | 50 | img->w_conf_win_bottom_offset = yv12->w_win_bottom_offset; |
106 | | |
107 | | // Convert |
108 | 50 | const int plane_left_offset = |
109 | 50 | (img->w_conf_win_left_offset * yv12->y_crop_width) / yv12->max_width; |
110 | 50 | const int plane_right_offset = |
111 | 50 | (img->w_conf_win_right_offset * yv12->y_crop_width) / yv12->max_width; |
112 | 50 | const int plane_top_offset = |
113 | 50 | (img->w_conf_win_top_offset * yv12->y_crop_height) / yv12->max_height; |
114 | 50 | const int plane_bottom_offset = |
115 | 50 | (img->w_conf_win_bottom_offset * yv12->y_crop_height) / |
116 | 50 | yv12->max_height; |
117 | | |
118 | | // Calculate cropping positions |
119 | 50 | int left_pos_x = plane_left_offset; |
120 | 50 | int right_pos_x = img->d_w - 1 - plane_right_offset; |
121 | 50 | int top_pos_y = plane_top_offset; |
122 | 50 | int bottom_pos_y = img->d_h - 1 - plane_bottom_offset; |
123 | | |
124 | | // Calculate the cropped size |
125 | 50 | img->crop_width = right_pos_x - left_pos_x + 1; |
126 | 50 | img->crop_height = bottom_pos_y - top_pos_y + 1; |
127 | 50 | img->w = img->d_w; |
128 | 50 | img->h = img->d_h; |
129 | 50 | img->d_w = img->crop_width; |
130 | 50 | img->d_h = img->crop_height; |
131 | | |
132 | 50 | const int scaled_left_offset = |
133 | 50 | (yv12->w_win_left_offset * yv12->y_crop_width) / yv12->max_width; |
134 | 50 | const int scaled_top_offset = |
135 | 50 | (yv12->w_win_top_offset * yv12->y_crop_height) / yv12->max_height; |
136 | | |
137 | | // Adjust plane pointers to point to the cropped region |
138 | 50 | const int bytes_per_sample = (img->fmt & AVM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; |
139 | | |
140 | | // Adjust Y plane pointer |
141 | 50 | img->planes[AVM_PLANE_Y] += (scaled_top_offset * img->stride[AVM_PLANE_Y]) + |
142 | 50 | (scaled_left_offset * bytes_per_sample); |
143 | | |
144 | 50 | const int chroma_left_offset = scaled_left_offset >> img->x_chroma_shift; |
145 | 50 | const int chroma_top_offset = scaled_top_offset >> img->y_chroma_shift; |
146 | | |
147 | 50 | if (!img->monochrome) { |
148 | 50 | img->planes[AVM_PLANE_U] += |
149 | 50 | (chroma_top_offset * img->stride[AVM_PLANE_U]) + |
150 | 50 | (chroma_left_offset * bytes_per_sample); |
151 | 50 | img->planes[AVM_PLANE_V] += |
152 | 50 | (chroma_top_offset * img->stride[AVM_PLANE_V]) + |
153 | 50 | (chroma_left_offset * bytes_per_sample); |
154 | 50 | } |
155 | 311 | } else { |
156 | 311 | img->w_conf_win_bottom_offset = 0; |
157 | 311 | img->w_conf_win_left_offset = 0; |
158 | 311 | img->w_conf_win_right_offset = 0; |
159 | 311 | img->w_conf_win_top_offset = 0; |
160 | 311 | } |
161 | 361 | img->max_width = yv12->max_width; |
162 | 361 | img->max_height = yv12->max_height; |
163 | 361 | } |
164 | | |
165 | | static avm_codec_err_t image2yuvconfig(const avm_image_t *img, |
166 | 0 | YV12_BUFFER_CONFIG *yv12) { |
167 | 0 | yv12->y_buffer = (uint16_t *)img->planes[AVM_PLANE_Y]; |
168 | 0 | yv12->u_buffer = (uint16_t *)img->planes[AVM_PLANE_U]; |
169 | 0 | yv12->v_buffer = (uint16_t *)img->planes[AVM_PLANE_V]; |
170 | |
|
171 | 0 | yv12->y_crop_width = img->d_w; |
172 | 0 | yv12->y_crop_height = img->d_h; |
173 | 0 | yv12->render_width = img->r_w; |
174 | 0 | yv12->render_height = img->r_h; |
175 | 0 | yv12->y_width = img->w; |
176 | 0 | yv12->y_height = img->h; |
177 | |
|
178 | 0 | yv12->uv_width = |
179 | 0 | img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2 : yv12->y_width; |
180 | 0 | yv12->uv_height = |
181 | 0 | img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2 : yv12->y_height; |
182 | 0 | yv12->uv_crop_width = yv12->uv_width; |
183 | 0 | yv12->uv_crop_height = yv12->uv_height; |
184 | |
|
185 | 0 | yv12->y_stride = img->stride[AVM_PLANE_Y]; |
186 | 0 | yv12->uv_stride = img->stride[AVM_PLANE_U]; |
187 | 0 | yv12->color_primaries = img->cp; |
188 | 0 | yv12->transfer_characteristics = img->tc; |
189 | 0 | yv12->matrix_coefficients = img->mc; |
190 | 0 | yv12->monochrome = img->monochrome; |
191 | 0 | yv12->chroma_sample_position = img->csp; |
192 | 0 | yv12->color_range = img->range; |
193 | | |
194 | | // In avm_image_t |
195 | | // planes point to uint8 address of start of data |
196 | | // stride counts uint8s to reach next row |
197 | | // In YV12_BUFFER_CONFIG |
198 | | // y_buffer, u_buffer, v_buffer point to uint16 address of data |
199 | | // stride and border counts in uint16s |
200 | | // This means that all the address calculations in the main body of code |
201 | | // should work correctly. |
202 | | // However, before we do any pixel operations we need to cast the address |
203 | | // to a uint16 ponter and double its value. |
204 | 0 | yv12->y_stride >>= 1; |
205 | 0 | yv12->uv_stride >>= 1; |
206 | | |
207 | | // Note(yunqing): if img is allocated the same as the frame buffer, y_stride |
208 | | // is 32-byte aligned. Also, handle the cases while allocating img without a |
209 | | // border or stride_align is less than 32. |
210 | 0 | int border = (yv12->y_stride - (int)((img->w + 31) & ~31)) / 2; |
211 | 0 | yv12->border = (border < 0) ? 0 : border; |
212 | 0 | yv12->subsampling_x = img->x_chroma_shift; |
213 | 0 | yv12->subsampling_y = img->y_chroma_shift; |
214 | 0 | yv12->metadata = img->metadata; |
215 | 0 | return AVM_CODEC_OK; |
216 | 0 | } |
217 | | |
218 | | static void image2yuvconfig_upshift(avm_image_t *hbd_img, |
219 | | const avm_image_t *img, |
220 | 0 | YV12_BUFFER_CONFIG *yv12) { |
221 | 0 | avm_img_upshift(hbd_img, img, 0); |
222 | | // Copy some properties avm_img_upshift() ignores |
223 | 0 | hbd_img->cp = img->cp; |
224 | 0 | hbd_img->tc = img->tc; |
225 | 0 | hbd_img->mc = img->mc; |
226 | 0 | hbd_img->monochrome = img->monochrome; |
227 | 0 | hbd_img->csp = img->csp; |
228 | 0 | hbd_img->range = img->range; |
229 | 0 | image2yuvconfig(hbd_img, yv12); |
230 | 0 | yv12->metadata = img->metadata; |
231 | 0 | } |
232 | | #endif // AVM_AV2_AV2_IFACE_COMMON_H_ |