diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-09-16 21:49:34 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-09-16 21:49:34 +0000 |
commit | d2db0f3bbdc81aae2c316751daf1d53b42a3e6a0 (patch) | |
tree | e9f4a94547ada41ea13445185a20305378d6c0bd /src/libffmpeg/libavcodec/h263.c | |
parent | d35f836384d9fa164350612ead96362d9cd7b457 (diff) | |
download | xine-lib-d2db0f3bbdc81aae2c316751daf1d53b42a3e6a0.tar.gz xine-lib-d2db0f3bbdc81aae2c316751daf1d53b42a3e6a0.tar.bz2 |
- sync ffmpeg to cvs (sorry Mike it still doesn't decode your teststream --
something must be broken at ffmpeg, also happens with mplayer)
- added priority sorted lists, now autoprobing should work again.
- fixed infinite loop in plugin loader.
obs: latest ffmpeg contains ppc optimizations, someone will have to enable these
though.
CVS patchset: 2676
CVS date: 2002/09/16 21:49:34
Diffstat (limited to 'src/libffmpeg/libavcodec/h263.c')
-rw-r--r-- | src/libffmpeg/libavcodec/h263.c | 678 |
1 files changed, 495 insertions, 183 deletions
diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c index 2fd90e9ec..c9a0a9d30 100644 --- a/src/libffmpeg/libavcodec/h263.c +++ b/src/libffmpeg/libavcodec/h263.c @@ -18,7 +18,9 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * ac prediction encoding & b-frame support by Michael Niedermayer <michaelni@gmx.at> + * ac prediction encoding, b-frame support, error resilience, optimizations, + * qpel decoding, gmc decoding, interlaced decoding, + * by Michael Niedermayer <michaelni@gmx.at> */ //#define DEBUG @@ -48,7 +50,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n); static void h263_encode_motion(MpegEncContext * s, int val, int fcode); static void h263p_encode_umotion(MpegEncContext * s, int val); -static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, +static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int dc, UINT8 *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb); static int h263_decode_motion(MpegEncContext * s, int pred, int fcode); @@ -71,6 +73,22 @@ static UINT8 umv_fcode_tab[MAX_MV*2+1]; static UINT16 uni_DCtab_lum [512][2]; static UINT16 uni_DCtab_chrom[512][2]; +static UINT32 uni_mpeg4_intra_rl_bits[64*64*2*2]; +static UINT8 uni_mpeg4_intra_rl_len [64*64*2*2]; +static UINT32 uni_mpeg4_inter_rl_bits[64*64*2*2]; +static UINT8 uni_mpeg4_inter_rl_len [64*64*2*2]; +#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level)) +//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64) + +/* mpeg4 +inter +max level: 24/6 +max run: 53/63 + +intra +max level: 53/16 +max run: 29/41 +*/ int h263_get_picture_format(int width, int height) { @@ -169,12 +187,17 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) /* Custom Picture Format (CPFMT) */ if (s->aspect_ratio_info) - put_bits(&s->pb,4,s->aspect_ratio_info); + put_bits(&s->pb,4,s->aspect_ratio_info); else - put_bits(&s->pb,4,2); /* Aspect ratio: CIF 12:11 (4:3) picture */ + put_bits(&s->pb,4,2); /* Aspect ratio: CIF 12:11 (4:3) picture */ put_bits(&s->pb,9,(s->width >> 2) - 1); put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ put_bits(&s->pb,9,(s->height >> 2)); + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) + { + put_bits(&s->pb, 8, s->aspected_width); + put_bits(&s->pb, 8, s->aspected_height); + } } /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ @@ -347,6 +370,8 @@ void mpeg4_encode_mb(MpegEncContext * s, case 0: /* direct */ h263_encode_motion(s, motion_x, 1); h263_encode_motion(s, motion_y, 1); + s->b_count++; + s->f_count++; break; case 1: /* bidir */ h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); @@ -357,18 +382,22 @@ void mpeg4_encode_mb(MpegEncContext * s, s->last_mv[0][0][1]= s->mv[0][0][1]; s->last_mv[1][0][0]= s->mv[1][0][0]; s->last_mv[1][0][1]= s->mv[1][0][1]; + s->b_count++; + s->f_count++; break; case 2: /* backward */ h263_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); h263_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); s->last_mv[1][0][0]= motion_x; s->last_mv[1][0][1]= motion_y; + s->b_count++; break; case 3: /* forward */ h263_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); h263_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); s->last_mv[0][0][0]= motion_x; s->last_mv[0][0][1]= motion_y; + s->f_count++; break; default: printf("unknown mb type\n"); @@ -499,7 +528,7 @@ void mpeg4_encode_mb(MpegEncContext * s, s->p_tex_bits+= bits - s->last_bits; s->last_bits=bits; } - s->p_count++; + s->f_count++; } } else { int cbp; @@ -1085,6 +1114,91 @@ static void init_uni_dc_tab(void) } } +static void init_uni_mpeg4_rl_tab(RLTable *rl, UINT32 *bits_tab, UINT8 *len_tab){ + int slevel, run, last; + + assert(MAX_LEVEL >= 64); + assert(MAX_RUN >= 63); + + for(slevel=-64; slevel<64; slevel++){ + if(slevel==0) continue; + for(run=0; run<64; run++){ + for(last=0; last<=1; last++){ + const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); + int level= slevel < 0 ? -slevel : slevel; + int sign= slevel < 0 ? 1 : 0; + int bits, len, code; + int level1, run1; + + len_tab[index]= 100; + + /* ESC0 */ + code= get_rl_index(rl, last, run, level); + bits= rl->table_vlc[code][0]; + len= rl->table_vlc[code][1]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } +#if 1 + /* ESC1 */ + bits= rl->table_vlc[rl->n][0]; + len= rl->table_vlc[rl->n][1]; + bits=bits*2; len++; //esc1 + level1= level - rl->max_level[last][run]; + if(level1>0){ + code= get_rl_index(rl, last, run, level1); + bits<<= rl->table_vlc[code][1]; + len += rl->table_vlc[code][1]; + bits += rl->table_vlc[code][0]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } + } +#endif +#if 1 + /* ESC2 */ + bits= rl->table_vlc[rl->n][0]; + len= rl->table_vlc[rl->n][1]; + bits=bits*4+2; len+=2; //esc2 + run1 = run - rl->max_run[last][level] - 1; + if(run1>=0){ + code= get_rl_index(rl, last, run1, level); + bits<<= rl->table_vlc[code][1]; + len += rl->table_vlc[code][1]; + bits += rl->table_vlc[code][0]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } + } +#endif + /* ESC3 */ + bits= rl->table_vlc[rl->n][0]; + len = rl->table_vlc[rl->n][1]; + bits=bits*4+3; len+=2; //esc3 + bits=bits*2+last; len++; + bits=bits*64+run; len+=6; + bits=bits*2+1; len++; //marker + bits=bits*4096+(slevel&0xfff); len+=12; + bits=bits*2+1; len++; //marker + + if(len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } + } + } + } +} + void h263_encode_init(MpegEncContext *s) { static int done = 0; @@ -1097,6 +1211,9 @@ void h263_encode_init(MpegEncContext *s) init_rl(&rl_inter); init_rl(&rl_intra); init_rl(&rl_intra_aic); + + init_uni_mpeg4_rl_tab(&rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); + init_uni_mpeg4_rl_tab(&rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); init_mv_penalty_and_fcode(s); } @@ -1210,13 +1327,16 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; } - - s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; + + if(s->avctx->pts) + s->time= (s->avctx->pts*s->time_increment_resolution + 500*1000)/(1000*1000); + else + s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; time_div= s->time/s->time_increment_resolution; time_mod= s->time%s->time_increment_resolution; if(s->pict_type==B_TYPE){ - s->bp_time= s->last_non_b_time - s->time; + s->pb_time= s->pp_time - (s->last_non_b_time - s->time); }else{ s->last_time_base= s->time_base; s->time_base= time_div; @@ -1246,6 +1366,11 @@ static void mpeg4_encode_vol_header(MpegEncContext * s) put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ else put_bits(&s->pb, 4, 1); /* aspect ratio info= sqare pixel */ + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) + { + put_bits(&s->pb, 8, s->aspected_width); + put_bits(&s->pb, 8, s->aspected_height); + } if(s->low_delay){ put_bits(&s->pb, 1, 1); /* vol control parameters= yes */ @@ -1295,14 +1420,17 @@ static void mpeg4_encode_vol_header(MpegEncContext * s) put_bits(&s->pb, 1, 0); /* reduced res vop */ } put_bits(&s->pb, 1, 0); /* scalability */ - + ff_mpeg4_stuffing(&s->pb); - put_bits(&s->pb, 16, 0); - put_bits(&s->pb, 16, 0x1B2); /* user_data */ - sprintf(buf, "FFmpeg%sb%s", FFMPEG_VERSION, LIBAVCODEC_BUILD_STR); - put_string(&s->pb, buf); - ff_mpeg4_stuffing(&s->pb); + /* user data */ + if(!ff_bit_exact){ + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, 0x1B2); /* user_data */ + sprintf(buf, "FFmpeg%sb%s", FFMPEG_VERSION, LIBAVCODEC_BUILD_STR); + put_string(&s->pb, buf); + ff_mpeg4_stuffing(&s->pb); + } } /* write mpeg4 VOP header */ @@ -1529,34 +1657,69 @@ static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) #endif } -static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, +static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, UINT8 *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) { - int level, run, last, i, j, last_index, last_non_zero, sign, slevel; + int last, i, last_non_zero, sign; int code; const RLTable *rl; + UINT32 *bits_tab; + UINT8 *len_tab; + const int last_index = s->block_last_index[n]; - if (s->mb_intra) { + if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away /* mpeg4 based DC predictor */ mpeg4_encode_dc(dc_pb, intra_dc, n); + if(last_index<1) return; i = 1; rl = &rl_intra; + bits_tab= uni_mpeg4_intra_rl_bits; + len_tab = uni_mpeg4_intra_rl_len; } else { + if(last_index<0) return; i = 0; rl = &rl_inter; + bits_tab= uni_mpeg4_inter_rl_bits; + len_tab = uni_mpeg4_inter_rl_len; } /* AC coefs */ - last_index = s->block_last_index[n]; last_non_zero = i - 1; - for (; i <= last_index; i++) { - j = scan_table[i]; - level = block[j]; +#if 1 + for (; i < last_index; i++) { + int level = block[ scan_table[i] ]; if (level) { - run = i - last_non_zero - 1; + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(0, run, level); + put_bits(ac_pb, len_tab[index], bits_tab[index]); + }else{ //ESC3 + put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } + last_non_zero = i; + } + } + /*if(i<=last_index)*/{ + int level = block[ scan_table[i] ]; + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(1, run, level); + put_bits(ac_pb, len_tab[index], bits_tab[index]); + }else{ //ESC3 + put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } + } +#else + for (; i <= last_index; i++) { + const int slevel = block[ scan_table[i] ]; + if (slevel) { + int level; + int run = i - last_non_zero - 1; last = (i == last_index); sign = 0; - slevel = level; + level = slevel; if (level < 0) { sign = 1; level = -level; @@ -1605,6 +1768,7 @@ static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int i last_non_zero = i; } } +#endif } @@ -1746,6 +1910,8 @@ void h263_decode_init_vlc(MpegEncContext *s) &mb_type_b_tab[0][1], 2, 1, &mb_type_b_tab[0][0], 2, 1); } + + s->progressive_sequence=1; // set to most likely for the case of incomplete headers } int h263_decode_gob_header(MpegEncContext *s) @@ -1895,24 +2061,12 @@ static int decode_video_packet_header(MpegEncContext *s, GetBitContext *gb) if(header_extension){ int time_increment; int time_incr=0; - printf("header extension not supported\n"); - return -1; while (get_bits1(gb) != 0) time_incr++; check_marker(gb, "before time_increment in video packed header"); time_increment= get_bits(gb, s->time_increment_bits); - if(s->pict_type!=B_TYPE){ - s->last_time_base= s->time_base; - s->time_base+= time_incr; - s->time= s->time_base*s->time_increment_resolution + time_increment; - s->pp_time= s->time - s->last_non_b_time; - s->last_non_b_time= s->time; - }else{ - s->time= (s->last_time_base + time_incr)*s->time_increment_resolution + time_increment; - s->bp_time= s->last_non_b_time - s->time; - } check_marker(gb, "before vop_coding_type in video packed header"); skip_bits(gb, 2); /* vop coding type */ @@ -1923,19 +2077,22 @@ static int decode_video_packet_header(MpegEncContext *s, GetBitContext *gb) if(s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE && s->num_sprite_warping_points){ mpeg4_decode_sprite_trajectory(s); + fprintf(stderr, "untested\n"); } //FIXME reduced res stuff here if (s->pict_type != I_TYPE) { - s->f_code = get_bits(gb, 3); /* fcode_for */ - if(s->f_code==0){ - printf("Error, video packet header damaged or not MPEG4 header (f_code=0)\n"); - return -1; // makes no sense to continue, as the MV decoding will break very quickly + int f_code = get_bits(gb, 3); /* fcode_for */ + if(f_code==0){ + printf("Error, video packet header damaged (f_code=0)\n"); } } if (s->pict_type == B_TYPE) { - s->b_code = get_bits(gb, 3); + int b_code = get_bits(gb, 3); + if(b_code==0){ + printf("Error, video packet header damaged (b_code=0)\n"); + } } } } @@ -2426,7 +2583,37 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, return 0; } +#if 0 +static inline void decode_interlaced_info(MpegEncContext *s, int cbp, int mb_type){ + s->mv_type= 0; + if(!s->progressive_sequence){ + if(cbp || s->mb_intra) + s->interlaced_dct= get_bits1(&s->gb); + + if(!s->mb_intra){ + if( s->pict_type==P_TYPE //FIXME check that 4MV is forbidden + || (s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && !s->mcsel) + || (s->pict_type==B_TYPE && mb_type!=0) ){ + + if(get_bits1(&s->gb)){ + s->mv_type= MV_TYPE_FIELD; + if( s->pict_type==P_TYPE + || (s->pict_type==B_TYPE && mb_type!=2)){ + s->field_select[0][0]= get_bits1(&s->gb); + s->field_select[0][1]= get_bits1(&s->gb); + } + if(s->pict_type==B_TYPE && mb_type!=3){ + s->field_select[1][0]= get_bits1(&s->gb); + s->field_select[1][1]= get_bits1(&s->gb); + } + }else + s->mv_type= 0; + } + } + } +} +#endif int h263_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) @@ -2507,55 +2694,75 @@ int h263_decode_mb(MpegEncContext *s, s->qscale = 31; h263_dc_scale(s); } + if((!s->progressive_sequence) && (cbp || s->workaround_bugs==2)) + s->interlaced_dct= get_bits1(&s->gb); + s->mv_dir = MV_DIR_FORWARD; if ((cbpc & 16) == 0) { - PRINT_MB_TYPE("P"); - /* 16x16 motion prediction */ - s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, &pred_x, &pred_y); - if (s->umvplus_dec) - mx = h263p_decode_umotion(s, pred_x); - else if(!s->mcsel) - mx = h263_decode_motion(s, pred_x, s->f_code); - else { - const int a= s->sprite_warping_accuracy; + if(s->mcsel){ + const int a= s->sprite_warping_accuracy; + PRINT_MB_TYPE("G"); + /* 16x16 global motion prediction */ + s->mv_type = MV_TYPE_16X16; // int l = (1 << (s->f_code - 1)) * 32; if(s->divx_version==500 && s->divx_build==413){ mx = s->sprite_offset[0][0] / (1<<(a-s->quarter_sample)); + my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample)); }else{ mx = RSHIFT(s->sprite_offset[0][0], a-s->quarter_sample); + my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample); } -// if (mx < -l) mx= -l, printf("C"); -// else if (mx >= l) mx= l-1, printf("C"); - } - if (mx >= 0xffff) - return -1; - - if (s->umvplus_dec) - my = h263p_decode_umotion(s, pred_y); - else if(!s->mcsel) - my = h263_decode_motion(s, pred_y, s->f_code); - else{ - const int a= s->sprite_warping_accuracy; // int l = (1 << (s->f_code - 1)) * 32; - if(s->divx_version==500 && s->divx_build==413){ - my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample)); - }else{ - my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample); + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + }else if((!s->progressive_sequence) && get_bits1(&s->gb)){ + PRINT_MB_TYPE("f"); + /* 16x8 field motion prediction */ + s->mv_type= MV_TYPE_FIELD; + + s->field_select[0][0]= get_bits1(&s->gb); + s->field_select[0][1]= get_bits1(&s->gb); + + h263_pred_motion(s, 0, &pred_x, &pred_y); + + for(i=0; i<2; i++){ + mx = h263_decode_motion(s, pred_x, s->f_code); + if (mx >= 0xffff) + return -1; + + my = h263_decode_motion(s, pred_y/2, s->f_code); + if (my >= 0xffff) + return -1; + + s->mv[0][i][0] = mx; + s->mv[0][i][1] = my; } -// if (my < -l) my= -l, printf("C"); -// else if (my >= l) my= l-1, printf("C"); + }else{ + PRINT_MB_TYPE("P"); + /* 16x16 motion prediction */ + s->mv_type = MV_TYPE_16X16; + h263_pred_motion(s, 0, &pred_x, &pred_y); + if (s->umvplus_dec) + mx = h263p_decode_umotion(s, pred_x); + else + mx = h263_decode_motion(s, pred_x, s->f_code); + + if (mx >= 0xffff) + return -1; + + if (s->umvplus_dec) + my = h263p_decode_umotion(s, pred_y); + else + my = h263_decode_motion(s, pred_y, s->f_code); + + if (my >= 0xffff) + return -1; + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + + if (s->umvplus_dec && (mx - pred_x) == 1 && (my - pred_y) == 1) + skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ } - if (my >= 0xffff) - return -1; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - /*fprintf(stderr, "\n MB %d", (s->mb_y * s->mb_width) + s->mb_x); - fprintf(stderr, "\n\tmvx: %d\t\tpredx: %d", mx, pred_x); - fprintf(stderr, "\n\tmvy: %d\t\tpredy: %d", my, pred_y);*/ - if (s->umvplus_dec && (mx - pred_x) == 1 && (my - pred_y) == 1) - skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ - } else { PRINT_MB_TYPE("4"); s->mv_type = MV_TYPE_8X8; @@ -2594,10 +2801,12 @@ int h263_decode_mb(MpegEncContext *s, s->mcsel=0; // ... true gmc blocks if(s->mb_x==0){ - s->last_mv[0][0][0]= - s->last_mv[0][0][1]= - s->last_mv[1][0][0]= - s->last_mv[1][0][1]= 0; + for(i=0; i<2; i++){ + s->last_mv[i][0][0]= + s->last_mv[i][0][1]= + s->last_mv[i][1][0]= + s->last_mv[i][1][1]= 0; + } } /* if we skipped it in the future P Frame than skip it now too */ @@ -2614,20 +2823,23 @@ int h263_decode_mb(MpegEncContext *s, s->mv[0][0][1] = 0; s->mv[1][0][0] = 0; s->mv[1][0][1] = 0; -//FIXME is this correct? -/* s->last_mv[0][0][0]= - s->last_mv[0][0][1]=0;*/ PRINT_MB_TYPE("s"); return 0; } - modb1= get_bits1(&s->gb); - if(modb1==0){ + modb1= get_bits1(&s->gb); + if(modb1){ + mb_type=4; //like MB_TYPE_B_DIRECT but no vectors coded + cbp=0; + }else{ + int field_mv; + modb2= get_bits1(&s->gb); mb_type= get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1); - if(modb2==0) cbp= get_bits(&s->gb, 6); - else cbp=0; - if (mb_type && cbp) { + if(modb2) cbp= 0; + else cbp= get_bits(&s->gb, 6); + + if (mb_type!=MB_TYPE_B_DIRECT && cbp) { if(get_bits1(&s->gb)){ s->qscale +=get_bits1(&s->gb)*4 - 2; if (s->qscale < 1) @@ -2637,81 +2849,141 @@ int h263_decode_mb(MpegEncContext *s, h263_dc_scale(s); } } - }else{ - mb_type=4; //like 0 but no vectors coded - cbp=0; + field_mv=0; + + if(!s->progressive_sequence){ + if(cbp) + s->interlaced_dct= get_bits1(&s->gb); + + if(mb_type!=MB_TYPE_B_DIRECT && get_bits1(&s->gb)){ + field_mv=1; + + if(mb_type!=MB_TYPE_B_BACKW){ + s->field_select[0][0]= get_bits1(&s->gb); + s->field_select[0][1]= get_bits1(&s->gb); + } + if(mb_type!=MB_TYPE_B_FORW){ + s->field_select[1][0]= get_bits1(&s->gb); + s->field_select[1][1]= get_bits1(&s->gb); + } + } + } + + s->mv_dir = 0; + if(mb_type!=MB_TYPE_B_DIRECT && !field_mv){ + s->mv_type= MV_TYPE_16X16; + if(mb_type!=MB_TYPE_B_BACKW){ + s->mv_dir = MV_DIR_FORWARD; + + mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); + my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); + s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx; + s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my; + } + + if(mb_type!=MB_TYPE_B_FORW){ + s->mv_dir |= MV_DIR_BACKWARD; + + mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); + my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); + s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx; + s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my; + } + if(mb_type!=MB_TYPE_B_DIRECT) + PRINT_MB_TYPE(mb_type==MB_TYPE_B_FORW ? "F" : (mb_type==MB_TYPE_B_BACKW ? "B" : "T")); + }else if(mb_type!=MB_TYPE_B_DIRECT){ + s->mv_type= MV_TYPE_FIELD; + + if(mb_type!=MB_TYPE_B_BACKW){ + s->mv_dir = MV_DIR_FORWARD; + + for(i=0; i<2; i++){ + mx = h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); + my = h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0] = mx; + s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2; + } + } + + if(mb_type!=MB_TYPE_B_FORW){ + s->mv_dir |= MV_DIR_BACKWARD; + + for(i=0; i<2; i++){ + mx = h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); + my = h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); + s->last_mv[1][i][0]= s->mv[1][i][0] = mx; + s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2; + } + } + if(mb_type!=MB_TYPE_B_DIRECT) + PRINT_MB_TYPE(mb_type==MB_TYPE_B_FORW ? "f" : (mb_type==MB_TYPE_B_BACKW ? "b" : "t")); + } } - s->mv_type = MV_TYPE_16X16; // we'll switch to 8x8 only if the last P frame had 8x8 for this MB and mb_type=0 here - mx=my=0; //for case 4, we could put this to the mb_type=4 but than gcc compains about uninitalized mx/my - switch(mb_type) - { - case 0: /* direct */ - mx = h263_decode_motion(s, 0, 1); - my = h263_decode_motion(s, 0, 1); - case 4: /* direct with mx=my=0 */ + + if(mb_type==4 || mb_type==MB_TYPE_B_DIRECT){ + int mb_index= s->mb_x + s->mb_y*s->mb_width; + int i; + + if(mb_type==4) + mx=my=0; + else{ + mx = h263_decode_motion(s, 0, 1); + my = h263_decode_motion(s, 0, 1); + } + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; xy= s->block_index[0]; time_pp= s->pp_time; - time_pb= time_pp - s->bp_time; -//if(time_pp>3000 )printf("%d %d ", time_pp, time_pb); + time_pb= s->pb_time; + //FIXME avoid divides - s->mv[0][0][0] = s->motion_val[xy][0]*time_pb/time_pp + mx; - s->mv[0][0][1] = s->motion_val[xy][1]*time_pb/time_pp + my; - s->mv[1][0][0] = mx ? s->mv[0][0][0] - s->motion_val[xy][0] - : s->motion_val[xy][0]*(time_pb - time_pp)/time_pp + mx; - s->mv[1][0][1] = my ? s->mv[0][0][1] - s->motion_val[xy][1] - : s->motion_val[xy][1]*(time_pb - time_pp)/time_pp + my; - if(s->non_b_mv4_table[xy]){ - int i; + switch(s->co_located_type_table[mb_index]){ + case 0: + s->mv_type= MV_TYPE_16X16; + s->mv[0][0][0] = s->motion_val[xy][0]*time_pb/time_pp + mx; + s->mv[0][0][1] = s->motion_val[xy][1]*time_pb/time_pp + my; + s->mv[1][0][0] = mx ? s->mv[0][0][0] - s->motion_val[xy][0] + : s->motion_val[xy][0]*(time_pb - time_pp)/time_pp; + s->mv[1][0][1] = my ? s->mv[0][0][1] - s->motion_val[xy][1] + : s->motion_val[xy][1]*(time_pb - time_pp)/time_pp; + PRINT_MB_TYPE(mb_type==4 ? "D" : "S"); + break; + case CO_LOCATED_TYPE_4MV: s->mv_type = MV_TYPE_8X8; - for(i=1; i<4; i++){ + for(i=0; i<4; i++){ xy= s->block_index[i]; s->mv[0][i][0] = s->motion_val[xy][0]*time_pb/time_pp + mx; s->mv[0][i][1] = s->motion_val[xy][1]*time_pb/time_pp + my; s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->motion_val[xy][0] - : s->motion_val[xy][0]*(time_pb - time_pp)/time_pp + mx; + : s->motion_val[xy][0]*(time_pb - time_pp)/time_pp; s->mv[1][i][1] = my ? s->mv[0][i][1] - s->motion_val[xy][1] - : s->motion_val[xy][1]*(time_pb - time_pp)/time_pp + my; + : s->motion_val[xy][1]*(time_pb - time_pp)/time_pp; } PRINT_MB_TYPE("4"); - }else{ - PRINT_MB_TYPE(mb_type==4 ? "D" : "S"); + break; + case CO_LOCATED_TYPE_FIELDMV: + s->mv_type = MV_TYPE_FIELD; + for(i=0; i<2; i++){ + if(s->top_field_first){ + time_pp= s->pp_field_time - s->field_select_table[mb_index][i] + i; + time_pb= s->pb_field_time - s->field_select_table[mb_index][i] + i; + }else{ + time_pp= s->pp_field_time + s->field_select_table[mb_index][i] - i; + time_pb= s->pb_field_time + s->field_select_table[mb_index][i] - i; + } + s->mv[0][i][0] = s->field_mv_table[mb_index][i][0]*time_pb/time_pp + mx; + s->mv[0][i][1] = s->field_mv_table[mb_index][i][1]*time_pb/time_pp + my; + s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->field_mv_table[mb_index][i][0] + : s->field_mv_table[mb_index][i][0]*(time_pb - time_pp)/time_pp; + s->mv[1][i][1] = my ? s->mv[0][i][1] - s->field_mv_table[mb_index][i][1] + : s->field_mv_table[mb_index][i][1]*(time_pb - time_pp)/time_pp; + } + PRINT_MB_TYPE("="); + break; } -/* s->mv[0][0][0] = - s->mv[0][0][1] = - s->mv[1][0][0] = - s->mv[1][0][1] = 1000;*/ - break; - case 1: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); - my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); - s->last_mv[0][0][0]= s->mv[0][0][0] = mx; - s->last_mv[0][0][1]= s->mv[0][0][1] = my; - - mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); - my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); - s->last_mv[1][0][0]= s->mv[1][0][0] = mx; - s->last_mv[1][0][1]= s->mv[1][0][1] = my; - PRINT_MB_TYPE("i"); - break; - case 2: - s->mv_dir = MV_DIR_BACKWARD; - mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); - my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); - s->last_mv[1][0][0]= s->mv[1][0][0] = mx; - s->last_mv[1][0][1]= s->mv[1][0][1] = my; - PRINT_MB_TYPE("B"); - break; - case 3: - s->mv_dir = MV_DIR_FORWARD; - mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); - my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); - s->last_mv[0][0][0]= s->mv[0][0][0] = mx; - s->last_mv[0][0][1]= s->mv[0][0][1] = my; - PRINT_MB_TYPE("F"); - break; - default: + } + + if(mb_type<0 || mb_type>4){ printf("illegal MB_type\n"); return -1; } @@ -2741,6 +3013,8 @@ intra: s->qscale = 31; h263_dc_scale(s); } + if(!s->progressive_sequence) + s->interlaced_dct= get_bits1(&s->gb); /* decode each block */ if (s->h263_pred) { @@ -2774,7 +3048,7 @@ intra: static int h263_decode_motion(MpegEncContext * s, int pred, int f_code) { - int code, val, sign, shift, l, m; + int code, val, sign, shift, l; code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); if (code < 0) @@ -2795,11 +3069,10 @@ static int h263_decode_motion(MpegEncContext * s, int pred, int f_code) /* modulo decoding */ if (!s->h263_long_vectors) { l = (1 << (f_code - 1)) * 32; - m = 2 * l; if (val < -l) { - val += m; + val += l<<1; } else if (val >= l) { - val -= m; + val -= l<<1; } } else { /* horrible h263 long vector mode */ @@ -2900,7 +3173,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, if (s->h263_rv10 && level == -128) { /* XXX: should patch encoder too */ level = get_bits(&s->gb, 12); - level = (level << 20) >> 20; + level= (level + ((-1)<<11)) ^ ((-1)<<11); //sign extension } } else { run = rl->table_run[code]; @@ -3000,7 +3273,9 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, goto not_coded; rl = &rl_intra; rl_vlc = rl_intra.rl_vlc[0]; - if (s->ac_pred) { + if(s->alternate_scan) + scan_table = ff_alternate_vertical_scan; /* left */ + else if (s->ac_pred) { if (dc_pred_dir == 0) scan_table = ff_alternate_vertical_scan; /* left */ else @@ -3017,7 +3292,12 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, return 0; } rl = &rl_inter; - scan_table = zigzag_direct; + + if(s->alternate_scan) + scan_table = ff_alternate_vertical_scan; /* left */ + else + scan_table = zigzag_direct; + if(s->mpeg_quant){ qmul=1; qadd=0; @@ -3282,10 +3562,10 @@ int h263_decode_picture_header(MpegEncContext *s) skip_bits1(&s->gb); height = get_bits(&s->gb, 9) * 4; dprintf("\nH.263+ Custom picture: %dx%d\n",width,height); - if (s->aspect_ratio_info == EXTENDED_PAR) { + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { /* aspected dimensions */ - skip_bits(&s->gb, 8); /* width */ - skip_bits(&s->gb, 8); /* height */ + s->aspected_width = get_bits(&s->gb, 8); + s->aspected_height = get_bits(&s->gb, 8); } } else { width = h263_format[format][0]; @@ -3552,9 +3832,9 @@ int mpeg4_decode_picture_header(MpegEncContext * s) } //printf("vo type:%d\n",s->vo_type); s->aspect_ratio_info= get_bits(&s->gb, 4); - if(s->aspect_ratio_info == EXTENDED_PAR){ - skip_bits(&s->gb, 8); //par_width - skip_bits(&s->gb, 8); // par_height + if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + s->aspected_width = get_bits(&s->gb, 8); // par_width + s->aspected_height = get_bits(&s->gb, 8); // par_height } if ((s->vol_control_parameters=get_bits1(&s->gb))) { /* vol control parameter */ @@ -3564,8 +3844,17 @@ int mpeg4_decode_picture_header(MpegEncContext * s) } s->low_delay= get_bits1(&s->gb); if(get_bits1(&s->gb)){ /* vbv parameters */ - printf("vbv parameters not supported\n"); - return -1; + get_bits(&s->gb, 15); /* first_half_bitrate */ + skip_bits1(&s->gb); /* marker */ + get_bits(&s->gb, 15); /* latter_half_bitrate */ + skip_bits1(&s->gb); /* marker */ + get_bits(&s->gb, 15); /* first_half_vbv_buffer_size */ + skip_bits1(&s->gb); /* marker */ + get_bits(&s->gb, 3); /* latter_half_vbv_buffer_size */ + get_bits(&s->gb, 11); /* first_half_vbv_occupancy */ + skip_bits1(&s->gb); /* marker */ + get_bits(&s->gb, 15); /* latter_half_vbv_occupancy */ + skip_bits1(&s->gb); /* marker */ } }else{ // set low delay flag only once so the smart? low delay detection wont be overriden @@ -3583,6 +3872,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s) skip_bits1(&s->gb); /* marker */ s->time_increment_resolution = get_bits(&s->gb, 16); + s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; if (s->time_increment_bits < 1) s->time_increment_bits = 1; @@ -3606,7 +3896,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s) } } - if(get_bits1(&s->gb)) printf("interlaced not supported\n"); /* interlaced */ + s->progressive_sequence= get_bits1(&s->gb)^1; if(!get_bits1(&s->gb)) printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ if (vo_ver_id == 1) { s->vol_sprite_usage = get_bits1(&s->gb); /* vol_sprite_usage */ @@ -3763,11 +4053,6 @@ int mpeg4_decode_picture_header(MpegEncContext * s) printf("This file was encoded with DivX%d Build%d\n", ver, build); if(ver==500 && build==413){ printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n"); -#if 0 - }else{ - printf("hmm, i havnt seen that version of divx yet, lets assume they fixed these bugs ...\n" - "using mpeg4 decoder, if it fails contact the developers (of ffmpeg)\n"); -#endif } } } @@ -3783,7 +4068,12 @@ int mpeg4_decode_picture_header(MpegEncContext * s) printf("low_delay flag set, but shouldnt, clearing it\n"); s->low_delay=0; } -// printf("pic: %d, qpel:%d\n", s->pict_type, s->quarter_sample); +// printf("pic: %d, qpel:%d part:%d resync:%d\n", s->pict_type, s->quarter_sample, s->data_partitioning, s->resync_marker); + + if(s->time_increment_resolution==0){ + s->time_increment_resolution=1; +// fprintf(stderr, "time_increment_resolution is illegal\n"); + } time_incr=0; while (get_bits1(&s->gb) != 0) time_incr++; @@ -3795,17 +4085,32 @@ int mpeg4_decode_picture_header(MpegEncContext * s) s->last_time_base= s->time_base; s->time_base+= time_incr; s->time= s->time_base*s->time_increment_resolution + time_increment; + if(s->time < s->last_non_b_time && s->workaround_bugs==3){ + fprintf(stderr, "header is not mpeg4 compatible, broken encoder, trying to workaround\n"); + s->time_base++; + s->time+= s->time_increment_resolution; + } s->pp_time= s->time - s->last_non_b_time; s->last_non_b_time= s->time; }else{ s->time= (s->last_time_base + time_incr)*s->time_increment_resolution + time_increment; - s->bp_time= s->last_non_b_time - s->time; - if(s->pp_time <=s->bp_time){ + s->pb_time= s->pp_time - (s->last_non_b_time - s->time); + if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){ // printf("messed up order, seeking?, skiping current b frame\n"); return FRAME_SKIPED; } + + if(s->t_frame==0) s->t_frame= s->time - s->last_time_base; + if(s->t_frame==0) s->t_frame=1; // 1/0 protection +//printf("%Ld %Ld %d %d\n", s->last_non_b_time, s->time, s->pp_time, s->t_frame); fflush(stdout); + s->pp_field_time= ( ROUNDED_DIV(s->last_non_b_time, s->t_frame) + - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; + s->pb_field_time= ( ROUNDED_DIV(s->time, s->t_frame) + - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; } - + + s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution; + if(check_marker(&s->gb, "before vop_coded")==0 && s->picture_number==0){ printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n"); for(s->time_increment_bits++ ;s->time_increment_bits<16; s->time_increment_bits++){ @@ -3816,8 +4121,8 @@ int mpeg4_decode_picture_header(MpegEncContext * s) /* vop coded */ if (get_bits1(&s->gb) != 1) goto redo; -//printf("time %d %d %d || %d %d %d\n", s->time_increment_bits, s->time_increment, s->time_base, -//s->time, s->last_non_b_time[0], s->last_non_b_time[1]); +//printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->time_increment_resolution, s->time_base, +//s->time, s->last_non_b_time, s->last_non_b_time - s->pp_time); if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) { /* rounding type for motion estimation */ @@ -3851,7 +4156,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s) int t; t=get_bits(&s->gb, 3); /* intra dc VLC threshold */ //printf("threshold %d\n", t); - //FIXME interlaced specific bits + if(!s->progressive_sequence){ + s->top_field_first= get_bits1(&s->gb); + s->alternate_scan= get_bits1(&s->gb); + }else + s->alternate_scan= 0; } if(s->pict_type == S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ @@ -3883,11 +4192,15 @@ int mpeg4_decode_picture_header(MpegEncContext * s) if (s->pict_type == B_TYPE) { s->b_code = get_bits(&s->gb, 3); -//printf("b-code %d\n", s->b_code); }else s->b_code=1; - -//printf("quant:%d fcode:%d bcode:%d type:%d\n", s->qscale, s->f_code, s->b_code, s->pict_type); +#if 0 +printf("qp:%d fc:%d bc:%d type:%s size:%d pro:%d alt:%d top:%d qpel:%d part:%d resync:%d\n", + s->qscale, s->f_code, s->b_code, + s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), + s->gb.size,s->progressive_sequence, s->alternate_scan, s->top_field_first, + s->quarter_sample, s->data_partitioning, s->resync_marker); +#endif if(!s->scalability){ if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) { skip_bits1(&s->gb); // vop shape coding type @@ -3910,7 +4223,6 @@ int mpeg4_decode_picture_header(MpegEncContext * s) } s->picture_number++; // better than pic number==0 allways ;) -//printf("done\n"); s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; |