diff options
author | wm4 <wm4@nowhere> | 2017-10-16 16:36:21 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-10-16 16:36:51 +0200 |
commit | 0a7c5a130e73c7c96faafc7da80fa56ee9b7bf00 (patch) | |
tree | 8f08e6ebf7656a15062c1d39d1bba15a8771e6bd /video/mp_image.c | |
parent | a7464c4ed84762f81205f52c338b41bd43a973ee (diff) | |
download | mpv-0a7c5a130e73c7c96faafc7da80fa56ee9b7bf00.tar.bz2 mpv-0a7c5a130e73c7c96faafc7da80fa56ee9b7bf00.tar.xz |
video: properly pass through ICC data
The same should happen with any other side data that matters to mpv,
otherwise filters will drop it.
(No, don't try to argue that mpv should use AVFrame. That won't work.)
ffmpeg_garbage() is copy&paste from frame_new_side_data() in FFmpeg
(roughly feed201849b8f91), because it's not public API. The name
reflects my opinion about FFmpeg's API.
In mp_image_to_av_frame(), change the too-fragile
*new_ref = (struct mp_image){0};
into explicitly zeroing out the fields that are "transferred" to the
created AVFrame.
Diffstat (limited to 'video/mp_image.c')
-rw-r--r-- | video/mp_image.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/video/mp_image.c b/video/mp_image.c index 401144424a..18d700df15 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -29,6 +29,7 @@ #include "mpv_talloc.h" #include "config.h" +#include "common/av_common.h" #include "common/common.h" #include "hwdec.h" #include "mp_image.h" @@ -826,6 +827,7 @@ void mp_image_params_guess_csp(struct mp_image_params *params) struct mp_image *mp_image_from_av_frame(struct AVFrame *src) { struct mp_image *dst = &(struct mp_image){0}; + AVFrameSideData *sd; for (int p = 0; p < MP_MAX_PLANES; p++) dst->bufs[p] = src->buf[p]; @@ -880,9 +882,16 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src) } #endif +#if HAVE_AVUTIL_ICC_PROFILE + sd = av_frame_get_side_data(src, AV_FRAME_DATA_ICC_PROFILE); + if (sd) + dst->icc_profile = av_buffer_ref(sd->buf); +#endif + return mp_image_new_ref(dst); } + // Convert the mp_image reference to a AVFrame reference. struct AVFrame *mp_image_to_av_frame(struct mp_image *src) { @@ -894,10 +903,13 @@ struct AVFrame *mp_image_to_av_frame(struct mp_image *src) return NULL; } - for (int p = 0; p < MP_MAX_PLANES; p++) + for (int p = 0; p < MP_MAX_PLANES; p++) { dst->buf[p] = new_ref->bufs[p]; + new_ref->bufs[p] = NULL; + } dst->hw_frames_ctx = new_ref->hwctx; + new_ref->hwctx = NULL; dst->format = imgfmt2pixfmt(src->imgfmt); dst->width = src->w; @@ -935,8 +947,18 @@ struct AVFrame *mp_image_to_av_frame(struct mp_image *src) *(struct mp_image_params *)dst->opaque_ref->data = src->params; #endif - *new_ref = (struct mp_image){0}; +#if HAVE_AVUTIL_ICC_PROFILE + if (src->icc_profile) { + AVFrameSideData *sd = + ffmpeg_garbage(dst, AV_FRAME_DATA_ICC_PROFILE, new_ref->icc_profile); + if (!sd) + abort(); + new_ref->icc_profile = NULL; + } +#endif + talloc_free(new_ref); + if (dst->format == AV_PIX_FMT_NONE) av_frame_free(&dst); return dst; |