more flexible frame skip decission
Originally committed as revision 3743 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							
								
								
									
										6
									
								
								ffmpeg.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								ffmpeg.c
									
									
									
									
									
								
							@@ -195,6 +195,8 @@ static int subpel_quality= 8;
 | 
				
			|||||||
static int lowres= 0;
 | 
					static int lowres= 0;
 | 
				
			||||||
static int frame_skip_threshold= 0;
 | 
					static int frame_skip_threshold= 0;
 | 
				
			||||||
static int frame_skip_factor= 0;
 | 
					static int frame_skip_factor= 0;
 | 
				
			||||||
 | 
					static int frame_skip_exp= 0;
 | 
				
			||||||
 | 
					static int frame_skip_cmp= FF_CMP_DCTMAX;
 | 
				
			||||||
extern int loop_input; /* currently a hack */
 | 
					extern int loop_input; /* currently a hack */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int gop_size = 12;
 | 
					static int gop_size = 12;
 | 
				
			||||||
@@ -3227,6 +3229,8 @@ static void opt_output_file(const char *filename)
 | 
				
			|||||||
                video_enc->me_subpel_quality= subpel_quality;
 | 
					                video_enc->me_subpel_quality= subpel_quality;
 | 
				
			||||||
                video_enc->frame_skip_threshold= frame_skip_threshold;
 | 
					                video_enc->frame_skip_threshold= frame_skip_threshold;
 | 
				
			||||||
                video_enc->frame_skip_factor= frame_skip_factor;
 | 
					                video_enc->frame_skip_factor= frame_skip_factor;
 | 
				
			||||||
 | 
					                video_enc->frame_skip_exp= frame_skip_exp;
 | 
				
			||||||
 | 
					                video_enc->frame_skip_cmp= frame_skip_cmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(packet_size){
 | 
					                if(packet_size){
 | 
				
			||||||
                    video_enc->rtp_mode= 1;
 | 
					                    video_enc->rtp_mode= 1;
 | 
				
			||||||
@@ -3955,6 +3959,8 @@ const OptionDef options[] = {
 | 
				
			|||||||
    { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" },
 | 
					    { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" },
 | 
				
			||||||
    { "skip_threshold", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_threshold}, "frame skip threshold", "threshold" },
 | 
					    { "skip_threshold", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_threshold}, "frame skip threshold", "threshold" },
 | 
				
			||||||
    { "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" },
 | 
					    { "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" },
 | 
				
			||||||
 | 
					    { "skip_exp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_exp}, "frame skip exponent", "exponent" },
 | 
				
			||||||
 | 
					    { "skip_cmp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_cmp}, "frame skip compare function", "compare function" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* audio options */
 | 
					    /* audio options */
 | 
				
			||||||
    { "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },
 | 
					    { "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ extern "C" {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define FFMPEG_VERSION_INT     0x000409
 | 
					#define FFMPEG_VERSION_INT     0x000409
 | 
				
			||||||
#define FFMPEG_VERSION         "0.4.9-pre1"
 | 
					#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_INT FFMPEG_VERSION_INT
 | 
				
			||||||
#define LIBAVCODEC_VERSION     FFMPEG_VERSION
 | 
					#define LIBAVCODEC_VERSION     FFMPEG_VERSION
 | 
				
			||||||
@@ -1293,6 +1293,7 @@ typedef struct AVCodecContext {
 | 
				
			|||||||
#define FF_CMP_NSSE 10
 | 
					#define FF_CMP_NSSE 10
 | 
				
			||||||
#define FF_CMP_W53  11
 | 
					#define FF_CMP_W53  11
 | 
				
			||||||
#define FF_CMP_W97  12
 | 
					#define FF_CMP_W97  12
 | 
				
			||||||
 | 
					#define FF_CMP_DCTMAX 13
 | 
				
			||||||
#define FF_CMP_CHROMA 256
 | 
					#define FF_CMP_CHROMA 256
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -1703,6 +1704,20 @@ typedef struct AVCodecContext {
 | 
				
			|||||||
     * - decoding: unused
 | 
					     * - decoding: unused
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    int frame_skip_factor;
 | 
					    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;
 | 
					} AVCodecContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2891,6 +2891,9 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){
 | 
				
			|||||||
        case FF_CMP_DCT:
 | 
					        case FF_CMP_DCT:
 | 
				
			||||||
            cmp[i]= c->dct_sad[i];
 | 
					            cmp[i]= c->dct_sad[i];
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case FF_CMP_DCTMAX:
 | 
				
			||||||
 | 
					            cmp[i]= c->dct_max[i];
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        case FF_CMP_PSNR:
 | 
					        case FF_CMP_PSNR:
 | 
				
			||||||
            cmp[i]= c->quant_psnr[i];
 | 
					            cmp[i]= c->quant_psnr[i];
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@@ -3114,6 +3117,23 @@ static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2
 | 
				
			|||||||
    return sum;
 | 
					    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
 | 
					void simple_idct(DCTELEM *block); //FIXME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
 | 
					static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
 | 
				
			||||||
@@ -3343,6 +3363,7 @@ static int vsse16_c(/*MpegEncContext*/ void *c, uint8_t *s1, uint8_t *s2, int st
 | 
				
			|||||||
WARPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
 | 
					WARPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
 | 
				
			||||||
WARPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
 | 
					WARPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
 | 
				
			||||||
WARPER8_16_SQ(dct_sad8x8_c, dct_sad16_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(quant_psnr8x8_c, quant_psnr16_c)
 | 
				
			||||||
WARPER8_16_SQ(rd8x8_c, rd16_c)
 | 
					WARPER8_16_SQ(rd8x8_c, rd16_c)
 | 
				
			||||||
WARPER8_16_SQ(bit8x8_c, bit16_c)
 | 
					WARPER8_16_SQ(bit8x8_c, bit16_c)
 | 
				
			||||||
@@ -3599,6 +3620,7 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
 | 
				
			|||||||
    SET_CMP_FUNC(hadamard8_diff)
 | 
					    SET_CMP_FUNC(hadamard8_diff)
 | 
				
			||||||
    c->hadamard8_diff[4]= hadamard8_intra16_c;
 | 
					    c->hadamard8_diff[4]= hadamard8_intra16_c;
 | 
				
			||||||
    SET_CMP_FUNC(dct_sad)
 | 
					    SET_CMP_FUNC(dct_sad)
 | 
				
			||||||
 | 
					    SET_CMP_FUNC(dct_max)
 | 
				
			||||||
    c->sad[0]= pix_abs16_c;
 | 
					    c->sad[0]= pix_abs16_c;
 | 
				
			||||||
    c->sad[1]= pix_abs8_c;
 | 
					    c->sad[1]= pix_abs8_c;
 | 
				
			||||||
    c->sse[0]= sse16_c;
 | 
					    c->sse[0]= sse16_c;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -172,12 +172,14 @@ typedef struct DSPContext {
 | 
				
			|||||||
    me_cmp_func nsse[5];
 | 
					    me_cmp_func nsse[5];
 | 
				
			||||||
    me_cmp_func w53[5];
 | 
					    me_cmp_func w53[5];
 | 
				
			||||||
    me_cmp_func w97[5];
 | 
					    me_cmp_func w97[5];
 | 
				
			||||||
 | 
					    me_cmp_func dct_max[5];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    me_cmp_func me_pre_cmp[5];
 | 
					    me_cmp_func me_pre_cmp[5];
 | 
				
			||||||
    me_cmp_func me_cmp[5];
 | 
					    me_cmp_func me_cmp[5];
 | 
				
			||||||
    me_cmp_func me_sub_cmp[5];
 | 
					    me_cmp_func me_sub_cmp[5];
 | 
				
			||||||
    me_cmp_func mb_cmp[5];
 | 
					    me_cmp_func mb_cmp[5];
 | 
				
			||||||
    me_cmp_func ildct_cmp[5]; //only width 16 used
 | 
					    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.
 | 
					     * Halfpel motion compensation with rounding (a+b+1)>>1.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1205,6 +1205,7 @@ int MPV_encode_init(AVCodecContext *avctx)
 | 
				
			|||||||
    s->quant_precision=5;
 | 
					    s->quant_precision=5;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);
 | 
					    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_ENCODERS
 | 
				
			||||||
#ifdef CONFIG_RISKY
 | 
					#ifdef CONFIG_RISKY
 | 
				
			||||||
@@ -2018,40 +2019,35 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
 | 
				
			|||||||
    return 0;
 | 
					    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){
 | 
					static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){
 | 
				
			||||||
    int x, y, plane;
 | 
					    int x, y, plane;
 | 
				
			||||||
    int score=0;
 | 
					    int score=0;
 | 
				
			||||||
 | 
					    int64_t score64=0;
 | 
				
			||||||
 | 
					    int64_t threshold;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(plane=0; plane<3; plane++){
 | 
					    for(plane=0; plane<3; plane++){
 | 
				
			||||||
        const int stride= p->linesize[plane];
 | 
					        const int stride= p->linesize[plane];
 | 
				
			||||||
        const int bw= plane ? 1 : 2;
 | 
					        const int bw= plane ? 1 : 2;
 | 
				
			||||||
        for(y=0; y<s->mb_height*bw; y++){
 | 
					        for(y=0; y<s->mb_height*bw; y++){
 | 
				
			||||||
            for(x=0; x<s->mb_width*bw; x++){
 | 
					            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);
 | 
					                switch(s->avctx->frame_skip_exp){
 | 
				
			||||||
                v= block_max(s->block[0]);
 | 
					                    case 0: score= FFMAX(score, v); break;
 | 
				
			||||||
                
 | 
					                    case 1: score+= ABS(v);break;
 | 
				
			||||||
                if(v>score) 
 | 
					                    case 2: score+= v*v;break;
 | 
				
			||||||
                    score=v;
 | 
					                    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;
 | 
					        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 1;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user