Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/3] avfilter/vf_libplacebo: list AV_PIX_FMT_VULKAN first
@ 2025-06-16 18:05 Niklas Haas
  2025-06-16 18:05 ` [FFmpeg-devel] [PATCH 2/3] avfilter/vf_libplacebo: correctly update SAR to reflect scaled result Niklas Haas
  2025-06-16 18:05 ` [FFmpeg-devel] [PATCH 3/3] avfilter/vf_libplaceb: add `reset_sar` option Niklas Haas
  0 siblings, 2 replies; 3+ messages in thread
From: Niklas Haas @ 2025-06-16 18:05 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Under normal circumstances, this change does not affect anything, as the vast
majority of filters either support only vulkan or only software formats.
However, when a filter supports both (such as vf_libplacebo itself, and
possibly vf_scale in the future), linking together two such filter instances
without an explicit format will default matching the input format, resulting
in a redundant round trip through host RAM.

This change bumps up AV_PIX_FMT_VULKAN to the first entry in the format list,
ensuring that it gets preferred whenever possible.
---
 libavfilter/vf_libplacebo.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 9ff64053cc..c7a1b15f92 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -1150,8 +1150,17 @@ static int libplacebo_query_format(const AVFilterContext *ctx,
     const AVPixFmtDescriptor *desc = NULL;
     AVFilterFormats *infmts = NULL, *outfmts = NULL;
 
+    /* List AV_PIX_FMT_VULKAN first to prefer it when possible */
+    if (s->have_hwdevice) {
+        RET(ff_add_format(&infmts, AV_PIX_FMT_VULKAN));
+        if (s->out_format == AV_PIX_FMT_NONE || av_vkfmt_from_pixfmt(s->out_format))
+            RET(ff_add_format(&outfmts, AV_PIX_FMT_VULKAN));
+    }
+
     while ((desc = av_pix_fmt_desc_next(desc))) {
         enum AVPixelFormat pixfmt = av_pix_fmt_desc_get_id(desc);
+        if (pixfmt == AV_PIX_FMT_VULKAN)
+            continue; /* Handled above */
 
 #if PL_API_VER < 232
         // Older libplacebo can't handle >64-bit pixel formats, so safe-guard
@@ -1160,9 +1169,6 @@ static int libplacebo_query_format(const AVFilterContext *ctx,
             continue;
 #endif
 
-        if (pixfmt == AV_PIX_FMT_VULKAN && !s->have_hwdevice)
-            continue;
-
         if (!pl_test_pixfmt(s->gpu, pixfmt))
             continue;
 
@@ -1173,15 +1179,8 @@ static int libplacebo_query_format(const AVFilterContext *ctx,
             continue; /* BE formats are not supported by pl_download_avframe */
 
         /* Mask based on user specified format */
-        if (s->out_format != AV_PIX_FMT_NONE) {
-            if (pixfmt == AV_PIX_FMT_VULKAN && av_vkfmt_from_pixfmt(s->out_format)) {
-                /* OK */
-            } else if (pixfmt == s->out_format) {
-                /* OK */
-            } else {
-                continue; /* Not OK */
-            }
-        }
+        if (pixfmt != s->out_format && s->out_format != AV_PIX_FMT_NONE)
+            continue;
 
 #if PL_API_VER >= 293
         if (!pl_test_pixfmt_caps(s->gpu, pixfmt, PL_FMT_CAP_RENDERABLE))
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [FFmpeg-devel] [PATCH 2/3] avfilter/vf_libplacebo: correctly update SAR to reflect scaled result
  2025-06-16 18:05 [FFmpeg-devel] [PATCH 1/3] avfilter/vf_libplacebo: list AV_PIX_FMT_VULKAN first Niklas Haas
@ 2025-06-16 18:05 ` Niklas Haas
  2025-06-16 18:05 ` [FFmpeg-devel] [PATCH 3/3] avfilter/vf_libplaceb: add `reset_sar` option Niklas Haas
  1 sibling, 0 replies; 3+ messages in thread
From: Niklas Haas @ 2025-06-16 18:05 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

This aligns the behavior of vf_libplacebo with other filters in the
vf_scale family, that forward any change in the SAR as a result of
changing the output resolution to the output frame / link, and updates
the ff_scale_adjust_dimensions() call to continue working as intended.

The new behavior reflects the documentation of vf_libplacebo, which
described this behavior despite that not being the way the filter worked
up to this point.

As an aside, also fixes a bug where the AVFrame SAR was inconsistent
with the AVFilterLink SAR when the s->nb_inputs > 1 condition was met.
---
 libavfilter/vf_libplacebo.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index c7a1b15f92..4775673127 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -186,6 +186,7 @@ typedef struct LibplaceboContext {
     float corner_rounding;
     int force_original_aspect_ratio;
     int force_divisible_by;
+    int reset_sar;
     int normalize_sar;
     int apply_filmgrain;
     int apply_dovi;
@@ -911,6 +912,15 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
     if (s->apply_filmgrain)
         av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
 
+    if (s->reset_sar) {
+        out->sample_aspect_ratio = ref->sample_aspect_ratio;
+    } else {
+        const AVRational ar_ref  = { ref->width, ref->height };
+        const AVRational ar_out  = { out->width, out->height };
+        const AVRational stretch = av_div_q(ar_ref, ar_out);
+        out->sample_aspect_ratio = av_mul_q(ref->sample_aspect_ratio, stretch);
+    }
+
     /* Map, render and unmap output frame */
     if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
         ok = pl_map_avframe_ex(s->gpu, &target, pl_avframe_params(
@@ -1270,19 +1280,28 @@ static int libplacebo_config_output(AVFilterLink *outlink)
     RET(ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
                                  &outlink->w, &outlink->h));
 
+    s->reset_sar = s->normalize_sar || s->nb_inputs > 1;
+    double sar_in = inlink->sample_aspect_ratio.num ?
+                    av_q2d(inlink->sample_aspect_ratio) : 1.0;
+
     ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
                                s->force_original_aspect_ratio,
-                               s->force_divisible_by, 1.f);
+                               s->force_divisible_by,
+                               s->reset_sar ? sar_in : 1.0);
 
-    if (s->normalize_sar || s->nb_inputs > 1) {
+    if (s->reset_sar) {
         /* SAR is normalized, or we have multiple inputs, set out to 1:1 */
         outlink->sample_aspect_ratio = (AVRational){ 1, 1 };
-    } else {
+    } else if (inlink->sample_aspect_ratio.num) {
         /* This is consistent with other scale_* filters, which only
          * set the outlink SAR to be equal to the scale SAR iff the input SAR
          * was set to something nonzero */
-        if (inlink->sample_aspect_ratio.num)
-            outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
+        const AVRational ar_in   = { inlink->w,  inlink->h };
+        const AVRational ar_out  = { outlink->w, outlink->h };
+        const AVRational stretch = av_div_q(ar_in, ar_out);
+        outlink->sample_aspect_ratio = av_mul_q(inlink->sample_aspect_ratio, stretch);
+    } else {
+        outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
     }
 
     /* Frame rate */
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [FFmpeg-devel] [PATCH 3/3] avfilter/vf_libplaceb: add `reset_sar` option
  2025-06-16 18:05 [FFmpeg-devel] [PATCH 1/3] avfilter/vf_libplacebo: list AV_PIX_FMT_VULKAN first Niklas Haas
  2025-06-16 18:05 ` [FFmpeg-devel] [PATCH 2/3] avfilter/vf_libplacebo: correctly update SAR to reflect scaled result Niklas Haas
@ 2025-06-16 18:05 ` Niklas Haas
  1 sibling, 0 replies; 3+ messages in thread
From: Niklas Haas @ 2025-06-16 18:05 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

This was requested by users of `vf_libplacebo`, to mirror the existing
option on the other `vf_scale_*` family of filters. While we have
`vf_normalize`, it was not as useful in the event that the content
stretching was actually desired.

Bridges an important usability gap between `vf_scale` and `vf_libplacebo`
that made mixing and matching the filters needlessly difficult.
---
 doc/filters.texi            | 12 ++++++++----
 libavfilter/vf_libplacebo.c |  5 +++--
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 63f55f5794..65788d872e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -16291,11 +16291,15 @@ will be performed.
 @item force_divisible_by
 Work the same as the identical @ref{scale} filter options.
 
+@item reset_sar
+If enabled, output frames will always have a pixel aspect ratio of 1:1.  If
+disabled (the default), any aspect ratio mismatches, including those from
+e.g. anamorphic video sources, are forwarded to the output pixel aspect ratio.
+
 @item normalize_sar
-If enabled, output frames will always have a pixel aspect ratio of 1:1. This
-will introduce additional padding/cropping as necessary. If disabled (the
-default), any aspect ratio mismatches, including those from e.g. anamorphic
-video sources, are forwarded to the output pixel aspect ratio.
+Like @option{reset_sar}, but instead of stretching the video content to fill
+the new output aspect ratio, the content is instead padded or cropped as
+necessary.
 
 @item pad_crop_ratio
 Specifies a ratio (between @code{0.0} and @code{1.0}) between padding and
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 4775673127..2cf3ab712d 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -1280,7 +1280,7 @@ static int libplacebo_config_output(AVFilterLink *outlink)
     RET(ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
                                  &outlink->w, &outlink->h));
 
-    s->reset_sar = s->normalize_sar || s->nb_inputs > 1;
+    s->reset_sar |= s->normalize_sar || s->nb_inputs > 1;
     double sar_in = inlink->sample_aspect_ratio.num ?
                     av_q2d(inlink->sample_aspect_ratio) : 1.0;
 
@@ -1383,7 +1383,8 @@ static const AVOption libplacebo_options[] = {
         { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, STATIC, .unit = "force_oar" },
         { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, STATIC, .unit = "force_oar" },
     { "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 by adjusting pos_x/y/w/h", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
+    { "reset_sar", "force SAR normalization to 1:1 by adjusting pos_x/y/w/h", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
+    { "normalize_sar", "like reset_sar, but pad/crop instead of stretching the video", 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_COLOR, {.str = "black@0"}, .flags = DYNAMIC },
     { "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-06-16 18:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-16 18:05 [FFmpeg-devel] [PATCH 1/3] avfilter/vf_libplacebo: list AV_PIX_FMT_VULKAN first Niklas Haas
2025-06-16 18:05 ` [FFmpeg-devel] [PATCH 2/3] avfilter/vf_libplacebo: correctly update SAR to reflect scaled result Niklas Haas
2025-06-16 18:05 ` [FFmpeg-devel] [PATCH 3/3] avfilter/vf_libplaceb: add `reset_sar` option Niklas Haas

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git