summaryrefslogtreecommitdiffstats
path: root/video/filter/vf_format.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/filter/vf_format.c')
-rw-r--r--video/filter/vf_format.c95
1 files changed, 70 insertions, 25 deletions
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index b0cf04db7a..f226bf22a7 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -22,6 +22,9 @@
#include <math.h>
#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"
@@ -54,34 +57,37 @@ struct vf_format_opts {
int w, h;
int dw, dh;
double dar;
- int convert;
+ bool convert;
int force_scaler;
+ bool dovi;
+ bool hdr10plus;
+ bool film_grain;
};
static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
bool set_size)
{
if (p->colormatrix)
- out->color.space = p->colormatrix;
+ out->repr.sys = p->colormatrix;
if (p->colorlevels)
- out->color.levels = p->colorlevels;
+ out->repr.levels = p->colorlevels;
if (p->primaries)
out->color.primaries = p->primaries;
if (p->gamma) {
- enum mp_csp_trc in_gamma = p->gamma;
- out->color.gamma = p->gamma;
- if (in_gamma != out->color.gamma) {
+ enum pl_color_transfer in_gamma = p->gamma;
+ out->color.transfer = p->gamma;
+ if (in_gamma != out->color.transfer) {
// When changing the gamma function explicitly, also reset stuff
// related to the gamma function since that information will almost
// surely be false now and have to be re-inferred
- out->color.sig_peak = 0.0;
- out->color.light = MP_CSP_LIGHT_AUTO;
+ out->color.hdr = (struct pl_hdr_metadata){0};
+ out->light = MP_CSP_LIGHT_AUTO;
}
}
if (p->sig_peak)
- out->color.sig_peak = p->sig_peak;
+ out->color.hdr = (struct pl_hdr_metadata){ .max_luma = p->sig_peak * MP_REF_WHITE };
if (p->light)
- out->color.light = p->light;
+ out->light = p->light;
if (p->chroma_location)
out->chroma_location = p->chroma_location;
if (p->stereo_in)
@@ -89,7 +95,7 @@ static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
if (p->rotate >= 0)
out->rotate = p->rotate;
if (p->alpha)
- out->alpha = p->alpha;
+ out->repr.alpha = p->alpha;
if (p->w > 0 && set_size)
out->w = p->w;
@@ -106,6 +112,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;
@@ -119,10 +135,10 @@ static void vf_format_process(struct mp_filter *f)
int outfmt = priv->opts->fmt;
// If we convert from RGB to YUV, default to limited range.
- if (mp_imgfmt_get_forced_csp(img->imgfmt) == MP_CSP_RGB &&
- outfmt && mp_imgfmt_get_forced_csp(outfmt) == MP_CSP_AUTO)
+ if (mp_imgfmt_get_forced_csp(img->imgfmt) == PL_COLOR_SYSTEM_RGB &&
+ outfmt && mp_imgfmt_get_forced_csp(outfmt) == PL_COLOR_SYSTEM_UNKNOWN)
{
- par.color.levels = MP_CSP_LEVELS_TV;
+ par.repr.levels = PL_COLOR_LEVELS_LIMITED;
}
set_params(priv->opts, &par, true);
@@ -141,14 +157,39 @@ static void vf_format_process(struct mp_filter *f)
if (mp_pin_can_transfer_data(f->ppins[1], priv->conv->f->pins[1])) {
struct mp_frame frame = mp_pin_out_read(priv->conv->f->pins[1]);
+ struct mp_image *img = frame.data;
- if (!priv->opts->convert && frame.type == MP_FRAME_VIDEO) {
- struct mp_image *img = frame.data;
+ if (frame.type != MP_FRAME_VIDEO)
+ goto write_out;
+ if (!priv->opts->convert) {
set_params(priv->opts, &img->params, false);
mp_image_params_guess_csp(&img->params);
}
+ if (!priv->opts->dovi) {
+ 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->hdr10plus) {
+ memset(img->params.color.hdr.scene_max, 0,
+ sizeof(img->params.color.hdr.scene_max));
+ img->params.color.hdr.scene_avg = 0;
+ img->params.color.hdr.ootf = (struct pl_hdr_bezier){0};
+ }
+
+ if (!priv->opts->film_grain)
+ av_buffer_unref(&img->film_grain);
+
+write_out:
mp_pin_in_write(f->ppins[1], frame);
}
}
@@ -190,28 +231,29 @@ static struct mp_filter *vf_format_create(struct mp_filter *parent, void *option
#define OPT_BASE_STRUCT struct vf_format_opts
static const m_option_t vf_opts_fields[] = {
{"fmt", OPT_IMAGEFORMAT(fmt)},
- {"colormatrix", OPT_CHOICE_C(colormatrix, mp_csp_names)},
- {"colorlevels", OPT_CHOICE_C(colorlevels, mp_csp_levels_names)},
- {"primaries", OPT_CHOICE_C(primaries, mp_csp_prim_names)},
- {"gamma", OPT_CHOICE_C(gamma, mp_csp_trc_names)},
+ {"colormatrix", OPT_CHOICE_C(colormatrix, pl_csp_names)},
+ {"colorlevels", OPT_CHOICE_C(colorlevels, pl_csp_levels_names)},
+ {"primaries", OPT_CHOICE_C(primaries, pl_csp_prim_names)},
+ {"gamma", OPT_CHOICE_C(gamma, pl_csp_trc_names)},
{"sig-peak", OPT_FLOAT(sig_peak)},
{"light", OPT_CHOICE_C(light, mp_csp_light_names)},
- {"chroma-location", OPT_CHOICE_C(chroma_location, mp_chroma_names)},
+ {"chroma-location", OPT_CHOICE_C(chroma_location, pl_chroma_names)},
{"stereo-in", OPT_CHOICE_C(stereo_in, mp_stereo3d_names)},
{"rotate", OPT_INT(rotate), M_RANGE(-1, 359)},
- {"alpha", OPT_CHOICE_C(alpha, mp_alpha_names)},
+ {"alpha", OPT_CHOICE_C(alpha, pl_alpha_names)},
{"w", OPT_INT(w)},
{"h", OPT_INT(h)},
{"dw", OPT_INT(dw)},
{"dh", OPT_INT(dh)},
{"dar", OPT_DOUBLE(dar)},
- {"convert", OPT_FLAG(convert)},
+ {"convert", OPT_BOOL(convert)},
+ {"dolbyvision", OPT_BOOL(dovi)},
+ {"hdr10plus", OPT_BOOL(hdr10plus)},
+ {"film-grain", OPT_BOOL(film_grain)},
{"force-scaler", OPT_CHOICE(force_scaler,
{"auto", MP_SWS_AUTO},
{"sws", MP_SWS_SWS},
{"zimg", MP_SWS_ZIMG})},
- {"outputlevels", OPT_REMOVED("use the --video-output-levels global option")},
- {"peak", OPT_REMOVED("use sig-peak instead (changed value scale!)")},
{0}
};
@@ -222,6 +264,9 @@ const struct mp_user_filter_entry vf_format = {
.priv_size = sizeof(OPT_BASE_STRUCT),
.priv_defaults = &(const OPT_BASE_STRUCT){
.rotate = -1,
+ .dovi = true,
+ .hdr10plus = true,
+ .film_grain = true,
},
.options = vf_opts_fields,
},