summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2024-02-11 00:52:49 +0100
committerDudemanguy <random342@airmail.cc>2024-03-09 05:58:52 +0000
commitd9c1e9bc5c8ca5e4a75b197789b77890375cb8e2 (patch)
treeb0ded6868977c591bc03e442696762a85cfbb0ec
parent05c8d5a93a743cb735ca751c2a6343dba4dcf511 (diff)
downloadmpv-d9c1e9bc5c8ca5e4a75b197789b77890375cb8e2.tar.bz2
mpv-d9c1e9bc5c8ca5e4a75b197789b77890375cb8e2.tar.xz
mp_image: add Dolby Vision metadata mapping
Remove side-loading metadata in vo_gpu_next.c and remove unneded side-data duplication.
-rw-r--r--video/filter/vf_format.c23
-rw-r--r--video/mp_image.c37
-rw-r--r--video/mp_image.h2
-rw-r--r--video/out/placebo/utils.c24
-rw-r--r--video/out/placebo/utils.h3
-rw-r--r--video/out/vo_gpu_next.c3
6 files changed, 50 insertions, 42 deletions
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index 2063045864..4a2916864c 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -23,6 +23,8 @@
#include <libavutil/rational.h>
#include <libavutil/buffer.h>
+#include <libavutil/frame.h>
+#include <libplacebo/utils/libav.h>
#include "common/msg.h"
#include "common/common.h"
@@ -109,6 +111,16 @@ static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
mp_image_params_set_dsize(out, dsize.num, dsize.den);
}
+static inline void *get_side_data(const struct mp_image *mpi,
+ enum AVFrameSideDataType type)
+{
+ for (int i = 0; i < mpi->num_ff_side_data; i++) {
+ if (mpi->ff_side_data[i].type == type)
+ return (void *)mpi->ff_side_data[i].buf->data;
+ }
+ return NULL;
+}
+
static void vf_format_process(struct mp_filter *f)
{
struct priv *priv = f->priv;
@@ -155,8 +167,15 @@ static void vf_format_process(struct mp_filter *f)
}
if (!priv->opts->dovi) {
- av_buffer_unref(&img->dovi);
- av_buffer_unref(&img->dovi_buf);
+ if (img->params.repr.sys == PL_COLOR_SYSTEM_DOLBYVISION)
+ img->params.repr.sys = PL_COLOR_SYSTEM_BT_2020_NC;
+ // Map again to strip any DV metadata set to common fields.
+ img->params.color.hdr = (struct pl_hdr_metadata){0};
+ pl_map_hdr_metadata(&img->params.color.hdr, &(struct pl_av_hdr_metadata) {
+ .mdm = get_side_data(img, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA),
+ .clm = get_side_data(img, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL),
+ .dhp = get_side_data(img, AV_FRAME_DATA_DYNAMIC_HDR_PLUS),
+ });
}
if (!priv->opts->film_grain)
diff --git a/video/mp_image.c b/video/mp_image.c
index 23b1ab8af0..a8c0262aa7 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -209,7 +209,6 @@ static void mp_image_destructor(void *ptr)
av_buffer_unref(&mpi->a53_cc);
av_buffer_unref(&mpi->dovi);
av_buffer_unref(&mpi->film_grain);
- av_buffer_unref(&mpi->dovi_buf);
for (int n = 0; n < mpi->num_ff_side_data; n++)
av_buffer_unref(&mpi->ff_side_data[n].buf);
talloc_free(mpi->ff_side_data);
@@ -344,7 +343,6 @@ struct mp_image *mp_image_new_ref(struct mp_image *img)
ref_buffer(&new->a53_cc);
ref_buffer(&new->dovi);
ref_buffer(&new->film_grain);
- ref_buffer(&new->dovi_buf);
new->ff_side_data = talloc_memdup(NULL, new->ff_side_data,
new->num_ff_side_data * sizeof(new->ff_side_data[0]));
@@ -382,7 +380,6 @@ struct mp_image *mp_image_new_dummy_ref(struct mp_image *img)
new->a53_cc = NULL;
new->dovi = NULL;
new->film_grain = NULL;
- new->dovi_buf = NULL;
new->num_ff_side_data = 0;
new->ff_side_data = NULL;
return new;
@@ -542,7 +539,6 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
}
assign_bufref(&dst->icc_profile, src->icc_profile);
assign_bufref(&dst->dovi, src->dovi);
- assign_bufref(&dst->dovi_buf, src->dovi_buf);
assign_bufref(&dst->film_grain, src->film_grain);
assign_bufref(&dst->a53_cc, src->a53_cc);
@@ -1093,14 +1089,38 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
if (sd)
dst->a53_cc = sd->buf;
+ AVBufferRef *dovi = NULL;
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 16, 100)
sd = av_frame_get_side_data(src, AV_FRAME_DATA_DOVI_METADATA);
- if (sd)
- dst->dovi = sd->buf;
+ if (sd) {
+#ifdef PL_HAVE_LAV_DOLBY_VISION
+ const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->buf->data;
+ const AVDOVIRpuDataHeader *header = av_dovi_get_header(metadata);
+ if (header->disable_residual_flag) {
+ dst->dovi = dovi = av_buffer_alloc(sizeof(struct pl_dovi_metadata));
+ MP_HANDLE_OOM(dovi);
+#if PL_API_VER >= 343
+ pl_map_avdovi_metadata(&dst->params.color, &dst->params.repr,
+ (void *)dst->dovi->data, metadata);
+#else
+ struct pl_frame frame;
+ frame.repr = dst->params.repr;
+ frame.color = dst->params.color;
+ pl_frame_map_avdovi_metadata(&frame, (void *)dst->dovi->data, metadata);
+ dst->params.repr = frame.repr;
+ dst->params.color = frame.color;
+#endif
+ }
+#endif
+ }
sd = av_frame_get_side_data(src, AV_FRAME_DATA_DOVI_RPU_BUFFER);
- if (sd)
- dst->dovi_buf = sd->buf;
+ if (sd) {
+#ifdef PL_HAVE_LIBDOVI
+ pl_hdr_metadata_from_dovi_rpu(&dst->params.color.hdr, sd->buf->data,
+ sd->buf->size);
+#endif
+ }
#endif
sd = av_frame_get_side_data(src, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
@@ -1125,6 +1145,7 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
// Allocated, but non-refcounted data.
talloc_free(dst->ff_side_data);
+ av_buffer_unref(&dovi);
return res;
}
diff --git a/video/mp_image.h b/video/mp_image.h
index 3a6130a24d..af0d9fd58d 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -116,8 +116,6 @@ typedef struct mp_image {
struct AVBufferRef *dovi;
// Film grain data, if any
struct AVBufferRef *film_grain;
- // Dolby Vision RPU buffer, if any
- struct AVBufferRef *dovi_buf;
// Other side data we don't care about.
struct mp_ff_side_data *ff_side_data;
int num_ff_side_data;
diff --git a/video/out/placebo/utils.c b/video/out/placebo/utils.c
index e01c371039..86b0bfd38d 100644
--- a/video/out/placebo/utils.c
+++ b/video/out/placebo/utils.c
@@ -71,27 +71,3 @@ void mppl_log_set_probing(pl_log log, bool probing)
params.log_cb = probing ? log_cb_probing : log_cb;
pl_log_update(log, &params);
}
-
-void mp_map_dovi_metadata_to_pl(struct mp_image *mpi,
- struct pl_frame *frame)
-{
-#ifdef PL_HAVE_LAV_DOLBY_VISION
- if (mpi->dovi) {
- const AVDOVIMetadata *metadata = (AVDOVIMetadata *) mpi->dovi->data;
- const AVDOVIRpuDataHeader *header = av_dovi_get_header(metadata);
-
- if (header->disable_residual_flag) {
- // Only automatically map DoVi RPUs that don't require an EL
- struct pl_dovi_metadata *dovi = talloc_ptrtype(mpi, dovi);
- pl_frame_map_avdovi_metadata(frame, dovi, metadata);
- }
- }
-
-#if defined(PL_HAVE_LIBDOVI)
- if (mpi->dovi_buf)
- pl_hdr_metadata_from_dovi_rpu(&frame->color.hdr, mpi->dovi_buf->data,
- mpi->dovi_buf->size);
-#endif
-
-#endif // PL_HAVE_LAV_DOLBY_VISION
-}
diff --git a/video/out/placebo/utils.h b/video/out/placebo/utils.h
index d2fa619b4a..3f61d8b504 100644
--- a/video/out/placebo/utils.h
+++ b/video/out/placebo/utils.h
@@ -26,6 +26,3 @@ static inline struct pl_rect2d mp_rect2d_to_pl(struct mp_rect rc)
.y1 = rc.y1,
};
}
-
-void mp_map_dovi_metadata_to_pl(struct mp_image *mpi,
- struct pl_frame *frame);
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c
index 0139cfd3e1..84facb9e44 100644
--- a/video/out/vo_gpu_next.c
+++ b/video/out/vo_gpu_next.c
@@ -705,9 +705,6 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
// Update chroma location, must be done after initializing planes
pl_frame_set_chroma_location(frame, par->chroma_location);
- // Set the frame DOVI metadata
- mp_map_dovi_metadata_to_pl(mpi, frame);
-
if (mpi->film_grain)
pl_film_grain_from_av(&frame->film_grain, (AVFilmGrainParams *) mpi->film_grain->data);