Message ID | ZrcqHIAe8S9FpwT5@vicerveza.homeunix.net |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] PATCH: Fallback to NV12 format in VAAPI drivers | expand |
Context | Check | Description |
---|---|---|
yinshiyou/commit_msg_loongarch64 | warning | The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ". |
On 10/08/2024 09:51, Lluís Batlle i Rossell wrote: > On Fri, Aug 09, 2024 at 09:43:53AM +0200, Lluís Batlle i Rossell wrote: >> On Fri, Aug 09, 2024 at 11:49:54AM +0800, Zhao Zhili wrote: >>>> vaapi drivers often lack proper image converesions and not all >>>> situations allow vagetimage or vaputimage with the image formats >>>> reported by the api. nv12 seems allowed in all circumstances. >>>> >>>> with this change now one can use the hwaccel directly without >>>> explicit conversions to nv12 for frame downloading to work. >>>> >>>> gstreamer adopted a similar approach: >>>> https://bugzilla.gnome.org/show_bug.cgi?id=752958 >>> >>> Isn’t it break all pixel formats with bit depth > 8? >>> I think we already have hwcontext API to select sw_format, this isn’t a bug >>> inside ffmpeg. >> >> Correct... I didn't think of the need beyond NV12. >> >> What if I redo the patch so I keep all formats, but I simply move NV12 to >> the first place? That will make ffmpeg pick NV12 as default if NONE >> specified. > > I attach a different patch, so NV12 is only picked in case the dst format > is NONE. What are the surface formats where this actually gets used, and on what hardware and driver? It seems probably ok if this were restricted to 4:2:0 8-bit formats (as a surprise implicit downsample which can't be told anything about the source format seems very bad), but then what is it actually covering? Thanks, - Mark
On Sun, Aug 11, 2024 at 06:57:49PM +0100, Mark Thompson wrote: > On 10/08/2024 09:51, Lluís Batlle i Rossell wrote: > > On Fri, Aug 09, 2024 at 09:43:53AM +0200, Lluís Batlle i Rossell wrote: > >> On Fri, Aug 09, 2024 at 11:49:54AM +0800, Zhao Zhili wrote: > >>>> vaapi drivers often lack proper image converesions and not all > >>>> situations allow vagetimage or vaputimage with the image formats > >>>> reported by the api. nv12 seems allowed in all circumstances. > >>>> > >>>> with this change now one can use the hwaccel directly without > >>>> explicit conversions to nv12 for frame downloading to work. > >>>> > >>>> gstreamer adopted a similar approach: > >>>> https://bugzilla.gnome.org/show_bug.cgi?id=752958 > >>> > >>> Isn’t it break all pixel formats with bit depth > 8? > >>> I think we already have hwcontext API to select sw_format, this isn’t a bug > >>> inside ffmpeg. > >> > >> Correct... I didn't think of the need beyond NV12. > >> > >> What if I redo the patch so I keep all formats, but I simply move NV12 to > >> the first place? That will make ffmpeg pick NV12 as default if NONE > >> specified. > > > > I attach a different patch, so NV12 is only picked in case the dst format > > is NONE. > > What are the surface formats where this actually gets used, and on what hardware and driver? > > It seems probably ok if this were restricted to 4:2:0 8-bit formats (as a surprise implicit downsample which can't be told anything about the source format seems very bad), but then what is it actually covering? > I have found that webcams doing mjpeg get the hw frames as yuv422, and despite yuv422 is announced in ImageFormats, vaGetImage cannot download it, with a pair of Intel cpus I tried. I looked at the driver code and it looked broad. So with the patches I'm exploring what can be a good approach to this problem: va drivers report formats that maybe work through vaPutImage, but not with vaGetImage, for what I've seen. The immediate user problem of that is that operations using hwaccel vaapi with mjpeg will end up failing, unless you specify an output format that actually works. Otherwise, the vaGetImage operation says "not implemented". So mjpeg hw decoding will not work unless "-hwaccel_output_format" is given, or proper format is given to hwdownload in filters.
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 12bc95119a..0396038017 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -720,20 +720,22 @@ static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc, { VAAPIDeviceContext *ctx = hwfc->device_ctx->internal->priv; enum AVPixelFormat *pix_fmts; - int i, k, sw_format_available; + int i, k, nv12_format_available; - sw_format_available = 0; + /* Intel VAAPI drivers seem to support NV12 for vaGetImage, + * but fail for many formats announced in vaQueryImageFormats */ + nv12_format_available = 0; for (i = 0; i < ctx->nb_formats; i++) { - if (ctx->formats[i].pix_fmt == hwfc->sw_format) - sw_format_available = 1; + if (ctx->formats[i].pix_fmt == AV_PIX_FMT_NV12) + nv12_format_available = 1; } pix_fmts = av_malloc((ctx->nb_formats + 1) * sizeof(*pix_fmts)); if (!pix_fmts) return AVERROR(ENOMEM); - if (sw_format_available) { - pix_fmts[0] = hwfc->sw_format; + if (nv12_format_available) { + pix_fmts[0] = AV_PIX_FMT_NV12; k = 1; } else { k = 0;