From 17e7c03e12d1e4490921e7bffaeaa6b46a7ada4e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 17 May 2016 18:57:23 +0200 Subject: [PATCH] h264: only allow ending a field/starting a new one before finish_setup() Doing this after ff_thread_finish_setup() is called is invalid and can conflict with reads from the other thread. --- libavcodec/h264_slice.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index d9268840bf..990c85bdba 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1381,26 +1381,30 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, if (ret < 0) return ret; - if (sl->first_mb_addr == 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->setup_finished) { + if (sl->first_mb_addr == 0) { // FIXME better field boundary detection + if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) { + ff_h264_field_end(h, sl, 1); + } + + 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, + h->picture_structure == PICT_BOTTOM_FIELD); + } + h->cur_pic_ptr = NULL; + } } - 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, - h->picture_structure == PICT_BOTTOM_FIELD); - } - h->cur_pic_ptr = NULL; + if (h->current_slice == 0) { + ret = h264_field_start(h, sl, nal); + if (ret < 0) + return ret; } } - if (h->current_slice == 0) { - ret = h264_field_start(h, sl, nal); - if (ret < 0) - return ret; - } else { + if (h->current_slice > 0) { if (h->ps.pps != (const PPS*)h->ps.pps_list[sl->pps_id]->data) { av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n"); return AVERROR_INVALIDDATA;