From f3eb00834362273dcb1fd3320faa5f8f5a00fb22 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 29 Jul 2012 13:09:10 +0100 Subject: [PATCH] eamad/eatgq/eatqi: call special EA IDCT directly These decoders use a special non-MPEG2 IDCT. Call it directly instead of going through dsputil. There is never any reason to use a regular IDCT with these decoders or to use the EA IDCT with other codecs. This also fixes the bizarre situation of eamad and eatqi decoding incorrectly if eatgq is disabled. Signed-off-by: Mans Rullgard --- libavcodec/dsputil.c | 3 --- libavcodec/dsputil.h | 3 --- libavcodec/eaidct.c | 1 + libavcodec/eaidct.h | 27 +++++++++++++++++++++++++++ libavcodec/eamad.c | 20 +++++++------------- libavcodec/eatgq.c | 26 +++++++++++--------------- libavcodec/eatqi.c | 28 +++++++++++----------------- 7 files changed, 57 insertions(+), 51 deletions(-) create mode 100644 libavcodec/eaidct.h diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 46232d800a..787a46d1ea 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -2711,9 +2711,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) c->idct_add= ff_faanidct_add; c->idct = ff_faanidct; c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) { - c->idct_put= ff_ea_idct_put_c; - c->idct_permutation_type= FF_NO_IDCT_PERM; }else{ //accurate/default c->idct_put = ff_simple_idct_put_8; c->idct_add = ff_simple_idct_add_8; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index c3a787c5f3..e1b7efc45b 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -101,9 +101,6 @@ PUTAVG_PIXELS(10) #define ff_put_pixels16x16_c ff_put_pixels16x16_8_c #define ff_avg_pixels16x16_c ff_avg_pixels16x16_8_c -/* EA functions */ -void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); - /* RV40 functions */ void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride); void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride); diff --git a/libavcodec/eaidct.c b/libavcodec/eaidct.c index 9d829c4161..5e628b09d0 100644 --- a/libavcodec/eaidct.c +++ b/libavcodec/eaidct.c @@ -26,6 +26,7 @@ */ #include "dsputil.h" +#include "eaidct.h" #define ASQRT 181 /* (1/sqrt(2))<<8 */ #define A4 669 /* cos(pi/8)*sqrt(2)<<9 */ diff --git a/libavcodec/eaidct.h b/libavcodec/eaidct.h new file mode 100644 index 0000000000..4c0b5ae16e --- /dev/null +++ b/libavcodec/eaidct.h @@ -0,0 +1,27 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_EAIDCT_H +#define AVCODEC_EAIDCT_H + +#include +#include "dsputil.h" + +void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); + +#endif /* AVCODEC_EAIDCT_H */ diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index b738f9458c..ca7439397f 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -32,6 +32,7 @@ #include "get_bits.h" #include "dsputil.h" #include "aandcttab.h" +#include "eaidct.h" #include "mpeg12.h" #include "mpeg12data.h" #include "libavutil/imgutils.h" @@ -68,9 +69,8 @@ static av_cold int decode_init(AVCodecContext *avctx) MadContext *s = avctx->priv_data; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_YUV420P; - if (avctx->idct_algo == FF_IDCT_AUTO) - avctx->idct_algo = FF_IDCT_EA; ff_dsputil_init(&s->dsp, avctx); + ff_init_scantable_permutation(s->dsp.idct_permutation, FF_NO_IDCT_PERM); ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); ff_mpeg12_init_vlcs(); return 0; @@ -105,12 +105,12 @@ static inline void comp_block(MadContext *t, int mb_x, int mb_y, static inline void idct_put(MadContext *t, DCTELEM *block, int mb_x, int mb_y, int j) { if (j < 4) { - t->dsp.idct_put( + ff_ea_idct_put_c( t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), t->frame.linesize[0], block); } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; - t->dsp.idct_put( + ff_ea_idct_put_c( t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x*8, t->frame.linesize[index], block); } @@ -219,15 +219,9 @@ static void calc_quant_matrix(MadContext *s, int qscale) { int i; - if (s->avctx->idct_algo == FF_IDCT_EA) { - s->quant_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0]) >> 11; - for (i=1; i<64; i++) - s->quant_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32) >> 10; - } else { - s->quant_matrix[0] = ff_mpeg1_default_intra_matrix[0]; - for (i=1; i<64; i++) - s->quant_matrix[i] = (ff_mpeg1_default_intra_matrix[i]*qscale) << 1; - } + s->quant_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0]) >> 11; + for (i=1; i<64; i++) + s->quant_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32) >> 10; } static int decode_frame(AVCodecContext *avctx, diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index e53b99205b..a55b061a50 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -34,10 +34,10 @@ #include "bytestream.h" #include "dsputil.h" #include "aandcttab.h" +#include "eaidct.h" typedef struct TgqContext { AVCodecContext *avctx; - DSPContext dsp; AVFrame frame; int width,height; ScanTable scantable; @@ -48,11 +48,10 @@ typedef struct TgqContext { static av_cold int tgq_decode_init(AVCodecContext *avctx){ TgqContext *s = avctx->priv_data; + uint8_t idct_permutation[64]; s->avctx = avctx; - if(avctx->idct_algo==FF_IDCT_AUTO) - avctx->idct_algo=FF_IDCT_EA; - ff_dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); + ff_init_scantable_permutation(idct_permutation, FF_NO_IDCT_PERM); + ff_init_scantable(idct_permutation, &s->scantable, ff_zigzag_direct); avctx->time_base = (AVRational){1, 15}; avctx->pix_fmt = PIX_FMT_YUV420P; return 0; @@ -109,13 +108,13 @@ static void tgq_idct_put_mb(TgqContext *s, DCTELEM (*block)[64], int mb_x, int m uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8; uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8; - s->dsp.idct_put(dest_y , linesize, block[0]); - s->dsp.idct_put(dest_y + 8, linesize, block[1]); - s->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); - s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); + ff_ea_idct_put_c(dest_y , linesize, block[0]); + ff_ea_idct_put_c(dest_y + 8, linesize, block[1]); + ff_ea_idct_put_c(dest_y + 8*linesize , linesize, block[2]); + ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]); if(!(s->avctx->flags&CODEC_FLAG_GRAY)){ - s->dsp.idct_put(dest_cb, s->frame.linesize[1], block[4]); - s->dsp.idct_put(dest_cr, s->frame.linesize[2], block[5]); + ff_ea_idct_put_c(dest_cb, s->frame.linesize[1], block[4]); + ff_ea_idct_put_c(dest_cr, s->frame.linesize[2], block[5]); } } @@ -180,10 +179,7 @@ static void tgq_calculate_qtable(TgqContext *s, int quant){ const int b = (11*(100-quant))/100 + 4; for(j=0;j<8;j++) for(i=0;i<8;i++) - if (s->avctx->idct_algo==FF_IDCT_EA) - s->qtable[j*8+i] = ((a*(j+i)/(7+7) + b)*ff_inv_aanscales[j*8+i])>>(14-4); - else - s->qtable[j*8+i] = (a*(j+i)/(7+7) + b)<<3; + s->qtable[j*8+i] = ((a*(j+i)/(7+7) + b)*ff_inv_aanscales[j*8+i])>>(14-4); } static int tgq_decode_frame(AVCodecContext *avctx, diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 9824940d97..548a084044 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -30,6 +30,7 @@ #include "get_bits.h" #include "dsputil.h" #include "aandcttab.h" +#include "eaidct.h" #include "mpeg12.h" #include "mpegvideo.h" @@ -46,9 +47,8 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx) TqiContext *t = avctx->priv_data; MpegEncContext *s = &t->s; s->avctx = avctx; - if(avctx->idct_algo==FF_IDCT_AUTO) - avctx->idct_algo=FF_IDCT_EA; ff_dsputil_init(&s->dsp, avctx); + ff_init_scantable_permutation(s->dsp.idct_permutation, FF_NO_IDCT_PERM); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); s->qscale = 1; avctx->time_base = (AVRational){1, 15}; @@ -76,13 +76,13 @@ static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64]) uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8; uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8; - s->dsp.idct_put(dest_y , linesize, block[0]); - s->dsp.idct_put(dest_y + 8, linesize, block[1]); - s->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); - s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); + ff_ea_idct_put_c(dest_y , linesize, block[0]); + ff_ea_idct_put_c(dest_y + 8, linesize, block[1]); + ff_ea_idct_put_c(dest_y + 8*linesize , linesize, block[2]); + ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]); if(!(s->avctx->flags&CODEC_FLAG_GRAY)) { - s->dsp.idct_put(dest_cb, t->frame.linesize[1], block[4]); - s->dsp.idct_put(dest_cr, t->frame.linesize[2], block[5]); + ff_ea_idct_put_c(dest_cb, t->frame.linesize[1], block[4]); + ff_ea_idct_put_c(dest_cr, t->frame.linesize[2], block[5]); } } @@ -90,15 +90,9 @@ static void tqi_calculate_qtable(MpegEncContext *s, int quant) { const int qscale = (215 - 2*quant)*5; int i; - if (s->avctx->idct_algo==FF_IDCT_EA) { - 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] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14; - }else{ - s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; - for(i=1; i<64; i++) - s->intra_matrix[i] = (ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>3; - } + 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] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14; } static int tqi_decode_frame(AVCodecContext *avctx,