# HG changeset patch # User michael # Date 1102506376 0 # Node ID cfc9e04898595bb66c13471b9285790b22d58daa # Parent 3daf36fd1999dc1b07540741d4ea3ced0c99979a frame skip support diff -r 3daf36fd1999 -r cfc9e0489859 avcodec.h --- a/avcodec.h Tue Dec 07 13:14:37 2004 +0000 +++ b/avcodec.h Wed Dec 08 11:46:16 2004 +0000 @@ -17,7 +17,7 @@ #define FFMPEG_VERSION_INT 0x000409 #define FFMPEG_VERSION "0.4.9-pre1" -#define LIBAVCODEC_BUILD 4734 +#define LIBAVCODEC_BUILD 4735 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -1683,12 +1683,26 @@ int lowres; /** - * bistream width / height. may be different from width/height if lowres + * bitsream width / height. may be different from width/height if lowres * or other things are used * - encoding: unused * - decoding: set by user before init if known, codec should override / dynamically change if needed */ int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: set by user + * - decoding: unused + */ + int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: set by user + * - decoding: unused + */ + int frame_skip_factor; } AVCodecContext; diff -r 3daf36fd1999 -r cfc9e0489859 mpegvideo.c --- a/mpegvideo.c Tue Dec 07 13:14:37 2004 +0000 +++ b/mpegvideo.c Wed Dec 08 11:46:16 2004 +0000 @@ -2018,6 +2018,44 @@ 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; + + for(plane=0; plane<3; plane++){ + const int stride= p->linesize[plane]; + const int bw= plane ? 1 : 2; + for(y=0; ymb_height*bw; y++){ + for(x=0; xmb_width*bw; x++){ + int v; + + 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; + } + } + } + + if(score < s->avctx->frame_skip_threshold) + return 1; + if(score < ((s->avctx->frame_skip_factor * s->lambda)>>8)) + return 1; + return 0; +} + static void select_input_picture(MpegEncContext *s){ int i; @@ -2033,7 +2071,26 @@ s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; }else{ int b_frames; + + if(s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor){ + if(skip_check(s, s->input_picture[0], s->next_picture_ptr)){ +//av_log(NULL, AV_LOG_DEBUG, "skip %p %Ld\n", s->input_picture[0]->data[0], s->input_picture[0]->pts); + + if(s->input_picture[0]->type == FF_BUFFER_TYPE_SHARED){ + for(i=0; i<4; i++) + s->input_picture[0]->data[i]= NULL; + s->input_picture[0]->type= 0; + }else{ + assert( s->input_picture[0]->type==FF_BUFFER_TYPE_USER + || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); + s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]); + } + + goto no_output_pic; + } + } + if(s->flags&CODEC_FLAG_PASS2){ for(i=0; imax_b_frames+1; i++){ int pict_num= s->input_picture[0]->display_picture_number + i; @@ -2116,7 +2173,7 @@ } } } - +no_output_pic: if(s->reordered_input_picture[0]){ s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE ? 3 : 0;