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 */
108void 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
222void 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
373void 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 */
470void 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
578void 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/*****************************************************************************/
668void 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