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_iquant_itrans_recon.c
     22  *
     23  * @brief
     24  *  Contains function definitions for inverse  quantization, inverse
     25  * transform and reconstruction  of chroma interleaved data.
     26  *
     27  * @author
     28  *  100470
     29  *
     30  * @par List of Functions:
     31  *   - ihevc_chroma_iquant_itrans_recon_4x4()
     32  *
     33  * @remarks
     34  *  None
     35  *
     36  *******************************************************************************
     37  */
     38 #include <stdio.h>
     39 #include <string.h>
     40 #include "ihevc_typedefs.h"
     41 #include "ihevc_macros.h"
     42 #include "ihevc_platform_macros.h"
     43 #include "ihevc_defs.h"
     44 #include "ihevc_trans_tables.h"
     45 #include "ihevc_chroma_iquant_itrans_recon.h"
     46 #include "ihevc_func_selector.h"
     47 #include "ihevc_trans_macros.h"
     48 
     49 /* All the functions work one component(U or V) of interleaved data depending upon pointers passed to it */
     50 /* Data visualization */
     51 /* U V U V U V U V */
     52 /* U V U V U V U V */
     53 /* U V U V U V U V */
     54 /* U V U V U V U V */
     55 /* If the pointer points to first byte of above stream (U) , functions will operate on U component */
     56 /* If the pointer points to second byte of above stream (V) , functions will operate on V component */
     57 
     58 
     59 /**
     60  *******************************************************************************
     61  *
     62  * @brief
     63  *  This function performs inverse quantization, inverse  transform and
     64  * reconstruction for 4x4 input block
     65  *
     66  * @par Description:
     67  *  Performs inverse quantization , inverse transform  and adds the
     68  * prediction data and clips output to 8 bit
     69  *
     70  * @param[in] pi2_src
     71  *  Input 4x4 coefficients
     72  *
     73  * @param[in] pi2_tmp
     74  *  Temporary 4x4 buffer for storing inverse transform
     75  *  1st stage output
     76  *
     77  * @param[in] pu1_pred
     78  *  Prediction 4x4 block
     79  *
     80  * @param[in] pi2_dequant_coeff
     81  *  Dequant Coeffs
     82  *
     83  * @param[out] pu1_dst
     84  *  Output 4x4 block
     85  *
     86  * @param[in] qp_div
     87  *  Quantization parameter / 6
     88  *
     89  * @param[in] qp_rem
     90  *  Quantization parameter % 6
     91  *
     92  * @param[in] src_strd
     93  *  Input stride
     94  *
     95  * @param[in] pred_strd
     96  *  Prediction stride
     97  *
     98  * @param[in] dst_strd
     99  *  Output Stride
    100  *
    101  * @param[in] zero_cols
    102  *  Zero columns in pi2_src
    103  *
    104  * @param[in] zero_rows
    105  *  Zero Rows in pi2_src
    106  *
    107  * @returns  Void
    108  *
    109  * @remarks
    110  *  None
    111  *
    112  *******************************************************************************
    113  */
    114 
    115 
    116 void ihevc_chroma_iquant_itrans_recon_4x4(WORD16 *pi2_src,
    117                                           WORD16 *pi2_tmp,
    118                                           UWORD8 *pu1_pred,
    119                                           WORD16 *pi2_dequant_coeff,
    120                                           UWORD8 *pu1_dst,
    121                                           WORD32 qp_div, /* qpscaled / 6 */
    122                                           WORD32 qp_rem, /* qpscaled % 6 */
    123                                           WORD32 src_strd,
    124                                           WORD32 pred_strd,
    125                                           WORD32 dst_strd,
    126                                           WORD32 zero_cols,
    127                                           WORD32 zero_rows)
    128 {
    129     UNUSED(zero_rows);
    130 
    131     /* Inverse Transform */
    132     {
    133         WORD32 j;
    134         WORD32 e[2], o[2];
    135         WORD32 add;
    136         WORD32 shift;
    137         WORD16 *pi2_tmp_orig;
    138         WORD32 shift_iq;
    139         WORD32 trans_size;
    140         /* Inverse Quantization constants */
    141         {
    142             WORD32 log2_trans_size, bit_depth;
    143 
    144             log2_trans_size = 2;
    145             bit_depth = 8 + 0;
    146             shift_iq = bit_depth + log2_trans_size - 5;
    147         }
    148 
    149         trans_size = TRANS_SIZE_4;
    150         pi2_tmp_orig = pi2_tmp;
    151 
    152         /* Inverse Transform 1st stage */
    153         shift = IT_SHIFT_STAGE_1;
    154         add = 1 << (shift - 1);
    155 
    156         for(j = 0; j < trans_size; j++)
    157         {
    158             /* Checking for Zero Cols */
    159             if((zero_cols & 1) == 1)
    160             {
    161                 memset(pi2_tmp, 0, trans_size * sizeof(WORD16));
    162             }
    163             else
    164             {
    165                 WORD32 iq_tmp_1, iq_tmp_2;
    166                 /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
    167                 IQUANT_4x4(iq_tmp_1,
    168                            pi2_src[1 * src_strd],
    169                            pi2_dequant_coeff[1 * trans_size] * g_ihevc_iquant_scales[qp_rem],
    170                            shift_iq, qp_div);
    171                 IQUANT_4x4(iq_tmp_2,
    172                            pi2_src[3 * src_strd],
    173                            pi2_dequant_coeff[3 * trans_size] * g_ihevc_iquant_scales[qp_rem],
    174                            shift_iq, qp_div);
    175 
    176                 o[0] = g_ai2_ihevc_trans_4[1][0] * iq_tmp_1
    177                                 + g_ai2_ihevc_trans_4[3][0] * iq_tmp_2;
    178                 o[1] = g_ai2_ihevc_trans_4[1][1] * iq_tmp_1
    179                                 + g_ai2_ihevc_trans_4[3][1] * iq_tmp_2;
    180 
    181                 IQUANT_4x4(iq_tmp_1,
    182                            pi2_src[0 * src_strd],
    183                            pi2_dequant_coeff[0 * trans_size] * g_ihevc_iquant_scales[qp_rem],
    184                            shift_iq, qp_div);
    185                 IQUANT_4x4(iq_tmp_2,
    186                            pi2_src[2 * src_strd],
    187                            pi2_dequant_coeff[2 * trans_size] * g_ihevc_iquant_scales[qp_rem],
    188                            shift_iq, qp_div);
    189 
    190                 e[0] = g_ai2_ihevc_trans_4[0][0] * iq_tmp_1
    191                                 + g_ai2_ihevc_trans_4[2][0] * iq_tmp_2;
    192                 e[1] = g_ai2_ihevc_trans_4[0][1] * iq_tmp_1
    193                                 + g_ai2_ihevc_trans_4[2][1] * iq_tmp_2;
    194 
    195                 pi2_tmp[0] =
    196                                 CLIP_S16(((e[0] + o[0] + add) >> shift));
    197                 pi2_tmp[1] =
    198                                 CLIP_S16(((e[1] + o[1] + add) >> shift));
    199                 pi2_tmp[2] =
    200                                 CLIP_S16(((e[1] - o[1] + add) >> shift));
    201                 pi2_tmp[3] =
    202                                 CLIP_S16(((e[0] - o[0] + add) >> shift));
    203             }
    204             pi2_src++;
    205             pi2_dequant_coeff++;
    206             pi2_tmp += trans_size;
    207             zero_cols = zero_cols >> 1;
    208         }
    209 
    210         pi2_tmp = pi2_tmp_orig;
    211 
    212         /* Inverse Transform 2nd stage */
    213         shift = IT_SHIFT_STAGE_2;
    214         add = 1 << (shift - 1);
    215 
    216         for(j = 0; j < trans_size; j++)
    217         {
    218             WORD32 itrans_out;
    219 
    220             /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
    221             o[0] = g_ai2_ihevc_trans_4[1][0] * pi2_tmp[trans_size]
    222                             + g_ai2_ihevc_trans_4[3][0]
    223                                             * pi2_tmp[3 * trans_size];
    224             o[1] = g_ai2_ihevc_trans_4[1][1] * pi2_tmp[trans_size]
    225                             + g_ai2_ihevc_trans_4[3][1]
    226                                             * pi2_tmp[3 * trans_size];
    227             e[0] = g_ai2_ihevc_trans_4[0][0] * pi2_tmp[0]
    228                             + g_ai2_ihevc_trans_4[2][0]
    229                                             * pi2_tmp[2 * trans_size];
    230             e[1] = g_ai2_ihevc_trans_4[0][1] * pi2_tmp[0]
    231                             + g_ai2_ihevc_trans_4[2][1]
    232                                             * pi2_tmp[2 * trans_size];
    233 
    234             itrans_out =
    235                             CLIP_S16(((e[0] + o[0] + add) >> shift));
    236             pu1_dst[0 * 2] = CLIP_U8((itrans_out + pu1_pred[0 * 2]));
    237 
    238             itrans_out =
    239                             CLIP_S16(((e[1] + o[1] + add) >> shift));
    240             pu1_dst[1 * 2] = CLIP_U8((itrans_out + pu1_pred[1 * 2]));
    241 
    242             itrans_out =
    243                             CLIP_S16(((e[1] - o[1] + add) >> shift));
    244             pu1_dst[2 * 2] = CLIP_U8((itrans_out + pu1_pred[2 * 2]));
    245 
    246             itrans_out =
    247                             CLIP_S16(((e[0] - o[0] + add) >> shift));
    248             pu1_dst[3 * 2] = CLIP_U8((itrans_out + pu1_pred[3 * 2]));
    249 
    250             pi2_tmp++;
    251             pu1_pred += pred_strd;
    252             pu1_dst += dst_strd;
    253 
    254         }
    255     }
    256 }
    257