mirror of
https://github.com/mpv-player/mpv
synced 2025-03-30 07:18:17 +00:00
mp_image: add Dolby Vision metadata mapping
Remove side-loading metadata in vo_gpu_next.c and remove unneded side-data duplication.
This commit is contained in:
parent
05c8d5a93a
commit
d9c1e9bc5c
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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, ¶ms);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user