diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2002-03-22 02:21:17 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2002-03-22 02:21:17 +0000 |
commit | 45870f57182db02053328ec3ae110b5116438d43 (patch) | |
tree | 55cedd9a23c9f569bb572894152b8ced09e62414 /libavcodec/mpegvideo.c | |
parent | daa57641370d17af7c5d8d757d110027488182b8 (diff) | |
download | ffmpeg-45870f57182db02053328ec3ae110b5116438d43.tar.gz |
new motion estimation (epzs) not complete yet but allready pretty good :)
unlimited mv search range
minor bugfix in the mpeg4 header parser
reset picture in gop counter if scene change is detected
Originally committed as revision 344 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/mpegvideo.c')
-rw-r--r-- | libavcodec/mpegvideo.c | 83 |
1 files changed, 77 insertions, 6 deletions
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 054f12a577..180addb6f6 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -67,6 +67,9 @@ static UINT8 h263_chroma_roundtab[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, }; +static UINT16 default_mv_penalty[MAX_FCODE][MAX_MV*2+1]; +static UINT8 default_fcode_tab[MAX_MV*2+1]; + /* default motion estimation */ int motion_estimation_method = ME_LOG; @@ -356,8 +359,24 @@ int MPV_encode_init(AVCodecContext *avctx) return -1; } + { /* set up some save defaults, some codecs might override them later */ + static int done=0; + if(!done){ + int i; + done=1; + memset(default_mv_penalty, 0, sizeof(UINT16)*MAX_FCODE*(2*MAX_MV+1)); + memset(default_fcode_tab , 0, sizeof(UINT8)*(2*MAX_MV+1)); + + for(i=-16; i<16; i++){ + default_fcode_tab[i + MAX_MV]= 1; + } + } + } + s->mv_penalty= default_mv_penalty; + s->fcode_tab= default_fcode_tab; + if (s->out_format == FMT_H263) - h263_encode_init_vlc(s); + h263_encode_init(s); s->encoding = 1; @@ -375,6 +394,7 @@ int MPV_encode_init(AVCodecContext *avctx) rate_control_init(s); s->picture_number = 0; + s->picture_in_gop_number = 0; s->fake_picture_number = 0; /* motion detector init */ s->f_code = 1; @@ -480,9 +500,10 @@ int MPV_encode_picture(AVCodecContext *avctx, if (!s->intra_only) { /* first picture of GOP is intra */ - if ((s->picture_number % s->gop_size) == 0) + if (s->picture_in_gop_number >= s->gop_size){ + s->picture_in_gop_number=0; s->pict_type = I_TYPE; - else + }else s->pict_type = P_TYPE; } else { s->pict_type = I_TYPE; @@ -521,6 +542,7 @@ int MPV_encode_picture(AVCodecContext *avctx, MPV_frame_end(s); s->picture_number++; + s->picture_in_gop_number++; if (s->out_format == FMT_MJPEG) mjpeg_picture_trailer(s); @@ -1077,17 +1099,66 @@ static void encode_picture(MpegEncContext *s, int picture_number) s->mv_table[1][xy] = motion_y; } } + emms_c(); if(s->avg_mb_var < s->mc_mb_var && s->pict_type != B_TYPE){ //FIXME subtract MV bits int i; s->pict_type= I_TYPE; - for(i=0; i<s->mb_height*s->mb_width; i++){ - s->mb_type[i] = I_TYPE; + s->picture_in_gop_number=0; + for(i=0; i<s->mb_num; i++){ + s->mb_type[i] = 1; s->mv_table[0][i] = 0; s->mv_table[1][i] = 0; } } - + + /* find best f_code */ + if(s->pict_type==P_TYPE){ + int mv_num[8]; + int i; + int loose=0; + UINT8 * fcode_tab= s->fcode_tab; + + for(i=0; i<8; i++) mv_num[i]=0; + + for(i=0; i<s->mb_num; i++){ + if(s->mb_type[i] == 0){ + mv_num[ fcode_tab[s->mv_table[0][i] + MAX_MV] ]++; + mv_num[ fcode_tab[s->mv_table[1][i] + MAX_MV] ]++; +//printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i); + } +//else printf("I"); + } + + for(i=MAX_FCODE; i>1; i--){ + loose+= mv_num[i]; + if(loose > 4) break; + } + s->f_code= i; + }else{ + s->f_code= 1; + } +//printf("f_code %d ///\n", s->f_code); + /* convert MBs with too long MVs to I-Blocks */ + if(s->pict_type==P_TYPE){ + int i; + const int f_code= s->f_code; + UINT8 * fcode_tab= s->fcode_tab; + + for(i=0; i<s->mb_num; i++){ + if(s->mb_type[i] == 0){ + if( fcode_tab[s->mv_table[0][i] + MAX_MV] > f_code + || fcode_tab[s->mv_table[0][i] + MAX_MV] == 0 + || fcode_tab[s->mv_table[1][i] + MAX_MV] > f_code + || fcode_tab[s->mv_table[1][i] + MAX_MV] == 0 ){ + s->mb_type[i] = 1; + s->mv_table[0][i] = 0; + s->mv_table[1][i] = 0; + } + } + } + } + // printf("%d %d\n", s->avg_mb_var, s->mc_mb_var); if (!s->fixed_qscale) |