Mercurial > libavcodec.hg
annotate dxva2_vc1.c @ 12043:f9a0bd0888a4 libavcodec
mpegaudio: call ff_mpegaudiodec_init_mmx() only from float decoder
The mmx code is floating-point only, and this function does not know
from which decoder it is called. Without this change, the integer
decoder only "works" because the size of the context struct is smaller
in this case, and the mmx init function writes the function pointer
outside the allocated context.
author | mru |
---|---|
date | Thu, 01 Jul 2010 23:21:17 +0000 |
parents | 8a4984c5cacc |
children |
rev | line source |
---|---|
10990 | 1 /* |
2 * DXVA2 WMV3/VC-1 HW acceleration. | |
3 * | |
4 * copyright (c) 2010 Laurent Aimar | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 #include "dxva2_internal.h" | |
24 #include "vc1.h" | |
25 #include "vc1data.h" | |
26 | |
27 struct dxva2_picture_context { | |
28 DXVA_PictureParameters pp; | |
29 DXVA_SliceInfo si; | |
30 | |
31 const uint8_t *bitstream; | |
32 unsigned bitstream_size; | |
33 }; | |
34 | |
35 static void fill_picture_parameters(AVCodecContext *avctx, | |
36 struct dxva_context *ctx, const VC1Context *v, | |
37 DXVA_PictureParameters *pp) | |
38 { | |
39 const MpegEncContext *s = &v->s; | |
40 const Picture *current_picture = s->current_picture_ptr; | |
41 | |
42 memset(pp, 0, sizeof(*pp)); | |
43 pp->wDecodedPictureIndex = | |
44 pp->wDeblockedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture); | |
45 if (s->pict_type != FF_I_TYPE) | |
46 pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->last_picture); | |
47 else | |
48 pp->wForwardRefPictureIndex = 0xffff; | |
49 if (s->pict_type == FF_B_TYPE) | |
50 pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->next_picture); | |
51 else | |
52 pp->wBackwardRefPictureIndex = 0xffff; | |
53 if (v->profile == PROFILE_ADVANCED) { | |
54 /* It is the cropped width/height -1 of the frame */ | |
55 pp->wPicWidthInMBminus1 = avctx->width - 1; | |
56 pp->wPicHeightInMBminus1= avctx->height - 1; | |
57 } else { | |
58 /* It is the coded width/height in macroblock -1 of the frame */ | |
59 pp->wPicWidthInMBminus1 = s->mb_width - 1; | |
60 pp->wPicHeightInMBminus1= s->mb_height - 1; | |
61 } | |
62 pp->bMacroblockWidthMinus1 = 15; | |
63 pp->bMacroblockHeightMinus1 = 15; | |
64 pp->bBlockWidthMinus1 = 7; | |
65 pp->bBlockHeightMinus1 = 7; | |
66 pp->bBPPminus1 = 7; | |
67 if (s->picture_structure & PICT_TOP_FIELD) | |
68 pp->bPicStructure |= 0x01; | |
69 if (s->picture_structure & PICT_BOTTOM_FIELD) | |
70 pp->bPicStructure |= 0x02; | |
71 pp->bSecondField = v->interlace && v->fcm != 0x03 && !s->first_field; | |
72 pp->bPicIntra = s->pict_type == FF_I_TYPE; | |
73 pp->bPicBackwardPrediction = s->pict_type == FF_B_TYPE; | |
74 pp->bBidirectionalAveragingMode = (1 << 7) | | |
75 ((ctx->cfg->ConfigIntraResidUnsigned != 0) << 6) | | |
76 ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) | | |
77 ((v->lumscale != 32 || v->lumshift != 0) << 4) | | |
78 ((v->profile == PROFILE_ADVANCED) << 3); | |
79 pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) | | |
80 (1 << 2) | | |
81 (0 << 1) | | |
82 (!s->quarter_sample ); | |
83 pp->bChromaFormat = v->chromaformat; | |
84 ctx->report_id++; | |
85 if (ctx->report_id >= (1 << 16)) | |
86 ctx->report_id = 1; | |
87 pp->bPicScanFixed = ctx->report_id >> 8; | |
88 pp->bPicScanMethod = ctx->report_id & 0xff; | |
89 pp->bPicReadbackRequests = 0; | |
90 pp->bRcontrol = v->rnd; | |
91 pp->bPicSpatialResid8 = (v->panscanflag << 7) | | |
92 (v->refdist_flag << 6) | | |
93 (s->loop_filter << 5) | | |
94 (v->fastuvmc << 4) | | |
95 (v->extended_mv << 3) | | |
96 (v->dquant << 1) | | |
97 (v->vstransform ); | |
98 pp->bPicOverflowBlocks = (v->quantizer_mode << 6) | | |
99 (v->multires << 5) | | |
100 (s->resync_marker << 4) | | |
101 (v->rangered << 3) | | |
102 (s->max_b_frames ); | |
103 pp->bPicExtrapolation = (!v->interlace || v->fcm == 0x00) ? 1 : 2; | |
104 pp->bPicDeblocked = ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) | | |
105 (s->loop_filter << 1); | |
106 pp->bPicDeblockConfined = (v->postprocflag << 7) | | |
107 (v->broadcast << 6) | | |
108 (v->interlace << 5) | | |
109 (v->tfcntrflag << 4) | | |
110 (v->finterpflag << 3) | | |
111 ((s->pict_type != FF_B_TYPE) << 2) | | |
112 (v->psf << 1) | | |
113 (v->extended_dmv ); | |
114 if (s->pict_type != FF_I_TYPE) | |
115 pp->bPic4MVallowed = v->mv_mode == MV_PMODE_MIXED_MV || | |
116 (v->mv_mode == MV_PMODE_INTENSITY_COMP && | |
117 v->mv_mode2 == MV_PMODE_MIXED_MV); | |
118 if (v->profile == PROFILE_ADVANCED) | |
119 pp->bPicOBMC = (v->range_mapy_flag << 7) | | |
120 (v->range_mapy << 4) | | |
121 (v->range_mapuv_flag << 3) | | |
122 (v->range_mapuv ); | |
123 pp->bPicBinPB = 0; | |
124 pp->bMV_RPS = 0; | |
125 pp->bReservedBits = 0; | |
126 if (s->picture_structure == PICT_FRAME) { | |
127 pp->wBitstreamFcodes = v->lumscale; | |
128 pp->wBitstreamPCEelements = v->lumshift; | |
129 } else { | |
130 /* Syntax: (top_field_param << 8) | bottom_field_param */ | |
131 pp->wBitstreamFcodes = (v->lumscale << 8) | v->lumscale; | |
132 pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift; | |
133 } | |
134 pp->bBitstreamConcealmentNeed = 0; | |
135 pp->bBitstreamConcealmentMethod = 0; | |
136 } | |
137 | |
138 static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice, | |
139 unsigned position, unsigned size) | |
140 { | |
141 const VC1Context *v = avctx->priv_data; | |
142 const MpegEncContext *s = &v->s; | |
143 | |
144 memset(slice, 0, sizeof(*slice)); | |
145 slice->wHorizontalPosition = 0; | |
146 slice->wVerticalPosition = s->mb_y; | |
147 slice->dwSliceBitsInBuffer = 8 * size; | |
148 slice->dwSliceDataLocation = position; | |
149 slice->bStartCodeBitOffset = 0; | |
150 slice->bReservedBits = 0; | |
151 slice->wMBbitOffset = get_bits_count(&s->gb); | |
152 slice->wNumberMBsInSlice = s->mb_width * s->mb_height; /* XXX We assume 1 slice */ | |
153 slice->wQuantizerScaleCode = v->pq; | |
154 slice->wBadSliceChopping = 0; | |
155 } | |
156 | |
157 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |
158 DXVA2_DecodeBufferDesc *bs, | |
159 DXVA2_DecodeBufferDesc *sc) | |
160 { | |
161 const VC1Context *v = avctx->priv_data; | |
162 struct dxva_context *ctx = avctx->hwaccel_context; | |
163 const MpegEncContext *s = &v->s; | |
164 struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private; | |
165 | |
166 DXVA_SliceInfo *slice = &ctx_pic->si; | |
167 | |
168 static const uint8_t start_code[] = { 0, 0, 1, 0x0d }; | |
169 const unsigned start_code_size = avctx->codec_id == CODEC_ID_VC1 ? sizeof(start_code) : 0; | |
170 const unsigned slice_size = slice->dwSliceBitsInBuffer / 8; | |
171 const unsigned padding = 128 - ((start_code_size + slice_size) & 127); | |
172 const unsigned data_size = start_code_size + slice_size + padding; | |
173 | |
174 uint8_t *dxva_data; | |
175 unsigned dxva_size; | |
176 int result; | |
177 | |
178 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, | |
179 DXVA2_BitStreamDateBufferType, | |
180 &dxva_data, &dxva_size))) | |
181 return -1; | |
182 | |
183 result = data_size <= dxva_size ? 0 : -1; | |
184 if (!result) { | |
185 if (start_code_size > 0) | |
186 memcpy(dxva_data, start_code, start_code_size); | |
187 memcpy(dxva_data + start_code_size, | |
188 ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size); | |
189 if (padding > 0) | |
190 memset(dxva_data + start_code_size + slice_size, 0, padding); | |
191 slice->dwSliceBitsInBuffer = 8 * data_size; | |
192 } | |
193 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, | |
194 DXVA2_BitStreamDateBufferType))) | |
195 return -1; | |
196 if (result) | |
197 return result; | |
198 | |
199 memset(bs, 0, sizeof(*bs)); | |
200 bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; | |
201 bs->DataSize = data_size; | |
202 bs->NumMBsInBuffer = s->mb_width * s->mb_height; | |
203 assert((bs->DataSize & 127) == 0); | |
204 | |
205 return ff_dxva2_commit_buffer(avctx, ctx, sc, | |
206 DXVA2_SliceControlBufferType, | |
207 slice, sizeof(*slice), bs->NumMBsInBuffer); | |
208 } | |
209 | |
210 static int start_frame(AVCodecContext *avctx, | |
211 av_unused const uint8_t *buffer, | |
212 av_unused uint32_t size) | |
213 { | |
214 const VC1Context *v = avctx->priv_data; | |
215 struct dxva_context *ctx = avctx->hwaccel_context; | |
216 struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private; | |
217 | |
218 if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0) | |
219 return -1; | |
220 assert(ctx_pic); | |
221 | |
222 fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp); | |
223 | |
224 ctx_pic->bitstream_size = 0; | |
225 ctx_pic->bitstream = NULL; | |
226 return 0; | |
227 } | |
228 | |
229 static int decode_slice(AVCodecContext *avctx, | |
230 const uint8_t *buffer, uint32_t size) | |
231 { | |
232 const VC1Context *v = avctx->priv_data; | |
233 const Picture *current_picture = v->s.current_picture_ptr; | |
234 struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; | |
235 | |
236 if (ctx_pic->bitstream_size > 0) | |
237 return -1; | |
238 | |
239 if (avctx->codec_id == CODEC_ID_VC1 && | |
240 size >= 4 && IS_MARKER(AV_RB32(buffer))) { | |
241 buffer += 4; | |
242 size -= 4; | |
243 } | |
244 | |
245 ctx_pic->bitstream_size = size; | |
246 ctx_pic->bitstream = buffer; | |
247 | |
248 fill_slice(avctx, &ctx_pic->si, 0, size); | |
249 return 0; | |
250 } | |
251 | |
252 static int end_frame(AVCodecContext *avctx) | |
253 { | |
254 VC1Context *v = avctx->priv_data; | |
255 struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private; | |
256 | |
257 if (ctx_pic->bitstream_size <= 0) | |
258 return -1; | |
259 | |
260 return ff_dxva2_common_end_frame(avctx, &v->s, | |
261 &ctx_pic->pp, sizeof(ctx_pic->pp), | |
262 NULL, 0, | |
263 commit_bitstream_and_slice_buffer); | |
264 } | |
265 | |
266 #if CONFIG_WMV3_DXVA2_HWACCEL | |
267 AVHWAccel wmv3_dxva2_hwaccel = { | |
268 .name = "wmv3_dxva2", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10990
diff
changeset
|
269 .type = AVMEDIA_TYPE_VIDEO, |
10990 | 270 .id = CODEC_ID_WMV3, |
271 .pix_fmt = PIX_FMT_DXVA2_VLD, | |
272 .capabilities = 0, | |
273 .start_frame = start_frame, | |
274 .decode_slice = decode_slice, | |
275 .end_frame = end_frame, | |
276 .priv_data_size = sizeof(struct dxva2_picture_context), | |
277 }; | |
278 #endif | |
279 | |
280 AVHWAccel vc1_dxva2_hwaccel = { | |
281 .name = "vc1_dxva2", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10990
diff
changeset
|
282 .type = AVMEDIA_TYPE_VIDEO, |
10990 | 283 .id = CODEC_ID_VC1, |
284 .pix_fmt = PIX_FMT_DXVA2_VLD, | |
285 .capabilities = 0, | |
286 .start_frame = start_frame, | |
287 .decode_slice = decode_slice, | |
288 .end_frame = end_frame, | |
289 .priv_data_size = sizeof(struct dxva2_picture_context), | |
290 }; | |
291 |