/src/libavc/encoder/ih264e_fmt_conv.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2015 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 | | * ih264e_fmt_conv.c |
25 | | * |
26 | | * @brief |
27 | | * Contains functions for format conversion or frame copy of output buffer |
28 | | * |
29 | | * @author |
30 | | * ittiam |
31 | | * |
32 | | * @par List of Functions: |
33 | | * - ih264e_fmt_conv_420sp_to_rgb565 |
34 | | * - ih264e_fmt_conv_420sp_to_rgba8888 |
35 | | * - ih264e_fmt_conv_420sp_to_420sp |
36 | | * - ih264e_fmt_conv_420sp_to_420sp_swap_uv |
37 | | * - ih264e_fmt_conv_420sp_to_420p |
38 | | * - ih264e_fmt_conv_420p_to_420sp |
39 | | * - ih264e_fmt_conv_422i_to_420sp |
40 | | * - ih264e_fmt_conv |
41 | | * |
42 | | * @remarks |
43 | | * none |
44 | | * |
45 | | ******************************************************************************* |
46 | | */ |
47 | | |
48 | | /*****************************************************************************/ |
49 | | /* File Includes */ |
50 | | /*****************************************************************************/ |
51 | | |
52 | | /* System Include Files */ |
53 | | #include <stdio.h> |
54 | | #include <stddef.h> |
55 | | #include <stdlib.h> |
56 | | #include <string.h> |
57 | | #include <assert.h> |
58 | | |
59 | | /* User Include Files */ |
60 | | #include "ih264_typedefs.h" |
61 | | #include "iv2.h" |
62 | | #include "ive2.h" |
63 | | #include "ithread.h" |
64 | | |
65 | | #include "ih264_debug.h" |
66 | | #include "ih264_macros.h" |
67 | | #include "ih264_error.h" |
68 | | #include "ih264_defs.h" |
69 | | #include "ih264_mem_fns.h" |
70 | | #include "ih264_padding.h" |
71 | | #include "ih264_structs.h" |
72 | | #include "ih264_trans_quant_itrans_iquant.h" |
73 | | #include "ih264_inter_pred_filters.h" |
74 | | #include "ih264_intra_pred_filters.h" |
75 | | #include "ih264_deblk_edge_filters.h" |
76 | | #include "ih264_cabac_tables.h" |
77 | | #include "ih264_platform_macros.h" |
78 | | |
79 | | #include "ime_defs.h" |
80 | | #include "ime_distortion_metrics.h" |
81 | | #include "ime_structs.h" |
82 | | |
83 | | #include "irc_cntrl_param.h" |
84 | | #include "irc_frame_info_collector.h" |
85 | | |
86 | | #include "ih264e.h" |
87 | | #include "ih264e_error.h" |
88 | | #include "ih264e_defs.h" |
89 | | #include "ih264e_rate_control.h" |
90 | | #include "ih264e_bitstream.h" |
91 | | #include "ih264e_cabac_structs.h" |
92 | | #include "ih264e_structs.h" |
93 | | #include "ih264e_fmt_conv.h" |
94 | | |
95 | | |
96 | | /*****************************************************************************/ |
97 | | /* Function Definitions */ |
98 | | /*****************************************************************************/ |
99 | | |
100 | | /** |
101 | | ******************************************************************************* |
102 | | * |
103 | | * @brief Function used to perform color space conversion from 420SP to RGB565 |
104 | | * |
105 | | * @par Description |
106 | | * Function used to perform color space conversion from 420SP to RGB565 |
107 | | * |
108 | | * @param[in] pu1_y_src |
109 | | * Input Y pointer |
110 | | * |
111 | | * @param[in] pu1_uv_src |
112 | | * Input UV pointer |
113 | | * |
114 | | * @param[in] pu2_rgb_dst |
115 | | * Output RGB pointer |
116 | | * |
117 | | * @param[in] wd |
118 | | * Width |
119 | | * |
120 | | * @param[in] ht |
121 | | * Height |
122 | | * |
123 | | * @param[in] src_y_strd |
124 | | * Input Y Stride |
125 | | * |
126 | | * @param[in] src_uv_strd |
127 | | * Input UV stride |
128 | | * |
129 | | * @param[in] dst_strd |
130 | | * Output stride |
131 | | * |
132 | | * @param[in] is_u_first |
133 | | * Flag to indicate chroma ordering |
134 | | * |
135 | | * @returns none |
136 | | * |
137 | | ******************************************************************************* |
138 | | */ |
139 | | void ih264e_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src, |
140 | | UWORD8 *pu1_uv_src, |
141 | | UWORD16 *pu2_rgb_dst, |
142 | | WORD32 wd, |
143 | | WORD32 ht, |
144 | | WORD32 src_y_strd, |
145 | | WORD32 src_uv_strd, |
146 | | WORD32 dst_strd, |
147 | | WORD32 is_u_first) |
148 | 0 | { |
149 | 0 | WORD16 i2_r, i2_g, i2_b; |
150 | 0 | UWORD32 u4_r, u4_g, u4_b; |
151 | 0 | WORD16 i2_i, i2_j; |
152 | 0 | UWORD8 *pu1_y_src_nxt; |
153 | 0 | UWORD16 *pu2_rgb_dst_NextRow; |
154 | |
|
155 | 0 | UWORD8 *pu1_u_src, *pu1_v_src; |
156 | |
|
157 | 0 | if (is_u_first) |
158 | 0 | { |
159 | 0 | pu1_u_src = (UWORD8 *) pu1_uv_src; |
160 | 0 | pu1_v_src = (UWORD8 *) pu1_uv_src + 1; |
161 | 0 | } |
162 | 0 | else |
163 | 0 | { |
164 | 0 | pu1_u_src = (UWORD8 *) pu1_uv_src + 1; |
165 | 0 | pu1_v_src = (UWORD8 *) pu1_uv_src; |
166 | 0 | } |
167 | |
|
168 | 0 | pu1_y_src_nxt = pu1_y_src + src_y_strd; |
169 | 0 | pu2_rgb_dst_NextRow = pu2_rgb_dst + dst_strd; |
170 | |
|
171 | 0 | for (i2_i = 0; i2_i < (ht >> 1); i2_i++) |
172 | 0 | { |
173 | 0 | for (i2_j = (wd >> 1); i2_j > 0; i2_j--) |
174 | 0 | { |
175 | 0 | i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13); |
176 | 0 | i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3) |
177 | 0 | >> 13; |
178 | 0 | i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13; |
179 | |
|
180 | 0 | pu1_u_src += 2; |
181 | 0 | pu1_v_src += 2; |
182 | | /* pixel 0 */ |
183 | | /* B */ |
184 | 0 | u4_b = CLIP_U8(*pu1_y_src + i2_b); |
185 | 0 | u4_b >>= 3; |
186 | | /* G */ |
187 | 0 | u4_g = CLIP_U8(*pu1_y_src + i2_g); |
188 | 0 | u4_g >>= 2; |
189 | | /* R */ |
190 | 0 | u4_r = CLIP_U8(*pu1_y_src + i2_r); |
191 | 0 | u4_r >>= 3; |
192 | |
|
193 | 0 | pu1_y_src++; |
194 | 0 | *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b); |
195 | | |
196 | | /* pixel 1 */ |
197 | | /* B */ |
198 | 0 | u4_b = CLIP_U8(*pu1_y_src + i2_b); |
199 | 0 | u4_b >>= 3; |
200 | | /* G */ |
201 | 0 | u4_g = CLIP_U8(*pu1_y_src + i2_g); |
202 | 0 | u4_g >>= 2; |
203 | | /* R */ |
204 | 0 | u4_r = CLIP_U8(*pu1_y_src + i2_r); |
205 | 0 | u4_r >>= 3; |
206 | |
|
207 | 0 | pu1_y_src++; |
208 | 0 | *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b); |
209 | | |
210 | | /* pixel 2 */ |
211 | | /* B */ |
212 | 0 | u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); |
213 | 0 | u4_b >>= 3; |
214 | | /* G */ |
215 | 0 | u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); |
216 | 0 | u4_g >>= 2; |
217 | | /* R */ |
218 | 0 | u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); |
219 | 0 | u4_r >>= 3; |
220 | |
|
221 | 0 | pu1_y_src_nxt++; |
222 | 0 | *pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b); |
223 | | |
224 | | /* pixel 3 */ |
225 | | /* B */ |
226 | 0 | u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); |
227 | 0 | u4_b >>= 3; |
228 | | /* G */ |
229 | 0 | u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); |
230 | 0 | u4_g >>= 2; |
231 | | /* R */ |
232 | 0 | u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); |
233 | 0 | u4_r >>= 3; |
234 | |
|
235 | 0 | pu1_y_src_nxt++; |
236 | 0 | *pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b); |
237 | |
|
238 | 0 | } |
239 | |
|
240 | 0 | pu1_u_src = pu1_u_src + src_uv_strd - wd; |
241 | 0 | pu1_v_src = pu1_v_src + src_uv_strd - wd; |
242 | |
|
243 | 0 | pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd; |
244 | 0 | pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd; |
245 | |
|
246 | 0 | pu2_rgb_dst = pu2_rgb_dst_NextRow - wd + dst_strd; |
247 | 0 | pu2_rgb_dst_NextRow = pu2_rgb_dst_NextRow + (dst_strd << 1) - wd; |
248 | 0 | } |
249 | |
|
250 | 0 | } |
251 | | |
252 | | /** |
253 | | ******************************************************************************* |
254 | | * |
255 | | * @brief Function used to perform color space conversion from 420SP to RGBA888 |
256 | | * |
257 | | * @par Description |
258 | | * Function used to perform color space conversion from 420SP to RGBA888 |
259 | | * |
260 | | * @param[in] pu1_y_src |
261 | | * Input Y pointer |
262 | | * |
263 | | * @param[in] pu1_uv_src |
264 | | * Input UV pointer |
265 | | * |
266 | | * @param[in] pu4_rgba_dst |
267 | | * Output RGB pointer |
268 | | * |
269 | | * @param[in] wd |
270 | | * Width |
271 | | * |
272 | | * @param[in] ht |
273 | | * Height |
274 | | * |
275 | | * @param[in] src_y_strd |
276 | | * Input Y Stride |
277 | | * |
278 | | * @param[in] src_uv_strd |
279 | | * Input UV stride |
280 | | * |
281 | | * @param[in] dst_strd |
282 | | * Output stride |
283 | | * |
284 | | * @param[in] is_u_first |
285 | | * Flag to indicate chroma ordering |
286 | | * |
287 | | * @returns none |
288 | | * |
289 | | ******************************************************************************* |
290 | | */ |
291 | | void ih264e_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src, |
292 | | UWORD8 *pu1_uv_src, |
293 | | UWORD32 *pu4_rgba_dst, |
294 | | WORD32 wd, |
295 | | WORD32 ht, |
296 | | WORD32 src_y_strd, |
297 | | WORD32 src_uv_strd, |
298 | | WORD32 dst_strd, |
299 | | WORD32 is_u_first) |
300 | 0 | { |
301 | 0 | WORD16 i2_r, i2_g, i2_b; |
302 | 0 | UWORD32 u4_r, u4_g, u4_b; |
303 | 0 | WORD16 i2_i, i2_j; |
304 | 0 | UWORD8 *pu1_y_src_nxt; |
305 | 0 | UWORD32 *pu4_rgba_dst_NextRow; |
306 | 0 | UWORD8 *pu1_u_src, *pu1_v_src; |
307 | |
|
308 | 0 | if (is_u_first) |
309 | 0 | { |
310 | 0 | pu1_u_src = (UWORD8 *) pu1_uv_src; |
311 | 0 | pu1_v_src = (UWORD8 *) pu1_uv_src + 1; |
312 | 0 | } |
313 | 0 | else |
314 | 0 | { |
315 | 0 | pu1_u_src = (UWORD8 *) pu1_uv_src + 1; |
316 | 0 | pu1_v_src = (UWORD8 *) pu1_uv_src; |
317 | 0 | } |
318 | |
|
319 | 0 | pu1_y_src_nxt = pu1_y_src + src_y_strd; |
320 | |
|
321 | 0 | pu4_rgba_dst_NextRow = pu4_rgba_dst + dst_strd; |
322 | |
|
323 | 0 | for (i2_i = 0; i2_i < (ht >> 1); i2_i++) |
324 | 0 | { |
325 | 0 | for (i2_j = (wd >> 1); i2_j > 0; i2_j--) |
326 | 0 | { |
327 | 0 | i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13); |
328 | 0 | i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3) |
329 | 0 | >> 13; |
330 | 0 | i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13; |
331 | |
|
332 | 0 | pu1_u_src += 2; |
333 | 0 | pu1_v_src += 2; |
334 | | /* pixel 0 */ |
335 | | /* B */ |
336 | 0 | u4_b = CLIP_U8(*pu1_y_src + i2_b); |
337 | | /* G */ |
338 | 0 | u4_g = CLIP_U8(*pu1_y_src + i2_g); |
339 | | /* R */ |
340 | 0 | u4_r = CLIP_U8(*pu1_y_src + i2_r); |
341 | |
|
342 | 0 | pu1_y_src++; |
343 | 0 | *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); |
344 | | |
345 | | /* pixel 1 */ |
346 | | /* B */ |
347 | 0 | u4_b = CLIP_U8(*pu1_y_src + i2_b); |
348 | | /* G */ |
349 | 0 | u4_g = CLIP_U8(*pu1_y_src + i2_g); |
350 | | /* R */ |
351 | 0 | u4_r = CLIP_U8(*pu1_y_src + i2_r); |
352 | |
|
353 | 0 | pu1_y_src++; |
354 | 0 | *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); |
355 | | |
356 | | /* pixel 2 */ |
357 | | /* B */ |
358 | 0 | u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); |
359 | | /* G */ |
360 | 0 | u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); |
361 | | /* R */ |
362 | 0 | u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); |
363 | |
|
364 | 0 | pu1_y_src_nxt++; |
365 | 0 | *pu4_rgba_dst_NextRow++ = |
366 | 0 | ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); |
367 | | |
368 | | /* pixel 3 */ |
369 | | /* B */ |
370 | 0 | u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); |
371 | | /* G */ |
372 | 0 | u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); |
373 | | /* R */ |
374 | 0 | u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); |
375 | |
|
376 | 0 | pu1_y_src_nxt++; |
377 | 0 | *pu4_rgba_dst_NextRow++ = |
378 | 0 | ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); |
379 | |
|
380 | 0 | } |
381 | |
|
382 | 0 | pu1_u_src = pu1_u_src + src_uv_strd - wd; |
383 | 0 | pu1_v_src = pu1_v_src + src_uv_strd - wd; |
384 | |
|
385 | 0 | pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd; |
386 | 0 | pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd; |
387 | |
|
388 | 0 | pu4_rgba_dst = pu4_rgba_dst_NextRow - wd + dst_strd; |
389 | 0 | pu4_rgba_dst_NextRow = pu4_rgba_dst_NextRow + (dst_strd << 1) - wd; |
390 | 0 | } |
391 | |
|
392 | 0 | } |
393 | | |
394 | | /** |
395 | | ******************************************************************************* |
396 | | * |
397 | | * @brief Function used for copying a 420SP buffer |
398 | | * |
399 | | * @par Description |
400 | | * Function used for copying a 420SP buffer |
401 | | * |
402 | | * @param[in] pu1_y_src |
403 | | * Input Y pointer |
404 | | * |
405 | | * @param[in] pu1_uv_src |
406 | | * Input UV pointer (UV is interleaved either in UV or VU format) |
407 | | * |
408 | | * @param[in] pu1_y_dst |
409 | | * Output Y pointer |
410 | | * |
411 | | * @param[in] pu1_uv_dst |
412 | | * Output UV pointer (UV is interleaved in the same format as that of input) |
413 | | * |
414 | | * @param[in] wd |
415 | | * Width |
416 | | * |
417 | | * @param[in] ht |
418 | | * Height |
419 | | * |
420 | | * @param[in] src_y_strd |
421 | | * Input Y Stride |
422 | | * |
423 | | * @param[in] src_uv_strd |
424 | | * Input UV stride |
425 | | * |
426 | | * @param[in] dst_y_strd |
427 | | * Output Y stride |
428 | | * |
429 | | * @param[in] dst_uv_strd |
430 | | * Output UV stride |
431 | | * |
432 | | * @returns None |
433 | | * |
434 | | ******************************************************************************* |
435 | | */ |
436 | | void ih264e_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src, |
437 | | UWORD8 *pu1_uv_src, |
438 | | UWORD8 *pu1_y_dst, |
439 | | UWORD8 *pu1_uv_dst, |
440 | | WORD32 wd, |
441 | | WORD32 ht, |
442 | | WORD32 src_y_strd, |
443 | | WORD32 src_uv_strd, |
444 | | WORD32 dst_y_strd, |
445 | | WORD32 dst_uv_strd) |
446 | 0 | { |
447 | 0 | UWORD8 *pu1_src, *pu1_dst; |
448 | 0 | WORD32 num_rows, num_cols, src_strd, dst_strd; |
449 | 0 | WORD32 i; |
450 | | |
451 | | /* copy luma */ |
452 | 0 | pu1_src = (UWORD8 *) pu1_y_src; |
453 | 0 | pu1_dst = (UWORD8 *) pu1_y_dst; |
454 | |
|
455 | 0 | num_rows = ht; |
456 | 0 | num_cols = wd; |
457 | |
|
458 | 0 | src_strd = src_y_strd; |
459 | 0 | dst_strd = dst_y_strd; |
460 | |
|
461 | 0 | for (i = 0; i < num_rows; i++) |
462 | 0 | { |
463 | 0 | memcpy(pu1_dst, pu1_src, num_cols); |
464 | 0 | pu1_dst += dst_strd; |
465 | 0 | pu1_src += src_strd; |
466 | 0 | } |
467 | | |
468 | | /* copy U and V */ |
469 | 0 | pu1_src = (UWORD8 *) pu1_uv_src; |
470 | 0 | pu1_dst = (UWORD8 *) pu1_uv_dst; |
471 | |
|
472 | 0 | num_rows = ht >> 1; |
473 | 0 | num_cols = wd; |
474 | |
|
475 | 0 | src_strd = src_uv_strd; |
476 | 0 | dst_strd = dst_uv_strd; |
477 | |
|
478 | 0 | for (i = 0; i < num_rows; i++) |
479 | 0 | { |
480 | 0 | memcpy(pu1_dst, pu1_src, num_cols); |
481 | 0 | pu1_dst += dst_strd; |
482 | 0 | pu1_src += src_strd; |
483 | 0 | } |
484 | 0 | return; |
485 | 0 | } |
486 | | |
487 | | /** |
488 | | ******************************************************************************* |
489 | | * |
490 | | * @brief Function used for copying a 420SP buffer and interchange chroma planes |
491 | | * |
492 | | * @par Description |
493 | | * Function used for copying a 420SP buffer and interchange chroma planes |
494 | | * |
495 | | * @param[in] pu1_y_src |
496 | | * Input Y pointer |
497 | | * |
498 | | * @param[in] pu1_uv_src |
499 | | * Input UV pointer (UV is interleaved either in UV or VU format) |
500 | | * |
501 | | * @param[in] pu1_y_dst |
502 | | * Output Y pointer |
503 | | * |
504 | | * @param[in] pu1_uv_dst |
505 | | * Output UV pointer (UV is interleaved in the opp. format as that of input) |
506 | | * |
507 | | * @param[in] wd |
508 | | * Width |
509 | | * |
510 | | * @param[in] ht |
511 | | * Height |
512 | | * |
513 | | * @param[in] src_y_strd |
514 | | * Input Y Stride |
515 | | * |
516 | | * @param[in] src_uv_strd |
517 | | * Input UV stride |
518 | | * |
519 | | * @param[in] dst_y_strd |
520 | | * Output Y stride |
521 | | * |
522 | | * @param[in] dst_uv_strd |
523 | | * Output UV stride |
524 | | * |
525 | | * @returns None |
526 | | * |
527 | | ******************************************************************************* |
528 | | */ |
529 | | void ih264e_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src, |
530 | | UWORD8 *pu1_uv_src, |
531 | | UWORD8 *pu1_y_dst, |
532 | | UWORD8 *pu1_uv_dst, |
533 | | WORD32 wd, |
534 | | WORD32 ht, |
535 | | WORD32 src_y_strd, |
536 | | WORD32 src_uv_strd, |
537 | | WORD32 dst_y_strd, |
538 | | WORD32 dst_uv_strd) |
539 | 0 | { |
540 | 0 | UWORD8 *pu1_src, *pu1_dst; |
541 | 0 | WORD32 num_rows, num_cols, src_strd, dst_strd; |
542 | 0 | WORD32 i; |
543 | | |
544 | | /* copy luma */ |
545 | 0 | pu1_src = (UWORD8 *) pu1_y_src; |
546 | 0 | pu1_dst = (UWORD8 *) pu1_y_dst; |
547 | |
|
548 | 0 | num_rows = ht; |
549 | 0 | num_cols = wd; |
550 | |
|
551 | 0 | src_strd = src_y_strd; |
552 | 0 | dst_strd = dst_y_strd; |
553 | |
|
554 | 0 | for (i = 0; i < num_rows; i++) |
555 | 0 | { |
556 | 0 | memcpy(pu1_dst, pu1_src, num_cols); |
557 | 0 | pu1_dst += dst_strd; |
558 | 0 | pu1_src += src_strd; |
559 | 0 | } |
560 | | |
561 | | /* copy U and V */ |
562 | 0 | pu1_src = (UWORD8 *) pu1_uv_src; |
563 | 0 | pu1_dst = (UWORD8 *) pu1_uv_dst; |
564 | |
|
565 | 0 | num_rows = ht >> 1; |
566 | 0 | num_cols = wd; |
567 | |
|
568 | 0 | src_strd = src_uv_strd; |
569 | 0 | dst_strd = dst_uv_strd; |
570 | |
|
571 | 0 | for (i = 0; i < num_rows; i++) |
572 | 0 | { |
573 | 0 | WORD32 j; |
574 | 0 | for (j = 0; j < num_cols; j += 2) |
575 | 0 | { |
576 | 0 | pu1_dst[j + 0] = pu1_src[j + 1]; |
577 | 0 | pu1_dst[j + 1] = pu1_src[j + 0]; |
578 | 0 | } |
579 | 0 | pu1_dst += dst_strd; |
580 | 0 | pu1_src += src_strd; |
581 | 0 | } |
582 | 0 | return; |
583 | 0 | } |
584 | | |
585 | | /** |
586 | | ******************************************************************************* |
587 | | * |
588 | | * @brief Function used to perform color space conversion from 420SP to 420P |
589 | | * |
590 | | * @par Description |
591 | | * Function used to perform color space conversion from 420SP to 420P |
592 | | * |
593 | | * @param[in] pu1_y_src |
594 | | * Input Y pointer |
595 | | * |
596 | | * @param[in] pu1_uv_src |
597 | | * Input UV pointer (UV is interleaved either in UV or VU format) |
598 | | * |
599 | | * @param[in] pu1_y_dst |
600 | | * Output Y pointer |
601 | | * |
602 | | * @param[in] pu1_u_dst |
603 | | * Output U pointer |
604 | | * |
605 | | * @param[in] pu1_v_dst |
606 | | * Output V pointer |
607 | | * |
608 | | * @param[in] wd |
609 | | * Width |
610 | | * |
611 | | * @param[in] ht |
612 | | * Height |
613 | | * |
614 | | * @param[in] src_y_strd |
615 | | * Input Y Stride |
616 | | * |
617 | | * @param[in] src_uv_strd |
618 | | * Input UV stride |
619 | | * |
620 | | * @param[in] dst_y_strd |
621 | | * Output Y stride |
622 | | * |
623 | | * @param[in] dst_uv_strd |
624 | | * Output UV stride |
625 | | * |
626 | | * @param[in] is_u_first |
627 | | * Flag to indicate chroma ordering |
628 | | * |
629 | | * @param[in] disable_luma_copy |
630 | | * Flag to indicate if only UV copy needs to be done |
631 | | * |
632 | | * @returns none |
633 | | * |
634 | | * @remarks none |
635 | | * |
636 | | ******************************************************************************* |
637 | | */ |
638 | | void ih264e_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src, |
639 | | UWORD8 *pu1_uv_src, |
640 | | UWORD8 *pu1_y_dst, |
641 | | UWORD8 *pu1_u_dst, |
642 | | UWORD8 *pu1_v_dst, |
643 | | WORD32 wd, |
644 | | WORD32 ht, |
645 | | WORD32 src_y_strd, |
646 | | WORD32 src_uv_strd, |
647 | | WORD32 dst_y_strd, |
648 | | WORD32 dst_uv_strd, |
649 | | WORD32 is_u_first, |
650 | | WORD32 disable_luma_copy) |
651 | 1.84k | { |
652 | 1.84k | UWORD8 *pu1_src, *pu1_dst; |
653 | 1.84k | UWORD8 *pu1_u_src, *pu1_v_src; |
654 | 1.84k | WORD32 num_rows, num_cols, src_strd, dst_strd; |
655 | 1.84k | WORD32 i, j; |
656 | | |
657 | 1.84k | if (0 == disable_luma_copy) |
658 | 1.84k | { |
659 | | /* copy luma */ |
660 | 1.84k | pu1_src = (UWORD8 *) pu1_y_src; |
661 | 1.84k | pu1_dst = (UWORD8 *) pu1_y_dst; |
662 | | |
663 | 1.84k | num_rows = ht; |
664 | 1.84k | num_cols = wd; |
665 | | |
666 | 1.84k | src_strd = src_y_strd; |
667 | 1.84k | dst_strd = dst_y_strd; |
668 | | |
669 | 504k | for (i = 0; i < num_rows; i++) |
670 | 502k | { |
671 | 502k | memcpy(pu1_dst, pu1_src, num_cols); |
672 | 502k | pu1_dst += dst_strd; |
673 | 502k | pu1_src += src_strd; |
674 | 502k | } |
675 | 1.84k | } |
676 | | /* de-interleave U and V and copy to destination */ |
677 | 1.84k | if (is_u_first) |
678 | 1.84k | { |
679 | 1.84k | pu1_u_src = (UWORD8 *) pu1_uv_src; |
680 | 1.84k | pu1_v_src = (UWORD8 *) pu1_uv_src + 1; |
681 | 1.84k | } |
682 | 0 | else |
683 | 0 | { |
684 | 0 | pu1_u_src = (UWORD8 *) pu1_uv_src + 1; |
685 | 0 | pu1_v_src = (UWORD8 *) pu1_uv_src; |
686 | 0 | } |
687 | | |
688 | 1.84k | num_rows = ht >> 1; |
689 | 1.84k | num_cols = wd >> 1; |
690 | | |
691 | 1.84k | src_strd = src_uv_strd; |
692 | 1.84k | dst_strd = dst_uv_strd; |
693 | | |
694 | 253k | for (i = 0; i < num_rows; i++) |
695 | 251k | { |
696 | 130M | for (j = 0; j < num_cols; j++) |
697 | 130M | { |
698 | 130M | pu1_u_dst[j] = pu1_u_src[j * 2]; |
699 | 130M | pu1_v_dst[j] = pu1_v_src[j * 2]; |
700 | 130M | } |
701 | | |
702 | 251k | pu1_u_dst += dst_strd; |
703 | 251k | pu1_v_dst += dst_strd; |
704 | 251k | pu1_u_src += src_strd; |
705 | 251k | pu1_v_src += src_strd; |
706 | 251k | } |
707 | 1.84k | return; |
708 | 1.84k | } |
709 | | |
710 | | /** |
711 | | ******************************************************************************* |
712 | | * |
713 | | * @brief Function used to perform color space conversion from 420P to 420SP |
714 | | * |
715 | | * @par Description |
716 | | * Function used to perform color space conversion from 420P to 420SP |
717 | | * |
718 | | * @param[in] pu1_y_src |
719 | | * Input Y pointer |
720 | | * |
721 | | * @param[in] pu1_u_src |
722 | | * Input U pointer |
723 | | * |
724 | | * @param[in] pu1_v_dst |
725 | | * Input V pointer |
726 | | * |
727 | | * @param[in] pu1_y_dst |
728 | | * Output Y pointer |
729 | | * |
730 | | * @param[in] pu1_uv_dst |
731 | | * Output UV pointer |
732 | | * |
733 | | * @param[in] u4_width |
734 | | * Width |
735 | | * |
736 | | * @param[in] u4_height |
737 | | * Height |
738 | | * |
739 | | * @param[in] src_y_strd |
740 | | * Input Y Stride |
741 | | * |
742 | | * @param[in] src_u_strd |
743 | | * Input U stride |
744 | | * |
745 | | * @param[in] src_v_strd |
746 | | * Input V stride |
747 | | * |
748 | | * @param[in] dst_y_strd |
749 | | * Output Y stride |
750 | | * |
751 | | * @param[in] dst_uv_strd |
752 | | * Output UV stride |
753 | | * |
754 | | * @param[in] convert_uv_only |
755 | | * Flag to indicate if only UV copy needs to be done |
756 | | * |
757 | | * @returns none |
758 | | * |
759 | | * @remarks none |
760 | | * |
761 | | ******************************************************************************* |
762 | | */ |
763 | | void ih264e_fmt_conv_420p_to_420sp(UWORD8 *pu1_y_src, |
764 | | UWORD8 *pu1_u_src, |
765 | | UWORD8 *pu1_v_src, |
766 | | UWORD8 *pu1_y_dst, |
767 | | UWORD8 *pu1_uv_dst, |
768 | | UWORD16 u2_height, |
769 | | UWORD16 u2_width, |
770 | | UWORD16 src_y_strd, |
771 | | UWORD16 src_u_strd, |
772 | | UWORD16 src_v_strd, |
773 | | UWORD16 dst_y_strd, |
774 | | UWORD16 dst_uv_strd, |
775 | | UWORD32 convert_uv_only) |
776 | 110k | { |
777 | 110k | UWORD8 *pu1_src, *pu1_dst; |
778 | 110k | UWORD8 *pu1_src_u, *pu1_src_v; |
779 | 110k | UWORD16 i; |
780 | 110k | UWORD32 u2_width_uv; |
781 | 110k | UWORD32 dest_inc_Y = 0, dest_inc_UV = 0; |
782 | | |
783 | 110k | dest_inc_UV = dst_uv_strd; |
784 | | |
785 | 110k | if (0 == convert_uv_only) |
786 | 104k | { |
787 | | /* Copy Y buffer */ |
788 | 104k | pu1_dst = (UWORD8 *) pu1_y_dst; |
789 | 104k | pu1_src = (UWORD8 *) pu1_y_src; |
790 | | |
791 | 104k | dest_inc_Y = dst_y_strd; |
792 | | |
793 | 3.79M | for (i = 0; i < u2_height; i++) |
794 | 3.69M | { |
795 | 3.69M | memcpy((void *) pu1_dst, (void *) pu1_src, u2_width); |
796 | 3.69M | pu1_dst += dest_inc_Y; |
797 | 3.69M | pu1_src += src_y_strd; |
798 | 3.69M | } |
799 | 104k | } |
800 | | |
801 | | /* Interleave Cb and Cr buffers */ |
802 | 110k | pu1_src_u = pu1_u_src; |
803 | 110k | pu1_src_v = pu1_v_src; |
804 | 110k | pu1_dst = pu1_uv_dst; |
805 | | |
806 | 110k | u2_height = (u2_height + 1) >> 1; |
807 | 110k | u2_width_uv = (u2_width + 1) >> 1; |
808 | 2.00M | for (i = 0; i < u2_height; i++) |
809 | 1.89M | { |
810 | 1.89M | UWORD32 j; |
811 | 686M | for (j = 0; j < u2_width_uv; j++) |
812 | 684M | { |
813 | 684M | *pu1_dst++ = *pu1_src_u++; |
814 | 684M | *pu1_dst++ = *pu1_src_v++; |
815 | 684M | } |
816 | | |
817 | 1.89M | pu1_dst += dest_inc_UV - u2_width; |
818 | 1.89M | pu1_src_u += src_u_strd - u2_width_uv; |
819 | 1.89M | pu1_src_v += src_v_strd - u2_width_uv; |
820 | 1.89M | } |
821 | 110k | } |
822 | | |
823 | | /** |
824 | | ******************************************************************************* |
825 | | * |
826 | | * @brief Function used to convert 422 interleaved to 420sp |
827 | | * |
828 | | * @par Description |
829 | | * Function used to convert 422 interleaved to 420sp |
830 | | * |
831 | | * @param[in] pu1_y_buf |
832 | | * Output Y pointer |
833 | | * |
834 | | * @param[in] pu1_u_buf |
835 | | * Output u pointer |
836 | | * |
837 | | * @param[in[ pu1_v_buf |
838 | | * Output V pointer |
839 | | * |
840 | | * @param[in] pu1_422i_buf |
841 | | * Input 422i pointer |
842 | | * |
843 | | * @param[in] u4_y_width |
844 | | * Width of Y component |
845 | | * |
846 | | * @param[in] u4_y_height |
847 | | * Height of Y component |
848 | | * |
849 | | * @param[in] u4_y_stride |
850 | | * Stride of pu1_y_buf |
851 | | * |
852 | | * @param[in] u4_u_stride |
853 | | * Stride of pu1_u_buf |
854 | | * |
855 | | * @param[in] u4_v_stride |
856 | | * Stride of pu1_v_buf |
857 | | * |
858 | | * @param[in] u4_422i_stride |
859 | | * Stride of pu1_422i_buf |
860 | | * |
861 | | * @returns None |
862 | | * |
863 | | * @remarks For conversion |
864 | | * pu1_v_buf = pu1_u_buf+1 |
865 | | * u4_u_stride = u4_v_stride |
866 | | * |
867 | | * The extra parameters are for maintaining API with assembly function |
868 | | * |
869 | | ******************************************************************************* |
870 | | */ |
871 | | void ih264e_fmt_conv_422i_to_420sp(UWORD8 *pu1_y_buf, |
872 | | UWORD8 *pu1_u_buf, |
873 | | UWORD8 *pu1_v_buf, |
874 | | UWORD8 *pu1_422i_buf, |
875 | | WORD32 u4_y_width, |
876 | | WORD32 u4_y_height, |
877 | | WORD32 u4_y_stride, |
878 | | WORD32 u4_u_stride, |
879 | | WORD32 u4_v_stride, |
880 | | WORD32 u4_422i_stride) |
881 | 41.0k | { |
882 | 41.0k | WORD32 row, col; |
883 | 41.0k | UWORD8 *row_even_422 = pu1_422i_buf; |
884 | 41.0k | UWORD8 *row_odd_422 = row_even_422 + (u4_422i_stride << 1); |
885 | 41.0k | UWORD8 *row_even_luma = pu1_y_buf; |
886 | | /* Since at the end of loop, we have row_even_luma += (luma_width << 1), |
887 | | * it should be same here right? */ |
888 | 41.0k | UWORD8 *row_odd_luma = row_even_luma + u4_y_stride; |
889 | 41.0k | UWORD8 *row_cb = pu1_u_buf; |
890 | 41.0k | UWORD8 *row_cr = pu1_v_buf; |
891 | | |
892 | 367k | for (row = 0; row < u4_y_height; row = row + 2) |
893 | 326k | { |
894 | 220M | for (col = 0; col < (u4_y_width << 1); col = col + 4) |
895 | 220M | { |
896 | 220M | UWORD8 cb_even = row_even_422[col]; |
897 | 220M | UWORD8 cr_even = row_even_422[col + 2]; |
898 | | |
899 | 220M | row_cb[col >> 1] = cb_even; |
900 | 220M | row_cr[col >> 1] = cr_even; |
901 | | |
902 | 220M | row_even_luma[col >> 1] = row_even_422[col + 1]; |
903 | 220M | row_even_luma[(col >> 1) + 1] = row_even_422[col + 3]; |
904 | | |
905 | 220M | row_odd_luma[col >> 1] = row_odd_422[col + 1]; |
906 | 220M | row_odd_luma[(col >> 1) + 1] = row_odd_422[col + 3]; |
907 | 220M | } |
908 | | |
909 | 326k | row_even_422 += (u4_422i_stride << 2); |
910 | 326k | row_odd_422 += (u4_422i_stride << 2); |
911 | | |
912 | 326k | row_even_luma += (u4_y_stride << 1); |
913 | 326k | row_odd_luma += (u4_y_stride << 1); |
914 | | |
915 | 326k | row_cb += u4_u_stride; |
916 | 326k | row_cr += u4_v_stride; |
917 | 326k | } |
918 | 41.0k | } |
919 | | |
920 | | /** |
921 | | ******************************************************************************* |
922 | | * |
923 | | * @brief Function used for format conversion or frame copy |
924 | | * |
925 | | * @par Description |
926 | | * Function used from copying or converting a reference frame to display buffer |
927 | | * in non shared mode |
928 | | * |
929 | | * @param[in] ps_codec |
930 | | * Codec ctxt |
931 | | * |
932 | | * @param[in] ps_pic |
933 | | * Reference pic ctxt |
934 | | * |
935 | | * @param[in] pu1_y_dst |
936 | | * Output Y pointer |
937 | | * |
938 | | * @param[in] pu1_u_dst |
939 | | * Output U/UV pointer ( UV is interleaved in the same format as that of input) |
940 | | * |
941 | | * @param[in] pu1_v_dst |
942 | | * Output V pointer ( used in 420P output case) |
943 | | * |
944 | | * @param[in] u4_dst_y_strd |
945 | | * Stride of destination Y buffer |
946 | | * |
947 | | * @param[in] u4_dst_u_strd |
948 | | * Stride of destination U/V buffer |
949 | | * |
950 | | * @param[in] cur_row |
951 | | * Start row of fmt conversion |
952 | | * |
953 | | * @param[in] num_rows |
954 | | * number of rows to process |
955 | | * |
956 | | * @returns error status |
957 | | * |
958 | | * @remarks Assumes that the stride of U and V buffers are same. |
959 | | * |
960 | | ******************************************************************************* |
961 | | */ |
962 | | IH264E_ERROR_T ih264e_fmt_conv(codec_t *ps_codec, |
963 | | pic_buf_t *ps_pic, |
964 | | UWORD8 *pu1_y_dst, |
965 | | UWORD8 *pu1_u_dst, |
966 | | UWORD8 *pu1_v_dst, |
967 | | UWORD32 u4_dst_y_strd, |
968 | | UWORD32 u4_dst_uv_strd, |
969 | | WORD32 cur_row, |
970 | | WORD32 num_rows) |
971 | 0 | { |
972 | 0 | IH264E_ERROR_T ret = IH264E_SUCCESS; |
973 | 0 | UWORD8 *pu1_y_src, *pu1_uv_src; |
974 | 0 | UWORD8 *pu1_y_dst_tmp, *pu1_uv_dst_tmp; |
975 | 0 | UWORD8 *pu1_u_dst_tmp, *pu1_v_dst_tmp; |
976 | 0 | UWORD16 *pu2_rgb_dst_tmp; |
977 | 0 | UWORD32 *pu4_rgb_dst_tmp; |
978 | 0 | WORD32 is_u_first; |
979 | 0 | UWORD8 *pu1_luma; |
980 | 0 | UWORD8 *pu1_chroma; |
981 | 0 | WORD32 dst_stride, wd; |
982 | |
|
983 | 0 | if (0 == num_rows) |
984 | 0 | return ret; |
985 | | |
986 | 0 | pu1_luma = ps_pic->pu1_luma; |
987 | 0 | pu1_chroma = ps_pic->pu1_chroma; |
988 | |
|
989 | 0 | dst_stride = ps_codec->s_cfg.u4_wd; |
990 | 0 | wd = ps_codec->s_cfg.u4_disp_wd; |
991 | 0 | is_u_first = (IV_YUV_420SP_UV == ps_codec->e_codec_color_format) ? 1 : 0; |
992 | | |
993 | | /* In case of 420P output luma copy is disabled for shared mode */ |
994 | 0 | { |
995 | 0 | pu1_y_src = pu1_luma + cur_row * ps_codec->i4_rec_strd; |
996 | 0 | pu1_uv_src = pu1_chroma + (cur_row / 2) * ps_codec->i4_rec_strd; |
997 | |
|
998 | 0 | pu2_rgb_dst_tmp = (UWORD16 *) pu1_y_dst; |
999 | 0 | pu2_rgb_dst_tmp += cur_row * dst_stride; |
1000 | 0 | pu4_rgb_dst_tmp = (UWORD32 *) pu1_y_dst; |
1001 | 0 | pu4_rgb_dst_tmp += cur_row * dst_stride; |
1002 | |
|
1003 | 0 | pu1_y_dst_tmp = pu1_y_dst + cur_row * u4_dst_y_strd; |
1004 | 0 | pu1_uv_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd; |
1005 | 0 | pu1_u_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd; |
1006 | 0 | pu1_v_dst_tmp = pu1_v_dst + (cur_row / 2) * u4_dst_uv_strd; |
1007 | | |
1008 | | /* If the call is non-blocking and there are no rows to be copied then return */ |
1009 | | /* In non-shared mode, reference buffers are in 420SP UV format, |
1010 | | * if output also is in 420SP_UV, then just copy |
1011 | | * if output is in 420SP_VU then swap UV values |
1012 | | */ |
1013 | 0 | if ((IV_YUV_420SP_UV == ps_codec->s_cfg.e_recon_color_fmt) || |
1014 | 0 | (IV_YUV_420SP_VU == ps_codec->s_cfg.e_recon_color_fmt)) |
1015 | 0 | { |
1016 | 0 | ih264e_fmt_conv_420sp_to_420sp(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp, |
1017 | 0 | pu1_uv_dst_tmp, wd, num_rows, |
1018 | 0 | ps_codec->i4_rec_strd, |
1019 | 0 | ps_codec->i4_rec_strd, u4_dst_y_strd, |
1020 | 0 | u4_dst_uv_strd); |
1021 | 0 | } |
1022 | 0 | else if (IV_YUV_420P == ps_codec->s_cfg.e_recon_color_fmt) |
1023 | 0 | { |
1024 | 0 | ih264e_fmt_conv_420sp_to_420p(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp, |
1025 | 0 | pu1_u_dst_tmp, pu1_v_dst_tmp, wd, |
1026 | 0 | num_rows, ps_codec->i4_rec_strd, |
1027 | 0 | ps_codec->i4_rec_strd, u4_dst_y_strd, |
1028 | 0 | u4_dst_uv_strd, is_u_first, 0); |
1029 | 0 | } |
1030 | 0 | } |
1031 | 0 | return(ret); |
1032 | 0 | } |
1033 | | |