[FFmpeg-devel] [PATCH v3] avcodec: fix atomics usage for h264/mpeg error_count
Aman Gupta
aman at tmm1.net
Tue Mar 13 11:49:30 EET 2018
On Mon, Mar 12, 2018 at 6:49 PM, Aman Gupta <ffmpeg at tmm1.net> wrote:
> From: Aman Gupta <aman at tmm1.net>
>
> ---
> libavcodec/h264_slice.c | 5 +++--
> libavcodec/mpeg12dec.c | 12 +++++++-----
> libavcodec/mpegvideo_enc.c | 3 ++-
> 3 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
> index 90e05ed8f1..b381397b4d 100644
> --- a/libavcodec/h264_slice.c
> +++ b/libavcodec/h264_slice.c
> @@ -2762,7 +2762,7 @@ int ff_h264_execute_decode_slices(H264Context *h)
>
> sl = &h->slice_ctx[i];
> if (CONFIG_ERROR_RESILIENCE) {
> - sl->er.error_count = 0;
> + sl->er.error_count = ATOMIC_VAR_INIT(0);
> }
>
> /* make sure none of those slices overlap */
> @@ -2786,7 +2786,8 @@ int ff_h264_execute_decode_slices(H264Context *h)
> h->mb_y = sl->mb_y;
> if (CONFIG_ERROR_RESILIENCE) {
> for (i = 1; i < context_count; i++)
> - h->slice_ctx[0].er.error_count +=
> h->slice_ctx[i].er.error_count;
> + atomic_fetch_add(&h->slice_ctx[0].er.error_count,
> + atomic_load(&h->slice_ctx[i].
> er.error_count));
> }
>
> if (h->postpone_filter) {
> diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
> index 9e076e89da..5a8570672c 100644
> --- a/libavcodec/mpeg12dec.c
> +++ b/libavcodec/mpeg12dec.c
> @@ -1992,7 +1992,7 @@ static int slice_decode_thread(AVCodecContext *c,
> void *arg)
> int mb_y = s->start_mb_y;
> const int field_pic = s->picture_structure != PICT_FRAME;
>
> - s->er.error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width)
> >> field_pic;
> + s->er.error_count = ATOMIC_VAR_INIT((3 * (s->end_mb_y -
> s->start_mb_y) * s->mb_width) >> field_pic);
>
> for (;;) {
> uint32_t start_code;
> @@ -2002,7 +2002,7 @@ static int slice_decode_thread(AVCodecContext *c,
> void *arg)
> emms_c();
> ff_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
> ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
> - s->start_mb_y, s->end_mb_y, s->er.error_count);
> + s->start_mb_y, s->end_mb_y, atomic_load(&s->er.error_
> count));
> if (ret < 0) {
> if (c->err_recognition & AV_EF_EXPLODE)
> return ret;
> @@ -2485,7 +2485,8 @@ static int decode_chunks(AVCodecContext *avctx,
> AVFrame *picture,
> &s2->thread_context[0], NULL,
> s->slice_count, sizeof(void *));
> for (i = 0; i < s->slice_count; i++)
> - s2->er.error_count += s2->thread_context[i]->er.
> error_count;
> + atomic_fetch_add(&s2->er.error_count,
> + atomic_load(&s2->thread_
> context[i]->er.error_count));
> }
>
> ret = slice_end(avctx, picture);
> @@ -2499,7 +2500,7 @@ static int decode_chunks(AVCodecContext *avctx,
> AVFrame *picture,
> }
> s2->pict_type = 0;
>
> - if (avctx->err_recognition & AV_EF_EXPLODE &&
> s2->er.error_count)
> + if (avctx->err_recognition & AV_EF_EXPLODE &&
> atomic_load(&s2->er.error_count))
> return AVERROR_INVALIDDATA;
>
> return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
> @@ -2553,7 +2554,8 @@ static int decode_chunks(AVCodecContext *avctx,
> AVFrame *picture,
> s2->thread_context, NULL,
> s->slice_count, sizeof(void *));
> for (i = 0; i < s->slice_count; i++)
> - s2->er.error_count += s2->thread_context[i]->er.
> error_count;
> + atomic_fetch_add(&s2->er.error_count,
> + atomic_load(&s2->thread_
> context[i]->er.error_count));
> s->slice_count = 0;
> }
> if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
> diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> index 979e138b88..3447c5e87a 100644
> --- a/libavcodec/mpegvideo_enc.c
> +++ b/libavcodec/mpegvideo_enc.c
> @@ -3595,7 +3595,8 @@ static void merge_context_after_encode(MpegEncContext
> *dst, MpegEncContext *src)
> MERGE(b_count);
> MERGE(skip_count);
> MERGE(misc_bits);
> - MERGE(er.error_count);
> + atomic_fetch_add(&dst->er.error_count, atomic_load(&src->er.error_
> count));
> + atomic_store(&src->er.error_count, 0);
> MERGE(padding_bug_score);
> MERGE(current_picture.encoding_error[0]);
> MERGE(current_picture.encoding_error[1]);
>
There was some uncertainty on IRC about whether the usages of
atomic_store() and ATOMIC_VAR_INIT() in this patch were correct, or needed
to be swapped.
Would appreciate if someone familiar with the error resilience code could
comment. /cc @michaelni
Aman
> --
> 2.14.2
>
>
More information about the ffmpeg-devel
mailing list