[FFmpeg-soc] [soc]: r3879 - in dirac/libavcodec: dirac.h diracdec.c

conrad subversion at mplayerhq.hu
Tue Dec 9 23:05:45 CET 2008


Author: conrad
Date: Tue Dec  9 23:05:45 2008
New Revision: 3879

Log:
Use Plane and SubBand structs (based on snow)


Modified:
   dirac/libavcodec/dirac.h
   dirac/libavcodec/diracdec.c

Modified: dirac/libavcodec/dirac.h
==============================================================================
--- dirac/libavcodec/dirac.h	(original)
+++ dirac/libavcodec/dirac.h	Tue Dec  9 23:05:45 2008
@@ -31,6 +31,7 @@
 #include "avcodec.h"
 #include "bitstream.h"
 #include "dirac_arith.h"
+#include "dsputil.h"
 
 typedef enum {
     COLOR_PRIMARY_HDTV,         ///< ITU-R BT. 709, also computer/web/sRGB
@@ -147,6 +148,25 @@ struct dirac_blockmotion {
 #define MAX_REFERENCE_FRAMES 16
 #define MAX_DELAYED_FRAMES 16
 #define MAX_FRAMES 32
+#define MAX_DECOMPOSITIONS 8
+
+typedef struct SubBand{
+    int level;
+    int orientation;
+    int stride;
+    int width;
+    int height;
+    IDWTELEM *ibuf;
+    struct SubBand *parent;
+} SubBand;
+
+typedef struct Plane{
+    int width;
+    int height;
+    int padded_width;
+    int padded_height;
+    SubBand band[MAX_DECOMPOSITIONS][4];
+} Plane;
 
 typedef struct DiracContext {
     AVCodecContext *avctx;
@@ -170,13 +190,8 @@ typedef struct DiracContext {
     struct decoding_parameters decoding;
 
     unsigned int codeblock_mode;
-    unsigned int codeblocksh[7]; /* XXX: 7 levels. */
-    unsigned int codeblocksv[7]; /* XXX: 7 levels. */
-
-    int padded_luma_width;    ///< padded luma width
-    int padded_luma_height;   ///< padded luma height
-    int padded_chroma_width;  ///< padded chroma width
-    int padded_chroma_height; ///< padded chroma height
+    unsigned int codeblocksh[MAX_DECOMPOSITIONS+1];
+    unsigned int codeblocksv[MAX_DECOMPOSITIONS+1];
 
     int chroma_hshift;        ///< horizontal bits to shift for choma
     int chroma_vshift;        ///< vertical bits to shift for choma
@@ -200,9 +215,9 @@ typedef struct DiracContext {
 
     unsigned int wavelet_idx;
 
+    Plane plane[3];
+
     /* Current component. */
-    int padded_width;         ///< padded width of the current component
-    int padded_height;        ///< padded height of the current component
     int width;
     int height;
     int xbsep;
@@ -237,32 +252,6 @@ typedef enum {
     subband_hh = 3
 } dirac_subband;
 
-/**
- * Calculate the width of a subband on a given level
- *
- * @param level subband level
- * @return subband width
- */
-static int inline subband_width(DiracContext *s, int level)
-{
-    if (level == 0)
-        return s->padded_width >> s->decoding.wavelet_depth;
-    return s->padded_width >> (s->decoding.wavelet_depth - level + 1);
-}
-
-/**
- * Calculate the height of a subband on a given level
- *
- * @param level subband level
- * @return height of the subband
- */
-static int inline subband_height(DiracContext *s, int level)
-{
-    if (level == 0)
-        return s->padded_height >> s->decoding.wavelet_depth;
-    return s->padded_height >> (s->decoding.wavelet_depth - level + 1);
-}
-
 // this assumes a max quantizer of 119 (larger would overflow 32 bits),
 // which schoedinger and dirac-research also assume
 static unsigned int inline coeff_quant_factor(unsigned int quant)
@@ -297,49 +286,13 @@ static unsigned int inline coeff_quant_o
     return (coeff_quant_factor(quant) * 3 + 4) >> 3;
 }
 
-/**
- * Calculate the horizontal position of a coefficient given a level,
- * orientation and horizontal position within the subband.
- *
- * @param level subband level
- * @param orientation orientation of the subband within the level
- * @param x position within the subband
- * @return horizontal position within the coefficient array
- */
-static int inline coeff_posx(DiracContext *s, int level,
-                             dirac_subband orientation, int x)
-{
-    if (orientation == subband_hl || orientation == subband_hh)
-        return subband_width(s, level) + x;
-
-    return x;
-}
-
-/**
- * Calculate the vertical position of a coefficient given a level,
- * orientation and vertical position within the subband.
- *
- * @param level subband level
- * @param orientation orientation of the subband within the level
- * @param y position within the subband
- * @return vertical position within the coefficient array
- */
 static inline
-int coeff_posy(DiracContext *s, int level, dirac_subband orientation, int y)
-{
-    if (orientation == subband_lh || orientation == subband_hh)
-        return subband_height(s, level) + y;
-
-    return y;
-}
-
-static inline
-int zero_neighbourhood(DiracContext *s, int16_t *data, int x, int y)
+int zero_neighbourhood(int16_t *data, int x, int y, int stride)
 {
     /* Check if there is a zero to the left and top left of this
        coefficient. */
-    if (y > 0 && (data[-s->padded_width]
-                  || ( x > 0 && data[-s->padded_width - 1])))
+    if (y > 0 && (data[-stride]
+                  || ( x > 0 && data[-stride - 1])))
         return 0;
     else if (x > 0 && data[- 1])
         return 0;
@@ -357,11 +310,11 @@ int zero_neighbourhood(DiracContext *s, 
  * @return prediction for the sign: -1 when negative, 1 when positive, 0 when 0
  */
 static inline
-int sign_predict(DiracContext *s, int16_t *data, dirac_subband orientation,
-                 int x, int y)
+int sign_predict(int16_t *data, dirac_subband orientation,
+                 int x, int y, int stride)
 {
     if (orientation == subband_hl && y > 0)
-        return DIRAC_SIGN(data[-s->padded_width]);
+        return DIRAC_SIGN(data[-stride]);
     else if (orientation == subband_lh && x > 0)
         return DIRAC_SIGN(data[-1]);
     else
@@ -369,13 +322,13 @@ int sign_predict(DiracContext *s, int16_
 }
 
 static inline
-int intra_dc_coeff_prediction(DiracContext *s, int16_t *coeff, int x, int y)
+int intra_dc_coeff_prediction(int16_t *coeff, int x, int y, int stride)
 {
     int pred;
     if (x > 0 && y > 0) {
         pred = (coeff[-1]
-                + coeff[-s->padded_width]
-                + coeff[-s->padded_width - 1]);
+                + coeff[-stride]
+                + coeff[-stride - 1]);
         if (pred > 0)
             pred = (pred + 1) / 3;
         else
@@ -384,7 +337,7 @@ int intra_dc_coeff_prediction(DiracConte
         /* Just use the coefficient left of this one. */
         pred = coeff[-1];
     } else if (y > 0)
-        pred = coeff[-s->padded_width];
+        pred = coeff[-stride];
     else
         pred = 0;
 

Modified: dirac/libavcodec/diracdec.c
==============================================================================
--- dirac/libavcodec/diracdec.c	(original)
+++ dirac/libavcodec/diracdec.c	Tue Dec  9 23:05:45 2008
@@ -131,8 +131,8 @@ static inline int coeff_dequant(int coef
  * @param qoffset quantizer offset
  * @param qfact quantizer factor
  */
-static void coeff_unpack(DiracContext *s, int16_t *data, int level,
-                         dirac_subband orientation, int x, int y,
+static void coeff_unpack(DiracContext *s, SubBand *b,
+                         int x, int y,
                          int qoffset, int qfactor)
 {
     int parent = 0;
@@ -142,26 +142,19 @@ static void coeff_unpack(DiracContext *s
     int read_sign;
     struct dirac_arith_context_set *context;
     int16_t *coeffp;
-    int vdata, hdata;
 
-    vdata = coeff_posy(s, level, orientation, y);
-    hdata = coeff_posx(s, level, orientation, x);
-
-    coeffp = &data[hdata + vdata * s->padded_width];
+    coeffp = &b->ibuf[y * b->stride + x];
 
     /* The value of the pixel belonging to the lower level. */
-    if (level >= 2) {
-        int low_x = coeff_posx(s, level - 1, orientation, x >> 1);
-        int low_y = coeff_posy(s, level - 1, orientation, y >> 1);
-        parent = data[s->padded_width * low_y + low_x] != 0;
-    }
+    if (b->parent)
+        parent = b->parent->ibuf[b->parent->stride * (y>>1) + (x>>1)] != 0;
 
     /* Determine if the pixel has only zeros in its neighbourhood. */
-    nhood = zero_neighbourhood(s, coeffp, x, y);
+    nhood = zero_neighbourhood(coeffp, x, y, b->stride);
 
     /* Calculate an index into context_sets_waveletcoeff. */
     idx = parent * 6 + (!nhood) * 3;
-    idx += sign_predict(s, coeffp, orientation, x, y);
+    idx += sign_predict(coeffp, b->orientation, x, y, b->stride);
 
     context = &ff_dirac_context_sets_waveletcoeff[idx];
 
@@ -188,19 +181,18 @@ static void coeff_unpack(DiracContext *s
  * @param quant quantizer offset
  * @param quant quantizer factor
  */
-static void codeblock(DiracContext *s, int16_t *data, int level,
-                      dirac_subband orientation, int cb_x, int cb_y,
-                      unsigned int *quant)
+static void codeblock(DiracContext *s, SubBand *b,
+                      int cb_x, int cb_y, int cb_numx, int cb_numy,
+                      unsigned int *quant, int blockcnt_one)
 {
-    int blockcnt_one = (s->codeblocksh[level] + s->codeblocksv[level]) == 2;
     int left, right, top, bottom;
     int x, y;
     unsigned int qoffset, qfactor;
 
-    left   = (subband_width(s, level)  *  cb_x     ) / s->codeblocksh[level];
-    right  = (subband_width(s, level)  * (cb_x + 1)) / s->codeblocksh[level];
-    top    = (subband_height(s, level) *  cb_y     ) / s->codeblocksv[level];
-    bottom = (subband_height(s, level) * (cb_y + 1)) / s->codeblocksv[level];
+    left   = (b->width  *  cb_x   ) / cb_numx;
+    right  = (b->width  * (cb_x+1)) / cb_numx;
+    top    = (b->height *  cb_y   ) / cb_numy;
+    bottom = (b->height * (cb_y+1)) / cb_numy;
 
     if (!blockcnt_one) {
         /* Determine if this codeblock is a zero block. */
@@ -216,7 +208,7 @@ static void codeblock(DiracContext *s, i
 
     for (y = top; y < bottom; y++)
         for (x = left; x < right; x++)
-            coeff_unpack(s, data, level, orientation, x, y, qoffset, qfactor);
+            coeff_unpack(s, b, x, y, qoffset, qfactor);
 }
 
 /**
@@ -224,16 +216,16 @@ static void codeblock(DiracContext *s, i
  *
  * @param data coefficients
  */
-static void intra_dc_prediction(DiracContext *s, int16_t *data)
+static void intra_dc_prediction(SubBand *b)
 {
     int x, y;
-    int16_t *line = data;
+    int16_t *line = b->ibuf;
 
-    for (y = 0; y < subband_height(s, 0); y++) {
-        for (x = 0; x < subband_width(s, 0); x++) {
-            line[x] += intra_dc_coeff_prediction(s, &line[x], x, y);
+    for (y = 0; y < b->height; y++) {
+        for (x = 0; x < b->width; x++) {
+            line[x] += intra_dc_coeff_prediction(&line[x], x, y, b->stride);
         }
-        line += s->padded_width;
+        line += b->stride;
     }
 }
 
@@ -244,13 +236,15 @@ static void intra_dc_prediction(DiracCon
  * @param level subband level
  * @param orientation orientation of the subband
  */
-static int subband(DiracContext *s, int16_t *data, int level,
-                   dirac_subband orientation)
+static int subband(DiracContext *s, SubBand *b)
 {
     GetBitContext *gb = &s->gb;
     unsigned int length;
     unsigned int quant;
     int cb_x, cb_y;
+    int cb_numx = s->codeblocksh[b->level + (b->orientation != subband_ll)];
+    int cb_numy = s->codeblocksv[b->level + (b->orientation != subband_ll)];
+    int blockcnt_one = (cb_numx + cb_numy) == 2;
 
     length = svq3_get_ue_golomb(gb);
     if (! length) {
@@ -260,14 +254,14 @@ static int subband(DiracContext *s, int1
 
         dirac_arith_init(&s->arith, gb, length);
 
-        for (cb_y = 0; cb_y < s->codeblocksv[level]; cb_y++)
-            for (cb_x = 0; cb_x < s->codeblocksh[level]; cb_x++)
-                codeblock(s, data, level, orientation, cb_x, cb_y, &quant);
+        for (cb_y = 0; cb_y < cb_numy; cb_y++)
+            for (cb_x = 0; cb_x < cb_numx; cb_x++)
+                codeblock(s, b, cb_x, cb_y, cb_numx, cb_numy, &quant, blockcnt_one);
         dirac_arith_flush(&s->arith);
     }
 
-    if (level == 0 && s->refs == 0)
-        intra_dc_prediction(s, data);
+    if (b->orientation == subband_ll && s->refs == 0)
+        intra_dc_prediction(b);
 
     return 0;
 }
@@ -277,23 +271,18 @@ static int subband(DiracContext *s, int1
  *
  * @param coeffs coefficients for this component
  */
-static void decode_component(DiracContext *s, int16_t *coeffs)
+static void decode_component(DiracContext *s, int comp)
 {
     GetBitContext *gb = &s->gb;
     int level;
     dirac_subband orientation;
 
-    /* Align for coefficient bitstream. */
-    align_get_bits(gb);
-
-    /* Unpack LL, level 0. */
-    subband(s, coeffs, 0, subband_ll);
-
-    /* Unpack all other subbands at all levels. */
-    for (level = 1; level <= s->decoding.wavelet_depth; level++) {
-        for (orientation = 1; orientation <= subband_hh; orientation++) {
+    /* Unpack all subbands at all levels. */
+    for (level = 0; level < s->decoding.wavelet_depth; level++) {
+        for (orientation = (level ? 1 : 0); orientation < 4; orientation++) {
+            SubBand *b = &s->plane[comp].band[level][orientation];
             align_get_bits(gb);
-            subband(s, coeffs, level, orientation);
+            subband(s, b);
         }
     }
 }
@@ -616,22 +605,22 @@ static int dirac_unpack_block_motion_dat
  * @param coeffs coefficients to transform
  * @return returns 0 on succes, otherwise -1
  */
-int dirac_idwt(DiracContext *s, int16_t *coeffs, int16_t *synth)
+int dirac_idwt(DiracContext *s, int16_t *coeffs, int16_t *synth, int comp)
 {
     int level;
     int width, height;
 
     for (level = 1; level <= s->decoding.wavelet_depth; level++) {
-        width  = subband_width(s, level);
-        height = subband_height(s, level);
+        width  = s->plane[comp].band[level-1][1].width;
+        height = s->plane[comp].band[level-1][1].height;
 
         switch(s->wavelet_idx) {
         case 0:
-            dirac_subband_idwt_97(s->avctx, width, height, s->padded_width,
+            dirac_subband_idwt_97(s->avctx, width, height, s->plane[comp].padded_width,
                                   coeffs, synth, level);
             break;
         case 1:
-            dirac_subband_idwt_53(s->avctx, width, height, s->padded_width,
+            dirac_subband_idwt_53(s->avctx, width, height, s->plane[comp].padded_width,
                                   coeffs, synth, level);
             break;
         default:
@@ -654,24 +643,56 @@ static int dirac_decode_frame_internal(D
     int16_t *coeffs;
     int16_t *line;
     int16_t *mcline;
-    int comp;
-    int x,y;
     int16_t *synth;
+    int comp, level, orientation;
+    int x, y;
 
-    if (avcodec_check_dimensions(s->avctx, s->padded_luma_width,
-                                 s->padded_luma_height))
-        return -1;
+#define PAD(size, depth) \
+         (((size + (1 << depth) - 1) >> depth) << depth)
 
-    coeffs = av_malloc(s->padded_luma_width * s->padded_luma_height
-                       * sizeof(int16_t));
+    for (comp = 0; comp < 3; comp++) {
+        int w = s->source.width  >> (comp ? s->chroma_hshift : 0);
+        int h = s->source.height >> (comp ? s->chroma_vshift : 0);
+
+        s->plane[comp].width  = w;
+        s->plane[comp].height = h;
+        s->plane[comp].padded_width  = w = PAD(w, s->decoding.wavelet_depth);
+        s->plane[comp].padded_height = h = PAD(h, s->decoding.wavelet_depth);
+
+        if (!comp) {
+            coeffs = av_malloc(w * h * sizeof(IDWTELEM));
     if (! coeffs) {
         av_log(s->avctx, AV_LOG_ERROR, "av_malloc() failed\n");
         return -1;
     }
+        }
+
+        for (level = s->decoding.wavelet_depth-1; level >= 0; level--) {
+            for (orientation = level ? 1 : 0; orientation < 4; orientation++) {
+                SubBand *b = &s->plane[comp].band[level][orientation];
+
+                b->ibuf   = coeffs;
+                b->level  = level;
+                b->stride = s->plane[comp].padded_width;
+                b->width  = (w + !(orientation&1))>>1;
+                b->height = (h + !(orientation>1))>>1;
+                b->orientation = orientation;
+
+                if (orientation & 1)
+                    b->ibuf += b->width;
+                if (orientation > 1)
+                    b->ibuf += b->height * b->stride;
+
+                if (level)
+                    b->parent = &s->plane[comp].band[level-1][orientation];
+            }
+            w = (w+1)>>1;
+            h = (h+1)>>1;
+        }
+    }
 
     /* Allocate memory for the IDWT to work in. */
-    synth = av_malloc(s->padded_luma_width * s->padded_luma_height
-                      * sizeof(int16_t));
+    synth = av_malloc(s->plane[0].padded_width * s->plane[0].padded_height * sizeof(int16_t));
     if (!synth) {
         av_log(avctx, AV_LOG_ERROR, "av_malloc() failed\n");
         return -1;
@@ -683,21 +704,14 @@ static int dirac_decode_frame_internal(D
 
         width  = s->source.width  >> (comp ? s->chroma_hshift : 0);
         height = s->source.height >> (comp ? s->chroma_vshift : 0);
-        if (comp == 0) {
-            s->padded_width  = s->padded_luma_width;
-            s->padded_height = s->padded_luma_height;
-        } else {
-            s->padded_width  = s->padded_chroma_width;
-            s->padded_height = s->padded_chroma_height;
-        }
 
         memset(coeffs, 0,
-               s->padded_width * s->padded_height * sizeof(int16_t));
+               s->plane[comp].padded_width * s->plane[comp].padded_height * sizeof(int16_t));
 
         if (!s->zero_res)
-            decode_component(s, coeffs);
+            decode_component(s, comp);
 
-        dirac_idwt(s, coeffs, synth);
+        dirac_idwt(s, coeffs, synth, comp);
 
         if (s->refs) {
             if (dirac_motion_compensation(s, coeffs, comp)) {
@@ -720,7 +734,7 @@ static int dirac_decode_frame_internal(D
                     frame[x]= av_clip_uint8(coeff + 128);
                 }
 
-                line  += s->padded_width;
+                line  += s->plane[comp].padded_width;
                 frame += s->current_picture->linesize[comp];
                 mcline    += s->width;
             }
@@ -730,7 +744,7 @@ static int dirac_decode_frame_internal(D
                     frame[x]= av_clip_uint8(line[x] + 128);
                 }
 
-                line  += s->padded_width;
+                line  += s->plane[comp].padded_width;
                 frame += s->current_picture->linesize[comp];
             }
         }
@@ -825,20 +839,6 @@ static int parse_frame(DiracContext *s)
             for (i = 0; i <= s->decoding.wavelet_depth; i++)
                 s->codeblocksh[i] = s->codeblocksv[i] = 1;
     }
-
-#define CALC_PADDING(size, depth) \
-         (((size + (1 << depth) - 1) >> depth) << depth)
-
-    /* Round up to a multiple of 2^depth. */
-    s->padded_luma_width    = CALC_PADDING(s->source.width,
-                                           s->decoding.wavelet_depth);
-    s->padded_luma_height   = CALC_PADDING(s->source.height,
-                                           s->decoding.wavelet_depth);
-    s->padded_chroma_width  = CALC_PADDING((s->source.width >> s->chroma_hshift),
-                                           s->decoding.wavelet_depth);
-    s->padded_chroma_height = CALC_PADDING((s->source.height >> s->chroma_vshift),
-                                           s->decoding.wavelet_depth);
-
     return 0;
 }
 



More information about the FFmpeg-soc mailing list