Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -112,6 +112,78 @@ static const char write_444[] = { · 111 unmodified lines | ||
| 112 | 112 | C(0, } ) |
| 113 | 113 | }; |
| 114 | 114 | |
| 115 | +static int init_scale_shader(ScaleVulkanContext *s, FFVulkanShader *shd, | |
| 116 | + FFVulkanDescriptorSetBinding *desc, AVFrame *in) | |
| 117 | +{ | |
| 118 | + GLSLD( scale_bilinear ); | |
| 119 | + | |
| 120 | + if (s->vkctx.output_format != s->vkctx.input_format) { | |
| 121 | + GLSLD( rgb2yuv ); | |
| 122 | + } | |
| 123 | + | |
| 124 | + switch (s->vkctx.output_format) { | |
| 125 | + case AV_PIX_FMT_NV12: GLSLD(write_nv12); break; | |
| 126 | + case AV_PIX_FMT_YUV420P: GLSLD( write_420); break; | |
| 127 | + case AV_PIX_FMT_YUV444P: GLSLD( write_444); break; | |
| 128 | + default: break; | |
| 129 | + } | |
| 130 | + | |
| 131 | + GLSLC(0, void main() ); | |
| 132 | + GLSLC(0, { ); | |
| 133 | + GLSLC(1, ivec2 size; ); | |
| 134 | + GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); | |
| 135 | + GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height); | |
| 136 | + GLSLC(1, vec2 c_r = vec2(crop_w, crop_h) / in_d; ); | |
| 137 | + GLSLC(1, vec2 c_o = vec2(crop_x, crop_y) / in_d; ); | |
| 138 | + GLSLC(0, ); | |
| 139 | + | |
| 140 | + if (s->vkctx.output_format == s->vkctx.input_format) { | |
| 141 | + for (int i = 0; i < desc[1].elems; i++) { | |
| 142 | + GLSLF(1, size = imageSize(output_img[%i]); ,i); | |
| 143 | + GLSLC(1, if (IS_WITHIN(pos, size)) { ); | |
| 144 | + switch (s->scaler) { | |
| 145 | + case F_NEAREST: | |
| 146 | + case F_BILINEAR: | |
| 147 | + GLSLF(2, vec4 res = scale_bilinear(%i, pos, c_r, c_o); ,i); | |
| 148 | + GLSLF(2, imageStore(output_img[%i], pos, res); ,i); | |
| 149 | + break; | |
| 150 | + }; | |
| 151 | + GLSLC(1, } ); | |
| 152 | + } | |
| 153 | + } else { | |
| 154 | + GLSLC(1, vec4 res = scale_bilinear(0, pos, c_r, c_o); ); | |
| 155 | + GLSLF(1, res = rgb2yuv(res, %i); ,s->out_range == AVCOL_RANGE_JPEG); | |
| 156 | + switch (s->vkctx.output_format) { | |
| 157 | + case AV_PIX_FMT_NV12: GLSLC(1, write_nv12(res, pos); ); break; | |
| 158 | + case AV_PIX_FMT_YUV420P: GLSLC(1, write_420(res, pos); ); break; | |
| 159 | + case AV_PIX_FMT_YUV444P: GLSLC(1, write_444(res, pos); ); break; | |
| 160 | + default: return AVERROR(EINVAL); | |
| 161 | + } | |
| 162 | + } | |
| 163 | + | |
| 164 | + GLSLC(0, } ); | |
| 165 | + | |
| 166 | + if (s->vkctx.output_format != s->vkctx.input_format) { | |
| 167 | + const AVLumaCoefficients *lcoeffs; | |
| 168 | + double tmp_mat[3][3]; | |
| 169 | + | |
| 170 | + lcoeffs = av_csp_luma_coeffs_from_avcsp(in->colorspace); | |
| 171 | + if (!lcoeffs) { | |
| 172 | + av_log(s, AV_LOG_ERROR, "Unsupported colorspace\n"); | |
| 173 | + return AVERROR(EINVAL); | |
| 174 | + } | |
| 175 | + | |
| 176 | + ff_fill_rgb2yuv_table(lcoeffs, tmp_mat); | |
| 177 | + | |
| 178 | + for (int y = 0; y < 3; y++) | |
| 179 | + for (int x = 0; x < 3; x++) | |
| 180 | + s->opts.yuv_matrix[x][y] = tmp_mat[x][y]; | |
| 181 | + s->opts.yuv_matrix[3][3] = 1.0; | |
| 182 | + } | |
| 183 | + | |
| 184 | + return 0; | |
| 185 | +} | |
| 186 | + | |
| 115 | 187 | static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) |
| 116 | 188 | { |
| 117 | 189 | int err; |
| @@ -157,18 +229,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) · 39 unmodified lines | ||
| 157 | 229 | 32, 32, 1, |
| 158 | 230 | 0)); |
| 159 | 231 | |
| 160 | − GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); | |
| 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; ); | |
| 166 | − GLSLC(0, }; ); | |
| 167 | − GLSLC(0, ); | |
| 168 | − | |
| 169 | − ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), | |
| 170 | − VK_SHADER_STAGE_COMPUTE_BIT); | |
| 171 | − | |
| 172 | 232 | desc = (FFVulkanDescriptorSetBinding []) { |
| 173 | 233 | { |
| 174 | 234 | .name = "input_img", |
| @@ -191,71 +251,21 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) · 16 unmodified lines | ||
| 191 | 251 | |
| 192 | 252 | RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0)); |
| 193 | 253 | |
| 194 | − GLSLD( scale_bilinear ); | |
| 195 | − | |
| 196 | − if (s->vkctx.output_format != s->vkctx.input_format) { | |
| 197 | − GLSLD( rgb2yuv ); | |
| 198 | − } | |
| 199 | − | |
| 200 | − switch (s->vkctx.output_format) { | |
| 201 | − case AV_PIX_FMT_NV12: GLSLD(write_nv12); break; | |
| 202 | − case AV_PIX_FMT_YUV420P: GLSLD( write_420); break; | |
| 203 | − case AV_PIX_FMT_YUV444P: GLSLD( write_444); break; | |
| 204 | − default: break; | |
| 205 | − } | |
| 206 | − | |
| 207 | − GLSLC(0, void main() ); | |
| 208 | − GLSLC(0, { ); | |
| 209 | − GLSLC(1, ivec2 size; ); | |
| 210 | − GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); | |
| 211 | − GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height); | |
| 212 | − GLSLC(1, vec2 c_r = vec2(crop_w, crop_h) / in_d; ); | |
| 213 | − GLSLC(1, vec2 c_o = vec2(crop_x, crop_y) / in_d; ); | |
| 214 | − GLSLC(0, ); | |
| 215 | − | |
| 216 | − if (s->vkctx.output_format == s->vkctx.input_format) { | |
| 217 | − for (int i = 0; i < desc[1].elems; i++) { | |
| 218 | − GLSLF(1, size = imageSize(output_img[%i]); ,i); | |
| 219 | − GLSLC(1, if (IS_WITHIN(pos, size)) { ); | |
| 220 | − switch (s->scaler) { | |
| 221 | − case F_NEAREST: | |
| 222 | − case F_BILINEAR: | |
| 223 | − GLSLF(2, vec4 res = scale_bilinear(%i, pos, c_r, c_o); ,i); | |
| 224 | − GLSLF(2, imageStore(output_img[%i], pos, res); ,i); | |
| 225 | − break; | |
| 226 | − }; | |
| 227 | − GLSLC(1, } ); | |
| 228 | − } | |
| 229 | − } else { | |
| 230 | − GLSLC(1, vec4 res = scale_bilinear(0, pos, c_r, c_o); ); | |
| 231 | − GLSLF(1, res = rgb2yuv(res, %i); ,s->out_range == AVCOL_RANGE_JPEG); | |
| 232 | − switch (s->vkctx.output_format) { | |
| 233 | − case AV_PIX_FMT_NV12: GLSLC(1, write_nv12(res, pos); ); break; | |
| 234 | − case AV_PIX_FMT_YUV420P: GLSLC(1, write_420(res, pos); ); break; | |
| 235 | − case AV_PIX_FMT_YUV444P: GLSLC(1, write_444(res, pos); ); break; | |
| 236 | − default: return AVERROR(EINVAL); | |
| 237 | − } | |
| 238 | − } | |
| 239 | − | |
| 240 | − GLSLC(0, } ); | |
| 241 | − | |
| 242 | − if (s->vkctx.output_format != s->vkctx.input_format) { | |
| 243 | − const AVLumaCoefficients *lcoeffs; | |
| 244 | − double tmp_mat[3][3]; | |
| 245 | − | |
| 246 | − lcoeffs = av_csp_luma_coeffs_from_avcsp(in->colorspace); | |
| 247 | − if (!lcoeffs) { | |
| 248 | − av_log(ctx, AV_LOG_ERROR, "Unsupported colorspace\n"); | |
| 249 | − return AVERROR(EINVAL); | |
| 250 | − } | |
| 254 | + GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); | |
| 255 | + GLSLC(1, mat4 yuv_matrix; ); | |
| 256 | + GLSLC(1, int crop_x; ); | |
| 257 | + GLSLC(1, int crop_y; ); | |
| 258 | + GLSLC(1, int crop_w; ); | |
| 259 | + GLSLC(1, int crop_h; ); | |
| 260 | + GLSLC(0, }; ); | |
| 261 | + GLSLC(0, ); | |
| 251 | 262 | |
| 252 | − ff_fill_rgb2yuv_table(lcoeffs, tmp_mat); | |
| 263 | + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), | |
| 264 | + VK_SHADER_STAGE_COMPUTE_BIT); | |
| 253 | 265 | |
| 254 | − for (int y = 0; y < 3; y++) | |
| 255 | − for (int x = 0; x < 3; x++) | |
| 256 | − s->opts.yuv_matrix[x][y] = tmp_mat[x][y]; | |
| 257 | − s->opts.yuv_matrix[3][3] = 1.0; | |
| 258 | − } | |
| 266 | + err = init_scale_shader(s, shd, desc, in); | |
| 267 | + if (err < 0) | |
| 268 | + goto fail; | |
| 259 | 269 | |
| 260 | 270 | RET(spv->compile_shader(vkctx, spv, shd, &spv_data, &spv_len, "main", |
| 261 | 271 | &spv_opaque)); |