Originally committed as revision 3743 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
@@ -195,6 +195,8 @@ static int subpel_quality= 8; | |||
static int lowres= 0; | |||
static int frame_skip_threshold= 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 */ | |||
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->frame_skip_threshold= frame_skip_threshold; | |||
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){ | |||
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" }, | |||
{ "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_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 */ | |||
{ "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 "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 @@ typedef struct AVCodecContext { | |||
#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 @@ typedef struct AVCodecContext { | |||
* - 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; | |||
@@ -2891,6 +2891,9 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ | |||
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 @@ static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2 | |||
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 @@ 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_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 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) | |||
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; | |||
@@ -172,12 +172,14 @@ typedef struct DSPContext { | |||
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. | |||
@@ -1205,6 +1205,7 @@ int MPV_encode_init(AVCodecContext *avctx) | |||
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 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ | |||
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; | |||
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]); | |||
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); | |||
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) score64= score; | |||
if(score < s->avctx->frame_skip_threshold) | |||
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; | |||
} | |||