avfilter API requires all the filter parameters, including hw context (if present) to be available during init, so that is the proper place to perform such setup.
Unified · Split
| @@ -194,6 +194,8 @@ typedef struct LibplaceboContext { · 193 unmodified lines | ||
| 194 | 194 | int color_trc; |
| 195 | 195 | AVDictionary *extra_opts; |
| 196 | 196 | |
| 197 | + int have_hwdevice; | |
| 198 | + | |
| 197 | 199 | /* pl_render_params */ |
| 198 | 200 | pl_options opts; |
| 199 | 201 | char *upscaler; |
| @@ -493,11 +495,13 @@ static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len) · 293 unmodified lines | ||
| 493 | 495 | |
| 494 | 496 | static void libplacebo_uninit(AVFilterContext *avctx); |
| 495 | 497 | static int libplacebo_config_input(AVFilterLink *inlink); |
| 498 | +static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx); | |
| 496 | 499 | |
| 497 | 500 | static int libplacebo_init(AVFilterContext *avctx) |
| 498 | 501 | { |
| 499 | 502 | int err = 0; |
| 500 | 503 | LibplaceboContext *s = avctx->priv; |
| 504 | + const AVVulkanDeviceContext *vkhwctx = NULL; | |
| 501 | 505 | |
| 502 | 506 | /* Create libplacebo log context */ |
| 503 | 507 | s->log = pl_log_create(PL_API_VER, pl_log_params( |
| @@ -559,7 +563,14 @@ static int libplacebo_init(AVFilterContext *avctx) · 55 unmodified lines | ||
| 559 | 563 | if (strcmp(s->fps_string, "none") != 0) |
| 560 | 564 | RET(av_parse_video_rate(&s->fps, s->fps_string)); |
| 561 | 565 | |
| 562 | − /* Note: s->vulkan etc. are initialized later, when hwctx is available */ | |
| 566 | + if (avctx->hw_device_ctx) { | |
| 567 | + const AVHWDeviceContext *avhwctx = (void *) avctx->hw_device_ctx->data; | |
| 568 | + if (avhwctx->type == AV_HWDEVICE_TYPE_VULKAN) | |
| 569 | + vkhwctx = avhwctx->hwctx; | |
| 570 | + } | |
| 571 | + | |
| 572 | + RET(init_vulkan(avctx, vkhwctx)); | |
| 573 | + | |
| 563 | 574 | return 0; |
| 564 | 575 | |
| 565 | 576 | fail: |
| @@ -648,6 +659,8 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct · 82 unmodified lines | ||
| 648 | 659 | err = AVERROR_EXTERNAL; |
| 649 | 660 | goto fail; |
| 650 | 661 | #endif |
| 662 | + | |
| 663 | + s->have_hwdevice = 1; | |
| 651 | 664 | } else { |
| 652 | 665 | s->vulkan = pl_vulkan_create(s->log, pl_vulkan_params( |
| 653 | 666 | .queue_count = 0, /* enable all queues for parallelization */ |
| @@ -1081,18 +1094,9 @@ static int libplacebo_query_format(AVFilterContext *ctx) · 427 unmodified lines | ||
| 1081 | 1094 | { |
| 1082 | 1095 | int err; |
| 1083 | 1096 | LibplaceboContext *s = ctx->priv; |
| 1084 | − const AVVulkanDeviceContext *vkhwctx = NULL; | |
| 1085 | 1097 | const AVPixFmtDescriptor *desc = NULL; |
| 1086 | 1098 | AVFilterFormats *infmts = NULL, *outfmts = NULL; |
| 1087 | 1099 | |
| 1088 | − if (ctx->hw_device_ctx) { | |
| 1089 | − const AVHWDeviceContext *avhwctx = (void *) ctx->hw_device_ctx->data; | |
| 1090 | − if (avhwctx->type == AV_HWDEVICE_TYPE_VULKAN) | |
| 1091 | − vkhwctx = avhwctx->hwctx; | |
| 1092 | − } | |
| 1093 | − | |
| 1094 | − RET(init_vulkan(ctx, vkhwctx)); | |
| 1095 | − | |
| 1096 | 1100 | while ((desc = av_pix_fmt_desc_next(desc))) { |
| 1097 | 1101 | enum AVPixelFormat pixfmt = av_pix_fmt_desc_get_id(desc); |
| 1098 | 1102 | |
| @@ -1103,10 +1107,8 @@ static int libplacebo_query_format(AVFilterContext *ctx) · 4 unmodified lines | ||
| 1103 | 1107 | continue; |
| 1104 | 1108 | #endif |
| 1105 | 1109 | |
| 1106 | − if (pixfmt == AV_PIX_FMT_VULKAN) { | |
| 1107 | − if (!vkhwctx || vkhwctx->act_dev != s->vulkan->device) | |
| 1108 | − continue; | |
| 1109 | − } | |
| 1110 | + if (pixfmt == AV_PIX_FMT_VULKAN && !s->have_hwdevice) | |
| 1111 | + continue; | |
| 1110 | 1112 | |
| 1111 | 1113 | if (!pl_test_pixfmt(s->gpu, pixfmt)) |
| 1112 | 1114 | continue; |