blob: e06aea1b37e6d840c0f13a3cc98c64826eeb357c [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
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 "ih264e.h"
64#include "ithread.h"
65#include "ih264_defs.h"
66#include "ih264_debug.h"
67#include "ime_distortion_metrics.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053068#include "ime_defs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053069#include "ime_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053070#include "ih264_error.h"
71#include "ih264_structs.h"
72#include "ih264_trans_quant_itrans_iquant.h"
73#include "ih264_inter_pred_filters.h"
74#include "ih264_mem_fns.h"
75#include "ih264_padding.h"
76#include "ih264_intra_pred_filters.h"
77#include "ih264_deblk_edge_filters.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053078#include "ih264_cabac_tables.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053079#include "ih264_macros.h"
80#include "ih264_platform_macros.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053081#include "ih264_buf_mgr.h"
82#include "ih264e_defs.h"
83#include "ih264e_error.h"
84#include "ih264e_bitstream.h"
85#include "irc_cntrl_param.h"
86#include "irc_frame_info_collector.h"
87#include "ih264e_rate_control.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053088#include "ih264e_cabac_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053089#include "ih264e_structs.h"
90#include "ih264e_fmt_conv.h"
91
92
93/*****************************************************************************/
94/* Function Definitions */
95/*****************************************************************************/
96
97void ih264e_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src,
98 UWORD8 *pu1_uv_src,
99 UWORD16 *pu2_rgb_dst,
100 WORD32 wd,
101 WORD32 ht,
102 WORD32 src_y_strd,
103 WORD32 src_uv_strd,
104 WORD32 dst_strd,
105 WORD32 is_u_first)
106{
107 WORD16 i2_r, i2_g, i2_b;
108 UWORD32 u4_r, u4_g, u4_b;
109 WORD16 i2_i, i2_j;
110 UWORD8 *pu1_y_src_nxt;
111 UWORD16 *pu2_rgb_dst_NextRow;
112
113 UWORD8 *pu1_u_src, *pu1_v_src;
114
115 if (is_u_first)
116 {
117 pu1_u_src = (UWORD8 *) pu1_uv_src;
118 pu1_v_src = (UWORD8 *) pu1_uv_src + 1;
119 }
120 else
121 {
122 pu1_u_src = (UWORD8 *) pu1_uv_src + 1;
123 pu1_v_src = (UWORD8 *) pu1_uv_src;
124 }
125
126 pu1_y_src_nxt = pu1_y_src + src_y_strd;
127 pu2_rgb_dst_NextRow = pu2_rgb_dst + dst_strd;
128
129 for (i2_i = 0; i2_i < (ht >> 1); i2_i++)
130 {
131 for (i2_j = (wd >> 1); i2_j > 0; i2_j--)
132 {
133 i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13);
134 i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3)
135 >> 13;
136 i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13;
137
138 pu1_u_src += 2;
139 pu1_v_src += 2;
140 /* pixel 0 */
141 /* B */
142 u4_b = CLIP_U8(*pu1_y_src + i2_b);
143 u4_b >>= 3;
144 /* G */
145 u4_g = CLIP_U8(*pu1_y_src + i2_g);
146 u4_g >>= 2;
147 /* R */
148 u4_r = CLIP_U8(*pu1_y_src + i2_r);
149 u4_r >>= 3;
150
151 pu1_y_src++;
152 *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
153
154 /* pixel 1 */
155 /* B */
156 u4_b = CLIP_U8(*pu1_y_src + i2_b);
157 u4_b >>= 3;
158 /* G */
159 u4_g = CLIP_U8(*pu1_y_src + i2_g);
160 u4_g >>= 2;
161 /* R */
162 u4_r = CLIP_U8(*pu1_y_src + i2_r);
163 u4_r >>= 3;
164
165 pu1_y_src++;
166 *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
167
168 /* pixel 2 */
169 /* B */
170 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
171 u4_b >>= 3;
172 /* G */
173 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
174 u4_g >>= 2;
175 /* R */
176 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
177 u4_r >>= 3;
178
179 pu1_y_src_nxt++;
180 *pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
181
182 /* pixel 3 */
183 /* B */
184 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
185 u4_b >>= 3;
186 /* G */
187 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
188 u4_g >>= 2;
189 /* R */
190 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
191 u4_r >>= 3;
192
193 pu1_y_src_nxt++;
194 *pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
195
196 }
197
198 pu1_u_src = pu1_u_src + src_uv_strd - wd;
199 pu1_v_src = pu1_v_src + src_uv_strd - wd;
200
201 pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd;
202 pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd;
203
204 pu2_rgb_dst = pu2_rgb_dst_NextRow - wd + dst_strd;
205 pu2_rgb_dst_NextRow = pu2_rgb_dst_NextRow + (dst_strd << 1) - wd;
206 }
207
208}
209
210void ih264e_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src,
211 UWORD8 *pu1_uv_src,
212 UWORD32 *pu4_rgba_dst,
213 WORD32 wd,
214 WORD32 ht,
215 WORD32 src_y_strd,
216 WORD32 src_uv_strd,
217 WORD32 dst_strd,
218 WORD32 is_u_first)
219{
220 WORD16 i2_r, i2_g, i2_b;
221 UWORD32 u4_r, u4_g, u4_b;
222 WORD16 i2_i, i2_j;
223 UWORD8 *pu1_y_src_nxt;
224 UWORD32 *pu4_rgba_dst_NextRow;
225 UWORD8 *pu1_u_src, *pu1_v_src;
226
227 if (is_u_first)
228 {
229 pu1_u_src = (UWORD8 *) pu1_uv_src;
230 pu1_v_src = (UWORD8 *) pu1_uv_src + 1;
231 }
232 else
233 {
234 pu1_u_src = (UWORD8 *) pu1_uv_src + 1;
235 pu1_v_src = (UWORD8 *) pu1_uv_src;
236 }
237
238 pu1_y_src_nxt = pu1_y_src + src_y_strd;
239
240 pu4_rgba_dst_NextRow = pu4_rgba_dst + dst_strd;
241
242 for (i2_i = 0; i2_i < (ht >> 1); i2_i++)
243 {
244 for (i2_j = (wd >> 1); i2_j > 0; i2_j--)
245 {
246 i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13);
247 i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3)
248 >> 13;
249 i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13;
250
251 pu1_u_src += 2;
252 pu1_v_src += 2;
253 /* pixel 0 */
254 /* B */
255 u4_b = CLIP_U8(*pu1_y_src + i2_b);
256 /* G */
257 u4_g = CLIP_U8(*pu1_y_src + i2_g);
258 /* R */
259 u4_r = CLIP_U8(*pu1_y_src + i2_r);
260
261 pu1_y_src++;
262 *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
263
264 /* pixel 1 */
265 /* B */
266 u4_b = CLIP_U8(*pu1_y_src + i2_b);
267 /* G */
268 u4_g = CLIP_U8(*pu1_y_src + i2_g);
269 /* R */
270 u4_r = CLIP_U8(*pu1_y_src + i2_r);
271
272 pu1_y_src++;
273 *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
274
275 /* pixel 2 */
276 /* B */
277 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
278 /* G */
279 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
280 /* R */
281 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
282
283 pu1_y_src_nxt++;
284 *pu4_rgba_dst_NextRow++ =
285 ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
286
287 /* pixel 3 */
288 /* B */
289 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
290 /* G */
291 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
292 /* R */
293 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
294
295 pu1_y_src_nxt++;
296 *pu4_rgba_dst_NextRow++ =
297 ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
298
299 }
300
301 pu1_u_src = pu1_u_src + src_uv_strd - wd;
302 pu1_v_src = pu1_v_src + src_uv_strd - wd;
303
304 pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd;
305 pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd;
306
307 pu4_rgba_dst = pu4_rgba_dst_NextRow - wd + dst_strd;
308 pu4_rgba_dst_NextRow = pu4_rgba_dst_NextRow + (dst_strd << 1) - wd;
309 }
310
311}
312
313/**
314*******************************************************************************
315*
316* @brief Function used for copying a 420SP buffer
317*
318* @par Description
319* Function used for copying a 420SP buffer
320*
321* @param[in] pu1_y_src
322* Input Y pointer
323*
324* @param[in] pu1_uv_src
325* Input UV pointer (UV is interleaved either in UV or VU format)
326*
327* @param[in] pu1_y_dst
328* Output Y pointer
329*
330* @param[in] pu1_uv_dst
331* Output UV pointer (UV is interleaved in the same format as that of input)
332*
333* @param[in] wd
334* Width
335*
336* @param[in] ht
337* Height
338*
339* @param[in] src_y_strd
340* Input Y Stride
341*
342* @param[in] src_uv_strd
343* Input UV stride
344*
345* @param[in] dst_y_strd
346* Output Y stride
347*
348* @param[in] dst_uv_strd
349* Output UV stride
350*
351* @returns None
352*
353* @remarks In case there is a need to perform partial frame copy then
354* by passion appropriate source and destination pointers and appropriate
355* values for wd and ht it can be done
356*
357*******************************************************************************
358*/
359void ih264e_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src,
360 UWORD8 *pu1_uv_src,
361 UWORD8 *pu1_y_dst,
362 UWORD8 *pu1_uv_dst,
363 WORD32 wd,
364 WORD32 ht,
365 WORD32 src_y_strd,
366 WORD32 src_uv_strd,
367 WORD32 dst_y_strd,
368 WORD32 dst_uv_strd)
369{
370 UWORD8 *pu1_src, *pu1_dst;
371 WORD32 num_rows, num_cols, src_strd, dst_strd;
372 WORD32 i;
373
374 /* copy luma */
375 pu1_src = (UWORD8 *) pu1_y_src;
376 pu1_dst = (UWORD8 *) pu1_y_dst;
377
378 num_rows = ht;
379 num_cols = wd;
380
381 src_strd = src_y_strd;
382 dst_strd = dst_y_strd;
383
384 for (i = 0; i < num_rows; i++)
385 {
386 memcpy(pu1_dst, pu1_src, num_cols);
387 pu1_dst += dst_strd;
388 pu1_src += src_strd;
389 }
390
391 /* copy U and V */
392 pu1_src = (UWORD8 *) pu1_uv_src;
393 pu1_dst = (UWORD8 *) pu1_uv_dst;
394
395 num_rows = ht >> 1;
396 num_cols = wd;
397
398 src_strd = src_uv_strd;
399 dst_strd = dst_uv_strd;
400
401 for (i = 0; i < num_rows; i++)
402 {
403 memcpy(pu1_dst, pu1_src, num_cols);
404 pu1_dst += dst_strd;
405 pu1_src += src_strd;
406 }
407 return;
408}
409
410
411void ih264e_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src,
412 UWORD8 *pu1_uv_src,
413 UWORD8 *pu1_y_dst,
414 UWORD8 *pu1_uv_dst,
415 WORD32 wd,
416 WORD32 ht,
417 WORD32 src_y_strd,
418 WORD32 src_uv_strd,
419 WORD32 dst_y_strd,
420 WORD32 dst_uv_strd)
421{
422 UWORD8 *pu1_src, *pu1_dst;
423 WORD32 num_rows, num_cols, src_strd, dst_strd;
424 WORD32 i;
425
426 /* copy luma */
427 pu1_src = (UWORD8 *) pu1_y_src;
428 pu1_dst = (UWORD8 *) pu1_y_dst;
429
430 num_rows = ht;
431 num_cols = wd;
432
433 src_strd = src_y_strd;
434 dst_strd = dst_y_strd;
435
436 for (i = 0; i < num_rows; i++)
437 {
438 memcpy(pu1_dst, pu1_src, num_cols);
439 pu1_dst += dst_strd;
440 pu1_src += src_strd;
441 }
442
443 /* copy U and V */
444 pu1_src = (UWORD8 *) pu1_uv_src;
445 pu1_dst = (UWORD8 *) pu1_uv_dst;
446
447 num_rows = ht >> 1;
448 num_cols = wd;
449
450 src_strd = src_uv_strd;
451 dst_strd = dst_uv_strd;
452
453 for (i = 0; i < num_rows; i++)
454 {
455 WORD32 j;
456 for (j = 0; j < num_cols; j += 2)
457 {
458 pu1_dst[j + 0] = pu1_src[j + 1];
459 pu1_dst[j + 1] = pu1_src[j + 0];
460 }
461 pu1_dst += dst_strd;
462 pu1_src += src_strd;
463 }
464 return;
465}
466
467void ih264e_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src,
468 UWORD8 *pu1_uv_src,
469 UWORD8 *pu1_y_dst,
470 UWORD8 *pu1_u_dst,
471 UWORD8 *pu1_v_dst,
472 WORD32 wd,
473 WORD32 ht,
474 WORD32 src_y_strd,
475 WORD32 src_uv_strd,
476 WORD32 dst_y_strd,
477 WORD32 dst_uv_strd,
478 WORD32 is_u_first,
479 WORD32 disable_luma_copy)
480{
481 UWORD8 *pu1_src, *pu1_dst;
482 UWORD8 *pu1_u_src, *pu1_v_src;
483 WORD32 num_rows, num_cols, src_strd, dst_strd;
484 WORD32 i, j;
485
486 if (0 == disable_luma_copy)
487 {
488 /* copy luma */
489 pu1_src = (UWORD8 *) pu1_y_src;
490 pu1_dst = (UWORD8 *) pu1_y_dst;
491
492 num_rows = ht;
493 num_cols = wd;
494
495 src_strd = src_y_strd;
496 dst_strd = dst_y_strd;
497
498 for (i = 0; i < num_rows; i++)
499 {
500 memcpy(pu1_dst, pu1_src, num_cols);
501 pu1_dst += dst_strd;
502 pu1_src += src_strd;
503 }
504 }
505 /* de-interleave U and V and copy to destination */
506 if (is_u_first)
507 {
508 pu1_u_src = (UWORD8 *) pu1_uv_src;
509 pu1_v_src = (UWORD8 *) pu1_uv_src + 1;
510 }
511 else
512 {
513 pu1_u_src = (UWORD8 *) pu1_uv_src + 1;
514 pu1_v_src = (UWORD8 *) pu1_uv_src;
515 }
516
517 num_rows = ht >> 1;
518 num_cols = wd >> 1;
519
520 src_strd = src_uv_strd;
521 dst_strd = dst_uv_strd;
522
523 for (i = 0; i < num_rows; i++)
524 {
525 for (j = 0; j < num_cols; j++)
526 {
527 pu1_u_dst[j] = pu1_u_src[j * 2];
528 pu1_v_dst[j] = pu1_v_src[j * 2];
529 }
530
531 pu1_u_dst += dst_strd;
532 pu1_v_dst += dst_strd;
533 pu1_u_src += src_strd;
534 pu1_v_src += src_strd;
535 }
536 return;
537}
538
539/**
540*******************************************************************************
541*
542* @brief Function used to perform color space conversion from 420P to 420SP
543*
544* @par Description
545* Function used to perform color space conversion from 420P to 420SP
546*
547* @param[in] pu1_y_src
548* Input Y pointer
549*
550* @param[in] pu1_u_src
551* Input U pointer
552*
553* @param[in] pu1_v_dst
554* Input V pointer
555*
556* @param[in] pu1_y_dst
557* Output Y pointer
558*
559* @param[in] pu1_uv_dst
560* Output UV pointer
561*
562* @param[in] u4_width
563* Width
564*
565* @param[in] u4_height
566* Height
567*
568* @param[in] src_y_strd
569* Input Y Stride
570*
571* @param[in] src_u_strd
572* Input U stride
573*
574* @param[in] src_v_strd
575* Input V stride
576*
577* @param[in] dst_y_strd
578* Output Y stride
579*
580* @param[in] dst_uv_strd
581* Output UV stride
582*
583* @param[in] convert_uv_only
584* Flag to indicate if only UV copy needs to be done
585*
586* @returns none
587*
588* @remarks In case there is a need to perform partial frame copy then
589* by passion appropriate source and destination pointers and appropriate
590* values for wd and ht it can be done
591*
592*******************************************************************************
593*/
594void ih264e_fmt_conv_420p_to_420sp(UWORD8 *pu1_y_src,
595 UWORD8 *pu1_u_src,
596 UWORD8 *pu1_v_src,
597 UWORD8 *pu1_y_dst,
598 UWORD8 *pu1_uv_dst,
599 UWORD16 u2_height,
600 UWORD16 u2_width,
601 UWORD16 src_y_strd,
602 UWORD16 src_u_strd,
603 UWORD16 src_v_strd,
604 UWORD16 dst_y_strd,
605 UWORD16 dst_uv_strd,
606 UWORD32 convert_uv_only)
607{
608 UWORD8 *pu1_src, *pu1_dst;
609 UWORD8 *pu1_src_u, *pu1_src_v;
610 UWORD16 i;
611 UWORD32 u2_width_uv;
612 UWORD32 dest_inc_Y = 0, dest_inc_UV = 0;
613
614 dest_inc_UV = dst_uv_strd;
615
616 if (0 == convert_uv_only)
617 {
618
619 /* Copy Y buffer */
620 pu1_dst = (UWORD8 *) pu1_y_dst;
621 pu1_src = (UWORD8 *) pu1_y_src;
622
623 dest_inc_Y = dst_y_strd;
624
625 for (i = 0; i < u2_height; i++)
626 {
627 memcpy((void *) pu1_dst, (void *) pu1_src, u2_width);
628 pu1_dst += dest_inc_Y;
629 pu1_src += src_y_strd;
630 }
631 }
632
633 /* Interleave Cb and Cr buffers */
634 pu1_src_u = pu1_u_src;
635 pu1_src_v = pu1_v_src;
636 pu1_dst = pu1_uv_dst;
637
638 u2_height = (u2_height + 1) >> 1;
639 u2_width_uv = (u2_width + 1) >> 1;
640 for (i = 0; i < u2_height; i++)
641 {
642 UWORD32 j;
643 for (j = 0; j < u2_width_uv; j++)
644 {
645 *pu1_dst++ = *pu1_src_u++;
646 *pu1_dst++ = *pu1_src_v++;
647 }
648
649 pu1_dst += dest_inc_UV - u2_width;
650 pu1_src_u += src_u_strd - u2_width_uv;
651 pu1_src_v += src_v_strd - u2_width_uv;
652 }
653}
654
655/**
656*******************************************************************************
657*
658* @brief Function used to convert 422 interleaved to 420sp
659*
660* @par Description
661* Function used to convert 422 interleaved to 420sp
662*
663* @param[in] pu1_y_buf
664* Output Y pointer
665*
666* @param[in] pu1_u_buf
667* Output u pointer
668*
669* @param[in[ pu1_v_buf
670* Output V pointer
671*
672* @param[in] pu1_422i_buf
673* Input 422i pointer
674*
675* @param[in] u4_y_width
676* Width of Y component
677*
678* @param[in] u4_y_height
679* Height of Y component
680*
681* @param[in] u4_y_stride
682* Stride of pu1_y_buf
683*
684* @param[in] u4_u_stride
685* Stride of pu1_u_buf
686*
687* @param[in] u4_v_stride
688* Stride of pu1_v_buf
689*
690* @param[in] u4_422i_stride
691* Stride of pu1_422i_buf
692*
693* @returns None
694*
695* @remarks For conversion
696* pu1_v_buf = pu1_u_buf+1
697* u4_u_stride = u4_v_stride
698*
699* The extra parameters are for maintaining API with assembly function
700*
701*******************************************************************************
702*/
703void ih264e_fmt_conv_422i_to_420sp(UWORD8 *pu1_y_buf,
704 UWORD8 *pu1_u_buf,
705 UWORD8 *pu1_v_buf,
706 UWORD8 *pu1_422i_buf,
707 WORD32 u4_y_width,
708 WORD32 u4_y_height,
709 WORD32 u4_y_stride,
710 WORD32 u4_u_stride,
711 WORD32 u4_v_stride,
712 WORD32 u4_422i_stride)
713{
714 WORD32 row, col;
715 UWORD8 *row_even_422 = pu1_422i_buf;
716 UWORD8 *row_odd_422 = row_even_422 + (u4_422i_stride << 1);
717 UWORD8 *row_even_luma = pu1_y_buf;
718 /* Since at the end of loop, we have row_even_luma += (luma_width << 1),
719 * it should be same here right? */
720 UWORD8 *row_odd_luma = row_even_luma + u4_y_stride;
721 UWORD8 *row_cb = pu1_u_buf;
722 UWORD8 *row_cr = pu1_v_buf;
723
724 for (row = 0; row < u4_y_height; row = row + 2)
725 {
726 for (col = 0; col < (u4_y_width << 1); col = col + 4)
727 {
728 UWORD8 cb_even = row_even_422[col];
729 UWORD8 cr_even = row_even_422[col + 2];
730
731 row_cb[col >> 1] = cb_even;
732 row_cr[col >> 1] = cr_even;
733
734 row_even_luma[col >> 1] = row_even_422[col + 1];
735 row_even_luma[(col >> 1) + 1] = row_even_422[col + 3];
736
737 row_odd_luma[col >> 1] = row_odd_422[col + 1];
738 row_odd_luma[(col >> 1) + 1] = row_odd_422[col + 3];
739 }
740
741 row_even_422 += (u4_422i_stride << 2);
742 row_odd_422 += (u4_422i_stride << 2);
743
744 row_even_luma += (u4_y_stride << 1);
745 row_odd_luma += (u4_y_stride << 1);
746
747 row_cb += u4_u_stride;
748 row_cr += u4_v_stride;
749 }
750}
751
752/**
753*******************************************************************************
754*
755* @brief Function used from format conversion or frame copy
756*
757* @par Description
758* Function used from copying or converting a reference frame to display buffer
759* in non shared mode
760*
761* @param[in] pu1_y_dst
762* Output Y pointer
763*
764* @param[in] pu1_u_dst
765* Output U/UV pointer ( UV is interleaved in the same format as that of input)
766*
767* @param[in] pu1_v_dst
768* Output V pointer ( used in 420P output case)
769*
770* @param[in] u4_dst_y_strd
771* Stride of destination Y buffer
772*
773* @param[in] u4_dst_u_strd
774* Stride of destination U/V buffer
775*
776* @param[in] blocking
777* To indicate whether format conversion should wait till frame is reconstructed
778* and then return after complete copy is done. To be set to 1 when called at the
779* end of frame processing and set to 0 when called between frame processing modules
780* in order to utilize available MCPS
781*
782* @returns error status
783*
784* @remarks
785* Assumes that the stride of U and V buffers are same.
786* This is correct in most cases
787* If a case comes where this is not true we need to modify the fmt conversion
788* functions called inside also
789*
790*******************************************************************************
791*/
792IH264E_ERROR_T ih264e_fmt_conv(codec_t *ps_codec,
793 pic_buf_t *ps_pic,
794 UWORD8 *pu1_y_dst,
795 UWORD8 *pu1_u_dst,
796 UWORD8 *pu1_v_dst,
797 UWORD32 u4_dst_y_strd,
798 UWORD32 u4_dst_uv_strd,
799 WORD32 cur_row,
800 WORD32 num_rows)
801{
802 IH264E_ERROR_T ret = IH264E_SUCCESS;
803 UWORD8 *pu1_y_src, *pu1_uv_src;
804 UWORD8 *pu1_y_dst_tmp, *pu1_uv_dst_tmp;
805 UWORD8 *pu1_u_dst_tmp, *pu1_v_dst_tmp;
806 UWORD16 *pu2_rgb_dst_tmp;
807 UWORD32 *pu4_rgb_dst_tmp;
808 WORD32 is_u_first;
809 UWORD8 *pu1_luma;
810 UWORD8 *pu1_chroma;
811 WORD32 dst_stride, wd;
812
813
814 if (0 == num_rows)
815 return ret;
816
817 pu1_luma = ps_pic->pu1_luma;
818 pu1_chroma = ps_pic->pu1_chroma;
819
820
821 dst_stride = ps_codec->s_cfg.u4_wd;
822 wd = ps_codec->s_cfg.u4_disp_wd;
823 is_u_first = (IV_YUV_420SP_UV == ps_codec->e_codec_color_format) ? 1 : 0;
824
825 /* In case of 420P output luma copy is disabled for shared mode */
826 {
827 pu1_y_src = pu1_luma + cur_row * ps_codec->i4_rec_strd;
828 pu1_uv_src = pu1_chroma + (cur_row / 2) * ps_codec->i4_rec_strd;
829
830 pu2_rgb_dst_tmp = (UWORD16 *) pu1_y_dst;
831 pu2_rgb_dst_tmp += cur_row * dst_stride;
832 pu4_rgb_dst_tmp = (UWORD32 *) pu1_y_dst;
833 pu4_rgb_dst_tmp += cur_row * dst_stride;
834
835 pu1_y_dst_tmp = pu1_y_dst + cur_row * u4_dst_y_strd;
836 pu1_uv_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd;
837 pu1_u_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd;
838 pu1_v_dst_tmp = pu1_v_dst + (cur_row / 2) * u4_dst_uv_strd;
839
840 /* If the call is non-blocking and there are no rows to be copied then return */
841 /* In non-shared mode, reference buffers are in 420SP UV format,
842 * if output also is in 420SP_UV, then just copy
843 * if output is in 420SP_VU then swap UV values
844 */
845 if ((IV_YUV_420SP_UV == ps_codec->s_cfg.e_recon_color_fmt) ||
846 (IV_YUV_420SP_VU == ps_codec->s_cfg.e_recon_color_fmt))
847 {
848 ih264e_fmt_conv_420sp_to_420sp(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp,
849 pu1_uv_dst_tmp, wd, num_rows,
850 ps_codec->i4_rec_strd,
851 ps_codec->i4_rec_strd, u4_dst_y_strd,
852 u4_dst_uv_strd);
853 }
854 else if (IV_YUV_420P == ps_codec->s_cfg.e_recon_color_fmt)
855 {
856 ih264e_fmt_conv_420sp_to_420p(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp,
857 pu1_u_dst_tmp, pu1_v_dst_tmp, wd,
858 num_rows, ps_codec->i4_rec_strd,
859 ps_codec->i4_rec_strd, u4_dst_y_strd,
860 u4_dst_uv_strd, is_u_first, 0);
861 }
862 }
863 return(ret);
864}
865