Home | History | Annotate | Download | only in common
      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         : impeg2_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 /*  List of Functions : YUV420toYUV420()                                      */
     28 /*                      YUV420toYUV422I()                                    */
     29 /*                      YUV420toYUV420SP_VU()                                */
     30 /*                      YUV420toYUV420SP_UU()                                */
     31 /*                                                                           */
     32 /*  Issues / Problems : None                                                 */
     33 /*                                                                           */
     34 /*  Revision History  :                                                      */
     35 /*                                                                           */
     36 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
     37 /*         28 08 2007  Naveen Kumar T        Draft                           */
     38 /*                                                                           */
     39 /*****************************************************************************/
     40 /*****************************************************************************/
     41 /* File Includes                                                             */
     42 /*****************************************************************************/
     43 
     44 /* System include files */
     45 
     46 /* User include files */
     47 #include <stdio.h>
     48 #include <string.h>
     49 #include "iv_datatypedef.h"
     50 #include "iv.h"
     51 #include "ithread.h"
     52 
     53 #include "iv_datatypedef.h"
     54 #include "impeg2_macros.h"
     55 #include "impeg2_buf_mgr.h"
     56 #include "impeg2_disp_mgr.h"
     57 #include "impeg2_defs.h"
     58 #include "impeg2_platform_macros.h"
     59 
     60 #include "impeg2_job_queue.h"
     61 #include "impeg2_format_conv.h"
     62 
     63 
     64 /*****************************************************************************/
     65 /*                                                                           */
     66 /*  Function Name : impeg2_copy_frm_yuv420p()                                        */
     67 /*                                                                           */
     68 /*  Description   : This function performs conversion from YUV420 to         */
     69 /*                  YUV422I color space.                                     */
     70 /*                                                                           */
     71 /*  Inputs        : pu1_src_y,       -   UWORD8 pointer to source y plane.   */
     72 /*                  pu1_src_u,       -   UWORD8 pointer to source u plane.   */
     73 /*                  pu1_src_v,       -   UWORD8 pointer to source v plane.   */
     74 /*                  pu1_dst_y,       -   UWORD8 pointer to dest y plane.     */
     75 /*                  pu1_dst_u,       -   UWORD8 pointer to dest u plane.     */
     76 /*                  pu1_dst_v,       -   UWORD8 pointer to dest v plane.     */
     77 /*                  u4_width,        -   Width of image.                     */
     78 /*                  u4_height,       -   Height of image.                    */
     79 /*                  u4_src_stride_y  -   Stride in pixels of source Y plane. */
     80 /*                  u4_src_stride_u  -   Stride in pixels of source U plane. */
     81 /*                  u4_src_stride_v  -   Stride in pixels of source V plane. */
     82 /*                  u4_dst_stride_y  -   Stride in pixels of dest Y plane.   */
     83 /*                  u4_dst_stride_u  -   Stride in pixels of dest U plane.   */
     84 /*                  u4_dst_stride_v  -   Stride in pixels of dest V plane.   */
     85 /*                                                                           */
     86 /*  Globals       : None                                                     */
     87 /*                                                                           */
     88 /*  Processing    : One row is processed at a time. The one iteration of the */
     89 /*                  code will rearrange pixels into YUV422 interleaved       */
     90 /*                  format.                                                  */
     91 /*                                                                           */
     92 /*  Outputs       : None                                                     */
     93 /*                                                                           */
     94 /*  Returns       : None                                                     */
     95 /*                                                                           */
     96 /*  Issues        : None                                                     */
     97 /*                                                                           */
     98 /*  Revision History:                                                        */
     99 /*                                                                           */
    100 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
    101 /*         29 08 2007  Naveen Kumar T        Draft                           */
    102 /*                                                                           */
    103 /*****************************************************************************/
    104 void impeg2_copy_frm_yuv420p(UWORD8 *pu1_src_y,
    105                              UWORD8 *pu1_src_u,
    106                              UWORD8 *pu1_src_v,
    107                              UWORD8 *pu1_dst_y,
    108                              UWORD8 *pu1_dst_u,
    109                              UWORD8 *pu1_dst_v,
    110                              UWORD32 u4_width,
    111                              UWORD32 u4_height,
    112                              UWORD32 u4_src_stride_y,
    113                              UWORD32 u4_src_stride_u,
    114                              UWORD32 u4_src_stride_v,
    115                              UWORD32 u4_dst_stride_y,
    116                              UWORD32 u4_dst_stride_u,
    117                              UWORD32 u4_dst_stride_v)
    118 {
    119     WORD32 i4_cnt;
    120     WORD32  i4_y_height     = (WORD32) u4_height;
    121     WORD32  i4_uv_height    = u4_height >> 1;
    122     WORD32  i4_uv_width     = u4_width >> 1;
    123 
    124     for(i4_cnt = 0; i4_cnt < i4_y_height; i4_cnt++)
    125     {
    126         memcpy(pu1_dst_y, pu1_src_y, u4_width);
    127         pu1_dst_y += (u4_dst_stride_y);
    128         pu1_src_y += (u4_src_stride_y);
    129     }
    130 
    131     for(i4_cnt = 0; i4_cnt < i4_uv_height; i4_cnt++)
    132     {
    133         memcpy(pu1_dst_u, pu1_src_u, i4_uv_width);
    134         pu1_dst_u += (u4_dst_stride_u);
    135         pu1_src_u += (u4_src_stride_u);
    136 
    137     }
    138 
    139     for(i4_cnt = 0; i4_cnt < i4_uv_height; i4_cnt++)
    140     {
    141         memcpy(pu1_dst_v, pu1_src_v, i4_uv_width);
    142         pu1_dst_v += (u4_dst_stride_v);
    143         pu1_src_v += (u4_src_stride_v);
    144 
    145     }
    146 
    147 }
    148 
    149 /*****************************************************************************/
    150 /*                                                                           */
    151 /*  Function Name : impeg2_fmt_conv_yuv420p_to_yuv422ile()                   */
    152 /*                                                                           */
    153 /*  Description   : This function performs conversion from YUV420 to         */
    154 /*                  YUV422I color space.                                     */
    155 /*                                                                           */
    156 /*  Inputs        : pu1_y            -   UWORD8 pointer to y plane.          */
    157 /*                  pu1_u            -   UWORD8 pointer to u plane.          */
    158 /*                  pu1_v            -   UWORD8 pointer to u plane.          */
    159 /*                  pu2_yuv422i      -   UWORD16 pointer to yuv422iimage.    */
    160 /*                  u4_width         -   Width of the Y plane.               */
    161 /*                  u4_height        -   Height of the Y plane.              */
    162 /*                  u4_stride_y      -   Stride in pixels of Y plane.        */
    163 /*                  u4_stride_u      -   Stride in pixels of U plane.        */
    164 /*                  u4_stride_v      -   Stride in pixels of V plane.        */
    165 /*                  u4_stride_yuv422i-   Stride in pixels of yuv422i image.  */
    166 /*                                                                           */
    167 /*  Globals       : None                                                     */
    168 /*                                                                           */
    169 /*  Processing    : One row is processed at a time. The one iteration of the */
    170 /*                  code will rearrange pixels into YUV422 interleaved       */
    171 /*                  format.                                                  */
    172 /*                                                                           */
    173 /*  Outputs       : None                                                     */
    174 /*                                                                           */
    175 /*  Returns       : None                                                     */
    176 /*                                                                           */
    177 /*  Issues        : None                                                     */
    178 /*                                                                           */
    179 /*  Revision History:                                                        */
    180 /*                                                                           */
    181 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
    182 /*         29 08 2007  Naveen Kumar T        Draft                           */
    183 /*                                                                           */
    184 /*****************************************************************************/
    185 
    186 void impeg2_fmt_conv_yuv420p_to_yuv422ile(register UWORD8 *pu1_y,
    187                      register UWORD8 *pu1_u,
    188                      register UWORD8 *pu1_v,
    189                      void *pv_yuv422i,
    190                      UWORD32 u4_width,
    191                      UWORD32 u4_height,
    192                      UWORD32 u4_stride_y,
    193                      UWORD32 u4_stride_u,
    194                      UWORD32 u4_stride_v,
    195                      UWORD32 u4_stride_yuv422i)
    196 {
    197     /* Declare local variables */
    198     register WORD16  i,j;
    199     register UWORD16 u2_offset1,u2_offset2,u2_offset3,u2_offset_yuv422i;
    200     register UWORD8  u1_y1,u1_uv;
    201     register UWORD32 u4_pixel;
    202     register UWORD16 u2_width_cnt;
    203     register UWORD32 *pu4_yuv422i;
    204 
    205     UWORD8 u1_flag;             /* This flag is used to indicate wether the row is even or odd */
    206 
    207     u1_flag=0x0;                /* Intialize it with 0 indicating odd row */
    208 
    209     /* Calculate the offsets necessary to make input and output buffers to point next row */
    210     u2_offset1       = u4_stride_y - u4_width;
    211     u2_offset2       = u4_stride_u - ((u4_width + 1) >> 1);
    212     u2_offset3       = u4_stride_v - ((u4_width + 1) >> 1);
    213     u2_offset_yuv422i = (u4_stride_yuv422i >> 1) -((u4_width + 1) >> 1);
    214 
    215     /* Type cast the output pointer to UWORD32 */
    216     pu4_yuv422i      = (UWORD32 *)pv_yuv422i;
    217 
    218     /* Calculate the loop counter for inner loop */
    219     u2_width_cnt     = u4_width >> 1;
    220 
    221     /* Run the loop for height of input buffer */
    222     for(i = u4_height; i > 0; i--)
    223     {
    224         /* Run the loop for width/2 */
    225         for(j = u2_width_cnt; j > 0; j--)
    226         {
    227             /* Store the value in output buffer in the order U0Y0V0Y1U2Y2V2Y3.... */
    228             /* Load Y0 */
    229             u1_y1          = *pu1_y++;
    230             /* Load Y1 */
    231             u4_pixel       = *pu1_y++;
    232             /* Load V0 */
    233             u1_uv          = *pu1_v++;
    234             u4_pixel       = (u4_pixel << 8) + u1_uv;
    235             /* Load U0 */
    236             u1_uv          = *pu1_u++;
    237             u4_pixel       = (u4_pixel << 8) + u1_y1;
    238             u4_pixel       = (u4_pixel << 8) + u1_uv;
    239             *pu4_yuv422i++ = u4_pixel;
    240         }
    241         /* Incase of width is odd number take care of last pixel */
    242         if(u4_width & 0x1)
    243         {
    244             /* Store the value in output buffer in the order U0Y0V0Y1U2Y2V2Y3.... */
    245             /* Load Y0 */
    246             u1_y1          = *pu1_y++;
    247             /* Load V0 */
    248             u1_uv          = *pu1_v++;
    249             /* Take Y0 as Y1 */
    250             u4_pixel       = u1_y1;
    251             u4_pixel       = (u4_pixel << 8) + u1_uv;
    252             /* Load U0 */
    253             u1_uv          = *pu1_u++;
    254             u4_pixel       = (u4_pixel << 8) + u1_y1;
    255             u4_pixel       = (u4_pixel << 8) + u1_uv;
    256             *pu4_yuv422i++ = u4_pixel;
    257         }
    258         /* Make the pointers to buffer to point to next row */
    259         pu1_y = pu1_y       + u2_offset1;
    260         if(!u1_flag)
    261         {
    262             /* Restore the pointers of u and v buffer back so that the row of pixels are also  */
    263             /* Processed with same row of u and values again */
    264             pu1_u = pu1_u - ((u4_width + 1) >> 1);
    265             pu1_v = pu1_v - ((u4_width + 1) >> 1);
    266         }
    267         else
    268         {
    269             /* Adjust the u and v buffer pointers so that they will point to next row */
    270             pu1_u = pu1_u + u2_offset2;
    271             pu1_v = pu1_v + u2_offset3;
    272         }
    273 
    274         /* Adjust the output buffer pointer for next row */
    275         pu4_yuv422i = pu4_yuv422i + u2_offset_yuv422i;
    276         /* Toggle the flag to convert between odd and even row */
    277         u1_flag= u1_flag ^ 0x1;
    278     }
    279 }
    280 
    281 
    282 
    283 
    284 void impeg2_fmt_conv_yuv420p_to_yuv420sp_vu(UWORD8 *pu1_y, UWORD8 *pu1_u, UWORD8 *pu1_v,
    285                                      UWORD8 *pu1_dest_y, UWORD8 *pu1_dest_uv,
    286                                      UWORD32 u4_height,  UWORD32 u4_width,UWORD32 u4_stridey,
    287                                      UWORD32 u4_strideu, UWORD32 u4_stridev,
    288                                      UWORD32 u4_dest_stride_y, UWORD32 u4_dest_stride_uv,
    289                                      UWORD32 u4_convert_uv_only
    290                                      )
    291 
    292 {
    293 
    294 
    295     UWORD8 *pu1_src,*pu1_dst;
    296     UWORD8 *pu1_src_u, *pu1_src_v;
    297     UWORD16 i;
    298     UWORD32 u2_width_uv;
    299 
    300     UWORD32 u4_dest_inc_y=0, u4_dest_inc_uv=0;
    301 
    302 
    303     /* Copy Y buffer */
    304     pu1_dst = (UWORD8 *)pu1_dest_y;
    305     pu1_src = (UWORD8 *)pu1_y;
    306 
    307     u4_dest_inc_y =    u4_dest_stride_y;
    308     u4_dest_inc_uv =   u4_dest_stride_uv;
    309 
    310     if(0 == u4_convert_uv_only)
    311     {
    312         for(i = 0; i < u4_height; i++)
    313         {
    314             memcpy((void *)pu1_dst,(void *)pu1_src, u4_width);
    315             pu1_dst += u4_dest_inc_y;
    316             pu1_src += u4_stridey;
    317         }
    318     }
    319 
    320     /* Interleave Cb and Cr buffers */
    321     pu1_src_u = pu1_u;
    322     pu1_src_v = pu1_v;
    323     pu1_dst = pu1_dest_uv ;
    324 
    325     u4_height = (u4_height + 1) >> 1;
    326     u2_width_uv = (u4_width + 1) >> 1;
    327     for(i = 0; i < u4_height ; i++)
    328     {
    329         UWORD32 j;
    330         for(j = 0; j < u2_width_uv; j++)
    331         {
    332             *pu1_dst++ = *pu1_src_v++;
    333             *pu1_dst++ = *pu1_src_u++;
    334 
    335         }
    336 
    337         pu1_dst += u4_dest_inc_uv - u4_width;
    338         pu1_src_u  += u4_strideu - u2_width_uv;
    339         pu1_src_v  += u4_stridev - u2_width_uv;
    340     }
    341 }
    342 
    343 void impeg2_fmt_conv_yuv420p_to_yuv420sp_uv(UWORD8 *pu1_y, UWORD8 *pu1_u, UWORD8 *pu1_v,
    344                                      UWORD8 *pu1_dest_y, UWORD8 *pu1_dest_uv,
    345                                      UWORD32 u4_height,  UWORD32 u4_width,UWORD32 u4_stridey,
    346                                      UWORD32 u4_strideu, UWORD32 u4_stridev,
    347                                      UWORD32 u4_dest_stride_y, UWORD32 u4_dest_stride_uv,
    348                                      UWORD32 u4_convert_uv_only)
    349 
    350 {
    351 
    352 
    353     UWORD8 *pu1_src,*pu1_dst;
    354     UWORD8 *pu1_src_u, *pu1_src_v;
    355     UWORD16 i;
    356     UWORD32 u2_width_uv;
    357 
    358     UWORD32 u4_dest_inc_y=0, u4_dest_inc_uv=0;
    359 
    360 
    361     /* Copy Y buffer */
    362     pu1_dst = (UWORD8 *)pu1_dest_y;
    363     pu1_src = (UWORD8 *)pu1_y;
    364 
    365     u4_dest_inc_y =    u4_dest_stride_y;
    366     u4_dest_inc_uv =   u4_dest_stride_uv;
    367 
    368     if(0 == u4_convert_uv_only)
    369     {
    370         for(i = 0; i < u4_height; i++)
    371         {
    372             memcpy((void *)pu1_dst,(void *)pu1_src, u4_width);
    373             pu1_dst += u4_dest_inc_y;
    374             pu1_src += u4_stridey;
    375         }
    376     }
    377 
    378     /* Interleave Cb and Cr buffers */
    379     pu1_src_u = pu1_u;
    380     pu1_src_v = pu1_v;
    381     pu1_dst = pu1_dest_uv ;
    382 
    383     u4_height = (u4_height + 1) >> 1;
    384     u2_width_uv = (u4_width + 1) >> 1;
    385     for(i = 0; i < u4_height ; i++)
    386     {
    387         UWORD32 j;
    388         for(j = 0; j < u2_width_uv; j++)
    389         {
    390             *pu1_dst++ = *pu1_src_u++;
    391             *pu1_dst++ = *pu1_src_v++;
    392         }
    393 
    394         pu1_dst += u4_dest_inc_uv - u4_width;
    395         pu1_src_u  += u4_strideu - u2_width_uv;
    396         pu1_src_v  += u4_stridev - u2_width_uv;
    397     }
    398 
    399 }
    400 
    401 
    402