summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mpegvideo.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index e792f3c852..3dd5443cd5 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -4941,6 +4941,7 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
DCTELEM *block, int16_t *weight, DCTELEM *orig,
int n, int qscale){
int16_t rem[64];
+ DCTELEM d1[64];
const int *qmat;
const uint8_t *scantable= s->intra_scantable.scantable;
const uint8_t *perm_scantable= s->intra_scantable.permutated;
@@ -5061,10 +5062,31 @@ STOP_TIMER("init rem[]")
int nochange_score= best_score;
int best_coeff=0;
int best_change=0;
- int run2, best_unquant_change;
+ int run2, best_unquant_change, analyze_gradient;
#ifdef REFINE_STATS
{START_TIMER
#endif
+ analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3;
+
+ if(analyze_gradient){
+#ifdef REFINE_STATS
+{START_TIMER
+#endif
+ for(i=0; i<64; i++){
+ int w= weight[i];
+
+ d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12);
+ }
+#ifdef REFINE_STATS
+STOP_TIMER("rem*w*w")}
+{START_TIMER
+#endif
+ s->dsp.fdct(d1);
+#ifdef REFINE_STATS
+STOP_TIMER("dct")}
+#endif
+ }
+
if(start_i){
const int level= block[0];
int change, old_coeff;
@@ -5141,6 +5163,13 @@ STOP_TIMER("init rem[]")
}
}else{
assert(ABS(new_level)==1);
+
+ if(analyze_gradient){
+ int g= d1[ scantable[i] ];
+ if(g && (g^new_level) >= 0)
+ continue;
+ }
+
if(i < last_non_zero){
int next_i= i + run2 + 1;
int next_level= block[ perm_scantable[next_i] ] + 64;