diff options
author | Loïc Le Loarer <lll+ffmpeg@m4x.org> | 2005-04-05 01:35:22 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2005-04-05 01:35:22 +0000 |
commit | 826de46ea306ee4a179dd4ad368bc4abb488db4c (patch) | |
tree | c9c2df0fdf5f32f240a835a2e37ebd8cce79befc /libavcodec/h264.c | |
parent | 0979831511cf8cbc6675019c5932c18b8fec0d57 (diff) | |
download | ffmpeg-826de46ea306ee4a179dd4ad368bc4abb488db4c.tar.gz |
CABAC support for MBAFF I frames patch by (Loïc Le Loarer | lll+ffmpeg m4x org)
Originally committed as revision 4106 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 127 |
1 files changed, 78 insertions, 49 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index eeb185f690..8e214b8bd4 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -508,11 +508,9 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ } } - if(for_deblock){ - h->top_mb_xy = top_xy; - h->left_mb_xy[0] = left_xy[0]; - h->left_mb_xy[1] = left_xy[1]; - } + h->top_mb_xy = top_xy; + h->left_mb_xy[0] = left_xy[0]; + h->left_mb_xy[1] = left_xy[1]; if(for_deblock){ topleft_type = h->slice_table[topleft_xy ] < 255 ? s->current_picture.mb_type[topleft_xy] : 0; top_type = h->slice_table[top_xy ] < 255 ? s->current_picture.mb_type[top_xy] : 0; @@ -609,7 +607,6 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][12]; h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][11]; - h->top_cbp= h->cbp_table[top_xy]; }else{ h->non_zero_count_cache[4+8*0]= h->non_zero_count_cache[5+8*0]= @@ -622,25 +619,44 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){ h->non_zero_count_cache[1+8*3]= h->non_zero_count_cache[2+8*3]= h->pps.cabac && !IS_INTRA(mb_type) ? 0 : 64; - if(IS_INTRA(mb_type)) h->top_cbp= 0x1C0; - else h->top_cbp= 0; } - + for (i=0; i<2; i++) { if(left_type[i]){ h->non_zero_count_cache[3+8*1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[0+2*i]]; h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[1+2*i]]; h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count[left_xy[i]][left_block[4+2*i]]; h->non_zero_count_cache[0+8*4 + 8*i]= h->non_zero_count[left_xy[i]][left_block[5+2*i]]; - h->left_cbp= h->cbp_table[left_xy[i]]; //FIXME interlacing }else{ h->non_zero_count_cache[3+8*1 + 2*8*i]= h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count_cache[0+8*4 + 8*i]= h->pps.cabac && !IS_INTRA(mb_type) ? 0 : 64; - - if(IS_INTRA(mb_type)) h->left_cbp= 0x1C0;//FIXME interlacing - else h->left_cbp= 0; + } + } + + if( h->pps.cabac ) { + // top_cbp + if(top_type) { + h->top_cbp = h->cbp_table[top_xy]; + } else if(IS_INTRA(mb_type)) { + h->top_cbp = 0x1C0; + } else { + h->top_cbp = 0; + } + // left_cbp + if (left_type[0]) { + h->left_cbp = h->cbp_table[left_xy[0]] & 0x1f0; + } else if(IS_INTRA(mb_type)) { + h->left_cbp = 0x1C0; + } else { + h->left_cbp = 0; + } + if (left_type[0]) { + h->left_cbp |= ((h->cbp_table[left_xy[0]]>>((left_block[0]&(~1))+1))&0x1) << 1; + } + if (left_type[1]) { + h->left_cbp |= ((h->cbp_table[left_xy[1]]>>((left_block[2]&(~1))+1))&0x1) << 3; } } @@ -4359,8 +4375,11 @@ decode_intra_mb: } for(list=0; list<2; list++){ - const int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list]; + int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list]; if(ref_count == 0) continue; + if (h->mb_aff_frame && h->mb_field_decoding_flag) { + ref_count <<= 1; + } for(i=0; i<4; i++){ if(IS_DIRECT(h->sub_mb_type[i])) continue; if(IS_DIR(h->sub_mb_type[i], 0, list)){ @@ -4614,6 +4633,25 @@ decode_intra_mb: return 0; } +static int decode_cabac_field_decoding_flag(H264Context *h) { + MpegEncContext * const s = &h->s; + const int mb_x = s->mb_x; + const int mb_y = s->mb_y & ~1; + const int mba_xy = mb_x - 1 + mb_y *s->mb_stride; + const int mbb_xy = mb_x + (mb_y-2)*s->mb_stride; + + unsigned int ctx = 0; + + if( h->slice_table[mba_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) ) { + ctx += 1; + } + if( h->slice_table[mbb_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) ) { + ctx += 1; + } + + return get_cabac( &h->cabac, &h->cabac_state[70 + ctx] ); +} + static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_slice) { uint8_t *state= &h->cabac_state[ctx_base]; int mb_type; @@ -4757,10 +4795,8 @@ static int decode_cabac_mb_intra4x4_pred_mode( H264Context *h, int pred_mode ) { } static int decode_cabac_mb_chroma_pre_mode( H264Context *h) { - MpegEncContext * const s = &h->s; - const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; - const int mba_xy = mb_xy - 1; - const int mbb_xy = mb_xy - s->mb_stride; + const int mba_xy = h->left_mb_xy[0]; + const int mbb_xy = h->top_mb_xy; int ctx = 0; @@ -4797,16 +4833,13 @@ static const uint8_t block_idx_xy[4][4] = { static int decode_cabac_mb_cbp_luma( H264Context *h) { MpegEncContext * const s = &h->s; - const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; int cbp = 0; int i8x8; - h->cbp_table[mb_xy] = 0; /* FIXME aaahahahah beurk */ - for( i8x8 = 0; i8x8 < 4; i8x8++ ) { - int mba_xy = -1; - int mbb_xy = -1; + int cbp_a = -1; + int cbp_b = -1; int x, y; int ctx = 0; @@ -4814,40 +4847,35 @@ static int decode_cabac_mb_cbp_luma( H264Context *h) { y = block_idx_y[4*i8x8]; if( x > 0 ) - mba_xy = mb_xy; - else if( s->mb_x > 0 ) { - mba_xy = mb_xy - 1; - if (h->slice_table[mba_xy] != h->slice_num) { - mba_xy = -1; - } + cbp_a = cbp; + else if( s->mb_x > 0 && (h->slice_table[h->left_mb_xy[0]] == h->slice_num)) { + cbp_a = h->left_cbp; + tprintf("cbp_a = left_cbp = %x\n", cbp_a); } if( y > 0 ) - mbb_xy = mb_xy; - else if( s->mb_y > 0 ) { - mbb_xy = mb_xy - s->mb_stride; - if (h->slice_table[mbb_xy] != h->slice_num) { - mbb_xy = -1; - } + cbp_b = cbp; + else if( s->mb_y > 0 && (h->slice_table[h->top_mb_xy] == h->slice_num)) { + cbp_b = h->top_cbp; + tprintf("cbp_b = top_cbp = %x\n", cbp_b); } /* No need to test for skip as we put 0 for skip block */ /* No need to test for IPCM as we put 1 for IPCM block */ - if( mba_xy >= 0 ) { + if( cbp_a >= 0 ) { int i8x8a = block_idx_xy[(x-1)&0x03][y]/4; - if( ((h->cbp_table[mba_xy] >> i8x8a)&0x01) == 0 ) + if( ((cbp_a >> i8x8a)&0x01) == 0 ) ctx++; } - if( mbb_xy >= 0 ) { + if( cbp_b >= 0 ) { int i8x8b = block_idx_xy[x][(y-1)&0x03]/4; - if( ((h->cbp_table[mbb_xy] >> i8x8b)&0x01) == 0 ) + if( ((cbp_b >> i8x8b)&0x01) == 0 ) ctx += 2; } if( get_cabac( &h->cabac, &h->cabac_state[73 + ctx] ) ) { cbp |= 1 << i8x8; - h->cbp_table[mb_xy] = cbp; /* FIXME aaahahahah beurk */ } } return cbp; @@ -5021,6 +5049,8 @@ static int inline get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int qp, int max_coeff) { const int mb_xy = h->s.mb_x + h->s.mb_y*h->s.mb_stride; const uint16_t *qmul= dequant_coeff[qp]; + static const int significant_coeff_flag_field_offset[2] = { 105, 277 }; + static const int last_significant_coeff_flag_field_offset[2] = { 166, 338 }; static const int significant_coeff_flag_offset[5] = { 0, 15, 29, 44, 47 }; static const int coeff_abs_level_m1_offset[5] = {227+ 0, 227+10, 227+20, 227+30, 227+39 }; @@ -5050,9 +5080,9 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat } for(last= 0; last < max_coeff - 1; last++) { - if( get_cabac( &h->cabac, &h->cabac_state[105+significant_coeff_flag_offset[cat]+last] )) { + if( get_cabac( &h->cabac, &h->cabac_state[significant_coeff_flag_field_offset[h->mb_field_decoding_flag]+significant_coeff_flag_offset[cat]+last] )) { index[coeff_count++] = last; - if( get_cabac( &h->cabac, &h->cabac_state[166+significant_coeff_flag_offset[cat]+last] ) ) { + if( get_cabac( &h->cabac, &h->cabac_state[last_significant_coeff_flag_field_offset[h->mb_field_decoding_flag]+significant_coeff_flag_offset[cat]+last] ) ) { last= max_coeff; break; } @@ -5133,11 +5163,6 @@ static int decode_mb_cabac(H264Context *h) { s->dsp.clear_blocks(h->mb); //FIXME avoid if allready clear (move after skip handlong?) - if( h->sps.mb_aff ) { - av_log( h->s.avctx, AV_LOG_ERROR, "Fields not supported with CABAC\n" ); - return -1; - } - tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); if( h->slice_type != I_TYPE && h->slice_type != SI_TYPE ) { /* read skip flags */ @@ -5152,6 +5177,12 @@ static int decode_mb_cabac(H264Context *h) { } } + if(h->mb_aff_frame){ + if ( ((s->mb_y&1) == 0) || h->prev_mb_skiped) + h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h); + }else + h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME); + h->prev_mb_skiped = 0; if( ( mb_type = decode_cabac_mb_type( h ) ) < 0 ) { @@ -5183,10 +5214,8 @@ decode_intra_mb: h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode; mb_type= i_mb_type_info[mb_type].type; } -#if 0 if(h->mb_field_decoding_flag) mb_type |= MB_TYPE_INTERLACED; -#endif s->current_picture.mb_type[mb_xy]= mb_type; h->slice_table[ mb_xy ]= h->slice_num; |