diff options
Diffstat (limited to 'libavcodec/vdpau.c')
-rw-r--r-- | libavcodec/vdpau.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index da6fc1e..167f06d 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -4,20 +4,20 @@ * * Copyright (c) 2008 NVIDIA * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,6 +31,9 @@ #include "vdpau.h" #include "vdpau_internal.h" +// XXX: at the time of adding this ifdefery, av_assert* wasn't use outside. +// When dropping it, make sure other av_assert* were not added since then. + /** * @addtogroup VDPAU_Decoding * @@ -61,6 +64,13 @@ static int vdpau_error(VdpStatus status) } } +AVVDPAUContext *av_alloc_vdpaucontext(void) +{ + return av_vdpau_alloc_context(); +} + +MAKE_ACCESSORS(AVVDPAUContext, vdpau_hwaccel, AVVDPAU_Render2, render2) + int av_vdpau_get_surface_parameters(AVCodecContext *avctx, VdpChromaType *type, uint32_t *width, uint32_t *height) @@ -128,6 +138,8 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, VdpVideoSurfaceQueryCapabilities *surface_query_caps; VdpDecoderQueryCapabilities *decoder_query_caps; VdpDecoderCreate *create; + VdpGetInformationString *info; + const char *info_string; void *func; VdpStatus status; VdpBool supported; @@ -184,6 +196,27 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, return AVERROR(ENOTSUP); status = vdctx->get_proc_address(vdctx->device, + VDP_FUNC_ID_GET_INFORMATION_STRING, + &func); + if (status != VDP_STATUS_OK) + return vdpau_error(status); + else + info = func; + + status = info(&info_string); + if (status != VDP_STATUS_OK) + return vdpau_error(status); + if (avctx->codec_id == AV_CODEC_ID_HEVC && strncmp(info_string, "NVIDIA ", 7) == 0 && + !(avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH)) { + int driver_version = 0; + sscanf(info_string, "NVIDIA VDPAU Driver Shared Library %d", &driver_version); + if (driver_version < 410) { + av_log(avctx, AV_LOG_VERBOSE, "HEVC with NVIDIA VDPAU drivers is buggy, skipping.\n"); + return AVERROR(ENOTSUP); + } + } + + status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, &func); if (status != VDP_STATUS_OK) @@ -300,6 +333,7 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, struct vdpau_picture_context *pic_ctx) { VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data; + AVVDPAUContext *hwctx = avctx->hwaccel_context; VdpVideoSurface surf = ff_vdpau_get_surface_id(frame); VdpStatus status; int val; @@ -308,11 +342,16 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, if (val < 0) return val; + if (hwctx && !hwctx->render && hwctx->render2) { + status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info, + pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); + } else status = vdctx->render(vdctx->decoder, surf, &pic_ctx->info, pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); av_freep(&pic_ctx->bitstream_buffers); + return vdpau_error(status); } @@ -405,7 +444,7 @@ do { \ AVVDPAUContext *av_vdpau_alloc_context(void) { - return av_mallocz(sizeof(AVVDPAUContext)); + return av_mallocz(sizeof(VDPAUHWContext)); } int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device, |