[FFmpeg-devel] [PATCH] Common code for Indeo interactive

Michael Niedermayer michaelni
Mon Mar 23 20:40:23 CET 2009


On Thu, Mar 19, 2009 at 11:12:40PM +0100, Maxim wrote:
> Hello guys,
> 
> here is the 1st part of my patch making FFmpeg decode Indeo interactive
> (indeo4/indeo5) streams. Both codecs are very similar but use abit
> different bitstream formats, so I decided myself to put all common
> functions and tables together and submit them as a separate patch.
> The 2nd part will be the long-awaited indeo5 decoder...
> Please review!

your attached files are not unified diffs

[...]
> /**
>  * @file ivi_common.c
>  * This file contains functions and data shared by both Indeo4 and Indeo5 decoders.
>  */
> 
> #define ALT_BITSTREAM_READER_LE
> #include "avcodec.h"
> #include "bitstream.h"
> #include "ivi_common.h"
> 
> 

> /**
>  *  inverse "nbits" bits of the value "val" and return the result right-justified
>  */
> static uint16_t ivi_inv_bits (uint16_t val, const int nbits)
> {
>     uint16_t  res = 0;
>     int     i;
> 
>     for (i = 0; i < nbits; i++) {
>         res |= (val & 1) << (nbits-i-1);
>         val >>= 1;
>     }
>     return res;
> }

we already have code to reverse bits and its table based and more efficient
also the ivi_ prefix seems unneeded


> 
> 
> /**
>  *  generates a huffman codebook from the given descriptor and convert it into the ffmpeg vlc table
>  *
>  *  @param cb   [in] pointer to codebook descriptor
>  *  @param pOut [out] where to place the generated VLC table
>  *  @param flag [in] flag: INIT_VLC_USE_STATIC or 0
>  *  @return     result code: 0 - OK, -1 = error (invalid codebook descriptor)
>  */
> int ivi_create_huff_from_desc (const IVIHuffDesc *cb, VLC *pOut, const int flag)

non static functions need a ff prefix


> {
>     int         result, pos, i, j, codes_per_row, prefix, last_row;
>     uint16_t    codewords[256]; /* FIXME: move this temporal storage out here? */
>     uint8_t     bits[256];
> 
>     pos = 0; /* current position = 0 */
> 
>     for (i = 0; i < cb->num_rows; i++) {
>         codes_per_row = 1 << cb->xbits[i];
>         last_row = (i - cb->num_rows + 1) != 0; /* = 0 for the last row */
>         prefix = ((1 << i) - 1) << (cb->xbits[i] + last_row);
> 
>         for (j = 0; j < codes_per_row; j++) {
>             if(pos >= 256)  /* some indeo5 codebooks can have more as 256 elements */
>                 break;      /* but only 256 codes are allowed! */
> 
>             bits[pos] = i + cb->xbits[i] + last_row;
>             if (bits[pos] > IVI_VLC_BITS)
>                 return -1; /* invalid descriptor */
> 
>             codewords[pos] = ivi_inv_bits((prefix | j), bits[pos]);
>             if (bits[pos] == 0)
>                 bits[pos] = 1;
> 
>             pos++;
>         }//for j
>     }//for i
> 
>     /* number of codewords = pos */
>     result = init_vlc(pOut, IVI_VLC_BITS, pos, &bits[0], 1, 1, &codewords[0], 2, 2, (flag & INIT_VLC_USE_STATIC) | INIT_VLC_LE);

#define INIT_VLC_USE_STATIC 1 ///< VERY strongly deprecated and forbidden


[...]
> /**
>  *  compare two huffman codebook descriptors
>  *
>  *  @param desc1    [in] ptr to the 1st descriptor to compare
>  *  @param desc2    [in] ptr to the 2nd descriptor to compare
>  *  @return         comparison result: 0 - equal, 1 - not equal
>  */
> int ivi_huff_desc_cmp (const IVIHuffDesc *desc1, const IVIHuffDesc *desc2)
> {
>     int i;
> 
>     if (desc1->num_rows != desc2->num_rows)
>         return 1;
> 
>     for (i = 0; i < desc1->num_rows; i++) {
>         if (desc1->xbits[i] != desc2->xbits[i])
>             return 1;
>     }
>     return 0;
> }

memcmp


> 
> 
> /**
>  *  copy huffman codebook descriptors
>  *
>  *  @param dst  [out] ptr to the destination descriptor
>  *  @param src  [in] ptr to the source descriptor
>  */
> void ivi_huff_desc_copy (IVIHuffDesc *dst, const IVIHuffDesc *src)
> {
>     int i;
> 
>     dst->num_rows = src->num_rows;
> 
>     for (i = 0; i < src->num_rows; i++)
>         dst->xbits[i] = src->xbits[i];
> }

memcpy


> 
> 
> /**
>  *  initialize planes (prepare descriptors, allocate buffers etc.)
>  *
>  *  @param planes       [in,out] pointer to the array of the plane descriptors
>  *  @param cfg          [in] pointer to the ivi_pic_config structure describing picture layout
>  *  @return             result code: 0 - OK
>  */
> int ivi_init_planes (IVIPlaneDesc *planes, const IVIPicConfig *cfg)
> {
>     int         p;
>     uint32_t    width_aligned, height_aligned, buf_size;
> 
>     /* fill in the descriptor of the luminance plane */
>     planes[0].width = cfg->pic_width;
>     planes[0].height = cfg->pic_height;
>     planes[0].num_bands = cfg->luma_bands;

vertical align


> 
>     /* allocate luma buffers (aligned on 16x16 for simplicity) */
>     if (planes[0].buf1)
>         av_free(planes[0].buf1);

teh if is redundant

[...]
>     planes[1].buf1 = av_malloc(buf_size);
>     if (planes[1].buf1 == NULL)
>         return AVERROR(ENOMEM);
>     planes[2].buf1 = av_malloc(buf_size);
>     if (planes[2].buf1 == NULL)
>         return AVERROR(ENOMEM);
>     planes[1].buf2 = av_malloc(buf_size);
>     if (planes[1].buf2 == NULL)
>         return AVERROR(ENOMEM);
>     planes[2].buf2 = av_malloc(buf_size);
>     if (planes[2].buf2 == NULL)
>         return AVERROR(ENOMEM);

loop


> 
>     if (planes[0].bands)
>         av_free(planes[0].bands);
>     planes[0].bands = av_mallocz(cfg->luma_bands * sizeof(IVIBandDesc));
>     if (planes[0].bands == NULL)
>         return AVERROR(ENOMEM);
> 
>     if (planes[1].bands)
>         av_free(planes[1].bands);
>     planes[1].bands = av_mallocz(cfg->chroma_bands * sizeof(IVIBandDesc));
>     if (planes[1].bands == NULL)
>         return AVERROR(ENOMEM);
> 
>     if (planes[2].bands)
>         av_free(planes[2].bands);
>     planes[2].bands = av_mallocz(cfg->chroma_bands * sizeof(IVIBandDesc));
>     if (planes[2].bands == NULL)
>         return AVERROR(ENOMEM);

loop

[...]
> 
> /**
>  *  decode size of the tile data
>  *  it's stored as a variable-length field having the following format:
>  *  if (tile_data_size < 255) than this field is only one byte long
>  *  if (tile_data_size >= 255) than this field four is byte long: 0xFF X1 X2 X3
>  *  where X1-X3 is size of the tile data
>  *
>  *  @param cb   [in] pointer to codebook descriptor
>  *  @param gb   [in,out] the GetBit context
>  *  @return     size of the tile data in bytes
>  */
> int ivi_dec_tile_data_size (GetBitContext *gb)
> {
>     int    len;
> 
>     if (get_bits1(gb)) {
>         len = get_bits(gb, 8);
>         if (len == 255)
>             len = get_bits_long(gb, 24);

>     }
>     else

belong on the same line in K&R style


>         len = 0;
> 
>     /* align the bitstream reader on the byte boundary */
>     align_get_bits(gb);
> 

>     return (len);

useless ()


> }
> 
> 
> /* butterfly operation for the inverse slant transform */
> #define IVI_SLANT_BFLY(x,y) t1 = x-y; x+=y; y = t1;
> 
> /* The following is a reflection using a,b = 1/2, 5/4 for the inverse slant transform */
> #define IVI_IREFLECT(s1,s2) {\
>     t1 = ((s1*5) + (s2*2) + 2) >> 2;\

t1 = s1 + ((s1 + s2*2 + 2) >> 2);\

and similar simplifications are possible for the others


[...]
>         IVI_INV_SLANT8(src[0], src[8], src[16], src[24], src[32], src[40], src[48], src[56], /* input operands*/
>                        dst[0], dst[8], dst[16], dst[24], dst[32], dst[40], dst[48], dst[56] /* output operands*/);

its known what src & dst are, the comments are redundant

[...]

> /**
>  *  this is a speed-up version of the inverse 2D slant transforms
>  *  for the case if there is a non-zero DC coeff and all AC coeffs are zero.
>  *  Performing the inverse slant transform in this case is equivalent to
>  *  spreading (DC_coeff + 1)/2 over the whole block.
>  *  It works much faster than performing the slant transform on a vector of zeroes.
>  *
>  *  @param  in          [in] pointer to the dc coefficient
>  *  @param  out         [out] pointer to the output buffer (frame)
>  *  @param  pitch       [in] pitch to move to the next y line
>  *  @param  blk_size    [in] transform block size
>  */
> void ivi_dc_slant_2d (int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
> {
>     int     x, y;
>     int16_t dc_coeff;
> 
>     dc_coeff = (*in + 1) >> 1;
> 
>     for (y = 0; y < blk_size; out += pitch, y++) {
>         for (x = 0; x < blk_size; x++)
>             out[x] = dc_coeff;
>     }
> }

each row/col should be likely checked, not just all or none 0


> 
> 
> /**
>  *  8x8 block motion compensation with adding delta
>  *
>  *  @param  buf     [in,out] pointer to the block in the current frame buffer containing delta
>  *  @param  ref_buf [in] pointer to the corresponding block in the reference frame
>  *  @param  pitch   [in] pitch for moving to the next y line
>  *  @param  mc_type [in] interpolation type
>  */
> static void ivi_mc_8x8_delta (int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type)
> {
>     int     i, r1, r2, r3, r4;
>     int16_t *wptr;
> 
>     switch(mc_type) {
>         case 0: /* fullpel (no interpolation) */
>             for (i = 0; i < 8; i++) {
>                 buf[0] += ref_buf[0];
>                 buf[1] += ref_buf[1];
>                 buf[2] += ref_buf[2];
>                 buf[3] += ref_buf[3];
>                 buf[4] += ref_buf[4];
>                 buf[5] += ref_buf[5];
>                 buf[6] += ref_buf[6];
>                 buf[7] += ref_buf[7];
>                 buf += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 1: /* horizontal halfpel interpolation */
>             for (i = 0; i < 8; i++) {
>                 r2 = ref_buf[1];
>                 r3 = ref_buf[2];
>                 r4 = ref_buf[3];
>                 buf[0] += (ref_buf[0] + r2) >> 1;
>                 buf[1] += (r2 + r3) >> 1;
>                 buf[2] += (r3 + r4) >> 1;
>                 r1 = ref_buf[4];
>                 buf[3] += (r4 + r1) >> 1;
>                 r2 = ref_buf[5];
>                 buf[4] += (r1 + r2) >> 1;
>                 r3 = ref_buf[6];
>                 buf[5] += (r2 + r3) >> 1;
>                 r4 = ref_buf[7];
>                 buf[6] += (r3 + r4) >> 1;
>                 r1 = ref_buf[8];
>                 buf[7] += (r4 + r1) >> 1;
>                 buf += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 2: /* vertical halfpel interpolation */
>             wptr = ref_buf + pitch;
>             for (i = 0; i < 8; i++) {
>                 buf[0] += (ref_buf[0] + wptr[0]) >> 1;
>                 buf[1] += (ref_buf[1] + wptr[1]) >> 1;
>                 buf[2] += (ref_buf[2] + wptr[2]) >> 1;
>                 buf[3] += (ref_buf[3] + wptr[3]) >> 1;
>                 buf[4] += (ref_buf[4] + wptr[4]) >> 1;
>                 buf[5] += (ref_buf[5] + wptr[5]) >> 1;
>                 buf[6] += (ref_buf[6] + wptr[6]) >> 1;
>                 buf[7] += (ref_buf[7] + wptr[7]) >> 1;
>                 buf += pitch;
>                 wptr += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 3: /* vertical and horizontal halfpel interpolation */
>             wptr = ref_buf + pitch;
>             for (i = 0; i < 8; i++) {
>                 r1 = ref_buf[1];
>                 r2 = wptr[1];
>                 buf[0] += (ref_buf[0] + r1 + wptr[0] + r2) >> 2;
>                 r3 = ref_buf[2];
>                 r4 = wptr[2];
>                 buf[1] += (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[3];
>                 r2 = wptr[3];
>                 buf[2] += (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[4];
>                 r4 = wptr[4];
>                 buf[3] += (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[5];
>                 r2 = wptr[5];
>                 buf[4] += (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[6];
>                 r4 = wptr[6];
>                 buf[5] += (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[7];
>                 r2 = wptr[7];
>                 buf[6] += (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[8];
>                 r4 = wptr[8];
>                 buf[7] += (r1 + r3 + r2 + r4) >> 2;
>                 buf += pitch;
>                 wptr += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>     }
> }

this can be simplified alot


> 
> 
> /**
>  *  4x4 block motion compensation with adding delta
>  *
>  *  @param  buf     [in,out] pointer to the block in the current frame buffer containing delta
>  *  @param  ref_buf [in] pointer to the corresponding block in the reference frame
>  *  @param  pitch   [in] pitch for moving to the next y line
>  *  @param  mc_type [in] interpolation type
>  */
> static void ivi_mc_4x4_delta (int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type)
> {
>     int     i, r1, r2, r3, r4;
>     int16_t *wptr;
> 
>     switch(mc_type) {
>         case 0: /* fullpel (no interpolation) */
>             for (i = 0; i < 4; i++) {
>                 buf[0] += ref_buf[0];
>                 buf[1] += ref_buf[1];
>                 buf[2] += ref_buf[2];
>                 buf[3] += ref_buf[3];
>                 buf += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 1: /* horizontal halfpel interpolation */
>             for (i = 0; i < 4; i++) {
>                 r2 = ref_buf[1];
>                 r3 = ref_buf[2];
>                 r4 = ref_buf[3];
>                 buf[0] += (ref_buf[0] + r2) >> 1;
>                 buf[1] += (r2 + r3) >> 1;
>                 buf[2] += (r3 + r4) >> 1;
>                 r1 = ref_buf[4];
>                 buf[3] += (r4 + r1) >> 1;
>                 buf += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 2: /* vertical halfpel interpolation */
>             wptr = ref_buf + pitch;
>             for (i = 0; i < 4; i++) {
>                 buf[0] += (ref_buf[0] + wptr[0]) >> 1;
>                 buf[1] += (ref_buf[1] + wptr[1]) >> 1;
>                 buf[2] += (ref_buf[2] + wptr[2]) >> 1;
>                 buf[3] += (ref_buf[3] + wptr[3]) >> 1;
>                 buf += pitch;
>                 wptr += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 3: /* vertical and horizontal halfpel interpolation */
>             wptr = ref_buf + pitch;
>             for (i = 0; i < 4; i++) {
>                 r1 = ref_buf[1];
>                 r2 = wptr[1];
>                 buf[0] += (ref_buf[0] + r1 + wptr[0] + r2) >> 2;
>                 r3 = ref_buf[2];
>                 r4 = wptr[2];
>                 buf[1] += (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[3];
>                 r2 = wptr[3];
>                 buf[2] += (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[4];
>                 r4 = wptr[4];
>                 buf[3] += (r1 + r3 + r2 + r4) >> 2;
>                 buf += pitch;
>                 wptr += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>     }
> }
> 
> 
> /**
>  *  motion compensation without adding delta
>  *
>  *  @param  buf     [in,out] pointer to the block in the current frame receiving the result
>  *  @param  ref_buf [in] pointer to the corresponding block in the reference frame
>  *  @param  pitch   [in] pitch for moving to the next y line
>  *  @param  mc_type [in] interpolation type
>  */
> static void ivi_mc_8x8_no_delta (int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type)
> {
>     int     i, r1, r2, r3, r4;
>     int16_t *wptr;
> 
>     switch(mc_type) {
>         case 0: /* fullpel (no interpolation, just copy) */
>             for (i = 0; i < 8; i++) {
>                 buf[0] = ref_buf[0];
>                 buf[1] = ref_buf[1];
>                 buf[2] = ref_buf[2];
>                 buf[3] = ref_buf[3];
>                 buf[4] = ref_buf[4];
>                 buf[5] = ref_buf[5];
>                 buf[6] = ref_buf[6];
>                 buf[7] = ref_buf[7];
>                 buf += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 1: /* horizontal halfpel interpolation */
>             for (i = 0; i < 8; i++) {
>                 r2 = ref_buf[1];
>                 r3 = ref_buf[2];
>                 r4 = ref_buf[3];
>                 buf[0] = (ref_buf[0] + r2) >> 1;
>                 buf[1] = (r2 + r3) >> 1;
>                 buf[2] = (r3 + r4) >> 1;
>                 r1 = ref_buf[4];
>                 buf[3] = (r4 + r1) >> 1;
>                 r2 = ref_buf[5];
>                 buf[4] = (r1 + r2) >> 1;
>                 r3 = ref_buf[6];
>                 buf[5] = (r2 + r3) >> 1;
>                 r4 = ref_buf[7];
>                 buf[6] = (r3 + r4) >> 1;
>                 r1 = ref_buf[8];
>                 buf[7] = (r4 + r1) >> 1;
>                 buf += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 2: /* vertical halfpel interpolation */
>             wptr = ref_buf + pitch;
>             for (i = 0; i < 8; i++) {
>                 buf[0] = (ref_buf[0] + wptr[0]) >> 1;
>                 buf[1] = (ref_buf[1] + wptr[1]) >> 1;
>                 buf[2] = (ref_buf[2] + wptr[2]) >> 1;
>                 buf[3] = (ref_buf[3] + wptr[3]) >> 1;
>                 buf[4] = (ref_buf[4] + wptr[4]) >> 1;
>                 buf[5] = (ref_buf[5] + wptr[5]) >> 1;
>                 buf[6] = (ref_buf[6] + wptr[6]) >> 1;
>                 buf[7] = (ref_buf[7] + wptr[7]) >> 1;
>                 buf += pitch;
>                 wptr += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>         case 3: /* vertical and horizontal halfpel interpolation */
>             wptr = ref_buf + pitch;
>             for (i = 0; i < 8; i++) {
>                 r1 = ref_buf[1];
>                 r2 = wptr[1];
>                 buf[0] = (ref_buf[0] + r1 + wptr[0] + r2) >> 2;
>                 r3 = ref_buf[2];
>                 r4 = wptr[2];
>                 buf[1] = (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[3];
>                 r2 = wptr[3];
>                 buf[2] = (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[4];
>                 r4 = wptr[4];
>                 buf[3] = (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[5];
>                 r2 = wptr[5];
>                 buf[4] = (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[6];
>                 r4 = wptr[6];
>                 buf[5] = (r1 + r3 + r2 + r4) >> 2;
>                 r1 = ref_buf[7];
>                 r2 = wptr[7];
>                 buf[6] = (r3 + r1 + r4 + r2) >> 2;
>                 r3 = ref_buf[8];
>                 r4 = wptr[8];
>                 buf[7] = (r1 + r3 + r2 + r4) >> 2;
>                 buf += pitch;
>                 wptr += pitch;
>                 ref_buf += pitch;
>             }
>             break;
>     }
> }
> 
> 
> /**
>  *  4x4 block motion compensation without adding delta
>  *
>  *  @param  buf     [in,out] pointer to the block in the current frame receiving the result
>  *  @param  ref_buf [in] pointer to the corresponding block in the reference frame
>  *  @param  pitch   [in] pitch for moving to the next y line
>  *  @param  mc_type [in] interpolation type
>  */
> static void ivi_mc_4x4_no_delta (int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type)
> {
>     int     i, r1, r2, r3, r4;
>     int16_t *wptr;

theres lots of factorization possible here


[...]
> /**
>  *  decode block data:
>  *  extract huffman-coded transform coefficients from the bitstream, dequantize them,
>  *  apply inverse transform and motion compensation in order to reconstruct picture
>  *
>  *  @param gb   [in,out] the GetBit context
>  *  @param band [in] pointer to the band descriptor
>  *  @param tile [in] pointer to the tile descriptor
>  *  @return     result code: 0 - OK, -1 = error (corrupted blocks data)
>  */
> int ivi_decode_blocks (GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
> {
>     int         mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val, pos, is_intra, mc_type, mv_x, mv_y;
>     int32_t     prev_dc, trvec[64];
>     uint32_t    cbp, sym, lo, hi, quant, buf_offs;
>     uint16_t    *dequant_tab, q;
>     IVIMbInfo   *mb;
>     RVMapDesc   *rvmap = band->rv_map;
>     void (*mc_with_delta_func)(int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type);
>     void (*mc_no_delta_func)(int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type);
> 
>     prev_dc = 0; /* init intra prediction for the DC coefficient */
> 
>     blk_size = band->blk_size;
>     num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */
>     num_coeffs = 16 << ((blk_size >> 2) & 2); /* 64 - for 8x8 block, 16 - for 4x4 */
>     if (blk_size == 8) {
>         mc_with_delta_func = ivi_mc_8x8_delta;
>         mc_no_delta_func = ivi_mc_8x8_no_delta;
>     }
>     else {
>         mc_with_delta_func = ivi_mc_4x4_delta;
>         mc_no_delta_func = ivi_mc_4x4_no_delta;
>     }
> 
>     for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {
>         is_intra = mb->type == 0;
>         cbp = mb->cbp;
>         quant = av_clip(band->glob_quant + mb->q_delta, 0, 23);
>         dequant_tab = (is_intra) ? band->dequant_intra : band->dequant_inter;
>         dequant_tab += quant * num_coeffs;
>         buf_offs = mb->buf_offs;
> 
>         if (!is_intra) {
>             mv_x = mb->mv_x;
>             mv_y = mb->mv_y;
>             if (!band->mc_resolution)
>                 mc_type = 0; /* we have only fullpel vectors */
>             else {
>                 mc_type = ((mv_y & 1) << 1) | (mv_x & 1);
>                 mv_x >>= 1;
>                 mv_y >>= 1; /* convert halfpel vectors into fullpel ones */
>             }
>         }
> 
>         for (blk = 0; blk < num_blocks; blk++) {
>             /* adjust block position in the buffer according with its number */
>             if (blk & 1)
>                 buf_offs += blk_size;
>             else if (blk == 2) {
>                 buf_offs -= blk_size;
>                 buf_offs += blk_size * band->pitch;
>             }
> 
>             if (cbp & 1) { /* block coded ? */
>                 scan_pos = -1;
>                 memset(trvec,0,num_coeffs*sizeof(int32_t)); /* zero transform vector */
> 
>                 while(scan_pos <= num_coeffs) {
>                     sym = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1);
>                     if (sym == rvmap->eob_sym)
>                         break; /* End of block */
> 
>                     if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */
>                         run = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1) + 1;
>                         lo = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1);
>                         hi = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1);
>                         val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */
>                     }
>                     else {
>                         run = rvmap->runtab[sym];
>                         val = rvmap->valtab[sym];
>                     }
> 
>                     /* de-zigzag and dequantize */
>                     scan_pos += run;
>                     pos = band->scan[scan_pos];

looks exploitable but cant say for sure as this patch is incomplete


> 
>                     q = dequant_tab[pos]; /* get scalefactor */
>                     if (q != 1 && val != 0) {
>                         if (val > 0)
>                             val = (val * q) + (q >> 1) - (q & 1);
>                         else
>                             val = (val * q) - (q >> 1) + (q & 1);
>                     }

duplicate <0 check


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The misfortune of the wise is better than the prosperity of the fool.
-- Epicurus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090323/675be3e8/attachment.pgp>



More information about the ffmpeg-devel mailing list