Home | History | Annotate | Download | only in common
      1 /******************************************************************************
      2 *
      3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      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 /**
     19 *******************************************************************************
     20 * @file
     21 *  ihevc_chroma_intra_pred_filters.c
     22 *
     23 * @brief
     24 *  Contains function Definition for intra prediction  interpolation filters
     25 *
     26 *
     27 * @author
     28 *  Ittiam
     29 *
     30 * @par List of Functions:
     31 *  ihevc_intra_pred_chroma_planar()
     32 *
     33 *  ihevc_intra_pred_chroma_dc()
     34 *
     35 *  ihevc_intra_pred_chroma_horz()
     36 *
     37 *  ihevc_intra_pred_chroma_ver()
     38 *
     39 *  ihevc_intra_pred_chroma_mode2()
     40 *
     41 *  ihevc_intra_pred_chroma_mode_18_34()
     42 *
     43 *  ihevc_intra_pred_chroma_mode_3_to_9()
     44 *
     45 *  ihevc_intra_pred_chroma_mode_11_to_17()
     46 *
     47 *  ihevc_intra_pred_chroma_mode_19_to_25()
     48 *
     49 *  ihevc_intra_pred_chroma_mode_27_to_33()
     50 *
     51 *  ihevc_intra_pred_chroma_ref_substitution()
     52 *
     53 *
     54 * @remarks
     55 *  None
     56 *
     57 *******************************************************************************
     58 */
     59 
     60 
     61 /*****************************************************************************/
     62 /* File Includes                                                             */
     63 /*****************************************************************************/
     64 
     65 #include "ihevc_typedefs.h"
     66 #include "ihevc_macros.h"
     67 #include "ihevc_func_selector.h"
     68 #include "ihevc_platform_macros.h"
     69 #include "ihevc_intra_pred.h"
     70 #include "ihevc_mem_fns.h"
     71 #include "ihevc_chroma_intra_pred.h"
     72 #include "ihevc_common_tables.h"
     73 
     74 
     75 /****************************************************************************/
     76 /* Constant Macros                                                          */
     77 /****************************************************************************/
     78 #define MAX_CU_SIZE 64
     79 #define BIT_DEPTH 8
     80 #define T32_4NT 128
     81 #define T16_4NT 64
     82 #define T16C_4NT 64
     83 #define T8C_4NT 32
     84 /****************************************************************************/
     85 /* Function Macros                                                          */
     86 /****************************************************************************/
     87 
     88 #define GET_BIT(y,x) ((y) & (1 << x)) && (1 << x)
     89 
     90 
     91 /*****************************************************************************/
     92 /* Function Definition                                                      */
     93 /*****************************************************************************/
     94 
     95 /**
     96 *******************************************************************************
     97 *
     98 * @brief
     99 *  Reference substitution process for samples unavailable  for prediction
    100 * Refer to section 8.4.4.2.2
    101 *
    102 * @par Description:
    103 *
    104 *
    105 * @param[in] pu1_top_left
    106 *  UWORD8 pointer to the top-left
    107 *
    108 * @param[in] pu1_top
    109 *  UWORD8 pointer to the top
    110 *
    111 * @param[in] pu1_left
    112 *  UWORD8 pointer to the left
    113 *
    114 * @param[in] src_strd
    115 *  WORD32 Source stride
    116 *
    117 * @param[in] nbr_flags
    118 *  WORD32 neighbor availability flags
    119 *
    120 * @param[in] nt
    121 *  WORD32 transform Block size
    122 *
    123 * @param[in] dst_strd
    124 *  WORD32 Destination stride
    125 *
    126 * @returns
    127 *
    128 * @remarks
    129 *  None
    130 *
    131 *******************************************************************************
    132 */
    133 
    134 
    135 void ihevc_intra_pred_chroma_ref_substitution(UWORD8 *pu1_top_left,
    136                                               UWORD8 *pu1_top,
    137                                               UWORD8 *pu1_left,
    138                                               WORD32 src_strd,
    139                                               WORD32 nt,
    140                                               WORD32 nbr_flags,
    141                                               UWORD8 *pu1_dst,
    142                                               WORD32 dst_strd)
    143 {
    144     UWORD8 pu1_ref_u, pu1_ref_v;
    145     WORD32 dc_val, i, j;
    146     WORD32 total_samples = (4 * nt) + 1;
    147     WORD32 get_bits;
    148     WORD32 next;
    149     WORD32 bot_left, left, top, tp_right, tp_left;
    150     WORD32 idx, nbr_id_from_bl, frwd_nbr_flag;
    151     WORD32 a_nbr_flag[5];
    152     UNUSED(dst_strd);
    153     /* Neighbor Flag Structure*/
    154     /* WORD32 nbr_flags MSB-->LSB   TOP LEFT | TOP-RIGHT |  TOP   | LEFT    | BOTTOM LEFT*/
    155     /*                              (1 bit)     (4 bits)  (4 bits) (4 bits)  (4 bits)  */
    156 
    157     if(nbr_flags == 0)
    158     {
    159 /* If no neighbor flags are present, fill the neighbor samples with DC value */
    160         /*dc_val = 1 << (BIT_DEPTH - 1);*/
    161         dc_val = 1 << (8 - 1);
    162         for(i = 0; i < (2 * total_samples); i++)
    163         {
    164             pu1_dst[i] = dc_val;
    165         }
    166     }
    167     else
    168     {
    169         /* Else fill the corresponding samples */
    170 
    171         /* Check for the neighbors availibility */
    172         tp_left     = (nbr_flags & 0x10000);
    173         tp_right    = (nbr_flags & 0x0f000);
    174         top         = (nbr_flags & 0x00f00);
    175         left        = (nbr_flags & 0x000f0);
    176         bot_left    = (nbr_flags & 0x0000f);
    177 
    178         /* Fill nbrs depending on avalibility */
    179         /* Top -Left nbrs  */
    180         if(0 != tp_left)
    181         {
    182             pu1_dst[(4 * nt)] = *pu1_top_left; // U top-left sample
    183             pu1_dst[(4 * nt) + 1] = *(pu1_top_left + 1); // V top-left sample
    184         }
    185         /* Left nbrs  */
    186         if(0 != left)
    187         {
    188             for(i = 0, j = 0; i < (2 * nt); i += 2)
    189             {
    190                 pu1_dst[(4 * nt) - 2 - i] = pu1_left[j * src_strd]; // U left samples
    191                 pu1_dst[(4 * nt) - 1 - i] = pu1_left[(j * src_strd) + 1]; // V left samples
    192                 j++;
    193             }
    194         }
    195         /* Bottom - Left nbrs  */
    196         if(0 != bot_left)
    197         {
    198             for(i = (2 * nt), j = nt; i < (4 * nt); i += 2)
    199             {
    200                 pu1_dst[(4 * nt) - 2 - i] = pu1_left[j * src_strd]; // U left samples
    201                 pu1_dst[(4 * nt) - 1 - i] = pu1_left[(j * src_strd) + 1]; // V left samples
    202                 j++;
    203             }
    204         }
    205         /* Top nbrs  */
    206         if(0 != top)
    207         {
    208             ihevc_memcpy_mul_8(&pu1_dst[(4 * nt) + 2], pu1_top, 2 * nt);
    209             // U-V interleaved Top-top right samples
    210         }
    211 
    212         /* Top - Right nbrs  */
    213         if(0 != tp_right)
    214         {
    215             ihevc_memcpy_mul_8(&pu1_dst[(4 * nt) + 2 + 2 * nt], pu1_top + 2 * nt, 2 * nt);
    216             // U-V interleaved Top-top right samples
    217         }
    218 
    219         if(nt == 4)
    220         {
    221             /* 1 bit extraction for all the neighboring blocks */
    222             tp_left = (nbr_flags & 0x10000) >> 16;
    223             bot_left = (nbr_flags & 0x8) >> 3;
    224             left = (nbr_flags & 0x80) >> 7;
    225             top = (nbr_flags & 0x100) >> 8;
    226             tp_right = (nbr_flags & 0x1000) >> 12;
    227 
    228             next = 1;
    229             a_nbr_flag[0] = bot_left;
    230             a_nbr_flag[1] = left;
    231             a_nbr_flag[2] = tp_left;
    232             a_nbr_flag[3] = top;
    233             a_nbr_flag[4] = tp_right;
    234 
    235             /* If bottom -left is not available, reverse substitution process*/
    236             if(bot_left == 0)
    237             {
    238                 /* Check for the 1st available sample from bottom-left*/
    239                 while(!a_nbr_flag[next])
    240                     next++;
    241 
    242                 /* If Left, top-left are available*/
    243                 if(next <= 2)
    244                 {
    245                     UWORD16 *pu2_dst;
    246                     idx = (nt * next);
    247                     pu2_dst = (UWORD16 *)&pu1_dst[2 * idx];
    248                     ihevc_memset_16bit((UWORD16 *)pu1_dst, pu2_dst[0], idx);
    249                 }
    250                 else /* If top, top-right are available */
    251                 {
    252                     UWORD16 *pu2_dst;
    253                     /* Idx is changed to copy 1 pixel value for top-left ,if top-left is not available*/
    254                     idx = (nt * (next - 1)) + 1;
    255                     pu2_dst = (UWORD16 *)&pu1_dst[2 * idx];
    256                     ihevc_memset_16bit((UWORD16 *)pu1_dst, pu2_dst[0], idx);
    257                 }
    258             }
    259 
    260             if(left == 0)
    261             {
    262                 UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(2 * nt) - 2];
    263                 ihevc_memset_16bit((UWORD16 *)&pu1_dst[(2 * nt)], pu2_dst[0], nt);
    264 
    265 
    266             }
    267             if(tp_left == 0)
    268             {
    269                 pu1_dst[4 * nt] = pu1_dst[(4 * nt) - 2];
    270                 pu1_dst[(4 * nt) + 1] = pu1_dst[(4 * nt) - 1];
    271             }
    272             if(top == 0)
    273             {
    274                 UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(4 * nt)];
    275                 ihevc_memset_16bit((UWORD16 *)&pu1_dst[(4 * nt) + 2], pu2_dst[0], nt);
    276 
    277 
    278             }
    279             if(tp_right == 0)
    280             {
    281                 UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(6 * nt)];
    282                 ihevc_memset_16bit((UWORD16 *)&pu1_dst[(6 * nt) + 2], pu2_dst[0], nt);
    283 
    284 
    285             }
    286         }
    287         else if(nt == 8)
    288         {
    289             WORD32 nbr_flags_temp = 0;
    290             nbr_flags_temp = ((nbr_flags & 0xC) >> 2) + ((nbr_flags & 0xC0) >> 4)
    291                             + ((nbr_flags & 0x300) >> 4)
    292                             + ((nbr_flags & 0x3000) >> 6)
    293                             + ((nbr_flags & 0x10000) >> 8);
    294 
    295             /* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/
    296             /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
    297             {
    298                 nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 4; /* for bottom left and left */
    299                 if(nbr_id_from_bl == 32)
    300                     nbr_id_from_bl = 16;
    301                 if(nbr_id_from_bl == 16)
    302                 {
    303                     /* for top left : 1 pel per nbr bit */
    304                     if(!((nbr_flags_temp >> 8) & 0x1))
    305                     {
    306                         nbr_id_from_bl++;
    307                         nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 4; /* top and top right;  8 pels per nbr bit */
    308 
    309                     }
    310                 }
    311                 /* Reverse Substitution Process*/
    312                 if(nbr_id_from_bl)
    313                 {
    314                     /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
    315                     pu1_ref_u = pu1_dst[2 * nbr_id_from_bl];
    316                     pu1_ref_v = pu1_dst[(2 * nbr_id_from_bl) + 1];
    317                     for(i = 2 * (nbr_id_from_bl - 1); i >= 0; i -= 2)
    318                     {
    319                         pu1_dst[i] = pu1_ref_u;
    320                         pu1_dst[i + 1] = pu1_ref_v;
    321                     }
    322                 }
    323             }
    324 
    325             /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
    326             while(nbr_id_from_bl < ((T8C_4NT)+1))
    327             {
    328                 /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
    329                 /* Divide by 8 to obtain the original index */
    330                 frwd_nbr_flag = (nbr_id_from_bl >> 2); /*+ (nbr_id_from_bl & 0x1);*/
    331 
    332                 /* The Top-left flag is at the last bit location of nbr_flags*/
    333                 if(nbr_id_from_bl == (T8C_4NT / 2))
    334                 {
    335                     get_bits = GET_BIT(nbr_flags_temp, 8);
    336 
    337                     /* only pel substitution for TL */
    338                     if(!get_bits)
    339                     {
    340                         pu1_dst[2 * nbr_id_from_bl] = pu1_dst[(2 * nbr_id_from_bl) - 2];
    341                         pu1_dst[(2 * nbr_id_from_bl) + 1] = pu1_dst[(2 * nbr_id_from_bl) - 1];
    342                     }
    343                 }
    344                 else
    345                 {
    346                     get_bits = GET_BIT(nbr_flags_temp, frwd_nbr_flag);
    347                     if(!get_bits)
    348                     {
    349                         UWORD16 *pu2_dst;
    350                         /* 8 pel substitution (other than TL) */
    351                         pu2_dst = (UWORD16 *)&pu1_dst[(2 * nbr_id_from_bl) - 2];
    352                         ihevc_memset_16bit((UWORD16 *)(pu1_dst + (2 * nbr_id_from_bl)), pu2_dst[0], 4);
    353                     }
    354 
    355                 }
    356                 nbr_id_from_bl += (nbr_id_from_bl == (T8C_4NT / 2)) ? 1 : 4;
    357             }
    358 
    359         }
    360         else if(nt == 16)
    361         {
    362             /* compute trailing ones based on mbr_flag for substitution process of below left see section .*/
    363             /* as each bit in nbr flags corresponds to 4 pels for bot_left, left, top and topright but 1 pel for topleft */
    364             {
    365                 nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 4; /* for bottom left and left */
    366 
    367                 if(nbr_id_from_bl == 32)
    368                 {
    369                     /* for top left : 1 pel per nbr bit */
    370                     if(!((nbr_flags >> 16) & 0x1))
    371                     {
    372                         /* top left not available */
    373                         nbr_id_from_bl++;
    374                         /* top and top right;  4 pels per nbr bit */
    375                         nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 4;
    376                     }
    377                 }
    378                 /* Reverse Substitution Process*/
    379                 if(nbr_id_from_bl)
    380                 {
    381                     /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
    382                     pu1_ref_u = pu1_dst[2 * nbr_id_from_bl];
    383                     pu1_ref_v = pu1_dst[2 * nbr_id_from_bl + 1];
    384                     for(i = (2 * (nbr_id_from_bl - 1)); i >= 0; i -= 2)
    385                     {
    386                         pu1_dst[i] = pu1_ref_u;
    387                         pu1_dst[i + 1] = pu1_ref_v;
    388                     }
    389                 }
    390             }
    391 
    392             /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
    393             while(nbr_id_from_bl < ((T16C_4NT)+1))
    394             {
    395                 /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
    396                 /* Devide by 4 to obtain the original index */
    397                 frwd_nbr_flag = (nbr_id_from_bl >> 2); /*+ (nbr_id_from_bl & 0x1);*/
    398 
    399                 /* The Top-left flag is at the last bit location of nbr_flags*/
    400                 if(nbr_id_from_bl == (T16C_4NT / 2))
    401                 {
    402                     get_bits = GET_BIT(nbr_flags, 16);
    403                     /* only pel substitution for TL */
    404                     if(!get_bits)
    405                     {
    406                         pu1_dst[2 * nbr_id_from_bl] = pu1_dst[(2 * nbr_id_from_bl) - 2];
    407                         pu1_dst[(2 * nbr_id_from_bl) + 1] = pu1_dst[(2 * nbr_id_from_bl) - 1];
    408                     }
    409                 }
    410                 else
    411                 {
    412                     get_bits = GET_BIT(nbr_flags, frwd_nbr_flag);
    413                     if(!get_bits)
    414                     {
    415                         UWORD16 *pu2_dst;
    416                         /* 4 pel substitution (other than TL) */
    417                         pu2_dst = (UWORD16 *)&pu1_dst[(2 * nbr_id_from_bl) - 2];
    418                         ihevc_memset_16bit((UWORD16 *)(pu1_dst + (2 * nbr_id_from_bl)), pu2_dst[0], 4);
    419                     }
    420 
    421                 }
    422                 nbr_id_from_bl += (nbr_id_from_bl == (T16C_4NT / 2)) ? 1 : 4;
    423             }
    424         }
    425     }
    426 }
    427 
    428 
    429 /**
    430 *******************************************************************************
    431 *
    432 * @brief
    433 *  Planar Intraprediction with reference neighboring samples location
    434 * pointed by 'pu1_ref' to the TU block location  pointed by 'pu1_dst'  Refer
    435 * to section 8.4.4.2.4 in the standard
    436 *
    437 * @par Description:
    438 *
    439 *
    440 * @param[in] pu1_src
    441 *  UWORD8 pointer to the source
    442 *
    443 * @param[in] pu1_dst
    444 *  UWORD8 pointer to the destination
    445 *
    446 * @param[in] src_strd
    447 *  integer source stride
    448 *
    449 * @param[in] dst_strd
    450 *  integer destination stride
    451 *
    452 * @param[in] nt
    453 *  integer Transform Block size
    454 *
    455 * @param[in] mode
    456 *  integer intraprediction mode
    457 *
    458 * @returns
    459 *
    460 * @remarks
    461 *  None
    462 *
    463 *******************************************************************************
    464 */
    465 
    466 
    467 void ihevc_intra_pred_chroma_planar(UWORD8 *pu1_ref,
    468                                     WORD32 src_strd,
    469                                     UWORD8 *pu1_dst,
    470                                     WORD32 dst_strd,
    471                                     WORD32 nt,
    472                                     WORD32 mode)
    473 {
    474 
    475     WORD32 row, col;
    476     WORD32 log2nt = 5;
    477     WORD32 two_nt, three_nt;
    478     UNUSED(src_strd);
    479     UNUSED(mode);
    480     switch(nt)
    481     {
    482         case 16:
    483             log2nt = 4;
    484             break;
    485         case 8:
    486             log2nt = 3;
    487             break;
    488         case 4:
    489             log2nt = 2;
    490             break;
    491         default:
    492             break;
    493     }
    494     two_nt = 2 * nt;
    495     three_nt = 3 * nt;
    496     /* Planar filtering */
    497     for(row = 0; row < nt; row++)
    498     {
    499         for(col = 0; col < (2 * nt); col += 2)
    500         {
    501             pu1_dst[row * dst_strd + col] = ((nt - 1 - col / 2)
    502                             * pu1_ref[2 * (two_nt - 1 - row)]
    503                             + (col / 2 + 1) * pu1_ref[2 * (three_nt + 1)]
    504                             + (nt - 1 - row) * pu1_ref[2 * (two_nt + 1) + col]
    505                             + (row + 1) * pu1_ref[2 * (nt - 1)] + nt) >> (log2nt + 1);
    506 
    507             pu1_dst[row * dst_strd + col + 1] = ((nt - 1 - col / 2)
    508                             * pu1_ref[2 * (two_nt - 1 - row) + 1]
    509                             + (col / 2 + 1) * pu1_ref[2 * (three_nt + 1) + 1]
    510                             + (nt - 1 - row) * pu1_ref[2 * (two_nt + 1) + col + 1]
    511                             + (row + 1) * pu1_ref[2 * (nt - 1) + 1] + nt) >> (log2nt + 1);
    512         }
    513     }
    514 }
    515 
    516 
    517 /**
    518 *******************************************************************************
    519 *
    520 * @brief
    521 *  Intraprediction for DC mode with reference neighboring  samples location
    522 * pointed by 'pu1_ref' to the TU block  location pointed by 'pu1_dst'  Refer
    523 * to section 8.4.4.2.5 in the standard
    524 *
    525 * @par Description:
    526 *
    527 *
    528 * @param[in] pu1_src
    529 *  UWORD8 pointer to the source
    530 *
    531 * @param[in] pu1_dst
    532 *  UWORD8 pointer to the destination
    533 *
    534 * @param[in] src_strd
    535 *  integer source stride
    536 *
    537 * @param[in] dst_strd
    538 *  integer destination stride
    539 *
    540 * @param[in] nt
    541 *  integer Transform Block size (Chroma)
    542 *
    543 * @param[in] mode
    544 *  integer intraprediction mode
    545 *
    546 * @returns
    547 *
    548 * @remarks
    549 *  None
    550 *
    551 *******************************************************************************
    552 */
    553 
    554 
    555 void ihevc_intra_pred_chroma_dc(UWORD8 *pu1_ref,
    556                                 WORD32 src_strd,
    557                                 UWORD8 *pu1_dst,
    558                                 WORD32 dst_strd,
    559                                 WORD32 nt,
    560                                 WORD32 mode)
    561 {
    562 
    563     WORD32 acc_dc_u, acc_dc_v;
    564     WORD32 dc_val_u, dc_val_v;
    565     WORD32 i;
    566     WORD32 row, col;
    567     WORD32 log2nt = 5;
    568     UNUSED(mode);
    569     UNUSED(src_strd);
    570     switch(nt)
    571     {
    572         case 32:
    573             log2nt = 5;
    574             break;
    575         case 16:
    576             log2nt = 4;
    577             break;
    578         case 8:
    579             log2nt = 3;
    580             break;
    581         case 4:
    582             log2nt = 2;
    583             break;
    584         default:
    585             break;
    586     }
    587 
    588 
    589     acc_dc_u = 0;
    590     acc_dc_v = 0;
    591     /* Calculate DC value for the transform block */
    592     for(i = (2 * nt); i < (4 * nt); i += 2)
    593     {
    594         acc_dc_u += pu1_ref[i];
    595         acc_dc_v += pu1_ref[i + 1];
    596     }
    597     for(i = ((4 * nt) + 2); i < ((6 * nt) + 2); i += 2)
    598     {
    599         acc_dc_u += pu1_ref[i];
    600         acc_dc_v += pu1_ref[i + 1];
    601     }
    602 
    603 
    604     dc_val_u = (acc_dc_u + nt) >> (log2nt + 1);
    605     dc_val_v = (acc_dc_v + nt) >> (log2nt + 1);
    606 
    607 
    608     /* Fill the remaining rows with DC value*/
    609     for(row = 0; row < nt; row++)
    610     {
    611         for(col = 0; col < (2 * nt); col += 2)
    612         {
    613             pu1_dst[(row * dst_strd) + col] = dc_val_u;
    614             pu1_dst[(row * dst_strd) + col + 1] = dc_val_v;
    615         }
    616     }
    617 
    618 }
    619 
    620 
    621 /**
    622 *******************************************************************************
    623 *
    624 * @brief
    625 *  Horizontal intraprediction(mode 10) with reference  samples location
    626 * pointed by 'pu1_ref' to the TU block  location pointed by 'pu1_dst'  Refer
    627 * to section 8.4.4.2.6 in the standard (Special case)
    628 *
    629 * @par Description:
    630 *
    631 *
    632 * @param[in] pu1_src
    633 *  UWORD8 pointer to the source
    634 *
    635 * @param[in] pu1_dst
    636 *  UWORD8 pointer to the destination
    637 *
    638 * @param[in] src_strd
    639 *  integer source stride
    640 *
    641 * @param[in] dst_strd
    642 *  integer destination stride
    643 *
    644 * @param[in] nt
    645 *  integer Transform Block size
    646 *
    647 * @param[in] mode
    648 *  integer intraprediction mode
    649 *
    650 * @returns
    651 *
    652 * @remarks
    653 *  None
    654 *
    655 *******************************************************************************
    656 */
    657 
    658 
    659 void ihevc_intra_pred_chroma_horz(UWORD8 *pu1_ref,
    660                                   WORD32 src_strd,
    661                                   UWORD8 *pu1_dst,
    662                                   WORD32 dst_strd,
    663                                   WORD32 nt,
    664                                   WORD32 mode)
    665 {
    666 
    667     WORD32 row, col;
    668     UNUSED(mode);
    669     UNUSED(src_strd);
    670     /* Replication to next rows*/
    671     for(row = 0; row < nt; row++)
    672     {
    673         for(col = 0; col < (2 * nt); col += 2)
    674         {
    675             pu1_dst[(row * dst_strd) + col] = pu1_ref[(4 * nt) - 2 - 2 * row];
    676             pu1_dst[(row * dst_strd) + col + 1] = pu1_ref[(4 * nt) - 1 - 2 * row];
    677         }
    678     }
    679 }
    680 
    681 
    682 
    683 /**
    684 *******************************************************************************
    685 *
    686 * @brief
    687 *  Horizontal intraprediction with reference neighboring  samples location
    688 * pointed by 'pu1_ref' to the TU block  location pointed by 'pu1_dst'  Refer
    689 * to section 8.4.4.2.6 in the standard (Special case)
    690 *
    691 * @par Description:
    692 *
    693 *
    694 * @param[in] pu1_src
    695 *  UWORD8 pointer to the source
    696 *
    697 * @param[in] pu1_dst
    698 *  UWORD8 pointer to the destination
    699 *
    700 * @param[in] src_strd
    701 *  integer source stride
    702 *
    703 * @param[in] dst_strd
    704 *  integer destination stride
    705 *
    706 * @param[in] nt
    707 *  integer Transform Block size
    708 *
    709 * @param[in] mode
    710 *  integer intraprediction mode
    711 *
    712 * @returns
    713 *
    714 * @remarks
    715 *  None
    716 *
    717 *******************************************************************************
    718 */
    719 
    720 
    721 void ihevc_intra_pred_chroma_ver(UWORD8 *pu1_ref,
    722                                  WORD32 src_strd,
    723                                  UWORD8 *pu1_dst,
    724                                  WORD32 dst_strd,
    725                                  WORD32 nt,
    726                                  WORD32 mode)
    727 {
    728     WORD32 row, col;
    729     UNUSED(mode);
    730     UNUSED(src_strd);
    731     /* Replication to next columns*/
    732     for(row = 0; row < nt; row++)
    733     {
    734         for(col = 0; col < (2 * nt); col += 2)
    735         {
    736             pu1_dst[(row * dst_strd) + col] = pu1_ref[(4 * nt) + 2 + col];
    737             pu1_dst[(row * dst_strd) + col + 1] = pu1_ref[(4 * nt) + 3 + col];
    738         }
    739     }
    740 }
    741 
    742 
    743 /**
    744 *******************************************************************************
    745 *
    746 * @brief
    747 *  Intraprediction for mode 2 (sw angle) with reference  neighboring samples
    748 * location pointed by 'pu1_ref' to the  TU block location pointed by
    749 * 'pu1_dst'  Refer to section 8.4.4.2.6 in the standard
    750 *
    751 * @par Description:
    752 *
    753 *
    754 * @param[in] pu1_src
    755 *  UWORD8 pointer to the source
    756 *
    757 * @param[in] pu1_dst
    758 *  UWORD8 pointer to the destination
    759 *
    760 * @param[in] src_strd
    761 *  integer source stride
    762 *
    763 * @param[in] dst_strd
    764 *  integer destination stride
    765 *
    766 * @param[in] nt
    767 *  integer Transform Block size
    768 *
    769 * @param[in] mode
    770 *  integer intraprediction mode
    771 *
    772 * @returns
    773 *
    774 * @remarks
    775 *  None
    776 *
    777 *******************************************************************************
    778 */
    779 
    780 
    781 void ihevc_intra_pred_chroma_mode2(UWORD8 *pu1_ref,
    782                                    WORD32 src_strd,
    783                                    UWORD8 *pu1_dst,
    784                                    WORD32 dst_strd,
    785                                    WORD32 nt,
    786                                    WORD32 mode)
    787 {
    788     WORD32 row, col;
    789 
    790     WORD32 intra_pred_ang = 32;
    791     WORD32 idx_u, idx_v;
    792     UNUSED(src_strd);
    793     UNUSED(mode);
    794     /* For the angle 45, replication is done from the corresponding angle */
    795     /* intra_pred_ang = tan(angle) in q5 format */
    796     for(col = 0; col < (2 * nt); col += 2)
    797     {
    798         idx_u = ((col + 1) * intra_pred_ang) >> 5; /* Use idx++ */
    799         idx_v = (((col + 1) + 1) * intra_pred_ang) >> 5; /* Use idx++ */
    800         for(row = 0; row < nt; row++)
    801         {
    802             pu1_dst[col + (row * dst_strd)] = pu1_ref[(4 * nt) - 2 * row - idx_u - 3];
    803             pu1_dst[(col + 1) + (row * dst_strd)] = pu1_ref[(4 * nt) - 2 * row - idx_v - 1];
    804         }
    805     }
    806 
    807 }
    808 
    809 
    810 /**
    811 *******************************************************************************
    812 *
    813 * @brief
    814 *  Intraprediction for mode 34 (ne angle) and  mode 18 (nw angle) with
    815 * reference  neighboring samples location pointed by 'pu1_ref' to the  TU
    816 * block location pointed by 'pu1_dst'
    817 *
    818 * @par Description:
    819 *
    820 *
    821 * @param[in] pu1_src
    822 *  UWORD8 pointer to the source
    823 *
    824 * @param[in] pu1_dst
    825 *  UWORD8 pointer to the destination
    826 *
    827 * @param[in] src_strd
    828 *  integer source stride
    829 *
    830 * @param[in] dst_strd
    831 *  integer destination stride
    832 *
    833 * @param[in] nt
    834 *  integer Transform Block size
    835 *
    836 * @param[in] mode
    837 *  integer intraprediction mode
    838 *
    839 * @returns
    840 *
    841 * @remarks
    842 *  None
    843 *
    844 *******************************************************************************
    845 */
    846 
    847 
    848 void ihevc_intra_pred_chroma_mode_18_34(UWORD8 *pu1_ref,
    849                                         WORD32 src_strd,
    850                                         UWORD8 *pu1_dst,
    851                                         WORD32 dst_strd,
    852                                         WORD32 nt,
    853                                         WORD32 mode)
    854 {
    855     WORD32 row, col;
    856     WORD32 intra_pred_ang;
    857     WORD32 idx = 0;
    858     UNUSED(src_strd);
    859     intra_pred_ang = 32; /*Default value*/
    860     /* For mode 18, angle is -45degree */
    861     if(mode == 18)
    862         intra_pred_ang = -32;
    863     /* For mode 34, angle is 45degree */
    864     else if(mode == 34)
    865         intra_pred_ang = 32;
    866     /* For the angle 45 and -45, replication is done from the corresponding angle */
    867     /* No interpolation is done for 45 degree*/
    868     for(row = 0; row < nt; row++)
    869     {
    870         idx = ((row + 1) * intra_pred_ang) >> 5;
    871 
    872         for(col = 0; col < (2 * nt); col += 2)
    873         {
    874             pu1_dst[col + (row * dst_strd)] = pu1_ref[(4 * nt) + col + 2 * idx + 2];
    875             pu1_dst[(col + 1) + (row * dst_strd)] = pu1_ref[(4 * nt) + (col + 1) + 2 * idx + 2];
    876         }
    877 
    878     }
    879 
    880 }
    881 
    882 
    883 /**
    884 *******************************************************************************
    885 *
    886 * @brief
    887 *  Intraprediction for mode 3 to 9  (positive angle, horizontal mode ) with
    888 * reference  neighboring samples location pointed by 'pu1_ref' to the  TU
    889 * block location pointed by 'pu1_dst'
    890 *
    891 * @par Description:
    892 *
    893 *
    894 * @param[in] pu1_src
    895 *  UWORD8 pointer to the source
    896 *
    897 * @param[in] pu1_dst
    898 *  UWORD8 pointer to the destination
    899 *
    900 * @param[in] src_strd
    901 *  integer source stride
    902 *
    903 * @param[in] dst_strd
    904 *  integer destination stride
    905 *
    906 * @param[in] nt
    907 *  integer Transform Block size
    908 *
    909 * @param[in] mode
    910 *  integer intraprediction mode
    911 *
    912 * @returns
    913 *
    914 * @remarks
    915 *  None
    916 *
    917 *******************************************************************************
    918 */
    919 
    920 
    921 void ihevc_intra_pred_chroma_mode_3_to_9(UWORD8 *pu1_ref,
    922                                          WORD32 src_strd,
    923                                          UWORD8 *pu1_dst,
    924                                          WORD32 dst_strd,
    925                                          WORD32 nt,
    926                                          WORD32 mode)
    927 {
    928     WORD32 row, col;
    929 
    930     WORD32 intra_pred_ang;
    931     WORD32 idx_u, ref_main_idx_u;
    932     WORD32 idx_v, ref_main_idx_v;
    933     WORD32 pos_u, fract_u;
    934     WORD32 pos_v, fract_v;
    935     UNUSED(src_strd);
    936     /* Intra Pred Angle according to the mode */
    937     intra_pred_ang = gai4_ihevc_ang_table[mode];
    938 
    939     /* For the angles other then 45 degree, interpolation btw 2 neighboring */
    940     /* samples dependent on distance to obtain destination sample */
    941 
    942     for(col = 0; col < (2 * nt); col += 2)
    943     {
    944         pos_u = ((col / 2 + 1) * intra_pred_ang);
    945         pos_v = ((col / 2 + 1) * intra_pred_ang);
    946 
    947         idx_u = pos_u >> 5;
    948         fract_u = pos_u & (31);
    949 
    950         idx_v = pos_v >> 5;
    951         fract_v = pos_v & (31);
    952         // Do linear filtering
    953         for(row = 0; row < nt; row++)
    954         {
    955             ref_main_idx_u = (4 * nt) - 2 * row - 2 * idx_u - 2;
    956             ref_main_idx_v = (4 * nt) - 2 * row - 2 * idx_v - 1;
    957 
    958             pu1_dst[col + (row * dst_strd)] = (((32 - fract_u)
    959                             * pu1_ref[ref_main_idx_u]
    960                             + fract_u * pu1_ref[ref_main_idx_u - 2] + 16) >> 5);
    961 
    962             pu1_dst[(col + 1) + (row * dst_strd)] = (((32 - fract_v)
    963                             * pu1_ref[ref_main_idx_v]
    964                             + fract_v * pu1_ref[ref_main_idx_v - 2] + 16) >> 5);
    965         }
    966 
    967     }
    968 
    969 }
    970 
    971 
    972 /**
    973 *******************************************************************************
    974 *
    975 * @brief
    976 *  Intraprediction for mode 11 to 17  (negative angle, horizontal mode )
    977 * with reference  neighboring samples location pointed by 'pu1_ref' to the
    978 * TU block location pointed by 'pu1_dst'
    979 *
    980 * @par Description:
    981 *
    982 *
    983 * @param[in] pu1_src
    984 *  UWORD8 pointer to the source
    985 *
    986 * @param[in] pu1_dst
    987 *  UWORD8 pointer to the destination
    988 *
    989 * @param[in] src_strd
    990 *  integer source stride
    991 *
    992 * @param[in] dst_strd
    993 *  integer destination stride
    994 *
    995 * @param[in] nt
    996 *  integer Transform Block size
    997 *
    998 * @param[in] mode
    999 *  integer intraprediction mode
   1000 *
   1001 * @returns
   1002 *
   1003 * @remarks
   1004 *  None
   1005 *
   1006 *******************************************************************************
   1007 */
   1008 
   1009 
   1010 void ihevc_intra_pred_chroma_mode_11_to_17(UWORD8 *pu1_ref,
   1011                                            WORD32 src_strd,
   1012                                            UWORD8 *pu1_dst,
   1013                                            WORD32 dst_strd,
   1014                                            WORD32 nt,
   1015                                            WORD32 mode)
   1016 {
   1017     /* This function and ihevc_intra_pred_CHROMA_mode_19_to_25 are same except*/
   1018     /* for ref main & side samples assignment,can be combined for */
   1019     /* optimzation*/
   1020 
   1021     WORD32 row, col, k;
   1022     WORD32 intra_pred_ang, inv_ang, inv_ang_sum;
   1023     WORD32 idx_u, idx_v, ref_main_idx_u, ref_main_idx_v, ref_idx;
   1024     WORD32 pos_u, pos_v, fract_u, fract_v;
   1025 
   1026     UWORD8 ref_temp[2 * MAX_CU_SIZE + 2];
   1027     UWORD8 *ref_main;
   1028     UNUSED(src_strd);
   1029     inv_ang_sum = 128;
   1030 
   1031     intra_pred_ang = gai4_ihevc_ang_table[mode];
   1032 
   1033     inv_ang = gai4_ihevc_inv_ang_table[mode - 11];
   1034     /* Intermediate reference samples for negative angle modes */
   1035     /* This have to be removed during optimization*/
   1036 
   1037     /* For horizontal modes, (ref main = ref left) (ref side = ref above) */
   1038 
   1039 
   1040     ref_main = ref_temp + 2 * nt;
   1041     for(k = 0; k < (2 * (nt + 1)); k += 2)
   1042     {
   1043         ref_temp[k + (2 * (nt - 1))] = pu1_ref[(4 * nt) - k];
   1044         ref_temp[k + 1 + (2 * (nt - 1))] = pu1_ref[(4 * nt) - k + 1];
   1045     }
   1046 
   1047     ref_main = ref_temp + (2 * (nt - 1));
   1048     ref_idx = (nt * intra_pred_ang) >> 5;
   1049 
   1050     /* SIMD Optimization can be done using look-up table for the loop */
   1051     /* For negative angled derive the main reference samples from side */
   1052     /*  reference samples refer to section 8.4.4.2.6 */
   1053     for(k = -2; k > (2 * ref_idx); k -= 2)
   1054     {
   1055         inv_ang_sum += inv_ang;
   1056         ref_main[k] = pu1_ref[(4 * nt) + ((inv_ang_sum >> 8) << 1)];
   1057         ref_main[k + 1] = pu1_ref[((4 * nt) + 1) + ((inv_ang_sum >> 8) << 1)];
   1058     }
   1059 
   1060     /* For the angles other then 45 degree, interpolation btw 2 neighboring */
   1061     /* samples dependent on distance to obtain destination sample */
   1062     for(col = 0; col < (2 * nt); col += 2)
   1063     {
   1064         pos_u = ((col / 2 + 1) * intra_pred_ang);
   1065         pos_v = ((col / 2 + 1) * intra_pred_ang);
   1066         idx_u = pos_u >> 5;
   1067         idx_v = pos_v >> 5;
   1068         fract_u = pos_u & (31);
   1069         fract_v = pos_v & (31);
   1070 
   1071         // Do linear filtering
   1072         for(row = 0; row < nt; row++)
   1073         {
   1074             ref_main_idx_u = 2 * (row + idx_u + 1);
   1075             ref_main_idx_v = 2 * (row + idx_v + 1) + 1;
   1076 
   1077             pu1_dst[col + (dst_strd * row)] = (UWORD8)(((32 - fract_u)
   1078                             * ref_main[ref_main_idx_u]
   1079                             + fract_u * ref_main[ref_main_idx_u + 2] + 16) >> 5);
   1080             pu1_dst[(col + 1) + (dst_strd * row)] = (UWORD8)(((32 - fract_v)
   1081                             * ref_main[ref_main_idx_v]
   1082                             + fract_v * ref_main[ref_main_idx_v + 2] + 16) >> 5);
   1083 
   1084         }
   1085 
   1086     }
   1087 
   1088 }
   1089 
   1090 
   1091 
   1092 /**
   1093 *******************************************************************************
   1094 *
   1095 * @brief
   1096 *  Intraprediction for mode 19 to 25  (negative angle, vertical mode ) with
   1097 * reference  neighboring samples location pointed by 'pu1_ref' to the  TU
   1098 * block location pointed by 'pu1_dst'
   1099 *
   1100 * @par Description:
   1101 *
   1102 *
   1103 * @param[in] pu1_src
   1104 *  UWORD8 pointer to the source
   1105 *
   1106 * @param[in] pu1_dst
   1107 *  UWORD8 pointer to the destination
   1108 *
   1109 * @param[in] src_strd
   1110 *  integer source stride
   1111 *
   1112 * @param[in] dst_strd
   1113 *  integer destination stride
   1114 *
   1115 * @param[in] nt
   1116 *  integer Transform Block size
   1117 *
   1118 * @param[in] mode
   1119 *  integer intraprediction mode
   1120 *
   1121 * @returns
   1122 *
   1123 * @remarks
   1124 *  None
   1125 *
   1126 *******************************************************************************
   1127 */
   1128 
   1129 
   1130 void ihevc_intra_pred_chroma_mode_19_to_25(UWORD8 *pu1_ref,
   1131                                            WORD32 src_strd,
   1132                                            UWORD8 *pu1_dst,
   1133                                            WORD32 dst_strd,
   1134                                            WORD32 nt,
   1135                                            WORD32 mode)
   1136 {
   1137 
   1138     WORD32 row, col, k;
   1139     WORD32 intra_pred_ang, idx;
   1140     WORD32 inv_ang, inv_ang_sum, pos, fract;
   1141     WORD32 ref_main_idx_u, ref_main_idx_v, ref_idx;
   1142     UWORD8 ref_temp[(2 * MAX_CU_SIZE) + 2];
   1143     UWORD8 *ref_main;
   1144     UNUSED(src_strd);
   1145 
   1146 
   1147     intra_pred_ang = gai4_ihevc_ang_table_chroma[mode];
   1148     inv_ang = gai4_ihevc_inv_ang_table_chroma[mode - 12];
   1149 
   1150     /* Intermediate reference samples for negative angle modes */
   1151     /* This have to be removed during optimization*/
   1152     /* For horizontal modes, (ref main = ref above) (ref side = ref left) */
   1153     ref_main = ref_temp + 2 * nt;
   1154     for(k = 0; k < (2 * (nt + 1)); k += 2)
   1155     {
   1156         ref_temp[k + (2 * (nt - 1))] = pu1_ref[(4 * nt) + k];
   1157         ref_temp[k + 1 + (2 * (nt - 1))] = pu1_ref[(4 * nt) + k + 1];
   1158     }
   1159 
   1160 
   1161     ref_idx = (nt * intra_pred_ang) >> 5;
   1162     inv_ang_sum = 128;
   1163     ref_main = ref_temp + (2 * (nt - 1));
   1164     /* SIMD Optimization can be done using look-up table for the loop */
   1165     /* For negative angled derive the main reference samples from side */
   1166     /*  reference samples refer to section 8.4.4.2.6 */
   1167     for(k = -2; k > (2 * ref_idx); k -= 2)
   1168     {
   1169         inv_ang_sum += inv_ang;
   1170         ref_main[k] = pu1_ref[(4 * nt) - (inv_ang_sum >> 8) * 2];
   1171         ref_main[k + 1] = pu1_ref[((4 * nt) + 1) - (inv_ang_sum >> 8) * 2];
   1172     }
   1173 
   1174     for(row = 0; row < nt; row++)
   1175     {
   1176         pos = ((row + 1) * intra_pred_ang);
   1177         idx = pos >> 5;
   1178         fract = pos & (31);
   1179 
   1180         // Do linear filtering
   1181         for(col = 0; col < (2 * nt); col += 2)
   1182         {
   1183             ref_main_idx_u = col + 2 * idx + 2;
   1184             ref_main_idx_v = (col + 1) + 2 * idx + 2;
   1185             pu1_dst[(row * dst_strd) + col] = (UWORD8)(((32 - fract)
   1186                             * ref_main[ref_main_idx_u]
   1187                             + fract * ref_main[ref_main_idx_u + 2] + 16) >> 5);
   1188             pu1_dst[(row * dst_strd) + (col + 1)] = (UWORD8)(((32 - fract)
   1189                             * ref_main[ref_main_idx_v]
   1190                             + fract * ref_main[ref_main_idx_v + 2] + 16) >> 5);
   1191 
   1192         }
   1193 
   1194     }
   1195 
   1196 }
   1197 
   1198 
   1199 
   1200 /**
   1201 *******************************************************************************
   1202 *
   1203 * @brief
   1204 *  Intraprediction for mode 27 to 33  (positive angle, vertical mode ) with
   1205 * reference  neighboring samples location pointed by 'pu1_ref' to the  TU
   1206 * block location pointed by 'pu1_dst'
   1207 *
   1208 * @par Description:
   1209 *
   1210 *
   1211 * @param[in] pu1_src
   1212 *  UWORD8 pointer to the source
   1213 *
   1214 * @param[in] pu1_dst
   1215 *  UWORD8 pointer to the destination
   1216 *
   1217 * @param[in] src_strd
   1218 *  integer source stride
   1219 *
   1220 * @param[in] dst_strd
   1221 *  integer destination stride
   1222 *
   1223 * @param[in] nt
   1224 *  integer Transform Block size
   1225 *
   1226 * @param[in] mode
   1227 *  integer intraprediction mode
   1228 *
   1229 * @returns
   1230 *
   1231 * @remarks
   1232 *  None
   1233 *
   1234 *******************************************************************************
   1235 */
   1236 
   1237 
   1238 void ihevc_intra_pred_chroma_mode_27_to_33(UWORD8 *pu1_ref,
   1239                                            WORD32 src_strd,
   1240                                            UWORD8 *pu1_dst,
   1241                                            WORD32 dst_strd,
   1242                                            WORD32 nt,
   1243                                            WORD32 mode)
   1244 {
   1245     WORD32 row, col;
   1246     WORD32 pos, fract;
   1247     WORD32 intra_pred_ang;
   1248     WORD32 idx, ref_main_idx_u, ref_main_idx_v;
   1249     UNUSED(src_strd);
   1250 
   1251 
   1252     intra_pred_ang = gai4_ihevc_ang_table_chroma[mode];
   1253 
   1254     for(row = 0; row < nt; row++)
   1255     {
   1256         pos = ((row + 1) * intra_pred_ang);
   1257         idx = pos >> 5;
   1258         fract = pos & (31);
   1259 
   1260 
   1261         // Do linear filtering
   1262         for(col = 0; col < (2 * nt); col += 2)
   1263         {
   1264             ref_main_idx_u = (4 * nt) + col + 2 * idx + 2;
   1265             ref_main_idx_v = (4 * nt) + (col + 1) + 2 * idx + 2;
   1266             pu1_dst[col + (row * dst_strd)] = (((32 - fract)
   1267                             * pu1_ref[ref_main_idx_u]
   1268                             + fract * pu1_ref[ref_main_idx_u + 2] + 16) >> 5);
   1269             pu1_dst[(col + 1) + (row * dst_strd)] = (((32 - fract)
   1270                             * pu1_ref[ref_main_idx_v]
   1271                             + fract * pu1_ref[ref_main_idx_v + 2] + 16) >> 5);
   1272 
   1273         }
   1274     }
   1275 
   1276 }
   1277 
   1278