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
     23 *  impeg2d_mcu.c
     24 *
     25 * @brief
     26 *  Contains MC function definitions for MPEG2 decoder
     27 *
     28 * @author
     29 *  Harish
     30 *
     31 * @par List of Functions:
     32 * - impeg2_copy_mb()
     33 * - impeg2_interpolate()
     34 * - impeg2_mc_halfx_halfy_8x8()
     35 * - impeg2_mc_halfx_fully_8x8()
     36 * - impeg2_mc_fullx_halfy_8x8()
     37 * - impeg2_mc_fullx_fully_8x8()
     38 *
     39 * @remarks
     40 *  None
     41 *
     42 *******************************************************************************
     43 */
     44 
     45 #include <stdio.h>
     46 #include <string.h>
     47 #include "iv_datatypedef.h"
     48 #include "iv.h"
     49 #include "impeg2_buf_mgr.h"
     50 #include "impeg2_disp_mgr.h"
     51 #include "impeg2_defs.h"
     52 #include "impeg2_platform_macros.h"
     53 
     54 #include "impeg2_inter_pred.h"
     55 #include "impeg2_globals.h"
     56 #include "impeg2_macros.h"
     57 #include "impeg2_idct.h"
     58 
     59 /*******************************************************************************
     60 *  Function Name   : impeg2_copy_mb
     61 *
     62 *  Description     : copies 3 components to the frame from mc_buf
     63 *
     64 *  Arguments       :
     65 *  src_buf         : Source Buffer
     66 *  dst_buf         : Destination Buffer
     67 *  src_offset_x    : X offset for source
     68 *  src_offset_y    : Y offset for source
     69 *  dst_offset_x    : X offset for destination
     70 *  dst_offset_y    : Y offset for destination
     71 *  src_wd          : Source Width
     72 *  dst_wd          : destination Width
     73 *  rows            : Number of rows
     74 *  cols            : Number of columns
     75 *
     76 *  Values Returned : None
     77 *******************************************************************************/
     78 void impeg2_copy_mb(yuv_buf_t *ps_src_buf,
     79                     yuv_buf_t *ps_dst_buf,
     80                     UWORD32 u4_src_wd,
     81                     UWORD32 u4_dst_wd)
     82 {
     83     UWORD8 *pu1_src;
     84     UWORD8 *pu1_dst;
     85     UWORD32 i;
     86     UWORD32 u4_rows = MB_SIZE;
     87     UWORD32 u4_cols = MB_SIZE;
     88 
     89     /*******************************************************/
     90     /* copy Y                                              */
     91     /*******************************************************/
     92     pu1_src = ps_src_buf->pu1_y;
     93     pu1_dst = ps_dst_buf->pu1_y;
     94     for(i = 0; i < u4_rows; i++)
     95     {
     96         memcpy(pu1_dst, pu1_src, u4_cols);
     97         pu1_src += u4_src_wd;
     98         pu1_dst += u4_dst_wd;
     99     }
    100 
    101     u4_src_wd >>= 1;
    102     u4_dst_wd >>= 1;
    103     u4_rows >>= 1;
    104     u4_cols >>= 1;
    105 
    106     /*******************************************************/
    107     /* copy U                                              */
    108     /*******************************************************/
    109     pu1_src = ps_src_buf->pu1_u;
    110     pu1_dst = ps_dst_buf->pu1_u;
    111     for(i = 0; i < u4_rows; i++)
    112     {
    113         memcpy(pu1_dst, pu1_src, u4_cols);
    114 
    115         pu1_src += u4_src_wd;
    116         pu1_dst += u4_dst_wd;
    117     }
    118     /*******************************************************/
    119     /* copy V                                              */
    120     /*******************************************************/
    121     pu1_src = ps_src_buf->pu1_v;
    122     pu1_dst = ps_dst_buf->pu1_v;
    123     for(i = 0; i < u4_rows; i++)
    124     {
    125         memcpy(pu1_dst, pu1_src, u4_cols);
    126 
    127         pu1_src += u4_src_wd;
    128         pu1_dst += u4_dst_wd;
    129     }
    130 
    131 }
    132 
    133 /*****************************************************************************/
    134 /*                                                                           */
    135 /*  Function Name : impeg2_interpolate                                       */
    136 /*                                                                           */
    137 /*  Description   : averages the contents of buf_src1 and buf_src2 and stores*/
    138 /*                  result in buf_dst                                        */
    139 /*                                                                           */
    140 /*  Inputs        : buf_src1 -  First Source                                 */
    141 /*                  buf_src2 -  Second Source                                */
    142 /*                                                                           */
    143 /*  Globals       : None                                                     */
    144 /*                                                                           */
    145 /*  Processing    : Avg the values from two sources and store the result in  */
    146 /*                  destination buffer                                       */
    147 /*                                                                           */
    148 /*  Outputs       : buf_dst  -  Avg of contents of buf_src1 and buf_src2     */
    149 /*                                                                           */
    150 /*  Returns       : None                                                     */
    151 /*                                                                           */
    152 /*  Issues        : Assumes that all 3 buffers are of same size              */
    153 /*                                                                           */
    154 /*  Revision History:                                                        */
    155 /*                                                                           */
    156 /*         DD MM YYYY   Author(s)       Changes                              */
    157 /*         14 09 2005   Harish M        First Version                        */
    158 /*         15 09 2010   Venkat          Added stride                         */
    159 /*                                                                           */
    160 /*****************************************************************************/
    161 void impeg2_interpolate(yuv_buf_t *ps_buf_src1,
    162                         yuv_buf_t *ps_buf_src2,
    163                         yuv_buf_t *ps_buf_dst,
    164                         UWORD32 u4_stride)
    165 {
    166 
    167     UWORD32 i,j;
    168     UWORD8 *pu1_src1,*pu1_src2,*pu1_dst;
    169     pu1_src1 = ps_buf_src1->pu1_y;
    170     pu1_src2 = ps_buf_src2->pu1_y;
    171     pu1_dst  = ps_buf_dst->pu1_y;
    172     for(i = MB_SIZE; i > 0; i--)
    173     {
    174         for(j = MB_SIZE; j > 0; j--)
    175         {
    176             *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
    177         }
    178 
    179         pu1_dst += u4_stride - MB_SIZE;
    180 
    181     }
    182 
    183     u4_stride >>= 1;
    184 
    185     pu1_src1 = ps_buf_src1->pu1_u;
    186     pu1_src2 = ps_buf_src2->pu1_u;
    187     pu1_dst  = ps_buf_dst->pu1_u;
    188     for(i = MB_CHROMA_SIZE; i > 0 ; i--)
    189     {
    190         for(j = MB_CHROMA_SIZE; j > 0; j--)
    191         {
    192             *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
    193         }
    194 
    195         pu1_dst += u4_stride - MB_CHROMA_SIZE;
    196     }
    197 
    198     pu1_src1 = ps_buf_src1->pu1_v;
    199     pu1_src2 = ps_buf_src2->pu1_v;
    200     pu1_dst  = ps_buf_dst->pu1_v;
    201     for(i = MB_CHROMA_SIZE; i > 0 ; i--)
    202     {
    203         for(j = MB_CHROMA_SIZE; j > 0; j--)
    204         {
    205             *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
    206         }
    207 
    208         pu1_dst += u4_stride - MB_CHROMA_SIZE;
    209     }
    210 
    211 }
    212 
    213 /*****************************************************************************/
    214 /*                                                                           */
    215 /*  Function Name : impeg2_mc_halfx_halfy_8x8()                                 */
    216 /*                                                                           */
    217 /*  Description   : Gets the buffer from (0.5,0.5) to (8.5,8.5)              */
    218 /*                  and the above block of size 8 x 8 will be placed as a    */
    219 /*                  block from the current position of out_buf               */
    220 /*                                                                           */
    221 /*  Inputs        : ref - Reference frame from which the block will be       */
    222 /*                        block will be extracted.                           */
    223 /*                  ref_wid - WIdth of reference frame                       */
    224 /*                  out_wid - WIdth of the output frame                      */
    225 /*                  blk_width  - width of the block                          */
    226 /*                  blk_width  - height of the block                         */
    227 /*                                                                           */
    228 /*  Globals       : None                                                     */
    229 /*                                                                           */
    230 /*  Processing    : Point to the (0,0),(1,0),(0,1),(1,1) position in         */
    231 /*                  the ref frame.Interpolate these four values to get the   */
    232 /*                  value at(0.5,0.5).Repeat this to get an 8 x 8 block      */
    233 /*                  using 9 x 9 block from reference frame                   */
    234 /*                                                                           */
    235 /*  Outputs       : out -  Output containing the extracted block             */
    236 /*                                                                           */
    237 /*  Returns       : None                                                     */
    238 /*                                                                           */
    239 /*  Issues        : None                                                     */
    240 /*                                                                           */
    241 /*  Revision History:                                                        */
    242 /*                                                                           */
    243 /*         DD MM YYYY   Author(s)       Changes                              */
    244 /*         05 09 2005   Harish M        First Version                        */
    245 /*                                                                           */
    246 /*****************************************************************************/
    247 void impeg2_mc_halfx_halfy_8x8(UWORD8 *pu1_out,
    248                             UWORD8 *pu1_ref,
    249                             UWORD32 u4_ref_wid,
    250                             UWORD32 u4_out_wid)
    251 {
    252     UWORD8 *pu1_ref_p0,*pu1_ref_p1,*pu1_ref_p2,*pu1_ref_p3;
    253     UWORD32 i,j;
    254     /* P0-P3 are the pixels in the reference frame and Q is the value being */
    255     /* estimated                                                            */
    256     /*
    257        P0 P1
    258          Q
    259        P2 P3
    260     */
    261 
    262     pu1_ref_p0 = pu1_ref;
    263     pu1_ref_p1 = pu1_ref + 1;
    264     pu1_ref_p2 = pu1_ref + u4_ref_wid;
    265     pu1_ref_p3 = pu1_ref + u4_ref_wid + 1;
    266 
    267     for(i = 0; i < BLK_SIZE; i++)
    268     {
    269         for(j = 0; j < BLK_SIZE; j++)
    270         {
    271             *pu1_out++ =   (( (*pu1_ref_p0++ )
    272                         + (*pu1_ref_p1++ )
    273                         + (*pu1_ref_p2++ )
    274                         + (*pu1_ref_p3++ ) + 2 ) >> 2);
    275         }
    276         pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
    277         pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
    278         pu1_ref_p2 += u4_ref_wid - BLK_SIZE;
    279         pu1_ref_p3 += u4_ref_wid - BLK_SIZE;
    280 
    281         pu1_out    += u4_out_wid - BLK_SIZE;
    282     }
    283     return;
    284 }
    285 
    286 /*****************************************************************************/
    287 /*                                                                           */
    288 /*  Function Name : impeg2_mc_halfx_fully_8x8()                                 */
    289 /*                                                                           */
    290 /*  Description   : Gets the buffer from (0.5,0) to (8.5,8)                  */
    291 /*                  and the above block of size 8 x 8 will be placed as a    */
    292 /*                  block from the current position of out_buf               */
    293 /*                                                                           */
    294 /*  Inputs        : ref - Reference frame from which the block will be       */
    295 /*                        block will be extracted.                           */
    296 /*                  ref_wid - WIdth of reference frame                       */
    297 /*                  out_wid - WIdth of the output frame                      */
    298 /*                  blk_width  - width of the block                          */
    299 /*                  blk_width  - height of the block                         */
    300 /*                                                                           */
    301 /*  Globals       : None                                                     */
    302 /*                                                                           */
    303 /*  Processing    : Point to the (0,0) and (1,0) position in the ref frame   */
    304 /*                  Interpolate these two values to get the value at(0.5,0)  */
    305 /*                  Repeat this to get an 8 x 8 block using 9 x 8 block from */
    306 /*                  reference frame                                          */
    307 /*                                                                           */
    308 /*  Outputs       : out -  Output containing the extracted block             */
    309 /*                                                                           */
    310 /*  Returns       : None                                                     */
    311 /*                                                                           */
    312 /*  Issues        : None                                                     */
    313 /*                                                                           */
    314 /*  Revision History:                                                        */
    315 /*                                                                           */
    316 /*         DD MM YYYY   Author(s)       Changes                              */
    317 /*         05 09 2005   Harish M        First Version                        */
    318 /*                                                                           */
    319 /*****************************************************************************/
    320 void impeg2_mc_halfx_fully_8x8(UWORD8 *pu1_out,
    321                             UWORD8 *pu1_ref,
    322                             UWORD32 u4_ref_wid,
    323                             UWORD32 u4_out_wid)
    324 {
    325     UWORD8 *pu1_ref_p0, *pu1_ref_p1;
    326     UWORD32 i,j;
    327 
    328     /* P0-P3 are the pixels in the reference frame and Q is the value being */
    329     /* estimated                                                            */
    330     /*
    331        P0 Q P1
    332     */
    333 
    334     pu1_ref_p0 = pu1_ref;
    335     pu1_ref_p1 = pu1_ref + 1;
    336 
    337     for(i = 0; i < BLK_SIZE; i++)
    338     {
    339         for(j = 0; j < BLK_SIZE; j++)
    340         {
    341             *pu1_out++ =   ((( *pu1_ref_p0++ )
    342                         + (*pu1_ref_p1++) + 1 ) >> 1);
    343         }
    344         pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
    345         pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
    346 
    347         pu1_out    += u4_out_wid - BLK_SIZE;
    348     }
    349     return;
    350 }
    351 
    352 /*****************************************************************************/
    353 /*                                                                           */
    354 /*  Function Name : impeg2_mc_fullx_halfy_8x8()                                 */
    355 /*                                                                           */
    356 /*  Description   : Gets the buffer from (0,0.5) to (8,8.5)                  */
    357 /*                  and the above block of size 8 x 8 will be placed as a    */
    358 /*                  block from the current position of out_buf               */
    359 /*                                                                           */
    360 /*  Inputs        : ref - Reference frame from which the block will be       */
    361 /*                        block will be extracted.                           */
    362 /*                  ref_wid - WIdth of reference frame                       */
    363 /*                  out_wid - WIdth of the output frame                      */
    364 /*                  blk_width  - width of the block                          */
    365 /*                  blk_width  - height of the block                         */
    366 /*                                                                           */
    367 /*  Globals       : None                                                     */
    368 /*                                                                           */
    369 /*  Processing    : Point to the (0,0) and (0,1)   position in the ref frame */
    370 /*                  Interpolate these two values to get the value at(0,0.5)  */
    371 /*                  Repeat this to get an 8 x 8 block using 8 x 9 block from */
    372 /*                  reference frame                                          */
    373 /*                                                                           */
    374 /*  Outputs       : out -  Output containing the extracted block             */
    375 /*                                                                           */
    376 /*  Returns       : None                                                     */
    377 /*                                                                           */
    378 /*  Issues        : None                                                     */
    379 /*                                                                           */
    380 /*  Revision History:                                                        */
    381 /*                                                                           */
    382 /*         DD MM YYYY   Author(s)       Changes                              */
    383 /*         05 09 2005   Harish M        First Version                        */
    384 /*                                                                           */
    385 /*****************************************************************************/
    386 void impeg2_mc_fullx_halfy_8x8(UWORD8 *pu1_out,
    387                             UWORD8 *pu1_ref,
    388                             UWORD32 u4_ref_wid,
    389                             UWORD32 u4_out_wid)
    390 {
    391 
    392     UWORD8 *pu1_ref_p0, *pu1_ref_p1;
    393     UWORD32 i,j;
    394     /* P0-P3 are the pixels in the reference frame and Q is the value being */
    395     /* estimated                                                            */
    396     /*
    397        P0
    398         x
    399        P1
    400     */
    401     pu1_ref_p0 = pu1_ref;
    402     pu1_ref_p1 = pu1_ref + u4_ref_wid;
    403 
    404     for(i = 0; i < BLK_SIZE; i++)
    405     {
    406         for(j = 0; j < BLK_SIZE; j++)
    407         {
    408             *pu1_out++ =   ((( *pu1_ref_p0++)
    409                         + (*pu1_ref_p1++) + 1 ) >> 1);
    410         }
    411         pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
    412         pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
    413 
    414         pu1_out    += u4_out_wid - BLK_SIZE;
    415     }
    416 
    417     return;
    418 }
    419 
    420 /*****************************************************************************/
    421 /*                                                                           */
    422 /*  Function Name : impeg2_mc_fullx_fully_8x8()                                 */
    423 /*                                                                           */
    424 /*  Description   : Gets the buffer from (x,y) to (x+8,y+8)                  */
    425 /*                  and the above block of size 8 x 8 will be placed as a    */
    426 /*                  block from the current position of out_buf               */
    427 /*                                                                           */
    428 /*  Inputs        : ref - Reference frame from which the block will be       */
    429 /*                        block will be extracted.                           */
    430 /*                  ref_wid - WIdth of reference frame                       */
    431 /*                  out_wid - WIdth of the output frame                      */
    432 /*                  blk_width  - width of the block                          */
    433 /*                  blk_width  - height of the block                         */
    434 /*                                                                           */
    435 /*  Globals       : None                                                     */
    436 /*                                                                           */
    437 /*  Processing    : Point to the (0,0) position in the ref frame             */
    438 /*                  Get an 8 x 8 block from reference frame                  */
    439 /*                                                                           */
    440 /*  Outputs       : out -  Output containing the extracted block             */
    441 /*                                                                           */
    442 /*  Returns       : None                                                     */
    443 /*                                                                           */
    444 /*  Issues        : None                                                     */
    445 /*                                                                           */
    446 /*  Revision History:                                                        */
    447 /*                                                                           */
    448 /*         DD MM YYYY   Author(s)       Changes                              */
    449 /*         05 09 2005   Harish M        First Version                        */
    450 /*                                                                           */
    451 /*****************************************************************************/
    452 void impeg2_mc_fullx_fully_8x8(UWORD8 *pu1_out,
    453                             UWORD8 *pu1_ref,
    454                             UWORD32 u4_ref_wid,
    455                             UWORD32 u4_out_wid)
    456 {
    457 
    458     UWORD32 i;
    459 
    460     for(i = 0; i < BLK_SIZE; i++)
    461     {
    462         memcpy(pu1_out, pu1_ref, BLK_SIZE);
    463         pu1_ref += u4_ref_wid;
    464         pu1_out += u4_out_wid;
    465     }
    466     return;
    467 }
    468