* [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