summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-01-29 13:47:05 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-01-30 03:10:27 -0800
commit3d367e009c22e390c021bd6b2be32adc641222e7 (patch)
treebd9cbd71e9dcf73a7d4acc88b4bdbdb430c87e43
parent0366ba253159a551127a7d1817a4a000e078d322 (diff)
downloadmpv-3d367e009c22e390c021bd6b2be32adc641222e7.tar.bz2
mpv-3d367e009c22e390c021bd6b2be32adc641222e7.tar.xz
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.
-rw-r--r--video/mp_image.c32
1 files 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;