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 v2] avfilter/scale*: add option reset_sar
@ 2025-02-09 10:11 Gyan Doshi
  2025-02-10 10:56 ` Gyan Doshi
  0 siblings, 1 reply; 2+ messages in thread
From: Gyan Doshi @ 2025-02-09 10:11 UTC (permalink / raw)
  To: ffmpeg-devel

For anamorphic videos, enabling this option leads to adjustment of
output dimensions to obtain square pixels when the user requests
proportional scaling through either of the w/h expressions or
force_original_aspect_ratio.

Output SAR is always reset to 1.

Option added to scale, scale_cuda, scale_npp & scale_vaapi.

libplacebo already has a similar option with different semantics,
scale_vt and scale_vulkan don't implement force_oar, so for these
three filters, I've made minimal changes needed to not break building
or change output.
---
v2:
Rewrote doc option description
Added doc examples
w_adj init nit resolved

 doc/filters.texi              | 36 +++++++++++++++++++++++++++++++++--
 libavfilter/scale_eval.c      | 13 +++++++------
 libavfilter/scale_eval.h      |  5 ++++-
 libavfilter/vf_libplacebo.c   |  2 +-
 libavfilter/vf_scale.c        | 13 +++++++++++--
 libavfilter/vf_scale_cuda.c   | 25 ++++++++++++++++++------
 libavfilter/vf_scale_npp.c    | 13 +++++++++++--
 libavfilter/vf_scale_vaapi.c  | 13 +++++++++++--
 libavfilter/vf_scale_vt.c     |  2 +-
 libavfilter/vf_scale_vulkan.c |  2 +-
 10 files changed, 100 insertions(+), 24 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index a14c7e7e77..bf9a60712f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21285,6 +21285,14 @@ This option can be handy if you need to have a video fit within or exceed
 a defined resolution using @option{force_original_aspect_ratio} but also have
 encoder restrictions on width or height divisibility.
 
+@item reset_sar
+Enabling this option leads to the output SAR being reset to 1.
+Additionally, if the user requests proportional scaling either
+through the width or height expressions, e.g. @code{w=-4:h=360} or @code{w=iw/2:h=-1}
+or by enabling @code{force_original_aspect_ratio}, then the input DAR is taken into
+account and the output is scaled to produce square pixels.
+Default is false.
+
 @end table
 
 The values of the @option{w} and @option{h} options are expressions
@@ -21445,10 +21453,28 @@ scale='trunc(ih*dar):ih',setsar=1/1
 @end example
 
 @item
-Make pixels square by combining scale and setsar,
+Make pixels square using reset_sar,
 making sure the resulting resolution is even (required by some codecs):
 @example
-scale='trunc(ih*dar/2)*2:trunc(ih/2)*2',setsar=1/1
+scale='-2:ih-mod(ih,2):reset_sar=1'
+@end example
+
+@item
+Scale to target exactly, however reset SAR to 1:
+@example
+scale='400:300:reset_sar=1'
+@end example
+
+@item
+Scale to even dimensions that fit within 400x300, preserving input SAR:
+@example
+scale='400:300:force_original_aspect_ratio=decrease:force_divisible_by=2'
+@end example
+
+@item
+Scale to produce square pixels with even dimensions that fit within 400x300:
+@example
+scale='400:300:force_original_aspect_ratio=decrease:force_divisible_by=2:reset_sar=1'
 @end example
 
 @item
@@ -21538,6 +21564,9 @@ Affects the curves of the bicubic algorithm.
 @item force_divisible_by
 Work the same as the identical @ref{scale} filter options.
 
+@item reset_sar
+Works the same as the identical @ref{scale} filter option.
+
 @end table
 
 @subsection Examples
@@ -21641,6 +21670,9 @@ This option can be handy if you need to have a video fit within or exceed
 a defined resolution using @option{force_original_aspect_ratio} but also have
 encoder restrictions on width or height divisibility.
 
+@item reset_sar
+Works the same as the identical @ref{scale} filter option.
+
 @item eval
 Specify when to evaluate @var{width} and @var{height} expression. It accepts the following values:
 
diff --git a/libavfilter/scale_eval.c b/libavfilter/scale_eval.c
index dc8d522b1e..53f5e22b0e 100644
--- a/libavfilter/scale_eval.c
+++ b/libavfilter/scale_eval.c
@@ -112,7 +112,8 @@ fail:
 
 int ff_scale_adjust_dimensions(AVFilterLink *inlink,
     int *ret_w, int *ret_h,
-    int force_original_aspect_ratio, int force_divisible_by)
+    int force_original_aspect_ratio, int force_divisible_by,
+    double w_adj)
 {
     int64_t w, h;
     int factor_w, factor_h;
@@ -132,7 +133,7 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink,
     }
 
     if (w < 0 && h < 0) {
-        w = inlink->w;
+        w = inlink->w * w_adj;
         h = inlink->h;
     }
 
@@ -140,18 +141,18 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink,
      * earlier. If no factor was set, nothing will happen as the default
      * factor is 1 */
     if (w < 0)
-        w = av_rescale(h, inlink->w, inlink->h * factor_w) * factor_w;
+        w = av_rescale(h, inlink->w * w_adj, inlink->h * factor_w) * factor_w;
     if (h < 0)
-        h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h;
+        h = av_rescale(w, inlink->h, inlink->w * w_adj * factor_h) * factor_h;
 
     /* Note that force_original_aspect_ratio may overwrite the previous set
      * dimensions so that it is not divisible by the set factors anymore
      * unless force_divisible_by is defined as well */
     if (force_original_aspect_ratio) {
         // Including force_divisible_by here rounds to the nearest multiple of it.
-        int64_t tmp_w = av_rescale(h, inlink->w, inlink->h * (int64_t)force_divisible_by)
+        int64_t tmp_w = av_rescale(h, inlink->w * w_adj, inlink->h * (int64_t)force_divisible_by)
                     * force_divisible_by;
-        int64_t tmp_h = av_rescale(w, inlink->h, inlink->w * (int64_t)force_divisible_by)
+        int64_t tmp_h = av_rescale(w, inlink->h, inlink->w * w_adj * (int64_t)force_divisible_by)
                     * force_divisible_by;
 
         if (force_original_aspect_ratio == 1) {
diff --git a/libavfilter/scale_eval.h b/libavfilter/scale_eval.h
index b489528404..6cab623e1c 100644
--- a/libavfilter/scale_eval.h
+++ b/libavfilter/scale_eval.h
@@ -40,10 +40,13 @@ int ff_scale_eval_dimensions(void *ctx,
  * or both of the evaluated values are of the form '-n' or if
  * force_original_aspect_ratio is set. force_divisible_by is used only when
  * force_original_aspect_ratio is set and must be at least 1.
+ * w_adj is the input SAR when the output dimensions are intended to be square
+ * pixels, else should be 1.
  *
  * Returns negative error code on error or non negative on success
  */
 int ff_scale_adjust_dimensions(AVFilterLink *inlink,
     int *ret_w, int *ret_h,
-    int force_original_aspect_ratio, int force_divisible_by);
+    int force_original_aspect_ratio, int force_divisible_by,
+    double w_adj);
 #endif
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index c884c621c8..e1c6629f6d 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -1201,7 +1201,7 @@ static int libplacebo_config_output(AVFilterLink *outlink)
 
     ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
                                s->force_original_aspect_ratio,
-                               s->force_divisible_by);
+                               s->force_divisible_by, 1.f);
 
     if (s->normalize_sar || s->nb_inputs > 1) {
         /* SAR is normalized, or we have multiple inputs, set out to 1:1 */
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 14ce1fbbd8..4b0b08d9d4 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -176,6 +176,7 @@ typedef struct ScaleContext {
 
     int force_original_aspect_ratio;
     int force_divisible_by;
+    int reset_sar;
 
     int eval_mode;              ///< expression evaluation mode
 
@@ -645,6 +646,7 @@ static int config_props(AVFilterLink *outlink)
                             outlink->src->inputs[0];
     ScaleContext *scale = ctx->priv;
     uint8_t *flags_val = NULL;
+    double w_adj = 1.0;
     int ret;
 
     if ((ret = scale_eval_dimensions(ctx)) < 0)
@@ -653,9 +655,13 @@ static int config_props(AVFilterLink *outlink)
     outlink->w = scale->w;
     outlink->h = scale->h;
 
+    if (scale->reset_sar)
+        w_adj = IS_SCALE2REF(ctx) ? scale->var_values[VAR_S2R_MAIN_SAR] :
+                                    scale->var_values[VAR_SAR];
+
     ret = ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
                                scale->force_original_aspect_ratio,
-                               scale->force_divisible_by);
+                               scale->force_divisible_by, w_adj);
 
     if (ret < 0)
         goto fail;
@@ -668,7 +674,9 @@ static int config_props(AVFilterLink *outlink)
 
     /* TODO: make algorithm configurable */
 
-    if (inlink0->sample_aspect_ratio.num){
+    if (scale->reset_sar)
+        outlink->sample_aspect_ratio = (AVRational){1, 1};
+    else if (inlink0->sample_aspect_ratio.num){
         outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio);
     } else
         outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;
@@ -1175,6 +1183,7 @@ static const AVOption scale_options[] = {
     { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
     { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
+    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
     { "param0", "Scaler param 0",             OFFSET(param[0]),  AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX  }, -DBL_MAX, DBL_MAX, FLAGS },
     { "param1", "Scaler param 1",             OFFSET(param[1]),  AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX  }, -DBL_MAX, DBL_MAX, FLAGS },
     { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c
index 5f9fd59118..de1883a1df 100644
--- a/libavfilter/vf_scale_cuda.c
+++ b/libavfilter/vf_scale_cuda.c
@@ -96,6 +96,7 @@ typedef struct CUDAScaleContext {
 
     int force_original_aspect_ratio;
     int force_divisible_by;
+    int reset_sar;
 
     CUcontext   cu_ctx;
     CUmodule    cu_module;
@@ -355,6 +356,7 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
     AVHWFramesContext     *frames_ctx;
     AVCUDADeviceContext *device_hwctx;
     int w, h;
+    double w_adj = 1.0;
     int ret;
 
     if ((ret = ff_scale_eval_dimensions(s,
@@ -363,8 +365,12 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
                                         &w, &h)) < 0)
         goto fail;
 
+    if (s->reset_sar)
+        w_adj = inlink->sample_aspect_ratio.num ?
+        (double)inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
+
     ff_scale_adjust_dimensions(inlink, &w, &h,
-                               s->force_original_aspect_ratio, s->force_divisible_by);
+                               s->force_original_aspect_ratio, s->force_divisible_by, w_adj);
 
     if (((int64_t)h * inlink->w) > INT_MAX  ||
         ((int64_t)w * inlink->h) > INT_MAX)
@@ -383,7 +389,9 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
     s->hwctx = device_hwctx;
     s->cu_stream = s->hwctx->stream;
 
-    if (inlink->sample_aspect_ratio.num) {
+    if (s->reset_sar)
+        outlink->sample_aspect_ratio = (AVRational){1, 1};
+    else if (inlink->sample_aspect_ratio.num) {
         outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
                                                              outlink->w*inlink->h},
                                                 inlink->sample_aspect_ratio);
@@ -574,10 +582,14 @@ static int cudascale_filter_frame(AVFilterLink *link, AVFrame *in)
     if (ret < 0)
         goto fail;
 
-    av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
-              (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
-              (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
-              INT_MAX);
+    if (s->reset_sar) {
+        out->sample_aspect_ratio = (AVRational){1, 1};
+    } else {
+        av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
+                  (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
+                  (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
+                  INT_MAX);
+    } 
 
     av_frame_free(&in);
     return ff_filter_frame(outlink, out);
@@ -614,6 +626,7 @@ static const AVOption options[] = {
         { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
         { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
+    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
     { NULL },
 };
 
diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c
index ec3267801b..5274158f1b 100644
--- a/libavfilter/vf_scale_npp.c
+++ b/libavfilter/vf_scale_npp.c
@@ -160,6 +160,7 @@ typedef struct NPPScaleContext {
 
     int force_original_aspect_ratio;
     int force_divisible_by;
+    int reset_sar;
 
     int interp_algo;
 
@@ -650,14 +651,19 @@ static int config_props(AVFilterLink *outlink)
                             outlink->src->inputs[1] :
                             outlink->src->inputs[0];
     NPPScaleContext *s = ctx->priv;
+    double w_adj = 1.0;
     int ret;
 
     if ((ret = nppscale_eval_dimensions(ctx)) < 0)
         goto fail;
 
+    if (s->reset_sar)
+        w_adj = IS_SCALE2REF(ctx) ? s->var_values[VAR_S2R_MAIN_SAR] :
+                                    s->var_values[VAR_SAR];
+
     ff_scale_adjust_dimensions(inlink, &s->w, &s->h,
                                s->force_original_aspect_ratio,
-                               s->force_divisible_by);
+                               s->force_divisible_by, w_adj);
 
     if (s->w > INT_MAX || s->h > INT_MAX ||
         (s->h * inlink->w) > INT_MAX ||
@@ -674,7 +680,9 @@ static int config_props(AVFilterLink *outlink)
     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
            inlink->w, inlink->h, outlink->w, outlink->h);
 
-    if (inlink->sample_aspect_ratio.num)
+    if (s->reset_sar)
+        outlink->sample_aspect_ratio = (AVRational){1, 1};
+    else if (inlink->sample_aspect_ratio.num)
         outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
                                                              outlink->w*inlink->h},
                                                 inlink->sample_aspect_ratio);
@@ -1019,6 +1027,7 @@ static const AVOption options[] = {
     { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
     { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
+    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
     { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, { .i64 = EVAL_MODE_INIT }, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
          { "init",  "eval expressions once during initialization",          0, AV_OPT_TYPE_CONST, { .i64 = EVAL_MODE_INIT  }, 0, 0, FLAGS, .unit = "eval" },
          { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, { .i64 = EVAL_MODE_FRAME }, 0, 0, FLAGS, .unit = "eval" },
diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c
index 0f2d617996..ab95d41e0e 100644
--- a/libavfilter/vf_scale_vaapi.c
+++ b/libavfilter/vf_scale_vaapi.c
@@ -39,6 +39,7 @@ typedef struct ScaleVAAPIContext {
 
     int force_original_aspect_ratio;
     int force_divisible_by;
+    int reset_sar;
 
     char *colour_primaries_string;
     char *colour_transfer_string;
@@ -73,6 +74,7 @@ static int scale_vaapi_config_output(AVFilterLink *outlink)
     AVFilterContext *avctx   = outlink->src;
     VAAPIVPPContext *vpp_ctx = avctx->priv;
     ScaleVAAPIContext *ctx   = avctx->priv;
+    double w_adj = 1.0;
     int err;
 
     if ((err = ff_scale_eval_dimensions(ctx,
@@ -81,8 +83,12 @@ static int scale_vaapi_config_output(AVFilterLink *outlink)
                                         &vpp_ctx->output_width, &vpp_ctx->output_height)) < 0)
         return err;
 
+    if (ctx->reset_sar)
+        w_adj = inlink->sample_aspect_ratio.num ?
+        (double)inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
+
     ff_scale_adjust_dimensions(inlink, &vpp_ctx->output_width, &vpp_ctx->output_height,
-                               ctx->force_original_aspect_ratio, ctx->force_divisible_by);
+                               ctx->force_original_aspect_ratio, ctx->force_divisible_by, w_adj);
 
     if (inlink->w == vpp_ctx->output_width && inlink->h == vpp_ctx->output_height &&
         (vpp_ctx->input_frames->sw_format == vpp_ctx->output_format ||
@@ -98,7 +104,9 @@ static int scale_vaapi_config_output(AVFilterLink *outlink)
     if (err < 0)
         return err;
 
-    if (inlink->sample_aspect_ratio.num)
+    if (ctx->reset_sar)
+        outlink->sample_aspect_ratio = (AVRational){1, 1};
+    else if (inlink->sample_aspect_ratio.num)
         outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio);
     else
         outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
@@ -274,6 +282,7 @@ static const AVOption scale_vaapi_options[] = {
     { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
     { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
+    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
 
     { NULL },
 };
diff --git a/libavfilter/vf_scale_vt.c b/libavfilter/vf_scale_vt.c
index 162ea8fcec..c024717bc2 100644
--- a/libavfilter/vf_scale_vt.c
+++ b/libavfilter/vf_scale_vt.c
@@ -248,7 +248,7 @@ static int scale_vt_config_output(AVFilterLink *outlink)
     if (err < 0)
         return err;
 
-    ff_scale_adjust_dimensions(inlink, &s->output_width, &s->output_height, 0, 1);
+    ff_scale_adjust_dimensions(inlink, &s->output_width, &s->output_height, 0, 1, 1.f);
 
     outlink->w = s->output_width;
     outlink->h = s->output_height;
diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
index 6f99769d81..1d6492e213 100644
--- a/libavfilter/vf_scale_vulkan.c
+++ b/libavfilter/vf_scale_vulkan.c
@@ -336,7 +336,7 @@ static int scale_vulkan_config_output(AVFilterLink *outlink)
     if (err < 0)
         return err;
 
-    ff_scale_adjust_dimensions(inlink, &vkctx->output_width, &vkctx->output_height, 0, 1);
+    ff_scale_adjust_dimensions(inlink, &vkctx->output_width, &vkctx->output_height, 0, 1, 1.f);
 
     outlink->w = vkctx->output_width;
     outlink->h = vkctx->output_height;
-- 
2.46.1

_______________________________________________
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] 2+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2] avfilter/scale*: add option reset_sar
  2025-02-09 10:11 [FFmpeg-devel] [PATCH v2] avfilter/scale*: add option reset_sar Gyan Doshi
@ 2025-02-10 10:56 ` Gyan Doshi
  0 siblings, 0 replies; 2+ messages in thread
From: Gyan Doshi @ 2025-02-10 10:56 UTC (permalink / raw)
  To: ffmpeg-devel



On 2025-02-09 03:41 pm, Gyan Doshi wrote:
> For anamorphic videos, enabling this option leads to adjustment of
> output dimensions to obtain square pixels when the user requests
> proportional scaling through either of the w/h expressions or
> force_original_aspect_ratio.
>
> Output SAR is always reset to 1.
>
> Option added to scale, scale_cuda, scale_npp & scale_vaapi.
>
> libplacebo already has a similar option with different semantics,
> scale_vt and scale_vulkan don't implement force_oar, so for these
> three filters, I've made minimal changes needed to not break building
> or change output.
> ---
> v2:
> Rewrote doc option description
> Added doc examples
> w_adj init nit resolved

Pushed as a28dc06869fe1f98c07e42f9b0a411d2744ff7d7

Regards,
Gyan


>
>   doc/filters.texi              | 36 +++++++++++++++++++++++++++++++++--
>   libavfilter/scale_eval.c      | 13 +++++++------
>   libavfilter/scale_eval.h      |  5 ++++-
>   libavfilter/vf_libplacebo.c   |  2 +-
>   libavfilter/vf_scale.c        | 13 +++++++++++--
>   libavfilter/vf_scale_cuda.c   | 25 ++++++++++++++++++------
>   libavfilter/vf_scale_npp.c    | 13 +++++++++++--
>   libavfilter/vf_scale_vaapi.c  | 13 +++++++++++--
>   libavfilter/vf_scale_vt.c     |  2 +-
>   libavfilter/vf_scale_vulkan.c |  2 +-
>   10 files changed, 100 insertions(+), 24 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index a14c7e7e77..bf9a60712f 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -21285,6 +21285,14 @@ This option can be handy if you need to have a video fit within or exceed
>   a defined resolution using @option{force_original_aspect_ratio} but also have
>   encoder restrictions on width or height divisibility.
>   
> +@item reset_sar
> +Enabling this option leads to the output SAR being reset to 1.
> +Additionally, if the user requests proportional scaling either
> +through the width or height expressions, e.g. @code{w=-4:h=360} or @code{w=iw/2:h=-1}
> +or by enabling @code{force_original_aspect_ratio}, then the input DAR is taken into
> +account and the output is scaled to produce square pixels.
> +Default is false.
> +
>   @end table
>   
>   The values of the @option{w} and @option{h} options are expressions
> @@ -21445,10 +21453,28 @@ scale='trunc(ih*dar):ih',setsar=1/1
>   @end example
>   
>   @item
> -Make pixels square by combining scale and setsar,
> +Make pixels square using reset_sar,
>   making sure the resulting resolution is even (required by some codecs):
>   @example
> -scale='trunc(ih*dar/2)*2:trunc(ih/2)*2',setsar=1/1
> +scale='-2:ih-mod(ih,2):reset_sar=1'
> +@end example
> +
> +@item
> +Scale to target exactly, however reset SAR to 1:
> +@example
> +scale='400:300:reset_sar=1'
> +@end example
> +
> +@item
> +Scale to even dimensions that fit within 400x300, preserving input SAR:
> +@example
> +scale='400:300:force_original_aspect_ratio=decrease:force_divisible_by=2'
> +@end example
> +
> +@item
> +Scale to produce square pixels with even dimensions that fit within 400x300:
> +@example
> +scale='400:300:force_original_aspect_ratio=decrease:force_divisible_by=2:reset_sar=1'
>   @end example
>   
>   @item
> @@ -21538,6 +21564,9 @@ Affects the curves of the bicubic algorithm.
>   @item force_divisible_by
>   Work the same as the identical @ref{scale} filter options.
>   
> +@item reset_sar
> +Works the same as the identical @ref{scale} filter option.
> +
>   @end table
>   
>   @subsection Examples
> @@ -21641,6 +21670,9 @@ This option can be handy if you need to have a video fit within or exceed
>   a defined resolution using @option{force_original_aspect_ratio} but also have
>   encoder restrictions on width or height divisibility.
>   
> +@item reset_sar
> +Works the same as the identical @ref{scale} filter option.
> +
>   @item eval
>   Specify when to evaluate @var{width} and @var{height} expression. It accepts the following values:
>   
> diff --git a/libavfilter/scale_eval.c b/libavfilter/scale_eval.c
> index dc8d522b1e..53f5e22b0e 100644
> --- a/libavfilter/scale_eval.c
> +++ b/libavfilter/scale_eval.c
> @@ -112,7 +112,8 @@ fail:
>   
>   int ff_scale_adjust_dimensions(AVFilterLink *inlink,
>       int *ret_w, int *ret_h,
> -    int force_original_aspect_ratio, int force_divisible_by)
> +    int force_original_aspect_ratio, int force_divisible_by,
> +    double w_adj)
>   {
>       int64_t w, h;
>       int factor_w, factor_h;
> @@ -132,7 +133,7 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink,
>       }
>   
>       if (w < 0 && h < 0) {
> -        w = inlink->w;
> +        w = inlink->w * w_adj;
>           h = inlink->h;
>       }
>   
> @@ -140,18 +141,18 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink,
>        * earlier. If no factor was set, nothing will happen as the default
>        * factor is 1 */
>       if (w < 0)
> -        w = av_rescale(h, inlink->w, inlink->h * factor_w) * factor_w;
> +        w = av_rescale(h, inlink->w * w_adj, inlink->h * factor_w) * factor_w;
>       if (h < 0)
> -        h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h;
> +        h = av_rescale(w, inlink->h, inlink->w * w_adj * factor_h) * factor_h;
>   
>       /* Note that force_original_aspect_ratio may overwrite the previous set
>        * dimensions so that it is not divisible by the set factors anymore
>        * unless force_divisible_by is defined as well */
>       if (force_original_aspect_ratio) {
>           // Including force_divisible_by here rounds to the nearest multiple of it.
> -        int64_t tmp_w = av_rescale(h, inlink->w, inlink->h * (int64_t)force_divisible_by)
> +        int64_t tmp_w = av_rescale(h, inlink->w * w_adj, inlink->h * (int64_t)force_divisible_by)
>                       * force_divisible_by;
> -        int64_t tmp_h = av_rescale(w, inlink->h, inlink->w * (int64_t)force_divisible_by)
> +        int64_t tmp_h = av_rescale(w, inlink->h, inlink->w * w_adj * (int64_t)force_divisible_by)
>                       * force_divisible_by;
>   
>           if (force_original_aspect_ratio == 1) {
> diff --git a/libavfilter/scale_eval.h b/libavfilter/scale_eval.h
> index b489528404..6cab623e1c 100644
> --- a/libavfilter/scale_eval.h
> +++ b/libavfilter/scale_eval.h
> @@ -40,10 +40,13 @@ int ff_scale_eval_dimensions(void *ctx,
>    * or both of the evaluated values are of the form '-n' or if
>    * force_original_aspect_ratio is set. force_divisible_by is used only when
>    * force_original_aspect_ratio is set and must be at least 1.
> + * w_adj is the input SAR when the output dimensions are intended to be square
> + * pixels, else should be 1.
>    *
>    * Returns negative error code on error or non negative on success
>    */
>   int ff_scale_adjust_dimensions(AVFilterLink *inlink,
>       int *ret_w, int *ret_h,
> -    int force_original_aspect_ratio, int force_divisible_by);
> +    int force_original_aspect_ratio, int force_divisible_by,
> +    double w_adj);
>   #endif
> diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> index c884c621c8..e1c6629f6d 100644
> --- a/libavfilter/vf_libplacebo.c
> +++ b/libavfilter/vf_libplacebo.c
> @@ -1201,7 +1201,7 @@ static int libplacebo_config_output(AVFilterLink *outlink)
>   
>       ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
>                                  s->force_original_aspect_ratio,
> -                               s->force_divisible_by);
> +                               s->force_divisible_by, 1.f);
>   
>       if (s->normalize_sar || s->nb_inputs > 1) {
>           /* SAR is normalized, or we have multiple inputs, set out to 1:1 */
> diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
> index 14ce1fbbd8..4b0b08d9d4 100644
> --- a/libavfilter/vf_scale.c
> +++ b/libavfilter/vf_scale.c
> @@ -176,6 +176,7 @@ typedef struct ScaleContext {
>   
>       int force_original_aspect_ratio;
>       int force_divisible_by;
> +    int reset_sar;
>   
>       int eval_mode;              ///< expression evaluation mode
>   
> @@ -645,6 +646,7 @@ static int config_props(AVFilterLink *outlink)
>                               outlink->src->inputs[0];
>       ScaleContext *scale = ctx->priv;
>       uint8_t *flags_val = NULL;
> +    double w_adj = 1.0;
>       int ret;
>   
>       if ((ret = scale_eval_dimensions(ctx)) < 0)
> @@ -653,9 +655,13 @@ static int config_props(AVFilterLink *outlink)
>       outlink->w = scale->w;
>       outlink->h = scale->h;
>   
> +    if (scale->reset_sar)
> +        w_adj = IS_SCALE2REF(ctx) ? scale->var_values[VAR_S2R_MAIN_SAR] :
> +                                    scale->var_values[VAR_SAR];
> +
>       ret = ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
>                                  scale->force_original_aspect_ratio,
> -                               scale->force_divisible_by);
> +                               scale->force_divisible_by, w_adj);
>   
>       if (ret < 0)
>           goto fail;
> @@ -668,7 +674,9 @@ static int config_props(AVFilterLink *outlink)
>   
>       /* TODO: make algorithm configurable */
>   
> -    if (inlink0->sample_aspect_ratio.num){
> +    if (scale->reset_sar)
> +        outlink->sample_aspect_ratio = (AVRational){1, 1};
> +    else if (inlink0->sample_aspect_ratio.num){
>           outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio);
>       } else
>           outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;
> @@ -1175,6 +1183,7 @@ static const AVOption scale_options[] = {
>       { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
>       { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
> +    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
>       { "param0", "Scaler param 0",             OFFSET(param[0]),  AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX  }, -DBL_MAX, DBL_MAX, FLAGS },
>       { "param1", "Scaler param 1",             OFFSET(param[1]),  AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX  }, -DBL_MAX, DBL_MAX, FLAGS },
>       { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
> diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c
> index 5f9fd59118..de1883a1df 100644
> --- a/libavfilter/vf_scale_cuda.c
> +++ b/libavfilter/vf_scale_cuda.c
> @@ -96,6 +96,7 @@ typedef struct CUDAScaleContext {
>   
>       int force_original_aspect_ratio;
>       int force_divisible_by;
> +    int reset_sar;
>   
>       CUcontext   cu_ctx;
>       CUmodule    cu_module;
> @@ -355,6 +356,7 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
>       AVHWFramesContext     *frames_ctx;
>       AVCUDADeviceContext *device_hwctx;
>       int w, h;
> +    double w_adj = 1.0;
>       int ret;
>   
>       if ((ret = ff_scale_eval_dimensions(s,
> @@ -363,8 +365,12 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
>                                           &w, &h)) < 0)
>           goto fail;
>   
> +    if (s->reset_sar)
> +        w_adj = inlink->sample_aspect_ratio.num ?
> +        (double)inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
> +
>       ff_scale_adjust_dimensions(inlink, &w, &h,
> -                               s->force_original_aspect_ratio, s->force_divisible_by);
> +                               s->force_original_aspect_ratio, s->force_divisible_by, w_adj);
>   
>       if (((int64_t)h * inlink->w) > INT_MAX  ||
>           ((int64_t)w * inlink->h) > INT_MAX)
> @@ -383,7 +389,9 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink)
>       s->hwctx = device_hwctx;
>       s->cu_stream = s->hwctx->stream;
>   
> -    if (inlink->sample_aspect_ratio.num) {
> +    if (s->reset_sar)
> +        outlink->sample_aspect_ratio = (AVRational){1, 1};
> +    else if (inlink->sample_aspect_ratio.num) {
>           outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
>                                                                outlink->w*inlink->h},
>                                                   inlink->sample_aspect_ratio);
> @@ -574,10 +582,14 @@ static int cudascale_filter_frame(AVFilterLink *link, AVFrame *in)
>       if (ret < 0)
>           goto fail;
>   
> -    av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
> -              (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
> -              (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
> -              INT_MAX);
> +    if (s->reset_sar) {
> +        out->sample_aspect_ratio = (AVRational){1, 1};
> +    } else {
> +        av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
> +                  (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
> +                  (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
> +                  INT_MAX);
> +    }
>   
>       av_frame_free(&in);
>       return ff_filter_frame(outlink, out);
> @@ -614,6 +626,7 @@ static const AVOption options[] = {
>           { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
>           { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
> +    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
>       { NULL },
>   };
>   
> diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c
> index ec3267801b..5274158f1b 100644
> --- a/libavfilter/vf_scale_npp.c
> +++ b/libavfilter/vf_scale_npp.c
> @@ -160,6 +160,7 @@ typedef struct NPPScaleContext {
>   
>       int force_original_aspect_ratio;
>       int force_divisible_by;
> +    int reset_sar;
>   
>       int interp_algo;
>   
> @@ -650,14 +651,19 @@ static int config_props(AVFilterLink *outlink)
>                               outlink->src->inputs[1] :
>                               outlink->src->inputs[0];
>       NPPScaleContext *s = ctx->priv;
> +    double w_adj = 1.0;
>       int ret;
>   
>       if ((ret = nppscale_eval_dimensions(ctx)) < 0)
>           goto fail;
>   
> +    if (s->reset_sar)
> +        w_adj = IS_SCALE2REF(ctx) ? s->var_values[VAR_S2R_MAIN_SAR] :
> +                                    s->var_values[VAR_SAR];
> +
>       ff_scale_adjust_dimensions(inlink, &s->w, &s->h,
>                                  s->force_original_aspect_ratio,
> -                               s->force_divisible_by);
> +                               s->force_divisible_by, w_adj);
>   
>       if (s->w > INT_MAX || s->h > INT_MAX ||
>           (s->h * inlink->w) > INT_MAX ||
> @@ -674,7 +680,9 @@ static int config_props(AVFilterLink *outlink)
>       av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
>              inlink->w, inlink->h, outlink->w, outlink->h);
>   
> -    if (inlink->sample_aspect_ratio.num)
> +    if (s->reset_sar)
> +        outlink->sample_aspect_ratio = (AVRational){1, 1};
> +    else if (inlink->sample_aspect_ratio.num)
>           outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
>                                                                outlink->w*inlink->h},
>                                                   inlink->sample_aspect_ratio);
> @@ -1019,6 +1027,7 @@ static const AVOption options[] = {
>       { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
>       { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
> +    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
>       { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, { .i64 = EVAL_MODE_INIT }, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
>            { "init",  "eval expressions once during initialization",          0, AV_OPT_TYPE_CONST, { .i64 = EVAL_MODE_INIT  }, 0, 0, FLAGS, .unit = "eval" },
>            { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, { .i64 = EVAL_MODE_FRAME }, 0, 0, FLAGS, .unit = "eval" },
> diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c
> index 0f2d617996..ab95d41e0e 100644
> --- a/libavfilter/vf_scale_vaapi.c
> +++ b/libavfilter/vf_scale_vaapi.c
> @@ -39,6 +39,7 @@ typedef struct ScaleVAAPIContext {
>   
>       int force_original_aspect_ratio;
>       int force_divisible_by;
> +    int reset_sar;
>   
>       char *colour_primaries_string;
>       char *colour_transfer_string;
> @@ -73,6 +74,7 @@ static int scale_vaapi_config_output(AVFilterLink *outlink)
>       AVFilterContext *avctx   = outlink->src;
>       VAAPIVPPContext *vpp_ctx = avctx->priv;
>       ScaleVAAPIContext *ctx   = avctx->priv;
> +    double w_adj = 1.0;
>       int err;
>   
>       if ((err = ff_scale_eval_dimensions(ctx,
> @@ -81,8 +83,12 @@ static int scale_vaapi_config_output(AVFilterLink *outlink)
>                                           &vpp_ctx->output_width, &vpp_ctx->output_height)) < 0)
>           return err;
>   
> +    if (ctx->reset_sar)
> +        w_adj = inlink->sample_aspect_ratio.num ?
> +        (double)inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
> +
>       ff_scale_adjust_dimensions(inlink, &vpp_ctx->output_width, &vpp_ctx->output_height,
> -                               ctx->force_original_aspect_ratio, ctx->force_divisible_by);
> +                               ctx->force_original_aspect_ratio, ctx->force_divisible_by, w_adj);
>   
>       if (inlink->w == vpp_ctx->output_width && inlink->h == vpp_ctx->output_height &&
>           (vpp_ctx->input_frames->sw_format == vpp_ctx->output_format ||
> @@ -98,7 +104,9 @@ static int scale_vaapi_config_output(AVFilterLink *outlink)
>       if (err < 0)
>           return err;
>   
> -    if (inlink->sample_aspect_ratio.num)
> +    if (ctx->reset_sar)
> +        outlink->sample_aspect_ratio = (AVRational){1, 1};
> +    else if (inlink->sample_aspect_ratio.num)
>           outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio);
>       else
>           outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
> @@ -274,6 +282,7 @@ static const AVOption scale_vaapi_options[] = {
>       { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
>       { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .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, FLAGS },
> +    { "reset_sar", "scale output frame to have square pixels", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
>   
>       { NULL },
>   };
> diff --git a/libavfilter/vf_scale_vt.c b/libavfilter/vf_scale_vt.c
> index 162ea8fcec..c024717bc2 100644
> --- a/libavfilter/vf_scale_vt.c
> +++ b/libavfilter/vf_scale_vt.c
> @@ -248,7 +248,7 @@ static int scale_vt_config_output(AVFilterLink *outlink)
>       if (err < 0)
>           return err;
>   
> -    ff_scale_adjust_dimensions(inlink, &s->output_width, &s->output_height, 0, 1);
> +    ff_scale_adjust_dimensions(inlink, &s->output_width, &s->output_height, 0, 1, 1.f);
>   
>       outlink->w = s->output_width;
>       outlink->h = s->output_height;
> diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
> index 6f99769d81..1d6492e213 100644
> --- a/libavfilter/vf_scale_vulkan.c
> +++ b/libavfilter/vf_scale_vulkan.c
> @@ -336,7 +336,7 @@ static int scale_vulkan_config_output(AVFilterLink *outlink)
>       if (err < 0)
>           return err;
>   
> -    ff_scale_adjust_dimensions(inlink, &vkctx->output_width, &vkctx->output_height, 0, 1);
> +    ff_scale_adjust_dimensions(inlink, &vkctx->output_width, &vkctx->output_height, 0, 1, 1.f);
>   
>       outlink->w = vkctx->output_width;
>       outlink->h = vkctx->output_height;

_______________________________________________
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] 2+ messages in thread

end of thread, other threads:[~2025-02-10 10:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-09 10:11 [FFmpeg-devel] [PATCH v2] avfilter/scale*: add option reset_sar Gyan Doshi
2025-02-10 10:56 ` Gyan Doshi

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