1
mirror of https://github.com/mpv-player/mpv synced 2024-10-02 16:25:33 +02:00

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.
This commit is contained in:
wm4 2018-01-29 13:47:05 +01:00 committed by Kevin Mitchell
parent 0366ba2531
commit 3d367e009c

View File

@ -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, // Return a new reference to img. The returned reference is owned by the caller,
// while img is left untouched. // while img is left untouched.
struct mp_image *mp_image_new_ref(struct mp_image *img) 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; *new = *img;
bool fail = false; bool fail = false;
for (int p = 0; p < MP_MAX_PLANES; p++) { for (int p = 0; p < MP_MAX_PLANES; p++)
if (new->bufs[p]) { fail |= !ref_buffer(&new->bufs[p]);
new->bufs[p] = av_buffer_ref(new->bufs[p]);
if (!new->bufs[p]) fail |= !ref_buffer(&new->hwctx);
fail = true; fail |= !ref_buffer(&new->icc_profile);
}
}
if (new->hwctx) {
new->hwctx = av_buffer_ref(new->hwctx);
if (!new->hwctx)
fail = true;
}
if (new->icc_profile) {
new->icc_profile = av_buffer_ref(new->icc_profile);
if (!new->icc_profile)
fail = true;
}
if (!fail) if (!fail)
return new; return new;