ffmpeg | branch: master | Clément Bœsch <clem...@stupeflix.com> | Wed Jun 29 14:55:02 2016 +0200| [c54e2740e1f4a8fb7fa4e521755bf4158c4cda51] | committer: Clément Bœsch
Merge commit 'd06e4d8aab9c679b6aea2591d2a9b382df9e5f74' * commit 'd06e4d8aab9c679b6aea2591d2a9b382df9e5f74': h264: start splitting decode_slice_header() Merged-by: Clément Bœsch <clem...@stupeflix.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c54e2740e1f4a8fb7fa4e521755bf4158c4cda51 --- libavcodec/h264_slice.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 45c23c8..cab674f 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1020,22 +1020,14 @@ static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a) } } -/** - * Decode a slice header. - * This will (re)initialize the decoder and call h264_frame_start() as needed. - * - * @param h h264context - * - * @return 0 if okay, <0 if an error occurred - */ -int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) +static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) { const SPS *sps; const PPS *pps; unsigned int first_mb_in_slice; unsigned int pps_id; int ret; - unsigned int slice_type, tmp, i, j; + unsigned int slice_type, tmp, i; int last_pic_structure, last_pic_droppable; int must_reinit; int needs_reinit = 0; @@ -1703,6 +1695,25 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) } } + return 0; +} + +/** + * Decode a slice header. + * This will (re)initialize the decoder and call h264_frame_start() as needed. + * + * @param h h264context + * + * @return 0 if okay, <0 if an error occurred + */ +int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) +{ + int i, j, ret = 0; + + ret = h264_slice_header_parse(h, sl); + if (ret < 0) + return ret; + if (h->avctx->skip_loop_filter >= AVDISCARD_ALL || (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE) || @@ -1726,9 +1737,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) sl->qp_thresh = 15 - FFMIN(sl->slice_alpha_c0_offset, sl->slice_beta_offset) - FFMAX3(0, - pps->chroma_qp_index_offset[0], - pps->chroma_qp_index_offset[1]) + - 6 * (sps->bit_depth_luma - 8); + h->ps.pps->chroma_qp_index_offset[0], + h->ps.pps->chroma_qp_index_offset[1]) + + 6 * (h->ps.sps->bit_depth_luma - 8); sl->slice_num = ++h->current_slice; @@ -1776,14 +1787,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) if (h->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(h->avctx, AV_LOG_DEBUG, - "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n", + "slice:%d %s mb:%d %c%s%s frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n", sl->slice_num, (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"), - first_mb_in_slice, + 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" : "", - pps_id, h->poc.frame_num, + h->poc.frame_num, h->cur_pic_ptr->field_poc[0], h->cur_pic_ptr->field_poc[1], sl->ref_count[0], sl->ref_count[1], ====================================================================== diff --cc libavcodec/h264_slice.c index 45c23c8,404e333..cab674f --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@@ -1003,85 -899,30 +1003,77 @@@ static int h264_slice_header_init(H264C h->context_initialized = 1; return 0; +fail: + ff_h264_free_tables(h); + h->context_initialized = 0; + return ret; +} + +static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a) +{ + switch (a) { + case AV_PIX_FMT_YUVJ420P: return AV_PIX_FMT_YUV420P; + case AV_PIX_FMT_YUVJ422P: return AV_PIX_FMT_YUV422P; + case AV_PIX_FMT_YUVJ444P: return AV_PIX_FMT_YUV444P; + default: + return a; + } } - /** - * Decode a slice header. - * This will (re)initialize the decoder and call h264_frame_start() as needed. - * - * @param h h264context - * - * @return 0 if okay, <0 if an error occurred - */ - int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) + static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) { const SPS *sps; const PPS *pps; unsigned int first_mb_in_slice; unsigned int pps_id; int ret; - unsigned int slice_type, tmp, i, j; + unsigned int slice_type, tmp, i; int last_pic_structure, last_pic_droppable; + int must_reinit; int needs_reinit = 0; int field_pic_flag, bottom_field_flag; + int first_slice = sl == h->slice_ctx && !h->current_slice; int frame_num, droppable, picture_structure; - int mb_aff_frame = 0; + int mb_aff_frame, last_mb_aff_frame; - first_mb_in_slice = get_ue_golomb(&sl->gb); + if (first_slice) + av_assert0(!h->setup_finished); + + first_mb_in_slice = get_ue_golomb_long(&sl->gb); if (first_mb_in_slice == 0) { // FIXME better field boundary detection - if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) { - ff_h264_field_end(h, sl, 1); + if (h->current_slice) { + if (h->setup_finished) { + av_log(h->avctx, AV_LOG_ERROR, "Too many fields\n"); + return AVERROR_INVALIDDATA; + } + if (h->max_contexts > 1) { + if (!h->single_decode_warning) { + av_log(h->avctx, AV_LOG_WARNING, "Cannot decode multiple access units as slice threads\n"); + h->single_decode_warning = 1; + } + h->max_contexts = 1; + return SLICE_SINGLETHREAD; + } + + if (h->cur_pic_ptr && FIELD_PICTURE(h) && h->first_field) { + ret = ff_h264_field_end(h, h->slice_ctx, 1); + h->current_slice = 0; + if (ret < 0) + return ret; + } else if (h->cur_pic_ptr && !FIELD_PICTURE(h) && !h->first_field && h->nal_unit_type == NAL_IDR_SLICE) { + av_log(h, AV_LOG_WARNING, "Broken frame packetizing\n"); + ret = ff_h264_field_end(h, h->slice_ctx, 1); + h->current_slice = 0; + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); + h->cur_pic_ptr = NULL; + if (ret < 0) + return ret; + } else + return AVERROR_INVALIDDATA; } - h->current_slice = 0; if (!h->first_field) { if (h->cur_pic_ptr && !h->droppable) { ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, @@@ -1703,10 -1445,27 +1695,29 @@@ } } + return 0; + } + + /** + * Decode a slice header. + * This will (re)initialize the decoder and call h264_frame_start() as needed. + * + * @param h h264context + * + * @return 0 if okay, <0 if an error occurred + */ + int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) + { + int i, j, ret = 0; + + ret = h264_slice_header_parse(h, sl); + if (ret < 0) + return ret; + if (h->avctx->skip_loop_filter >= AVDISCARD_ALL || (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY && + h->nal_unit_type != NAL_IDR_SLICE) || + (h->avctx->skip_loop_filter >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) || (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) || @@@ -1726,19 -1485,14 +1737,19 @@@ sl->qp_thresh = 15 - FFMIN(sl->slice_alpha_c0_offset, sl->slice_beta_offset) - FFMAX3(0, - pps->chroma_qp_index_offset[0], - pps->chroma_qp_index_offset[1]) + - 6 * (sps->bit_depth_luma - 8); + h->ps.pps->chroma_qp_index_offset[0], + h->ps.pps->chroma_qp_index_offset[1]) + + 6 * (h->ps.sps->bit_depth_luma - 8); sl->slice_num = ++h->current_slice; - if (sl->slice_num >= MAX_SLICES) { - av_log(h->avctx, AV_LOG_ERROR, - "Too many slices, increase MAX_SLICES and recompile\n"); + + if (sl->slice_num) + h->slice_row[(sl->slice_num-1)&(MAX_SLICES-1)]= sl->resync_mb_y; + if ( h->slice_row[sl->slice_num&(MAX_SLICES-1)] + 3 >= sl->resync_mb_y + && h->slice_row[sl->slice_num&(MAX_SLICES-1)] <= sl->resync_mb_y + && sl->slice_num >= MAX_SLICES) { + //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case + av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", sl->slice_num, MAX_SLICES); } for (j = 0; j < 2; j++) { _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog