Home | History | Annotate | Download | only in decoder
      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  */
    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 
    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 
    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  */
    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 
    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 /*****************************************************************************/
    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