summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2017-07-25 23:06:27 +0200
committerNiklas Haas <git@haasn.xyz>2017-08-03 21:48:25 +0200
commit1aab0376014ff7fc278a81847c989b3970aa0736 (patch)
tree3942c4563227490bdb9afc7ba9ce845f0db1da22 /video
parent0f956f0929bacd6f4ad1a8c8ad4892ee14001b2d (diff)
downloadmpv-1aab0376014ff7fc278a81847c989b3970aa0736.tar.bz2
mpv-1aab0376014ff7fc278a81847c989b3970aa0736.tar.xz
vd_lavc: decode embedded ICC profiles
Since these need to be refcounted, we throw them directly into struct mp_image instead of being part of mp_colorspace. Even though they would semantically make more sense in mp_colorspace, having them there is really awkward because mp_colorspace is passed around and stored a lot, and this way their lifetime is exactly tied to the lifetime of the mp_image associated with it.
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd_lavc.c6
-rw-r--r--video/mp_image.c14
-rw-r--r--video/mp_image.h2
3 files changed, 22 insertions, 0 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index f1b2a83749..9c09d0a9c5 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -1184,6 +1184,12 @@ static bool decode_frame(struct dec_video *vd)
mp_pts_from_av(av_frame_get_pkt_duration(ctx->pic), &ctx->codec_timebase);
#endif
+#if HAVE_AVUTIL_ICC_PROFILE
+ sd = av_frame_get_side_data(ctx->pic, AV_FRAME_DATA_ICC_PROFILE);
+ if (sd)
+ mpi->icc_profile = av_buffer_ref(sd->buf);
+#endif
+
update_image_params(vd, ctx->pic, &mpi->params);
av_frame_unref(ctx->pic);
diff --git a/video/mp_image.c b/video/mp_image.c
index d4de39fe58..765289f8ff 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -200,6 +200,7 @@ static void mp_image_destructor(void *ptr)
for (int p = 0; p < MP_MAX_PLANES; p++)
av_buffer_unref(&mpi->bufs[p]);
av_buffer_unref(&mpi->hwctx);
+ av_buffer_unref(&mpi->icc_profile);
}
int mp_chroma_div_up(int size, int shift)
@@ -316,6 +317,12 @@ struct mp_image *mp_image_new_ref(struct mp_image *img)
fail = true;
}
+ if (new->icc_profile) {
+ new->icc_profile = av_buffer_ref(new->icc_profile);
+ if (!new->icc_profile)
+ fail = true;
+ }
+
if (!fail)
return new;
@@ -525,6 +532,13 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
memcpy(dst->planes[1], src->planes[1], MP_PALETTE_SIZE);
}
}
+ av_buffer_unref(&dst->icc_profile);
+ dst->icc_profile = src->icc_profile;
+ if (dst->icc_profile) {
+ dst->icc_profile = av_buffer_ref(dst->icc_profile);
+ if (!dst->icc_profile)
+ abort();
+ }
}
// Crop the given image to (x0, y0)-(x1, y1) (bottom/right border exclusive)
diff --git a/video/mp_image.h b/video/mp_image.h
index e949b9b81f..640e2709e9 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -100,6 +100,8 @@ typedef struct mp_image {
struct AVBufferRef *bufs[MP_MAX_PLANES];
// Points to AVHWFramesContext* (same as AVFrame.hw_frames_ctx)
struct AVBufferRef *hwctx;
+ // Embedded ICC profile, if any
+ struct AVBufferRef *icc_profile;
} mp_image_t;
int mp_chroma_div_up(int size, int shift);