diff mbox series

[FFmpeg-devel,1/3] avfilter/vf_libplacebo: add fillcolor option

Message ID 20230501150301.55718-1-ffmpeg@haasn.xyz
State Accepted
Commit 4b11a07550363e1f1d6f8e43923d9b6b327737b0
Headers show
Series [FFmpeg-devel,1/3] avfilter/vf_libplacebo: add fillcolor option | expand

Checks

Context Check Description
andriy/make_x86 fail Make failed

Commit Message

Niklas Haas May 1, 2023, 3:02 p.m. UTC
From: Niklas Haas <git@haasn.dev>

In some circumstances, libplacebo will clear the background as a result
of cropping/padding. Currently, this uses the hard-coded default fill
color of black. This option makes this behavior configurable.
---
 doc/filters.texi            |  6 ++++++
 libavfilter/vf_libplacebo.c | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)

Comments

Niklas Haas May 3, 2023, 9:42 p.m. UTC | #1
Merged as 4b11a0755036..ad417eb5fa1

On Mon, 01 May 2023 17:02:59 +0200 Niklas Haas <ffmpeg@haasn.xyz> wrote:
> From: Niklas Haas <git@haasn.dev>
> 
> In some circumstances, libplacebo will clear the background as a result
> of cropping/padding. Currently, this uses the hard-coded default fill
> color of black. This option makes this behavior configurable.
> ---
>  doc/filters.texi            |  6 ++++++
>  libavfilter/vf_libplacebo.c | 22 ++++++++++++++++++++++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 6d2672063c1..35df5c339a7 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -16018,6 +16018,12 @@ content with black borders, while a value of @code{1.0} always crops off parts
>  of the content. Intermediate values are possible, leading to a mix of the two
>  approaches.
>  
> +@item fillcolor
> +Set the color used to fill the output area not covered by the output image, for
> +example as a result of @ref{normalize_sar}. For the general syntax of this
> +option, check the @ref{color syntax,,"Color" section in the ffmpeg-utils
> +manual,ffmpeg-utils}. Defaults to @code{black}.
> +
>  @item colorspace
>  @item color_primaries
>  @item color_trc
> diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> index 66929223dd9..fcdc97e48e2 100644
> --- a/libavfilter/vf_libplacebo.c
> +++ b/libavfilter/vf_libplacebo.c
> @@ -18,6 +18,7 @@
>  
>  #include "libavutil/file.h"
>  #include "libavutil/opt.h"
> +#include "libavutil/parseutils.h"
>  #include "internal.h"
>  #include "vulkan_filter.h"
>  #include "scale_eval.h"
> @@ -73,6 +74,7 @@ typedef struct LibplaceboContext {
>      /* settings */
>      char *out_format_string;
>      enum AVPixelFormat out_format;
> +    char *fillcolor;
>      char *w_expr;
>      char *h_expr;
>      AVRational target_sar;
> @@ -225,6 +227,24 @@ static int find_scaler(AVFilterContext *avctx,
>      return AVERROR(EINVAL);
>  }
>  
> +static int parse_fillcolor(AVFilterContext *avctx,
> +                           struct pl_render_params *params,
> +                           const char *color_str)
> +{
> +    int err = 0;
> +    uint8_t color_rgba[4];
> +
> +    RET(av_parse_color(color_rgba, color_str, -1, avctx));
> +    params->background_color[0] = (float) color_rgba[0] / UINT8_MAX;
> +    params->background_color[1] = (float) color_rgba[1] / UINT8_MAX;
> +    params->background_color[2] = (float) color_rgba[2] / UINT8_MAX;
> +    params->background_transparency = 1.0f - (float) color_rgba[3] / UINT8_MAX;
> +    return 0;
> +
> +fail:
> +    return err;
> +}
> +
>  static void libplacebo_uninit(AVFilterContext *avctx);
>  
>  static int libplacebo_init(AVFilterContext *avctx)
> @@ -469,6 +489,7 @@ static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in)
>  
>      RET(find_scaler(avctx, &params.upscaler, s->upscaler));
>      RET(find_scaler(avctx, &params.downscaler, s->downscaler));
> +    RET(parse_fillcolor(avctx, &params, s->fillcolor));
>  
>      pl_render_image(s->renderer, &image, &target, &params);
>      pl_unmap_avframe(s->gpu, &image);
> @@ -703,6 +724,7 @@ static const AVOption libplacebo_options[] = {
>      { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, STATIC },
>      { "normalize_sar", "force SAR normalization to 1:1", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
>      { "pad_crop_ratio", "ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)", OFFSET(pad_crop_ratio), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0, DYNAMIC },
> +    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = DYNAMIC },
>  
>      {"colorspace", "select colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_SPC_NB-1, DYNAMIC, "colorspace"},
>      {"auto", "keep the same colorspace",  0, AV_OPT_TYPE_CONST, {.i64=-1},                          INT_MIN, INT_MAX, STATIC, "colorspace"},
> -- 
> 2.40.0
>
diff mbox series

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index 6d2672063c1..35df5c339a7 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -16018,6 +16018,12 @@  content with black borders, while a value of @code{1.0} always crops off parts
 of the content. Intermediate values are possible, leading to a mix of the two
 approaches.
 
+@item fillcolor
+Set the color used to fill the output area not covered by the output image, for
+example as a result of @ref{normalize_sar}. For the general syntax of this
+option, check the @ref{color syntax,,"Color" section in the ffmpeg-utils
+manual,ffmpeg-utils}. Defaults to @code{black}.
+
 @item colorspace
 @item color_primaries
 @item color_trc
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 66929223dd9..fcdc97e48e2 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -18,6 +18,7 @@ 
 
 #include "libavutil/file.h"
 #include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
 #include "internal.h"
 #include "vulkan_filter.h"
 #include "scale_eval.h"
@@ -73,6 +74,7 @@  typedef struct LibplaceboContext {
     /* settings */
     char *out_format_string;
     enum AVPixelFormat out_format;
+    char *fillcolor;
     char *w_expr;
     char *h_expr;
     AVRational target_sar;
@@ -225,6 +227,24 @@  static int find_scaler(AVFilterContext *avctx,
     return AVERROR(EINVAL);
 }
 
+static int parse_fillcolor(AVFilterContext *avctx,
+                           struct pl_render_params *params,
+                           const char *color_str)
+{
+    int err = 0;
+    uint8_t color_rgba[4];
+
+    RET(av_parse_color(color_rgba, color_str, -1, avctx));
+    params->background_color[0] = (float) color_rgba[0] / UINT8_MAX;
+    params->background_color[1] = (float) color_rgba[1] / UINT8_MAX;
+    params->background_color[2] = (float) color_rgba[2] / UINT8_MAX;
+    params->background_transparency = 1.0f - (float) color_rgba[3] / UINT8_MAX;
+    return 0;
+
+fail:
+    return err;
+}
+
 static void libplacebo_uninit(AVFilterContext *avctx);
 
 static int libplacebo_init(AVFilterContext *avctx)
@@ -469,6 +489,7 @@  static int process_frames(AVFilterContext *avctx, AVFrame *out, AVFrame *in)
 
     RET(find_scaler(avctx, &params.upscaler, s->upscaler));
     RET(find_scaler(avctx, &params.downscaler, s->downscaler));
+    RET(parse_fillcolor(avctx, &params, s->fillcolor));
 
     pl_render_image(s->renderer, &image, &target, &params);
     pl_unmap_avframe(s->gpu, &image);
@@ -703,6 +724,7 @@  static const AVOption libplacebo_options[] = {
     { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, STATIC },
     { "normalize_sar", "force SAR normalization to 1:1", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
     { "pad_crop_ratio", "ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)", OFFSET(pad_crop_ratio), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0, DYNAMIC },
+    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = DYNAMIC },
 
     {"colorspace", "select colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCOL_SPC_NB-1, DYNAMIC, "colorspace"},
     {"auto", "keep the same colorspace",  0, AV_OPT_TYPE_CONST, {.i64=-1},                          INT_MIN, INT_MAX, STATIC, "colorspace"},