Mercurial > libavcodec.hg
changeset 619:2be2cc8fd0a1 libavcodec
mpeg4 interlaced decoding support (not completly implemented/tested due to lack of samples)
author | michaelni |
---|---|
date | Tue, 27 Aug 2002 16:28:19 +0000 |
parents | 4f3d4a07d374 |
children | a5aa53b6e648 |
files | h263.c mpegvideo.c |
diffstat | 2 files changed, 119 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/h263.c Mon Aug 26 20:45:01 2002 +0000 +++ b/h263.c Tue Aug 27 16:28:19 2002 +0000 @@ -1746,6 +1746,8 @@ &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) @@ -2426,7 +2428,37 @@ 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 +2539,75 @@ 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); - } -// 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); } -// if (my < -l) my= -l, printf("C"); -// else if (my >= l) my= l-1, printf("C"); +// int l = (1 << (s->f_code - 1)) * 32; + 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*2; + } + }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; @@ -2614,9 +2666,6 @@ 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; } @@ -2637,6 +2686,7 @@ h263_dc_scale(s); } } +// decode_interlaced_info(s, cbp, mb_type); }else{ mb_type=4; //like 0 but no vectors coded cbp=0; @@ -2682,6 +2732,7 @@ s->mv[1][0][0] = s->mv[1][0][1] = 1000;*/ break; +//FIXME additional MVs for interlaced stuff 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); @@ -2741,6 +2792,8 @@ 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) { @@ -3606,7 +3659,7 @@ } } - 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 +3816,6 @@ 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 } } } @@ -3851,7 +3899,11 @@ 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); +//printf("top:%d alt:%d\n", s->top_field_first, s->alternate_scan); + } } if(s->pict_type == S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){
--- a/mpegvideo.c Mon Aug 26 20:45:01 2002 +0000 +++ b/mpegvideo.c Tue Aug 27 16:28:19 2002 +0000 @@ -600,6 +600,7 @@ } /* draw the edges of width 'w' of an image of size width, height */ +//FIXME check that this is ok for mpeg4 interlaced static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w) { UINT8 *ptr, *last_line; @@ -1452,18 +1453,25 @@ /* update motion predictor, not for B-frames as they need the motion_val from the last P/S-Frame */ if (s->out_format == FMT_H263 && s->pict_type!=B_TYPE) { //FIXME move into h263.c if possible, format specific stuff shouldnt be here - int motion_x, motion_y; const int wrap = s->block_wrap[0]; const int xy = s->block_index[0]; - if (s->mb_intra) { - motion_x = 0; - motion_y = 0; - goto motion_init; - } else if (s->mv_type == MV_TYPE_16X16) { - motion_x = s->mv[0][0][0]; - motion_y = s->mv[0][0][1]; - motion_init: + if(s->mv_type == MV_TYPE_8X8){ + s->non_b_mv4_table[xy]=1; + } else { + int motion_x, motion_y; + if (s->mb_intra) { + motion_x = 0; + motion_y = 0; + } else if (s->mv_type == MV_TYPE_16X16) { + motion_x = s->mv[0][0][0]; + motion_y = s->mv[0][0][1]; + } else /*if (s->mv_type == MV_TYPE_FIELD)*/ { + motion_x = s->mv[0][0][0] + s->mv[0][1][0]; + motion_y = s->mv[0][0][1] + s->mv[0][1][1]; + motion_x = (motion_x>>1) | (motion_x&1); + motion_y = (motion_y>>1) | (motion_y&1); + } /* no update if 8X8 because it has been done during parsing */ s->motion_val[xy][0] = motion_x; s->motion_val[xy][1] = motion_y; @@ -1474,8 +1482,6 @@ s->motion_val[xy + 1 + wrap][0] = motion_x; s->motion_val[xy + 1 + wrap][1] = motion_y; s->non_b_mv4_table[xy]=0; - } else { /* 8X8 */ - s->non_b_mv4_table[xy]=1; } }