# HG changeset patch # User michael # Date 1107485265 0 # Node ID 4d6d056a00c64a46b818e6d9d44576d0b81e4be4 # Parent 69adfbbdcdeb883e58538bcdcc46e62b1394bd65 H.264 multiple slice support in CABAC patch by (Loic (lll+ffmpeg m4x org) 3 more streams of the conformance suite decode to the end instead of failing on an assert (CABACI3_Sony_B.jsv, CABAST3_Sony_E.jsv and CABASTBR3_Sony_B.jsv), they are still false since the first B slice probably because of deblocking in B slices not yet implemented. diff -r 69adfbbdcdeb -r 4d6d056a00c6 h264.c --- a/h264.c Fri Feb 04 02:20:38 2005 +0000 +++ b/h264.c Fri Feb 04 02:47:45 2005 +0000 @@ -3477,24 +3477,31 @@ int first_mb_in_slice, pps_id; int num_ref_idx_active_override_flag; static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; + int slice_type; + int default_ref_list_done = 0; s->current_picture.reference= h->nal_ref_idc != 0; first_mb_in_slice= get_ue_golomb(&s->gb); - h->slice_type= get_ue_golomb(&s->gb); - if(h->slice_type > 9){ + slice_type= get_ue_golomb(&s->gb); + if(slice_type > 9){ av_log(h->s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h->slice_type, s->mb_x, s->mb_y); return -1; } - if(h->slice_type > 4){ - h->slice_type -= 5; + if(slice_type > 4){ + slice_type -= 5; h->slice_type_fixed=1; }else h->slice_type_fixed=0; - h->slice_type= slice_type_map[ h->slice_type ]; - + slice_type= slice_type_map[ slice_type ]; + if (slice_type == I_TYPE + || (h->slice_num != 0 && slice_type == h->slice_type) ) { + default_ref_list_done = 1; + } + h->slice_type= slice_type; + s->pict_type= h->slice_type; // to make a few old func happy, its wrong though pps_id= get_ue_golomb(&s->gb); @@ -3623,7 +3630,7 @@ } } - if(h->slice_num == 0){ + if(!default_ref_list_done){ fill_default_ref_list(h); } @@ -4342,10 +4349,12 @@ if(intra_slice){ 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; int ctx=0; - if( s->mb_x > 0 && !IS_INTRA4x4( s->current_picture.mb_type[mb_xy-1] ) ) + if( h->slice_table[mba_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mba_xy] ) ) ctx++; - if( s->mb_y > 0 && !IS_INTRA4x4( s->current_picture.mb_type[mb_xy-s->mb_stride] ) ) + if( h->slice_table[mbb_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mbb_xy] ) ) ctx++; if( get_cabac( &h->cabac, &state[ctx] ) == 0 ) return 0; /* I4x4 */ @@ -4399,14 +4408,16 @@ } } else if( h->slice_type == B_TYPE ) { 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; int ctx = 0; int bits; - if( s->mb_x > 0 && !IS_SKIP( s->current_picture.mb_type[mb_xy-1] ) - && !IS_DIRECT( s->current_picture.mb_type[mb_xy-1] ) ) + if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mba_xy] ) + && !IS_DIRECT( s->current_picture.mb_type[mba_xy] ) ) ctx++; - if( s->mb_y > 0 && !IS_SKIP( s->current_picture.mb_type[mb_xy-s->mb_stride] ) - && !IS_DIRECT( s->current_picture.mb_type[mb_xy-s->mb_stride] ) ) + if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mbb_xy] ) + && !IS_DIRECT( s->current_picture.mb_type[mbb_xy] ) ) ctx++; if( !get_cabac( &h->cabac, &h->cabac_state[27+ctx] ) ) @@ -4444,9 +4455,9 @@ const int mbb_xy = mb_xy - s->mb_stride; int ctx = 0; - if( s->mb_x > 0 && !IS_SKIP( s->current_picture.mb_type[mba_xy] ) ) + if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mba_xy] )) ctx++; - if( s->mb_y > 0 && !IS_SKIP( s->current_picture.mb_type[mbb_xy] ) ) + if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mbb_xy] )) ctx++; if( h->slice_type == P_TYPE || h->slice_type == SP_TYPE) @@ -4482,10 +4493,10 @@ int ctx = 0; /* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */ - if( s->mb_x > 0 && h->chroma_pred_mode_table[mba_xy] != 0 ) + if( h->slice_table[mba_xy] == h->slice_num && h->chroma_pred_mode_table[mba_xy] != 0 ) ctx++; - if( s->mb_y > 0 && h->chroma_pred_mode_table[mbb_xy] != 0 ) + if( h->slice_table[mbb_xy] == h->slice_num && h->chroma_pred_mode_table[mbb_xy] != 0 ) ctx++; if( get_cabac( &h->cabac, &h->cabac_state[64+ctx] ) == 0 ) @@ -4532,13 +4543,21 @@ if( x > 0 ) mba_xy = mb_xy; - else if( s->mb_x > 0 ) + else if( s->mb_x > 0 ) { mba_xy = mb_xy - 1; + if (h->slice_table[mba_xy] != h->slice_num) { + mba_xy = -1; + } + } if( y > 0 ) mbb_xy = mb_xy; - else if( s->mb_y > 0 ) + 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; + } + } /* No need to test for skip as we put 0 for skip block */ if( mba_xy >= 0 ) { @@ -4589,7 +4608,7 @@ else mbn_xy = s->mb_width - 1 + (s->mb_y-1)*s->mb_stride; - if( mbn_xy >= 0 && h->last_qscale_diff != 0 && ( IS_INTRA16x16(s->current_picture.mb_type[mbn_xy] ) || (h->cbp_table[mbn_xy]&0x3f) ) ) + if( h->last_qscale_diff != 0 && ( IS_INTRA16x16(s->current_picture.mb_type[mbn_xy] ) || (h->cbp_table[mbn_xy]&0x3f) ) ) ctx++; while( get_cabac( &h->cabac, &h->cabac_state[60 + ctx] ) ) {