From 3d367e009c22e390c021bd6b2be32adc641222e7 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Jan 2018 13:47:05 +0100 Subject: [PATCH] mp_image: factor buffer referencing Reduce the trivial but still annoying code duplication in mp_image_new_ref(), which has to create new buffer references and deal with possible failure of creating them. The tricky part is that if creating a reference fails, we must set the target to NULL, so that unreferencing the failed new mp_image reference does not release the buffer references of the original mp_image. For the same reason, the code can't jump to error handling when it can't create a new reference, and has to set a flag instead. --- video/mp_image.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/video/mp_image.c b/video/mp_image.c index 4da576c400..0c07fd3098 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -296,6 +296,16 @@ void mp_image_unref_data(struct mp_image *img) } } +static bool ref_buffer(AVBufferRef **dst) +{ + if (*dst) { + *dst = av_buffer_ref(*dst); + if (!*dst) + return false; + } + return true; +} + // Return a new reference to img. The returned reference is owned by the caller, // while img is left untouched. struct mp_image *mp_image_new_ref(struct mp_image *img) @@ -311,24 +321,12 @@ struct mp_image *mp_image_new_ref(struct mp_image *img) *new = *img; bool fail = false; - for (int p = 0; p < MP_MAX_PLANES; p++) { - if (new->bufs[p]) { - new->bufs[p] = av_buffer_ref(new->bufs[p]); - if (!new->bufs[p]) - fail = true; - } - } - if (new->hwctx) { - new->hwctx = av_buffer_ref(new->hwctx); - if (!new->hwctx) - fail = true; - } + for (int p = 0; p < MP_MAX_PLANES; p++) + fail |= !ref_buffer(&new->bufs[p]); + + fail |= !ref_buffer(&new->hwctx); + fail |= !ref_buffer(&new->icc_profile); - if (new->icc_profile) { - new->icc_profile = av_buffer_ref(new->icc_profile); - if (!new->icc_profile) - fail = true; - } if (!fail) return new;