[FFmpeg-devel] [PATCH] Electronic Arts TQI decoder

Michael Niedermayer michaelni
Fri Jan 30 20:01:52 CET 2009


On Sat, Jan 31, 2009 at 02:40:30AM +1100, Peter Ross wrote:
> On Mon, Jan 26, 2009 at 11:17:57AM +0100, Michael Niedermayer wrote:
> > On Sun, Jan 25, 2009 at 11:06:25PM +1100, Peter Ross wrote:
> > > Patch enclosed.
> 
> Updated.
> 
> > [...]
> > > Index: libavcodec/mpeg12.c
> > > ===================================================================
> > > --- libavcodec/mpeg12.c	(revision 16768)
> > > +++ libavcodec/mpeg12.c	(working copy)
> > > @@ -46,6 +46,9 @@
> > >  #define MB_PTYPE_VLC_BITS 6
> > >  #define MB_BTYPE_VLC_BITS 6
> > >  
> > > +VLC ff_mpeg12_dc_lum_vlc;
> > > +VLC ff_mpeg12_dc_chroma_vlc;
> > 
> > i wonder if mpeg12data would be a better place but then maybe not ..
> > either way this patch is ok as well with whichever place for the
> > VLC tables you like most
> 
> No need, the run-lengh decoder is identical to MPEG-1.
> 
> One snag is that eatqi needs mpeg1_decode_block_intra(), which is presently
> inlined within mpeg12.c I have made this function global, but am looking for
> a better solution.
[...]
> +static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
> +{
> +    int n;

> +    memset(block, 0, 6*64*sizeof(DCTELEM));

clear_blocks()


[...]
> +static void tqi_calculate_qtable(MpegEncContext *s, int quant)
> +{
> +    const double flt_value = (107.5-quant)*0.625;
> +    int i;
> +    s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0])>>11;
> +    for(i=1; i<64; i++)
> +        s->intra_matrix[i] = (int)(ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*flt_value + 2)>>10;
> +}

i suspect that the ff_inv_aanscales is wrong for the normal IDCTs
the normal ones should have a "flat" scaling

flt_value= (215 - 2*quant)*5

...*flt_value + 32)>>14;

avoids floats


> +
> +static int tqi_decode_frame(AVCodecContext *avctx,
> +                            void *data, int *data_size,
> +                            const uint8_t *buf, int buf_size)
> +{
> +    const uint8_t *buf_end = buf+buf_size;
> +    TqiContext *t = avctx->priv_data;
> +    MpegEncContext *s = &t->s;
> +    DCTELEM block[6][64];
> +
> +    s->width  = AV_RL16(&buf[0]);
> +    s->height = AV_RL16(&buf[2]);
> +    tqi_calculate_qtable(s, buf[4]);
> +    buf += 8;
> +
> +    if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
> +        avcodec_set_dimensions(s->avctx, s->width, s->height);
> +        if (t->frame.data[0])
> +            avctx->release_buffer(avctx, &t->frame);
> +    }
> +
> +    if (!t->frame.data[0]) {
> +        if(avctx->get_buffer(avctx, &t->frame) < 0) {
> +            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
> +            return -1;
> +        }
> +    }

you have to call get/release_buffer on each frame, ffmpeg uses them
immedeatly but other applications could store them in a que before using
simply drawing again in the previous is not safe (if you set CODEC_CAP_DR1
at least)


[...]
> @@ -614,7 +611,7 @@
>      return val;
>  }
>  
> -static inline int mpeg1_decode_block_intra(MpegEncContext *s,
> +int mpeg1_decode_block_intra(MpegEncContext *s,
>                                 DCTELEM *block,
>                                 int n)
>  {

i think this one should be extern inline if i remember correctly
and it needs a ff_ prefix


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

Awnsering whenever a program halts or runs forever is
On a turing machine, in general impossible (turings halting problem).
On any real computer, always possible as a real computer has a finite number
of states N, and will either halt in less than N cycles or never halt.
-------------- 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/20090130/a2ec4156/attachment.pgp>



More information about the ffmpeg-devel mailing list