[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