# HG changeset patch # User michael # Date 1067815187 0 # Node ID 4c9165372ab3bc003b45ba700bb3412b52cf7124 # Parent c1d5491f144a88edac0d29673bacd2df4de4dca1 noise reduction of dct coefficients diff -r c1d5491f144a -r 4c9165372ab3 avcodec.h --- a/avcodec.h Sun Nov 02 22:56:47 2003 +0000 +++ b/avcodec.h Sun Nov 02 23:19:47 2003 +0000 @@ -16,7 +16,7 @@ #define FFMPEG_VERSION_INT 0x000408 #define FFMPEG_VERSION "0.4.8" -#define LIBAVCODEC_BUILD 4689 +#define LIBAVCODEC_BUILD 4690 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -1358,6 +1358,13 @@ * - decoding: set by user. */ struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: set by user. + * - decoding: unused + */ + int noise_reduction; } AVCodecContext; diff -r c1d5491f144a -r 4c9165372ab3 i386/mpegvideo_mmx.c --- a/i386/mpegvideo_mmx.c Sun Nov 02 22:56:47 2003 +0000 +++ b/i386/mpegvideo_mmx.c Sun Nov 02 23:19:47 2003 +0000 @@ -495,6 +495,7 @@ #define HAVE_MMX2 #undef RENAME +#undef RENAMEl #define RENAME(a) a ## _MMX2 #define RENAMEl(a) a ## _mmx2 #include "mpegvideo_mmx_template.c" diff -r c1d5491f144a -r 4c9165372ab3 i386/mpegvideo_mmx_template.c --- a/i386/mpegvideo_mmx_template.c Sun Nov 02 22:56:47 2003 +0000 +++ b/i386/mpegvideo_mmx_template.c Sun Nov 02 23:19:47 2003 +0000 @@ -45,6 +45,9 @@ //s->fdct (block); RENAMEl(ff_fdct) (block); //cant be anything else ... + if(s->dct_error_sum) + ff_denoise_dct(s, block); + if (s->mb_intra) { int dummy; if (n < 4) diff -r c1d5491f144a -r 4c9165372ab3 mpegvideo.c --- a/mpegvideo.c Sun Nov 02 22:56:47 2003 +0000 +++ b/mpegvideo.c Sun Nov 02 23:19:47 2003 +0000 @@ -458,6 +458,11 @@ CHECKED_ALLOCZ(s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t)) CHECKED_ALLOCZ(s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*)) CHECKED_ALLOCZ(s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*)) + + if(s->avctx->noise_reduction){ + CHECKED_ALLOCZ(s->dct_error_sum, 2 * 64 * sizeof(int)) + CHECKED_ALLOCZ(s->dct_offset, 2 * 64 * sizeof(uint16_t)) + } } CHECKED_ALLOCZ(s->blocks, 64*6*2 * sizeof(DCTELEM)) @@ -588,6 +593,8 @@ av_freep(&s->blocks); av_freep(&s->input_picture); av_freep(&s->reordered_input_picture); + av_freep(&s->dct_error_sum); + av_freep(&s->dct_offset); if(s->picture){ for(i=0; idct_count[intra] > (1<<16)){ + for(i=0; i<64; i++){ + s->dct_error_sum[intra][i] >>=1; + } + s->dct_count[intra] >>= 1; + } + + for(i=0; i<64; i++){ + s->dct_offset[intra][i]= (s->avctx->noise_reduction * s->dct_count[intra] + s->dct_error_sum[intra][i]/2) / (s->dct_error_sum[intra][i]+1); + } + } +} + /** * generic function for encode/decode called after coding/decoding the header and before a frame is coded/decoded */ @@ -1136,6 +1160,12 @@ else s->dct_unquantize = s->dct_unquantize_mpeg1; + if(s->dct_error_sum){ + assert(s->avctx->noise_reduction && s->encoding); + + update_noise_reduction(s); + } + #ifdef HAVE_XVMC if(s->avctx->xvmc_acceleration) return XVMC_field_start(s, avctx); @@ -4042,6 +4072,28 @@ } } +void ff_denoise_dct(MpegEncContext *s, DCTELEM *block){ + const int intra= s->mb_intra; + int i; + + for(i=0; i<64; i++){ + int level= block[i]; + + if(level){ + if(level>0){ + s->dct_error_sum[intra][i] += level; + level -= s->dct_offset[intra][i]; + if(level<0) level=0; + }else{ + s->dct_error_sum[intra][i] -= level; + level += s->dct_offset[intra][i]; + if(level>0) level=0; + } + block[i]= level; + } + } +} + static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow){ @@ -4070,7 +4122,10 @@ const int patch_table= s->out_format == FMT_MPEG1 && !s->mb_intra; s->dsp.fdct (block); - + + if(s->dct_error_sum) + ff_denoise_dct(s, block); + qmul= qscale*16; qadd= ((qscale-1)|1)*8; @@ -4362,6 +4417,9 @@ s->dsp.fdct (block); + if(s->dct_error_sum) + ff_denoise_dct(s, block); + if (s->mb_intra) { if (!s->h263_aic) { if (n < 4) diff -r c1d5491f144a -r 4c9165372ab3 mpegvideo.h --- a/mpegvideo.h Sun Nov 02 22:56:47 2003 +0000 +++ b/mpegvideo.h Sun Nov 02 23:19:47 2003 +0000 @@ -468,6 +468,11 @@ ScanTable intra_h_scantable; ScanTable intra_v_scantable; ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce tha cache usage + + /* noise reduction */ + int (*dct_error_sum)[64]; + int dct_count[2]; + uint16_t (*dct_offset)[64]; void *opaque; ///< private data for the user @@ -719,6 +724,7 @@ void ff_print_debug_info(MpegEncContext *s, Picture *pict); void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix); int ff_find_unused_picture(MpegEncContext *s, int shared); +void ff_denoise_dct(MpegEncContext *s, DCTELEM *block); void ff_er_frame_start(MpegEncContext *s); void ff_er_frame_end(MpegEncContext *s);