media/libtheora/lib/quant.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /********************************************************************
michael@0 2 * *
michael@0 3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
michael@0 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
michael@0 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
michael@0 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
michael@0 7 * *
michael@0 8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 *
michael@0 9 * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
michael@0 10 * *
michael@0 11 ********************************************************************
michael@0 12
michael@0 13 function:
michael@0 14 last mod: $Id: quant.c 17307 2010-06-27 06:02:15Z tterribe $
michael@0 15
michael@0 16 ********************************************************************/
michael@0 17
michael@0 18 #include <stdlib.h>
michael@0 19 #include <string.h>
michael@0 20 #include <ogg/ogg.h>
michael@0 21 #include "quant.h"
michael@0 22 #include "decint.h"
michael@0 23
michael@0 24 /*The maximum output of the DCT with +/- 255 inputs is +/- 8157.
michael@0 25 These minimum quantizers ensure the result after quantization (and after
michael@0 26 prediction for DC) will be no more than +/- 510.
michael@0 27 The tokenization system can handle values up to +/- 580, so there is no need
michael@0 28 to do any coefficient clamping.
michael@0 29 I would rather have allowed smaller quantizers and had to clamp, but these
michael@0 30 minimums were required when constructing the original VP3 matrices and have
michael@0 31 been formalized in the spec.*/
michael@0 32 static const unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2};
michael@0 33 static const unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2};
michael@0 34
michael@0 35 /*Initializes the dequantization tables from a set of quantizer info.
michael@0 36 Currently the dequantizer (and elsewhere enquantizer) tables are expected to
michael@0 37 be initialized as pointing to the storage reserved for them in the
michael@0 38 oc_theora_state (resp. oc_enc_ctx) structure.
michael@0 39 If some tables are duplicates of others, the pointers will be adjusted to
michael@0 40 point to a single copy of the tables, but the storage for them will not be
michael@0 41 freed.
michael@0 42 If you're concerned about the memory footprint, the obvious thing to do is
michael@0 43 to move the storage out of its fixed place in the structures and allocate
michael@0 44 it on demand.
michael@0 45 However, a much, much better option is to only store the quantization
michael@0 46 matrices being used for the current frame, and to recalculate these as the
michael@0 47 qi values change between frames (this is what VP3 did).*/
michael@0 48 void oc_dequant_tables_init(ogg_uint16_t *_dequant[64][3][2],
michael@0 49 int _pp_dc_scale[64],const th_quant_info *_qinfo){
michael@0 50 /*Coding mode: intra or inter.*/
michael@0 51 int qti;
michael@0 52 /*Y', C_b, C_r*/
michael@0 53 int pli;
michael@0 54 for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
michael@0 55 /*Quality index.*/
michael@0 56 int qi;
michael@0 57 /*Range iterator.*/
michael@0 58 int qri;
michael@0 59 for(qi=0,qri=0;qri<=_qinfo->qi_ranges[qti][pli].nranges;qri++){
michael@0 60 th_quant_base base;
michael@0 61 ogg_uint32_t q;
michael@0 62 int qi_start;
michael@0 63 int qi_end;
michael@0 64 memcpy(base,_qinfo->qi_ranges[qti][pli].base_matrices[qri],
michael@0 65 sizeof(base));
michael@0 66 qi_start=qi;
michael@0 67 if(qri==_qinfo->qi_ranges[qti][pli].nranges)qi_end=qi+1;
michael@0 68 else qi_end=qi+_qinfo->qi_ranges[qti][pli].sizes[qri];
michael@0 69 /*Iterate over quality indicies in this range.*/
michael@0 70 for(;;){
michael@0 71 ogg_uint32_t qfac;
michael@0 72 int zzi;
michael@0 73 int ci;
michael@0 74 /*In the original VP3.2 code, the rounding offset and the size of the
michael@0 75 dead zone around 0 were controlled by a "sharpness" parameter.
michael@0 76 The size of our dead zone is now controlled by the per-coefficient
michael@0 77 quality thresholds returned by our HVS module.
michael@0 78 We round down from a more accurate value when the quality of the
michael@0 79 reconstruction does not fall below our threshold and it saves bits.
michael@0 80 Hence, all of that VP3.2 code is gone from here, and the remaining
michael@0 81 floating point code has been implemented as equivalent integer code
michael@0 82 with exact precision.*/
michael@0 83 qfac=(ogg_uint32_t)_qinfo->dc_scale[qi]*base[0];
michael@0 84 /*For postprocessing, not dequantization.*/
michael@0 85 if(_pp_dc_scale!=NULL)_pp_dc_scale[qi]=(int)(qfac/160);
michael@0 86 /*Scale DC the coefficient from the proper table.*/
michael@0 87 q=(qfac/100)<<2;
michael@0 88 q=OC_CLAMPI(OC_DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
michael@0 89 _dequant[qi][pli][qti][0]=(ogg_uint16_t)q;
michael@0 90 /*Now scale AC coefficients from the proper table.*/
michael@0 91 for(zzi=1;zzi<64;zzi++){
michael@0 92 q=((ogg_uint32_t)_qinfo->ac_scale[qi]*base[OC_FZIG_ZAG[zzi]]/100)<<2;
michael@0 93 q=OC_CLAMPI(OC_AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
michael@0 94 _dequant[qi][pli][qti][zzi]=(ogg_uint16_t)q;
michael@0 95 }
michael@0 96 /*If this is a duplicate of a previous matrix, use that instead.
michael@0 97 This simple check helps us improve cache coherency later.*/
michael@0 98 {
michael@0 99 int dupe;
michael@0 100 int qtj;
michael@0 101 int plj;
michael@0 102 dupe=0;
michael@0 103 for(qtj=0;qtj<=qti;qtj++){
michael@0 104 for(plj=0;plj<(qtj<qti?3:pli);plj++){
michael@0 105 if(!memcmp(_dequant[qi][pli][qti],_dequant[qi][plj][qtj],
michael@0 106 sizeof(oc_quant_table))){
michael@0 107 dupe=1;
michael@0 108 break;
michael@0 109 }
michael@0 110 }
michael@0 111 if(dupe)break;
michael@0 112 }
michael@0 113 if(dupe)_dequant[qi][pli][qti]=_dequant[qi][plj][qtj];
michael@0 114 }
michael@0 115 if(++qi>=qi_end)break;
michael@0 116 /*Interpolate the next base matrix.*/
michael@0 117 for(ci=0;ci<64;ci++){
michael@0 118 base[ci]=(unsigned char)(
michael@0 119 (2*((qi_end-qi)*_qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
michael@0 120 (qi-qi_start)*_qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
michael@0 121 +_qinfo->qi_ranges[qti][pli].sizes[qri])/
michael@0 122 (2*_qinfo->qi_ranges[qti][pli].sizes[qri]));
michael@0 123 }
michael@0 124 }
michael@0 125 }
michael@0 126 }
michael@0 127 }

mercurial