@ -120,6 +120,75 @@ found:
return i - ( state & 5 ) - 3 * ( state > 7 ) ;
}
static int scan_mmco_reset ( AVCodecParserContext * s )
{
H264Context * h = s - > priv_data ;
h - > slice_type_nos = s - > pict_type & 3 ;
if ( h - > pps . redundant_pic_cnt_present )
get_ue_golomb ( & h - > gb ) ; // redundant_pic_count
if ( ff_set_ref_count ( h ) < 0 )
return AVERROR_INVALIDDATA ;
if ( h - > slice_type_nos ! = AV_PICTURE_TYPE_I ) {
int list ;
for ( list = 0 ; list < h - > list_count ; list + + ) {
if ( get_bits1 ( & h - > gb ) ) {
int index ;
for ( index = 0 ; ; index + + ) {
unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31 ( & h - > gb ) ;
if ( reordering_of_pic_nums_idc < 3 )
get_ue_golomb ( & h - > gb ) ;
else if ( reordering_of_pic_nums_idc > 3 ) {
av_log ( h - > avctx , AV_LOG_ERROR ,
" illegal reordering_of_pic_nums_idc %d \n " ,
reordering_of_pic_nums_idc ) ;
return AVERROR_INVALIDDATA ;
} else
break ;
if ( index > = h - > ref_count [ list ] ) {
av_log ( h - > avctx , AV_LOG_ERROR , " reference count overflow \n " ) ;
return AVERROR_INVALIDDATA ;
}
}
}
}
}
if ( ( h - > pps . weighted_pred & & h - > slice_type_nos = = AV_PICTURE_TYPE_P ) | |
( h - > pps . weighted_bipred_idc = = 1 & & h - > slice_type_nos = = AV_PICTURE_TYPE_B ) )
ff_pred_weight_table ( h ) ;
if ( get_bits1 ( & h - > gb ) ) { // adaptive_ref_pic_marking_mode_flag
int i ;
for ( i = 0 ; i < MAX_MMCO_COUNT ; i + + ) {
MMCOOpcode opcode = get_ue_golomb_31 ( & h - > gb ) ;
if ( opcode > ( unsigned ) MMCO_LONG ) {
av_log ( h - > avctx , AV_LOG_ERROR ,
" illegal memory management control operation %d \n " ,
opcode ) ;
return AVERROR_INVALIDDATA ;
}
if ( opcode = = MMCO_END )
return 0 ;
else if ( opcode = = MMCO_RESET )
return 1 ;
if ( opcode = = MMCO_SHORT2UNUSED | | opcode = = MMCO_SHORT2LONG )
get_ue_golomb ( & h - > gb ) ;
if ( opcode = = MMCO_SHORT2LONG | | opcode = = MMCO_LONG2UNUSED | |
opcode = = MMCO_LONG | | opcode = = MMCO_SET_MAX_LONG )
get_ue_golomb_31 ( & h - > gb ) ;
}
}
return 0 ;
}
/**
* Parse NAL units of found picture and decode some basic information .
*
@ -136,7 +205,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
const uint8_t * buf_end = buf + buf_size ;
unsigned int pps_id ;
unsigned int slice_type ;
int state = - 1 ;
int state = - 1 , got_reset = 0 ;
const uint8_t * ptr ;
int q264 = buf_size > = 4 & & ! memcmp ( " Q264 " , buf , 4 ) ;
int field_poc [ 2 ] ;
@ -180,8 +249,16 @@ static inline int parse_nal_units(AVCodecParserContext *s,
case NAL_SLICE :
case NAL_IDR_SLICE :
// Do not walk the whole buffer just to decode slice header
if ( src_length > 60 )
src_length = 60 ;
if ( state & 0x1f = = NAL_IDR_SLICE | | ( state > > 5 ) & 0x3 = = 0 ) {
/* IDR or disposable slice
* No need to decode many bytes because MMCOs shall not be present . */
if ( src_length > 60 )
src_length = 60 ;
} else {
/* To decode up to MMCOs */
if ( src_length > 1000 )
src_length = 1000 ;
}
break ;
}
ptr = ff_h264_decode_nal ( h , buf , & dst_length , & consumed , src_length ) ;
@ -267,16 +344,33 @@ static inline int parse_nal_units(AVCodecParserContext *s,
h - > delta_poc [ 1 ] = get_se_golomb ( & h - > gb ) ;
}
/* Decode POC of this picture. */
/* Decode POC of this picture.
* The prev_ values needed for decoding POC of the next picture are not set here . */
field_poc [ 0 ] = field_poc [ 1 ] = INT_MAX ;
ff_init_poc ( h , field_poc , & s - > output_picture_number ) ;
/* Continue parsing to check if MMCO_RESET is present.
* FIXME : MMCO_RESET could appear in non - first slice .
* Maybe , we should parse all undisposable non - IDR slice of this
* picture until encountering MMCO_RESET in a slice of it . */
if ( h - > nal_ref_idc & & h - > nal_unit_type ! = NAL_IDR_SLICE ) {
got_reset = scan_mmco_reset ( s ) ;
if ( got_reset < 0 )
return got_reset ;
}
/* Set up the prev_ values for decoding POC of the next picture. */
h - > prev_frame_num = h - > frame_num ;
h - > prev_frame_num_offset = h - > frame_num_offset ;
h - > prev_frame_num = got_reset ? 0 : h - > frame_num ;
h - > prev_frame_num_offset = got_reset ? 0 : h - > frame_num_offset ;
if ( h - > nal_ref_idc ! = 0 ) {
h - > prev_poc_msb = h - > poc_msb ;
h - > prev_poc_lsb = h - > poc_lsb ;
if ( ! got_reset ) {
h - > prev_poc_msb = h - > poc_msb ;
h - > prev_poc_lsb = h - > poc_lsb ;
} else {
h - > prev_poc_msb = 0 ;
h - > prev_poc_lsb =
h - > picture_structure = = PICT_BOTTOM_FIELD ? 0 : field_poc [ 0 ] ;
}
}
if ( h - > sps . pic_struct_present_flag ) {