[FFmpeg-soc] [soc]: r481 - dirac/dirac.c

marco subversion at mplayerhq.hu
Wed Jul 18 14:36:39 CEST 2007


Author: marco
Date: Wed Jul 18 14:36:39 2007
New Revision: 481

Log:
Move the dequantization functions and actually use them.


Modified:
   dirac/dirac.c

Modified: dirac/dirac.c
==============================================================================
--- dirac/dirac.c	(original)
+++ dirac/dirac.c	Wed Jul 18 14:36:39 2007
@@ -834,6 +834,47 @@ static int inline subband_height(AVCodec
     return s->padded_height >> (s->frame_decoding.wavelet_depth - level + 1);
 }
 
+static int inline coeff_quant_factor(int idx) {
+    int base;
+    idx = FFMAX(idx, 0);
+    base = 1 << (idx / 4);
+    switch(idx & 3) {
+    case 0:
+        return base << 2;
+    case 1:
+        return (503829 * base + 52958) / 105917;
+    case 2:
+        return (665857 * idx + 58854) / 117708;
+    case 3:
+        return (440253 * base + 32722) / 65444;
+    }
+    return 0; /* XXX: should never be reached */
+}
+
+static int inline coeff_quant_offset(int idx) {
+    if (idx == 0)
+        return 1;
+    /* XXX: Hardcode for intra frames.  */
+    if (idx == 1)
+        return 2;
+    return (coeff_quant_factor(idx) + 1) >> 1;
+}
+
+static int inline coeff_dequant(int coeff, int idx) {
+    int64_t magnitude = abs(coeff) * coeff_quant_factor(idx);
+
+    if (! magnitude)
+        return 0;
+
+    magnitude += coeff_quant_offset(idx) + 2;
+    magnitude >>= 2;
+
+    /* Reintroduce the sign.  */
+    if (coeff < 0)
+        magnitude = -magnitude;
+    return magnitude;
+}
+
 static int inline coeff_posx(AVCodecContext *avctx, int level,
                       subband_t orientation, int x) {
     int right = 0;
@@ -899,7 +940,7 @@ static int sign_predict(AVCodecContext *
 }
 
 static void coeff_unpack(AVCodecContext *avctx, int *data, int level,
-                         subband_t orientation, int v, int h) {
+                         subband_t orientation, int v, int h, int quant) {
     int parent = 0;
     int nhood;
     int sign_pred;
@@ -916,11 +957,16 @@ static void coeff_unpack(AVCodecContext 
         parent = data[s->padded_width * y + x] != 0;
     }
 
+    /* XXX: This was recently changed in the reference specification
+       to function exactly like in the specification.  For now, I'll
+       match this behavior.  */
+#if 0
     /* XXX: this is what the reference implementation effectively
        does, although this does not seem to comply with the spec.  I
        have asked the Dirac BBC why this seems to be required.  */
     if (level < 2)
         parent = 1;
+#endif
 
     /* Determine if the pixel has only zeros in its neighbourhood.  */
     nhood = zero_neighbourhood(avctx, data, level, orientation, v, h);
@@ -939,11 +985,13 @@ static void coeff_unpack(AVCodecContext 
     coeff = arith_read_int(avctx, context);
     vdata = coeff_posy(avctx, level, orientation, v);
     hdata = coeff_posx(avctx, level, orientation, h);
+    coeff = coeff_dequant(coeff, quant);
+
     data[hdata + vdata * s->padded_width] = coeff;
 }
 
 static void codeblock(AVCodecContext *avctx, int *data, int level,
-                      subband_t orientation, int x, int y) {
+                      subband_t orientation, int x, int y, int quant) {
     DiracContext *s = avctx->priv_data;
     int blockcnt = s->codeblocksh[level] * s->codeblocksv[level];
     int zero = 0;
@@ -967,7 +1015,7 @@ static void codeblock(AVCodecContext *av
        spec.  */
     for (v = top; v < bottom; v++)
         for (h = left; h < right; h++)
-            coeff_unpack(avctx, data, level, orientation, v, h);
+            coeff_unpack(avctx, data, level, orientation, v, h, quant);
 
     /* XXX: Quantization.  */
 }
@@ -1023,7 +1071,7 @@ static int subband(AVCodecContext *avctx
 
             for (y = 0; y < s->codeblocksv[level]; y++)
                 for (x = 0; x < s->codeblocksh[level]; x++)
-                    codeblock(avctx, data, level, orientation, x, y);
+                    codeblock(avctx, data, level, orientation, x, y, quant);
             arith_flush(avctx);
         }
 
@@ -1034,47 +1082,6 @@ static int subband(AVCodecContext *avctx
     return 0;
 }
 
-static int inline coeff_quant_factor(int idx) {
-    int base;
-    if (idx < 0)
-        idx = 0;
-    base = 1 << (idx / 4);
-    switch(idx & 3) {
-    case 0:
-        return base << 2;
-    case 1:
-        return (503829 * base + 52958) / 105917;
-    case 2:
-        return (665857 * idx + 58854) / 117708;
-    case 3:
-        return (440253 * base + 32722) / 65444;
-    }
-}
-
-static int inline coeff_quant_offset(int idx) {
-    if (idx == 0)
-        return 1;
-    /* XXX: Hardcode for intra frames.  */
-    if (idx == 1)
-        return 2;
-    return (coeff_quant_factor(idx) + 1) >> 1;
-}
-
-static int inline coeff_dequant(int coeff, int idx) {
-    int64_t magnitude = abs(coeff) * coeff_quant_factor(idx);
-
-    if (! magnitude)
-        return 0;
-
-    magnitude += coeff_quant_offset(idx) + 2;
-    magnitude >>= 2;
-
-    /* Reintroduce the sign.  */
-    if (coeff < 0)
-        magnitude = -magnitude;
-    return magnitude;
-}
-
 static void decode_component(AVCodecContext *avctx, int *coeffs) {
     DiracContext *s = avctx->priv_data;
     GetBitContext *gb = s->gb;



More information about the FFmpeg-soc mailing list