Skip to content

cv::va_intel::convertFromVASurface always fails on AMD devices using mesa #21536

@edman007

Description

@edman007
System information (version)
  • OpenCV => 4.5.5
  • Operating System / Platform => Slackware-current
Detailed description

cv::va_intel::convertFromVASurface always fails on AMD devices using mesa

Steps to reproduce

I am trying to convert a VAAPI image from FFMPEG in an AVFrame to a UMat, so my code is like this:

bool MotionOpenCV::process_frame(const AVFrame *frame, bool video){
    //check if the incoming frame is VAAPI
    if (video && frame->format == AV_PIX_FMT_VAAPI && frame->hw_frames_ctx){
        AVHWFramesContext *hw_frames = (AVHWFramesContext *)frame->hw_frames_ctx->data;
        AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
        AVVAAPIDeviceContext *hwctx;
        if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI){
            LERROR("VAAPI frame does not have VAAPI device");
            return false;
        }
        hwctx = static_cast<AVVAAPIDeviceContext*>(device_ctx->hwctx);
        cv::UMat tmp;
        const VASurfaceID surf = reinterpret_cast<uintptr_t const>(frame->data[3]);
        try {
            cv::va_intel::convertFromVASurface(hwctx->display, surf, cv::Size(frame->width, frame->height), tmp);
        } catch (cv::Exception &e){
            LWARN("Error converting image from VA-API To OpenCV: " + e.msg);
            return false;
        }

Digging into it, modules/core/src/va_intel.cpp calls vaDeriveImage which if using mesa, calls vlVaDeriveImage. but per the comment in mesa, that always fails on AMD devices unless your program name is "vlc", "h264encode", or "hevcencode"

/* This function is used by some programs to test for hardware decoding, but on
    * AMD devices, the buffers default to interlaced, which causes this function to fail.
    * Some programs expect this function to fail, while others, assume this means
    * hardware acceleration is not available and give up without trying the fall-back
    * vaCreateImage + vaPutImage
    */

https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/gallium/frontends/va/image.c#L213

The solution then, is modules/core/src/va_intel.cpp should have the vaCreateImage + vaPutImage fallback that mesa requires.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions