583 lines · 19.1 KB · C
RawDownload
/* *  Copyright (c) 2010 The WebM project authors. All Rights Reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS.  All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */  #include <math.h>#include "vpx_mem/vpx_mem.h" #include "onyx_int.h"#include "quantize.h"#include "vp8/common/quant_common.h" void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d){    int i, rc, eob;    int x, y, z, sz;    short *coeff_ptr   = b->coeff;    short *round_ptr   = b->round;    short *quant_ptr   = b->quant_fast;    short *qcoeff_ptr  = d->qcoeff;    short *dqcoeff_ptr = d->dqcoeff;    short *dequant_ptr = d->dequant;     eob = -1;    for (i = 0; i < 16; i++)    {        rc   = vp8_default_zig_zag1d[i];        z    = coeff_ptr[rc];         sz = (z >> 31);                              /* sign of z */        x  = (z ^ sz) - sz;                          /* x = abs(z) */         y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; /* quantize (x) */        x  = (y ^ sz) - sz;                          /* get the sign back */        qcoeff_ptr[rc] = x;                          /* write to destination */        dqcoeff_ptr[rc] = x * dequant_ptr[rc];       /* dequantized value */         if (y)        {            eob = i;                                 /* last nonzero coeffs */        }    }    *d->eob = (char)(eob + 1);} void vp8_regular_quantize_b_c(BLOCK *b, BLOCKD *d){    int i, rc, eob;    int zbin;    int x, y, z, sz;    short *zbin_boost_ptr  = b->zrun_zbin_boost;    short *coeff_ptr       = b->coeff;    short *zbin_ptr        = b->zbin;    short *round_ptr       = b->round;    short *quant_ptr       = b->quant;    short *quant_shift_ptr = b->quant_shift;    short *qcoeff_ptr      = d->qcoeff;    short *dqcoeff_ptr     = d->dqcoeff;    short *dequant_ptr     = d->dequant;    short zbin_oq_value    = b->zbin_extra;     vpx_memset(qcoeff_ptr, 0, 32);    vpx_memset(dqcoeff_ptr, 0, 32);     eob = -1;     for (i = 0; i < 16; i++)    {        rc   = vp8_default_zig_zag1d[i];        z    = coeff_ptr[rc];         zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;         zbin_boost_ptr ++;        sz = (z >> 31);                              /* sign of z */        x  = (z ^ sz) - sz;                          /* x = abs(z) */         if (x >= zbin)        {            x += round_ptr[rc];            y  = ((((x * quant_ptr[rc]) >> 16) + x)                 * quant_shift_ptr[rc]) >> 16;       /* quantize (x) */            x  = (y ^ sz) - sz;                      /* get the sign back */            qcoeff_ptr[rc]  = x;                     /* write to destination */            dqcoeff_ptr[rc] = x * dequant_ptr[rc];   /* dequantized value */             if (y)            {                eob = i;                             /* last nonzero coeffs */                zbin_boost_ptr = b->zrun_zbin_boost; /* reset zero runlength */            }        }    }     *d->eob = (char)(eob + 1);} void vp8_quantize_mby(MACROBLOCK *x){    int i;    int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);     for (i = 0; i < 16; i++)        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);     if(has_2nd_order)        x->quantize_b(&x->block[24], &x->e_mbd.block[24]);} void vp8_quantize_mb(MACROBLOCK *x){    int i;    int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);     for (i = 0; i < 24+has_2nd_order; i++)        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);}  void vp8_quantize_mbuv(MACROBLOCK *x){    int i;     for (i = 16; i < 24; i++)        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);} static const int qrounding_factors[129] ={    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48};  static const int qzbin_factors[129] ={    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80};  static const int qrounding_factors_y2[129] ={    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48, 48, 48, 48, 48, 48, 48, 48,    48};  static const int qzbin_factors_y2[129] ={    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    84, 84, 84, 84, 84, 84, 84, 84,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80, 80, 80, 80, 80, 80, 80, 80,    80};  static void invert_quant(int improved_quant, short *quant,                         short *shift, short d){    if(improved_quant)    {        unsigned t;        int l;        t = d;        for(l = 0; t > 1; l++)            t>>=1;        t = 1 + (1<<(16+l))/d;        *quant = (short)(t - (1<<16));        *shift = l;        /* use multiplication and constant shift by 16 */        *shift = 1 << (16 - *shift);    }    else    {        *quant = (1 << 16) / d;        *shift = 0;        /* use multiplication and constant shift by 16 */        *shift = 1 << (16 - *shift);    }}  void vp8cx_init_quantizer(VP8_COMP *cpi){    int i;    int quant_val;    int Q;     int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44,                          44, 44};     for (Q = 0; Q < QINDEX_RANGE; Q++)    {        /* dc values */        quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);        cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;        invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,                     cpi->Y1quant_shift[Q] + 0, quant_val);        cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;        cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;        cpi->common.Y1dequant[Q][0] = quant_val;        cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;         quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);        cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;        invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,                     cpi->Y2quant_shift[Q] + 0, quant_val);        cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;        cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;        cpi->common.Y2dequant[Q][0] = quant_val;        cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;         quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);        cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;        invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,                     cpi->UVquant_shift[Q] + 0, quant_val);        cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;        cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;        cpi->common.UVdequant[Q][0] = quant_val;        cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;         /* all the ac values = ; */        quant_val = vp8_ac_yquant(Q);        cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val;        invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1,                     cpi->Y1quant_shift[Q] + 1, quant_val);        cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;        cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;        cpi->common.Y1dequant[Q][1] = quant_val;        cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7;         quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);        cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val;        invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1,                     cpi->Y2quant_shift[Q] + 1, quant_val);        cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;        cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7;        cpi->common.Y2dequant[Q][1] = quant_val;        cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7;         quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);        cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val;        invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1,                     cpi->UVquant_shift[Q] + 1, quant_val);        cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;        cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;        cpi->common.UVdequant[Q][1] = quant_val;        cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7;         for (i = 2; i < 16; i++)        {            cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1];            cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1];            cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1];            cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1];            cpi->Y1round[Q][i] = cpi->Y1round[Q][1];            cpi->zrun_zbin_boost_y1[Q][i] = (cpi->common.Y1dequant[Q][1] *                                             zbin_boost[i]) >> 7;             cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1];            cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1];            cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1];            cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1];            cpi->Y2round[Q][i] = cpi->Y2round[Q][1];            cpi->zrun_zbin_boost_y2[Q][i] = (cpi->common.Y2dequant[Q][1] *                                             zbin_boost[i]) >> 7;             cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1];            cpi->UVquant[Q][i] = cpi->UVquant[Q][1];            cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1];            cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1];            cpi->UVround[Q][i] = cpi->UVround[Q][1];            cpi->zrun_zbin_boost_uv[Q][i] = (cpi->common.UVdequant[Q][1] *                                             zbin_boost[i]) >> 7;        }    }} #define ZBIN_EXTRA_Y \    (( cpi->common.Y1dequant[QIndex][1] *  \    ( x->zbin_over_quant +  \      x->zbin_mode_boost +  \      x->act_zbin_adj ) ) >> 7) #define ZBIN_EXTRA_UV \    (( cpi->common.UVdequant[QIndex][1] *  \    ( x->zbin_over_quant +  \      x->zbin_mode_boost +  \      x->act_zbin_adj ) ) >> 7) #define ZBIN_EXTRA_Y2 \    (( cpi->common.Y2dequant[QIndex][1] *  \    ( (x->zbin_over_quant / 2) +  \       x->zbin_mode_boost +  \       x->act_zbin_adj ) ) >> 7) void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip){    int i;    int QIndex;    MACROBLOCKD *xd = &x->e_mbd;    int zbin_extra;     /* Select the baseline MB Q index. */    if (xd->segmentation_enabled)    {        /* Abs Value */        if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)            QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];        /* Delta Value */        else        {            QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];            /* Clamp to valid range */            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;        }    }    else        QIndex = cpi->common.base_qindex;     /* This initialization should be called at least once. Use ok_to_skip to     * decide if it is ok to skip.     * Before encoding a frame, this function is always called with ok_to_skip     * =0, which means no skiping of calculations. The "last" values are     * initialized at that time.     */    if (!ok_to_skip || QIndex != x->q_index)    {         xd->dequant_y1_dc[0] = 1;        xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0];        xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0];        xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0];         for (i = 1; i < 16; i++)        {            xd->dequant_y1_dc[i] =            xd->dequant_y1[i] = cpi->common.Y1dequant[QIndex][1];            xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1];            xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1];        }#if 1        /*TODO:  Remove dequant from BLOCKD.  This is a temporary solution until         * the quantizer code uses a passed in pointer to the dequant constants.         * This will also require modifications to the x86 and neon assembly.         * */        for (i = 0; i < 16; i++)            x->e_mbd.block[i].dequant = xd->dequant_y1;        for (i = 16; i < 24; i++)            x->e_mbd.block[i].dequant = xd->dequant_uv;        x->e_mbd.block[24].dequant = xd->dequant_y2;#endif         /* Y */        zbin_extra = ZBIN_EXTRA_Y;         for (i = 0; i < 16; i++)        {            x->block[i].quant = cpi->Y1quant[QIndex];            x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];            x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];            x->block[i].zbin = cpi->Y1zbin[QIndex];            x->block[i].round = cpi->Y1round[QIndex];            x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];            x->block[i].zbin_extra = (short)zbin_extra;        }         /* UV */        zbin_extra = ZBIN_EXTRA_UV;         for (i = 16; i < 24; i++)        {            x->block[i].quant = cpi->UVquant[QIndex];            x->block[i].quant_fast = cpi->UVquant_fast[QIndex];            x->block[i].quant_shift = cpi->UVquant_shift[QIndex];            x->block[i].zbin = cpi->UVzbin[QIndex];            x->block[i].round = cpi->UVround[QIndex];            x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];            x->block[i].zbin_extra = (short)zbin_extra;        }         /* Y2 */        zbin_extra = ZBIN_EXTRA_Y2;         x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];        x->block[24].quant = cpi->Y2quant[QIndex];        x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];        x->block[24].zbin = cpi->Y2zbin[QIndex];        x->block[24].round = cpi->Y2round[QIndex];        x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];        x->block[24].zbin_extra = (short)zbin_extra;         /* save this macroblock QIndex for vp8_update_zbin_extra() */        x->q_index = QIndex;         x->last_zbin_over_quant = x->zbin_over_quant;        x->last_zbin_mode_boost = x->zbin_mode_boost;        x->last_act_zbin_adj = x->act_zbin_adj;       }    else if(x->last_zbin_over_quant != x->zbin_over_quant            || x->last_zbin_mode_boost != x->zbin_mode_boost            || x->last_act_zbin_adj != x->act_zbin_adj)    {        /* Y */        zbin_extra = ZBIN_EXTRA_Y;         for (i = 0; i < 16; i++)            x->block[i].zbin_extra = (short)zbin_extra;         /* UV */        zbin_extra = ZBIN_EXTRA_UV;         for (i = 16; i < 24; i++)            x->block[i].zbin_extra = (short)zbin_extra;         /* Y2 */        zbin_extra = ZBIN_EXTRA_Y2;        x->block[24].zbin_extra = (short)zbin_extra;         x->last_zbin_over_quant = x->zbin_over_quant;        x->last_zbin_mode_boost = x->zbin_mode_boost;        x->last_act_zbin_adj = x->act_zbin_adj;    }} void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x){    int i;    int QIndex = x->q_index;    int zbin_extra;

Lines 1–500 of 583.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t