diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b7b512478ca57b54adc9aeffceb37afcce57636a..04a504be74a65a000b5b01213c3e6a37f2dce761 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -324,9 +324,9 @@ OBJS-$(CONFIG_RV10_DECODER) += rv10.o OBJS-$(CONFIG_RV10_ENCODER) += rv10enc.o OBJS-$(CONFIG_RV20_DECODER) += rv10.o OBJS-$(CONFIG_RV20_ENCODER) += rv20enc.o -OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o \ +OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o rv34dsp.o \ mpegvideo.o error_resilience.o -OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv40dsp.o \ +OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv34dsp.o rv40dsp.o \ mpegvideo.o error_resilience.o OBJS-$(CONFIG_S302M_DECODER) += s302m.o OBJS-$(CONFIG_SGI_DECODER) += sgidec.o diff --git a/libavcodec/rv30dsp.c b/libavcodec/rv30dsp.c index 6ba1a6bfc18cff9c112e638843370e321f451b6d..bcd1a462b1554053c9ee60df82e6058a9ae80d0e 100644 --- a/libavcodec/rv30dsp.c +++ b/libavcodec/rv30dsp.c @@ -253,6 +253,9 @@ RV30_MC(avg_, 8) RV30_MC(avg_, 16) av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) { + + ff_rv34dsp_init(c, dsp); + c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0]; c->put_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c; c->put_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c; diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index abdfce50a5388f46f3e2809a1677acf2b1d98dce..b771a7f97e54b49f5a9eabfacfce87e83695b868 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -171,82 +171,6 @@ static av_cold void rv34_init_tables(void) /** @} */ // vlc group - -/** - * @name RV30/40 inverse transform functions - * @{ - */ - -static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block) -{ - int i; - - for(i = 0; i < 4; i++){ - const int z0 = 13*(block[i+8*0] + block[i+8*2]); - const int z1 = 13*(block[i+8*0] - block[i+8*2]); - const int z2 = 7* block[i+8*1] - 17*block[i+8*3]; - const int z3 = 17* block[i+8*1] + 7*block[i+8*3]; - - temp[4*i+0] = z0 + z3; - temp[4*i+1] = z1 + z2; - temp[4*i+2] = z1 - z2; - temp[4*i+3] = z0 - z3; - } -} - -/** - * Real Video 3.0/4.0 inverse transform - * Code is almost the same as in SVQ3, only scaling is different. - */ -static void rv34_inv_transform(DCTELEM *block){ - int temp[16]; - int i; - - rv34_row_transform(temp, block); - - for(i = 0; i < 4; i++){ - const int z0 = 13*(temp[4*0+i] + temp[4*2+i]) + 0x200; - const int z1 = 13*(temp[4*0+i] - temp[4*2+i]) + 0x200; - const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; - const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; - - block[i*8+0] = (z0 + z3) >> 10; - block[i*8+1] = (z1 + z2) >> 10; - block[i*8+2] = (z1 - z2) >> 10; - block[i*8+3] = (z0 - z3) >> 10; - } - -} - -/** - * RealVideo 3.0/4.0 inverse transform for DC block - * - * Code is almost the same as rv34_inv_transform() - * but final coefficients are multiplied by 1.5 and have no rounding. - */ -static void rv34_inv_transform_noround(DCTELEM *block){ - int temp[16]; - int i; - - rv34_row_transform(temp, block); - - for(i = 0; i < 4; i++){ - const int z0 = 13*(temp[4*0+i] + temp[4*2+i]); - const int z1 = 13*(temp[4*0+i] - temp[4*2+i]); - const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; - const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; - - block[i*8+0] = ((z0 + z3) * 3) >> 11; - block[i*8+1] = ((z1 + z2) * 3) >> 11; - block[i*8+2] = ((z1 - z2) * 3) >> 11; - block[i*8+3] = ((z0 - z3) * 3) >> 11; - } - -} - -/** @} */ // transform - - /** * @name RV30/40 4x4 block decoding functions * @{ @@ -1226,7 +1150,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) memset(block16, 0, sizeof(block16)); rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0); rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]); - rv34_inv_transform_noround(block16); + r->rdsp.rv34_inv_transform_tab[1](block16); } for(i = 0; i < 16; i++, cbp >>= 1){ @@ -1238,7 +1162,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]); if(r->is16) //FIXME: optimize s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)]; - rv34_inv_transform(s->block[blknum] + blkoff); + r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); } if(r->block_type == RV34_MB_P_MIX16x16) r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); @@ -1248,7 +1172,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) blkoff = ((i & 1) << 2) + ((i & 2) << 4); rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1); rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]); - rv34_inv_transform(s->block[blknum] + blkoff); + r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); } if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])) rv34_output_macroblock(r, intra_types, cbp2, r->is16); diff --git a/libavcodec/rv34dsp.c b/libavcodec/rv34dsp.c new file mode 100644 index 0000000000000000000000000000000000000000..59038a7a3132243379ab83e6ebb66c8dcf520857 --- /dev/null +++ b/libavcodec/rv34dsp.c @@ -0,0 +1,106 @@ +/* + * RV30/40 decoder common dsp functions + * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov + * Copyright (c) 2011 Janne Grunau + * + * 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 + */ + +/** + * @file + * RV30/40 decoder common dsp functions + */ +#include "dsputil.h" +#include "rv34dsp.h" + +/** + * @name RV30/40 inverse transform functions + * @{ + */ + +static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block) +{ + int i; + + for(i = 0; i < 4; i++){ + const int z0 = 13*(block[i+8*0] + block[i+8*2]); + const int z1 = 13*(block[i+8*0] - block[i+8*2]); + const int z2 = 7* block[i+8*1] - 17*block[i+8*3]; + const int z3 = 17* block[i+8*1] + 7*block[i+8*3]; + + temp[4*i+0] = z0 + z3; + temp[4*i+1] = z1 + z2; + temp[4*i+2] = z1 - z2; + temp[4*i+3] = z0 - z3; + } +} + +/** + * Real Video 3.0/4.0 inverse transform + * Code is almost the same as in SVQ3, only scaling is different. + */ +static void rv34_inv_transform_c(DCTELEM *block){ + int temp[16]; + int i; + + rv34_row_transform(temp, block); + + for(i = 0; i < 4; i++){ + const int z0 = 13*(temp[4*0+i] + temp[4*2+i]) + 0x200; + const int z1 = 13*(temp[4*0+i] - temp[4*2+i]) + 0x200; + const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; + const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; + + block[i*8+0] = (z0 + z3) >> 10; + block[i*8+1] = (z1 + z2) >> 10; + block[i*8+2] = (z1 - z2) >> 10; + block[i*8+3] = (z0 - z3) >> 10; + } +} + +/** + * RealVideo 3.0/4.0 inverse transform for DC block + * + * Code is almost the same as rv34_inv_transform() + * but final coefficients are multiplied by 1.5 and have no rounding. + */ +static void rv34_inv_transform_noround_c(DCTELEM *block){ + int temp[16]; + int i; + + rv34_row_transform(temp, block); + + for(i = 0; i < 4; i++){ + const int z0 = 13*(temp[4*0+i] + temp[4*2+i]); + const int z1 = 13*(temp[4*0+i] - temp[4*2+i]); + const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; + const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; + + block[i*8+0] = ((z0 + z3) * 3) >> 11; + block[i*8+1] = ((z1 + z2) * 3) >> 11; + block[i*8+2] = ((z1 - z2) * 3) >> 11; + block[i*8+3] = ((z0 - z3) * 3) >> 11; + } +} + +/** @} */ // transform + + +av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) { + c->rv34_inv_transform_tab[0] = rv34_inv_transform_c; + c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c; +} diff --git a/libavcodec/rv34dsp.h b/libavcodec/rv34dsp.h index e1def7dc267ed2cf0920a24e33deed9d8ec7acac..a2ab5f232bccfee8195a6ee877ba2ffeb2fdc097 100644 --- a/libavcodec/rv34dsp.h +++ b/libavcodec/rv34dsp.h @@ -34,15 +34,19 @@ typedef void (*rv40_weight_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src2/*align width (8 or 16)*/, int w1, int w2, int stride); +typedef void (*rv34_inv_transform_func)(DCTELEM *block); + typedef struct RV34DSPContext { qpel_mc_func put_pixels_tab[4][16]; qpel_mc_func avg_pixels_tab[4][16]; h264_chroma_mc_func put_chroma_pixels_tab[3]; h264_chroma_mc_func avg_chroma_pixels_tab[3]; rv40_weight_func rv40_weight_pixels_tab[2]; + rv34_inv_transform_func rv34_inv_transform_tab[2]; } RV34DSPContext; void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp); +void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp); void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp); void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp); diff --git a/libavcodec/rv40dsp.c b/libavcodec/rv40dsp.c index c54f96556f5889f5cf9ca00778778dc29eb7a6c4..efc049f1cb127c022b485bd162e52592d9b27796 100644 --- a/libavcodec/rv40dsp.c +++ b/libavcodec/rv40dsp.c @@ -295,6 +295,9 @@ RV40_WEIGHT_FUNC(16) RV40_WEIGHT_FUNC(8) av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) { + + ff_rv34dsp_init(c, dsp); + c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0]; c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c; c->put_pixels_tab[0][ 2] = dsp->put_h264_qpel_pixels_tab[0][2];