X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fh263.c;h=0b09dc7311044d4dae1e12c0ddc2605b89594e50;hb=5ff85f1d8b5721a9e7f0ca6e03f61f5d3a4c3664;hp=d6da47ad48441ee9f515c26b138e00472760d67b;hpb=4d2a48349d6f40a2357bb25b4f360f2a6e669ad4;p=ffmpeg diff --git a/libavcodec/h263.c b/libavcodec/h263.c index d6da47ad484..0b09dc73110 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -29,6 +29,8 @@ */ //#define DEBUG +#include + #include "common.h" #include "dsputil.h" #include "avcodec.h" @@ -39,14 +41,8 @@ //#undef NDEBUG //#include -#if 1 -#define PRINT_MB_TYPE(a) {} -#else -#define PRINT_MB_TYPE(a) printf(a) -#endif - #define INTRA_MCBPC_VLC_BITS 6 -#define INTER_MCBPC_VLC_BITS 6 +#define INTER_MCBPC_VLC_BITS 7 #define CBPY_VLC_BITS 6 #define MV_VLC_BITS 9 #define DC_VLC_BITS 9 @@ -56,11 +52,11 @@ #ifdef CONFIG_ENCODERS static void h263_encode_block(MpegEncContext * s, DCTELEM * block, - int n); + int n); static void h263_encode_motion(MpegEncContext * s, int val, int fcode); static void h263p_encode_umotion(MpegEncContext * s, int val); static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, - int n, int dc, uint8_t *scan_table, + int n, int dc, uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb); #endif @@ -73,14 +69,12 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded, int intra, int rvlc); static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr); #ifdef CONFIG_ENCODERS -static void mpeg4_inv_pred_ac(MpegEncContext * s, DCTELEM *block, int n, - int dir); +static void mpeg4_encode_visual_object_header(MpegEncContext * s); +static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); #endif //CONFIG_ENCODERS static void mpeg4_decode_sprite_trajectory(MpegEncContext * s); static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr, int *dir_ptr); -extern uint32_t inverse[256]; - #ifdef CONFIG_ENCODERS static uint8_t uni_DCtab_lum_len[512]; static uint8_t uni_DCtab_chrom_len[512]; @@ -110,6 +104,11 @@ max run: 29/41 */ #endif +#if 0 //3IV1 is quite rare and tis slows things down a tiny bit +#define IS_3IV1 s->avctx->codec_tag == ff_get_fourcc("3IV1") +#else +#define IS_3IV1 0 +#endif int h263_get_picture_format(int width, int height) { @@ -132,19 +131,13 @@ int h263_get_picture_format(int width, int height) #ifdef CONFIG_ENCODERS -static void float_aspect_to_info(MpegEncContext * s, float aspect){ +static void aspect_to_info(MpegEncContext * s, AVRational aspect){ int i; - aspect*= s->height/(double)s->width; -//printf("%f\n", aspect); - - if(aspect==0) aspect= 1.0; - - ff_float2fraction(&s->aspected_width, &s->aspected_height, aspect, 255); + if(aspect.num==0) aspect= (AVRational){1,1}; -//printf("%d %d\n", s->aspected_width, s->aspected_height); for(i=1; i<6; i++){ - if(s->aspected_width == pixel_aspect[i][0] && s->aspected_height== pixel_aspect[i][1]){ + if(av_cmp_q(pixel_aspect[i], aspect) == 0){ s->aspect_ratio_info=i; return; } @@ -153,6 +146,52 @@ static void float_aspect_to_info(MpegEncContext * s, float aspect){ s->aspect_ratio_info= FF_ASPECT_EXTENDED; } +void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number) +{ + int format; + + align_put_bits(&s->pb); + + put_bits(&s->pb, 17, 1); + put_bits(&s->pb, 5, (s->h263_flv-1)); /* 0: h263 escape codes 1: 11-bit escape codes */ + put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->frame_rate_base) / + s->avctx->frame_rate) & 0xff); /* TemporalReference */ + if (s->width == 352 && s->height == 288) + format = 2; + else if (s->width == 176 && s->height == 144) + format = 3; + else if (s->width == 128 && s->height == 96) + format = 4; + else if (s->width == 320 && s->height == 240) + format = 5; + else if (s->width == 160 && s->height == 120) + format = 6; + else if (s->width <= 255 && s->height <= 255) + format = 0; /* use 1 byte width & height */ + else + format = 1; /* use 2 bytes width & height */ + put_bits(&s->pb, 3, format); /* PictureSize */ + if (format == 0) { + put_bits(&s->pb, 8, s->width); + put_bits(&s->pb, 8, s->height); + } else if (format == 1) { + put_bits(&s->pb, 16, s->width); + put_bits(&s->pb, 16, s->height); + } + put_bits(&s->pb, 2, s->pict_type == P_TYPE); /* PictureType */ + put_bits(&s->pb, 1, 1); /* DeblockingFlag: on */ + put_bits(&s->pb, 5, s->qscale); /* Quantizer */ + put_bits(&s->pb, 1, 0); /* ExtraInformation */ + + if(s->h263_aic){ + s->y_dc_scale_table= + s->c_dc_scale_table= h263_aic_dc_scale_table; + }else{ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } +} + void h263_encode_picture_header(MpegEncContext * s, int picture_number) { int format; @@ -225,16 +264,15 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) if (format == 7) { /* Custom Picture Format (CPFMT) */ - float_aspect_to_info(s, s->avctx->aspect_ratio); + aspect_to_info(s, s->avctx->sample_aspect_ratio); put_bits(&s->pb,4,s->aspect_ratio_info); 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); + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); } } @@ -278,27 +316,54 @@ int h263_encode_gob_header(MpegEncContext * s, int mb_line) return 0; } -static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int dir[6]) +static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){ + int last=0; + int j; + int rate=0; + + for(j=1; j<=block_last_index; j++){ + const int index= scantable[j]; + int level= block[index]; + if(level){ + level+= 64; + if((level&(~127)) == 0){ + if(jintra_ac_vlc_length [UNI_AC_ENC_INDEX(j-last-1, level)]; + else rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)]; + }else + rate += s->ac_esc_length; + level-= 64; + + last= j; + } + } + + return rate; +} + +static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int dir[6], uint8_t *st[6], int zigzag_last_index[6]) { - int score0=0, score1=0; + int score= 0; int i, n; int8_t * const qscale_table= s->current_picture.qscale_table; + memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6); + for(n=0; n<6; n++){ int16_t *ac_val, *ac_val1; + + score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated); ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val1= ac_val; if(dir[n]){ - const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; + const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; /* top prediction */ ac_val-= s->block_wrap[n]*16; if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ /* same qscale */ for(i=1; i<8; i++){ const int level= block[n][s->dsp.idct_permutation[i ]]; - score0+= ABS(level); - score1+= ABS(level - ac_val[i+8]); + block[n][s->dsp.idct_permutation[i ]] = level - ac_val[i+8]; ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; ac_val1[i+8]= level; } @@ -306,22 +371,21 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d /* different qscale, we must rescale */ for(i=1; i<8; i++){ const int level= block[n][s->dsp.idct_permutation[i ]]; - score0+= ABS(level); - score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale)); + block[n][s->dsp.idct_permutation[i ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; ac_val1[i+8]= level; } } + st[n]= s->intra_h_scantable.permutated; }else{ - const int xy= s->mb_x-1 + s->mb_y*s->mb_width; + const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; /* left prediction */ ac_val-= 16; if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ /* same qscale */ for(i=1; i<8; i++){ const int level= block[n][s->dsp.idct_permutation[i<<3]]; - score0+= ABS(level); - score1+= ABS(level - ac_val[i]); + block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i]; ac_val1[i ]= level; ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; } @@ -329,16 +393,45 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d /* different qscale, we must rescale */ for(i=1; i<8; i++){ const int level= block[n][s->dsp.idct_permutation[i<<3]]; - score0+= ABS(level); - score1+= ABS(level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale)); + block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); ac_val1[i ]= level; ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; } } + st[n]= s->intra_v_scantable.permutated; } + + for(i=63; i>0; i--) //FIXME optimize + if(block[n][ st[n][i] ]) break; + s->block_last_index[n]= i; + + score += get_block_rate(s, block[n], s->block_last_index[n], st[n]); } - return score0 > score1 ? 1 : 0; + return score < 0; +} + +static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], int dir[6], uint8_t *st[6], int zigzag_last_index[6]) +{ + int i, n; + memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6); + + for(n=0; n<6; n++){ + int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + + st[n]= s->intra_scantable.permutated; + if(dir[n]){ + /* top prediction */ + for(i=1; i<8; i++){ + block[n][s->dsp.idct_permutation[i ]] = ac_val[i+8]; + } + }else{ + /* left prediction */ + for(i=1; i<8; i++){ + block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i ]; + } + } + } } /** @@ -349,12 +442,12 @@ void ff_clean_h263_qscales(MpegEncContext *s){ int8_t * const qscale_table= s->current_picture.qscale_table; for(i=1; imb_num; i++){ - if(qscale_table[i] - qscale_table[i-1] >2) - qscale_table[i]= qscale_table[i-1]+2; + if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i-1] ] >2) + qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i-1] ]+2; } for(i=s->mb_num-2; i>=0; i--){ - if(qscale_table[i] - qscale_table[i+1] >2) - qscale_table[i]= qscale_table[i+1]+2; + if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i+1] ] >2) + qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i+1] ]+2; } } @@ -368,9 +461,11 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){ ff_clean_h263_qscales(s); for(i=1; imb_num; i++){ - if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){ - s->mb_type[i]&= ~MB_TYPE_INTER4V; - s->mb_type[i]|= MB_TYPE_INTER; + int mb_xy= s->mb_index2xy[i]; + + if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&MB_TYPE_INTER4V)){ + s->mb_type[mb_xy]&= ~MB_TYPE_INTER4V; + s->mb_type[mb_xy]|= MB_TYPE_INTER; } } @@ -380,52 +475,47 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){ for the actual adaptive quantization */ for(i=0; imb_num; i++){ - odd += qscale_table[i]&1; + int mb_xy= s->mb_index2xy[i]; + odd += qscale_table[mb_xy]&1; } if(2*odd > s->mb_num) odd=1; else odd=0; for(i=0; imb_num; i++){ - if((qscale_table[i]&1) != odd) - qscale_table[i]++; - if(qscale_table[i] > 31) - qscale_table[i]= 31; + int mb_xy= s->mb_index2xy[i]; + if((qscale_table[mb_xy]&1) != odd) + qscale_table[mb_xy]++; + if(qscale_table[mb_xy] > 31) + qscale_table[mb_xy]= 31; } for(i=1; imb_num; i++){ - if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){ - s->mb_type[i]&= ~MB_TYPE_DIRECT; - s->mb_type[i]|= MB_TYPE_BIDIR; + int mb_xy= s->mb_index2xy[i]; + if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&MB_TYPE_DIRECT)){ + s->mb_type[mb_xy]&= ~MB_TYPE_DIRECT; + s->mb_type[mb_xy]|= MB_TYPE_BIDIR; } } } } #endif //CONFIG_ENCODERS - -void ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ - const int mb_index= s->mb_x + s->mb_y*s->mb_width; +/** + * + * @return the mb_type + */ +int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ + const int mb_index= s->mb_x + s->mb_y*s->mb_stride; + const int colocated_mb_type= s->next_picture.mb_type[mb_index]; //FIXME or next? int xy= s->block_index[0]; uint16_t time_pp= s->pp_time; uint16_t time_pb= s->pb_time; int i; //FIXME avoid divides - switch(s->co_located_type_table[mb_index]){ - case 0: - s->mv[0][0][0] = s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->motion_val[xy][0]*time_pb/time_pp + mx; - s->mv[0][0][1] = s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->motion_val[xy][1]*time_pb/time_pp + my; - s->mv[1][0][0] = s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][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] = s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = my ? s->mv[0][0][1] - s->motion_val[xy][1] - : s->motion_val[xy][1]*(time_pb - time_pp)/time_pp; - if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample) - s->mv_type= MV_TYPE_16X16; - else - s->mv_type= MV_TYPE_8X8; - break; - case CO_LOCATED_TYPE_4MV: + + if(IS_8X8(colocated_mb_type)){ s->mv_type = MV_TYPE_8X8; for(i=0; i<4; i++){ xy= s->block_index[i]; @@ -436,8 +526,8 @@ void ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ 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; } - break; - case CO_LOCATED_TYPE_FIELDMV: + return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; + } else if(IS_INTERLACED(colocated_mb_type)){ s->mv_type = MV_TYPE_FIELD; for(i=0; i<2; i++){ if(s->top_field_first){ @@ -454,17 +544,175 @@ void ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ 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; } - break; + return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; + }else{ + s->mv[0][0][0] = s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->motion_val[xy][0]*time_pb/time_pp + mx; + s->mv[0][0][1] = s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->motion_val[xy][1]*time_pb/time_pp + my; + s->mv[1][0][0] = s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][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] = s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = my ? s->mv[0][0][1] - s->motion_val[xy][1] + : s->motion_val[xy][1]*(time_pb - time_pp)/time_pp; + if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample) + s->mv_type= MV_TYPE_16X16; + else + s->mv_type= MV_TYPE_8X8; + return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; //Note see prev line + } +} + +void ff_h263_update_motion_val(MpegEncContext * s){ + const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; + //FIXME a lot of thet is only needed for !low_delay + const int wrap = s->block_wrap[0]; + const int xy = s->block_index[0]; + + s->current_picture.mbskip_table[mb_xy]= s->mb_skiped; + + if(s->mv_type != MV_TYPE_8X8){ + 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)*/ { + int i; + 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); + for(i=0; i<2; i++){ + s->field_mv_table[mb_xy][i][0]= s->mv[0][i][0]; + s->field_mv_table[mb_xy][i][1]= s->mv[0][i][1]; + s->field_select_table[mb_xy][i]= s->field_select[0][i]; + } + } + + /* 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; + s->motion_val[xy + 1][0] = motion_x; + s->motion_val[xy + 1][1] = motion_y; + s->motion_val[xy + wrap][0] = motion_x; + s->motion_val[xy + wrap][1] = motion_y; + s->motion_val[xy + 1 + wrap][0] = motion_x; + s->motion_val[xy + 1 + wrap][1] = motion_y; + } + + if(s->encoding){ //FIXME encoding MUST be cleaned up + if (s->mv_type == MV_TYPE_8X8) + s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_8x8; + else + s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_16x16; } } #ifdef CONFIG_ENCODERS + +static inline int get_p_cbp(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y){ + int cbp, i; + + if(s->flags & CODEC_FLAG_CBP_RD){ + int best_cbpy_score= INT_MAX; + int best_cbpc_score= INT_MAX; + int cbpc, cbpy; + const int offset= (s->mv_type==MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0); + const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); + + for(i=0; i<4; i++){ + int score= inter_MCBPC_bits[i + offset] * lambda; + if(i&1) score += s->coded_score[5]; + if(i&2) score += s->coded_score[4]; + + if(score < best_cbpc_score){ + best_cbpc_score= score; + cbpc= i; + } + } + + for(i=0; i<16; i++){ + int score= cbpy_tab[i ^ 0xF][1] * lambda; + if(i&1) score += s->coded_score[3]; + if(i&2) score += s->coded_score[2]; + if(i&4) score += s->coded_score[1]; + if(i&8) score += s->coded_score[0]; + + if(score < best_cbpy_score){ + best_cbpy_score= score; + cbpy= i; + } + } + cbp= cbpc + 4*cbpy; + if ((motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16){ + if(best_cbpy_score + best_cbpc_score + 2*lambda >= 0) + cbp= 0; + } + + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){ + s->block_last_index[i]= -1; + memset(s->block[i], 0, sizeof(DCTELEM)*64); + } + } + }else{ + cbp= 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + } + return cbp; +} + +static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64], + int motion_x, int motion_y, int mb_type){ + int cbp=0, i; + + if(s->flags & CODEC_FLAG_CBP_RD){ + int score=0; + const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); + + for(i=0; i<6; i++){ + if(s->coded_score[i] < 0){ + score += s->coded_score[i]; + cbp |= 1 << (5 - i); + } + } + + if(cbp){ + int zero_score= -6; + if ((motion_x | motion_y | s->dquant | mb_type) == 0){ + zero_score-= 4; //2*MV + mb_type + cbp bit + } + + zero_score*= lambda; + if(zero_score <= score){ + cbp=0; + } + } + + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){ + s->block_last_index[i]= -1; + memset(s->block[i], 0, sizeof(DCTELEM)*64); + } + } + }else{ + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + } + return cbp; +} + void mpeg4_encode_mb(MpegEncContext * s, DCTELEM block[6][64], int motion_x, int motion_y) { int cbpc, cbpy, pred_x, pred_y; - int bits; PutBitContext * const pb2 = s->data_partitioning ? &s->pb2 : &s->pb; PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=B_TYPE ? &s->tex_pb : &s->pb; PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=I_TYPE ? &s->pb2 : &s->pb; @@ -474,12 +722,8 @@ void mpeg4_encode_mb(MpegEncContext * s, // printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); if (!s->mb_intra) { /* compute cbp */ - int i, cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - + int i, cbp; + if(s->pict_type==B_TYPE){ static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ int mb_type= mb_type_table[s->mv_dir]; @@ -496,7 +740,7 @@ void mpeg4_encode_mb(MpegEncContext * s, assert(mb_type>=0); /* nothing to do if this MB was skiped in the next P Frame */ - if(s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ... + if(s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]){ //FIXME avoid DCT & ... s->skip_count++; s->mv[0][0][0]= s->mv[0][0][1]= @@ -509,6 +753,8 @@ void mpeg4_encode_mb(MpegEncContext * s, return; } + cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type); + if ((cbp | motion_x | motion_y | mb_type) ==0) { /* direct MB with MV={0,0} */ assert(s->dquant==0); @@ -599,6 +845,8 @@ void mpeg4_encode_mb(MpegEncContext * s, s->p_tex_bits+= get_bits_diff(s); } }else{ /* s->pict_type==B_TYPE */ + cbp= get_p_cbp(s, block, motion_x, motion_y); + if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { /* check if the B frames can skip it too, as we must skip it if we skip here why didnt they just compress the skip-mb bits instead of reusing them ?! */ @@ -642,6 +890,7 @@ void mpeg4_encode_mb(MpegEncContext * s, s->last_bits++; } s->skip_count++; + return; } } @@ -736,23 +985,10 @@ void mpeg4_encode_mb(MpegEncContext * s, } } - s->ac_pred= decide_ac_pred(s, block, dir); - - if(s->ac_pred){ - for(i=0; i<6; i++){ - uint8_t *st; - int last_index; - - mpeg4_inv_pred_ac(s, block[i], i, dir[i]); - if (dir[i]==0) st = s->intra_v_scantable.permutated; /* left */ - else st = s->intra_h_scantable.permutated; /* top */ - - for(last_index=63; last_index>=0; last_index--) //FIXME optimize - if(block[i][st[last_index]]) break; - zigzag_last_index[i]= s->block_last_index[i]; - s->block_last_index[i]= last_index; - scan_table[i]= st; - } + if(s->flags & CODEC_FLAG_AC_PRED){ + s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index); + if(!s->ac_pred) + restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); }else{ for(i=0; i<6; i++) scan_table[i]= s->intra_scantable.permutated; @@ -803,23 +1039,8 @@ void mpeg4_encode_mb(MpegEncContext * s, s->i_count++; /* restore ac coeffs & last_index stuff if we messed them up with the prediction */ - if(s->ac_pred){ - for(i=0; i<6; i++){ - int j; - int16_t *ac_val; - - ac_val = s->ac_val[0][0] + s->block_index[i] * 16; - - if(dir[i]){ - for(j=1; j<8; j++) - block[i][s->dsp.idct_permutation[j ]]= ac_val[j+8]; - }else{ - for(j=1; j<8; j++) - block[i][s->dsp.idct_permutation[j<<3]]= ac_val[j ]; - } - s->block_last_index[i]= zigzag_last_index[i]; - } - } + if(s->ac_pred) + restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); } } @@ -831,19 +1052,21 @@ void h263_encode_mb(MpegEncContext * s, int16_t pred_dc; int16_t rec_intradc[6]; uint16_t *dc_ptr[6]; + const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1); const int dquant_code[5]= {1,0,9,2,3}; //printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); if (!s->mb_intra) { /* compute cbp */ - cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } + cbp= get_p_cbp(s, block, motion_x, motion_y); + if ((cbp | motion_x | motion_y | s->dquant) == 0) { /* skip macroblock */ put_bits(&s->pb, 1, 1); + if(interleaved_stats){ + s->misc_bits++; + s->last_bits++; + } return; } put_bits(&s->pb, 1, 0); /* mb coded */ @@ -858,6 +1081,10 @@ void h263_encode_mb(MpegEncContext * s, if(s->dquant) put_bits(&s->pb, 2, dquant_code[s->dquant+2]); + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + /* motion vectors: 16x16 mode only now */ h263_pred_motion(s, 0, &pred_x, &pred_y); @@ -872,6 +1099,10 @@ void h263_encode_mb(MpegEncContext * s, /* To prevent Start Code emulation */ put_bits(&s->pb,1,1); } + + if(interleaved_stats){ + s->mv_bits+= get_bits_diff(s); + } } else { int li = s->h263_aic ? 0 : 1; @@ -939,6 +1170,10 @@ void h263_encode_mb(MpegEncContext * s, put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); if(s->dquant) put_bits(&s->pb, 2, dquant_code[s->dquant+2]); + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } } for(i=0; i<6; i++) { @@ -951,6 +1186,16 @@ void h263_encode_mb(MpegEncContext * s, } } + + if(interleaved_stats){ + if (!s->mb_intra) { + s->p_tex_bits+= get_bits_diff(s); + s->f_count++; + }else{ + s->i_tex_bits+= get_bits_diff(s); + s->i_count++; + } + } } #endif @@ -1453,6 +1698,20 @@ void h263_encode_init(MpegEncContext *s) s->luma_dc_vlc_length= uni_DCtab_lum_len; s->chroma_dc_vlc_length= uni_DCtab_chrom_len; s->ac_esc_length= 7+2+1+6+1+12+1; + + if(s->flags & CODEC_FLAG_GLOBAL_HEADER){ + + s->avctx->extradata= av_malloc(1024); + init_put_bits(&s->pb, s->avctx->extradata, 1024); + + mpeg4_encode_visual_object_header(s); + mpeg4_encode_vol_header(s, 0, 0); + +// ff_mpeg4_stuffing(&s->pb); ? + flush_put_bits(&s->pb); + s->avctx->extradata_size= (get_bit_count(&s->pb)+7)>>3; + } + break; case CODEC_ID_H263P: s->fcode_tab= umv_fcode_tab; @@ -1460,6 +1719,17 @@ void h263_encode_init(MpegEncContext *s) s->max_qcoeff= 127; break; //Note for mpeg4 & h263 the dc-scale table will be set per frame as needed later + case CODEC_ID_FLV1: + if (s->h263_flv > 1) { + s->min_qcoeff= -1023; + s->max_qcoeff= 1023; + } else { + s->min_qcoeff= -127; + s->max_qcoeff= 127; + } + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + break; default: //nothing needed default table allready set in mpegvideo.c s->min_qcoeff= -127; s->max_qcoeff= 127; @@ -1521,6 +1791,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) code = get_rl_index(rl, last, run, level); put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); if (code == rl->n) { + if(s->h263_flv <= 1){ put_bits(&s->pb, 1, last); put_bits(&s->pb, 6, run); @@ -1533,11 +1804,28 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) put_bits(&s->pb, 5, slevel & 0x1f); put_bits(&s->pb, 6, (slevel>>5)&0x3f); } + }else{ + if(slevel < 64 && slevel > -64) { + /* 7-bit level */ + put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, last); + put_bits(&s->pb, 6, run); + + put_bits(&s->pb, 7, slevel & 0x7f); + } else { + /* 11-bit level */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 1, last); + put_bits(&s->pb, 6, run); + + put_bits(&s->pb, 11, slevel & 0x7ff); + } + } } else { put_bits(&s->pb, 1, sign); } - last_non_zero = i; - } + last_non_zero = i; + } } } #endif @@ -1560,13 +1848,6 @@ void ff_mpeg4_stuffing(PutBitContext * pbc) void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ int time_div, time_mod; - if(s->pict_type==I_TYPE){ //we will encode a vol header - int dummy; - av_reduce(&s->time_increment_resolution, &dummy, s->avctx->frame_rate, s->avctx->frame_rate_base, (1<<16)-1); - - s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; - } - if(s->current_picture.pts) s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000); else @@ -1621,9 +1902,9 @@ static void mpeg4_encode_visual_object_header(MpegEncContext * s){ put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, VOS_STARTCODE); - + put_bits(&s->pb, 8, profile_and_level_indication); - + put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE); @@ -1661,13 +1942,12 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */ put_bits(&s->pb, 3, 1); /* is obj layer priority */ - float_aspect_to_info(s, s->avctx->aspect_ratio); + aspect_to_info(s, s->avctx->sample_aspect_ratio); put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ - 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->aspect_ratio_info == FF_ASPECT_EXTENDED){ + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); } if(s->low_delay){ @@ -1703,7 +1983,11 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n s->quant_precision=5; put_bits(&s->pb, 1, 0); /* not 8 bit == false */ put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/ - if(s->mpeg_quant) put_bits(&s->pb, 2, 0); /* no custom matrixes */ + + if(s->mpeg_quant){ + ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); + ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); + } if (vo_ver_id != 1) put_bits(&s->pb, 1, s->quarter_sample); @@ -1740,8 +2024,10 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) if(s->pict_type==I_TYPE){ if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){ - mpeg4_encode_visual_object_header(s); - mpeg4_encode_vol_header(s, 0, 0); + if(s->strict_std_compliance < 2) //HACK, the reference sw is buggy + mpeg4_encode_visual_object_header(s); + if(s->strict_std_compliance < 2 || picture_number==0) //HACK, the reference sw is buggy + mpeg4_encode_vol_header(s, 0, 0); } mpeg4_encode_gop_header(s); } @@ -1787,8 +2073,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) 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; - s->h_edge_pos= s->width; - s->v_edge_pos= s->height; } #endif //CONFIG_ENCODERS @@ -1820,7 +2104,6 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ { int a, b, c, wrap, pred, scale; uint16_t *dc_val; - int dummy; /* find prediction */ if (n < 4) { @@ -1828,6 +2111,9 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ } else { scale = s->c_dc_scale; } + if(IS_3IV1) + scale= 8; + wrap= s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; @@ -1856,16 +2142,7 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ *dir_ptr = 0; /* left */ } /* we assume pred is positive */ -#ifdef ARCH_X86 - asm volatile ( - "xorl %%edx, %%edx \n\t" - "mul %%ecx \n\t" - : "=d" (pred), "=a"(dummy) - : "a" (pred + (scale >> 1)), "c" (inverse[scale]) - ); -#else - pred = (pred + (scale >> 1)) / scale; -#endif + pred = FASTDIV((pred + (scale >> 1)), scale); /* prepare address for prediction update */ *dc_val_ptr = &dc_val[0]; @@ -1890,7 +2167,7 @@ void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, ac_val1 = ac_val; if (s->ac_pred) { if (dir == 0) { - const int xy= s->mb_x-1 + s->mb_y*s->mb_width; + const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; /* left prediction */ ac_val -= 16; @@ -1906,7 +2183,7 @@ void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, } } } else { - const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; + const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; /* top prediction */ ac_val -= 16 * s->block_wrap[n]; @@ -1935,49 +2212,6 @@ void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, #ifdef CONFIG_ENCODERS -static void mpeg4_inv_pred_ac(MpegEncContext * s, DCTELEM *block, int n, - int dir) -{ - int i; - int16_t *ac_val; - int8_t * const qscale_table= s->current_picture.qscale_table; - - /* find prediction */ - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - - if (dir == 0) { - const int xy= s->mb_x-1 + s->mb_y*s->mb_width; - /* left prediction */ - ac_val -= 16; - if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ - /* same qscale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i<<3]] -= ac_val[i]; - } - }else{ - /* different qscale, we must rescale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); - } - } - } else { - const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; - /* top prediction */ - ac_val -= 16 * s->block_wrap[n]; - if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ - /* same qscale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i]] -= ac_val[i + 8]; - } - }else{ - /* different qscale, we must rescale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); - } - } - } -} - /** * encodes the dc value. * @param n block index (0-3 are luma, 4-5 are chroma) @@ -2268,10 +2502,10 @@ void h263_decode_init_vlc(MpegEncContext *s) if (!done) { done = 1; - init_vlc(&intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 8, + init_vlc(&intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9, intra_MCBPC_bits, 1, 1, intra_MCBPC_code, 1, 1); - init_vlc(&inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 25, + init_vlc(&inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28, inter_MCBPC_bits, 1, 1, inter_MCBPC_code, 1, 1); init_vlc(&cbpy_vlc, CBPY_VLC_BITS, 16, @@ -2351,6 +2585,8 @@ static int h263_decode_gob_header(MpegEncContext *s) return -1; s->mb_x= 0; s->mb_y= s->gob_index* s->gob_number; + if(s->mb_y >= s->mb_height) + return -1; #ifdef DEBUG fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", s->gob_number, gfid, s->qscale); #endif @@ -2368,8 +2604,8 @@ static inline void memsetw(short *tab, int val, int n) void ff_mpeg4_init_partitions(MpegEncContext *s) { - init_put_bits(&s->tex_pb, s->tex_pb_buffer, PB_BUFFER_SIZE, NULL, NULL); - init_put_bits(&s->pb2 , s->pb2_buffer , PB_BUFFER_SIZE, NULL, NULL); + init_put_bits(&s->tex_pb, s->tex_pb_buffer, PB_BUFFER_SIZE); + init_put_bits(&s->pb2 , s->pb2_buffer , PB_BUFFER_SIZE); } void ff_mpeg4_merge_partitions(MpegEncContext *s) @@ -2499,6 +2735,11 @@ static int mpeg4_decode_video_packet_header(MpegEncContext *s) fprintf(stderr, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); return -1; } + if(s->pict_type == B_TYPE){ + while(s->next_picture.mbskip_table[ s->mb_index2xy[ mb_num ] ]) mb_num++; + if(mb_num >= s->mb_num) return -1; // slice contains just skiped MBs which where allready decoded + } + s->mb_x= mb_num % s->mb_width; s->mb_y= mb_num / s->mb_width; @@ -2594,10 +2835,10 @@ void ff_mpeg4_clean_buffers(MpegEncContext *s) int ff_h263_resync(MpegEncContext *s){ int left, ret; - if(s->codec_id==CODEC_ID_MPEG4) + if(s->codec_id==CODEC_ID_MPEG4){ skip_bits1(&s->gb); - - align_get_bits(&s->gb); + align_get_bits(&s->gb); + } if(show_bits(&s->gb, 16)==0){ if(s->codec_id==CODEC_ID_MPEG4) @@ -2688,7 +2929,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ for(; s->mb_ymb_height; s->mb_y++){ ff_init_block_index(s); for(; s->mb_xmb_width; s->mb_x++){ - const int xy= s->mb_x + s->mb_y*s->mb_width; + const int xy= s->mb_x + s->mb_y*s->mb_stride; int cbpc; int dir=0; @@ -2697,24 +2938,23 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) s->first_slice_line=0; - if(s->mb_x==0) PRINT_MB_TYPE("\n"); - if(s->pict_type==I_TYPE){ int i; - if(show_bits(&s->gb, 19)==DC_MARKER){ + if(show_bits_long(&s->gb, 19)==DC_MARKER){ return mb_num-1; } - PRINT_MB_TYPE("I"); - cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1); - if (cbpc < 0){ + do{ + cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); + if (cbpc < 0){ + fprintf(stderr, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 8); - fprintf(stderr, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; - } s->cbp_table[xy]= cbpc & 3; - s->mb_type[xy]= MB_TYPE_INTRA; + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; s->mb_intra = 1; if(cbpc & 4) { @@ -2739,6 +2979,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ int16_t * const mot_val= s->motion_val[s->block_index[0]]; const int stride= s->block_wrap[0]*2; +// do{ //FIXME bits= show_bits(&s->gb, 17); if(bits==MOTION_MARKER){ return mb_num-1; @@ -2746,13 +2987,12 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ skip_bits1(&s->gb); if(bits&0x10000){ /* skip mb */ - s->mb_type[xy]= MB_TYPE_SKIPED; if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ - PRINT_MB_TYPE("G"); + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; mx= get_amv(s, 0); my= get_amv(s, 1); }else{ - PRINT_MB_TYPE("S"); + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; mx=my=0; } mot_val[0 ]= mot_val[2 ]= @@ -2764,23 +3004,21 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ ff_clean_intra_table_entries(s); continue; } + cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); if (cbpc < 0){ fprintf(stderr, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - if (cbpc > 20) - cbpc+=3; - else if (cbpc == 20) - fprintf(stderr, "Stuffing !"); +// }while(cbpc == 20); + s->cbp_table[xy]= cbpc&(8+3); //8 is dquant s->mb_intra = ((cbpc & 4) != 0); if(s->mb_intra){ - PRINT_MB_TYPE("I"); + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; s->mbintra_table[xy]= 1; - s->mb_type[xy]= MB_TYPE_INTRA; mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= 0; mot_val[1 ]= mot_val[3 ]= @@ -2794,9 +3032,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ else s->mcsel= 0; if ((cbpc & 16) == 0) { - PRINT_MB_TYPE("P"); /* 16x16 motion prediction */ - s->mb_type[xy]= MB_TYPE_INTER; h263_pred_motion(s, 0, &pred_x, &pred_y); if(!s->mcsel){ @@ -2807,9 +3043,11 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ my = h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; } else { mx = get_amv(s, 0); my = get_amv(s, 1); + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; } mot_val[0 ]= mot_val[2 ] = @@ -2818,8 +3056,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ mot_val[1+stride]= mot_val[3+stride]= my; } else { int i; - PRINT_MB_TYPE("4"); - s->mb_type[xy]= MB_TYPE_INTER4V; + s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { int16_t *mot_val= h263_pred_motion(s, i, &pred_x, &pred_y); mx = h263_decode_motion(s, pred_x, s->f_code); @@ -2855,7 +3092,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ for(s->mb_y= s->resync_mb_y; mb_num < mb_count; s->mb_y++){ ff_init_block_index(s); for(; mb_num < mb_count && s->mb_xmb_width; s->mb_x++){ - const int xy= s->mb_x + s->mb_y*s->mb_width; + const int xy= s->mb_x + s->mb_y*s->mb_stride; mb_num++; ff_update_block_index(s); @@ -2871,9 +3108,9 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ } s->cbp_table[xy]|= cbpy<<2; - s->pred_dir_table[xy]|= ac_pred<<7; + s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; }else{ /* P || S_TYPE */ - if(s->mb_type[xy]&MB_TYPE_INTRA){ + if(IS_INTRA(s->current_picture.mb_type[xy])){ int dir=0,i; int ac_pred = get_bits1(&s->gb); int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); @@ -2900,8 +3137,9 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ } s->cbp_table[xy]&= 3; //remove dquant s->cbp_table[xy]|= cbpy<<2; - s->pred_dir_table[xy]= dir | (ac_pred<<7); - }else if(s->mb_type[xy]&MB_TYPE_SKIPED){ + s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + s->pred_dir_table[xy]= dir; + }else if(IS_SKIP(s->current_picture.mb_type[xy])){ s->current_picture.qscale_table[xy]= s->qscale; s->cbp_table[xy]= 0; }else{ @@ -2953,7 +3191,7 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) s->mb_num_left= mb_num; if(s->pict_type==I_TYPE){ - if(get_bits(&s->gb, 19)!=DC_MARKER){ + if(get_bits_long(&s->gb, 19)!=DC_MARKER){ fprintf(stderr, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -2984,9 +3222,9 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) { int cbp, mb_type; - const int xy= s->mb_x + s->mb_y*s->mb_width; + const int xy= s->mb_x + s->mb_y*s->mb_stride; - mb_type= s->mb_type[xy]; + mb_type= s->current_picture.mb_type[xy]; cbp = s->cbp_table[xy]; if(s->current_picture.qscale_table[xy] != s->qscale){ @@ -3001,9 +3239,9 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) s->mv[0][i][0] = s->motion_val[ s->block_index[i] ][0]; s->mv[0][i][1] = s->motion_val[ s->block_index[i] ][1]; } - s->mb_intra = mb_type&MB_TYPE_INTRA; + s->mb_intra = IS_INTRA(mb_type); - if (mb_type&MB_TYPE_SKIPED) { + if (IS_SKIP(mb_type)) { /* skip mb */ for(i=0;i<6;i++) s->block_last_index[i] = -1; @@ -3017,12 +3255,12 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) s->mb_skiped = 1; } }else if(s->mb_intra){ - s->ac_pred = s->pred_dir_table[xy]>>7; + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); }else if(!s->mb_intra){ // s->mcsel= 0; //FIXME do we need to init that s->mv_dir = MV_DIR_FORWARD; - if (mb_type&MB_TYPE_INTER4V) { + if (IS_8X8(mb_type)) { s->mv_type = MV_TYPE_8X8; } else { s->mv_type = MV_TYPE_16X16; @@ -3030,10 +3268,10 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) } } else { /* I-Frame */ s->mb_intra = 1; - s->ac_pred = s->pred_dir_table[xy]>>7; + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); } - if (!(mb_type&MB_TYPE_SKIPED)) { + if (!IS_SKIP(mb_type)) { int i; /* decode each block */ for (i = 0; i < 6; i++) { @@ -3054,10 +3292,12 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) else return SLICE_NOEND; }else{ - if(s->cbp_table[xy+1] && mpeg4_is_resync(s)) - return SLICE_END; - else - return SLICE_OK; + if(mpeg4_is_resync(s)){ + const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; + if(s->cbp_table[xy+delta]) + return SLICE_END; + } + return SLICE_OK; } } @@ -3067,10 +3307,10 @@ int ff_h263_decode_mb(MpegEncContext *s, int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; int16_t *mot_val; static int8_t quant_tab[4] = { -1, -2, 1, 2 }; - - if(s->mb_x==0) PRINT_MB_TYPE("\n"); - + const int xy= s->mb_x + s->mb_y * s->mb_stride; + if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) { + do{ if (get_bits1(&s->gb)) { /* skip mb */ s->mb_intra = 0; @@ -3079,14 +3319,14 @@ int ff_h263_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ - PRINT_MB_TYPE("G"); + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; s->mcsel=1; s->mv[0][0][0]= get_amv(s, 0); s->mv[0][0][1]= get_amv(s, 1); s->mb_skiped = 0; }else{ - PRINT_MB_TYPE("S"); + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; s->mcsel=0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; @@ -3096,12 +3336,11 @@ int ff_h263_decode_mb(MpegEncContext *s, } cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); //fprintf(stderr, "\tCBPC: %d", cbpc); - if (cbpc < 0) + if (cbpc < 0){ + fprintf(stderr, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); return -1; - if (cbpc > 20) - cbpc+=3; - else if (cbpc == 20) - fprintf(stderr, "Stuffing !"); + } + }while(cbpc == 20); dquant = cbpc & 8; s->mb_intra = ((cbpc & 4) != 0); @@ -3121,7 +3360,7 @@ int ff_h263_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; if ((cbpc & 16) == 0) { if(s->mcsel){ - PRINT_MB_TYPE("G"); + s->current_picture.mb_type[xy]= MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 global motion prediction */ s->mv_type = MV_TYPE_16X16; mx= get_amv(s, 0); @@ -3129,7 +3368,7 @@ int ff_h263_decode_mb(MpegEncContext *s, 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"); + s->current_picture.mb_type[xy]= MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; /* 16x8 field motion prediction */ s->mv_type= MV_TYPE_FIELD; @@ -3151,7 +3390,7 @@ int ff_h263_decode_mb(MpegEncContext *s, s->mv[0][i][1] = my; } }else{ - PRINT_MB_TYPE("P"); + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; h263_pred_motion(s, 0, &pred_x, &pred_y); @@ -3177,7 +3416,7 @@ int ff_h263_decode_mb(MpegEncContext *s, skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ } } else { - PRINT_MB_TYPE("4"); + s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { mot_val = h263_pred_motion(s, i, &pred_x, &pred_y); @@ -3220,7 +3459,7 @@ int ff_h263_decode_mb(MpegEncContext *s, } /* if we skipped it in the future P Frame than skip it now too */ - s->mb_skiped= s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC + s->mb_skiped= s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC if(s->mb_skiped){ /* skip mb */ @@ -3233,41 +3472,44 @@ int ff_h263_decode_mb(MpegEncContext *s, s->mv[0][0][1] = 0; s->mv[1][0][0] = 0; s->mv[1][0][1] = 0; - PRINT_MB_TYPE("s"); + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; goto end; } modb1= get_bits1(&s->gb); if(modb1){ - mb_type=4; //like MB_TYPE_B_DIRECT but no vectors coded + mb_type= MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1; //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(mb_type<0){ + printf("illegal MB_type\n"); + return -1; + } + mb_type= mb_type_b_map[ mb_type ]; if(modb2) cbp= 0; else cbp= get_bits(&s->gb, 6); - if (mb_type!=MB_TYPE_B_DIRECT && cbp) { + if ((!IS_DIRECT(mb_type)) && cbp) { if(get_bits1(&s->gb)){ change_qscale(s, get_bits1(&s->gb)*4 - 2); } } - 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(!IS_DIRECT(mb_type) && get_bits1(&s->gb)){ + mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + mb_type &= ~MB_TYPE_16x16; - if(mb_type!=MB_TYPE_B_BACKW){ + if(USES_LIST(mb_type, 0)){ 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){ + if(USES_LIST(mb_type, 1)){ s->field_select[1][0]= get_bits1(&s->gb); s->field_select[1][1]= get_bits1(&s->gb); } @@ -3275,9 +3517,10 @@ int ff_h263_decode_mb(MpegEncContext *s, } s->mv_dir = 0; - if(mb_type!=MB_TYPE_B_DIRECT && !field_mv){ + if((mb_type & (MB_TYPE_DIRECT2|MB_TYPE_INTERLACED)) == 0){ s->mv_type= MV_TYPE_16X16; - if(mb_type!=MB_TYPE_B_BACKW){ + + if(USES_LIST(mb_type, 0)){ s->mv_dir = MV_DIR_FORWARD; mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); @@ -3286,7 +3529,7 @@ int ff_h263_decode_mb(MpegEncContext *s, 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){ + if(USES_LIST(mb_type, 1)){ s->mv_dir |= MV_DIR_BACKWARD; mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); @@ -3294,12 +3537,10 @@ int ff_h263_decode_mb(MpegEncContext *s, 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){ + }else if(!IS_DIRECT(mb_type)){ s->mv_type= MV_TYPE_FIELD; - if(mb_type!=MB_TYPE_B_BACKW){ + if(USES_LIST(mb_type, 0)){ s->mv_dir = MV_DIR_FORWARD; for(i=0; i<2; i++){ @@ -3310,7 +3551,7 @@ int ff_h263_decode_mb(MpegEncContext *s, } } - if(mb_type!=MB_TYPE_B_FORW){ + if(USES_LIST(mb_type, 1)){ s->mv_dir |= MV_DIR_BACKWARD; for(i=0; i<2; i++){ @@ -3320,13 +3561,11 @@ int ff_h263_decode_mb(MpegEncContext *s, 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")); } } - if(mb_type==4 || mb_type==MB_TYPE_B_DIRECT){ - if(mb_type==4) + if(IS_DIRECT(mb_type)){ + if(IS_SKIP(mb_type)) mx=my=0; else{ mx = h263_decode_motion(s, 0, 1); @@ -3334,30 +3573,38 @@ int ff_h263_decode_mb(MpegEncContext *s, } s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - ff_mpeg4_set_direct_mv(s, mx, my); - } - - if(mb_type<0 || mb_type>4){ - printf("illegal MB_type\n"); - return -1; + mb_type |= ff_mpeg4_set_direct_mv(s, mx, my); } + s->current_picture.mb_type[xy]= mb_type; } else { /* I-Frame */ - cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1); - if (cbpc < 0) - return -1; + do{ + cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); + if (cbpc < 0){ + fprintf(stderr, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 8); + dquant = cbpc & 4; s->mb_intra = 1; intra: - s->ac_pred = 0; + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; if (s->h263_pred || s->h263_aic) { s->ac_pred = get_bits1(&s->gb); - if (s->ac_pred && s->h263_aic) - s->h263_aic_dir = get_bits1(&s->gb); - } - PRINT_MB_TYPE(s->ac_pred ? "A" : "I"); + if(s->ac_pred){ + s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED; + + if (s->h263_aic) + s->h263_aic_dir = get_bits1(&s->gb); + } + }else + s->ac_pred = 0; cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0) return -1; + if(cbpy<0){ + fprintf(stderr, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } cbp = (cbpc & 3) | (cbpy << 2); if (dquant) { change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); @@ -3402,7 +3649,8 @@ end: /* per-MB end of slice check */ if(s->codec_id==CODEC_ID_MPEG4){ if(mpeg4_is_resync(s)){ - if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x+1]) + const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; + if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[xy + delta]) return SLICE_OK; return SLICE_END; } @@ -3424,18 +3672,20 @@ static int h263_decode_motion(MpegEncContext * s, int pred, int f_code) { int code, val, sign, shift, l; code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); - if (code < 0) - return 0xffff; if (code == 0) return pred; + if (code < 0) + return 0xffff; sign = get_bits1(&s->gb); shift = f_code - 1; - val = (code - 1) << shift; - if (shift > 0) + val = code; + if (shift) { + val = (val - 1) << shift; val |= get_bits(&s->gb, shift); - val++; + val++; + } if (sign) val = -val; val += pred; @@ -3443,11 +3693,7 @@ static int h263_decode_motion(MpegEncContext * s, int pred, int f_code) /* modulo decoding */ if (!s->h263_long_vectors) { l = 1 << (f_code + 4); - if (val < -l) { - val += l<<1; - } else if (val >= l) { - val -= l<<1; - } + val = ((val + l)&(l*2-1)) - l; } else { /* horrible h263 long vector mode */ if (pred < -31 && val < -63) @@ -3551,18 +3797,27 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, } if (code == rl->n) { /* escape */ - last = get_bits1(&s->gb); - run = get_bits(&s->gb, 6); - level = (int8_t)get_bits(&s->gb, 8); - if(level == -128){ - if (s->h263_rv10) { - /* XXX: should patch encoder too */ - level = get_bits(&s->gb, 12); - level= (level + ((-1)<<11)) ^ ((-1)<<11); //sign extension - }else{ - level = get_bits(&s->gb, 5); - level += get_bits(&s->gb, 6)<<5; - level= (level + ((-1)<<10)) ^ ((-1)<<10); //sign extension + if (s->h263_flv > 1) { + int is11 = get_bits1(&s->gb); + last = get_bits1(&s->gb); + run = get_bits(&s->gb, 6); + if(is11){ + level = get_sbits(&s->gb, 11); + } else { + level = get_sbits(&s->gb, 7); + } + } else { + last = get_bits1(&s->gb); + run = get_bits(&s->gb, 6); + level = (int8_t)get_bits(&s->gb, 8); + if(level == -128){ + if (s->h263_rv10) { + /* XXX: should patch encoder too */ + level = get_sbits(&s->gb, 12); + }else{ + level = get_bits(&s->gb, 5); + level |= get_sbits(&s->gb, 6)<<5; + } } } } else { @@ -3614,9 +3869,19 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) if (code == 0) { level = 0; } else { - level = get_bits(&s->gb, code); - if ((level >> (code - 1)) == 0) /* if MSB not set it is negative*/ - level = - (level ^ ((1 << code) - 1)); + if(IS_3IV1){ + if(code==1) + level= 2*get_bits1(&s->gb)-1; + else{ + if(get_bits1(&s->gb)) + level = get_bits(&s->gb, code-1) + (1<<(code-1)); + else + level = -get_bits(&s->gb, code-1) - (1<<(code-1)); + } + }else{ + level = get_xbits(&s->gb, code); + } + if (code > 8){ if(get_bits1(&s->gb)==0){ /* marker */ if(s->error_resilience>=2){ @@ -3640,6 +3905,9 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) } else { *dc_val = level * s->c_dc_scale; } + if(IS_3IV1) + *dc_val = level * 8; + if(s->error_resilience>=3){ if(*dc_val > 2048 + s->y_dc_scale + s->c_dc_scale){ fprintf(stderr, "dc overflow at %dx%d\n", s->mb_x, s->mb_y); @@ -3666,12 +3934,13 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, //Note intra & rvlc should be optimized away if this is inlined if(intra) { + if(s->qscale < s->intra_dc_threshold){ /* DC coef */ if(s->partitioned_frame){ level = s->dc_val[0][ s->block_index[n] ]; - if(n<4) level= (level + (s->y_dc_scale>>1))/s->y_dc_scale; //FIXME optimizs - else level= (level + (s->c_dc_scale>>1))/s->c_dc_scale; - dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_width]<y_dc_scale>>1)), s->y_dc_scale); + else level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale); + dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<gb, 1+11+5+1); i+= run + 1; - if(last) i+=192; + if(last) i+=192; }else{ int cache; cache= GET_CACHE(re, &s->gb); + + if(IS_3IV1) + cache ^= 0xC0000000; + if (cache&0x80000000) { if (cache&0x40000000) { /* third escape */ @@ -3776,28 +4052,32 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, SKIP_COUNTER(re, &s->gb, 2+1+6); UPDATE_CACHE(re, &s->gb); - if(SHOW_UBITS(re, &s->gb, 1)==0){ - fprintf(stderr, "1. marker bit missing in 3. esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); - - level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12); + if(IS_3IV1){ + level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12); + }else{ + if(SHOW_UBITS(re, &s->gb, 1)==0){ + fprintf(stderr, "1. marker bit missing in 3. esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12); + + if(SHOW_UBITS(re, &s->gb, 1)==0){ + fprintf(stderr, "2. marker bit missing in 3. esc\n"); + return -1; + }; LAST_SKIP_CACHE(re, &s->gb, 1); + + SKIP_COUNTER(re, &s->gb, 1+12+1); + } - if(SHOW_UBITS(re, &s->gb, 1)==0){ - fprintf(stderr, "2. marker bit missing in 3. esc\n"); - return -1; - }; LAST_SKIP_CACHE(re, &s->gb, 1); - - SKIP_COUNTER(re, &s->gb, 1+12+1); - if(level*s->qscale>1024 || level*s->qscale<-1024){ fprintf(stderr, "|level| overflow in 3. esc, qp=%d\n", s->qscale); return -1; } -#if 1 - { +#if 0 + if(s->error_resilience >= FF_ER_COMPLIANT){ const int abs_level= ABS(level); - if(abs_level<=MAX_LEVEL && run<=MAX_RUN && !(s->workaround_bugs&FF_BUG_AC_VLC)){ + if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ const int run1= run - rl->max_run[last][abs_level] - 1; if(abs_level <= rl->max_level[last][run]){ fprintf(stderr, "illegal 3. esc, vlc encoding possible\n"); @@ -3870,7 +4150,19 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, CLOSE_READER(re, &s->gb); } not_coded: - if (s->mb_intra) { + if (intra) { + if(s->qscale >= s->intra_dc_threshold){ + uint16_t *dc_val; + block[0] += ff_mpeg4_pred_dc(s, n, &dc_val, &dc_pred_dir); + if (n < 4) { + *dc_val = block[0] * s->y_dc_scale; + } else { + *dc_val = block[0] * s->c_dc_scale; + } + + if(i == -1) i=0; + } + mpeg4_pred_ac(s, block, n, dc_pred_dir); if (s->ac_pred) { i = 63; /* XXX: not optimal */ @@ -3883,10 +4175,21 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, /* most is hardcoded. should extend to handle all h263 streams */ int h263_decode_picture_header(MpegEncContext *s) { - int format, width, height; + int format, width, height, i; + uint32_t startcode; + + align_get_bits(&s->gb); + + startcode= get_bits(&s->gb, 22-8); - /* picture start code */ - if (get_bits(&s->gb, 22) != 0x20) { + for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=8) { + startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF; + + if(startcode == 0x20) + break; + } + + if (startcode != 0x20) { fprintf(stderr, "Bad picture start code\n"); return -1; } @@ -3926,8 +4229,6 @@ int h263_decode_picture_header(MpegEncContext *s) if (!width) return -1; - s->width = width; - s->height = height; s->pict_type = I_TYPE + get_bits1(&s->gb); s->unrestricted_mv = get_bits1(&s->gb); @@ -3947,6 +4248,9 @@ int h263_decode_picture_header(MpegEncContext *s) } s->qscale = get_bits(&s->gb, 5); skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ + + s->width = width; + s->height = height; } else { int ufep; @@ -3961,6 +4265,7 @@ int h263_decode_picture_header(MpegEncContext *s) dprintf("ufep=1, format: %d\n", format); skip_bits(&s->gb,1); /* Custom PCF */ s->umvplus = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ + s->unrestricted_mv = s->umvplus; skip_bits1(&s->gb); /* Syntax-based Arithmetic Coding (SAC) */ if (get_bits1(&s->gb) != 0) { s->mv_type = MV_TYPE_8X8; /* Advanced prediction mode */ @@ -3969,15 +4274,26 @@ int h263_decode_picture_header(MpegEncContext *s) s->h263_aic = 1; } - skip_bits(&s->gb, 7); - /* these are the 7 bits: (in order of appearence */ - /* Deblocking Filter */ - /* Slice Structured */ - /* Reference Picture Selection */ - /* Independent Segment Decoding */ - /* Alternative Inter VLC */ - /* Modified Quantization */ - /* Prevent start code emulation */ + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Deblocking Filter not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Slice Structured not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Reference Picture Selection not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Independent Segment Decoding not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Alternative Inter VLC not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Modified Quantization not supported\n"); + } + + skip_bits(&s->gb, 1); /* Prevent start code emulation */ skip_bits(&s->gb, 3); /* Reserved */ } else if (ufep != 0) { @@ -4017,11 +4333,10 @@ int h263_decode_picture_header(MpegEncContext *s) dprintf("\nH.263+ Custom picture: %dx%d\n",width,height); if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { /* aspected dimensions */ - s->aspected_width = get_bits(&s->gb, 8); - s->aspected_height = get_bits(&s->gb, 8); + s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 8); + s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 8); }else{ - s->aspected_width = pixel_aspect[s->aspect_ratio_info][0]; - s->aspected_height= pixel_aspect[s->aspect_ratio_info][1]; + s->avctx->sample_aspect_ratio= pixel_aspect[s->aspect_ratio_info]; } } else { width = h263_format[format][0]; @@ -4053,6 +4368,18 @@ int h263_decode_picture_header(MpegEncContext *s) s->c_dc_scale_table= ff_mpeg1_dc_scale_table; } + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + printf("qp:%d %c size:%d rnd:%d %s %s %s %s\n", + s->qscale, av_get_pict_type_char(s->pict_type), + s->gb.size_in_bits, 1-s->no_rounding, + s->mv_type == MV_TYPE_8X8 ? "ADV" : "", + s->umvplus ? "UMV" : "", + s->h263_long_vectors ? "LONG" : "", + s->h263_plus ? "+" : "" + ); + } + + return 0; } @@ -4078,19 +4405,13 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s) length= get_vlc(&s->gb, &sprite_trajectory); if(length){ - x= get_bits(&s->gb, length); - - if ((x >> (length - 1)) == 0) /* if MSB not set it is negative*/ - x = - (x ^ ((1 << length) - 1)); + x= get_xbits(&s->gb, length); } if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(&s->gb); /* marker bit */ length= get_vlc(&s->gb, &sprite_trajectory); if(length){ - y=get_bits(&s->gb, length); - - if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/ - y = - (y ^ ((1 << length) - 1)); + y=get_xbits(&s->gb, length); } skip_bits1(&s->gb); /* marker bit */ //printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy); @@ -4302,11 +4623,10 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ //printf("vo type:%d\n",s->vo_type); s->aspect_ratio_info= get_bits(gb, 4); if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){ - s->aspected_width = get_bits(gb, 8); // par_width - s->aspected_height = get_bits(gb, 8); // par_height + s->avctx->sample_aspect_ratio.num= get_bits(gb, 8); // par_width + s->avctx->sample_aspect_ratio.den= get_bits(gb, 8); // par_height }else{ - s->aspected_width = pixel_aspect[s->aspect_ratio_info][0]; - s->aspected_height= pixel_aspect[s->aspect_ratio_info][1]; + s->avctx->sample_aspect_ratio= pixel_aspect[s->aspect_ratio_info]; } if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */ @@ -4341,14 +4661,15 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ skip_bits(gb, 4); //video_object_layer_shape_extension } - skip_bits1(gb); /* marker */ + check_marker(gb, "before time_increment_resolution"); s->time_increment_resolution = get_bits(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; - skip_bits1(gb); /* marker */ + + check_marker(gb, "before fixed_vop_rate"); if (get_bits1(gb) != 0) { /* fixed_vop_rate */ skip_bits(gb, s->time_increment_bits); @@ -4369,7 +4690,8 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ } s->progressive_sequence= get_bits1(gb)^1; - if(!get_bits1(gb)) printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ + if(!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO)) + printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ if (vo_ver_id == 1) { s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */ } else { @@ -4437,8 +4759,8 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ /* replicate last value */ for(; i<64; i++){ int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->intra_matrix[j]= v; - s->chroma_intra_matrix[j]= v; + s->intra_matrix[j]= last; + s->chroma_intra_matrix[j]= last; } } @@ -4558,13 +4880,6 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ s->divx_version= ver; s->divx_build= build; s->divx_packed= e==3 && last=='p'; - if(s->picture_number==0){ - printf("This file was encoded with DivX%d Build%d", ver, build); - if(s->divx_packed) - printf("p\n"); - else - printf("\n"); - } } /* ffmpeg detection */ @@ -4580,16 +4895,12 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ if(e==4){ s->ffmpeg_version= ver*256*256 + ver2*256 + ver3; s->lavc_build= build; - if(s->picture_number==0) - printf("This file was encoded with libavcodec build %d\n", build); } /* xvid detection */ e=sscanf(buf, "XviD%d", &build); if(e==1){ s->xvid_build= build; - if(s->picture_number==0) - printf("This file was encoded with XviD build %d\n", build); } //printf("User Data: %s\n", buf); @@ -4600,7 +4911,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ int time_incr, time_increment; s->pict_type = get_bits(gb, 2) + I_TYPE; /* pict type: I = 0 , P = 1 */ - if(s->pict_type==B_TYPE && s->low_delay && s->vol_control_parameters==0){ + if(s->pict_type==B_TYPE && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){ printf("low_delay flag set, but shouldnt, clearing it\n"); s->low_delay=0; } @@ -4621,17 +4932,20 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ check_marker(gb, "before time_increment"); - if(s->picture_number==0 && (show_bits(gb, s->time_increment_bits+1)&1)==0){ + if(s->time_increment_bits==0){ printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n"); - for(s->time_increment_bits=1 ;s->time_increment_bits<16; s->time_increment_bits++){ if(show_bits(gb, s->time_increment_bits+1)&1) break; } + printf("my guess is %d bits ;)\n",s->time_increment_bits); } - time_increment= get_bits(gb, s->time_increment_bits); + if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further + else time_increment= get_bits(gb, s->time_increment_bits); + +// printf("%d %X\n", s->time_increment_bits, time_increment); //printf(" type:%d modulo_time_base:%d increment:%d\n", s->pict_type, time_incr, time_increment); if(s->pict_type!=B_TYPE){ s->last_time_base= s->time_base; @@ -4706,9 +5020,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ //FIXME complexity estimation stuff if (s->shape != BIN_ONLY_SHAPE) { - int t; - t=get_bits(gb, 3); /* intra dc VLC threshold */ -//printf("threshold %d\n", t); + s->intra_dc_threshold= mpeg4_dc_threshold[ get_bits(gb, 3) ]; if(!s->progressive_sequence){ s->top_field_first= get_bits1(gb); s->alternate_scan= get_bits1(gb); @@ -4717,15 +5029,15 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } if(s->alternate_scan){ - ff_init_scantable(s, &s->inter_scantable , ff_alternate_vertical_scan); - ff_init_scantable(s, &s->intra_scantable , ff_alternate_vertical_scan); - ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_vertical_scan); - ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); } else{ - ff_init_scantable(s, &s->inter_scantable , ff_zigzag_direct); - ff_init_scantable(s, &s->intra_scantable , ff_zigzag_direct); - ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_horizontal_scan); - ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); } if(s->pict_type == S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ @@ -4756,12 +5068,12 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ s->b_code=1; if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - printf("qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d\n", + printf("qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%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")), gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first, s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points, - s->sprite_warping_accuracy); + s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold); } if(!s->scalability){ @@ -4790,7 +5102,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ 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; - if(!(s->workaround_bugs&FF_BUG_EDGE)){ + if(s->workaround_bugs&FF_BUG_EDGE){ s->h_edge_pos= s->width; s->v_edge_pos= s->height; } @@ -4857,20 +5169,18 @@ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) printf(" at %d\n", get_bits_count(gb)); } - switch(startcode){ - case 0x120: - decode_vol_header(s, gb); - break; - case USER_DATA_STARTCODE: + if(startcode >= 0x120 && startcode <= 0x12F){ + if(decode_vol_header(s, gb) < 0) + return -1; + } + else if(startcode == USER_DATA_STARTCODE){ decode_user_data(s, gb); - break; - case GOP_STARTCODE: + } + else if(startcode == GOP_STARTCODE){ mpeg4_decode_gop_header(s, gb); - break; - case VOP_STARTCODE: + } + else if(startcode == VOP_STARTCODE){ return decode_vop_header(s, gb); - default: - break; } align_get_bits(gb); @@ -4884,7 +5194,7 @@ int intel_h263_decode_picture_header(MpegEncContext *s) int format; /* picture header */ - if (get_bits(&s->gb, 22) != 0x20) { + if (get_bits_long(&s->gb, 22) != 0x20) { fprintf(stderr, "Bad picture start code\n"); return -1; } @@ -4945,3 +5255,85 @@ int intel_h263_decode_picture_header(MpegEncContext *s) return 0; } +int flv_h263_decode_picture_header(MpegEncContext *s) +{ + int format, width, height; + + /* picture header */ + if (get_bits_long(&s->gb, 17) != 1) { + fprintf(stderr, "Bad picture start code\n"); + return -1; + } + format = get_bits(&s->gb, 5); + if (format != 0 && format != 1) { + fprintf(stderr, "Bad picture format\n"); + return -1; + } + s->h263_flv = format+1; + s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */ + format = get_bits(&s->gb, 3); + switch (format) { + case 0: + width = get_bits(&s->gb, 8); + height = get_bits(&s->gb, 8); + break; + case 1: + width = get_bits(&s->gb, 16); + height = get_bits(&s->gb, 16); + break; + case 2: + width = 352; + height = 288; + break; + case 3: + width = 176; + height = 144; + break; + case 4: + width = 128; + height = 96; + break; + case 5: + width = 320; + height = 240; + break; + case 6: + width = 160; + height = 120; + break; + default: + width = height = 0; + break; + } + if ((width == 0) || (height == 0)) + return -1; + s->width = width; + s->height = height; + + s->pict_type = I_TYPE + get_bits(&s->gb, 2); + if (s->pict_type > P_TYPE) + s->pict_type = P_TYPE; + skip_bits1(&s->gb); /* deblocking flag */ + s->qscale = get_bits(&s->gb, 5); + + s->h263_plus = 0; + + s->unrestricted_mv = 1; + s->h263_long_vectors = 0; + + /* PEI */ + while (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); + } + s->f_code = 1; + + if(s->avctx->debug & FF_DEBUG_PICT_INFO){ + printf("%c esc_type:%d, qp:%d num:%d\n", + av_get_pict_type_char(s->pict_type), s->h263_flv-1, s->qscale, s->picture_number); + } + + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + + return 0; +}