On Sun, 19 Feb 2017 18:46:28 +0000 Mark Thompson <[email protected]> wrote:
> From: wm4 <[email protected]> > > This supports retrieving the device from a provided hw_frames_ctx, and > automatically creating a hw_frames_ctx if hw_device_ctx is set. > > The old API is not deprecated yet. The user can still use > av_vdpau_bind_context() (with or without setting hw_frames_ctx), or use > the API before that by allocating and setting hwaccel_context manually. > --- > doc/APIchanges | 4 +++ > libavcodec/vdpau.c | 85 > +++++++++++++++++++++++++++++++++++---------- > libavcodec/vdpau_internal.h | 2 ++ > 3 files changed, 72 insertions(+), 19 deletions(-) > > diff --git a/doc/APIchanges b/doc/APIchanges > index 3bf392465..1e84c3803 100644 > --- a/doc/APIchanges > +++ b/doc/APIchanges > @@ -14,6 +14,10 @@ libavutil: 2015-08-28 > API changes, most recent first: > > 2017-02-xx - xxxxxxx - lavc - avcodec.h > + The vdpau hwaccel now works with the AVCodecContext.hw_frames_ctx and > + AVCodecContext.hw_device_ctx APIs. > + > +2017-02-xx - xxxxxxx - lavc - avcodec.h > Add AVCodecContext.hwaccel_flags field. This will control some hwaccels at > a later point. > > diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c > index d3cb188d7..68d0813f6 100644 > --- a/libavcodec/vdpau.c > +++ b/libavcodec/vdpau.c > @@ -118,29 +118,76 @@ int ff_vdpau_common_init(AVCodecContext *avctx, > VdpDecoderProfile profile, > > vdctx->width = UINT32_MAX; > vdctx->height = UINT32_MAX; > - hwctx->reset = 0; > > - if (hwctx->context.decoder != VDP_INVALID_HANDLE) { > - vdctx->decoder = hwctx->context.decoder; > - vdctx->render = hwctx->context.render; > - vdctx->device = VDP_INVALID_HANDLE; > - return 0; /* Decoder created by user */ > - } > + if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) > + return AVERROR(ENOSYS); > > - vdctx->device = hwctx->device; > - vdctx->get_proc_address = hwctx->get_proc_address; > + if (hwctx) { > + hwctx->reset = 0; > > - if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) > - level = 0; > - else if (level < 0) > - return AVERROR(ENOTSUP); > + if (hwctx->context.decoder != VDP_INVALID_HANDLE) { > + vdctx->decoder = hwctx->context.decoder; > + vdctx->render = hwctx->context.render; > + vdctx->device = VDP_INVALID_HANDLE; > + return 0; /* Decoder created by user */ > + } > > - if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) > - return AVERROR(ENOSYS); > + vdctx->device = hwctx->device; > + vdctx->get_proc_address = hwctx->get_proc_address; > + > + if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) > + level = 0; > + > + if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) && > + type != VDP_CHROMA_TYPE_420) > + return AVERROR(ENOSYS); > + } else { > + AVHWFramesContext *frames_ctx = NULL; > + AVVDPAUDeviceContext *dev_ctx; > + > + // We assume the hw_frames_ctx always survives until > ff_vdpau_common_uninit > + // is called. This holds true as the user is not allowed to touch > + // hw_device_ctx, or hw_frames_ctx after get_format (and > ff_get_format > + // itself also uninits before unreffing hw_frames_ctx). > + if (avctx->hw_frames_ctx) { > + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; > + } else if (avctx->hw_device_ctx) { > + int ret; > + > + 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; > + frames_ctx->format = AV_PIX_FMT_VDPAU; > + frames_ctx->sw_format = avctx->sw_pix_fmt; > + frames_ctx->width = avctx->coded_width; > + frames_ctx->height = avctx->coded_height; > + > + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); > + if (ret < 0) { > + av_buffer_unref(&avctx->hw_frames_ctx); > + return ret; > + } > + } > > - if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) && > - type != VDP_CHROMA_TYPE_420) > - return AVERROR(ENOSYS); > + if (!frames_ctx) { > + av_log(avctx, AV_LOG_ERROR, "A hardware frames context is " > + "required for VDPAU decoding.\n"); > + return AVERROR(EINVAL); > + } > + > + dev_ctx = frames_ctx->device_ctx->hwctx; > + > + vdctx->device = dev_ctx->device; > + vdctx->get_proc_address = dev_ctx->get_proc_address; > + > + if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) > + level = 0; > + } > + > + if (level < 0) > + return AVERROR(ENOTSUP); > > status = vdctx->get_proc_address(vdctx->device, > > VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, > @@ -238,7 +285,7 @@ static int ff_vdpau_common_reinit(AVCodecContext *avctx) > if (vdctx->device == VDP_INVALID_HANDLE) > return 0; /* Decoder created by user */ > if (avctx->coded_width == vdctx->width && > - avctx->coded_height == vdctx->height && !hwctx->reset) > + avctx->coded_height == vdctx->height && (!hwctx || !hwctx->reset)) > return 0; > > avctx->hwaccel->uninit(avctx); > diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h > index c7281a6b5..a0eb46c48 100644 > --- a/libavcodec/vdpau_internal.h > +++ b/libavcodec/vdpau_internal.h > @@ -28,6 +28,8 @@ > #include <vdpau/vdpau.h> > > #include "libavutil/frame.h" > +#include "libavutil/hwcontext.h" > +#include "libavutil/hwcontext_vdpau.h" > > #include "avcodec.h" > #include "vdpau.h" I assume nothing got changed. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
