[FFmpeg-soc] [soc]: r3895 - in dirac/libavcodec: dirac.h diracdec.c
conrad
subversion at mplayerhq.hu
Sun Dec 28 08:28:09 CET 2008
Author: conrad
Date: Sun Dec 28 08:28:09 2008
New Revision: 3895
Log:
Add support for VLC/golomb coding of dwt coefficients
Modified:
dirac/libavcodec/dirac.h
dirac/libavcodec/diracdec.c
Modified: dirac/libavcodec/dirac.h
==============================================================================
--- dirac/libavcodec/dirac.h Sat Dec 27 13:28:29 2008 (r3894)
+++ dirac/libavcodec/dirac.h Sun Dec 28 08:28:09 2008 (r3895)
@@ -196,6 +196,7 @@ typedef struct DiracContext {
int sbheight; ///< number of superblocks (vertically)
int zero_res; ///< zero residue flag
+ int is_arith; ///< whether coeffs use arith or golomb coding
int refs; ///< number of reference pictures
int globalmc_flag; ///< use global motion compensation flag
Modified: dirac/libavcodec/diracdec.c
==============================================================================
--- dirac/libavcodec/diracdec.c Sat Dec 27 13:28:29 2008 (r3894)
+++ dirac/libavcodec/diracdec.c Sun Dec 28 08:28:09 2008 (r3895)
@@ -132,7 +132,7 @@ static inline int coeff_dequant(int coef
* @param qoffset quantizer offset
* @param qfact quantizer factor
*/
-static void coeff_unpack(DiracContext *s, SubBand *b,
+static inline void coeff_unpack_arith(DiracContext *s, SubBand *b,
int x, int y,
int qoffset, int qfactor)
{
@@ -171,6 +171,18 @@ static void coeff_unpack(DiracContext *s
*coeffp = coeff;
}
+static inline void coeff_unpack_vlc(DiracContext *s, SubBand *b,
+ int x, int y, int qoffset, int qfactor)
+{
+ int coeff, sign;
+ coeff = sign = svq3_get_ue_golomb(&s->gb);
+ coeff = coeff_dequant(coeff, qoffset, qfactor);
+ if (sign && get_bits1(&s->gb))
+ coeff = -coeff;
+
+ b->ibuf[y * b->stride + x] = coeff;
+}
+
/**
* Decode a codeblock
*
@@ -182,9 +194,9 @@ static void coeff_unpack(DiracContext *s
* @param quant quantizer offset
* @param quant quantizer factor
*/
-static void codeblock(DiracContext *s, SubBand *b,
+static inline void codeblock(DiracContext *s, SubBand *b,
int cb_x, int cb_y, int cb_numx, int cb_numy,
- unsigned int *quant, int blockcnt_one)
+ unsigned int *quant, int blockcnt_one, int is_arith)
{
int left, right, top, bottom;
int x, y;
@@ -196,20 +208,32 @@ static void codeblock(DiracContext *s, S
bottom = (b->height * (cb_y+1)) / cb_numy;
if (!blockcnt_one) {
+ int zero_block;
/* Determine if this codeblock is a zero block. */
- if (dirac_arith_get_bit(&s->arith, ARITH_CONTEXT_ZERO_BLOCK))
+ if (is_arith)
+ zero_block = dirac_arith_get_bit(&s->arith, ARITH_CONTEXT_ZERO_BLOCK);
+ else
+ zero_block = get_bits1(&s->gb);
+
+ if (zero_block)
return;
- if (s->codeblock_mode)
+ if (s->codeblock_mode && is_arith)
*quant += dirac_arith_read_int(&s->arith, &ff_dirac_context_set_quant);
+ else if (s->codeblock_mode)
+ *quant += dirac_get_se_golomb(&s->gb);
}
qfactor = coeff_quant_factor(*quant);
qoffset = coeff_quant_offset(s->refs == 0, *quant) + 2;
for (y = top; y < bottom; y++)
- for (x = left; x < right; x++)
- coeff_unpack(s, b, x, y, qoffset, qfactor);
+ for (x = left; x < right; x++) {
+ if (is_arith)
+ coeff_unpack_arith(s, b, x, y, qoffset, qfactor);
+ else
+ coeff_unpack_vlc(s, b, x, y, qoffset, qfactor);
+ }
}
/**
@@ -217,7 +241,7 @@ static void codeblock(DiracContext *s, S
*
* @param data coefficients
*/
-static void intra_dc_prediction(SubBand *b)
+static inline void intra_dc_prediction(SubBand *b)
{
int x, y;
int16_t *line = b->ibuf;
@@ -237,7 +261,7 @@ static void intra_dc_prediction(SubBand
* @param level subband level
* @param orientation orientation of the subband
*/
-static int subband(DiracContext *s, SubBand *b)
+static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
{
GetBitContext *gb = &s->gb;
unsigned int length;
@@ -252,12 +276,15 @@ static int subband(DiracContext *s, SubB
align_get_bits(gb);
} else {
quant = svq3_get_ue_golomb(gb);
+ align_get_bits(gb);
+ if (is_arith)
dirac_arith_init(&s->arith, gb, length);
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);
+ codeblock(s, b, cb_x, cb_y, cb_numx, cb_numy, &quant, blockcnt_one, is_arith);
+ if (is_arith)
dirac_arith_flush(&s->arith);
}
@@ -267,6 +294,16 @@ static int subband(DiracContext *s, SubB
return 0;
}
+static av_noinline int decode_subband_arith(DiracContext *s, SubBand *b)
+{
+ return decode_subband_internal(s, b, 1);
+}
+
+static av_noinline int decode_subband_vlc(DiracContext *s, SubBand *b)
+{
+ return decode_subband_internal(s, b, 0);
+}
+
/**
* Decode a single component
*
@@ -283,7 +320,10 @@ static void decode_component(DiracContex
for (orientation = (level ? 1 : 0); orientation < 4; orientation++) {
SubBand *b = &s->plane[comp].band[level][orientation];
align_get_bits(gb);
- subband(s, b);
+ if (s->is_arith)
+ decode_subband_arith(s, b);
+ else
+ decode_subband_vlc(s, b);
}
}
}
@@ -821,6 +861,7 @@ static int alloc_frame(AVCodecContext *a
avcodec_get_frame_defaults(pic);
s->refs = parse_code & 0x03;
+ s->is_arith = (parse_code & 0x48) == 0x08;
pic->reference = (parse_code & 0x0C) == 0x0C;
pic->key_frame = s->refs == 0;
pic->pict_type = pict_type[s->refs];
More information about the FFmpeg-soc
mailing list