From: Aman Gupta <a...@tmm1.net> Copied directly from vf_scale.c.
Implements the same expression logic, however not all the variables were copied over. This patch was sufficient for my particular use-case `scale_vaapi=-2:min(ih\,720)`, but perhaps it makes sense to add support for the remaining variables and pull out shared code into a new vf_scale_common.c? --- libavfilter/vf_scale_vaapi.c | 98 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index d1cb246..0d1e1b3 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -22,6 +22,7 @@ #include <va/va_vpp.h> #include "libavutil/avassert.h" +#include "libavutil/eval.h" #include "libavutil/hwcontext.h" #include "libavutil/hwcontext_vaapi.h" #include "libavutil/mem.h" @@ -32,6 +33,22 @@ #include "formats.h" #include "internal.h" +static const char *const var_names[] = { + "in_w", "iw", + "in_h", "ih", + "out_w", "ow", + "out_h", "oh", + NULL +}; + +enum var_name { + VAR_IN_W, VAR_IW, + VAR_IN_H, VAR_IH, + VAR_OUT_W, VAR_OW, + VAR_OUT_H, VAR_OH, + VARS_NB +}; + typedef struct ScaleVAAPIContext { const AVClass *class; @@ -50,9 +67,21 @@ typedef struct ScaleVAAPIContext { char *output_format_string; enum AVPixelFormat output_format; + + /** + * New dimensions. Special values are: + * 0 = original width/height + * -1 = keep original aspect + * -N = try to keep aspect but make sure it is divisible by N + */ + int w, h; + + char *w_expr; ///< width expression string + char *h_expr; ///< height expression string + + /* computed width/height */ int output_width; int output_height; - } ScaleVAAPIContext; @@ -118,6 +147,14 @@ static int scale_vaapi_config_output(AVFilterLink *outlink) VAStatus vas; int err, i; + AVFilterLink *inlink = outlink->src->inputs[0]; + ScaleVAAPIContext *scale = ctx; + int64_t w, h; + double var_values[VARS_NB], res; + char *expr; + int ret; + int factor_w, factor_h; + scale_vaapi_pipeline_uninit(ctx); ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref); @@ -162,6 +199,61 @@ static int scale_vaapi_config_output(AVFilterLink *outlink) } } + var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; + var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; + var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; + var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; + + /* evaluate width and height */ + av_expr_parse_and_eval(&res, (expr = scale->w_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx); + scale->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; + if ((ret = av_expr_parse_and_eval(&res, (expr = scale->h_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto fail; + scale->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res; + /* evaluate again the width, as it may depend on the output height */ + if ((ret = av_expr_parse_and_eval(&res, (expr = scale->w_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto fail; + scale->w = res; + + w = scale->w; + h = scale->h; + + /* Check if it is requested that the result has to be divisible by a some + * factor (w or h = -n with n being the factor). */ + factor_w = 1; + factor_h = 1; + if (w < -1) { + factor_w = -w; + } + if (h < -1) { + factor_h = -h; + } + + if (w < 0 && h < 0) + scale->w = scale->h = 0; + + if (!(w = scale->w)) + w = inlink->w; + if (!(h = scale->h)) + h = inlink->h; + + /* Make sure that the result is divisible by the factor we determined + * earlier. If no factor was set, it is nothing will happen as the default + * factor is 1 */ + if (w < 0) + w = av_rescale(h, inlink->w, inlink->h * factor_w) * factor_w; + if (h < 0) + h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h; + + ctx->output_width = w; + ctx->output_height = h; + if (ctx->output_width < constraints->min_width || ctx->output_height < constraints->min_height || ctx->output_width > constraints->max_width || @@ -414,9 +506,9 @@ static av_cold void scale_vaapi_uninit(AVFilterContext *avctx) #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM) static const AVOption scale_vaapi_options[] = { { "w", "Output video width", - OFFSET(output_width), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, + OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = FLAGS }, { "h", "Output video height", - OFFSET(output_height), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, + OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = FLAGS }, { "format", "Output video format (software format of hardware frames)", OFFSET(output_format_string), AV_OPT_TYPE_STRING, .flags = FLAGS }, { NULL }, -- 2.10.1 (Apple Git-78) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel