diff options
author | Mike Melanson <mike@multimedia.cx> | 2004-03-14 21:14:07 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2004-03-14 21:14:07 +0000 |
commit | 0d90aec0fd7428a77b5c4c536ab65635669bc42d (patch) | |
tree | 9eb56c6c1176bf6a6f3ae65199a3f43aa8c2aa2d /src/libffmpeg/libavcodec/h263.c | |
parent | b4d3aa3dcce07b90098e33c37b563e797378d0f1 (diff) | |
download | xine-lib-0d90aec0fd7428a77b5c4c536ab65635669bc42d.tar.gz xine-lib-0d90aec0fd7428a77b5c4c536ab65635669bc42d.tar.bz2 |
sync to ffmpeg build 4707
CVS patchset: 6253
CVS date: 2004/03/14 21:14:07
Diffstat (limited to 'src/libffmpeg/libavcodec/h263.c')
-rw-r--r-- | src/libffmpeg/libavcodec/h263.c | 194 |
1 files changed, 140 insertions, 54 deletions
diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c index de9110a4e..8a60ff08b 100644 --- a/src/libffmpeg/libavcodec/h263.c +++ b/src/libffmpeg/libavcodec/h263.c @@ -197,15 +197,36 @@ void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number) void h263_encode_picture_header(MpegEncContext * s, int picture_number) { - int format; + int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref; + int best_clock_code=1; + int best_divisor=60; + int best_error= INT_MAX; + + if(s->h263_plus){ + for(i=0; i<2; i++){ + int div, error; + div= (s->avctx->frame_rate_base*1800000LL + 500LL*s->avctx->frame_rate) / ((1000LL+i)*s->avctx->frame_rate); + div= clip(1, div, 127); + error= ABS(s->avctx->frame_rate_base*1800000LL - (1000LL+i)*s->avctx->frame_rate*div); + if(error < best_error){ + best_error= error; + best_divisor= div; + best_clock_code= i; + } + } + } + s->custom_pcf= best_clock_code!=1 || best_divisor!=60; + coded_frame_rate= 1800000; + coded_frame_rate_base= (1000+best_clock_code)*best_divisor; align_put_bits(&s->pb); /* Update the pointer to last GOB */ s->ptr_lastgob = pbBufPtr(&s->pb); put_bits(&s->pb, 22, 0x20); /* PSC */ - put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->frame_rate_base) / - s->avctx->frame_rate) & 0xff); + temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->frame_rate_base / + (coded_frame_rate_base * (int64_t)s->avctx->frame_rate); + put_bits(&s->pb, 8, temp_ref & 0xff); /* TemporalReference */ put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, 1, 0); /* h263 id */ @@ -228,16 +249,18 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 5, s->qscale); put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */ } else { + int ufep=1; /* H.263v2 */ /* H.263 Plus PTYPE */ + put_bits(&s->pb, 3, 7); - put_bits(&s->pb,3,1); /* Update Full Extended PTYPE */ + put_bits(&s->pb,3,ufep); /* Update Full Extended PTYPE */ if (format == 7) put_bits(&s->pb,3,6); /* Custom Source Format */ else put_bits(&s->pb, 3, format); - put_bits(&s->pb,1,0); /* Custom PCF: off */ + put_bits(&s->pb,1, s->custom_pcf); put_bits(&s->pb,1, s->umvplus); /* Unrestricted Motion Vector */ put_bits(&s->pb,1,0); /* SAC: off */ put_bits(&s->pb,1,s->obmc); /* Advanced Prediction Mode */ @@ -275,6 +298,13 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); } } + if(s->custom_pcf){ + if(ufep){ + put_bits(&s->pb, 1, best_clock_code); + put_bits(&s->pb, 7, best_divisor); + } + put_bits(&s->pb, 2, (temp_ref>>8)&3); + } /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ if (s->umvplus) @@ -1123,7 +1153,7 @@ void h263_encode_mb(MpegEncContext * s, /* compute cbp */ cbp= get_p_cbp(s, block, motion_x, motion_y); - if ((cbp | motion_x | motion_y | s->dquant) == 0) { + if ((cbp | motion_x | motion_y | s->dquant | (s->mv_type - MV_TYPE_16X16)) == 0) { /* skip macroblock */ put_bits(&s->pb, 1, 1); if(interleaved_stats){ @@ -1961,7 +1991,9 @@ 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; - + s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; + s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; + if(s->flags & CODEC_FLAG_GLOBAL_HEADER){ s->avctx->extradata= av_malloc(1024); @@ -1972,7 +2004,7 @@ void h263_encode_init(MpegEncContext *s) // ff_mpeg4_stuffing(&s->pb); ? flush_put_bits(&s->pb); - s->avctx->extradata_size= (get_bit_count(&s->pb)+7)>>3; + s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3; } break; @@ -2146,7 +2178,7 @@ void ff_mpeg4_stuffing(PutBitContext * pbc) { int length; put_bits(pbc, 1, 0); - length= (-get_bit_count(pbc))&7; + length= (-put_bits_count(pbc))&7; if(length) put_bits(pbc, length, (1<<length)-1); } @@ -2154,10 +2186,9 @@ void ff_mpeg4_stuffing(PutBitContext * pbc) void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ int time_div, time_mod; - if(s->current_picture_ptr->pts) - s->time= (s->current_picture_ptr->pts*s->time_increment_resolution + 500*1000)/(1000*1000); - else - s->time= av_rescale(picture_number*(int64_t)s->avctx->frame_rate_base, s->time_increment_resolution, s->avctx->frame_rate); + assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE); + s->time= (s->current_picture_ptr->pts*s->time_increment_resolution + AV_TIME_BASE/2)/AV_TIME_BASE; + time_div= s->time/s->time_increment_resolution; time_mod= s->time%s->time_increment_resolution; @@ -2178,11 +2209,10 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, GOP_STARTCODE); - if(s->current_picture_ptr->pts && s->reordered_input_picture[1]){ - time= FFMIN(s->reordered_input_picture[1]->pts, s->current_picture_ptr->pts); - time= (time*s->time_increment_resolution + 500*1000)/(1000*1000); - }else - time= av_rescale(s->current_picture_ptr->coded_picture_number*(int64_t)s->avctx->frame_rate_base, s->time_increment_resolution, s->avctx->frame_rate); + time= s->current_picture_ptr->pts; + if(s->reordered_input_picture[1]) + time= FFMIN(time, s->reordered_input_picture[1]->pts); + time= (time*s->time_increment_resolution + AV_TIME_BASE/2)/AV_TIME_BASE; seconds= time/s->time_increment_resolution; minutes= seconds/60; seconds %= 60; @@ -2290,12 +2320,11 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1); put_bits(&s->pb, 1, 1); /* obmc disable */ if (vo_ver_id == 1) { - put_bits(&s->pb, 1, s->vol_sprite_usage=0); /* sprite enable */ + put_bits(&s->pb, 1, s->vol_sprite_usage); /* sprite enable */ }else{ - put_bits(&s->pb, 2, s->vol_sprite_usage=0); /* sprite enable */ + put_bits(&s->pb, 2, s->vol_sprite_usage); /* sprite enable */ } - 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)*/ @@ -2326,8 +2355,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n if(!(s->flags & CODEC_FLAG_BITEXACT)){ put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, 0x1B2); /* user_data */ - put_string(&s->pb, LIBAVCODEC_IDENT); - ff_mpeg4_stuffing(&s->pb); + put_string(&s->pb, LIBAVCODEC_IDENT, 0); } } @@ -2385,9 +2413,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) if (s->pict_type == B_TYPE) put_bits(&s->pb, 3, s->b_code); /* fcode_back */ // printf("****frame %d\n", 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; } #endif //CONFIG_ENCODERS @@ -2966,15 +2991,23 @@ 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); - init_put_bits(&s->pb2 , s->pb2_buffer , PB_BUFFER_SIZE); + uint8_t *start= pbBufPtr(&s->pb); + uint8_t *end= s->pb.buf_end; + int size= end - start; + int pb_size = size/3; + int pb2_size= size/3; + int tex_size= size - pb_size - pb2_size; + + set_put_bits_buffer_size(&s->pb, pb_size); + init_put_bits(&s->tex_pb, start + pb_size , tex_size); + init_put_bits(&s->pb2 , start + pb_size + tex_size, pb2_size); } void ff_mpeg4_merge_partitions(MpegEncContext *s) { - const int pb2_len = get_bit_count(&s->pb2 ); - const int tex_pb_len= get_bit_count(&s->tex_pb); - const int bits= get_bit_count(&s->pb); + const int pb2_len = put_bits_count(&s->pb2 ); + const int tex_pb_len= put_bits_count(&s->tex_pb); + const int bits= put_bits_count(&s->pb); if(s->pict_type==I_TYPE){ put_bits(&s->pb, 19, DC_MARKER); @@ -2990,9 +3023,10 @@ void ff_mpeg4_merge_partitions(MpegEncContext *s) flush_put_bits(&s->pb2); flush_put_bits(&s->tex_pb); - ff_copy_bits(&s->pb, s->pb2_buffer , pb2_len); - ff_copy_bits(&s->pb, s->tex_pb_buffer, tex_pb_len); - s->last_bits= get_bit_count(&s->pb); + set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf); + ff_copy_bits(&s->pb, s->pb2.buf , pb2_len); + ff_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len); + s->last_bits= put_bits_count(&s->pb); } #endif //CONFIG_ENCODERS @@ -3302,18 +3336,18 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ if(s->pict_type==I_TYPE){ int i; - if(show_bits_long(&s->gb, 19)==DC_MARKER){ - return mb_num-1; - } - do{ + if(show_bits_long(&s->gb, 19)==DC_MARKER){ + return mb_num-1; + } + cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); if (cbpc < 0){ av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } }while(cbpc == 8); - + s->cbp_table[xy]= cbpc & 3; s->current_picture.mb_type[xy]= MB_TYPE_INTRA; s->mb_intra = 1; @@ -3340,7 +3374,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ int16_t * const mot_val= s->current_picture.motion_val[0][s->block_index[0]]; const int stride= s->block_wrap[0]*2; -// do{ //FIXME +try_again: bits= show_bits(&s->gb, 17); if(bits==MOTION_MARKER){ return mb_num-1; @@ -3371,7 +3405,8 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } -// }while(cbpc == 20); + if(cbpc == 20) + goto try_again; s->cbp_table[xy]= cbpc&(8+3); //8 is dquant @@ -3552,11 +3587,15 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) s->mb_num_left= mb_num; if(s->pict_type==I_TYPE){ + while(show_bits(&s->gb, 9) == 1) + skip_bits(&s->gb, 9); if(get_bits_long(&s->gb, 19)!=DC_MARKER){ av_log(s->avctx, AV_LOG_ERROR, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y); return -1; } }else{ + while(show_bits(&s->gb, 10) == 1) + skip_bits(&s->gb, 10); if(get_bits(&s->gb, 17)!=MOTION_MARKER){ av_log(s->avctx, AV_LOG_ERROR, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y); return -1; @@ -3867,8 +3906,15 @@ int ff_h263_decode_mb(MpegEncContext *s, } } + /* decode each block */ + for (i = 0; i < 6; i++) { + if (h263_decode_block(s, block[i], i, cbp&32) < 0) + return -1; + cbp+=cbp; + } + if(s->obmc){ - if(s->pict_type == P_TYPE && s->mb_x+1<s->mb_width) + if(s->pict_type == P_TYPE && s->mb_x+1<s->mb_width && s->mb_num_left != 1) preview_obmc(s); } } else if(s->pict_type==B_TYPE) { @@ -3958,6 +4004,13 @@ int ff_h263_decode_mb(MpegEncContext *s, } s->current_picture.mb_type[xy]= mb_type; + + /* decode each block */ + for (i = 0; i < 6; i++) { + if (h263_decode_block(s, block[i], i, cbp&32) < 0) + return -1; + cbp+=cbp; + } } else { /* I-Frame */ do{ cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); @@ -3990,13 +4043,13 @@ intra: if (dquant) { h263_decode_dquant(s); } - } - /* decode each block */ - for (i = 0; i < 6; i++) { - if (h263_decode_block(s, block[i], i, cbp&32) < 0) - return -1; - cbp+=cbp; + /* decode each block */ + for (i = 0; i < 6; i++) { + if (h263_decode_block(s, block[i], i, cbp&32) < 0) + return -1; + cbp+=cbp; + } } end: @@ -4873,7 +4926,10 @@ int h263_decode_picture_header(MpegEncContext *s) return -1; } /* temporal reference */ - s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */ + i = get_bits(&s->gb, 8); /* picture timestamp */ + if( (s->picture_number&~0xFF)+i < s->picture_number) + i+= 256; + s->picture_number= (s->picture_number&~0xFF) + i; /* PTYPE starts here */ if (get_bits1(&s->gb) != 1) { @@ -4925,6 +4981,9 @@ int h263_decode_picture_header(MpegEncContext *s) s->width = width; s->height = height; + s->avctx->sample_aspect_ratio= (AVRational){12,11}; + s->avctx->frame_rate = 30000; + s->avctx->frame_rate_base= 1001; } else { int ufep; @@ -4937,7 +4996,7 @@ int h263_decode_picture_header(MpegEncContext *s) /* OPPTYPE */ format = get_bits(&s->gb, 3); dprintf("ufep=1, format: %d\n", format); - skip_bits(&s->gb,1); /* Custom PCF */ + s->custom_pcf= get_bits1(&s->gb); s->umvplus = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ if (get_bits1(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "Syntax-based Arithmetic Coding (SAC) not supported\n"); @@ -5010,11 +5069,37 @@ int h263_decode_picture_header(MpegEncContext *s) } else { width = h263_format[format][0]; height = h263_format[format][1]; + s->avctx->sample_aspect_ratio= (AVRational){12,11}; } if ((width == 0) || (height == 0)) return -1; s->width = width; s->height = height; + + if(s->custom_pcf){ + int gcd; + s->avctx->frame_rate= 1800000; + s->avctx->frame_rate_base= 1000 + get_bits1(&s->gb); + s->avctx->frame_rate_base*= get_bits(&s->gb, 7); + if(s->avctx->frame_rate_base == 0){ + av_log(s, AV_LOG_ERROR, "zero framerate\n"); + return -1; + } + gcd= ff_gcd(s->avctx->frame_rate, s->avctx->frame_rate_base); + s->avctx->frame_rate /= gcd; + s->avctx->frame_rate_base /= gcd; +// av_log(s->avctx, AV_LOG_DEBUG, "%d/%d\n", s->avctx->frame_rate, s->avctx->frame_rate_base); + }else{ + s->avctx->frame_rate = 30000; + s->avctx->frame_rate_base= 1001; + } + } + + if(s->custom_pcf){ + skip_bits(&s->gb, 2); //extended Temporal reference + } + + if (ufep) { if (s->umvplus) { if(get_bits1(&s->gb)==0) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ skip_bits1(&s->gb); @@ -5061,7 +5146,7 @@ int h263_decode_picture_header(MpegEncContext *s) } if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s\n", + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n", s->qscale, av_get_pict_type_char(s->pict_type), s->gb.size_in_bits, 1-s->no_rounding, s->obmc ? " AP" : "", @@ -5072,7 +5157,8 @@ int h263_decode_picture_header(MpegEncContext *s) s->alt_inter_vlc ? " AIV" : "", s->modified_quant ? " MQ" : "", s->loop_filter ? " LOOP" : "", - s->h263_slice_structured ? " SS" : "" + s->h263_slice_structured ? " SS" : "", + s->avctx->frame_rate, s->avctx->frame_rate_base ); } #if 1 @@ -5690,9 +5776,9 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; } - s->current_picture_ptr->pts= s->time*1000LL*1000LL / s->time_increment_resolution; + s->current_picture_ptr->pts= s->time*(int64_t)AV_TIME_BASE / s->time_increment_resolution; if(s->avctx->debug&FF_DEBUG_PTS) - av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %f\n", s->current_picture_ptr->pts/(1000.0*1000.0)); + av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %f\n", s->current_picture_ptr->pts/(float)AV_TIME_BASE); check_marker(gb, "before vop_coded"); |