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 /* File Name : ih264d_format_conv.c */
23 /* */
24 /* Description : Contains functions needed to convert the images in */
25 /* different color spaces to yuv 422i color space */
26 /* */
27 /* */
28 /* Issues / Problems : None */
29 /* */
30 /* Revision History : */
31 /* */
32 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
33 /* 28 08 2007 Naveen Kumar T Draft */
34 /* */
35 /*****************************************************************************/
36 /*****************************************************************************/
37 /* File Includes */
38 /*****************************************************************************/
39
40 /* System include files */
41 #include <string.h>
42 /* User include files */
43 #include "ih264_typedefs.h"
44 #include "iv.h"
45 #include "ih264_macros.h"
46 #include "ih264_platform_macros.h"
47 #include "ih264d_structs.h"
48 #include "ih264d_format_conv.h"
49 #include "ih264d_defs.h"
50
51
52
53 #ifdef LOGO_EN
54 #include "ih264d_ittiam_logo.h"
55 #define INSERT_LOGO(pu1_buf_y,pu1_buf_u,pu1_buf_v, u4_stride, u4_x_pos, u4_y_pos, u4_yuv_fmt, u4_disp_wd, u4_disp_ht) \
56 ih264d_insert_logo(pu1_buf_y,pu1_buf_u,pu1_buf_v, u4_stride,\
57 u4_x_pos, u4_y_pos, u4_yuv_fmt, u4_disp_wd, u4_disp_ht)
58 #else
59 #define INSERT_LOGO(pu1_buf_y,pu1_buf_u,pu1_buf_v, u4_stride, u4_x_pos, u4_y_pos, u4_yuv_fmt, u4_disp_wd, u4_disp_ht)
60 #endif
61
62 /**
63 *******************************************************************************
64 *
65 * @brief Function used from copying a 420SP buffer
66 *
67 * @par Description
68 * Function used from copying a 420SP buffer
69 *
70 * @param[in] pu1_y_src
71 * Input Y pointer
72 *
73 * @param[in] pu1_uv_src
74 * Input UV pointer (UV is interleaved either in UV or VU format)
75 *
76 * @param[in] pu1_y_dst
77 * Output Y pointer
78 *
79 * @param[in] pu1_uv_dst
80 * Output UV pointer (UV is interleaved in the same format as that of input)
81 *
82 * @param[in] wd
83 * Width
84 *
85 * @param[in] ht
86 * Height
87 *
88 * @param[in] src_y_strd
89 * Input Y Stride
90 *
91 * @param[in] src_uv_strd
92 * Input UV stride
93 *
94 * @param[in] dst_y_strd
95 * Output Y stride
96 *
97 * @param[in] dst_uv_strd
98 * Output UV stride
99 *
100 * @returns None
101 *
102 * @remarks In case there is a need to perform partial frame copy then
103 * by passion appropriate source and destination pointers and appropriate
104 * values for wd and ht it can be done
105 *
106 *******************************************************************************
107 */
ih264d_fmt_conv_420sp_to_rgb565(UWORD8 * pu1_y_src,UWORD8 * pu1_uv_src,UWORD16 * pu2_rgb_dst,WORD32 wd,WORD32 ht,WORD32 src_y_strd,WORD32 src_uv_strd,WORD32 dst_strd,WORD32 is_u_first)108 void ih264d_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src,
109 UWORD8 *pu1_uv_src,
110 UWORD16 *pu2_rgb_dst,
111 WORD32 wd,
112 WORD32 ht,
113 WORD32 src_y_strd,
114 WORD32 src_uv_strd,
115 WORD32 dst_strd,
116 WORD32 is_u_first)
117 {
118
119 WORD16 i2_r, i2_g, i2_b;
120 UWORD32 u4_r, u4_g, u4_b;
121 WORD16 i2_i, i2_j;
122 UWORD8 *pu1_y_src_nxt;
123 UWORD16 *pu2_rgb_dst_next_row;
124
125 UWORD8 *pu1_u_src, *pu1_v_src;
126
127 if(is_u_first)
128 {
129 pu1_u_src = (UWORD8 *)pu1_uv_src;
130 pu1_v_src = (UWORD8 *)pu1_uv_src + 1;
131 }
132 else
133 {
134 pu1_u_src = (UWORD8 *)pu1_uv_src + 1;
135 pu1_v_src = (UWORD8 *)pu1_uv_src;
136 }
137
138 pu1_y_src_nxt = pu1_y_src + src_y_strd;
139 pu2_rgb_dst_next_row = pu2_rgb_dst + dst_strd;
140
141 for(i2_i = 0; i2_i < (ht >> 1); i2_i++)
142 {
143 for(i2_j = (wd >> 1); i2_j > 0; i2_j--)
144 {
145 i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13);
146 i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3)
147 >> 13;
148 i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13;
149
150 pu1_u_src += 2;
151 pu1_v_src += 2;
152 /* pixel 0 */
153 /* B */
154 u4_b = CLIP_U8(*pu1_y_src + i2_b);
155 u4_b >>= 3;
156 /* G */
157 u4_g = CLIP_U8(*pu1_y_src + i2_g);
158 u4_g >>= 2;
159 /* R */
160 u4_r = CLIP_U8(*pu1_y_src + i2_r);
161 u4_r >>= 3;
162
163 pu1_y_src++;
164 *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
165
166 /* pixel 1 */
167 /* B */
168 u4_b = CLIP_U8(*pu1_y_src + i2_b);
169 u4_b >>= 3;
170 /* G */
171 u4_g = CLIP_U8(*pu1_y_src + i2_g);
172 u4_g >>= 2;
173 /* R */
174 u4_r = CLIP_U8(*pu1_y_src + i2_r);
175 u4_r >>= 3;
176
177 pu1_y_src++;
178 *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
179
180 /* pixel 2 */
181 /* B */
182 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
183 u4_b >>= 3;
184 /* G */
185 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
186 u4_g >>= 2;
187 /* R */
188 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
189 u4_r >>= 3;
190
191 pu1_y_src_nxt++;
192 *pu2_rgb_dst_next_row++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
193
194 /* pixel 3 */
195 /* B */
196 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
197 u4_b >>= 3;
198 /* G */
199 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
200 u4_g >>= 2;
201 /* R */
202 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
203 u4_r >>= 3;
204
205 pu1_y_src_nxt++;
206 *pu2_rgb_dst_next_row++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
207
208 }
209
210 pu1_u_src = pu1_u_src + src_uv_strd - wd;
211 pu1_v_src = pu1_v_src + src_uv_strd - wd;
212
213 pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd;
214 pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd;
215
216 pu2_rgb_dst = pu2_rgb_dst_next_row - wd + dst_strd;
217 pu2_rgb_dst_next_row = pu2_rgb_dst_next_row + (dst_strd << 1) - wd;
218 }
219
220 }
221
ih264d_fmt_conv_420sp_to_rgba8888(UWORD8 * pu1_y_src,UWORD8 * pu1_uv_src,UWORD32 * pu4_rgba_dst,WORD32 wd,WORD32 ht,WORD32 src_y_strd,WORD32 src_uv_strd,WORD32 dst_strd,WORD32 is_u_first)222 void ih264d_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src,
223 UWORD8 *pu1_uv_src,
224 UWORD32 *pu4_rgba_dst,
225 WORD32 wd,
226 WORD32 ht,
227 WORD32 src_y_strd,
228 WORD32 src_uv_strd,
229 WORD32 dst_strd,
230 WORD32 is_u_first)
231 {
232
233 WORD16 i2_r, i2_g, i2_b;
234 UWORD32 u4_r, u4_g, u4_b;
235 WORD16 i2_i, i2_j;
236 UWORD8 *pu1_y_src_nxt;
237 UWORD32 *pu4_rgba_dst_next_row;
238
239 UWORD8 *pu1_u_src, *pu1_v_src;
240
241 if(is_u_first)
242 {
243 pu1_u_src = (UWORD8 *)pu1_uv_src;
244 pu1_v_src = (UWORD8 *)pu1_uv_src + 1;
245 }
246 else
247 {
248 pu1_u_src = (UWORD8 *)pu1_uv_src + 1;
249 pu1_v_src = (UWORD8 *)pu1_uv_src;
250 }
251
252 pu1_y_src_nxt = pu1_y_src + src_y_strd;
253 pu4_rgba_dst_next_row = pu4_rgba_dst + dst_strd;
254
255 for(i2_i = 0; i2_i < (ht >> 1); i2_i++)
256 {
257 for(i2_j = (wd >> 1); i2_j > 0; i2_j--)
258 {
259 i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13);
260 i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3)
261 >> 13;
262 i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13;
263
264 pu1_u_src += 2;
265 pu1_v_src += 2;
266 /* pixel 0 */
267 /* B */
268 u4_b = CLIP_U8(*pu1_y_src + i2_b);
269 /* G */
270 u4_g = CLIP_U8(*pu1_y_src + i2_g);
271 /* R */
272 u4_r = CLIP_U8(*pu1_y_src + i2_r);
273
274 pu1_y_src++;
275 *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
276
277 /* pixel 1 */
278 /* B */
279 u4_b = CLIP_U8(*pu1_y_src + i2_b);
280 /* G */
281 u4_g = CLIP_U8(*pu1_y_src + i2_g);
282 /* R */
283 u4_r = CLIP_U8(*pu1_y_src + i2_r);
284
285 pu1_y_src++;
286 *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
287
288 /* pixel 2 */
289 /* B */
290 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
291 /* G */
292 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
293 /* R */
294 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
295
296 pu1_y_src_nxt++;
297 *pu4_rgba_dst_next_row++ =
298 ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
299
300 /* pixel 3 */
301 /* B */
302 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
303 /* G */
304 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
305 /* R */
306 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
307
308 pu1_y_src_nxt++;
309 *pu4_rgba_dst_next_row++ =
310 ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
311
312 }
313
314 pu1_u_src = pu1_u_src + src_uv_strd - wd;
315 pu1_v_src = pu1_v_src + src_uv_strd - wd;
316
317 pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd;
318 pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd;
319
320 pu4_rgba_dst = pu4_rgba_dst_next_row - wd + dst_strd;
321 pu4_rgba_dst_next_row = pu4_rgba_dst_next_row + (dst_strd << 1) - wd;
322 }
323
324 }
325
326 /**
327 *******************************************************************************
328 *
329 * @brief Function used from copying a 420SP buffer
330 *
331 * @par Description
332 * Function used from copying a 420SP buffer
333 *
334 * @param[in] pu1_y_src
335 * Input Y pointer
336 *
337 * @param[in] pu1_uv_src
338 * Input UV pointer (UV is interleaved either in UV or VU format)
339 *
340 * @param[in] pu1_y_dst
341 * Output Y pointer
342 *
343 * @param[in] pu1_uv_dst
344 * Output UV pointer (UV is interleaved in the same format as that of input)
345 *
346 * @param[in] wd
347 * Width
348 *
349 * @param[in] ht
350 * Height
351 *
352 * @param[in] src_y_strd
353 * Input Y Stride
354 *
355 * @param[in] src_uv_strd
356 * Input UV stride
357 *
358 * @param[in] dst_y_strd
359 * Output Y stride
360 *
361 * @param[in] dst_uv_strd
362 * Output UV stride
363 *
364 * @returns None
365 *
366 * @remarks In case there is a need to perform partial frame copy then
367 * by passion appropriate source and destination pointers and appropriate
368 * values for wd and ht it can be done
369 *
370 *******************************************************************************
371 */
372
ih264d_fmt_conv_420sp_to_420sp(UWORD8 * pu1_y_src,UWORD8 * pu1_uv_src,UWORD8 * pu1_y_dst,UWORD8 * pu1_uv_dst,WORD32 wd,WORD32 ht,WORD32 src_y_strd,WORD32 src_uv_strd,WORD32 dst_y_strd,WORD32 dst_uv_strd)373 void ih264d_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src,
374 UWORD8 *pu1_uv_src,
375 UWORD8 *pu1_y_dst,
376 UWORD8 *pu1_uv_dst,
377 WORD32 wd,
378 WORD32 ht,
379 WORD32 src_y_strd,
380 WORD32 src_uv_strd,
381 WORD32 dst_y_strd,
382 WORD32 dst_uv_strd)
383 {
384 UWORD8 *pu1_src, *pu1_dst;
385 WORD32 num_rows, num_cols, src_strd, dst_strd;
386 WORD32 i;
387
388 /* copy luma */
389 pu1_src = (UWORD8 *)pu1_y_src;
390 pu1_dst = (UWORD8 *)pu1_y_dst;
391
392 num_rows = ht;
393 num_cols = wd;
394
395 src_strd = src_y_strd;
396 dst_strd = dst_y_strd;
397
398 for(i = 0; i < num_rows; i++)
399 {
400 memcpy(pu1_dst, pu1_src, num_cols);
401 pu1_dst += dst_strd;
402 pu1_src += src_strd;
403 }
404
405 /* copy U and V */
406 pu1_src = (UWORD8 *)pu1_uv_src;
407 pu1_dst = (UWORD8 *)pu1_uv_dst;
408
409 num_rows = ht >> 1;
410 num_cols = wd;
411
412 src_strd = src_uv_strd;
413 dst_strd = dst_uv_strd;
414
415 for(i = 0; i < num_rows; i++)
416 {
417 memcpy(pu1_dst, pu1_src, num_cols);
418 pu1_dst += dst_strd;
419 pu1_src += src_strd;
420 }
421 return;
422 }
423
424 /**
425 *******************************************************************************
426 *
427 * @brief Function used from copying a 420SP buffer
428 *
429 * @par Description
430 * Function used from copying a 420SP buffer
431 *
432 * @param[in] pu1_y_src
433 * Input Y pointer
434 *
435 * @param[in] pu1_uv_src
436 * Input UV pointer (UV is interleaved either in UV or VU format)
437 *
438 * @param[in] pu1_y_dst
439 * Output Y pointer
440 *
441 * @param[in] pu1_uv_dst
442 * Output UV pointer (UV is interleaved in the same format as that of input)
443 *
444 * @param[in] wd
445 * Width
446 *
447 * @param[in] ht
448 * Height
449 *
450 * @param[in] src_y_strd
451 * Input Y Stride
452 *
453 * @param[in] src_uv_strd
454 * Input UV stride
455 *
456 * @param[in] dst_y_strd
457 * Output Y stride
458 *
459 * @param[in] dst_uv_strd
460 * Output UV stride
461 *
462 * @returns None
463 *
464 * @remarks In case there is a need to perform partial frame copy then
465 * by passion appropriate source and destination pointers and appropriate
466 * values for wd and ht it can be done
467 *
468 *******************************************************************************
469 */
ih264d_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 * pu1_y_src,UWORD8 * pu1_uv_src,UWORD8 * pu1_y_dst,UWORD8 * pu1_uv_dst,WORD32 wd,WORD32 ht,WORD32 src_y_strd,WORD32 src_uv_strd,WORD32 dst_y_strd,WORD32 dst_uv_strd)470 void ih264d_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src,
471 UWORD8 *pu1_uv_src,
472 UWORD8 *pu1_y_dst,
473 UWORD8 *pu1_uv_dst,
474 WORD32 wd,
475 WORD32 ht,
476 WORD32 src_y_strd,
477 WORD32 src_uv_strd,
478 WORD32 dst_y_strd,
479 WORD32 dst_uv_strd)
480 {
481 UWORD8 *pu1_src, *pu1_dst;
482 WORD32 num_rows, num_cols, src_strd, dst_strd;
483 WORD32 i;
484
485 /* copy luma */
486 pu1_src = (UWORD8 *)pu1_y_src;
487 pu1_dst = (UWORD8 *)pu1_y_dst;
488
489 num_rows = ht;
490 num_cols = wd;
491
492 src_strd = src_y_strd;
493 dst_strd = dst_y_strd;
494
495 for(i = 0; i < num_rows; i++)
496 {
497 memcpy(pu1_dst, pu1_src, num_cols);
498 pu1_dst += dst_strd;
499 pu1_src += src_strd;
500 }
501
502 /* copy U and V */
503 pu1_src = (UWORD8 *)pu1_uv_src;
504 pu1_dst = (UWORD8 *)pu1_uv_dst;
505
506 num_rows = ht >> 1;
507 num_cols = wd;
508
509 src_strd = src_uv_strd;
510 dst_strd = dst_uv_strd;
511
512 for(i = 0; i < num_rows; i++)
513 {
514 WORD32 j;
515 for(j = 0; j < num_cols; j += 2)
516 {
517 pu1_dst[j + 0] = pu1_src[j + 1];
518 pu1_dst[j + 1] = pu1_src[j + 0];
519 }
520 pu1_dst += dst_strd;
521 pu1_src += src_strd;
522 }
523 return;
524 }
525 /**
526 *******************************************************************************
527 *
528 * @brief Function used from copying a 420SP buffer
529 *
530 * @par Description
531 * Function used from copying a 420SP buffer
532 *
533 * @param[in] pu1_y_src
534 * Input Y pointer
535 *
536 * @param[in] pu1_uv_src
537 * Input UV pointer (UV is interleaved either in UV or VU format)
538 *
539 * @param[in] pu1_y_dst
540 * Output Y pointer
541 *
542 * @param[in] pu1_u_dst
543 * Output U pointer
544 *
545 * @param[in] pu1_v_dst
546 * Output V pointer
547 *
548 * @param[in] wd
549 * Width
550 *
551 * @param[in] ht
552 * Height
553 *
554 * @param[in] src_y_strd
555 * Input Y Stride
556 *
557 * @param[in] src_uv_strd
558 * Input UV stride
559 *
560 * @param[in] dst_y_strd
561 * Output Y stride
562 *
563 * @param[in] dst_uv_strd
564 * Output UV stride
565 *
566 * @param[in] is_u_first
567 * Flag to indicate if U is the first byte in input chroma part
568 *
569 * @returns none
570 *
571 * @remarks In case there is a need to perform partial frame copy then
572 * by passion appropriate source and destination pointers and appropriate
573 * values for wd and ht it can be done
574 *
575 *******************************************************************************
576 */
577
ih264d_fmt_conv_420sp_to_420p(UWORD8 * pu1_y_src,UWORD8 * pu1_uv_src,UWORD8 * pu1_y_dst,UWORD8 * pu1_u_dst,UWORD8 * pu1_v_dst,WORD32 wd,WORD32 ht,WORD32 src_y_strd,WORD32 src_uv_strd,WORD32 dst_y_strd,WORD32 dst_uv_strd,WORD32 is_u_first,WORD32 disable_luma_copy)578 void ih264d_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src,
579 UWORD8 *pu1_uv_src,
580 UWORD8 *pu1_y_dst,
581 UWORD8 *pu1_u_dst,
582 UWORD8 *pu1_v_dst,
583 WORD32 wd,
584 WORD32 ht,
585 WORD32 src_y_strd,
586 WORD32 src_uv_strd,
587 WORD32 dst_y_strd,
588 WORD32 dst_uv_strd,
589 WORD32 is_u_first,
590 WORD32 disable_luma_copy)
591 {
592 UWORD8 *pu1_src, *pu1_dst;
593 UWORD8 *pu1_u_src, *pu1_v_src;
594 WORD32 num_rows, num_cols, src_strd, dst_strd;
595 WORD32 i, j;
596
597 if(0 == disable_luma_copy)
598 {
599 /* copy luma */
600 pu1_src = (UWORD8 *)pu1_y_src;
601 pu1_dst = (UWORD8 *)pu1_y_dst;
602
603 num_rows = ht;
604 num_cols = wd;
605
606 src_strd = src_y_strd;
607 dst_strd = dst_y_strd;
608
609 for(i = 0; i < num_rows; i++)
610 {
611 memcpy(pu1_dst, pu1_src, num_cols);
612 pu1_dst += dst_strd;
613 pu1_src += src_strd;
614 }
615 }
616 /* de-interleave U and V and copy to destination */
617 if(is_u_first)
618 {
619 pu1_u_src = (UWORD8 *)pu1_uv_src;
620 pu1_v_src = (UWORD8 *)pu1_uv_src + 1;
621 }
622 else
623 {
624 pu1_u_src = (UWORD8 *)pu1_uv_src + 1;
625 pu1_v_src = (UWORD8 *)pu1_uv_src;
626 }
627
628 num_rows = ht >> 1;
629 num_cols = wd >> 1;
630
631 src_strd = src_uv_strd;
632 dst_strd = dst_uv_strd;
633
634 for(i = 0; i < num_rows; i++)
635 {
636 for(j = 0; j < num_cols; j++)
637 {
638 pu1_u_dst[j] = pu1_u_src[j * 2];
639 pu1_v_dst[j] = pu1_v_src[j * 2];
640 }
641
642 pu1_u_dst += dst_strd;
643 pu1_v_dst += dst_strd;
644 pu1_u_src += src_strd;
645 pu1_v_src += src_strd;
646 }
647 return;
648 }
649
650 /*****************************************************************************/
651 /* Function Name : ih264d_format_convert */
652 /* */
653 /* Description : Implements format conversion/frame copy */
654 /* Inputs : ps_dec - Decoder parameters */
655 /* Globals : None */
656 /* Processing : Refer bumping process in the standard */
657 /* Outputs : Assigns display sequence number. */
658 /* Returns : None */
659 /* */
660 /* Issues : None */
661 /* */
662 /* Revision History: */
663 /* */
664 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
665 /* 27 04 2005 NS Draft */
666 /* */
667 /*****************************************************************************/
ih264d_format_convert(dec_struct_t * ps_dec,ivd_get_display_frame_op_t * pv_disp_op,UWORD32 u4_start_y,UWORD32 u4_num_rows_y)668 void ih264d_format_convert(dec_struct_t *ps_dec,
669 ivd_get_display_frame_op_t *pv_disp_op,
670 UWORD32 u4_start_y,
671 UWORD32 u4_num_rows_y)
672 {
673 UWORD32 convert_uv_only = 0;
674 iv_yuv_buf_t *ps_op_frm;
675 UWORD8 *pu1_y_src, *pu1_uv_src;
676 UWORD32 start_uv = u4_start_y >> 1;
677
678 if(1 == pv_disp_op->u4_error_code)
679 return;
680
681 ps_op_frm = &(ps_dec->s_disp_frame_info);
682
683 /* Requires u4_start_y and u4_num_rows_y to be even */
684 if(u4_start_y & 1)
685 {
686 return;
687 }
688
689 if((1 == ps_dec->u4_share_disp_buf) &&
690 (pv_disp_op->e_output_format == IV_YUV_420SP_UV))
691 {
692 return;
693 }
694
695 pu1_y_src = (UWORD8 *)ps_op_frm->pv_y_buf;
696 pu1_y_src += u4_start_y * ps_op_frm->u4_y_strd,
697
698 pu1_uv_src = (UWORD8 *)ps_op_frm->pv_u_buf;
699 pu1_uv_src += start_uv * ps_op_frm->u4_u_strd;
700
701 if(pv_disp_op->e_output_format == IV_YUV_420P)
702 {
703 UWORD8 *pu1_y_dst, *pu1_u_dst, *pu1_v_dst;
704 IV_COLOR_FORMAT_T e_output_format = pv_disp_op->e_output_format;
705
706 if(0 == ps_dec->u4_share_disp_buf)
707 {
708 convert_uv_only = 0;
709 }
710 else
711 {
712 convert_uv_only = 1;
713 }
714
715 pu1_y_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf;
716 pu1_y_dst += u4_start_y * pv_disp_op->s_disp_frm_buf.u4_y_strd;
717
718 pu1_u_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_u_buf;
719 pu1_u_dst += start_uv * pv_disp_op->s_disp_frm_buf.u4_u_strd;
720
721 pu1_v_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_v_buf;
722 pu1_v_dst += start_uv * pv_disp_op->s_disp_frm_buf.u4_v_strd;
723
724 ih264d_fmt_conv_420sp_to_420p(pu1_y_src,
725 pu1_uv_src,
726 pu1_y_dst,
727 pu1_u_dst,
728 pu1_v_dst,
729 ps_op_frm->u4_y_wd,
730 u4_num_rows_y,
731 ps_op_frm->u4_y_strd,
732 ps_op_frm->u4_u_strd,
733 pv_disp_op->s_disp_frm_buf.u4_y_strd,
734 pv_disp_op->s_disp_frm_buf.u4_u_strd,
735 1,
736 convert_uv_only);
737
738 }
739 else if((pv_disp_op->e_output_format == IV_YUV_420SP_UV) ||
740 (pv_disp_op->e_output_format == IV_YUV_420SP_VU))
741 {
742 UWORD8* pu1_y_dst, *pu1_uv_dst;
743
744 pu1_y_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf;
745 pu1_y_dst += u4_start_y * pv_disp_op->s_disp_frm_buf.u4_y_strd;
746
747 pu1_uv_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_u_buf;
748 pu1_uv_dst += start_uv * pv_disp_op->s_disp_frm_buf.u4_u_strd;
749
750 if(pv_disp_op->e_output_format == IV_YUV_420SP_UV)
751 {
752 ih264d_fmt_conv_420sp_to_420sp(pu1_y_src,
753 pu1_uv_src,
754 pu1_y_dst,
755 pu1_uv_dst,
756 ps_op_frm->u4_y_wd,
757 u4_num_rows_y,
758 ps_op_frm->u4_y_strd,
759 ps_op_frm->u4_u_strd,
760 pv_disp_op->s_disp_frm_buf.u4_y_strd,
761 pv_disp_op->s_disp_frm_buf.u4_u_strd);
762 }
763 else
764 {
765 ih264d_fmt_conv_420sp_to_420sp_swap_uv(pu1_y_src,
766 pu1_uv_src,
767 pu1_y_dst,
768 pu1_uv_dst,
769 ps_op_frm->u4_y_wd,
770 u4_num_rows_y,
771 ps_op_frm->u4_y_strd,
772 ps_op_frm->u4_u_strd,
773 pv_disp_op->s_disp_frm_buf.u4_y_strd,
774 pv_disp_op->s_disp_frm_buf.u4_u_strd);
775 }
776 }
777 else if(pv_disp_op->e_output_format == IV_RGB_565)
778 {
779 UWORD16 *pu2_rgb_dst;
780
781 pu2_rgb_dst = (UWORD16 *)pv_disp_op->s_disp_frm_buf.pv_y_buf;
782 pu2_rgb_dst += u4_start_y * pv_disp_op->s_disp_frm_buf.u4_y_strd;
783
784 ih264d_fmt_conv_420sp_to_rgb565(pu1_y_src,
785 pu1_uv_src,
786 pu2_rgb_dst,
787 ps_op_frm->u4_y_wd,
788 u4_num_rows_y,
789 ps_op_frm->u4_y_strd,
790 ps_op_frm->u4_u_strd,
791 pv_disp_op->s_disp_frm_buf.u4_y_strd,
792 1);
793 }
794
795 if((u4_start_y + u4_num_rows_y) >= ps_dec->s_disp_frame_info.u4_y_ht)
796 {
797
798 INSERT_LOGO(pv_disp_op->s_disp_frm_buf.pv_y_buf,
799 pv_disp_op->s_disp_frm_buf.pv_u_buf,
800 pv_disp_op->s_disp_frm_buf.pv_v_buf,
801 pv_disp_op->s_disp_frm_buf.u4_y_strd,
802 ps_dec->u2_disp_width,
803 ps_dec->u2_disp_height,
804 pv_disp_op->e_output_format,
805 ps_op_frm->u4_y_wd,
806 ps_op_frm->u4_y_ht);
807 }
808
809 return;
810 }
811