You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-10-06 05:47:18 +02:00
avfilter/vf_libplacebo: introduce fit_sense
option
This allows choosing whether the `fit_mode` merely controls the placement of the image within the output resolution, or whether the output resolution is also adjusted according to the given `fit_mode`.
This commit is contained in:
@@ -16449,7 +16449,8 @@ will be performed.
|
|||||||
|
|
||||||
@item force_original_aspect_ratio
|
@item force_original_aspect_ratio
|
||||||
@item force_divisible_by
|
@item force_divisible_by
|
||||||
Work the same as the identical @ref{scale} filter options.
|
Work the same as the identical @ref{scale} filter options. Note that
|
||||||
|
@option{force_divisible_by} also works with @code{fit_sense=constraint}.
|
||||||
|
|
||||||
@item reset_sar
|
@item reset_sar
|
||||||
If enabled, output frames will always have a pixel aspect ratio of 1:1. If
|
If enabled, output frames will always have a pixel aspect ratio of 1:1. If
|
||||||
@@ -16503,6 +16504,22 @@ to either @code{contain} or @code{none}, depending on whether the input is
|
|||||||
larger than the output or not.
|
larger than the output or not.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item fit_sense
|
||||||
|
When @option{fit_mode} is in use, this option controls how the fit strategy
|
||||||
|
is applied against the specified output resolution. Mutually exclusive with
|
||||||
|
@option{force_original_aspect_ratio}. Valid values are:
|
||||||
|
|
||||||
|
@table @samp
|
||||||
|
@item target
|
||||||
|
The computed output resolution is taken as the exact size of the output frame.
|
||||||
|
This is the default behavior.
|
||||||
|
|
||||||
|
@item constraint
|
||||||
|
The computed output resolution is a size reference against which the fit mode
|
||||||
|
is applied, enlarging or decreasing the true frame size as needed to fit the
|
||||||
|
content.
|
||||||
|
@end table
|
||||||
|
|
||||||
@item fillcolor
|
@item fillcolor
|
||||||
Set the color used to fill the output area not covered by the output image, for
|
Set the color used to fill the output area not covered by the output image, for
|
||||||
example as a result of @option{normalize_sar}. For the general syntax of this
|
example as a result of @option{normalize_sar}. For the general syntax of this
|
||||||
|
@@ -161,6 +161,12 @@ enum fit_mode {
|
|||||||
FIT_MODE_NB,
|
FIT_MODE_NB,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum fit_sense {
|
||||||
|
FIT_TARGET,
|
||||||
|
FIT_CONSTRAINT,
|
||||||
|
FIT_SENSE_NB,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct LibplaceboContext {
|
typedef struct LibplaceboContext {
|
||||||
/* lavfi vulkan*/
|
/* lavfi vulkan*/
|
||||||
FFVulkanContext vkctx;
|
FFVulkanContext vkctx;
|
||||||
@@ -206,6 +212,7 @@ typedef struct LibplaceboContext {
|
|||||||
int reset_sar;
|
int reset_sar;
|
||||||
int normalize_sar;
|
int normalize_sar;
|
||||||
int fit_mode;
|
int fit_mode;
|
||||||
|
int fit_sense;
|
||||||
int apply_filmgrain;
|
int apply_filmgrain;
|
||||||
int apply_dovi;
|
int apply_dovi;
|
||||||
int colorspace;
|
int colorspace;
|
||||||
@@ -1452,11 +1459,24 @@ static int libplacebo_config_output(AVFilterLink *outlink)
|
|||||||
double sar_in = inlink->sample_aspect_ratio.num ?
|
double sar_in = inlink->sample_aspect_ratio.num ?
|
||||||
av_q2d(inlink->sample_aspect_ratio) : 1.0;
|
av_q2d(inlink->sample_aspect_ratio) : 1.0;
|
||||||
|
|
||||||
|
int force_oar = s->force_original_aspect_ratio;
|
||||||
|
if (!force_oar && s->fit_sense == FIT_CONSTRAINT) {
|
||||||
|
if (s->fit_mode == FIT_CONTAIN || s->fit_mode == FIT_SCALE_DOWN) {
|
||||||
|
force_oar = SCALE_FORCE_OAR_DECREASE;
|
||||||
|
} else if (s->fit_mode == FIT_COVER) {
|
||||||
|
force_oar = SCALE_FORCE_OAR_INCREASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
|
ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
|
||||||
s->force_original_aspect_ratio,
|
force_oar, s->force_divisible_by,
|
||||||
s->force_divisible_by,
|
|
||||||
s->reset_sar ? sar_in : 1.0);
|
s->reset_sar ? sar_in : 1.0);
|
||||||
|
|
||||||
|
if (s->fit_mode == FIT_SCALE_DOWN && s->fit_sense == FIT_CONSTRAINT) {
|
||||||
|
int w_adj = s->reset_sar ? sar_in * inlink->w : inlink->w;
|
||||||
|
outlink->w = FFMIN(outlink->w, w_adj);
|
||||||
|
outlink->h = FFMIN(outlink->h, inlink->h);
|
||||||
|
}
|
||||||
|
|
||||||
if (s->nb_inputs > 1 && !s->disable_fbos) {
|
if (s->nb_inputs > 1 && !s->disable_fbos) {
|
||||||
/* Create a separate renderer and composition texture */
|
/* Create a separate renderer and composition texture */
|
||||||
@@ -1586,6 +1606,9 @@ static const AVOption libplacebo_options[] = {
|
|||||||
{ "none", "Keep input unscaled, padding and cropping as needed", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_NONE }, 0, 0, STATIC, .unit = "fit_mode" },
|
{ "none", "Keep input unscaled, padding and cropping as needed", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_NONE }, 0, 0, STATIC, .unit = "fit_mode" },
|
||||||
{ "place", "Keep input unscaled, padding and cropping as needed", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_NONE }, 0, 0, STATIC, .unit = "fit_mode" },
|
{ "place", "Keep input unscaled, padding and cropping as needed", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_NONE }, 0, 0, STATIC, .unit = "fit_mode" },
|
||||||
{ "scale_down", "Downscale only if larger, padding to preserve aspect", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_SCALE_DOWN }, 0, 0, STATIC, .unit = "fit_mode" },
|
{ "scale_down", "Downscale only if larger, padding to preserve aspect", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_SCALE_DOWN }, 0, 0, STATIC, .unit = "fit_mode" },
|
||||||
|
{ "fit_sense", "Output size strategy (for the base layer only)", OFFSET(fit_sense), AV_OPT_TYPE_INT, {.i64 = FIT_TARGET }, 0, FIT_SENSE_NB - 1, STATIC, .unit = "fit_sense" },
|
||||||
|
{ "target", "Computed resolution is the exact output size", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_TARGET }, 0, 0, STATIC, .unit = "fit_sense" },
|
||||||
|
{ "constraint", "Computed resolution constrains the output size", 0, AV_OPT_TYPE_CONST, {.i64 = FIT_CONSTRAINT }, 0, 0, STATIC, .unit = "fit_sense" },
|
||||||
{ "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_COLOR, {.str = "black@0"}, .flags = 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 },
|
{ "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
|
||||||
{ "lut", "Path to custom LUT file to apply", OFFSET(lut_filename), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = STATIC },
|
{ "lut", "Path to custom LUT file to apply", OFFSET(lut_filename), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = STATIC },
|
||||||
|
Reference in New Issue
Block a user