History

avfilter/scale_vulkan: add dynamic crop region and aspect ratio match

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.

Koushik Dutta committed 1 year ago

Commit 252fc2e1 parent 19c95ec1 file · +20 −6Browse files

Unified · Split

libavfilter/vf_scale_vulkan.c+20−6
@@ -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) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t