diff options
author | Anton Khirnov <anton@khirnov.net> | 2016-05-17 18:57:23 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2016-06-21 11:10:00 +0200 |
commit | 17e7c03e12d1e4490921e7bffaeaa6b46a7ada4e (patch) | |
tree | 8b92ced8be9afdbe9bfce42795f11d7e388f4288 /libavcodec | |
parent | debca90863e4ee53447efd02483c500f89766384 (diff) | |
download | ffmpeg-17e7c03e12d1e4490921e7bffaeaa6b46a7ada4e.tar.gz |
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.
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/h264_slice.c | 34 |
1 files 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->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->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; |