On 04/05/17 07:44, wm4 wrote: > This also adds support to avconv (which is trivial due to the new > hwaccel API being generic enough). For now, this keeps avconv_dxva2.c as > "dxva2-old", although it doesn't work as avconv.c can't handle multiple > hwaccels with the same pixfmt.
Is there any reason to keep it on in avconv? It doesn't look like it offers anything which isn't fully replaced. > The new decoder setup code in dxva2.c is significantly based on work by > Steve Lhomme <[email protected]>, but with heavy changes/rewrites. > --- > Changelog | 1 + > avtools/avconv.h | 2 + > avtools/avconv_opt.c | 8 +- > configure | 12 +- > doc/APIchanges | 6 + > libavcodec/allcodecs.c | 5 + > libavcodec/dxva2.c | 654 > +++++++++++++++++++++++++++++++++++++++++++- > libavcodec/dxva2_h264.c | 22 ++ > libavcodec/dxva2_hevc.c | 22 ++ > libavcodec/dxva2_internal.h | 43 ++- > libavcodec/dxva2_mpeg2.c | 22 ++ > libavcodec/dxva2_vc1.c | 44 +++ > libavcodec/h264_slice.c | 3 +- > libavcodec/hevcdec.c | 3 +- > libavcodec/mpeg12dec.c | 1 + > libavcodec/vc1dec.c | 1 + > libavcodec/version.h | 4 +- > libavutil/hwcontext_dxva2.h | 3 + > 18 files changed, 844 insertions(+), 12 deletions(-) > > diff --git a/Changelog b/Changelog > index 6fd30fddb9..e44df54c93 100644 > --- a/Changelog > +++ b/Changelog > @@ -15,6 +15,7 @@ version <next>: > - VP9 superframe split/merge bitstream filters > - FM Screen Capture Codec decoder > - ClearVideo decoder (I-frames only) > +- support for decoding through D3D11VA in avconv > > > version 12: > diff --git a/avtools/avconv.h b/avtools/avconv.h > index 3354c50444..fe2bb313b7 100644 > --- a/avtools/avconv.h > +++ b/avtools/avconv.h > @@ -54,9 +54,11 @@ enum HWAccelID { > HWACCEL_AUTO, > HWACCEL_VDPAU, > HWACCEL_DXVA2, > + HWACCEL_DXVA2_OLD, > HWACCEL_VDA, > HWACCEL_QSV, > HWACCEL_VAAPI, > + HWACCEL_D3D11VA, > }; > > typedef struct HWAccel { > diff --git a/avtools/avconv_opt.c b/avtools/avconv_opt.c > index 9839a2269e..e2599bd4d8 100644 > --- a/avtools/avconv_opt.c > +++ b/avtools/avconv_opt.c > @@ -60,8 +60,14 @@ const HWAccel hwaccels[] = { > { "vdpau", hwaccel_decode_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU, > AV_HWDEVICE_TYPE_VDPAU }, > #endif > +#if HAVE_D3D11VA_LIB > + { "d3d11va", hwaccel_decode_init, HWACCEL_D3D11VA, AV_PIX_FMT_D3D11, > + AV_HWDEVICE_TYPE_D3D11VA }, > +#endif > #if HAVE_DXVA2_LIB > - { "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD, > + { "dxva2", hwaccel_decode_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD, > + AV_HWDEVICE_TYPE_DXVA2}, Nit: missing space. > + { "dxva2-old", dxva2_init, HWACCEL_DXVA2_OLD, AV_PIX_FMT_DXVA2_VLD, > AV_HWDEVICE_TYPE_NONE }, > #endif > #if CONFIG_VDA (No changes at all in avconv_hw :) > ... > +// This must work before the decoder is created. > +// This somehow needs to be exported to the user. > +static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext > *frames_ctx) > +{ > + FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx); > + int surface_alignment, num_surfaces; > + > + frames_ctx->format = sctx->pix_fmt; > + > + /* decoding MPEG-2 requires additional alignment on some Intel GPUs, > + but it causes issues for H.264 on certain AMD GPUs..... */ > + if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO) > + surface_alignment = 32; > + /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure > + all coding features have enough room to work with */ > + else if (avctx->codec_id == AV_CODEC_ID_HEVC) > + surface_alignment = 128; > + else > + surface_alignment = 16; > + > + /* 4 base work surfaces */ > + num_surfaces = 4; > + > + /* add surfaces based on number of possible refs */ > + if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == > AV_CODEC_ID_HEVC) > + num_surfaces += 16; > + else > + num_surfaces += 2; > + > + /* add extra surfaces for frame threading */ > + if (avctx->active_thread_type & FF_THREAD_FRAME) > + num_surfaces += avctx->thread_count; > + > + frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? > + AV_PIX_FMT_P010 : AV_PIX_FMT_NV12; > + frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment); > + frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment); > + frames_ctx->initial_pool_size = num_surfaces; > + > + if (frames_ctx->format == AV_PIX_FMT_DXVA2_VLD) { > + AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx; > + > + frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget; > + } > + > + if (frames_ctx->format == AV_PIX_FMT_D3D11) { > + AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx; > + > + frames_hwctx->BindFlags |= D3D11_BIND_DECODER; > + } > +} > + > +int ff_dxva2_decode_init(AVCodecContext *avctx) > +{ > + FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx); > + AVHWFramesContext *frames_ctx = NULL; > + int ret = 0; > + > + // Old API. > + if (avctx->hwaccel_context) > + return 0; > + > + // (avctx->pix_fmt is not updated yet at this point) > + sctx->pix_fmt = avctx->hwaccel->pix_fmt; > + > + if (avctx->codec_id == AV_CODEC_ID_H264 && > + (avctx->profile & ~FF_PROFILE_H264_CONSTRAINED) > > FF_PROFILE_H264_HIGH) { > + av_log(avctx, AV_LOG_VERBOSE, "Unsupported H.264 profile for DXVA > HWAccel: %d\n",avctx->profile); > + return AVERROR(ENOTSUP); > + } > + > + if (avctx->codec_id == AV_CODEC_ID_HEVC && > + avctx->profile != FF_PROFILE_HEVC_MAIN && avctx->profile != > FF_PROFILE_HEVC_MAIN_10) { > + av_log(avctx, AV_LOG_VERBOSE, "Unsupported HEVC profile for DXVA > HWAccel: %d\n", avctx->profile); > + return AVERROR(ENOTSUP); > + } > + > + if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) { > + av_log(avctx, AV_LOG_ERROR, "Either a hw_frames_ctx or a > hw_device_ctx needs to be set for hardware decoding.\n"); > + return AVERROR(EINVAL); > + } > + > + if (avctx->hw_frames_ctx) { > + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; > + } else { > + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx); > + if (!avctx->hw_frames_ctx) > + return AVERROR(ENOMEM); > + > + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; > + > + dxva_adjust_hwframes(avctx, frames_ctx); > + > + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); > + if (ret < 0) > + goto fail; > + } > + > + sctx->device_ctx = frames_ctx->device_ctx; > + > + if (frames_ctx->format != sctx->pix_fmt || > + !((sctx->pix_fmt == AV_PIX_FMT_D3D11 && CONFIG_D3D11VA) || > + (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && CONFIG_DXVA2))) { > + av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n"); > + ret = AVERROR(EINVAL); > + goto fail; > + } > + > +#if CONFIG_D3D11VA > + if (sctx->pix_fmt == AV_PIX_FMT_D3D11) { > + AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx; > + AVD3D11VAContext *d3d11_ctx = &sctx->ctx.d3d11va; > + HRESULT hr; > + > + ret = d3d11va_create_decoder(avctx); > + if (ret < 0) > + goto fail; > + > + d3d11_ctx->decoder = sctx->d3d11_decoder; > + d3d11_ctx->video_context = device_hwctx->video_context; > + d3d11_ctx->cfg = &sctx->d3d11_config; > + d3d11_ctx->surface_count = sctx->nb_d3d11_views; > + d3d11_ctx->surface = sctx->d3d11_views; > + d3d11_ctx->workaround = sctx->workaround; > + d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE; > + } > +#endif > + > +#if CONFIG_DXVA2 > + if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { > + AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx; > + struct dxva_context *dxva_ctx = &sctx->ctx.dxva2; > + > + ret = dxva2_create_decoder(avctx); > + if (ret < 0) > + goto fail; > + > + dxva_ctx->decoder = sctx->dxva2_decoder; > + dxva_ctx->cfg = &sctx->dxva2_config; > + dxva_ctx->surface = frames_hwctx->surfaces; > + dxva_ctx->surface_count = frames_hwctx->nb_surfaces; > + dxva_ctx->workaround = sctx->workaround; > + } > +#endif > + > + return 0; > + > +fail: > + ff_dxva2_decode_uninit(avctx); > + return ret; > +} So the user configuration we want here is replacement of the dxva_adjust_hwframes function? AVCodecContext.init_hw_frames from <https://lists.libav.org/pipermail/libav-devel/2017-March/083133.html> looks like exactly this (ignoring all the other parts there) - I think we were both loosely agreeing to something like it but the discussion tailed off without a conclusion, so maybe we should reopen it now. Rest of patch appears sensible, but I don't know enough API detail to review carefully. Thanks, - Mark _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
