/src/libavc/encoder/svc/isvce_downscaler.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2022 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | |
21 | | /** |
22 | | ******************************************************************************* |
23 | | * @file |
24 | | * isvce_downscaler.c |
25 | | * |
26 | | * @brief |
27 | | * Contains downscaler functions required by the SVC encoder |
28 | | * |
29 | | * @author |
30 | | * ittiam |
31 | | * |
32 | | * @par List of Functions: |
33 | | * - isvce_get_downscaler_data_size() |
34 | | * - isvce_get_downscaler_padding_dims() |
35 | | * - isvce_get_downscaler_normalized_filtered_pixel() |
36 | | * - isvce_horizontal_downscale_and_transpose() |
37 | | * - isvce_process_downscaler() |
38 | | * - isvce_initialize_downscaler() |
39 | | * |
40 | | * @remarks |
41 | | * None |
42 | | * |
43 | | ******************************************************************************* |
44 | | */ |
45 | | |
46 | | /*****************************************************************************/ |
47 | | /* File Includes */ |
48 | | /*****************************************************************************/ |
49 | | |
50 | | /* system include files */ |
51 | | #include <stdio.h> |
52 | | #include <stdlib.h> |
53 | | |
54 | | #include "ih264_typedefs.h" |
55 | | #include "ih264_macros.h" |
56 | | #include "isvc_macros.h" |
57 | | #include "ih264_platform_macros.h" |
58 | | #include "iv2.h" |
59 | | #include "isvc_defs.h" |
60 | | #include "isvce_defs.h" |
61 | | #include "isvc_structs.h" |
62 | | #include "isvc_structs.h" |
63 | | #include "isvce_downscaler.h" |
64 | | #include "isvce_downscaler_private_defs.h" |
65 | | |
66 | | /** |
67 | | ****************************************************************************** |
68 | | * @brief lanczos filter coefficients for 2x downscaling |
69 | | * @remarks Though the length of the filter is 8, the |
70 | | * same coefficients |
71 | | * are replicated so that 2 rows can be processed at one |
72 | | * go in SIMD |
73 | | ****************************************************************************** |
74 | | */ |
75 | | static WORD8 gai1_lanczos_coefficients_2x[NUM_SCALER_FILTER_PHASES][NUM_SCALER_FILTER_TAPS * 2] = { |
76 | | {-7, 0, 39, 64, 39, 0, -7, 0, -7, 0, 39, 64, 39, 0, -7, 0}, |
77 | | {-6, 0, 33, 62, 41, 4, -6, 0, -6, 0, 33, 62, 41, 4, -6, 0}, |
78 | | {-5, -1, 29, 57, 45, 9, -5, -1, -5, -1, 29, 57, 45, 9, -5, -1}, |
79 | | {-4, -2, 23, 55, 48, 14, -4, -2, -4, -2, 23, 55, 48, 14, -4, -2}, |
80 | | {-3, -3, 18, 52, 52, 18, -3, -3, -3, -3, 18, 52, 52, 18, -3, -3}, |
81 | | {-2, -4, 13, 49, 54, 24, -2, -4, -2, -4, 13, 49, 54, 24, -2, -4}, |
82 | | {-1, -5, 9, 44, 58, 29, -1, -5, -1, -5, 9, 44, 58, 29, -1, -5}, |
83 | | {0, -6, 3, 42, 61, 34, 0, -6, 0, -6, 3, 42, 61, 34, 0, -6}}; |
84 | | |
85 | | /** |
86 | | ****************************************************************************** |
87 | | * @brief lanczos filter coefficients for 1.5x downscaling |
88 | | * @remarks Though the length of the filter is 8, the same coefficients |
89 | | * are replicated so that 2 rows can be processed at one go in SIMD. |
90 | | ****************************************************************************** |
91 | | */ |
92 | | static WORD8 gai1_lanczos_coefficients_3by2x[NUM_SCALER_FILTER_PHASES][NUM_SCALER_FILTER_TAPS * 2] = |
93 | | {{0, -11, 32, 86, 32, -11, 0, 0, 0, -11, 32, 86, 32, -11, 0, 0}, |
94 | | {0, -10, 26, 79, 39, -5, 0, 0, 0, -10, 26, 79, 39, -5, 0, 0}, |
95 | | {0, -8, 21, 72, 46, 0, -2, 0, 0, -8, 21, 72, 46, 0, -2, 0}, |
96 | | {0, -6, 15, 66, 52, 3, -3, 0, 0, -6, 15, 66, 52, 3, -3, 0}, |
97 | | {0, -6, 10, 60, 60, 10, -6, 0, 0, -6, 10, 60, 60, 10, -6, 0}, |
98 | | {0, -3, 3, 52, 66, 15, -6, 0, 0, -3, 3, 52, 66, 15, -6, 0}, |
99 | | {0, -2, 0, 46, 72, 21, -8, 0, 0, -2, 0, 46, 72, 21, -8, 0}, |
100 | | {0, 0, -5, 39, 79, 26, -10, 0, 0, 0, -5, 39, 79, 26, -10, 0}}; |
101 | | |
102 | | /** |
103 | | ******************************************************************************* |
104 | | * |
105 | | * @brief |
106 | | * gets the memory size required for downscaler |
107 | | * |
108 | | * @par Description: |
109 | | * returns the memory required by the downscaler context and state structs |
110 | | * for allocation. |
111 | | * |
112 | | * @returns |
113 | | * |
114 | | * @remarks |
115 | | * |
116 | | * |
117 | | ******************************************************************************* |
118 | | */ |
119 | | |
120 | | UWORD32 isvce_get_downscaler_data_size(UWORD8 u1_num_spatial_layers, DOUBLE d_scaling_factor, |
121 | | UWORD32 u4_width, UWORD32 u4_height) |
122 | 9.87k | { |
123 | 9.87k | UWORD32 u4_size = 0; |
124 | | |
125 | 9.87k | if(u1_num_spatial_layers > 1) |
126 | 8.08k | { |
127 | 8.08k | u4_size += sizeof(downscaler_state_t); |
128 | | |
129 | 8.08k | u4_size += |
130 | 8.08k | (u4_height + NUM_SCALER_FILTER_TAPS * 2) * ((UWORD32) (u4_width / d_scaling_factor)); |
131 | 8.08k | } |
132 | | |
133 | 9.87k | return u4_size; |
134 | 9.87k | } |
135 | | |
136 | | /** |
137 | | ******************************************************************************* |
138 | | * |
139 | | * @brief |
140 | | * gets the padding size required for filtering |
141 | | * |
142 | | * @par Description: |
143 | | * gets the padding size required for filtering |
144 | | * |
145 | | * @returns |
146 | | * |
147 | | * @remarks |
148 | | * |
149 | | * |
150 | | ******************************************************************************* |
151 | | */ |
152 | | |
153 | | void isvce_get_downscaler_padding_dims(padding_dims_t *ps_pad_dims) |
154 | 115k | { |
155 | 115k | ps_pad_dims->u1_left_pad_size = ALIGN8(NUM_SCALER_FILTER_TAPS / 2); |
156 | 115k | ps_pad_dims->u1_right_pad_size = ALIGN8(NUM_SCALER_FILTER_TAPS / 2); |
157 | 115k | ps_pad_dims->u1_top_pad_size = NUM_SCALER_FILTER_TAPS / 2; |
158 | 115k | ps_pad_dims->u1_bottom_pad_size = NUM_SCALER_FILTER_TAPS / 2; |
159 | 115k | } |
160 | | |
161 | | /** |
162 | | ******************************************************************************* |
163 | | * |
164 | | * @brief |
165 | | * processes downscaler |
166 | | * |
167 | | * @par Description: |
168 | | * calls the function for padding and scaling |
169 | | * |
170 | | * @param[in] ps_scaler |
171 | | * pointer to downdownscaler context |
172 | | * |
173 | | * @param[in] ps_src_buf_props |
174 | | * pointer to source buffer props struct |
175 | | * |
176 | | * @param[in] u4_blk_wd |
177 | | * width of the block to be processed |
178 | | * |
179 | | * @param[in] u4_blk_ht |
180 | | * height of the block to be processed |
181 | | * |
182 | | * @returns |
183 | | * |
184 | | * @remarks |
185 | | * |
186 | | * |
187 | | ******************************************************************************* |
188 | | */ |
189 | | |
190 | | void isvce_process_downscaler(downscaler_ctxt_t *ps_scaler, yuv_buf_props_t *ps_src_buf_props, |
191 | | yuv_buf_props_t *ps_dst_buf_props, UWORD32 u4_blk_wd, |
192 | | UWORD32 u4_blk_ht) |
193 | 507k | { |
194 | 507k | buffer_container_t s_src_buf; |
195 | 507k | buffer_container_t s_dst_buf; |
196 | | |
197 | 507k | UWORD32 u4_scaled_block_size_x, u4_scaled_block_size_y; |
198 | | |
199 | 507k | downscaler_state_t *ps_scaler_state = (downscaler_state_t *) ps_scaler->pv_scaler_state; |
200 | | |
201 | 507k | ASSERT(ps_src_buf_props->e_color_format == IV_YUV_420SP_UV); |
202 | | |
203 | 507k | u4_scaled_block_size_x = (UWORD32) (u4_blk_wd / ps_scaler->d_scaling_factor); |
204 | 507k | u4_scaled_block_size_y = (UWORD32) (u4_blk_ht / ps_scaler->d_scaling_factor); |
205 | | |
206 | | /* luma */ |
207 | 507k | s_src_buf = ps_src_buf_props->as_component_bufs[Y]; |
208 | 507k | s_src_buf.pv_data = ((UWORD8 *) s_src_buf.pv_data) - (NUM_SCALER_FILTER_TAPS / 2) - |
209 | 507k | (NUM_SCALER_FILTER_TAPS / 2) * s_src_buf.i4_data_stride; |
210 | | |
211 | 507k | s_dst_buf.pv_data = ps_scaler_state->pv_scratch_buf; |
212 | 507k | s_dst_buf.i4_data_stride = u4_blk_ht + NUM_SCALER_FILTER_TAPS; |
213 | | |
214 | 507k | ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters, |
215 | 507k | u4_scaled_block_size_x, u4_blk_ht + NUM_SCALER_FILTER_TAPS, 0); |
216 | | |
217 | 507k | s_src_buf = s_dst_buf; |
218 | 507k | s_dst_buf = ps_dst_buf_props->as_component_bufs[Y]; |
219 | | |
220 | 507k | ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters, |
221 | 507k | u4_scaled_block_size_y, u4_scaled_block_size_x, 0); |
222 | | |
223 | | /* chroma */ |
224 | 507k | u4_blk_ht /= 2; |
225 | 507k | u4_scaled_block_size_y /= 2; |
226 | | |
227 | 507k | s_src_buf = ps_src_buf_props->as_component_bufs[U]; |
228 | 507k | s_src_buf.pv_data = ((UWORD8 *) s_src_buf.pv_data) - NUM_SCALER_FILTER_TAPS - |
229 | 507k | (NUM_SCALER_FILTER_TAPS / 2) * s_src_buf.i4_data_stride; |
230 | | |
231 | 507k | s_dst_buf.pv_data = ps_scaler_state->pv_scratch_buf; |
232 | 507k | s_dst_buf.i4_data_stride = u4_blk_ht + NUM_SCALER_FILTER_TAPS; |
233 | | |
234 | 507k | ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters, |
235 | 507k | u4_scaled_block_size_x, u4_blk_ht + NUM_SCALER_FILTER_TAPS, 1); |
236 | | |
237 | 507k | s_src_buf = s_dst_buf; |
238 | 507k | s_dst_buf = ps_dst_buf_props->as_component_bufs[U]; |
239 | | |
240 | 507k | ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters, |
241 | 507k | u4_scaled_block_size_y, u4_scaled_block_size_x, 0); |
242 | 507k | } |
243 | | |
244 | | /** |
245 | | ******************************************************************************* |
246 | | * |
247 | | * @brief |
248 | | * normalized dot product computer for downscaler |
249 | | * |
250 | | * @par Description: |
251 | | * Given the downscaler filter coefficients, source buffer, the function |
252 | | * calculates the dot product between them, adds an offset and normalizes it |
253 | | * |
254 | | * @param[in] ps_scaler |
255 | | * pointer to src buf |
256 | | * |
257 | | * @param[in] pi1_filter |
258 | | * pointer to filter coefficients |
259 | | * |
260 | | * @returns |
261 | | * |
262 | | * @remarks |
263 | | * |
264 | | ******************************************************************************* |
265 | | */ |
266 | | |
267 | | static UWORD8 isvce_get_downscaler_normalized_filtered_pixel(UWORD8 *pu1_src, WORD8 *pi1_filter) |
268 | 3.70G | { |
269 | 3.70G | WORD32 i; |
270 | 3.70G | WORD32 i4_norm_dot_product; |
271 | 3.70G | UWORD8 u1_out_pixel; |
272 | 3.70G | WORD32 i4_dot_product_sum = 0; |
273 | 3.70G | WORD32 i4_rounding_offset = 1 << (FILTER_COEFF_Q - 1); |
274 | 3.70G | WORD32 i4_normalizing_factor = 1 << FILTER_COEFF_Q; |
275 | | |
276 | 33.3G | for(i = 0; i < NUM_SCALER_FILTER_TAPS; i++) |
277 | 29.6G | { |
278 | 29.6G | i4_dot_product_sum += (pu1_src[i] * pi1_filter[i]); |
279 | 29.6G | } |
280 | | |
281 | 3.70G | i4_norm_dot_product = ((i4_dot_product_sum + i4_rounding_offset) / i4_normalizing_factor); |
282 | 3.70G | u1_out_pixel = (UWORD8) CLIP_U8(i4_norm_dot_product); |
283 | | |
284 | 3.70G | return u1_out_pixel; |
285 | 3.70G | } |
286 | | |
287 | | /** |
288 | | ******************************************************************************* |
289 | | * |
290 | | * @brief |
291 | | * horizontal scaler function |
292 | | * |
293 | | * @par Description: |
294 | | * Does horizontal scaling for the given block |
295 | | * |
296 | | * @param[in] ps_scaler |
297 | | * pointer to downscaler context |
298 | | * |
299 | | * @param[in] ps_src |
300 | | * pointer to source buffer container |
301 | | * |
302 | | * @param[in] ps_dst |
303 | | * pointer to destination buffer container |
304 | | * |
305 | | * @param[in] pai1_filters |
306 | | * pointer to array of downscaler filters |
307 | | * |
308 | | * @param[in] u4_blk_wd |
309 | | * width of the block after horizontal scaling (output block width) |
310 | | * |
311 | | * @param[in] u4_blk_ht |
312 | | * height of the current block (input block height) |
313 | | * |
314 | | * @param[in] u1_is_chroma |
315 | | * flag suggesting whether the buffer is luma or chroma |
316 | | * |
317 | | * |
318 | | * @returns |
319 | | * |
320 | | * @remarks |
321 | | * The same function is used for vertical scaling too as |
322 | | * the horizontally scaled input in stored in transpose fashion. |
323 | | * |
324 | | ******************************************************************************* |
325 | | */ |
326 | | |
327 | | static void isvce_horizontal_downscale_and_transpose( |
328 | | downscaler_ctxt_t *ps_scaler, buffer_container_t *ps_src, buffer_container_t *ps_dst, |
329 | | FILTER_COEFF_ARRAY pai1_filters, UWORD32 u4_blk_wd, UWORD32 u4_blk_ht, UWORD8 u1_is_chroma) |
330 | 1.27M | { |
331 | 1.27M | WORD32 i, j, k; |
332 | 1.27M | UWORD8 u1_phase; |
333 | 1.27M | UWORD8 u1_filtered_out_pixel; |
334 | 1.27M | UWORD8 *pu1_src_j, *pu1_dst_j; |
335 | 1.27M | UWORD8 u1_filtered_out_u_pixel, u1_filtered_out_v_pixel; |
336 | 1.27M | UWORD8 *pu1_in_pixel; |
337 | 1.27M | UWORD8 *pu1_out_pixel; |
338 | 1.27M | WORD8 *pi1_filter_grid; |
339 | 1.27M | UWORD16 u2_full_pixel_inc; |
340 | 1.27M | UWORD8 au1_temp_u_buff[NUM_SCALER_FILTER_TAPS]; |
341 | 1.27M | UWORD8 au1_temp_v_buff[NUM_SCALER_FILTER_TAPS]; |
342 | | |
343 | 1.27M | downscaler_state_t *ps_scaler_state = (downscaler_state_t *) ps_scaler->pv_scaler_state; |
344 | | |
345 | 1.27M | UWORD32 u4_center_pixel_pos = ps_scaler_state->i4_init_offset; |
346 | 1.27M | UWORD32 u4_src_horz_increments = ps_scaler_state->u4_horz_increment; |
347 | 1.27M | UWORD8 *pu1_src = ps_src->pv_data; |
348 | 1.27M | UWORD32 u4_in_stride = ps_src->i4_data_stride; |
349 | 1.27M | UWORD8 *pu1_dst = ps_dst->pv_data; |
350 | 1.27M | UWORD32 u4_out_stride = ps_dst->i4_data_stride; |
351 | 1.27M | UWORD32 u4_center_pixel_pos_src = u4_center_pixel_pos; |
352 | | |
353 | | /* Offset the input so that the input pixel to be processed |
354 | | co-incides with the centre of filter (4th coefficient)*/ |
355 | 1.27M | pu1_src += (1 + u1_is_chroma); |
356 | | |
357 | 1.27M | ASSERT((1 << DOWNSCALER_Q) == ps_scaler_state->u4_vert_increment); |
358 | | |
359 | 1.27M | if(!u1_is_chroma) |
360 | 955k | { |
361 | 58.1M | for(j = 0; j < (WORD32) u4_blk_ht; j++) |
362 | 57.2M | { |
363 | 57.2M | pu1_src_j = pu1_src + (j * u4_in_stride); |
364 | 57.2M | pu1_dst_j = pu1_dst + j; |
365 | | |
366 | 57.2M | u4_center_pixel_pos = u4_center_pixel_pos_src; |
367 | | |
368 | 2.32G | for(i = 0; i < (WORD32) u4_blk_wd; i++) |
369 | 2.26G | { |
370 | 2.26G | u1_phase = get_filter_phase(u4_center_pixel_pos); |
371 | 2.26G | pi1_filter_grid = pai1_filters[u1_phase]; |
372 | | |
373 | | /* Doing the Calculation for current Loop Count */ |
374 | 2.26G | u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q; |
375 | 2.26G | pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma); |
376 | 2.26G | pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride); |
377 | | |
378 | 2.26G | u1_filtered_out_pixel = |
379 | 2.26G | isvce_get_downscaler_normalized_filtered_pixel(pu1_in_pixel, pi1_filter_grid); |
380 | 2.26G | *pu1_out_pixel = u1_filtered_out_pixel; |
381 | | |
382 | | /* Update the context for next Loop Count */ |
383 | 2.26G | u4_center_pixel_pos += u4_src_horz_increments; |
384 | 2.26G | } |
385 | 57.2M | } |
386 | 955k | } |
387 | 318k | else |
388 | 318k | { |
389 | 15.7M | for(j = 0; j < (WORD32) u4_blk_ht; j++) |
390 | 15.3M | { |
391 | 15.3M | pu1_src_j = pu1_src + (j * u4_in_stride); |
392 | 15.3M | pu1_dst_j = pu1_dst + j; |
393 | | |
394 | 15.3M | u4_center_pixel_pos = u4_center_pixel_pos_src; |
395 | | |
396 | 731M | for(i = 0; i < (WORD32) u4_blk_wd; i++) |
397 | 716M | { |
398 | 716M | u1_phase = get_filter_phase(u4_center_pixel_pos); |
399 | 716M | pi1_filter_grid = pai1_filters[u1_phase]; |
400 | | |
401 | | /*Doing the Calculation for current Loop Count */ |
402 | 716M | u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q; |
403 | 716M | pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma); |
404 | 716M | pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride); |
405 | | |
406 | 6.44G | for(k = 0; k < NUM_SCALER_FILTER_TAPS; k++) |
407 | 5.72G | { |
408 | 5.72G | au1_temp_u_buff[k] = *(pu1_in_pixel + (2 * k)); |
409 | 5.72G | au1_temp_v_buff[k] = *(pu1_in_pixel + ((2 * k) + 1)); |
410 | 5.72G | } |
411 | | |
412 | 716M | u1_filtered_out_u_pixel = isvce_get_downscaler_normalized_filtered_pixel( |
413 | 716M | au1_temp_u_buff, pi1_filter_grid); |
414 | 716M | u1_filtered_out_v_pixel = isvce_get_downscaler_normalized_filtered_pixel( |
415 | 716M | au1_temp_v_buff, pi1_filter_grid); |
416 | 716M | *pu1_out_pixel = u1_filtered_out_u_pixel; |
417 | 716M | *(pu1_out_pixel + u4_out_stride) = u1_filtered_out_v_pixel; |
418 | | |
419 | | /* Update the context for next Loop Count */ |
420 | 716M | u4_center_pixel_pos += u4_src_horz_increments; |
421 | 716M | } |
422 | 15.3M | } |
423 | 318k | } |
424 | 1.27M | } |
425 | | |
426 | | void isvce_downscaler_function_selector(downscaler_state_t *ps_scaler_state, IV_ARCH_T e_arch) |
427 | 4.04k | { |
428 | 4.04k | switch(e_arch) |
429 | 4.04k | { |
430 | 0 | #if defined(X86) |
431 | 1.55k | case ARCH_X86_SSE42: |
432 | 1.55k | { |
433 | 1.55k | ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose_sse42; |
434 | | |
435 | 1.55k | break; |
436 | 0 | } |
437 | | #elif defined(ARMV8) |
438 | | case ARCH_ARM_A53: |
439 | | case ARCH_ARM_A57: |
440 | | case ARCH_ARM_V8_NEON: |
441 | | { |
442 | | ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose_neon; |
443 | | |
444 | | break; |
445 | | } |
446 | | #elif defined(ARM) && !defined(DISABLE_NEON) |
447 | | case ARCH_ARM_A9Q: |
448 | | case ARCH_ARM_A9A: |
449 | | case ARCH_ARM_A9: |
450 | | case ARCH_ARM_A7: |
451 | | case ARCH_ARM_A5: |
452 | | case ARCH_ARM_A15: |
453 | | { |
454 | | ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose_neon; |
455 | | |
456 | | break; |
457 | | } |
458 | | #endif |
459 | 2.49k | default: |
460 | 2.49k | { |
461 | 2.49k | ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose; |
462 | | |
463 | 2.49k | break; |
464 | 0 | } |
465 | 4.04k | } |
466 | 4.04k | } |
467 | | |
468 | | /** |
469 | | ******************************************************************************* |
470 | | * |
471 | | * @brief |
472 | | * initializes the downscaler context |
473 | | * |
474 | | * @par Description: |
475 | | * initializes the downscaler context for the given scaling factor |
476 | | * with padding size, filter size, etc. |
477 | | * |
478 | | * @param[in] ps_scaler |
479 | | * pointer downscaler context |
480 | | * |
481 | | * @param[in] ps_mem_rec |
482 | | * pointer to memory allocated to downscaler process |
483 | | * |
484 | | * @param[in] d_scaling_factor |
485 | | * scaling reatio of width/ height between two consecutive SVC layers |
486 | | * |
487 | | * @param[in] u1_num_spatial_layers |
488 | | * scaling reatio of width/ height between two consecutive SVC layers |
489 | | * |
490 | | * @param[in] u4_wd |
491 | | * width of the input |
492 | | * |
493 | | * @param[in] u4_ht |
494 | | * height of the input |
495 | | * |
496 | | * @param[in] e_arch |
497 | | * architecure type |
498 | | * |
499 | | * @returns |
500 | | * |
501 | | * @remarks |
502 | | * when ARM intrinsics are added, update should be done here |
503 | | * |
504 | | ******************************************************************************* |
505 | | */ |
506 | | |
507 | | void isvce_initialize_downscaler(downscaler_ctxt_t *ps_scaler, iv_mem_rec_t *ps_mem_rec, |
508 | | DOUBLE d_scaling_factor, UWORD8 u1_num_spatial_layers, |
509 | | UWORD32 u4_in_width, UWORD32 u4_in_height, IV_ARCH_T e_arch) |
510 | 4.93k | { |
511 | 4.93k | if(u1_num_spatial_layers > 1) |
512 | 4.04k | { |
513 | 4.04k | downscaler_state_t *ps_scaler_state; |
514 | | |
515 | 4.04k | UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base; |
516 | | |
517 | 4.04k | ps_scaler_state = (downscaler_state_t *) pu1_buf; |
518 | 4.04k | pu1_buf += sizeof(ps_scaler_state[0]); |
519 | | |
520 | 4.04k | ps_scaler_state->pv_scratch_buf = pu1_buf; |
521 | 4.04k | ps_scaler_state->u4_in_wd = u4_in_width; |
522 | 4.04k | ps_scaler_state->u4_in_ht = u4_in_height; |
523 | | |
524 | 4.04k | ps_scaler->pv_scaler_state = ps_scaler_state; |
525 | 4.04k | ps_scaler->d_scaling_factor = d_scaling_factor; |
526 | 4.04k | ps_scaler->u1_num_spatial_layers = u1_num_spatial_layers; |
527 | | |
528 | 4.04k | isvce_downscaler_function_selector(ps_scaler_state, e_arch); |
529 | | |
530 | 4.04k | ps_scaler_state->u4_horz_increment = (UWORD32) (d_scaling_factor * (1 << DOWNSCALER_Q)); |
531 | | |
532 | 4.04k | ps_scaler_state->u4_vert_increment = (1 << DOWNSCALER_Q); |
533 | 4.04k | ps_scaler_state->i4_init_offset = 0; |
534 | 4.04k | ps_scaler_state->pai1_filters = (d_scaling_factor == 2.0) ? gai1_lanczos_coefficients_2x |
535 | 4.04k | : gai1_lanczos_coefficients_3by2x; |
536 | 4.04k | } |
537 | 4.93k | } |