diff options
Diffstat (limited to 'libavcodec/dsputil.c')
-rw-r--r-- | libavcodec/dsputil.c | 263 |
1 files changed, 238 insertions, 25 deletions
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 9fe6f0b757..eeeda7c23c 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -5,20 +5,20 @@ * * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg 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, + * FFmpeg 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 + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,6 +29,7 @@ #include "libavutil/attributes.h" #include "libavutil/imgutils.h" +#include "libavutil/internal.h" #include "avcodec.h" #include "copy_block.h" #include "dct.h" @@ -40,6 +41,7 @@ #include "mathops.h" #include "mpegvideo.h" #include "config.h" +#include "diracdsp.h" uint32_t ff_square_tab[512] = { 0, }; @@ -320,7 +322,7 @@ static int sse16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, return s; } -static void diff_pixels_c(int16_t *restrict block, const uint8_t *s1, +static void diff_pixels_c(int16_t *av_restrict block, const uint8_t *s1, const uint8_t *s2, int stride) { int i; @@ -341,7 +343,7 @@ static void diff_pixels_c(int16_t *restrict block, const uint8_t *s1, } } -static void put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, +static void put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size) { int i; @@ -362,8 +364,40 @@ static void put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, } } +static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, + int line_size) +{ + int i; + + /* read the pixels */ + for(i=0;i<4;i++) { + pixels[0] = av_clip_uint8(block[0]); + pixels[1] = av_clip_uint8(block[1]); + pixels[2] = av_clip_uint8(block[2]); + pixels[3] = av_clip_uint8(block[3]); + + pixels += line_size; + block += 8; + } +} + +static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, + int line_size) +{ + int i; + + /* read the pixels */ + for(i=0;i<2;i++) { + pixels[0] = av_clip_uint8(block[0]); + pixels[1] = av_clip_uint8(block[1]); + + pixels += line_size; + block += 8; + } +} + static void put_signed_pixels_clamped_c(const int16_t *block, - uint8_t *restrict pixels, + uint8_t *av_restrict pixels, int line_size) { int i, j; @@ -383,7 +417,7 @@ static void put_signed_pixels_clamped_c(const int16_t *block, } } -static void add_pixels8_c(uint8_t *restrict pixels, int16_t *block, +static void add_pixels8_c(uint8_t *av_restrict pixels, int16_t *block, int line_size) { int i; @@ -402,7 +436,7 @@ static void add_pixels8_c(uint8_t *restrict pixels, int16_t *block, } } -static void add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, +static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, int line_size) { int i; @@ -422,6 +456,36 @@ static void add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, } } +static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels, + int line_size) +{ + int i; + + /* read the pixels */ + for(i=0;i<4;i++) { + pixels[0] = av_clip_uint8(pixels[0] + block[0]); + pixels[1] = av_clip_uint8(pixels[1] + block[1]); + pixels[2] = av_clip_uint8(pixels[2] + block[2]); + pixels[3] = av_clip_uint8(pixels[3] + block[3]); + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels, + int line_size) +{ + int i; + + /* read the pixels */ + for(i=0;i<2;i++) { + pixels[0] = av_clip_uint8(pixels[0] + block[0]); + pixels[1] = av_clip_uint8(pixels[1] + block[1]); + pixels += line_size; + block += 8; + } +} + static int sum_abs_dctelem_c(int16_t *block) { int sum = 0, i; @@ -1547,6 +1611,51 @@ void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride) } #endif /* CONFIG_RV40_DECODER */ +#if CONFIG_DIRAC_DECODER +#define DIRAC_MC(OPNAME)\ +void ff_ ## OPNAME ## _dirac_pixels8_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_8_c(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_8_c(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_8_c(dst , src[0] , stride, h);\ + OPNAME ## _pixels16_8_c(dst+16, src[0]+16, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels8_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_l2_8(dst, src[0], src[1], stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l2_8(dst, src[0], src[1], stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l2_8(dst , src[0] , src[1] , stride, stride, stride, h);\ + OPNAME ## _pixels16_l2_8(dst+16, src[0]+16, src[1]+16, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels8_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l4_8(dst , src[0] , src[1] , src[2] , src[3] , stride, stride, stride, stride, stride, h);\ + OPNAME ## _pixels16_l4_8(dst+16, src[0]+16, src[1]+16, src[2]+16, src[3]+16, stride, stride, stride, stride, stride, h);\ +} +DIRAC_MC(put) +DIRAC_MC(avg) +#endif + static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w) { @@ -1896,7 +2005,7 @@ static int try_8x8basis_c(int16_t rem[64], int16_t weight[64], (BASIS_SHIFT - RECON_SHIFT)); int w = weight[i]; b >>= RECON_SHIFT; - assert(-512 < b && b < 512); + av_assert2(-512 < b && b < 512); sum += (w * b) * (w * b) >> 4; } @@ -1966,6 +2075,14 @@ void ff_set_cmp(DSPContext *c, me_cmp_func *cmp, int type) case FF_CMP_NSSE: cmp[i] = c->nsse[i]; break; +#if CONFIG_DWT + case FF_CMP_W53: + cmp[i]= c->w53[i]; + break; + case FF_CMP_W97: + cmp[i]= c->w97[i]; + break; +#endif default: av_log(NULL, AV_LOG_ERROR, "internal error in cmp function selection\n"); @@ -1986,7 +2103,7 @@ static void add_bytes_c(uint8_t *dst, uint8_t *src, int w) dst[i + 0] += src[i + 0]; } -static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) +static void diff_bytes_c(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w) { long i; @@ -2135,7 +2252,7 @@ static int hadamard8_diff8x8_c(MpegEncContext *s, uint8_t *dst, { int i, temp[64], sum = 0; - assert(h == 8); + av_assert2(h == 8); for (i = 0; i < 8; i++) { // FIXME: try pointer walks @@ -2187,7 +2304,7 @@ static int hadamard8_intra8x8_c(MpegEncContext *s, uint8_t *src, { int i, temp[64], sum = 0; - assert(h == 8); + av_assert2(h == 8); for (i = 0; i < 8; i++) { // FIXME: try pointer walks @@ -2239,7 +2356,7 @@ static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1, { LOCAL_ALIGNED_16(int16_t, temp, [64]); - assert(h == 8); + av_assert2(h == 8); s->dsp.diff_pixels(temp, src1, src2, stride); s->dsp.fdct(temp); @@ -2306,7 +2423,7 @@ static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1, LOCAL_ALIGNED_16(int16_t, temp, [64]); int sum = 0, i; - assert(h == 8); + av_assert2(h == 8); s->dsp.diff_pixels(temp, src1, src2, stride); s->dsp.fdct(temp); @@ -2324,7 +2441,7 @@ static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1, int16_t *const bak = temp + 64; int sum = 0, i; - assert(h == 8); + av_assert2(h == 8); s->mb_intra = 0; s->dsp.diff_pixels(temp, src1, src2, stride); @@ -2353,7 +2470,7 @@ static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, const int esc_length = s->ac_esc_length; uint8_t *length, *last_length; - assert(h == 8); + av_assert2(h == 8); copy_block8(lsrc1, src1, 8, stride, 8); copy_block8(lsrc2, src2, 8, stride, 8); @@ -2397,7 +2514,7 @@ static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, level = temp[i] + 64; - assert(level - 64); + av_assert2(level - 64); if ((level & (~127)) == 0) { bits += last_length[UNI_AC_ENC_INDEX(run, level)]; @@ -2428,7 +2545,7 @@ static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, const int esc_length = s->ac_esc_length; uint8_t *length, *last_length; - assert(h == 8); + av_assert2(h == 8); s->dsp.diff_pixels(temp, src1, src2, stride); @@ -2469,7 +2586,7 @@ static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, level = temp[i] + 64; - assert(level - 64); + av_assert2(level - 64); if ((level & (~127)) == 0) bits += last_length[UNI_AC_ENC_INDEX(run, level)]; @@ -2699,6 +2816,37 @@ static void jref_idct_add(uint8_t *dest, int line_size, int16_t *block) add_pixels_clamped_c(block, dest, line_size); } +static void ff_jref_idct4_put(uint8_t *dest, int line_size, int16_t *block) +{ + ff_j_rev_dct4 (block); + put_pixels_clamped4_c(block, dest, line_size); +} +static void ff_jref_idct4_add(uint8_t *dest, int line_size, int16_t *block) +{ + ff_j_rev_dct4 (block); + add_pixels_clamped4_c(block, dest, line_size); +} + +static void ff_jref_idct2_put(uint8_t *dest, int line_size, int16_t *block) +{ + ff_j_rev_dct2 (block); + put_pixels_clamped2_c(block, dest, line_size); +} +static void ff_jref_idct2_add(uint8_t *dest, int line_size, int16_t *block) +{ + ff_j_rev_dct2 (block); + add_pixels_clamped2_c(block, dest, line_size); +} + +static void ff_jref_idct1_put(uint8_t *dest, int line_size, int16_t *block) +{ + dest[0] = av_clip_uint8((block[0] + 4)>>3); +} +static void ff_jref_idct1_add(uint8_t *dest, int line_size, int16_t *block) +{ + dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3)); +} + /* init static data */ av_cold void ff_dsputil_static_init(void) { @@ -2708,10 +2856,33 @@ av_cold void ff_dsputil_static_init(void) ff_square_tab[i] = (i - 256) * (i - 256); } +int ff_check_alignment(void) +{ + static int did_fail = 0; + LOCAL_ALIGNED_16(int, aligned, [4]); + + if ((intptr_t)aligned & 15) { + if (!did_fail) { +#if HAVE_MMX || HAVE_ALTIVEC + av_log(NULL, AV_LOG_ERROR, + "Compiler did not align stack variables. Libavcodec has been miscompiled\n" + "and may be very slow or crash. This is not a bug in libavcodec,\n" + "but in the compiler. You may try recompiling using gcc >= 4.2.\n" + "Do not report crashes to FFmpeg developers.\n"); +#endif + did_fail=1; + } + return -1; + } + return 0; +} + av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) { const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; + ff_check_alignment(); + #if CONFIG_ENCODERS if (avctx->bits_per_raw_sample == 10) { c->fdct = ff_jpeg_fdct_islow_10; @@ -2730,12 +2901,33 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) } #endif /* CONFIG_ENCODERS */ - if (avctx->bits_per_raw_sample == 10) { - c->idct_put = ff_simple_idct_put_10; - c->idct_add = ff_simple_idct_add_10; - c->idct = ff_simple_idct_10; + if (avctx->lowres==1) { + c->idct_put = ff_jref_idct4_put; + c->idct_add = ff_jref_idct4_add; + c->idct = ff_j_rev_dct4; + c->idct_permutation_type = FF_NO_IDCT_PERM; + } else if (avctx->lowres==2) { + c->idct_put = ff_jref_idct2_put; + c->idct_add = ff_jref_idct2_add; + c->idct = ff_j_rev_dct2; + c->idct_permutation_type = FF_NO_IDCT_PERM; + } else if (avctx->lowres==3) { + c->idct_put = ff_jref_idct1_put; + c->idct_add = ff_jref_idct1_add; + c->idct = ff_j_rev_dct1; c->idct_permutation_type = FF_NO_IDCT_PERM; } else { + if (avctx->bits_per_raw_sample == 10) { + c->idct_put = ff_simple_idct_put_10; + c->idct_add = ff_simple_idct_add_10; + c->idct = ff_simple_idct_10; + c->idct_permutation_type = FF_NO_IDCT_PERM; + } else if (avctx->bits_per_raw_sample == 12) { + c->idct_put = ff_simple_idct_put_12; + c->idct_add = ff_simple_idct_add_12; + c->idct = ff_simple_idct_12; + c->idct_permutation_type = FF_NO_IDCT_PERM; + } else { if (avctx->idct_algo == FF_IDCT_INT) { c->idct_put = jref_idct_put; c->idct_add = jref_idct_add; @@ -2752,6 +2944,7 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) c->idct = ff_simple_idct_8; c->idct_permutation_type = FF_NO_IDCT_PERM; } + } } c->diff_pixels = diff_pixels_c; @@ -2867,6 +3060,9 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) c->vsse[5] = vsse_intra8_c; c->nsse[0] = nsse16_c; c->nsse[1] = nsse8_c; +#if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER + ff_dsputil_init_dwt(c); +#endif c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; @@ -2913,13 +3109,20 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) switch (avctx->bits_per_raw_sample) { case 9: case 10: + case 12: + case 14: BIT_DEPTH_FUNCS(16); break; default: - BIT_DEPTH_FUNCS(8); + if (avctx->bits_per_raw_sample<=8 || avctx->codec_type != AVMEDIA_TYPE_VIDEO) { + BIT_DEPTH_FUNCS(8); + } break; } + + if (ARCH_ALPHA) + ff_dsputil_init_alpha(c, avctx); if (ARCH_ARM) ff_dsputil_init_arm(c, avctx, high_bit_depth); if (ARCH_BFIN) @@ -2932,3 +3135,13 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) ff_init_scantable_permutation(c->idct_permutation, c->idct_permutation_type); } + +av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) +{ + ff_dsputil_init(c, avctx); +} + +av_cold void avpriv_dsputil_init(DSPContext *c, AVCodecContext *avctx) +{ + ff_dsputil_init(c, avctx); +} |