On 20/02/17 06:01, wm4 wrote: > 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.
Yeah, 5 and 6 are just your patches as-is so that I can include 7 for VDPAU. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
