changeset 2382:23e7af611c34 libavcodec

more flexible frame skip decission
author michael
date Wed, 08 Dec 2004 18:02:56 +0000
parents cfc9e0489859
children 3c2abf00b7c1
files avcodec.h dsputil.c dsputil.h mpegvideo.c
diffstat 4 files changed, 56 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Wed Dec 08 11:46:16 2004 +0000
+++ b/avcodec.h	Wed Dec 08 18:02:56 2004 +0000
@@ -17,7 +17,7 @@
 
 #define FFMPEG_VERSION_INT     0x000409
 #define FFMPEG_VERSION         "0.4.9-pre1"
-#define LIBAVCODEC_BUILD       4735
+#define LIBAVCODEC_BUILD       4736
 
 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVCODEC_VERSION     FFMPEG_VERSION
@@ -1293,6 +1293,7 @@
 #define FF_CMP_NSSE 10
 #define FF_CMP_W53  11
 #define FF_CMP_W97  12
+#define FF_CMP_DCTMAX 13
 #define FF_CMP_CHROMA 256
     
     /**
@@ -1703,6 +1704,20 @@
      * - decoding: unused
      */
     int frame_skip_factor;
+
+    /**
+     * frame skip exponent
+     * - encoding: set by user
+     * - decoding: unused
+     */
+    int frame_skip_exp;
+
+    /**
+     * frame skip comparission function
+     * - encoding: set by user.
+     * - decoding: unused
+     */
+    int frame_skip_cmp;
 } AVCodecContext;
 
 
--- a/dsputil.c	Wed Dec 08 11:46:16 2004 +0000
+++ b/dsputil.c	Wed Dec 08 18:02:56 2004 +0000
@@ -2891,6 +2891,9 @@
         case FF_CMP_DCT:
             cmp[i]= c->dct_sad[i];
             break;
+        case FF_CMP_DCTMAX:
+            cmp[i]= c->dct_max[i];
+            break;
         case FF_CMP_PSNR:
             cmp[i]= c->quant_psnr[i];
             break;
@@ -3114,6 +3117,23 @@
     return sum;
 }
 
+static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
+    MpegEncContext * const s= (MpegEncContext *)c;
+    uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8];
+    DCTELEM * const temp= (DCTELEM*)aligned_temp;
+    int sum=0, i;
+    
+    assert(h==8);
+
+    s->dsp.diff_pixels(temp, src1, src2, stride);
+    s->dsp.fdct(temp);
+
+    for(i=0; i<64; i++)
+        sum= FFMAX(sum, ABS(temp[i]));
+        
+    return sum;
+}
+
 void simple_idct(DCTELEM *block); //FIXME
 
 static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
@@ -3343,6 +3363,7 @@
 WARPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
 WARPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
 WARPER8_16_SQ(dct_sad8x8_c, dct_sad16_c)
+WARPER8_16_SQ(dct_max8x8_c, dct_max16_c)
 WARPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
 WARPER8_16_SQ(rd8x8_c, rd16_c)
 WARPER8_16_SQ(bit8x8_c, bit16_c)
@@ -3599,6 +3620,7 @@
     SET_CMP_FUNC(hadamard8_diff)
     c->hadamard8_diff[4]= hadamard8_intra16_c;
     SET_CMP_FUNC(dct_sad)
+    SET_CMP_FUNC(dct_max)
     c->sad[0]= pix_abs16_c;
     c->sad[1]= pix_abs8_c;
     c->sse[0]= sse16_c;
--- a/dsputil.h	Wed Dec 08 11:46:16 2004 +0000
+++ b/dsputil.h	Wed Dec 08 18:02:56 2004 +0000
@@ -172,12 +172,14 @@
     me_cmp_func nsse[5];
     me_cmp_func w53[5];
     me_cmp_func w97[5];
+    me_cmp_func dct_max[5];
 
     me_cmp_func me_pre_cmp[5];
     me_cmp_func me_cmp[5];
     me_cmp_func me_sub_cmp[5];
     me_cmp_func mb_cmp[5];
     me_cmp_func ildct_cmp[5]; //only width 16 used
+    me_cmp_func frame_skip_cmp[5]; //only width 8 used
 
     /**
      * Halfpel motion compensation with rounding (a+b+1)>>1.
--- a/mpegvideo.c	Wed Dec 08 11:46:16 2004 +0000
+++ b/mpegvideo.c	Wed Dec 08 18:02:56 2004 +0000
@@ -1205,6 +1205,7 @@
     s->quant_precision=5;
     
     ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);
+    ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp);
     
 #ifdef CONFIG_ENCODERS
 #ifdef CONFIG_RISKY
@@ -2018,40 +2019,35 @@
     return 0;
 }
 
-static inline int block_max(DCTELEM *block){
-    int i, max;
-    
-    max=0;
-    for(i=0; i<64; i++){
-        int v= ABS(block[i]);
-        if(v>max) max= v;
-    }
-    return max;
-}
-
 static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){
     int x, y, plane;
     int score=0;
+    int64_t score64=0;
+    int64_t threshold;
 
     for(plane=0; plane<3; plane++){
         const int stride= p->linesize[plane];
         const int bw= plane ? 1 : 2;
         for(y=0; y<s->mb_height*bw; y++){
             for(x=0; x<s->mb_width*bw; x++){
-                int v;
+                int v= s->dsp.frame_skip_cmp[1](s, p->data[plane] + 8*(x + y*stride), ref->data[plane] + 8*(x + y*stride), stride, 8);
                 
-                s->dsp.diff_pixels(s->block[0], p->data[plane] + 8*(x + y*stride), ref->data[plane] + 8*(x + y*stride), stride);
-                v= block_max(s->block[0]);
-                
-                if(v>score) 
-                    score=v;
+                switch(s->avctx->frame_skip_exp){
+                    case 0: score= FFMAX(score, v); break;
+                    case 1: score+= ABS(v);break;
+                    case 2: score+= v*v;break;
+                    case 3: score64+= ABS(v*v*(int64_t)v);break;
+                    case 4: score64+= v*v*(int64_t)(v*v);break;
+                }
             }
         }
     }
-
-    if(score < s->avctx->frame_skip_threshold)
+    
+    if(score) score64= score;
+
+    if(score64 < s->avctx->frame_skip_threshold)
         return 1;
-    if(score < ((s->avctx->frame_skip_factor * s->lambda)>>8))
+    if(score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda)>>8))
         return 1;
     return 0;
 }