@@ -47,6 +47,7 @@ typedef struct LibplaceboContext {
int force_divisible_by;
int normalize_sar;
int apply_filmgrain;
+ int apply_dovi;
int colorspace;
int color_range;
int color_primaries;
@@ -400,6 +401,22 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
out->width = outlink->w;
out->height = outlink->h;
+#if PL_API_VER >= 191
+ /* libplacebo cannot (currently) encode back to Dolby Vision */
+ av_frame_remove_side_data(out, AV_FRAME_DATA_DOVI_RPU_BUFFER);
+ av_frame_remove_side_data(out, AV_FRAME_DATA_DOVI_METADATA);
+ if (s->apply_dovi && av_frame_get_side_data(in, AV_FRAME_DATA_DOVI_METADATA)) {
+ /* Output of dovi reshaping is always BT.2020+PQ, so infer the correct
+ * output colorspace defaults */
+ out->colorspace = AVCOL_SPC_BT2020_NCL;
+ out->color_primaries = AVCOL_PRI_BT2020;
+ out->color_trc = AVCOL_TRC_SMPTE2084;
+ } else {
+ /* Prevent Dolby Vision metadata from getting applied by libplacebo */
+ av_frame_remove_side_data(in, AV_FRAME_DATA_DOVI_METADATA);
+ }
+#endif
+
if (s->colorspace >= 0)
out->colorspace = s->colorspace;
if (s->color_range >= 0)
@@ -559,6 +576,7 @@ static const AVOption libplacebo_options[] = {
{ "antiringing", "Antiringing strength (for non-EWA filters)", OFFSET(antiringing), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, DYNAMIC },
{ "sigmoid", "Enable sigmoid upscaling", OFFSET(sigmoid), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
{ "apply_filmgrain", "Apply film grain metadata", OFFSET(apply_filmgrain), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
+ { "apply_dolbyvision", "Apply Dolby Vision metadata", OFFSET(apply_dovi), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DYNAMIC },
{ "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC },
{ "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC },