On Fri, 6 Mar 2020 at 22:15, Soft Works <softwo...@hotmail.com> wrote:
> > -----Original Message----- > > From: ffmpeg-devel <ffmpeg-devel-boun...@ffmpeg.org> On Behalf Of > > Artem Galin > > Sent: Friday, March 6, 2020 2:10 PM > > To: ffmpeg-devel@ffmpeg.org > > Cc: Artem Galin <artem.ga...@gmail.com> > > Subject: [FFmpeg-devel] [PATCH v4] lavc/qsv: adding DX11 support > > > > This enables DX11 support for QSV with higher priority than DX9. > > In case of multiple GPUs configuration, DX9 API does not allow to get > access > > to QSV device in some cases - headless. > > Implementation based on DX11 resolves that restriction by enumerating > list > > of available GPUs and finding device with QSV support. > > > > Signed-off-by: Artem Galin <artem.ga...@gmail.com> > > --- > > fftools/ffmpeg_opt.c | 12 +- > > libavcodec/qsv.c | 53 +++++++- > > libavcodec/qsv_internal.h | 2 + > > libavfilter/qsvvpp.c | 36 +++-- > > libavutil/hwcontext_d3d11va.c | 56 +++++++- > > libavutil/hwcontext_qsv.c | 240 ++++++++++++++++++++++++++++------ > > 6 files changed, 340 insertions(+), 59 deletions(-) > > > > diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index > > 1b721c4954..da619b0043 100644 > > --- a/fftools/ffmpeg_opt.c > > +++ b/fftools/ffmpeg_opt.c > > @@ -504,7 +504,17 @@ static int opt_init_hw_device(void *optctx, const > > char *opt, const char *arg) > > printf("\n"); > > exit_program(0); > > } else { > > - return hw_device_init_from_string(arg, NULL); > > + HWDevice *dev; > > + int err; > > + if (!arg) > > + return AVERROR(ENOMEM); > > + err = hw_device_init_from_string(arg, &dev); > > + if (err < 0) > > + return err; > > + hw_device_ctx = av_buffer_ref(dev->device_ref); > > + if (!hw_device_ctx) > > + return AVERROR(ENOMEM); > > + return 0; > > } > > } > > > > diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index > > db98c75073..beea76896f 100644 > > --- a/libavcodec/qsv.c > > +++ b/libavcodec/qsv.c > > @@ -36,6 +36,8 @@ > > #include "avcodec.h" > > #include "qsv_internal.h" > > > > +#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) > > + > > #if QSV_VERSION_ATLEAST(1, 12) > > #include "mfx/mfxvp8.h" > > #endif > > @@ -221,8 +223,13 @@ int ff_qsv_find_surface_idx(QSVFramesContext > > *ctx, QSVFrame *frame) > > int i; > > for (i = 0; i < ctx->nb_mids; i++) { > > QSVMid *mid = &ctx->mids[i]; > > +#if CONFIG_D3D11VA > > + if (mid->handle_pair.second == frame->surface.Data.MemId) > > + return i; > > +#else > > if (mid->handle == frame->surface.Data.MemId) > > return i; > > +#endif > > } > > return AVERROR_BUG; > > } > > @@ -362,7 +369,11 @@ static int > > ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) int > > ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, > > const char *load_plugins, int > gpu_copy) { > > +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE > > mfxIMPL impl = MFX_IMPL_AUTO_ANY; > > +#else > > + mfxIMPL impl = MFX_IMPL_AUTO_ANY | MFX_IMPL_VIA_D3D11; > > +#endif > > mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } > > }; > > mfxInitParam init_par = { MFX_IMPL_AUTO_ANY }; > > > > @@ -449,11 +460,21 @@ static AVBufferRef *qsv_create_mids(AVBufferRef > > *hw_frames_ref) > > return NULL; > > } > > > > +#if CONFIG_D3D11VA > > + for (i = 0; i < nb_surfaces; i++) { > > + QSVMid *mid = &mids[i]; > > + mid->handle_is_pair = 1; > > + mid->handle_pair.first = (mfxHDL)frames_hwctx- > > >surfaces[i].Data.reserved2; > > + mid->handle_pair.second = frames_hwctx->surfaces[i].Data.MemId; > > + mid->hw_frames_ref = hw_frames_ref1; > > + } > > +#else > > for (i = 0; i < nb_surfaces; i++) { > > QSVMid *mid = &mids[i]; > > mid->handle = frames_hwctx->surfaces[i].Data.MemId; > > mid->hw_frames_ref = hw_frames_ref1; > > } > > +#endif > > > > return mids_buf; > > } > > @@ -661,7 +682,12 @@ static mfxStatus qsv_frame_unlock(mfxHDL pthis, > > mfxMemId mid, mfxFrameData *ptr) static mfxStatus > > qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) { > > QSVMid *qsv_mid = (QSVMid*)mid; > > - *hdl = qsv_mid->handle; > > + if (qsv_mid->handle_is_pair) { > > + mfxHDLPair *hdlpair = (mfxHDLPair*)hdl; > > + *hdlpair = qsv_mid->handle_pair; > > + } else { > > + *hdl = qsv_mid->handle; > > + } > > return MFX_ERR_NONE; > > } > > > > @@ -679,11 +705,11 @@ int ff_qsv_init_session_device(AVCodecContext > > *avctx, mfxSession *psession, > > mfxSession parent_session = device_hwctx->session; > > mfxInitParam init_par = { MFX_IMPL_AUTO_ANY }; > > mfxHDL handle = NULL; > > + mfxHandleType handle_type = MFX_HANDLE_D3D11_DEVICE; > > > > mfxSession session; > > mfxVersion ver; > > mfxIMPL impl; > > - mfxHandleType handle_type; > > mfxStatus err; > > > > int i, ret; > > @@ -695,11 +721,26 @@ int ff_qsv_init_session_device(AVCodecContext > > *avctx, mfxSession *psession, > > return ff_qsv_print_error(avctx, err, > > "Error querying the session > attributes"); > > > > + if (MFX_IMPL_VIA_D3D11 == MFX_IMPL_VIA_MASK(impl)) > > + { > > + handle_type = MFX_HANDLE_D3D11_DEVICE; > > + } > > + else if (MFX_IMPL_VIA_D3D9 == MFX_IMPL_VIA_MASK(impl)) > > + { > > + handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; > > + } > > + else if (MFX_IMPL_VIA_VAAPI == MFX_IMPL_VIA_MASK(impl)) > > + { > > + handle_type = MFX_HANDLE_VA_DISPLAY; > > + } > > + > > for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { > > - err = MFXVideoCORE_GetHandle(parent_session, handle_types[i], > > &handle); > > - if (err == MFX_ERR_NONE) { > > - handle_type = handle_types[i]; > > - break; > > + if (handle_types[i] == handle_type) > > + { > > + err = MFXVideoCORE_GetHandle(parent_session, > handle_types[i], > > &handle); > > + if (err == MFX_ERR_NONE) { > > + break; > > + } > > } > > handle = NULL; > > } > > diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index > > 6489836a67..99dfa8dcff 100644 > > --- a/libavcodec/qsv_internal.h > > +++ b/libavcodec/qsv_internal.h > > @@ -60,7 +60,9 @@ > > > > typedef struct QSVMid { > > AVBufferRef *hw_frames_ref; > > + int handle_is_pair; > > mfxHDL handle; > > + mfxHDLPair handle_pair; > > > > AVFrame *locked_frame; > > AVFrame *hw_frame; > > diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index > > 8d5ff2eb65..306bb2e0c3 100644 > > --- a/libavfilter/qsvvpp.c > > +++ b/libavfilter/qsvvpp.c > > @@ -32,10 +32,11 @@ > > #include "qsvvpp.h" > > #include "video.h" > > > > -#define IS_VIDEO_MEMORY(mode) (mode & > > (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | \ > > +#define IS_VIDEO_MEMORY(mode) (mode & > > (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | \ > > > > MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) > > -#define IS_OPAQUE_MEMORY(mode) (mode & > > MFX_MEMTYPE_OPAQUE_FRAME) -#define IS_SYSTEM_MEMORY(mode) > > (mode & MFX_MEMTYPE_SYSTEM_MEMORY) > > +#define IS_OPAQUE_MEMORY(mode) (mode & > > MFX_MEMTYPE_OPAQUE_FRAME) > > +#define IS_SYSTEM_MEMORY(mode) (mode & > > MFX_MEMTYPE_SYSTEM_MEMORY) > > +#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) > > > > typedef struct QSVFrame { > > AVFrame *frame; > > @@ -405,12 +406,12 @@ static int init_vpp_session(AVFilterContext *avctx, > > QSVVPPContext *s) > > AVFilterLink *outlink = avctx->outputs[0]; > > AVQSVFramesContext *in_frames_hwctx = NULL; > > AVQSVFramesContext *out_frames_hwctx = NULL; > > + mfxHandleType handle_type = MFX_HANDLE_D3D11_DEVICE; > > > > AVBufferRef *device_ref; > > AVHWDeviceContext *device_ctx; > > AVQSVDeviceContext *device_hwctx; > > mfxHDL handle; > > - mfxHandleType handle_type; > > mfxVersion ver; > > mfxIMPL impl; > > int ret, i; > > @@ -497,15 +498,30 @@ static int init_vpp_session(AVFilterContext *avctx, > > QSVVPPContext *s) > > return AVERROR_UNKNOWN; > > } > > > > + if (MFX_IMPL_VIA_D3D11 == MFX_IMPL_VIA_MASK(impl)) > > + { > > + handle_type = MFX_HANDLE_D3D11_DEVICE; > > + } > > + else if (MFX_IMPL_VIA_D3D9 == MFX_IMPL_VIA_MASK(impl)) > > + { > > + handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; > > + } > > + else if (MFX_IMPL_VIA_VAAPI == MFX_IMPL_VIA_MASK(impl)) > > + { > > + handle_type = MFX_HANDLE_VA_DISPLAY; > > + } > > + > > for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { > > - ret = MFXVideoCORE_GetHandle(device_hwctx->session, > > handle_types[i], &handle); > > - if (ret == MFX_ERR_NONE) { > > - handle_type = handle_types[i]; > > - break; > > + if (handle_types[i] == handle_type) > > + { > > + ret = MFXVideoCORE_GetHandle(device_hwctx->session, > > handle_types[i], &handle); > > + if (ret == MFX_ERR_NONE) { > > + break; > > + } > > } > > + handle = NULL; > > } > > - > > - if (ret != MFX_ERR_NONE) { > > + if (!handle) { > > av_log(avctx, AV_LOG_ERROR, "Error getting the session > handle\n"); > > return AVERROR_UNKNOWN; > > } > > diff --git a/libavutil/hwcontext_d3d11va.c > b/libavutil/hwcontext_d3d11va.c > > index c8ae58f908..13279b7e6f 100644 > > --- a/libavutil/e.c > > +++ b/libavutil/hwcontext_d3d11va.c > > @@ -511,15 +511,57 @@ static void > > d3d11va_device_uninit(AVHWDeviceContext *hwdev) > > } > > } > > > > +static int > > d3d11va_device_find_adapter_by_vendor_id(AVHWDeviceContext > > +*ctx, UINT creationFlags, char *vendor) { > > + HRESULT hr; > > + IDXGIAdapter *adapter = NULL; > > + int adapter_id = 0; > > + IDXGIFactory2 *factory; > > + long int vendor_id = strtol(vendor, NULL, 0); > > + hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&factory); > > + while (IDXGIFactory2_EnumAdapters(factory, adapter_id++, &adapter) > > != DXGI_ERROR_NOT_FOUND) > > + { > > + ID3D11Device* device = NULL; > > + DXGI_ADAPTER_DESC adapter_desc; > > + > > + hr = mD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, > > NULL, creationFlags, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL); > > + if (FAILED(hr)) { > > + av_log(ctx, AV_LOG_ERROR, "D3D11CreateDevice returned > error\n"); > > + continue; > > + } > > + > > + hr = IDXGIAdapter2_GetDesc(adapter, &adapter_desc); > > + if (FAILED(hr)) { > > + av_log(ctx, AV_LOG_ERROR, "IDXGIAdapter2_GetDesc returned > > error\n"); > > + continue; > > + } > > + > > + if (device) > > + ID3D11Device_Release(device); > > + > > + if (adapter) > > + IDXGIAdapter_Release(adapter); > > + > > + if (adapter_desc.VendorId == vendor_id) { > > + IDXGIFactory2_Release(factory); > > + return adapter_id - 1; > > + } > > + } > > + IDXGIFactory2_Release(factory); > > + return -1; > > +} > > + > > static int d3d11va_device_create(AVHWDeviceContext *ctx, const char > > *device, > > AVDictionary *opts, int flags) { > > AVD3D11VADeviceContext *device_hwctx = ctx->hwctx; > > > > HRESULT hr; > > + AVDictionaryEntry *e; > > IDXGIAdapter *pAdapter = NULL; > > ID3D10Multithread *pMultithread; > > UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; > > + int adapter = -1; > > int is_debug = !!av_dict_get(opts, "debug", NULL, 0); > > int ret; > > > > @@ -539,11 +581,23 @@ static int > > d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, > > return AVERROR_UNKNOWN; > > } > > > > + e = av_dict_get(opts, "vendor", NULL, 0); > > + if (e) { > > + adapter = d3d11va_device_find_adapter_by_vendor_id(ctx, > > creationFlags, e ? e->value : NULL); > > + if (adapter < 0) { > > + av_log(ctx, AV_LOG_ERROR, "Failed to find d3d11va adapter by > > vendor id %s\n", e ? e->value : NULL); > > + return AVERROR_UNKNOWN; > > + } > > + } > > + > > if (device) { > > + adapter = atoi(device); > > + } > > + > > + if (adapter >= 0) { > > IDXGIFactory2 *pDXGIFactory; > > hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void > > **)&pDXGIFactory); > > if (SUCCEEDED(hr)) { > > - int adapter = atoi(device); > > if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, > > &pAdapter))) > > pAdapter = NULL; > > IDXGIFactory2_Release(pDXGIFactory); > > diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index > > b1b67400de..97a18088c0 100644 > > --- a/libavutil/hwcontext_qsv.c > > +++ b/libavutil/hwcontext_qsv.c > > @@ -27,9 +27,13 @@ > > #include <pthread.h> > > #endif > > > > +#define COBJMACROS > > #if CONFIG_VAAPI > > #include "hwcontext_vaapi.h" > > #endif > > +#if CONFIG_D3D11VA > > +#include "hwcontext_d3d11va.h" > > +#endif > > #if CONFIG_DXVA2 > > #include "hwcontext_dxva2.h" > > #endif > > @@ -44,6 +48,8 @@ > > #include "pixdesc.h" > > #include "time.h" > > > > +#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) > > + > > typedef struct QSVDevicePriv { > > AVBufferRef *child_device_ctx; > > } QSVDevicePriv; > > @@ -89,6 +95,9 @@ static const struct { > > #if CONFIG_VAAPI > > { MFX_HANDLE_VA_DISPLAY, AV_HWDEVICE_TYPE_VAAPI, > > AV_PIX_FMT_VAAPI }, > > #endif > > +#if CONFIG_D3D11VA > > + { MFX_HANDLE_D3D11_DEVICE, AV_HWDEVICE_TYPE_D3D11VA, > > AV_PIX_FMT_D3D11 }, > > +#endif > > #if CONFIG_DXVA2 > > { MFX_HANDLE_D3D9_DEVICE_MANAGER, AV_HWDEVICE_TYPE_DXVA2, > > AV_PIX_FMT_DXVA2_VLD }, #endif @@ -119,25 +128,11 @@ static int > > qsv_device_init(AVHWDeviceContext *ctx) { > > AVQSVDeviceContext *hwctx = ctx->hwctx; > > QSVDeviceContext *s = ctx->internal->priv; > > + mfxHandleType handle_type = MFX_HANDLE_D3D11_DEVICE; > > > > mfxStatus err; > > int i; > > > > - for (i = 0; supported_handle_types[i].handle_type; i++) { > > - err = MFXVideoCORE_GetHandle(hwctx->session, > > supported_handle_types[i].handle_type, > > - &s->handle); > > - if (err == MFX_ERR_NONE) { > > - s->handle_type = > supported_handle_types[i].handle_type; > > - s->child_device_type = > supported_handle_types[i].device_type; > > - s->child_pix_fmt = supported_handle_types[i].pix_fmt; > > - break; > > - } > > - } > > - if (!s->handle) { > > - av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be > > retrieved " > > - "from the session\n"); > > - } > > - > > err = MFXQueryIMPL(hwctx->session, &s->impl); > > if (err == MFX_ERR_NONE) > > err = MFXQueryVersion(hwctx->session, &s->ver); @@ -146,6 > +141,36 > > @@ static int qsv_device_init(AVHWDeviceContext *ctx) > > return AVERROR_UNKNOWN; > > } > > > > + if (MFX_IMPL_VIA_D3D11 == MFX_IMPL_VIA_MASK(s->impl)) > > + { > > + handle_type = MFX_HANDLE_D3D11_DEVICE; > > + } > > + else if (MFX_IMPL_VIA_D3D9 == MFX_IMPL_VIA_MASK(s->impl)) > > + { > > + handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; > > + } > > + else if (MFX_IMPL_VIA_VAAPI == MFX_IMPL_VIA_MASK(s->impl)) > > + { > > + handle_type = MFX_HANDLE_VA_DISPLAY; > > + } > > + > > + for (i = 0; supported_handle_types[i].handle_type; i++) { > > + if (supported_handle_types[i].handle_type == handle_type) { > > + err = MFXVideoCORE_GetHandle(hwctx->session, > > supported_handle_types[i].handle_type, > > + &s->handle); > > + if (err == MFX_ERR_NONE) { > > + s->handle_type = > supported_handle_types[i].handle_type; > > + s->child_device_type = > supported_handle_types[i].device_type; > > + s->child_pix_fmt = > supported_handle_types[i].pix_fmt; > > + break; > > + } > > + } > > + } > > + if (!s->handle) { > > + av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be > > retrieved " > > + "from the session\n"); > > + } > > + > > return 0; > > } > > > > @@ -229,6 +254,13 @@ static int qsv_init_child_ctx(AVHWFramesContext > > *ctx) > > child_device_hwctx->display = (VADisplay)device_priv->handle; > > } > > #endif > > +#if CONFIG_D3D11VA > > + if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { > > + AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx- > > >hwctx; > > + ID3D11Device_AddRef((ID3D11Device*)device_priv->handle); > > + child_device_hwctx->device = (ID3D11Device*)device_priv->handle; > > + } > > +#endif > > #if CONFIG_DXVA2 > > if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { > > AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx- > > >hwctx; @@ -255,6 +287,16 @@ static int > > qsv_init_child_ctx(AVHWFramesContext *ctx) > > child_frames_ctx->width = FFALIGN(ctx->width, 16); > > child_frames_ctx->height = FFALIGN(ctx->height, 16); > > > > +#if CONFIG_D3D11VA > > + if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { > > + AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx- > > >hwctx; > > + child_frames_hwctx->MiscFlags |= D3D11_RESOURCE_MISC_SHARED; > > + if (hwctx->frame_type & > > MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) > > + child_frames_hwctx->BindFlags = D3D11_BIND_RENDER_TARGET ; > > + else > > + child_frames_hwctx->BindFlags = D3D11_BIND_DECODER; > > + } > > +#endif > > #if CONFIG_DXVA2 > > if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { > > AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx- > > >hwctx; @@ -279,6 +321,19 @@ static int > > qsv_init_child_ctx(AVHWFramesContext *ctx) > > hwctx->frame_type = > > MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; > > } > > #endif > > +#if CONFIG_D3D11VA > > + if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { > > + AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx- > > >hwctx; > > + for (i = 0; i < ctx->initial_pool_size; i++) { > > + s->surfaces_internal[i].Data.MemId = (mfxMemId)(intptr_t)i; > > + s->surfaces_internal[i].Data.reserved2 = > > (intptr_t)child_frames_hwctx->texture; > > + } > > + if (child_frames_hwctx->BindFlags & D3D11_BIND_DECODER) > > + hwctx->frame_type = > > MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; > > + else > > + hwctx->frame_type = > > MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; > > + } > > +#endif > > #if CONFIG_DXVA2 > > if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { > > AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx- > > >hwctx; @@ -421,6 +476,19 @@ static mfxStatus frame_unlock(mfxHDL > > pthis, mfxMemId mid, mfxFrameData *ptr) > > > > static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL > > *hdl) { > > +#if CONFIG_D3D11VA > > + AVHWFramesContext *ctx = pthis; > > + QSVFramesContext *s = ctx->internal->priv; > > + AVHWFramesContext *child_ctx = > > + (AVHWFramesContext*)s->child_frames_ref->data; > > + if (child_ctx->format == AV_PIX_FMT_D3D11) { > > + AVD3D11VAFramesContext *child_hwctx = child_ctx->hwctx; > > + mfxHDLPair *hdlpair = (mfxHDLPair*)hdl; > > + hdlpair->first = child_hwctx->texture; > > + hdlpair->second = mid; // (Texture array index.) > > + return MFX_ERR_NONE; > > + } > > +#endif > > *hdl = mid; > > return MFX_ERR_NONE; > > } > > @@ -668,6 +736,11 @@ static int qsv_map_from(AVHWFramesContext *ctx, > > child_data = > (uint8_t*)(intptr_t)*(VASurfaceID*)surf->Data.MemId; > > break; > > #endif > > +#if CONFIG_D3D11VA > > + case AV_HWDEVICE_TYPE_D3D11VA: > > + child_data = surf->Data.MemId; > > + break; > > +#endif > > #if CONFIG_DXVA2 > > case AV_HWDEVICE_TYPE_DXVA2: > > child_data = surf->Data.MemId; > > @@ -954,6 +1027,12 @@ static int > > qsv_frames_derive_to(AVHWFramesContext *dst_ctx, > > AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx; > > int i; > > > > + if (src_ctx->initial_pool_size == 0) { > > + av_log(dst_ctx, AV_LOG_ERROR, "Only fixed-size pools can be " > > + "mapped to QSV frames.\n"); > > + return AVERROR(EINVAL); > > + } > > + > > switch (src_ctx->device_ctx->type) { #if CONFIG_VAAPI > > case AV_HWDEVICE_TYPE_VAAPI: > > @@ -972,6 +1051,27 @@ static int > > qsv_frames_derive_to(AVHWFramesContext *dst_ctx, > > } > > break; > > #endif > > +#if CONFIG_D3D11VA > > + case AV_HWDEVICE_TYPE_D3D11VA: > > + { > > + AVD3D11VAFramesContext *src_hwctx = src_ctx->hwctx; > > + s->surfaces_internal = > av_mallocz_array(src_ctx->initial_pool_size, > > + > sizeof(*s->surfaces_internal)); > > + if (!s->surfaces_internal) > > + return AVERROR(ENOMEM); > > + for (i = 0; i < src_ctx->initial_pool_size; i++) { > > + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); > > + s->surfaces_internal[i].Data.MemId = > (mfxMemId)(intptr_t)i; > > + s->surfaces_internal[i].Data.reserved2 = > (intptr_t)src_hwctx- > > >texture; > > + } > > + dst_hwctx->nb_surfaces = src_ctx->initial_pool_size; > > + if (src_hwctx->BindFlags & D3D11_BIND_DECODER) > > + dst_hwctx->frame_type = > > MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; > > + else > > + dst_hwctx->frame_type = > > MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; > > + } > > + break; > > +#endif > > #if CONFIG_DXVA2 > > case AV_HWDEVICE_TYPE_DXVA2: > > { > > @@ -1005,21 +1105,33 @@ static int qsv_map_to(AVHWFramesContext > > *dst_ctx, > > AVFrame *dst, const AVFrame *src, int flags) { > > AVQSVFramesContext *hwctx = dst_ctx->hwctx; > > - int i, err; > > + int i, err, index = -1; > > > > - for (i = 0; i < hwctx->nb_surfaces; i++) { > > + for (i = 0; i < hwctx->nb_surfaces && index < 0; i++) { > > #if CONFIG_VAAPI > > - if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId == > > - (VASurfaceID)(uintptr_t)src->data[3]) > > + if (AV_PIX_FMT_VAAPI == src->format) { > > + if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId == > > + (VASurfaceID)(uintptr_t)src->data[3]) > > + index = i > > break; > > + } > > #endif > > -#if CONFIG_DXVA2 > > - if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId == > > - (IDirect3DSurface9*)(uintptr_t)src->data[3]) > > +#if CONFIG_D3D11VA > > + if (AV_PIX_FMT_D3D11 == src->format) { > > + if (i == (intptr_t)src->data[1]) > > + index = i; > > break; > > + } > > +#endif > > +#if CONFIG_DXVA2 > > + if (AV_PIX_FMT_DXVA2_VLD == src->format) { > > + if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId == > > + (IDirect3DSurface9*)(uintptr_t)src->data[3]) > > + index = i; > > + } > > #endif > > } > > - if (i >= hwctx->nb_surfaces) { > > + if (index < 0) { > > av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface > which " > > "is not in the mapped frames context.\n"); > > return AVERROR(EINVAL); > > @@ -1032,7 +1144,7 @@ static int qsv_map_to(AVHWFramesContext > > *dst_ctx, > > > > dst->width = src->width; > > dst->height = src->height; > > - dst->data[3] = (uint8_t*)&hwctx->surfaces[i]; > > + dst->data[3] = (uint8_t*)&hwctx->surfaces[index]; > > > > return 0; > > } > > @@ -1074,7 +1186,7 @@ static void qsv_device_free(AVHWDeviceContext > > *ctx) > > av_freep(&priv); > > } > > > > -static mfxIMPL choose_implementation(const char *device) > > +static mfxIMPL choose_implementation(const char *device, enum > > +AVHWDeviceType child_device_type) > > { > > static const struct { > > const char *name; > > @@ -1103,6 +1215,10 @@ static mfxIMPL choose_implementation(const > > char *device) > > impl = strtol(device, NULL, 0); > > } > > > > + if ( (child_device_type == AV_HWDEVICE_TYPE_D3D11VA) && (impl != > > MFX_IMPL_SOFTWARE) ) { > > + impl |= MFX_IMPL_VIA_D3D11; > > + } > > + > > return impl; > > } > > > > @@ -1129,6 +1245,15 @@ static int > > qsv_device_derive_from_child(AVHWDeviceContext *ctx, > > } > > break; > > #endif > > +#if CONFIG_D3D11VA > > + case AV_HWDEVICE_TYPE_D3D11VA: > > + { > > + AVD3D11VADeviceContext *child_device_hwctx = > child_device_ctx- > > >hwctx; > > + handle_type = MFX_HANDLE_D3D11_DEVICE; > > + handle = (mfxHDL)child_device_hwctx->device; > > + } > > + break; > > +#endif > > #if CONFIG_DXVA2 > > case AV_HWDEVICE_TYPE_DXVA2: > > { > > @@ -1191,7 +1316,9 @@ fail: > > static int qsv_device_derive(AVHWDeviceContext *ctx, > > AVHWDeviceContext *child_device_ctx, int > flags) { > > - return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY, > > + mfxIMPL impl; > > + impl = choose_implementation("hw_any", child_device_ctx->type); > > + return qsv_device_derive_from_child(ctx, impl, > > child_device_ctx, flags); } > > > > @@ -1214,35 +1341,66 @@ static int > > qsv_device_create(AVHWDeviceContext *ctx, const char *device, > > ctx->user_opaque = priv; > > ctx->free = qsv_device_free; > > > > - e = av_dict_get(opts, "child_device", NULL, 0); > > - > > - child_device_opts = NULL; > > - if (CONFIG_VAAPI) { > > + e = av_dict_get(opts, "child_device_type", NULL, 0); > > + if (e) { > > + child_device_type = av_hwdevice_find_type_by_name(e ? e->value : > > NULL); > > + if (child_device_type == AV_HWDEVICE_TYPE_NONE) { > > + av_log(ctx, AV_LOG_ERROR, "Unknown child device type " > > + "\"%s\".\n", e ? e->value : NULL); > > + return AVERROR(EINVAL); > > + } > > + } else if (CONFIG_VAAPI) { > > child_device_type = AV_HWDEVICE_TYPE_VAAPI; > > - // libmfx does not actually implement VAAPI properly, rather it > > - // depends on the specific behaviour of a matching iHD driver > when > > - // used on recent Intel hardware. Set options to the VAAPI > device > > - // creation so that we should pick a usable setup by default if > > - // possible, even when multiple devices and drivers are > available. > > - av_dict_set(&child_device_opts, "kernel_driver", "i915", 0); > > - av_dict_set(&child_device_opts, "driver", "iHD", 0); > > - } else if (CONFIG_DXVA2) > > + } else if (CONFIG_D3D11VA) { > > + child_device_type = AV_HWDEVICE_TYPE_D3D11VA; > > + } else if (CONFIG_DXVA2) { > > child_device_type = AV_HWDEVICE_TYPE_DXVA2; > > - else { > > + } else { > > av_log(ctx, AV_LOG_ERROR, "No supported child device type is > > enabled\n"); > > return AVERROR(ENOSYS); > > } > > > > + child_device_opts = NULL; > > + switch (child_device_type) { > > +#if CONFIG_VAAPI > > + case AV_HWDEVICE_TYPE_VAAPI: > > + { > > + // libmfx does not actually implement VAAPI properly, > rather it > > + // depends on the specific behaviour of a matching iHD > driver when > > + // used on recent Intel hardware. Set options to the VAAPI > device > > + // creation so that we should pick a usable setup by > default if > > + // possible, even when multiple devices and drivers are > available. > > + av_dict_set(&child_device_opts, "kernel_driver", "i915", 0); > > + av_dict_set(&child_device_opts, "driver", "iHD", 0); > > + } > > + break; > > +#endif > > +#if CONFIG_D3D11VA > > + case AV_HWDEVICE_TYPE_D3D11VA: > > + break; > > +#endif > > +#if CONFIG_DXVA2 > > + case AV_HWDEVICE_TYPE_DXVA2: > > + break; > > +#endif > > + default: > > + { > > + av_log(ctx, AV_LOG_ERROR, "No supported child device type is > > enabled\n"); > > + return AVERROR(ENOSYS); > > + } > > + break; > > + } > > + > > + e = av_dict_get(opts, "child_device", NULL, 0); > > ret = av_hwdevice_ctx_create(&priv->child_device_ctx, > > child_device_type, > > e ? e->value : NULL, > child_device_opts, 0); > > - > > av_dict_free(&child_device_opts); > > if (ret < 0) > > return ret; > > > > child_device = (AVHWDeviceContext*)priv->child_device_ctx->data; > > > > - impl = choose_implementation(device); > > + impl = choose_implementation(device, child_device_type); > > > > return qsv_device_derive_from_child(ctx, impl, child_device, 0); } > > -- > > 2.21.0 > > > This appears to be a bit half-baked. What's missing imo is: > > - Allow selection of a specific DXGI adapter > -qsv_device command line option allows you to select specific DXGI adapter. This options was available for a long time. > - Change filters to support mfxHandlePair > - filters are next step > - Allow deriving from D3D11VA hw context > - will check this > Also, have you tested all possible use cases: > > - Setting up standalone hw decoder (no hw encoder) > yes > - Setting up standalone hw encoder (no hw decoder) > yes > - Filter-only hw device context > Could you please clarify this? > > Further, I think there should be an explicit selection between D3D9 > and D3D11 instead of an automatic selection. > Explicit selection is available via -init_hw_device qsv:,child_device_type=d3d11va or -init_hw_device qsv:,child_device_type=dxva2 command line options Thanks, Artem. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".