@@ -60,7 +60,7 @@ const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 };
int avpriv_h264_has_num_reorder_frames (AVCodecContext *avctx)
{
H264Context *h = avctx->priv_data ;
return h ? h->sps . num_reorder_frames : 0 ;
return h ? h->ps . sps -> num_reorder_frames : 0 ;
}
static void h264_er_decode_mb (void *opaque, int ref, int mv_dir, int mv_type,
@@ -224,9 +224,6 @@ int ff_h264_alloc_tables(H264Context *h)
h->mb2br_xy [mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * h->mb_stride )));
}
if (!h->dequant4_coeff [0 ])
ff_h264_init_dequant_tables (h);
return 0 ;
fail:
@@ -425,7 +422,6 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
h->backup_width = -1 ;
h->backup_height = -1 ;
h->backup_pix_fmt = AV_PIX_FMT_NONE;
h->dequant_coeff_pps = -1 ;
h->current_sps_id = -1 ;
h->cur_chroma_format_idc = -1 ;
@@ -514,9 +510,9 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
}
}
if (h->sps . bitstream_restriction_flag &&
h->avctx ->has_b_frames < h->sps . num_reorder_frames ) {
h->avctx ->has_b_frames = h->sps . num_reorder_frames ;
if (h->ps . sps && h-> ps . sps -> bitstream_restriction_flag &&
h->avctx ->has_b_frames < h->ps . sps -> num_reorder_frames ) {
h->avctx ->has_b_frames = h->ps . sps -> num_reorder_frames ;
h->low_delay = 0 ;
}
@@ -567,6 +563,7 @@ static int decode_init_thread_copy(AVCodecContext *avctx)
*/
static void decode_postinit (H264Context *h, int setup_finished)
{
const SPS *sps = h->ps .sps ;
H264Picture *out = h->cur_pic_ptr ;
H264Picture *cur = h->cur_pic_ptr ;
int i, pics, out_of_order, out_idx;
@@ -596,7 +593,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
/* Prioritize picture timing SEI information over used
* decoding process if it exists. */
if (h-> sps . pic_struct_present_flag ) {
if (sps-> pic_struct_present_flag ) {
switch (h->sei_pic_struct ) {
case SEI_PIC_STRUCT_FRAME:
break ;
@@ -640,7 +637,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
/* Derive top_field_first from field pocs. */
cur->f ->top_field_first = cur->field_poc [0 ] < cur->field_poc [1 ];
} else {
if (h-> sps . pic_struct_present_flag ) {
if (sps-> pic_struct_present_flag ) {
/* Use picture timing SEI information. Even if it is a
* information of a past frame, better than nothing. */
if (h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM ||
@@ -737,9 +734,9 @@ static void decode_postinit(H264Context *h, int setup_finished)
// FIXME do something with unavailable reference frames
/* Sort B-frames into display order */
if (h-> sps . bitstream_restriction_flag ||
if (sps-> bitstream_restriction_flag ||
h->avctx ->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
h->avctx ->has_b_frames = FFMAX (h->avctx ->has_b_frames , h-> sps . num_reorder_frames );
h->avctx ->has_b_frames = FFMAX (h->avctx ->has_b_frames , sps-> num_reorder_frames );
}
h->low_delay = !h->avctx ->has_b_frames ;
@@ -762,7 +759,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
h->last_pocs [i] = INT_MIN;
h->last_pocs [0 ] = cur->poc ;
cur->mmco_reset = 1 ;
} else if (h->avctx ->has_b_frames < out_of_order && !h-> sps . bitstream_restriction_flag ){
} else if (h->avctx ->has_b_frames < out_of_order && !sps-> bitstream_restriction_flag ){
av_log (h->avctx , AV_LOG_INFO, " Increasing reorder buffer to %d \n " , out_of_order);
h->avctx ->has_b_frames = out_of_order;
h->low_delay = 0 ;
@@ -894,15 +891,16 @@ static void flush_dpb(AVCodecContext *avctx)
int ff_init_poc (H264Context *h, int pic_field_poc[2 ], int *pic_poc)
{
const int max_frame_num = 1 << h->sps .log2_max_frame_num ;
const SPS *sps = h->ps .sps ;
const int max_frame_num = 1 << sps->log2_max_frame_num ;
int field_poc[2 ];
h->frame_num_offset = h->prev_frame_num_offset ;
if (h->frame_num < h->prev_frame_num )
h->frame_num_offset += max_frame_num;
if (h-> sps . poc_type == 0 ) {
const int max_poc_lsb = 1 << h-> sps . log2_max_poc_lsb ;
if (sps-> poc_type == 0 ) {
const int max_poc_lsb = 1 << sps-> log2_max_poc_lsb ;
if (h->poc_lsb < h->prev_poc_lsb &&
h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2 )
@@ -916,11 +914,11 @@ int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
field_poc[1 ] = h->poc_msb + h->poc_lsb ;
if (h->picture_structure == PICT_FRAME)
field_poc[1 ] += h->delta_poc_bottom ;
} else if (h-> sps . poc_type == 1 ) {
} else if (sps-> poc_type == 1 ) {
int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
int i;
if (h-> sps . poc_cycle_length != 0 )
if (sps-> poc_cycle_length != 0 )
abs_frame_num = h->frame_num_offset + h->frame_num ;
else
abs_frame_num = 0 ;
@@ -929,25 +927,25 @@ int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
abs_frame_num--;
expected_delta_per_poc_cycle = 0 ;
for (i = 0 ; i < h-> sps . poc_cycle_length ; i++)
for (i = 0 ; i < sps-> poc_cycle_length ; i++)
// FIXME integrate during sps parse
expected_delta_per_poc_cycle += h-> sps . offset_for_ref_frame [i];
expected_delta_per_poc_cycle += sps-> offset_for_ref_frame [i];
if (abs_frame_num > 0 ) {
int poc_cycle_cnt = (abs_frame_num - 1 ) / h-> sps . poc_cycle_length ;
int frame_num_in_poc_cycle = (abs_frame_num - 1 ) % h-> sps . poc_cycle_length ;
int poc_cycle_cnt = (abs_frame_num - 1 ) / sps-> poc_cycle_length ;
int frame_num_in_poc_cycle = (abs_frame_num - 1 ) % sps-> poc_cycle_length ;
expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle;
for (i = 0 ; i <= frame_num_in_poc_cycle; i++)
expectedpoc = expectedpoc + h-> sps . offset_for_ref_frame [i];
expectedpoc = expectedpoc + sps-> offset_for_ref_frame [i];
} else
expectedpoc = 0 ;
if (h->nal_ref_idc == 0 )
expectedpoc = expectedpoc + h-> sps . offset_for_non_ref_pic ;
expectedpoc = expectedpoc + sps-> offset_for_non_ref_pic ;
field_poc[0 ] = expectedpoc + h->delta_poc [0 ];
field_poc[1 ] = field_poc[0 ] + h-> sps . offset_for_top_to_bottom_field ;
field_poc[1 ] = field_poc[0 ] + sps-> offset_for_top_to_bottom_field ;
if (h->picture_structure == PICT_FRAME)
field_poc[1 ] += h->delta_poc [1 ];
@@ -977,7 +975,7 @@ int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
*
* @return profile as defined by FF_PROFILE_H264_*
*/
int ff_h264_get_profile (SPS *sps)
int ff_h264_get_profile (const SPS *sps)
{
int profile = sps->profile_idc ;
@@ -1154,8 +1152,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
h->valid_recovery_point = 1 ;
if ( h->recovery_frame < 0
|| av_mod_uintp2 (h->recovery_frame - h->frame_num , h->sps . log2_max_frame_num ) > h->sei_recovery_frame_cnt ) {
h->recovery_frame = av_mod_uintp2 (h->frame_num + h->sei_recovery_frame_cnt , h->sps . log2_max_frame_num );
|| av_mod_uintp2 (h->recovery_frame - h->frame_num , h->ps . sps -> log2_max_frame_num ) > h->sei_recovery_frame_cnt ) {
h->recovery_frame = av_mod_uintp2 (h->frame_num + h->sei_recovery_frame_cnt , h->ps . sps -> log2_max_frame_num );
if (!h->valid_recovery_point )
h->recovery_frame = h->frame_num ;
@@ -1226,21 +1224,19 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
goto end;
break ;
case NAL_SPS:
h->gb = nal->gb ;
if (ff_h264_decode_seq_parameter_set (h, 0 ) >= 0 )
if (ff_h264_decode_seq_parameter_set (&nal->gb , avctx, &h->ps , 0 ) >= 0 )
break ;
av_log (h->avctx , AV_LOG_DEBUG,
" SPS decoding failure, trying again with the complete NAL\n " );
init_get_bits8 (&h->gb , nal->raw_data + 1 , nal->raw_size - 1 );
if (ff_h264_decode_seq_parameter_set (h , 0 ) >= 0 )
if (ff_h264_decode_seq_parameter_set (&nal-> gb , avctx, &h-> ps , 0 ) >= 0 )
break ;
h->gb = nal->gb ;
ff_h264_decode_seq_parameter_set (h, 1 );
ff_h264_decode_seq_parameter_set (&nal->gb , avctx, &h->ps , 1 );
break ;
case NAL_PPS:
h-> gb = nal->gb ;
ret = ff_h264_decode_picture_parameter_set (h, nal->size_bits );
ret = ff_h264_decode_picture_parameter_set (& nal->gb , avctx, &h-> ps ,
nal->size_bits );
if (ret < 0 && (h->avctx ->err_recognition & AV_EF_EXPLODE))
goto end;
break ;
@@ -1305,7 +1301,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
* past end by one (callers fault) and resync_mb_y != 0
* causes problems for the first MB line, too.
*/
if (!FIELD_PICTURE (h) && h->current_slice && !h->sps .new && h->enable_er ) {
if (!FIELD_PICTURE (h) && h->current_slice &&
h->ps .sps == (const SPS*)h->ps .sps_list [h->ps .pps ->sps_id ]->data &&
h->enable_er ) {
H264SliceContext *sl = h->slice_ctx ;
int use_last_pic = h->last_pic_for_ec .f ->buf [0 ] && !sl->ref_count [0 ];
@@ -1585,10 +1584,10 @@ av_cold void ff_h264_free_context(H264Context *h)
av_freep (&h->a53_caption );
for (i = 0 ; i < MAX_SPS_COUNT; i++)
av_freep ( h->sps_buffers + i );
av_buffer_unref (& h->ps . sps_list [i] );
for (i = 0 ; i < MAX_PPS_COUNT; i++)
av_freep ( h->pps_buffers + i );
av_buffer_unref (& h->ps . pps_list [i] );
ff_h2645_packet_uninit (&h->pkt );
}
Here is a small conflict - the code previously worked by keeping nal->gb unchanged and copying it, allowing various parsing attempts to work on the same GetBitContext.
Now they all act directly on nal->gb, modifying the "original". So instead, there should probably still be a copy of the GetBitContext which ff_h264_decode_seq_parameter_set works on, allowing to use 3 attempts to parse it without modifying the original one.