LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vp9/encoder - vp9_quantize.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 143 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include <math.h>
      12             : #include "./vpx_dsp_rtcd.h"
      13             : #include "vpx_mem/vpx_mem.h"
      14             : #include "vpx_ports/mem.h"
      15             : 
      16             : #include "vp9/common/vp9_quant_common.h"
      17             : #include "vp9/common/vp9_seg_common.h"
      18             : 
      19             : #include "vp9/encoder/vp9_encoder.h"
      20             : #include "vp9/encoder/vp9_quantize.h"
      21             : #include "vp9/encoder/vp9_rd.h"
      22             : 
      23           0 : void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
      24             :                        int skip_block, const int16_t *zbin_ptr,
      25             :                        const int16_t *round_ptr, const int16_t *quant_ptr,
      26             :                        const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
      27             :                        tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
      28             :                        uint16_t *eob_ptr, const int16_t *scan,
      29             :                        const int16_t *iscan) {
      30           0 :   int i, eob = -1;
      31             :   // TODO(jingning) Decide the need of these arguments after the
      32             :   // quantization process is completed.
      33             :   (void)zbin_ptr;
      34             :   (void)quant_shift_ptr;
      35             :   (void)iscan;
      36             : 
      37           0 :   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
      38           0 :   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
      39             : 
      40           0 :   if (!skip_block) {
      41             :     // Quantization pass: All coefficients with index >= zero_flag are
      42             :     // skippable. Note: zero_flag can be zero.
      43           0 :     for (i = 0; i < n_coeffs; i++) {
      44           0 :       const int rc = scan[i];
      45           0 :       const int coeff = coeff_ptr[rc];
      46           0 :       const int coeff_sign = (coeff >> 31);
      47           0 :       const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
      48             : 
      49           0 :       int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
      50           0 :       tmp = (tmp * quant_ptr[rc != 0]) >> 16;
      51             : 
      52           0 :       qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
      53           0 :       dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
      54             : 
      55           0 :       if (tmp) eob = i;
      56             :     }
      57             :   }
      58           0 :   *eob_ptr = eob + 1;
      59           0 : }
      60             : 
      61             : #if CONFIG_VP9_HIGHBITDEPTH
      62             : void vp9_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
      63             :                               int skip_block, const int16_t *zbin_ptr,
      64             :                               const int16_t *round_ptr,
      65             :                               const int16_t *quant_ptr,
      66             :                               const int16_t *quant_shift_ptr,
      67             :                               tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
      68             :                               const int16_t *dequant_ptr, uint16_t *eob_ptr,
      69             :                               const int16_t *scan, const int16_t *iscan) {
      70             :   int i;
      71             :   int eob = -1;
      72             :   // TODO(jingning) Decide the need of these arguments after the
      73             :   // quantization process is completed.
      74             :   (void)zbin_ptr;
      75             :   (void)quant_shift_ptr;
      76             :   (void)iscan;
      77             : 
      78             :   memset(qcoeff_ptr, 0, count * sizeof(*qcoeff_ptr));
      79             :   memset(dqcoeff_ptr, 0, count * sizeof(*dqcoeff_ptr));
      80             : 
      81             :   if (!skip_block) {
      82             :     // Quantization pass: All coefficients with index >= zero_flag are
      83             :     // skippable. Note: zero_flag can be zero.
      84             :     for (i = 0; i < count; i++) {
      85             :       const int rc = scan[i];
      86             :       const int coeff = coeff_ptr[rc];
      87             :       const int coeff_sign = (coeff >> 31);
      88             :       const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
      89             :       const int64_t tmp = abs_coeff + round_ptr[rc != 0];
      90             :       const int abs_qcoeff = (int)((tmp * quant_ptr[rc != 0]) >> 16);
      91             :       qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
      92             :       dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
      93             :       if (abs_qcoeff) eob = i;
      94             :     }
      95             :   }
      96             :   *eob_ptr = eob + 1;
      97             : }
      98             : #endif
      99             : 
     100             : // TODO(jingning) Refactor this file and combine functions with similar
     101             : // operations.
     102           0 : void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
     103             :                              int skip_block, const int16_t *zbin_ptr,
     104             :                              const int16_t *round_ptr, const int16_t *quant_ptr,
     105             :                              const int16_t *quant_shift_ptr,
     106             :                              tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
     107             :                              const int16_t *dequant_ptr, uint16_t *eob_ptr,
     108             :                              const int16_t *scan, const int16_t *iscan) {
     109           0 :   int i, eob = -1;
     110             :   (void)zbin_ptr;
     111             :   (void)quant_shift_ptr;
     112             :   (void)iscan;
     113             : 
     114           0 :   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     115           0 :   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     116             : 
     117           0 :   if (!skip_block) {
     118           0 :     for (i = 0; i < n_coeffs; i++) {
     119           0 :       const int rc = scan[i];
     120           0 :       const int coeff = coeff_ptr[rc];
     121           0 :       const int coeff_sign = (coeff >> 31);
     122           0 :       int tmp = 0;
     123           0 :       int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
     124             : 
     125           0 :       if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) {
     126           0 :         abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
     127           0 :         abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
     128           0 :         tmp = (abs_coeff * quant_ptr[rc != 0]) >> 15;
     129           0 :         qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
     130           0 :         dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
     131             :       }
     132             : 
     133           0 :       if (tmp) eob = i;
     134             :     }
     135             :   }
     136           0 :   *eob_ptr = eob + 1;
     137           0 : }
     138             : 
     139             : #if CONFIG_VP9_HIGHBITDEPTH
     140             : void vp9_highbd_quantize_fp_32x32_c(
     141             :     const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
     142             :     const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
     143             :     const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
     144             :     tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
     145             :     const int16_t *scan, const int16_t *iscan) {
     146             :   int i, eob = -1;
     147             :   (void)zbin_ptr;
     148             :   (void)quant_shift_ptr;
     149             :   (void)iscan;
     150             : 
     151             :   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     152             :   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     153             : 
     154             :   if (!skip_block) {
     155             :     for (i = 0; i < n_coeffs; i++) {
     156             :       uint32_t abs_qcoeff = 0;
     157             :       const int rc = scan[i];
     158             :       const int coeff = coeff_ptr[rc];
     159             :       const int coeff_sign = (coeff >> 31);
     160             :       const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
     161             : 
     162             :       if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) {
     163             :         const int64_t tmp =
     164             :             abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
     165             :         abs_qcoeff = (uint32_t)((tmp * quant_ptr[rc != 0]) >> 15);
     166             :         qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
     167             :         dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
     168             :       }
     169             : 
     170             :       if (abs_qcoeff) eob = i;
     171             :     }
     172             :   }
     173             :   *eob_ptr = eob + 1;
     174             : }
     175             : #endif
     176             : 
     177           0 : void vp9_regular_quantize_b_4x4(MACROBLOCK *x, int plane, int block,
     178             :                                 const int16_t *scan, const int16_t *iscan) {
     179           0 :   MACROBLOCKD *const xd = &x->e_mbd;
     180           0 :   struct macroblock_plane *p = &x->plane[plane];
     181           0 :   struct macroblockd_plane *pd = &xd->plane[plane];
     182             : 
     183             : #if CONFIG_VP9_HIGHBITDEPTH
     184             :   if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
     185             :     vpx_highbd_quantize_b(BLOCK_OFFSET(p->coeff, block), 16, x->skip_block,
     186             :                           p->zbin, p->round, p->quant, p->quant_shift,
     187             :                           BLOCK_OFFSET(p->qcoeff, block),
     188             :                           BLOCK_OFFSET(pd->dqcoeff, block), pd->dequant,
     189             :                           &p->eobs[block], scan, iscan);
     190             :     return;
     191             :   }
     192             : #endif
     193           0 :   vpx_quantize_b(BLOCK_OFFSET(p->coeff, block), 16, x->skip_block, p->zbin,
     194           0 :                  p->round, p->quant, p->quant_shift,
     195           0 :                  BLOCK_OFFSET(p->qcoeff, block),
     196           0 :                  BLOCK_OFFSET(pd->dqcoeff, block), pd->dequant, &p->eobs[block],
     197             :                  scan, iscan);
     198           0 : }
     199             : 
     200           0 : static void invert_quant(int16_t *quant, int16_t *shift, int d) {
     201             :   unsigned t;
     202             :   int l, m;
     203           0 :   t = d;
     204           0 :   for (l = 0; t > 1; l++) t >>= 1;
     205           0 :   m = 1 + (1 << (16 + l)) / d;
     206           0 :   *quant = (int16_t)(m - (1 << 16));
     207           0 :   *shift = 1 << (16 - l);
     208           0 : }
     209             : 
     210           0 : static int get_qzbin_factor(int q, vpx_bit_depth_t bit_depth) {
     211           0 :   const int quant = vp9_dc_quant(q, 0, bit_depth);
     212             : #if CONFIG_VP9_HIGHBITDEPTH
     213             :   switch (bit_depth) {
     214             :     case VPX_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
     215             :     case VPX_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
     216             :     case VPX_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
     217             :     default:
     218             :       assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
     219             :       return -1;
     220             :   }
     221             : #else
     222             :   (void)bit_depth;
     223           0 :   return q == 0 ? 64 : (quant < 148 ? 84 : 80);
     224             : #endif
     225             : }
     226             : 
     227           0 : void vp9_init_quantizer(VP9_COMP *cpi) {
     228           0 :   VP9_COMMON *const cm = &cpi->common;
     229           0 :   QUANTS *const quants = &cpi->quants;
     230             :   int i, q, quant;
     231             : 
     232           0 :   for (q = 0; q < QINDEX_RANGE; q++) {
     233           0 :     const int qzbin_factor = get_qzbin_factor(q, cm->bit_depth);
     234           0 :     const int qrounding_factor = q == 0 ? 64 : 48;
     235             : 
     236           0 :     for (i = 0; i < 2; ++i) {
     237           0 :       int qrounding_factor_fp = i == 0 ? 48 : 42;
     238           0 :       if (q == 0) qrounding_factor_fp = 64;
     239             : 
     240             :       // y
     241           0 :       quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth)
     242           0 :                      : vp9_ac_quant(q, 0, cm->bit_depth);
     243           0 :       invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant);
     244           0 :       quants->y_quant_fp[q][i] = (1 << 16) / quant;
     245           0 :       quants->y_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7;
     246           0 :       quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
     247           0 :       quants->y_round[q][i] = (qrounding_factor * quant) >> 7;
     248           0 :       cpi->y_dequant[q][i] = quant;
     249             : 
     250             :       // uv
     251           0 :       quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth)
     252           0 :                      : vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth);
     253           0 :       invert_quant(&quants->uv_quant[q][i], &quants->uv_quant_shift[q][i],
     254             :                    quant);
     255           0 :       quants->uv_quant_fp[q][i] = (1 << 16) / quant;
     256           0 :       quants->uv_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7;
     257           0 :       quants->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
     258           0 :       quants->uv_round[q][i] = (qrounding_factor * quant) >> 7;
     259           0 :       cpi->uv_dequant[q][i] = quant;
     260             :     }
     261             : 
     262           0 :     for (i = 2; i < 8; i++) {
     263           0 :       quants->y_quant[q][i] = quants->y_quant[q][1];
     264           0 :       quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
     265           0 :       quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
     266           0 :       quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
     267           0 :       quants->y_zbin[q][i] = quants->y_zbin[q][1];
     268           0 :       quants->y_round[q][i] = quants->y_round[q][1];
     269           0 :       cpi->y_dequant[q][i] = cpi->y_dequant[q][1];
     270             : 
     271           0 :       quants->uv_quant[q][i] = quants->uv_quant[q][1];
     272           0 :       quants->uv_quant_fp[q][i] = quants->uv_quant_fp[q][1];
     273           0 :       quants->uv_round_fp[q][i] = quants->uv_round_fp[q][1];
     274           0 :       quants->uv_quant_shift[q][i] = quants->uv_quant_shift[q][1];
     275           0 :       quants->uv_zbin[q][i] = quants->uv_zbin[q][1];
     276           0 :       quants->uv_round[q][i] = quants->uv_round[q][1];
     277           0 :       cpi->uv_dequant[q][i] = cpi->uv_dequant[q][1];
     278             :     }
     279             :   }
     280           0 : }
     281             : 
     282           0 : void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) {
     283           0 :   const VP9_COMMON *const cm = &cpi->common;
     284           0 :   MACROBLOCKD *const xd = &x->e_mbd;
     285           0 :   QUANTS *const quants = &cpi->quants;
     286           0 :   const int segment_id = xd->mi[0]->segment_id;
     287           0 :   const int qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
     288           0 :   const int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
     289             :   int i;
     290             : 
     291             :   // Y
     292           0 :   x->plane[0].quant = quants->y_quant[qindex];
     293           0 :   x->plane[0].quant_fp = quants->y_quant_fp[qindex];
     294           0 :   x->plane[0].round_fp = quants->y_round_fp[qindex];
     295           0 :   x->plane[0].quant_shift = quants->y_quant_shift[qindex];
     296           0 :   x->plane[0].zbin = quants->y_zbin[qindex];
     297           0 :   x->plane[0].round = quants->y_round[qindex];
     298           0 :   xd->plane[0].dequant = cpi->y_dequant[qindex];
     299             : 
     300           0 :   x->plane[0].quant_thred[0] = x->plane[0].zbin[0] * x->plane[0].zbin[0];
     301           0 :   x->plane[0].quant_thred[1] = x->plane[0].zbin[1] * x->plane[0].zbin[1];
     302             : 
     303             :   // UV
     304           0 :   for (i = 1; i < 3; i++) {
     305           0 :     x->plane[i].quant = quants->uv_quant[qindex];
     306           0 :     x->plane[i].quant_fp = quants->uv_quant_fp[qindex];
     307           0 :     x->plane[i].round_fp = quants->uv_round_fp[qindex];
     308           0 :     x->plane[i].quant_shift = quants->uv_quant_shift[qindex];
     309           0 :     x->plane[i].zbin = quants->uv_zbin[qindex];
     310           0 :     x->plane[i].round = quants->uv_round[qindex];
     311           0 :     xd->plane[i].dequant = cpi->uv_dequant[qindex];
     312             : 
     313           0 :     x->plane[i].quant_thred[0] = x->plane[i].zbin[0] * x->plane[i].zbin[0];
     314           0 :     x->plane[i].quant_thred[1] = x->plane[i].zbin[1] * x->plane[i].zbin[1];
     315             :   }
     316             : 
     317           0 :   x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
     318           0 :   x->q_index = qindex;
     319             : 
     320           0 :   set_error_per_bit(x, rdmult);
     321             : 
     322           0 :   vp9_initialize_me_consts(cpi, x, x->q_index);
     323           0 : }
     324             : 
     325           0 : void vp9_frame_init_quantizer(VP9_COMP *cpi) {
     326           0 :   vp9_init_plane_quantizers(cpi, &cpi->td.mb);
     327           0 : }
     328             : 
     329           0 : void vp9_set_quantizer(VP9_COMMON *cm, int q) {
     330             :   // quantizer has to be reinitialized with vp9_init_quantizer() if any
     331             :   // delta_q changes.
     332           0 :   cm->base_qindex = q;
     333           0 :   cm->y_dc_delta_q = 0;
     334           0 :   cm->uv_dc_delta_q = 0;
     335           0 :   cm->uv_ac_delta_q = 0;
     336           0 : }
     337             : 
     338             : // Table that converts 0-63 Q-range values passed in outside to the Qindex
     339             : // range used internally.
     340             : static const int quantizer_to_qindex[] = {
     341             :   0,   4,   8,   12,  16,  20,  24,  28,  32,  36,  40,  44,  48,
     342             :   52,  56,  60,  64,  68,  72,  76,  80,  84,  88,  92,  96,  100,
     343             :   104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
     344             :   156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
     345             :   208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
     346             : };
     347             : 
     348           0 : int vp9_quantizer_to_qindex(int quantizer) {
     349           0 :   return quantizer_to_qindex[quantizer];
     350             : }
     351             : 
     352           0 : int vp9_qindex_to_quantizer(int qindex) {
     353             :   int quantizer;
     354             : 
     355           0 :   for (quantizer = 0; quantizer < 64; ++quantizer)
     356           0 :     if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
     357             : 
     358           0 :   return 63;
     359             : }

Generated by: LCOV version 1.13