ffmpeg | branch: master | Clément Bœsch <u...@pkh.me> | Thu Jul 14 19:41:37 2016 +0200| [2c138b2c9b0ec92d9baf704498b1a32a989d03c5] | committer: Clément Bœsch
Merge commit 'b25cd7540e7cba9868edc13817c0ce1ddef90ffc' * commit 'b25cd7540e7cba9868edc13817c0ce1ddef90ffc': h264: pass a H2645NAL to slice header decoding Merged-by: Clément Bœsch <u...@pkh.me> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2c138b2c9b0ec92d9baf704498b1a32a989d03c5 --- libavcodec/h264.c | 2 +- libavcodec/h264.h | 3 ++- libavcodec/h264_slice.c | 29 ++++++++++++++++------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 8eb3b13..f79735b 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -951,7 +951,7 @@ again: case NAL_SLICE: sl->gb = nal->gb; - if ((err = ff_h264_decode_slice_header(h, sl))) + if ((err = ff_h264_decode_slice_header(h, sl, nal))) break; if (h->sei.recovery_point.recovery_frame_cnt >= 0) { diff --git a/libavcodec/h264.h b/libavcodec/h264.h index ed8498a..1e3dfd5 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -994,7 +994,8 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl); void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height); -int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl); +int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, + const H2645NAL *nal); #define SLICE_SINGLETHREAD 1 #define SLICE_SKIPED 2 diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 444d281..2562041 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1127,7 +1127,8 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl * slice in a field (or a frame). It decides whether we are decoding a new frame * or a second field in a pair and does the necessary setup. */ -static int h264_field_start(H264Context *h, const H264SliceContext *sl) +static int h264_field_start(H264Context *h, const H264SliceContext *sl, + const H2645NAL *nal) { int i; const SPS *sps; @@ -1138,7 +1139,7 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl) last_pic_droppable = h->droppable; last_pic_structure = h->picture_structure; - h->droppable = (h->nal_ref_idc == 0); + h->droppable = (nal->ref_idc == 0); h->picture_structure = sl->picture_structure; /* Shorten frame num gaps so we don't have to allocate reference @@ -1322,7 +1323,8 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl) return 0; } -static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) +static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl, + const H2645NAL *nal) { const SPS *sps; const PPS *pps; @@ -1400,7 +1402,7 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) sl->slice_type = slice_type; sl->slice_type_nos = slice_type & 3; - if (h->nal_unit_type == NAL_IDR_SLICE && + if (nal->type == NAL_IDR_SLICE && sl->slice_type_nos != AV_PICTURE_TYPE_I) { av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n"); return AVERROR_INVALIDDATA; @@ -1473,7 +1475,7 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) mb_aff_frame = 0; last_mb_aff_frame = h->mb_aff_frame; - droppable = h->nal_ref_idc == 0; + droppable = nal->ref_idc == 0; if (sps->frame_mbs_only_flag) { picture_structure = PICT_FRAME; } else { @@ -1522,7 +1524,7 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) h->max_pic_num = 1 << (sps->log2_max_frame_num + 1); } - if (h->nal_unit_type == NAL_IDR_SLICE) + if (nal->type == NAL_IDR_SLICE) get_ue_golomb_long(&sl->gb); /* idr_pic_id */ if (sps->poc_type == 0) { @@ -1584,7 +1586,7 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) sl->slice_type_nos, &sl->pwt, h->avctx); sl->explicit_ref_marking = 0; - if (h->nal_ref_idc) { + if (nal->ref_idc) { ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; @@ -1655,16 +1657,17 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) * * @return 0 if okay, <0 if an error occurred */ -int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) +int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, + const H2645NAL *nal) { int i, j, ret = 0; - ret = h264_slice_header_parse(h, sl); + ret = h264_slice_header_parse(h, sl, nal); if (ret) // can not be ret<0 because of SLICE_SKIPED, SLICE_SINGLETHREAD, ... return ret; if (h->current_slice == 0) { - ret = h264_field_start(h, sl); + ret = h264_field_start(h, sl, nal); if (ret < 0) return ret; } @@ -1684,7 +1687,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) 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); + h->ps.sps, &h->poc, h->picture_structure, nal->ref_idc); memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco)); h->nb_mmco = sl->nb_mmco; @@ -1716,7 +1719,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) || (h->avctx->skip_loop_filter >= AVDISCARD_NONREF && - h->nal_ref_idc == 0)) + nal->ref_idc == 0)) sl->deblocking_filter = 0; if (sl->deblocking_filter == 1 && h->max_contexts > 1) { @@ -1787,7 +1790,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) sl->mb_y * h->mb_width + sl->mb_x, av_get_picture_type_char(sl->slice_type), sl->slice_type_fixed ? " fix" : "", - h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", + nal->type == NAL_IDR_SLICE ? " IDR" : "", h->poc.frame_num, h->cur_pic_ptr->field_poc[0], h->cur_pic_ptr->field_poc[1], ====================================================================== diff --cc libavcodec/h264.c index 8eb3b13,b96b95a..f79735b --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@@ -951,28 -851,18 +951,28 @@@ again case NAL_SLICE: sl->gb = nal->gb; - if ((err = ff_h264_decode_slice_header(h, sl))) + if ((err = ff_h264_decode_slice_header(h, sl, nal))) break; - if (h->sei.recovery_point.recovery_frame_cnt >= 0 && h->recovery_frame < 0) { - h->recovery_frame = (h->poc.frame_num + h->sei.recovery_point.recovery_frame_cnt) & - ((1 << h->ps.sps->log2_max_frame_num) - 1); + if (h->sei.recovery_point.recovery_frame_cnt >= 0) { + const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt; + + if (h->poc.frame_num != sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) + h->valid_recovery_point = 1; + + if ( h->recovery_frame < 0 + || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > sei_recovery_frame_cnt) { + h->recovery_frame = av_mod_uintp2(h->poc.frame_num + sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num); + + if (!h->valid_recovery_point) + h->recovery_frame = h->poc.frame_num; + } } - h->cur_pic_ptr->f->key_frame |= - (nal->type == NAL_IDR_SLICE) || (h->sei.recovery_point.recovery_frame_cnt >= 0); + h->cur_pic_ptr->f->key_frame |= (nal->type == NAL_IDR_SLICE); - if (nal->type == NAL_IDR_SLICE || h->recovery_frame == h->poc.frame_num) { + if (nal->type == NAL_IDR_SLICE || + (h->recovery_frame == h->poc.frame_num && nal->ref_idc)) { h->recovery_frame = -1; h->cur_pic_ptr->recovered = 1; } diff --cc libavcodec/h264.h index ed8498a,6cd2506..1e3dfd5 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@@ -994,10 -929,8 +994,11 @@@ int ff_h264_slice_context_init(H264Cont void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height); - int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl); + int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, + const H2645NAL *nal); +#define SLICE_SINGLETHREAD 1 +#define SLICE_SKIPED 2 + int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count); int ff_h264_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); diff --cc libavcodec/h264_slice.c index 444d281,17608b4..2562041 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@@ -1127,9 -988,9 +1127,10 @@@ static int h264_init_ps(H264Context *h * slice in a field (or a frame). It decides whether we are decoding a new frame * or a second field in a pair and does the necessary setup. */ - static int h264_field_start(H264Context *h, const H264SliceContext *sl) + static int h264_field_start(H264Context *h, const H264SliceContext *sl, + const H2645NAL *nal) { + int i; const SPS *sps; int last_pic_structure, last_pic_droppable, ret; @@@ -1470,10 -1245,8 +1472,10 @@@ static int h264_slice_header_parse(H264 h->poc.frame_num = frame_num; sl->mb_mbaff = 0; + mb_aff_frame = 0; + last_mb_aff_frame = h->mb_aff_frame; - droppable = h->nal_ref_idc == 0; + droppable = nal->ref_idc == 0; if (sps->frame_mbs_only_flag) { picture_structure = PICT_FRAME; } else { @@@ -1522,8 -1288,8 +1524,8 @@@ h->max_pic_num = 1 << (sps->log2_max_frame_num + 1); } - if (h->nal_unit_type == NAL_IDR_SLICE) + if (nal->type == NAL_IDR_SLICE) - get_ue_golomb(&sl->gb); /* idr_pic_id */ + get_ue_golomb_long(&sl->gb); /* idr_pic_id */ if (sps->poc_type == 0) { int poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); @@@ -1581,10 -1347,10 +1583,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); sl->explicit_ref_marking = 0; - if (h->nal_ref_idc) { + if (nal->ref_idc) { ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; @@@ -1659,8 -1426,8 +1662,8 @@@ int ff_h264_decode_slice_header(H264Con { int i, j, ret = 0; - ret = h264_slice_header_parse(h, sl); + ret = h264_slice_header_parse(h, sl, nal); - if (ret < 0) + if (ret) // can not be ret<0 because of SLICE_SKIPED, SLICE_SINGLETHREAD, ... return ret; if (h->current_slice == 0) { @@@ -1716,10 -1481,10 +1719,10 @@@ (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) || (h->avctx->skip_loop_filter >= AVDISCARD_NONREF && - h->nal_ref_idc == 0)) + nal->ref_idc == 0)) sl->deblocking_filter = 0; - if (sl->deblocking_filter == 1 && h->nb_slice_ctx > 1) { + if (sl->deblocking_filter == 1 && h->max_contexts > 1) { if (h->avctx->flags2 & AV_CODEC_FLAG2_FAST) { /* Cheat slightly for speed: * Do not bother to deblock across slices. */ _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog