[FFmpeg-cvslog] avfilter/vf_libplacebo: fix format query
Niklas Haas
git at videolan.org
Tue Feb 7 16:13:10 EET 2023
ffmpeg | branch: master | Niklas Haas <git at haasn.dev> | Tue Feb 7 15:09:18 2023 +0100| [62dfa546886d55109f0ba0afb1c13e59157e524c] | committer: Niklas Haas
avfilter/vf_libplacebo: fix format query
We need to construct the output format list separatedly from the input
format list, because we need to adhere to two extra requirements:
1. Big-endian output formats are always unsupported (runtime error)
2. Combining 'vulkan' with an explicit out_format that is not supported
by the vulkan frame allocation code is illegal and will crash (abort)
As a free side benefit, this rewrite fixes a possible memory leak in the
`fail` path that was present in the old code.
Signed-off-by: Niklas Haas <git at haasn.dev>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=62dfa546886d55109f0ba0afb1c13e59157e524c
---
libavfilter/vf_libplacebo.c | 52 ++++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 12abca4cc7..5b31077107 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -547,10 +547,10 @@ fail:
static int libplacebo_query_format(AVFilterContext *ctx)
{
- int err = 0;
+ int err;
LibplaceboContext *s = ctx->priv;
const AVPixFmtDescriptor *desc = NULL;
- AVFilterFormats *formats = NULL;
+ AVFilterFormats *infmts = NULL, *outfmts = NULL;
RET(init_vulkan(ctx));
@@ -564,29 +564,47 @@ static int libplacebo_query_format(AVFilterContext *ctx)
continue;
#endif
- if (pl_test_pixfmt(s->gpu, pixfmt)) {
- if ((err = ff_add_format(&formats, pixfmt)) < 0)
- return err;
+ if (!pl_test_pixfmt(s->gpu, pixfmt))
+ continue;
+
+ RET(ff_add_format(&infmts, pixfmt));
+
+ /* Filter for supported output pixel formats */
+ if (desc->flags & AV_PIX_FMT_FLAG_BE)
+ continue; /* BE formats are not supported by pl_download_avframe */
+
+ /* Mask based on user specified format */
+ if (s->out_format != AV_PIX_FMT_NONE) {
+ if (pixfmt == AV_PIX_FMT_VULKAN && av_vkfmt_from_pixfmt(s->out_format)) {
+ /* OK */
+ } else if (pixfmt == s->out_format) {
+ /* OK */
+ } else {
+ continue; /* Not OK */
+ }
}
- }
- RET(ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats));
+ RET(ff_add_format(&outfmts, pixfmt));
+ }
- if (s->out_format != AV_PIX_FMT_NONE) {
- /* Support only requested format, and hwaccel (vulkan) */
- const enum AVPixelFormat out_fmts[] = {
- s->out_format, AV_PIX_FMT_VULKAN, AV_PIX_FMT_NONE,
- };
- RET(ff_formats_ref(ff_make_format_list(out_fmts),
- &ctx->outputs[0]->incfg.formats));
- } else {
- /* Support all formats */
- RET(ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats));
+ if (!infmts || !outfmts) {
+ if (s->out_format) {
+ av_log(s, AV_LOG_ERROR, "Invalid output format '%s'!\n",
+ av_get_pix_fmt_name(s->out_format));
+ }
+ err = AVERROR(EINVAL);
+ goto fail;
}
+ RET(ff_formats_ref(infmts, &ctx->inputs[0]->outcfg.formats));
+ RET(ff_formats_ref(outfmts, &ctx->outputs[0]->incfg.formats));
return 0;
fail:
+ if (infmts && !infmts->refcount)
+ ff_formats_unref(&infmts);
+ if (outfmts && !outfmts->refcount)
+ ff_formats_unref(&outfmts);
return err;
}
More information about the ffmpeg-cvslog
mailing list