summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/h263.c
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-09-16 21:49:34 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-09-16 21:49:34 +0000
commitd2db0f3bbdc81aae2c316751daf1d53b42a3e6a0 (patch)
treee9f4a94547ada41ea13445185a20305378d6c0bd /src/libffmpeg/libavcodec/h263.c
parentd35f836384d9fa164350612ead96362d9cd7b457 (diff)
downloadxine-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.c678
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;