[FFmpeg-devel] [PATCH] avfilter/scale_vulkan: add dynamic crop region and aspect ratio match

Lynne dev at lynne.ee
Tue Jan 7 01:37:49 EET 2025


On 27/11/2024 01:21, Koushik Dutta wrote:
> The scale_vulkan filter initializes the shader once, with the crop
> region set by the original frame. However, subsequent frames may
> specify a different crop region than the first frame. This change
> updates the cropping to match the behavior present on the other
> hardware frame scale filters.
> 
> The scale filter should also allow negative values
> that respect aspect ratio, similar to other scale filters.
> 
> Signed-off-by: Koushik Dutta <koushd at gmail.com>
> ---
>   libavfilter/vf_scale_vulkan.c | 26 ++++++++++++++++++++------
>   1 file changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
> index d675a309a8..2f4193ee85 100644
> --- a/libavfilter/vf_scale_vulkan.c
> +++ b/libavfilter/vf_scale_vulkan.c
> @@ -46,6 +46,10 @@ typedef struct ScaleVulkanContext {
>       /* Push constants / options */
>       struct {
>           float yuv_matrix[4][4];
> +        int crop_x;
> +        int crop_y;
> +        int crop_w;
> +        int crop_h;
>       } opts;
>   
>       char *out_format_string;
> @@ -121,10 +125,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
>       FFVkSPIRVCompiler *spv;
>       FFVulkanDescriptorSetBinding *desc;
>   
> -    int crop_x = in->crop_left;
> -    int crop_y = in->crop_top;
> -    int crop_w = in->width - (in->crop_left + in->crop_right);
> -    int crop_h = in->height - (in->crop_top + in->crop_bottom);
>       int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format);
>   
>       switch (s->scaler) {
> @@ -153,6 +153,10 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
>   
>       GLSLC(0, layout(push_constant, std430) uniform pushConstants {        );
>       GLSLC(1,    mat4 yuv_matrix;                                          );
> +    GLSLC(1,    int crop_x;                                               );
> +    GLSLC(1,    int crop_y;                                               );
> +    GLSLC(1,    int crop_w;                                               );
> +    GLSLC(1,    int crop_h;                                               );
>       GLSLC(0, };                                                           );
>       GLSLC(0,                                                              );
>   
> @@ -199,8 +203,8 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
>       GLSLC(1,     ivec2 size;                                                 );
>       GLSLC(1,     ivec2 pos = ivec2(gl_GlobalInvocationID.xy);                );
>       GLSLF(1,     vec2 in_d = vec2(%i, %i);             ,in->width, in->height);
> -    GLSLF(1,     vec2 c_r = vec2(%i, %i) / in_d;              ,crop_w, crop_h);
> -    GLSLF(1,     vec2 c_o = vec2(%i, %i) / in_d;               ,crop_x,crop_y);
> +    GLSLC(1,     vec2 c_r = vec2(crop_w, crop_h) / in_d;                     );
> +    GLSLC(1,     vec2 c_o = vec2(crop_x, crop_y) / in_d;                     );
>       GLSLC(0,                                                                 );
>   
>       if (s->vkctx.output_format == s->vkctx.input_format) {
> @@ -280,6 +284,11 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
>       if (!s->initialized)
>           RET(init_filter(ctx, in));
>   
> +    s->opts.crop_x = in->crop_left;
> +    s->opts.crop_y = in->crop_top;
> +    s->opts.crop_w = in->width - (in->crop_left + in->crop_right);
> +    s->opts.crop_h = in->height - (in->crop_top + in->crop_bottom);
> +
>       RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
>                                       s->sampler, &s->opts, sizeof(s->opts)));
>   
> @@ -316,6 +325,11 @@ 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);
> +
> +    outlink->w = vkctx->output_width;
> +    outlink->h = vkctx->output_height;
> +
>       if (s->out_format_string) {
>           s->vkctx.output_format = av_get_pix_fmt(s->out_format_string);
>           if (s->vkctx.output_format == AV_PIX_FMT_NONE) {

Thanks, pushed
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xA2FEA5F03F034464.asc
Type: application/pgp-keys
Size: 624 bytes
Desc: OpenPGP public key
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20250107/17c7c20e/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 236 bytes
Desc: OpenPGP digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20250107/17c7c20e/attachment.sig>


More information about the ffmpeg-devel mailing list