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.
Unified · Split
| @@ -46,6 +46,10 @@ typedef struct ScaleVulkanContext { · 45 unmodified lines | |||
| 46 | /* Push constants / options */ | 46 | /* Push constants / options */ |
| 47 | struct { | 47 | struct { |
| 48 | float yuv_matrix[4][4]; | 48 | float yuv_matrix[4][4]; |
| 49 | int crop_x; | ||
| 50 | int crop_y; | ||
| 51 | int crop_w; | ||
| 52 | int crop_h; | ||
| 49 | } opts; | 53 | } opts; |
| 50 | 54 | ||
| 51 | char *out_format_string; | 55 | char *out_format_string; |
| @@ -121,10 +125,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) · 69 unmodified lines | |||
| 121 | FFVkSPIRVCompiler *spv; | 125 | FFVkSPIRVCompiler *spv; |
| 122 | FFVulkanDescriptorSetBinding *desc; | 126 | FFVulkanDescriptorSetBinding *desc; |
| 123 | 127 | ||
| 124 | int crop_x = in->crop_left; | ||
| 125 | int crop_y = in->crop_top; | ||
| 126 | int crop_w = in->width - (in->crop_left + in->crop_right); | ||
| 127 | int crop_h = in->height - (in->crop_top + in->crop_bottom); | ||
| 128 | int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format); | 128 | int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format); |
| 129 | 129 | ||
| 130 | switch (s->scaler) { | 130 | switch (s->scaler) { |
| @@ -159,6 +159,10 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) · 28 unmodified lines | |||
| 159 | 159 | ||
| 160 | GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); | 160 | GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); |
| 161 | GLSLC(1, mat4 yuv_matrix; ); | 161 | GLSLC(1, mat4 yuv_matrix; ); |
| 162 | GLSLC(1, int crop_x; ); | ||
| 163 | GLSLC(1, int crop_y; ); | ||
| 164 | GLSLC(1, int crop_w; ); | ||
| 165 | GLSLC(1, int crop_h; ); | ||
| 162 | GLSLC(0, }; ); | 166 | GLSLC(0, }; ); |
| 163 | GLSLC(0, ); | 167 | GLSLC(0, ); |
| 164 | 168 | ||
| @@ -205,8 +209,8 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) · 40 unmodified lines | |||
| 205 | GLSLC(1, ivec2 size; ); | 209 | GLSLC(1, ivec2 size; ); |
| 206 | GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); | 210 | GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); |
| 207 | GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height); | 211 | GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height); |
| 208 | GLSLF(1, vec2 c_r = vec2(%i, %i) / in_d; ,crop_w, crop_h); | 212 | GLSLC(1, vec2 c_r = vec2(crop_w, crop_h) / in_d; ); |
| 209 | GLSLF(1, vec2 c_o = vec2(%i, %i) / in_d; ,crop_x,crop_y); | 213 | GLSLC(1, vec2 c_o = vec2(crop_x, crop_y) / in_d; ); |
| 210 | GLSLC(0, ); | 214 | GLSLC(0, ); |
| 211 | 215 | ||
| 212 | if (s->vkctx.output_format == s->vkctx.input_format) { | 216 | if (s->vkctx.output_format == s->vkctx.input_format) { |
| @@ -286,6 +290,11 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) · 73 unmodified lines | |||
| 286 | if (!s->initialized) | 290 | if (!s->initialized) |
| 287 | RET(init_filter(ctx, in)); | 291 | RET(init_filter(ctx, in)); |
| 288 | 292 | ||
| 293 | s->opts.crop_x = in->crop_left; | ||
| 294 | s->opts.crop_y = in->crop_top; | ||
| 295 | s->opts.crop_w = in->width - (in->crop_left + in->crop_right); | ||
| 296 | s->opts.crop_h = in->height - (in->crop_top + in->crop_bottom); | ||
| 297 | |||
| 289 | RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, | 298 | RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, |
| 290 | s->sampler, &s->opts, sizeof(s->opts))); | 299 | s->sampler, &s->opts, sizeof(s->opts))); |
| 291 | 300 | ||
| @@ -327,6 +336,11 @@ static int scale_vulkan_config_output(AVFilterLink *outlink) · 35 unmodified lines | |||
| 327 | if (err < 0) | 336 | if (err < 0) |
| 328 | return err; | 337 | return err; |
| 329 | 338 | ||
| 339 | ff_scale_adjust_dimensions(inlink, &vkctx->output_width, &vkctx->output_height, 0, 1); | ||
| 340 | |||
| 341 | outlink->w = vkctx->output_width; | ||
| 342 | outlink->h = vkctx->output_height; | ||
| 343 | |||
| 330 | if (s->out_format_string) { | 344 | if (s->out_format_string) { |
| 331 | s->vkctx.output_format = av_get_pix_fmt(s->out_format_string); | 345 | s->vkctx.output_format = av_get_pix_fmt(s->out_format_string); |
| 332 | if (s->vkctx.output_format == AV_PIX_FMT_NONE) { | 346 | if (s->vkctx.output_format == AV_PIX_FMT_NONE) { |