2 * Video Decode and Presentation API for UNIX (VDPAU) is used for
3 * HW decode acceleration for MPEG-1/2, MPEG-4 ASP, H.264 and VC-1.
5 * Copyright (c) 2008 NVIDIA
7 * This file is part of Libav.
9 * Libav is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * Libav is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with Libav; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "vdpau_internal.h"
36 * @addtogroup VDPAU_Decoding
41 static int vdpau_error(VdpStatus status)
46 case VDP_STATUS_NO_IMPLEMENTATION:
47 return AVERROR(ENOSYS);
48 case VDP_STATUS_DISPLAY_PREEMPTED:
50 case VDP_STATUS_INVALID_HANDLE:
51 return AVERROR(EBADF);
52 case VDP_STATUS_INVALID_POINTER:
53 return AVERROR(EFAULT);
54 case VDP_STATUS_RESOURCES:
55 return AVERROR(ENOBUFS);
56 case VDP_STATUS_HANDLE_DEVICE_MISMATCH:
57 return AVERROR(EXDEV);
58 case VDP_STATUS_ERROR:
61 return AVERROR(EINVAL);
65 int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx,
66 av_unused const uint8_t *buffer,
67 av_unused uint32_t size)
69 pic_ctx->bitstream_buffers_allocated = 0;
70 pic_ctx->bitstream_buffers_used = 0;
71 pic_ctx->bitstream_buffers = NULL;
75 int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
76 struct vdpau_picture_context *pic_ctx)
78 AVVDPAUContext *hwctx = avctx->hwaccel_context;
79 VdpVideoSurface surf = ff_vdpau_get_surface_id(frame);
82 status = hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
83 pic_ctx->bitstream_buffers_used,
84 pic_ctx->bitstream_buffers);
86 av_freep(&pic_ctx->bitstream_buffers);
87 return vdpau_error(status);
90 #if CONFIG_H263_VDPAU_HWACCEL || CONFIG_MPEG1_VDPAU_HWACCEL || \
91 CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \
92 CONFIG_VC1_VDPAU_HWACCEL || CONFIG_WMV3_VDPAU_HWACCEL
93 int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
95 MpegEncContext *s = avctx->priv_data;
96 Picture *pic = s->current_picture_ptr;
97 struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
100 val = ff_vdpau_common_end_frame(avctx, pic->f, pic_ctx);
104 ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
109 int ff_vdpau_add_buffer(struct vdpau_picture_context *pic_ctx,
110 const uint8_t *buf, uint32_t size)
112 VdpBitstreamBuffer *buffers = pic_ctx->bitstream_buffers;
114 buffers = av_fast_realloc(buffers, &pic_ctx->bitstream_buffers_allocated,
115 (pic_ctx->bitstream_buffers_used + 1) * sizeof(*buffers));
117 return AVERROR(ENOMEM);
119 pic_ctx->bitstream_buffers = buffers;
120 buffers += pic_ctx->bitstream_buffers_used++;
122 buffers->struct_version = VDP_BITSTREAM_BUFFER_VERSION;
123 buffers->bitstream = buf;
124 buffers->bitstream_bytes = size;
128 int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile)
130 #define PROFILE(prof) \
136 switch (avctx->codec_id) {
137 case AV_CODEC_ID_MPEG1VIDEO: PROFILE(VDP_DECODER_PROFILE_MPEG1);
138 case AV_CODEC_ID_MPEG2VIDEO:
139 switch (avctx->profile) {
140 case FF_PROFILE_MPEG2_MAIN: PROFILE(VDP_DECODER_PROFILE_MPEG2_MAIN);
141 case FF_PROFILE_MPEG2_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG2_SIMPLE);
142 default: return AVERROR(EINVAL);
144 case AV_CODEC_ID_H263: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP);
145 case AV_CODEC_ID_MPEG4:
146 switch (avctx->profile) {
147 case FF_PROFILE_MPEG4_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_SP);
148 case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP);
149 default: return AVERROR(EINVAL);
151 case AV_CODEC_ID_H264:
152 switch (avctx->profile & ~FF_PROFILE_H264_INTRA) {
153 case FF_PROFILE_H264_CONSTRAINED_BASELINE:
154 case FF_PROFILE_H264_BASELINE: PROFILE(VDP_DECODER_PROFILE_H264_BASELINE);
155 case FF_PROFILE_H264_MAIN: PROFILE(VDP_DECODER_PROFILE_H264_MAIN);
156 case FF_PROFILE_H264_HIGH: PROFILE(VDP_DECODER_PROFILE_H264_HIGH);
157 default: return AVERROR(EINVAL);
159 case AV_CODEC_ID_WMV3:
160 case AV_CODEC_ID_VC1:
161 switch (avctx->profile) {
162 case FF_PROFILE_VC1_SIMPLE: PROFILE(VDP_DECODER_PROFILE_VC1_SIMPLE);
163 case FF_PROFILE_VC1_MAIN: PROFILE(VDP_DECODER_PROFILE_VC1_MAIN);
164 case FF_PROFILE_VC1_ADVANCED: PROFILE(VDP_DECODER_PROFILE_VC1_ADVANCED);
165 default: return AVERROR(EINVAL);
168 return AVERROR(EINVAL);
171 AVVDPAUContext *av_vdpau_alloc_context(void)
173 return av_mallocz(sizeof(AVVDPAUContext));