diff options
author | Clément Bœsch <u@pkh.me> | 2016-06-12 13:24:27 +0200 |
---|---|---|
committer | Clément Bœsch <u@pkh.me> | 2016-06-12 13:26:52 +0200 |
commit | 1534ef87c74cc66a117bf61c467641c2129bc964 (patch) | |
tree | 68e36bf8432b8a5bd1cd9cc6187d874e0978b1a4 /libavcodec/h264.c | |
parent | 1a57b464cf1687d4571a075c99b6ac36a60f4480 (diff) | |
parent | 3176217c60ca7828712985092d9102d331ea4f3d (diff) | |
download | ffmpeg-1534ef87c74cc66a117bf61c467641c2129bc964.tar.gz |
Merge commit '3176217c60ca7828712985092d9102d331ea4f3d'
* commit '3176217c60ca7828712985092d9102d331ea4f3d':
h264: decouple h264_ps from the h264 decoder
Main changes:
- a local GetBitContext is created for the various
ff_h264_decode_seq_parameter_set() attempts
- just like the old code, remove_sps() is adjusted so it doesn't remove
the pps.
Fixes decode with Ticket #631
http://ffmpeg.org/pipermail/ffmpeg-user/attachments/20111108/dae58f17/attachment.mp4
but see next point as well.
- ff_h264_update_thread_context() is updated to work even when SPS
isn't set as it breaks current skip_frame code. This makes sure we
can still decode the sample from ticket #631 without the need for
-flags2 +chunks. (Thanks to Michael)
- keep {sps,pps}_ref pointers that stay alive even when the active
pps/sps get removed from the available lists (patch by michaelni with
additionnal frees in ff_h264_free_context() from mateo)
- added a check on sps in avpriv_h264_has_num_reorder_frames() to fix
crashes with mpegts_with_dvbsubs.ts from Ticket #4074
http://samples.ffmpeg.org/ffmpeg-bugs/trac/ticket4074/mpegts_with_dvbsubs.ts
- in h264_parser.c:h264_parse(), after the ff_h264_decode_extradata() is
called, the pps and sps from the local parser context are updated with
the pps and sps from the used h264context. This fixes fate-flv-demux.
- in h264_slice.c, "PPS changed between slices" error is not triggered
anymore in one condition as it makes fate-h264-xavc-4389 fails with
THREADS=N (Thanks to Michael)
Merged-by: Clément Bœsch <clement@stupeflix.com>
Merged-by: Michael Niedermayer <michael@niedermayer.cc>
Merged-by: Matthieu Bouron <matthieu.bouron@stupeflix.com>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 85 |
1 files changed, 44 insertions, 41 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index c011527b07..0de6d91d77 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -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 ? 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 @@ again: 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; @@ -1225,22 +1223,21 @@ again: if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) goto end; break; - case NAL_SPS: - h->gb = nal->gb; - if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) + case NAL_SPS: { + GetBitContext tmp_gb = nal->gb; + if (ff_h264_decode_seq_parameter_set(&tmp_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) + init_get_bits8(&tmp_gb, nal->raw_data + 1, nal->raw_size - 1); + if (ff_h264_decode_seq_parameter_set(&tmp_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 +1302,10 @@ end: * 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 +1585,13 @@ 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]); + + av_buffer_unref(&h->ps.sps_ref); + av_buffer_unref(&h->ps.pps_ref); ff_h2645_packet_uninit(&h->pkt); } |