Home | History | Annotate | Download | only in encoder
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2018 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 ******************************************************************************
     23 * \file ihevce_enc_sbh_funcs.c
     24 *
     25 * \brief
     26 *    This file contains utility functions for sbh
     27 *
     28 * \date
     29 *    31/08/2012
     30 *
     31 * \author
     32 *    Ittiam
     33 *
     34 * List of Functions
     35 *    ihevce_sign_data_hiding()
     36 *
     37 ******************************************************************************
     38 */
     39 
     40 /*****************************************************************************/
     41 /* File Includes                                                             */
     42 /*****************************************************************************/
     43 /* System include files */
     44 #include <stdio.h>
     45 #include <string.h>
     46 #include <stdlib.h>
     47 #include <assert.h>
     48 #include <stdarg.h>
     49 #include <math.h>
     50 
     51 /* User include files */
     52 #include "ihevc_typedefs.h"
     53 #include "itt_video_api.h"
     54 #include "ihevce_api.h"
     55 
     56 #include "rc_cntrl_param.h"
     57 #include "rc_frame_info_collector.h"
     58 #include "rc_look_ahead_params.h"
     59 
     60 #include "ihevc_defs.h"
     61 #include "ihevc_structs.h"
     62 #include "ihevc_platform_macros.h"
     63 #include "ihevc_deblk.h"
     64 #include "ihevc_itrans_recon.h"
     65 #include "ihevc_chroma_itrans_recon.h"
     66 #include "ihevc_chroma_intra_pred.h"
     67 #include "ihevc_intra_pred.h"
     68 #include "ihevc_inter_pred.h"
     69 #include "ihevc_mem_fns.h"
     70 #include "ihevc_padding.h"
     71 #include "ihevc_weighted_pred.h"
     72 #include "ihevc_sao.h"
     73 #include "ihevc_resi_trans.h"
     74 #include "ihevc_quant_iquant_ssd.h"
     75 #include "ihevc_cabac_tables.h"
     76 #include "ihevc_trans_tables.h"
     77 #include "ihevc_trans_macros.h"
     78 
     79 #include "ihevce_defs.h"
     80 #include "ihevce_lap_enc_structs.h"
     81 #include "ihevce_multi_thrd_structs.h"
     82 #include "ihevce_multi_thrd_funcs.h"
     83 #include "ihevce_me_common_defs.h"
     84 #include "ihevce_had_satd.h"
     85 #include "ihevce_error_codes.h"
     86 #include "ihevce_bitstream.h"
     87 #include "ihevce_cabac.h"
     88 #include "ihevce_rdoq_macros.h"
     89 #include "ihevce_function_selector.h"
     90 #include "ihevce_enc_structs.h"
     91 #include "ihevce_global_tables.h"
     92 #include "ihevce_enc_sbh_utils.h"
     93 
     94 /*****************************************************************************/
     95 /* Function Definitions                                                      */
     96 /*****************************************************************************/
     97 
     98 /**
     99 *******************************************************************************
    100 *
    101 * @brief
    102 *  This function find the coefficient that needs to be modified for SBH
    103 *  for each sub block, if required
    104 *
    105 * @par Description:
    106 *  Checks the validity for applying SBH
    107 *
    108 * @param[inout] ps_rdoq_sbh_params
    109 *  All the necessary parameters for SBH
    110 *
    111 * @returns  None
    112 *
    113 * @remarks  None
    114 *
    115 ********************************************************************************
    116 */
    117 void ihevce_sign_data_hiding(rdoq_sbh_ctxt_t *ps_rdoq_sbh_params)
    118 {
    119     WORD32 i, trans_unit_idx;
    120     UWORD8 *pu1_trans_table = NULL;
    121     UWORD8 *pu1_csb_table;
    122     WORD32 shift_value, mask_value;
    123     WORD32 blk_row, blk_col;
    124 
    125     WORD32 x_pos, y_pos;
    126     WORD16 i2_quant_coeff;
    127     WORD32 best_pos = -1;
    128 
    129     WORD16 *pi2_quant_coeffs = ps_rdoq_sbh_params->pi2_quant_coeffs;
    130     WORD16 *pi2_iquant_data = ps_rdoq_sbh_params->pi2_iquant_coeffs;
    131     WORD16 *pi2_tr_coeffs = ps_rdoq_sbh_params->pi2_trans_values;
    132     WORD32 *pi4_subBlock2csbfId_map = ps_rdoq_sbh_params->pi4_subBlock2csbfId_map;
    133     WORD16 *pi2_dequant_coeff = ps_rdoq_sbh_params->pi2_dequant_coeff;
    134     UWORD8 *pu1_csbf_buf = ps_rdoq_sbh_params->pu1_csbf_buf;
    135     WORD32 dst_iq_strd = ps_rdoq_sbh_params->i4_iq_data_strd;
    136     WORD32 dst_q_strd = ps_rdoq_sbh_params->i4_q_data_strd;
    137 
    138     WORD32 scan_idx = ps_rdoq_sbh_params->i4_scan_idx;
    139     WORD32 qp_div = ps_rdoq_sbh_params->i4_qp_div;
    140     WORD32 trans_size = ps_rdoq_sbh_params->i4_trans_size;
    141     WORD32 qp_rem = ps_rdoq_sbh_params->i2_qp_rem;
    142     LWORD64 ssd_cost = ps_rdoq_sbh_params->i8_ssd_cost;
    143 
    144     WORD32 last_cg = -1;
    145 
    146     WORD32 log2_size, bit_depth, shift_iq;
    147 
    148     GETRANGE(log2_size, trans_size);
    149     log2_size -= 1;
    150     bit_depth = ps_rdoq_sbh_params->i4_bit_depth;
    151     shift_iq = bit_depth + log2_size - 5;
    152 
    153     /* Select proper order for your transform unit and csb based on scan_idx*/
    154     /* and the trans_size */
    155 
    156     /* scan order inside a csb */
    157     pu1_csb_table = (UWORD8 *)&(g_u1_scan_table_4x4[scan_idx][0]);
    158 
    159     /* GETRANGE will give the log_2 of trans_size to shift_value */
    160     GETRANGE(shift_value, trans_size);
    161     shift_value = shift_value - 3; /* for finding. row no. from scan index */
    162     mask_value = (trans_size / 4) - 1; /*for finding the col. no. from scan index*/
    163     switch(trans_size)
    164     {
    165     case 32:
    166         pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_8x8[scan_idx][0]);
    167         break;
    168     case 16:
    169         pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_4x4[scan_idx][0]);
    170         break;
    171     case 8:
    172         pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_2x2[scan_idx][0]);
    173         break;
    174     case 4:
    175         pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_1x1[0]);
    176         break;
    177     default:
    178         ASSERT(0);
    179         break;
    180     }
    181     for(trans_unit_idx = (trans_size * trans_size / 16) - 1; trans_unit_idx >= 0; trans_unit_idx--)
    182     {
    183         WORD32 last_scan_pos = -1, first_scan_pos = 16, sign_first_coeff, sum_abs_level = 0,
    184                quant_coeff_first;
    185 
    186         if(pu1_csbf_buf[pi4_subBlock2csbfId_map[pu1_trans_table[trans_unit_idx]]])
    187         {
    188             /* row of csb */
    189             blk_row = (pu1_trans_table[trans_unit_idx] >> shift_value) * 4;
    190             /* col of csb */
    191             blk_col = (pu1_trans_table[trans_unit_idx] & mask_value) * 4;
    192 
    193             if(last_cg == -1)
    194             {
    195                 last_cg = 1;
    196             }
    197 
    198             for(i = 15; i >= 0; i--)
    199             {
    200                 x_pos = (pu1_csb_table[i] & 0x3) + blk_col;
    201                 y_pos = (pu1_csb_table[i] >> 2) + blk_row;
    202 
    203                 i2_quant_coeff = pi2_quant_coeffs[x_pos + (y_pos * trans_size)];
    204 
    205                 if(i2_quant_coeff)
    206                 {
    207                     first_scan_pos = i;
    208                     if(-1 == last_scan_pos)
    209                     {
    210                         last_scan_pos = i;
    211                     }
    212 
    213                     sum_abs_level += abs(i2_quant_coeff);
    214                 }
    215             }
    216 
    217             if((last_scan_pos - first_scan_pos) >= 4)
    218             {
    219                 x_pos = (pu1_csb_table[first_scan_pos] & 0x3) + blk_col;
    220                 y_pos = (pu1_csb_table[first_scan_pos] >> 2) + blk_row;
    221 
    222                 quant_coeff_first = pi2_quant_coeffs[x_pos + (y_pos * trans_size)];
    223 
    224                 sign_first_coeff = (quant_coeff_first > 0) ? 0 : 1;
    225 
    226                 if(sign_first_coeff != (sum_abs_level & 0x1))
    227                 {
    228                     WORD32 q_err;
    229                     WORD32 min_cost = MAX_INT;
    230                     WORD32 final_change = 0, cur_cost = 0, cur_change = 0;
    231                     WORD16 i2_tr_coeff;
    232                     WORD16 i2_iquant_coeff;
    233 
    234                     for(i = (last_cg == 1) ? last_scan_pos : 15; i >= 0; i--)
    235                     {
    236                         x_pos = (pu1_csb_table[i] & 0x3) + blk_col;
    237                         y_pos = (pu1_csb_table[i] >> 2) + blk_row;
    238 
    239                         i2_quant_coeff = pi2_quant_coeffs[x_pos + (y_pos * trans_size)];
    240                         i2_tr_coeff = pi2_tr_coeffs[x_pos + (y_pos * trans_size)];
    241                         i2_iquant_coeff = pi2_iquant_data[x_pos + (y_pos * dst_iq_strd)];
    242 
    243                         q_err = abs(i2_tr_coeff) - abs(i2_iquant_coeff);
    244 
    245                         if(i2_quant_coeff != 0)
    246                         {
    247                             cur_cost = -1 * SIGN(q_err) * q_err;
    248 
    249                             if(q_err <= 0)
    250                             {
    251                                 if(i == first_scan_pos && abs(i2_quant_coeff) == 1)
    252                                 {
    253                                     cur_cost = MAX_INT;
    254                                 }
    255                             }
    256                         }
    257                         else
    258                         {
    259                             cur_cost = -q_err;
    260                             if(i < first_scan_pos)
    261                             {
    262                                 WORD32 sign_bit = (i2_tr_coeff >= 0 ? 0 : 1);
    263 
    264                                 if(sign_first_coeff != sign_bit)
    265                                 {
    266                                     cur_cost = MAX_INT;
    267                                 }
    268                             }
    269                         }
    270 
    271                         cur_change = (i2_quant_coeff == 0) ? 1 : (q_err > 0 ? 1 : -1);
    272 
    273                         if(cur_cost < min_cost)
    274                         {
    275                             min_cost = cur_cost;
    276                             final_change = cur_change;
    277                             best_pos = i;
    278                         }
    279                     }
    280                     if((i2_quant_coeff == 32767) || (i2_quant_coeff == -32768))
    281                     {
    282                         final_change = -1;
    283                     }
    284 
    285                     x_pos = (pu1_csb_table[best_pos] & 0x3) + blk_col;
    286                     y_pos = (pu1_csb_table[best_pos] >> 2) + blk_row;
    287                     i2_iquant_coeff = pi2_iquant_data[x_pos + (y_pos * dst_iq_strd)];
    288                     i2_tr_coeff = pi2_tr_coeffs[x_pos + (y_pos * trans_size)];
    289 
    290                     if(i2_tr_coeff >= 0)
    291                     {
    292                         pi2_quant_coeffs[x_pos + (y_pos * trans_size)] += final_change;
    293                     }
    294                     else
    295                     {
    296                         pi2_quant_coeffs[x_pos + (y_pos * trans_size)] -= final_change;
    297                     }
    298 
    299                     {
    300                         WORD32 i4_err1, i4_err2;
    301 
    302                         /*  Inverse Quantization    */
    303                         IQUANT(
    304                             pi2_iquant_data[y_pos * dst_iq_strd + x_pos],
    305                             pi2_quant_coeffs[y_pos * dst_q_strd + x_pos],
    306                             pi2_dequant_coeff[y_pos * trans_size + x_pos] *
    307                                 g_ihevc_iquant_scales[qp_rem],
    308                             shift_iq,
    309                             qp_div);
    310 
    311                         i4_err1 = (i2_tr_coeff - i2_iquant_coeff);
    312                         i4_err1 = i4_err1 * i4_err1;
    313                         ssd_cost = ssd_cost - i4_err1;
    314                         i4_err2 = (i2_tr_coeff - pi2_iquant_data[y_pos * dst_iq_strd + x_pos]);
    315                         i4_err2 = i4_err2 * i4_err2;
    316                         ssd_cost = ssd_cost + i4_err2;
    317                     }
    318                 }
    319             }
    320             if(last_cg == 1)
    321             {
    322                 last_cg = 0;
    323             }
    324         }
    325     }
    326 
    327     ps_rdoq_sbh_params->i8_ssd_cost = ssd_cost;
    328 }
    329