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 *  ih264_chroma_intra_pred_filters.c
     24 *
     25 * @brief
     26 *  Contains function definitions for chroma intra prediction  filters
     27 *
     28 * @author
     29 *  Ittiam
     30 *
     31 * @par List of Functions:
     32 *  -ih264_intra_pred_chroma_8x8_mode_dc
     33 *  -ih264_intra_pred_chroma_8x8_mode_horz
     34 *  -ih264_intra_pred_chroma_8x8_mode_vert
     35 *  -ih264_intra_pred_chroma_8x8_mode_plane
     36 *
     37 * @remarks
     38 *  None
     39 *
     40 *******************************************************************************
     41 */
     42 
     43 /*****************************************************************************/
     44 /* File Includes                                                             */
     45 /*****************************************************************************/
     46 
     47 /* System include files */
     48 #include <stdio.h>
     49 #include <stddef.h>
     50 #include <string.h>
     51 
     52 /* User include files */
     53 #include "ih264_defs.h"
     54 #include "ih264_typedefs.h"
     55 #include "ih264_macros.h"
     56 #include "ih264_platform_macros.h"
     57 #include "ih264_intra_pred_filters.h"
     58 
     59 /* Global variables used only in assembly files*/
     60 const WORD8  ih264_gai1_intrapred_chroma_plane_coeffs1[] =
     61 { 0x01,0x00,0x01,0x00,
     62   0x02,0x00,0x02,0x00,
     63   0x03,0x00,0x03,0x00,
     64   0x04,0x00,0x04,0x00
     65 };
     66  const WORD8  ih264_gai1_intrapred_chroma_plane_coeffs2[] =
     67  { 0xfd,0xff,0xfe,0xff,
     68    0xff,0xff,0x00,0x00,
     69    0x01,0x00,0x02,0x00,
     70    0x03,0x00,0x04,0x00,
     71  };
     72 
     73 /*****************************************************************************/
     74 /* Chroma Intra prediction 8x8 filters                                       */
     75 /*****************************************************************************/
     76 
     77 /**
     78 *******************************************************************************
     79 *
     80 * ih264_intra_pred_chroma_8x8_mode_dc
     81 *
     82 * @brief
     83 *  Perform Intra prediction for  chroma_8x8 mode:DC
     84 *
     85 * @par Description:
     86 *  Perform Intra prediction for  chroma_8x8 mode:DC ,described in sec 8.3.4.1
     87 *
     88 * @param[in] pu1_src
     89 *  UWORD8 pointer to the source containing alternate U and V samples
     90 *
     91 * @param[out] pu1_dst
     92 *  UWORD8 pointer to the destination with alternate U and V samples
     93 *
     94 * @param[in] src_strd
     95 *  integer source stride
     96 *
     97 * @param[in] dst_strd
     98 *  integer destination stride
     99 *
    100 ** @param[in] ngbr_avail
    101 *  availability of neighbouring pixels
    102 *
    103 * @returns
    104 *
    105 * @remarks
    106 *  None
    107 *
    108 ******************************************************************************
    109 */
    110 void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src,
    111                                          UWORD8 *pu1_dst,
    112                                          WORD32 src_strd,
    113                                          WORD32 dst_strd,
    114                                          WORD32 ngbr_avail)
    115 {
    116     WORD32 left_avail, left_avail1, left_avail2; /* availability of left predictors (only for DC) */
    117     WORD32 top_avail; /* availability of top predictors (only for DC) */
    118     UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */
    119     UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */
    120 
    121     /* temporary variables to store accumulated first left half,second left half,
    122      * first top half,second top half of U and  V values*/
    123     WORD32 val_u_l1 = 0, val_u_l2 = 0, val_u_t1 = 0, val_u_t2 = 0;
    124     WORD32 val_v_l1 = 0, val_v_l2 = 0, val_v_t1 = 0, val_v_t2 = 0;
    125 
    126     WORD32 val_u1 = 0, val_u2 = 0, val_v1 = 0, val_v2 = 0;
    127 
    128     WORD32 col, row; /*loop variables*/
    129     UNUSED(src_strd);
    130 
    131     left_avail = ngbr_avail & 0x11;
    132     left_avail1 = ngbr_avail & 1;
    133     left_avail2 = (ngbr_avail >> 4) & 1;
    134     top_avail = (ngbr_avail >> 2) & 1;
    135 
    136     pu1_top = pu1_src + 2 * BLK8x8SIZE + 2;
    137     pu1_left = pu1_src + 2 * BLK8x8SIZE - 2;
    138 
    139     if(left_avail1)
    140     { /* First 4x4 block*/
    141         val_u_l1 += *pu1_left;
    142         val_v_l1 += *(pu1_left + 1);
    143         pu1_left -= 2;
    144         val_u_l1 += *pu1_left;
    145         val_v_l1 += *(pu1_left + 1);
    146         pu1_left -= 2;
    147         val_u_l1 += *pu1_left;
    148         val_v_l1 += *(pu1_left + 1);
    149         pu1_left -= 2;
    150         val_u_l1 += *pu1_left + 2;
    151         val_v_l1 += *(pu1_left + 1) + 2;
    152         pu1_left -= 2;
    153     }
    154     else
    155         pu1_left -= 2 * 4;
    156 
    157     if(left_avail2)
    158     {
    159         /* Second 4x4 block*/
    160         val_u_l2 += *pu1_left;
    161         val_v_l2 += *(pu1_left + 1);
    162         pu1_left -= 2;
    163         val_u_l2 += *pu1_left;
    164         val_v_l2 += *(pu1_left + 1);
    165         pu1_left -= 2;
    166         val_u_l2 += *pu1_left;
    167         val_v_l2 += *(pu1_left + 1);
    168         pu1_left -= 2;
    169         val_u_l2 += *pu1_left + 2;
    170         val_v_l2 += *(pu1_left + 1) + 2;
    171         pu1_left -= 2;
    172     }
    173     else
    174         pu1_left -= 2 * 4;
    175 
    176     if(top_avail)
    177     {
    178         val_u_t1 += *pu1_top + *(pu1_top + 2) + *(pu1_top + 4)
    179                         + *(pu1_top + 6) + 2;
    180         val_u_t2 += *(pu1_top + 8) + *(pu1_top + 10) + *(pu1_top + 12)
    181                         + *(pu1_top + 14) + 2;
    182         val_v_t1 += *(pu1_top + 1) + *(pu1_top + 3) + *(pu1_top + 5)
    183                         + *(pu1_top + 7) + 2;
    184         val_v_t2 += *(pu1_top + 9) + *(pu1_top + 11) + *(pu1_top + 13)
    185                         + *(pu1_top + 15) + 2;
    186     }
    187 
    188     if(left_avail + top_avail)
    189     {
    190         val_u1 = (left_avail1 + top_avail) ?
    191                         ((val_u_l1 + val_u_t1)
    192                                         >> (1 + left_avail1 + top_avail)) :128;
    193         val_v1 = (left_avail1 + top_avail) ?
    194                         ((val_v_l1 + val_v_t1)
    195                                         >> (1 + left_avail1 + top_avail)) :128;
    196         if(top_avail)
    197         {
    198             val_u2 = val_u_t2 >> 2;
    199             val_v2 = val_v_t2 >> 2;
    200         }
    201         else if(left_avail1)
    202         {
    203             val_u2 = val_u_l1 >> 2;
    204             val_v2 = val_v_l1 >> 2;
    205         }
    206         else
    207         {
    208             val_u2 = val_v2 = 128;
    209         }
    210 
    211         for(row = 0; row < 4; row++)
    212         {
    213             /*top left 4x4 block*/
    214             for(col = 0; col < 8; col += 2)
    215             {
    216                 *(pu1_dst + row * dst_strd + col) = val_u1;
    217                 *(pu1_dst + row * dst_strd + col + 1) = val_v1;
    218             }
    219             /*top right 4x4 block*/
    220             for(col = 8; col < 16; col += 2)
    221             {
    222                 *(pu1_dst + row * dst_strd + col) = val_u2;
    223                 *(pu1_dst + row * dst_strd + col + 1) = val_v2;
    224             }
    225         }
    226 
    227         if(left_avail2)
    228         {
    229             val_u1 = val_u_l2 >> 2;
    230             val_v1 = val_v_l2 >> 2;
    231         }
    232         else if(top_avail)
    233         {
    234             val_u1 = val_u_t1 >> 2;
    235             val_v1 = val_v_t1 >> 2;
    236         }
    237         else
    238         {
    239             val_u1 = val_v1 = 128;
    240         }
    241         val_u2 = (left_avail2 + top_avail) ?
    242                         ((val_u_l2 + val_u_t2)
    243                                         >> (1 + left_avail2 + top_avail)) : 128;
    244         val_v2 = (left_avail2 + top_avail) ?
    245                         ((val_v_l2 + val_v_t2)
    246                                         >> (1 + left_avail2 + top_avail)) :  128;
    247 
    248         for(row = 4; row < 8; row++)
    249         { /*bottom left 4x4 block*/
    250             for(col = 0; col < 8; col += 2)
    251             {
    252                 *(pu1_dst + row * dst_strd + col) = val_u1;
    253                 *(pu1_dst + row * dst_strd + col + 1) = val_v1;
    254             }
    255             /*bottom right 4x4 block*/
    256             for(col = 8; col < 16; col += 2)
    257             {
    258                 *(pu1_dst + row * dst_strd + col) = val_u2;
    259                 *(pu1_dst + row * dst_strd + col + 1) = val_v2;
    260             }
    261         }
    262     }
    263     else
    264     {
    265         /* Both left and top are unavailable, set the block to 128 */
    266         for(row = 0; row < 8; row++)
    267         {
    268             memset(pu1_dst + row * dst_strd, 128, 8 * sizeof(UWORD16));
    269         }
    270     }
    271 }
    272 
    273 /**
    274 *******************************************************************************
    275 *
    276 *ih264_intra_pred_chroma_8x8_mode_horz
    277 *
    278 * @brief
    279 *  Perform Intra prediction for  chroma_8x8 mode:Horizontal
    280 *
    281 * @par Description:
    282 *  Perform Intra prediction for  chroma_8x8 mode:Horizontal ,described in sec 8.3.4.2
    283 *
    284 * @param[in] pu1_src
    285 *  UWORD8 pointer to the source containing alternate U and V samples
    286 *
    287 * @param[out] pu1_dst
    288 *  UWORD8 pointer to the destination with alternate U and V samples
    289 *
    290 * @param[in] src_strd
    291 *  integer source stride
    292 *
    293 * @param[in] dst_strd
    294 *  integer destination stride
    295 *
    296 * @param[in] ngbr_avail
    297 * availability of neighbouring pixels(Not used in this function)
    298 *
    299 * @returns
    300 *
    301 * @remarks
    302 *  None
    303 *
    304 ******************************************************************************
    305 */
    306 void ih264_intra_pred_chroma_8x8_mode_horz(UWORD8 *pu1_src,
    307                                            UWORD8 *pu1_dst,
    308                                            WORD32 src_strd,
    309                                            WORD32 dst_strd,
    310                                            WORD32 ngbr_avail)
    311 {
    312 
    313     UWORD8 *pu1_left = NULL; /* Pointer to start of top predictors */
    314     WORD32 rows, cols; /* loop variables*/
    315     UNUSED(src_strd);
    316     UNUSED(ngbr_avail);
    317     pu1_left = pu1_src + 2 * BLK8x8SIZE - 2;
    318     for(rows = 0; rows < 8; rows++)
    319     {
    320         for(cols = 0; cols < 16; cols += 2)
    321         {
    322             *(pu1_dst + rows * dst_strd + cols) = *pu1_left;
    323 
    324             *(pu1_dst + rows * dst_strd + cols + 1) = *(pu1_left + 1);
    325         }
    326         pu1_left -= 2;
    327     }
    328 
    329 }
    330 
    331 /**
    332 *******************************************************************************
    333 *
    334 *ih264_intra_pred_chroma_8x8_mode_vert
    335 *
    336 * @brief
    337 *  Perform Intra prediction for  chroma_8x8 mode:vertical
    338 *
    339 * @par Description:
    340 *  Perform Intra prediction for  chroma_8x8 mode:vertical ,described in sec 8.3.4.3
    341 *
    342 * @param[in] pu1_src
    343 *  UWORD8 pointer to the source containing alternate U and V samples
    344 *
    345 * @param[out] pu1_dst
    346 *  UWORD8 pointer to the destination with alternate U and V samples
    347 *
    348 * @param[in] src_strd
    349 *  integer source stride
    350 *
    351 * @param[in] dst_strd
    352 *  integer destination stride
    353 *
    354 * @param[in] ngbr_avail
    355 * availability of neighbouring pixels(Not used in this function)
    356 *
    357 * @returns
    358 *
    359 * @remarks
    360 *  None
    361 *
    362 *******************************************************************************
    363 */
    364 void ih264_intra_pred_chroma_8x8_mode_vert(UWORD8 *pu1_src,
    365                                            UWORD8 *pu1_dst,
    366                                            WORD32 src_strd,
    367                                            WORD32 dst_strd,
    368                                            WORD32 ngbr_avail)
    369 {
    370 
    371     UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */
    372     WORD32 row;/*loop variable*/
    373     UNUSED(src_strd);
    374     UNUSED(ngbr_avail);
    375     pu1_top = pu1_src + 2 * BLK8x8SIZE + 2;
    376 
    377     /* 8 bytes are copied from src to dst */
    378     for(row = 0; row < 2; row++)
    379     {
    380         memcpy(pu1_dst, pu1_top, 16);
    381 
    382         pu1_dst += dst_strd;
    383         memcpy(pu1_dst, pu1_top, 16);
    384 
    385         pu1_dst += dst_strd;
    386         memcpy(pu1_dst, pu1_top, 16);
    387 
    388         pu1_dst += dst_strd;
    389         memcpy(pu1_dst, pu1_top, 16);
    390 
    391         pu1_dst += dst_strd;
    392     }
    393 }
    394 
    395 /**
    396 *******************************************************************************
    397 *
    398 * ih264_intra_pred_chroma_8x8_mode_plane
    399 *
    400 * @brief
    401 *  Perform Intra prediction for  chroma_8x8 mode:PLANE
    402 *
    403 * @par Description:
    404 *  Perform Intra prediction for  chroma_8x8 mode:PLANE ,described in sec 8.3.4.4
    405 *
    406 * @param[in] pu1_src
    407 *  UWORD8 pointer to the source containing alternate U and V samples
    408 *
    409 * @param[out] pu1_dst
    410 *  UWORD8 pointer to the destination with alternate U and V samples
    411 *
    412 * @param[in] src_strd
    413 *  integer source stride
    414 *
    415 * @param[in] dst_strd
    416 *  integer destination stride
    417 *
    418 * @param[in] ngbr_avail
    419 * availability of neighbouring pixels(Not used in this function)
    420 *
    421 * @returns
    422 *
    423 * @remarks
    424 *  None
    425 *
    426 ******************************************************************************
    427 */
    428 void ih264_intra_pred_chroma_8x8_mode_plane(UWORD8 *pu1_src,
    429                                             UWORD8 *pu1_dst,
    430                                             WORD32 src_strd,
    431                                             WORD32 dst_strd,
    432                                             WORD32 ngbr_avail)
    433 {
    434 
    435     UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */
    436     UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */
    437     WORD32 val = 0;
    438     WORD32 rows, cols; /* loop variables*/
    439     WORD32 a_u, b_u, c_u, h_u, v_u; /* Implementing section 8.3.4.4 . The variables represent the corresponding variables in the section*/
    440     WORD32 a_v, b_v, c_v, h_v, v_v;
    441     UNUSED(src_strd);
    442     UNUSED(ngbr_avail);
    443     a_u = b_u = c_u = h_u = v_u = 0;
    444     a_v = b_v = c_v = h_v = v_v = 0;
    445     /* As chroma format 4:2:0 is used,xCF = 4 * ( chroma_format_idc = = 3 ) = 0 and
    446      yCF = 4 * ( chroma_format_idc != 1  ) = 0   */
    447     pu1_top = pu1_src + 2 * BLK8x8SIZE + 2;
    448     pu1_left = pu1_src + 2 * BLK8x8SIZE - 2;
    449     /* Implementing section 8.3.4.4 */
    450     for(cols = 0; cols < 4; cols++)
    451     {
    452         h_u += (cols + 1) * (pu1_top[8 + 2 * cols] - pu1_top[4 - 2 * cols]);/*section 8.3.4.4   equation (8-144)*/
    453         h_v += (cols + 1) * (pu1_top[8 + 2 * cols + 1] - pu1_top[4 - 2 * cols+ 1]);
    454 
    455         v_u += (cols + 1) * (pu1_left[(4 + cols) * (-2)] - pu1_left[(2 - cols) * (-2)]);
    456         v_v += (cols + 1)  * (pu1_left[(4 + cols) * (-2) + 1]  - pu1_left[(2 - cols) * (-2) + 1]);/*section 8.3.4.4   equation (8-145)*/
    457     }
    458     a_u = 16 * (pu1_left[7 * (-2)] + pu1_top[14]);
    459     a_v = 16 * (pu1_left[7 * (-2) + 1] + pu1_top[15]);/*section 8.3.3.4   equation (8-141)*/
    460     b_u = (34 * h_u + 32) >> 6;/*section 8.3.3.4   equation (8-142)*/
    461     b_v = (34 * h_v + 32) >> 6;/*section 8.3.3.4   equation (8-142)*/
    462     c_u = (34 * v_u + 32) >> 6;/*section 8.3.3.4   equation (8-143)*/
    463     c_v = (34 * v_v + 32) >> 6;/*section 8.3.3.4   equation (8-143)*/
    464 
    465     for(rows = 0; rows < 8; rows++)
    466     {
    467         for(cols = 0; cols < 8; cols++)
    468         {
    469             val = (a_u + b_u * (cols - 3) + c_u * (rows - 3) );/*section 8.3.4.4   equation (8-140)*/
    470             val = (val + 16) >> 5;
    471             *(pu1_dst + rows * dst_strd + 2 * cols) = CLIP_U8(val);
    472             val = (a_v + b_v * (cols - 3) + c_v * (rows - 3) );/*section 8.3.4.4   equation (8-140)*/
    473             val = (val + 16) >> 5;
    474             *(pu1_dst + rows * dst_strd + 2 * cols + 1) = CLIP_U8(val);
    475         }
    476     }
    477 }
    478 
    479