[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