[soc]: r3895 - in dirac/libavcodec: dirac.h diracdec.c
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];
participants (1)
-
conrad