summaryrefslogtreecommitdiff
path: root/libavcodec/vdpau.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/vdpau.c')
-rw-r--r--libavcodec/vdpau.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index da6fc1e0bf..167f06d7ae 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,