2 * VC-1 decode acceleration through VDPAU
4 * Copyright (c) 2008 NVIDIA
5 * Copyright (c) 2013 RĂ©mi Denis-Courmont
7 * This file is part of FFmpeg.
9 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <vdpau/vdpau.h>
29 #include "vdpau_internal.h"
31 static int vdpau_vc1_start_frame(AVCodecContext
*avctx
,
32 const uint8_t *buffer
, uint32_t size
)
34 VC1Context
* const v
= avctx
->priv_data
;
35 MpegEncContext
* const s
= &v
->s
;
36 Picture
*pic
= s
->current_picture_ptr
;
37 struct vdpau_picture_context
*pic_ctx
= pic
->hwaccel_picture_private
;
38 VdpPictureInfoVC1
*info
= &pic_ctx
->info
.vc1
;
41 /* fill LvPictureInfoVC1 struct */
42 info
->forward_reference
= VDP_INVALID_HANDLE
;
43 info
->backward_reference
= VDP_INVALID_HANDLE
;
45 switch (s
->pict_type
) {
46 case AV_PICTURE_TYPE_B
:
47 if (s
->next_picture_ptr
) {
48 ref
= ff_vdpau_get_surface_id(s
->next_picture
.f
);
49 assert(ref
!= VDP_INVALID_HANDLE
);
50 info
->backward_reference
= ref
;
53 case AV_PICTURE_TYPE_P
:
54 if (s
->last_picture_ptr
) {
55 ref
= ff_vdpau_get_surface_id(s
->last_picture
.f
);
56 assert(ref
!= VDP_INVALID_HANDLE
);
57 info
->forward_reference
= ref
;
61 info
->slice_count
= 0;
63 info
->picture_type
= 4;
65 info
->picture_type
= s
->pict_type
- 1 + s
->pict_type
/ 3;
67 info
->frame_coding_mode
= v
->fcm
? (v
->fcm
+ 1) : 0;
68 info
->postprocflag
= v
->postprocflag
;
69 info
->pulldown
= v
->broadcast
;
70 info
->interlace
= v
->interlace
;
71 info
->tfcntrflag
= v
->tfcntrflag
;
72 info
->finterpflag
= v
->finterpflag
;
74 info
->dquant
= v
->dquant
;
75 info
->panscan_flag
= v
->panscanflag
;
76 info
->refdist_flag
= v
->refdist_flag
;
77 info
->quantizer
= v
->quantizer_mode
;
78 info
->extended_mv
= v
->extended_mv
;
79 info
->extended_dmv
= v
->extended_dmv
;
80 info
->overlap
= v
->overlap
;
81 info
->vstransform
= v
->vstransform
;
82 info
->loopfilter
= v
->s
.loop_filter
;
83 info
->fastuvmc
= v
->fastuvmc
;
84 info
->range_mapy_flag
= v
->range_mapy_flag
;
85 info
->range_mapy
= v
->range_mapy
;
86 info
->range_mapuv_flag
= v
->range_mapuv_flag
;
87 info
->range_mapuv
= v
->range_mapuv
;
88 /* Specific to simple/main profile only */
89 info
->multires
= v
->multires
;
90 info
->syncmarker
= v
->resync_marker
;
91 info
->rangered
= v
->rangered
| (v
->rangeredfrm
<< 1);
92 info
->maxbframes
= v
->s
.max_b_frames
;
93 info
->deblockEnable
= v
->postprocflag
& 1;
96 return ff_vdpau_common_start_frame(pic_ctx
, buffer
, size
);
99 static int vdpau_vc1_decode_slice(AVCodecContext
*avctx
,
100 const uint8_t *buffer
, uint32_t size
)
102 VC1Context
* const v
= avctx
->priv_data
;
103 MpegEncContext
* const s
= &v
->s
;
104 Picture
*pic
= s
->current_picture_ptr
;
105 struct vdpau_picture_context
*pic_ctx
= pic
->hwaccel_picture_private
;
108 val
= ff_vdpau_add_buffer(pic_ctx
, buffer
, size
);
112 pic_ctx
->info
.vc1
.slice_count
++;
116 static int vdpau_vc1_init(AVCodecContext
*avctx
)
118 VdpDecoderProfile profile
;
120 switch (avctx
->profile
) {
121 case FF_PROFILE_VC1_SIMPLE
:
122 profile
= VDP_DECODER_PROFILE_VC1_SIMPLE
;
124 case FF_PROFILE_VC1_MAIN
:
125 profile
= VDP_DECODER_PROFILE_VC1_MAIN
;
127 case FF_PROFILE_VC1_ADVANCED
:
128 profile
= VDP_DECODER_PROFILE_VC1_ADVANCED
;
131 return AVERROR(ENOTSUP
);
134 return ff_vdpau_common_init(avctx
, profile
, avctx
->level
);
137 #if CONFIG_WMV3_VDPAU_HWACCEL
138 AVHWAccel ff_wmv3_vdpau_hwaccel
= {
140 .type
= AVMEDIA_TYPE_VIDEO
,
141 .id
= AV_CODEC_ID_WMV3
,
142 .pix_fmt
= AV_PIX_FMT_VDPAU
,
143 .start_frame
= vdpau_vc1_start_frame
,
144 .end_frame
= ff_vdpau_mpeg_end_frame
,
145 .decode_slice
= vdpau_vc1_decode_slice
,
146 .frame_priv_data_size
= sizeof(struct vdpau_picture_context
),
147 .init
= vdpau_vc1_init
,
148 .uninit
= ff_vdpau_common_uninit
,
149 .priv_data_size
= sizeof(VDPAUContext
),
153 AVHWAccel ff_vc1_vdpau_hwaccel
= {
155 .type
= AVMEDIA_TYPE_VIDEO
,
156 .id
= AV_CODEC_ID_VC1
,
157 .pix_fmt
= AV_PIX_FMT_VDPAU
,
158 .start_frame
= vdpau_vc1_start_frame
,
159 .end_frame
= ff_vdpau_mpeg_end_frame
,
160 .decode_slice
= vdpau_vc1_decode_slice
,
161 .frame_priv_data_size
= sizeof(struct vdpau_picture_context
),
162 .init
= vdpau_vc1_init
,
163 .uninit
= ff_vdpau_common_uninit
,
164 .priv_data_size
= sizeof(VDPAUContext
),