ffmpeg | branch: master | Clément Bœsch <clem...@stupeflix.com> | Thu Jun 30 10:15:51 2016 +0200| [d407e76c42d5ae79791ff88d3bd5185e10ad6047] | committer: Clément Bœsch
Merge commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85' * commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85': h264: decode the MMCOs into per-slice contexts Merged-by: Clément Bœsch <clem...@stupeflix.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d407e76c42d5ae79791ff88d3bd5185e10ad6047 --- libavcodec/h264.h | 9 ++++++--- libavcodec/h264_refs.c | 44 +++++++++++++------------------------------- libavcodec/h264_slice.c | 21 ++++++++++----------- 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/libavcodec/h264.h b/libavcodec/h264.h index f0e4573..84cf59e 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -453,6 +453,9 @@ typedef struct H264SliceContext { CABACContext cabac; uint8_t cabac_state[1024]; int cabac_init_idc; + + MMCO mmco[MAX_MMCO_COUNT]; + int nb_mmco; } H264SliceContext; /** @@ -728,10 +731,10 @@ void ff_h264_remove_all_refs(H264Context *h); */ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count); -int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, - int first_slice); +int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl, + GetBitContext *gb); -int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice); +int ff_generate_sliding_window_mmcos(const H264Context *h, H264SliceContext *sl); void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl); int ff_h264_decode_init(AVCodecContext *avctx); diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index e7ae447..c710012 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -601,9 +601,10 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos) return 0; } -int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) +int ff_generate_sliding_window_mmcos(const H264Context *h, + H264SliceContext *sl) { - MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; + MMCO *mmco = sl->mmco; int nb_mmco = 0, i = 0; if (h->short_ref_count && @@ -620,16 +621,8 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) } } - if (first_slice) { - h->nb_mmco = nb_mmco; - } else if (!first_slice && nb_mmco >= 0 && - (nb_mmco != h->nb_mmco || - (i = check_opcodes(h->mmco, mmco_temp, nb_mmco)))) { - av_log(h->avctx, AV_LOG_ERROR, - "Inconsistent MMCO state between slices [%d, %d]\n", - nb_mmco, h->nb_mmco); - return AVERROR_INVALIDDATA; - } + sl->nb_mmco = nb_mmco; + return 0; } @@ -842,11 +835,11 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; } -int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, - int first_slice) +int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl, + GetBitContext *gb) { int i, ret; - MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp; + MMCO *mmco = sl->mmco; int nb_mmco = 0; if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields @@ -902,26 +895,15 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, } nb_mmco = i; } else { - if (first_slice) { - ret = ff_generate_sliding_window_mmcos(h, first_slice); - if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) - return ret; - } + ret = ff_generate_sliding_window_mmcos(h, sl); + if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) + return ret; nb_mmco = -1; } } - if (first_slice && nb_mmco != -1) { - memcpy(h->mmco, mmco_temp, sizeof(h->mmco)); - h->nb_mmco = nb_mmco; - } else if (!first_slice && nb_mmco >= 0 && - (nb_mmco != h->nb_mmco || - check_opcodes(h->mmco, mmco_temp, nb_mmco))) { - av_log(h->avctx, AV_LOG_ERROR, - "Inconsistent MMCO state between slices [%d, %d]\n", - nb_mmco, h->nb_mmco); - return AVERROR_INVALIDDATA; - } + if (nb_mmco != -1) + sl->nb_mmco = nb_mmco; return 0; } diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index a63c9b9..cb52b77 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1421,10 +1421,12 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag; ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); - ret = ff_generate_sliding_window_mmcos(h, 1); + + ret = ff_generate_sliding_window_mmcos(h, sl); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; - ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco); + + ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; /* Error concealment: If a ref is missing, copy the previous ref @@ -1575,15 +1577,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count, sl->slice_type_nos, &sl->pwt, h->avctx); - // If frame-mt is enabled, only update mmco tables for the first slice - // in a field. Subsequent slices can temporarily clobber h->nb_mmco - // or h->mmco, which will cause ref list mix-ups and decoding errors - // further down the line. This may break decoding if the first slice is - // corrupt, thus we only do this if frame-mt is enabled. if (h->nal_ref_idc) { - ret = ff_h264_decode_ref_pic_marking(h, &sl->gb, - !(h->avctx->active_thread_type & FF_THREAD_FRAME) || - h->current_slice == 0); + ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } @@ -1674,10 +1669,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) sl->resync_mb_y = sl->mb_y = sl->mb_y + 1; av_assert1(sl->mb_y < h->mb_height); - if (!h->setup_finished) + if (!h->setup_finished) { ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc, h->ps.sps, &h->poc, h->picture_structure, h->nal_ref_idc); + memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco)); + h->nb_mmco = sl->nb_mmco; + } + ret = ff_h264_build_ref_list(h, sl); if (ret < 0) return ret; ====================================================================== diff --cc libavcodec/h264_refs.c index e7ae447,dae5565..c710012 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@@ -601,13 -536,16 +601,14 @@@ static int check_opcodes(MMCO *mmco1, M return 0; } - int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) + int ff_generate_sliding_window_mmcos(const H264Context *h, + H264SliceContext *sl) { - MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; + MMCO *mmco = sl->mmco; int nb_mmco = 0, i = 0; - assert(h->long_ref_count + h->short_ref_count <= h->ps.sps->ref_frame_count); - if (h->short_ref_count && - h->long_ref_count + h->short_ref_count == h->ps.sps->ref_frame_count && + h->long_ref_count + h->short_ref_count >= h->ps.sps->ref_frame_count && !(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) { mmco[0].opcode = MMCO_SHORT2UNUSED; mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num; diff --cc libavcodec/h264_slice.c index a63c9b9,6967edb..cb52b77 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@@ -1418,13 -1199,14 +1418,15 @@@ static int h264_slice_header_parse(H264 h->poc.prev_frame_num++; h->poc.prev_frame_num %= 1 << sps->log2_max_frame_num; h->cur_pic_ptr->frame_num = h->poc.prev_frame_num; + h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag; ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); - ret = ff_generate_sliding_window_mmcos(h, 1); + + ret = ff_generate_sliding_window_mmcos(h, sl); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; - ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco); + + ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; /* Error concealment: If a ref is missing, copy the previous ref @@@ -1573,17 -1342,10 +1575,10 @@@ (pps->weighted_bipred_idc == 1 && sl->slice_type_nos == AV_PICTURE_TYPE_B)) ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count, - sl->slice_type_nos, &sl->pwt); + sl->slice_type_nos, &sl->pwt, h->avctx); - // If frame-mt is enabled, only update mmco tables for the first slice - // in a field. Subsequent slices can temporarily clobber h->nb_mmco - // or h->mmco, which will cause ref list mix-ups and decoding errors - // further down the line. This may break decoding if the first slice is - // corrupt, thus we only do this if frame-mt is enabled. if (h->nal_ref_idc) { - ret = ff_h264_decode_ref_pic_marking(h, &sl->gb, - !(h->avctx->active_thread_type & FF_THREAD_FRAME) || - h->current_slice == 0); + ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } @@@ -1672,9 -1434,9 +1667,9 @@@ int ff_h264_decode_slice_header(H264Con FIELD_OR_MBAFF_PICTURE(h); if (h->picture_structure == PICT_BOTTOM_FIELD) sl->resync_mb_y = sl->mb_y = sl->mb_y + 1; - assert(sl->mb_y < h->mb_height); + av_assert1(sl->mb_y < h->mb_height); - if (!h->setup_finished) + if (!h->setup_finished) { ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc, h->ps.sps, &h->poc, h->picture_structure, h->nal_ref_idc); _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog