lavu/hwcontext_qsv: make qsv hwdevice works with oneVPL
In oneVPL, MFXLoad() and MFXCreateSession() are required to create a workable mfx session[1] Add config filters for D3D9/D3D11 session (galinart) The default device is changed to d3d11va for oneVPL when both d3d11va and dxva2 are enabled on Microsoft Windows This is in preparation for oneVPL support [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/programming_guide/VPL_prg_session.html#onevpl-dispatcher Co-authored-by: galinart <artem.galin@intel.com> Signed-off-by: galinart <artem.galin@intel.com> Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
This commit is contained in:
		
							parent
							
								
									e0bbdbe0a6
								
							
						
					
					
						commit
						05bd88dca2
					
				@ -49,6 +49,7 @@
 | 
			
		||||
#include "pixdesc.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
#include "imgutils.h"
 | 
			
		||||
#include "avassert.h"
 | 
			
		||||
 | 
			
		||||
#define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
 | 
			
		||||
    (MFX_VERSION_MAJOR > (MAJOR) ||         \
 | 
			
		||||
@ -58,6 +59,12 @@
 | 
			
		||||
#define QSV_ONEVPL       QSV_VERSION_ATLEAST(2, 0)
 | 
			
		||||
#define QSV_HAVE_OPAQUE  !QSV_ONEVPL
 | 
			
		||||
 | 
			
		||||
#if QSV_ONEVPL
 | 
			
		||||
#include <mfxdispatcher.h>
 | 
			
		||||
#else
 | 
			
		||||
#define MFXUnload(a) do { } while(0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct QSVDevicePriv {
 | 
			
		||||
    AVBufferRef *child_device_ctx;
 | 
			
		||||
} QSVDevicePriv;
 | 
			
		||||
@ -619,6 +626,437 @@ static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
 | 
			
		||||
    return MFX_ERR_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if QSV_ONEVPL
 | 
			
		||||
 | 
			
		||||
static int qsv_d3d11_update_config(void *ctx, mfxHDL handle, mfxConfig cfg)
 | 
			
		||||
{
 | 
			
		||||
#if CONFIG_D3D11VA
 | 
			
		||||
    mfxStatus sts;
 | 
			
		||||
    IDXGIAdapter *pDXGIAdapter;
 | 
			
		||||
    DXGI_ADAPTER_DESC adapterDesc;
 | 
			
		||||
    IDXGIDevice *pDXGIDevice = NULL;
 | 
			
		||||
    HRESULT hr;
 | 
			
		||||
    ID3D11Device *device = handle;
 | 
			
		||||
    mfxVariant impl_value;
 | 
			
		||||
 | 
			
		||||
    hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void**)&pDXGIDevice);
 | 
			
		||||
    if (SUCCEEDED(hr)) {
 | 
			
		||||
        hr = IDXGIDevice_GetAdapter(pDXGIDevice, &pDXGIAdapter);
 | 
			
		||||
        if (FAILED(hr)) {
 | 
			
		||||
            av_log(ctx, AV_LOG_ERROR, "Error IDXGIDevice_GetAdapter %d\n", hr);
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        hr = IDXGIAdapter_GetDesc(pDXGIAdapter, &adapterDesc);
 | 
			
		||||
        if (FAILED(hr)) {
 | 
			
		||||
            av_log(ctx, AV_LOG_ERROR, "Error IDXGIAdapter_GetDesc %d\n", hr);
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error ID3D11Device_QueryInterface %d\n", hr);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_U16;
 | 
			
		||||
    impl_value.Data.U16 = adapterDesc.DeviceId;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
               "DeviceID property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_PTR;
 | 
			
		||||
    impl_value.Data.Ptr = &adapterDesc.AdapterLuid;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
               "DeviceLUID property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_U32;
 | 
			
		||||
    impl_value.Data.U32 = 0x0001;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxExtendedDeviceId.LUIDDeviceNodeMask", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
               "LUIDDeviceNodeMask property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
#endif
 | 
			
		||||
    return AVERROR_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qsv_d3d9_update_config(void *ctx, mfxHDL handle, mfxConfig cfg)
 | 
			
		||||
{
 | 
			
		||||
    int ret = AVERROR_UNKNOWN;
 | 
			
		||||
#if CONFIG_DXVA2
 | 
			
		||||
    mfxStatus sts;
 | 
			
		||||
    IDirect3DDeviceManager9* devmgr = handle;
 | 
			
		||||
    IDirect3DDevice9Ex *device = NULL;
 | 
			
		||||
    HANDLE device_handle = 0;
 | 
			
		||||
    IDirect3D9Ex *d3d9ex = NULL;
 | 
			
		||||
    LUID luid;
 | 
			
		||||
    D3DDEVICE_CREATION_PARAMETERS params;
 | 
			
		||||
    HRESULT hr;
 | 
			
		||||
    mfxVariant impl_value;
 | 
			
		||||
 | 
			
		||||
    hr = IDirect3DDeviceManager9_OpenDeviceHandle(devmgr, &device_handle);
 | 
			
		||||
    if (FAILED(hr)) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error OpenDeviceHandle %d\n", hr);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hr = IDirect3DDeviceManager9_LockDevice(devmgr, device_handle, &device, TRUE);
 | 
			
		||||
    if (FAILED(hr)) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error LockDevice %d\n", hr);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hr = IDirect3DDevice9Ex_GetCreationParameters(device, ¶ms);
 | 
			
		||||
    if (FAILED(hr)) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9_GetCreationParameters %d\n", hr);
 | 
			
		||||
        goto unlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9ex);
 | 
			
		||||
    if (FAILED(hr)) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr);
 | 
			
		||||
        goto unlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, params.AdapterOrdinal, &luid);
 | 
			
		||||
    if (FAILED(hr)) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr);
 | 
			
		||||
        goto unlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_PTR;
 | 
			
		||||
    impl_value.Data.Ptr = &luid;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
               "DeviceLUID property: %d.\n", sts);
 | 
			
		||||
        goto unlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = 0;
 | 
			
		||||
 | 
			
		||||
unlock:
 | 
			
		||||
    IDirect3DDeviceManager9_UnlockDevice(devmgr, device_handle, FALSE);
 | 
			
		||||
fail:
 | 
			
		||||
#endif
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qsv_va_update_config(void *ctx, mfxHDL handle, mfxConfig cfg)
 | 
			
		||||
{
 | 
			
		||||
#if CONFIG_VAAPI
 | 
			
		||||
#if VA_CHECK_VERSION(1, 15, 0)
 | 
			
		||||
    mfxStatus sts;
 | 
			
		||||
    VADisplay dpy = handle;
 | 
			
		||||
    VAStatus vas;
 | 
			
		||||
    VADisplayAttribute attr = {
 | 
			
		||||
        .type = VADisplayPCIID,
 | 
			
		||||
    };
 | 
			
		||||
    mfxVariant impl_value;
 | 
			
		||||
 | 
			
		||||
    vas = vaGetDisplayAttributes(dpy, &attr, 1);
 | 
			
		||||
    if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED) {
 | 
			
		||||
        impl_value.Type = MFX_VARIANT_TYPE_U16;
 | 
			
		||||
        impl_value.Data.U16 = (attr.value & 0xFFFF);
 | 
			
		||||
        sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                         (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value);
 | 
			
		||||
        if (sts != MFX_ERR_NONE) {
 | 
			
		||||
            av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
                   "DeviceID property: %d.\n", sts);
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "libva: Failed to get device id from the driver. Please "
 | 
			
		||||
               "consider to upgrade the driver to support VA-API 1.15.0\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
#else
 | 
			
		||||
    av_log(ctx, AV_LOG_ERROR, "libva: This version of libva doesn't support retrieving "
 | 
			
		||||
           "the device information from the driver. Please consider to upgrade libva to "
 | 
			
		||||
           "support VA-API 1.15.0\n");
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
    return AVERROR_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qsv_new_mfx_loader(void *ctx,
 | 
			
		||||
                              mfxHDL handle,
 | 
			
		||||
                              mfxHandleType handle_type,
 | 
			
		||||
                              mfxIMPL implementation,
 | 
			
		||||
                              mfxVersion *pver,
 | 
			
		||||
                              void **ploader)
 | 
			
		||||
{
 | 
			
		||||
    mfxStatus sts;
 | 
			
		||||
    mfxLoader loader = NULL;
 | 
			
		||||
    mfxConfig cfg;
 | 
			
		||||
    mfxVariant impl_value;
 | 
			
		||||
 | 
			
		||||
    *ploader = NULL;
 | 
			
		||||
    loader = MFXLoad();
 | 
			
		||||
    if (!loader) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error creating a MFX loader\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Create configurations for implementation */
 | 
			
		||||
    cfg = MFXCreateConfig(loader);
 | 
			
		||||
    if (!cfg) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error creating a MFX configuration\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_U32;
 | 
			
		||||
    impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ?
 | 
			
		||||
        MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxImplDescription.Impl", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration "
 | 
			
		||||
               "property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_U32;
 | 
			
		||||
    impl_value.Data.U32 = pver->Version;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxImplDescription.ApiVersion.Version",
 | 
			
		||||
                                     impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration "
 | 
			
		||||
               "property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_U16;
 | 
			
		||||
    impl_value.Data.U16 = 0x8086; // Intel device only
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxExtendedDeviceId.VendorID", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
               "VendorID property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (MFX_HANDLE_VA_DISPLAY == handle_type) {
 | 
			
		||||
        if (handle && qsv_va_update_config(ctx, handle, cfg))
 | 
			
		||||
            goto fail;
 | 
			
		||||
 | 
			
		||||
        impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI;
 | 
			
		||||
    } else if (MFX_HANDLE_D3D9_DEVICE_MANAGER == handle_type) {
 | 
			
		||||
        if (handle && qsv_d3d9_update_config(ctx, handle, cfg))
 | 
			
		||||
            goto fail;
 | 
			
		||||
 | 
			
		||||
        impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (handle && qsv_d3d11_update_config(ctx, handle, cfg))
 | 
			
		||||
            goto fail;
 | 
			
		||||
 | 
			
		||||
        impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl_value.Type = MFX_VARIANT_TYPE_U32;
 | 
			
		||||
    sts = MFXSetConfigFilterProperty(cfg,
 | 
			
		||||
                                     (const mfxU8 *)"mfxImplDescription.AccelerationMode", impl_value);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
 | 
			
		||||
               "AccelerationMode property: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *ploader = loader;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (loader)
 | 
			
		||||
        MFXUnload(loader);
 | 
			
		||||
 | 
			
		||||
    return AVERROR_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qsv_create_mfx_session_from_loader(void *ctx, mfxLoader loader, mfxSession *psession)
 | 
			
		||||
{
 | 
			
		||||
    mfxStatus sts;
 | 
			
		||||
    mfxSession session = NULL;
 | 
			
		||||
    uint32_t impl_idx = 0;
 | 
			
		||||
    mfxVersion ver;
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        /* Enumerate all implementations */
 | 
			
		||||
        mfxImplDescription *impl_desc;
 | 
			
		||||
 | 
			
		||||
        sts = MFXEnumImplementations(loader, impl_idx,
 | 
			
		||||
                                     MFX_IMPLCAPS_IMPLDESCSTRUCTURE,
 | 
			
		||||
                                     (mfxHDL *)&impl_desc);
 | 
			
		||||
        /* Failed to find an available implementation */
 | 
			
		||||
        if (sts == MFX_ERR_NOT_FOUND)
 | 
			
		||||
            break;
 | 
			
		||||
        else if (sts != MFX_ERR_NONE) {
 | 
			
		||||
            impl_idx++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sts = MFXCreateSession(loader, impl_idx, &session);
 | 
			
		||||
        MFXDispReleaseImplDescription(loader, impl_desc);
 | 
			
		||||
        if (sts == MFX_ERR_NONE)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        impl_idx++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error creating a MFX session: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sts = MFXQueryVersion(session, &ver);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error querying a MFX session: %d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation "
 | 
			
		||||
           "version is %d.%d\n", ver.Major, ver.Minor);
 | 
			
		||||
 | 
			
		||||
    *psession = session;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (session)
 | 
			
		||||
        MFXClose(session);
 | 
			
		||||
 | 
			
		||||
    return AVERROR_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qsv_create_mfx_session(void *ctx,
 | 
			
		||||
                                  mfxHDL handle,
 | 
			
		||||
                                  mfxHandleType handle_type,
 | 
			
		||||
                                  mfxIMPL implementation,
 | 
			
		||||
                                  mfxVersion *pver,
 | 
			
		||||
                                  mfxSession *psession,
 | 
			
		||||
                                  void **ploader)
 | 
			
		||||
{
 | 
			
		||||
    mfxLoader loader = NULL;
 | 
			
		||||
 | 
			
		||||
    av_log(ctx, AV_LOG_VERBOSE,
 | 
			
		||||
           "Use Intel(R) oneVPL to create MFX session, API version is "
 | 
			
		||||
           "%d.%d, the required implementation version is %d.%d\n",
 | 
			
		||||
           MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor);
 | 
			
		||||
 | 
			
		||||
    if (handle_type != MFX_HANDLE_VA_DISPLAY &&
 | 
			
		||||
        handle_type != MFX_HANDLE_D3D9_DEVICE_MANAGER &&
 | 
			
		||||
        handle_type != MFX_HANDLE_D3D11_DEVICE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR,
 | 
			
		||||
               "Invalid MFX device handle type\n");
 | 
			
		||||
        return AVERROR(EXDEV);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *psession = NULL;
 | 
			
		||||
 | 
			
		||||
    if (!*ploader) {
 | 
			
		||||
        if (qsv_new_mfx_loader(ctx, handle, handle_type, implementation, pver, (void **)&loader))
 | 
			
		||||
            goto fail;
 | 
			
		||||
 | 
			
		||||
        av_assert0(loader);
 | 
			
		||||
    } else
 | 
			
		||||
        loader = *ploader;      // Use the input mfxLoader to create mfx session
 | 
			
		||||
 | 
			
		||||
    if (qsv_create_mfx_session_from_loader(ctx, loader, psession))
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    if (!*ploader)
 | 
			
		||||
        *ploader = loader;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (!*ploader && loader)
 | 
			
		||||
        MFXUnload(loader);
 | 
			
		||||
 | 
			
		||||
    return AVERROR_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
static int qsv_create_mfx_session(void *ctx,
 | 
			
		||||
                                  mfxHDL handle,
 | 
			
		||||
                                  mfxHandleType handle_type,
 | 
			
		||||
                                  mfxIMPL implementation,
 | 
			
		||||
                                  mfxVersion *pver,
 | 
			
		||||
                                  mfxSession *psession,
 | 
			
		||||
                                  void **ploader)
 | 
			
		||||
{
 | 
			
		||||
    mfxVersion ver;
 | 
			
		||||
    mfxStatus sts;
 | 
			
		||||
    mfxSession session = NULL;
 | 
			
		||||
 | 
			
		||||
    av_log(ctx, AV_LOG_VERBOSE,
 | 
			
		||||
           "Use Intel(R) Media SDK to create MFX session, API version is "
 | 
			
		||||
           "%d.%d, the required implementation version is %d.%d\n",
 | 
			
		||||
           MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor);
 | 
			
		||||
 | 
			
		||||
    *ploader = NULL;
 | 
			
		||||
    *psession = NULL;
 | 
			
		||||
    ver = *pver;
 | 
			
		||||
    sts = MFXInit(implementation, &ver, &session);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
 | 
			
		||||
               "%d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sts = MFXQueryVersion(session, &ver);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: "
 | 
			
		||||
               "%d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation "
 | 
			
		||||
           "version is %d.%d\n", ver.Major, ver.Minor);
 | 
			
		||||
 | 
			
		||||
    MFXClose(session);
 | 
			
		||||
 | 
			
		||||
    sts = MFXInit(implementation, &ver, &session);
 | 
			
		||||
    if (sts != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
 | 
			
		||||
               "%d.\n", sts);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *psession = session;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (session)
 | 
			
		||||
        MFXClose(session);
 | 
			
		||||
 | 
			
		||||
    return AVERROR_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int qsv_init_internal_session(AVHWFramesContext *ctx,
 | 
			
		||||
                                     mfxSession *session, int upload)
 | 
			
		||||
{
 | 
			
		||||
@ -637,29 +1075,36 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx,
 | 
			
		||||
 | 
			
		||||
    mfxVideoParam par;
 | 
			
		||||
    mfxStatus err;
 | 
			
		||||
    int                   ret = AVERROR_UNKNOWN;
 | 
			
		||||
    AVQSVDeviceContext *hwctx = ctx->device_ctx->hwctx;
 | 
			
		||||
    /* hwctx->loader is non-NULL for oneVPL user and NULL for non-oneVPL user */
 | 
			
		||||
    void             **loader = &hwctx->loader;
 | 
			
		||||
 | 
			
		||||
#if QSV_HAVE_OPAQUE
 | 
			
		||||
    QSVFramesContext              *s = ctx->internal->priv;
 | 
			
		||||
    opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    err = MFXInit(device_priv->impl, &device_priv->ver, session);
 | 
			
		||||
    if (err != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n");
 | 
			
		||||
        return AVERROR_UNKNOWN;
 | 
			
		||||
    }
 | 
			
		||||
    ret = qsv_create_mfx_session(ctx, device_priv->handle, device_priv->handle_type,
 | 
			
		||||
                                 device_priv->impl, &device_priv->ver, session, loader);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    if (device_priv->handle) {
 | 
			
		||||
        err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type,
 | 
			
		||||
                                     device_priv->handle);
 | 
			
		||||
        if (err != MFX_ERR_NONE)
 | 
			
		||||
            return AVERROR_UNKNOWN;
 | 
			
		||||
        if (err != MFX_ERR_NONE) {
 | 
			
		||||
            ret = AVERROR_UNKNOWN;
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!opaque) {
 | 
			
		||||
        err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator);
 | 
			
		||||
        if (err != MFX_ERR_NONE)
 | 
			
		||||
            return AVERROR_UNKNOWN;
 | 
			
		||||
        if (err != MFX_ERR_NONE) {
 | 
			
		||||
            ret = AVERROR_UNKNOWN;
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(&par, 0, sizeof(par));
 | 
			
		||||
@ -695,11 +1140,20 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx,
 | 
			
		||||
    if (err != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session."
 | 
			
		||||
               "Surface upload/download will not be possible\n");
 | 
			
		||||
        MFXClose(*session);
 | 
			
		||||
        *session = NULL;
 | 
			
		||||
 | 
			
		||||
        ret = AVERROR_UNKNOWN;
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (*session)
 | 
			
		||||
        MFXClose(*session);
 | 
			
		||||
 | 
			
		||||
    *session = NULL;
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qsv_frames_init(AVHWFramesContext *ctx)
 | 
			
		||||
@ -1456,6 +1910,8 @@ static void qsv_device_free(AVHWDeviceContext *ctx)
 | 
			
		||||
    if (hwctx->session)
 | 
			
		||||
        MFXClose(hwctx->session);
 | 
			
		||||
 | 
			
		||||
    if (hwctx->loader)
 | 
			
		||||
        MFXUnload(hwctx->loader);
 | 
			
		||||
    av_buffer_unref(&priv->child_device_ctx);
 | 
			
		||||
    av_freep(&priv);
 | 
			
		||||
}
 | 
			
		||||
@ -1545,34 +2001,10 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx,
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = MFXInit(implementation, &ver, &hwctx->session);
 | 
			
		||||
    if (err != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
 | 
			
		||||
               "%d.\n", err);
 | 
			
		||||
        ret = AVERROR_UNKNOWN;
 | 
			
		||||
    ret = qsv_create_mfx_session(ctx, handle, handle_type, implementation, &ver,
 | 
			
		||||
                                 &hwctx->session, &hwctx->loader);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = MFXQueryVersion(hwctx->session, &ver);
 | 
			
		||||
    if (err != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: %d.\n", err);
 | 
			
		||||
        ret = AVERROR_UNKNOWN;
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    av_log(ctx, AV_LOG_VERBOSE,
 | 
			
		||||
           "Initialize MFX session: API version is %d.%d, implementation version is %d.%d\n",
 | 
			
		||||
           MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor);
 | 
			
		||||
 | 
			
		||||
    MFXClose(hwctx->session);
 | 
			
		||||
 | 
			
		||||
    err = MFXInit(implementation, &ver, &hwctx->session);
 | 
			
		||||
    if (err != MFX_ERR_NONE) {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR,
 | 
			
		||||
               "Error initializing an MFX session: %d.\n", err);
 | 
			
		||||
        ret = AVERROR_UNKNOWN;
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
 | 
			
		||||
    if (err != MFX_ERR_NONE) {
 | 
			
		||||
@ -1587,6 +2019,12 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx,
 | 
			
		||||
fail:
 | 
			
		||||
    if (hwctx->session)
 | 
			
		||||
        MFXClose(hwctx->session);
 | 
			
		||||
 | 
			
		||||
    if (hwctx->loader)
 | 
			
		||||
        MFXUnload(hwctx->loader);
 | 
			
		||||
 | 
			
		||||
    hwctx->session = NULL;
 | 
			
		||||
    hwctx->loader = NULL;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1629,6 +2067,16 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
 | 
			
		||||
        }
 | 
			
		||||
    } else if (CONFIG_VAAPI) {
 | 
			
		||||
        child_device_type = AV_HWDEVICE_TYPE_VAAPI;
 | 
			
		||||
#if QSV_ONEVPL
 | 
			
		||||
    } else if (CONFIG_D3D11VA) {  // Use D3D11 by default if d3d11va is enabled
 | 
			
		||||
        av_log(ctx, AV_LOG_VERBOSE,
 | 
			
		||||
               "Defaulting child_device_type to AV_HWDEVICE_TYPE_D3D11VA for oneVPL."
 | 
			
		||||
               "Please explicitly set child device type via \"-init_hw_device\" "
 | 
			
		||||
               "option if needed.\n");
 | 
			
		||||
        child_device_type = AV_HWDEVICE_TYPE_D3D11VA;
 | 
			
		||||
    } else if (CONFIG_DXVA2) {
 | 
			
		||||
        child_device_type = AV_HWDEVICE_TYPE_DXVA2;
 | 
			
		||||
#else
 | 
			
		||||
    } else if (CONFIG_DXVA2) {
 | 
			
		||||
        av_log(NULL, AV_LOG_WARNING,
 | 
			
		||||
                "WARNING: defaulting child_device_type to AV_HWDEVICE_TYPE_DXVA2 for compatibility "
 | 
			
		||||
@ -1637,6 +2085,7 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
 | 
			
		||||
        child_device_type = AV_HWDEVICE_TYPE_DXVA2;
 | 
			
		||||
    } else if (CONFIG_D3D11VA) {
 | 
			
		||||
        child_device_type = AV_HWDEVICE_TYPE_D3D11VA;
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n");
 | 
			
		||||
        return AVERROR(ENOSYS);
 | 
			
		||||
@ -1663,6 +2112,13 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
 | 
			
		||||
#endif
 | 
			
		||||
#if CONFIG_DXVA2
 | 
			
		||||
    case AV_HWDEVICE_TYPE_DXVA2:
 | 
			
		||||
#if QSV_ONEVPL
 | 
			
		||||
        {
 | 
			
		||||
            av_log(ctx, AV_LOG_VERBOSE,
 | 
			
		||||
                   "d3d11va is not available or child device type is set to dxva2 "
 | 
			
		||||
                   "explicitly for oneVPL.\n");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        break;
 | 
			
		||||
#endif
 | 
			
		||||
    default:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user