]> git.sesse.net Git - ffmpeg/blob - libavcodec/dxva2_vc1.c
avformat/avio: Add Metacube support
[ffmpeg] / libavcodec / dxva2_vc1.c
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 "mpegutils.h"
25 #include "vc1.h"
26 #include "vc1data.h"
27
28 #define MAX_SLICES 1024
29
30 struct dxva2_picture_context {
31     DXVA_PictureParameters pp;
32     unsigned               slice_count;
33     DXVA_SliceInfo         slice[MAX_SLICES];
34
35     const uint8_t          *bitstream;
36     unsigned               bitstream_size;
37 };
38
39 static void fill_picture_parameters(AVCodecContext *avctx,
40                                     AVDXVAContext *ctx, const VC1Context *v,
41                                     DXVA_PictureParameters *pp)
42 {
43     const MpegEncContext *s = &v->s;
44     const Picture *current_picture = s->current_picture_ptr;
45     int intcomp = 0;
46
47     // determine if intensity compensation is needed
48     if (s->pict_type == AV_PICTURE_TYPE_P) {
49       if ((v->fcm == ILACE_FRAME && v->intcomp) || (v->fcm != ILACE_FRAME && v->mv_mode == MV_PMODE_INTENSITY_COMP)) {
50         if (v->lumscale != 32 || v->lumshift != 0 || (s->picture_structure != PICT_FRAME && (v->lumscale2 != 32 || v->lumshift2 != 0)))
51           intcomp = 1;
52       }
53     }
54
55     memset(pp, 0, sizeof(*pp));
56     pp->wDecodedPictureIndex    =
57     pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f);
58     if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
59         pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->last_picture.f);
60     else
61         pp->wForwardRefPictureIndex = 0xffff;
62     if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
63         pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_picture.f);
64     else
65         pp->wBackwardRefPictureIndex = 0xffff;
66     if (v->profile == PROFILE_ADVANCED) {
67         /* It is the cropped width/height -1 of the frame */
68         pp->wPicWidthInMBminus1 = avctx->width  - 1;
69         pp->wPicHeightInMBminus1= avctx->height - 1;
70     } else {
71         /* It is the coded width/height in macroblock -1 of the frame */
72         pp->wPicWidthInMBminus1 = s->mb_width  - 1;
73         pp->wPicHeightInMBminus1= s->mb_height - 1;
74     }
75     pp->bMacroblockWidthMinus1  = 15;
76     pp->bMacroblockHeightMinus1 = 15;
77     pp->bBlockWidthMinus1       = 7;
78     pp->bBlockHeightMinus1      = 7;
79     pp->bBPPminus1              = 7;
80     if (s->picture_structure & PICT_TOP_FIELD)
81         pp->bPicStructure      |= 0x01;
82     if (s->picture_structure & PICT_BOTTOM_FIELD)
83         pp->bPicStructure      |= 0x02;
84     pp->bSecondField            = v->interlace && v->fcm == ILACE_FIELD && v->second_field;
85     pp->bPicIntra               = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type;
86     pp->bPicBackwardPrediction  = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type;
87     pp->bBidirectionalAveragingMode = (1                                           << 7) |
88                                       ((DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) != 0) << 6) |
89                                       ((DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) != 0) << 5) |
90                                       (intcomp                                     << 4) |
91                                       ((v->profile == PROFILE_ADVANCED)            << 3);
92     pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
93                                         (1                                       << 2) |
94                                         (0                                       << 1) |
95                                         (!s->quarter_sample                          );
96     pp->bChromaFormat           = v->chromaformat;
97     DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
98     if (DXVA_CONTEXT_REPORT_ID(avctx, ctx) >= (1 << 16))
99         DXVA_CONTEXT_REPORT_ID(avctx, ctx) = 1;
100     pp->bPicScanFixed           = DXVA_CONTEXT_REPORT_ID(avctx, ctx) >> 8;
101     pp->bPicScanMethod          = DXVA_CONTEXT_REPORT_ID(avctx, ctx) & 0xff;
102     pp->bPicReadbackRequests    = 0;
103     pp->bRcontrol               = v->rnd;
104     pp->bPicSpatialResid8       = (v->panscanflag  << 7) |
105                                   (v->refdist_flag << 6) |
106                                   (s->loop_filter  << 5) |
107                                   (v->fastuvmc     << 4) |
108                                   (v->extended_mv  << 3) |
109                                   (v->dquant       << 1) |
110                                   (v->vstransform      );
111     pp->bPicOverflowBlocks      = (v->quantizer_mode << 6) |
112                                   (v->multires       << 5) |
113                                   (v->resync_marker  << 4) |
114                                   (v->rangered       << 3) |
115                                   (s->max_b_frames       );
116     pp->bPicExtrapolation       = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 : 2;
117     pp->bPicDeblocked           = ((!pp->bPicBackwardPrediction && v->overlap)        << 6) |
118                                   ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) |
119                                   (s->loop_filter                                     << 1);
120     pp->bPicDeblockConfined     = (v->postprocflag             << 7) |
121                                   (v->broadcast                << 6) |
122                                   (v->interlace                << 5) |
123                                   (v->tfcntrflag               << 4) |
124                                   (v->finterpflag              << 3) |
125                                   ((s->pict_type != AV_PICTURE_TYPE_B) << 2) |
126                                   (v->psf                      << 1) |
127                                   (v->extended_dmv                 );
128     if (s->pict_type != AV_PICTURE_TYPE_I)
129         pp->bPic4MVallowed      = v->mv_mode == MV_PMODE_MIXED_MV ||
130                                   (v->mv_mode == MV_PMODE_INTENSITY_COMP &&
131                                    v->mv_mode2 == MV_PMODE_MIXED_MV);
132     if (v->profile == PROFILE_ADVANCED)
133         pp->bPicOBMC            = (v->range_mapy_flag  << 7) |
134                                   (v->range_mapy       << 4) |
135                                   (v->range_mapuv_flag << 3) |
136                                   (v->range_mapuv          );
137     pp->bPicBinPB               = 0;
138     pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
139     pp->bReservedBits           = v->pq;
140     if (s->picture_structure == PICT_FRAME) {
141         if (intcomp) {
142             pp->wBitstreamFcodes      = v->lumscale;
143             pp->wBitstreamPCEelements = v->lumshift;
144         } else {
145             pp->wBitstreamFcodes      = 32;
146             pp->wBitstreamPCEelements = 0;
147         }
148     } else {
149         /* Syntax: (top_field_param << 8) | bottom_field_param */
150         if (intcomp) {
151             pp->wBitstreamFcodes      = (v->lumscale << 8) | v->lumscale2;
152             pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift2;
153         } else {
154             pp->wBitstreamFcodes      = (32 << 8) | 32;
155             pp->wBitstreamPCEelements = 0;
156         }
157     }
158     pp->bBitstreamConcealmentNeed   = 0;
159     pp->bBitstreamConcealmentMethod = 0;
160 }
161
162 static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
163                        unsigned position, unsigned size)
164 {
165     const VC1Context *v = avctx->priv_data;
166     const MpegEncContext *s = &v->s;
167
168     memset(slice, 0, sizeof(*slice));
169     slice->wHorizontalPosition = 0;
170     slice->wVerticalPosition   = s->mb_y;
171     slice->dwSliceBitsInBuffer = 8 * size;
172     slice->dwSliceDataLocation = position;
173     slice->bStartCodeBitOffset = 0;
174     slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
175     slice->wMBbitOffset        = v->p_frame_skipped ? 0xffff : get_bits_count(&s->gb) + (avctx->codec_id == AV_CODEC_ID_VC1 ? 32 : 0);
176     /* XXX We store the index of the first MB and it will be fixed later */
177     slice->wNumberMBsInSlice   = (s->mb_y >> v->field_mode) * s->mb_width + s->mb_x;
178     slice->wQuantizerScaleCode = v->pq;
179     slice->wBadSliceChopping   = 0;
180 }
181
182 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
183                                              DECODER_BUFFER_DESC *bs,
184                                              DECODER_BUFFER_DESC *sc)
185 {
186     const VC1Context *v = avctx->priv_data;
187     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
188     const MpegEncContext *s = &v->s;
189     struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private;
190
191     static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
192     const unsigned start_code_size = avctx->codec_id == AV_CODEC_ID_VC1 ? sizeof(start_code) : 0;
193     const unsigned mb_count = s->mb_width * (s->mb_height >> v->field_mode);
194     DXVA_SliceInfo *slice = NULL;
195     void     *dxva_data_ptr;
196     uint8_t  *dxva_data, *current, *end;
197     unsigned dxva_size;
198     unsigned padding;
199     unsigned i;
200     unsigned type;
201
202 #if CONFIG_D3D11VA
203     if (ff_dxva2_is_d3d11(avctx)) {
204         type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
205         if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
206                                                        D3D11VA_CONTEXT(ctx)->decoder,
207                                                        type,
208                                                        &dxva_size, &dxva_data_ptr)))
209             return -1;
210     }
211 #endif
212 #if CONFIG_DXVA2
213     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
214         type = DXVA2_BitStreamDateBufferType;
215         if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
216                                                   type,
217                                                   &dxva_data_ptr, &dxva_size)))
218             return -1;
219     }
220 #endif
221
222     dxva_data = dxva_data_ptr;
223     current = dxva_data;
224     end = dxva_data + dxva_size;
225
226     for (i = 0; i < ctx_pic->slice_count; i++) {
227         unsigned position, size;
228         slice    = &ctx_pic->slice[i];
229         position = slice->dwSliceDataLocation;
230         size     = slice->dwSliceBitsInBuffer / 8;
231         if (start_code_size + size > end - current) {
232             av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
233             break;
234         }
235         slice->dwSliceDataLocation = current - dxva_data;
236
237         if (i < ctx_pic->slice_count - 1)
238             slice->wNumberMBsInSlice =
239                 slice[1].wNumberMBsInSlice - slice[0].wNumberMBsInSlice;
240         else
241             slice->wNumberMBsInSlice =
242                 mb_count - slice[0].wNumberMBsInSlice;
243
244         /* write the appropriate frame, field or slice start code */
245         if (start_code_size) {
246             memcpy(current, start_code, start_code_size);
247             if (i == 0 && v->second_field)
248                 current[3] = 0x0c;
249             else if (i > 0)
250                 current[3] = 0x0b;
251
252             current += start_code_size;
253             slice->dwSliceBitsInBuffer += start_code_size * 8;
254         }
255
256         memcpy(current, &ctx_pic->bitstream[position], size);
257         current += size;
258     }
259     padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
260     if (slice && padding > 0) {
261         memset(current, 0, padding);
262         current += padding;
263         slice->dwSliceBitsInBuffer += padding * 8;
264     }
265
266 #if CONFIG_D3D11VA
267     if (ff_dxva2_is_d3d11(avctx))
268         if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
269             return -1;
270 #endif
271 #if CONFIG_DXVA2
272     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
273         if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
274             return -1;
275 #endif
276     if (i < ctx_pic->slice_count)
277         return -1;
278
279 #if CONFIG_D3D11VA
280     if (ff_dxva2_is_d3d11(avctx)) {
281         D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
282         memset(dsc11, 0, sizeof(*dsc11));
283         dsc11->BufferType           = type;
284         dsc11->DataSize             = current - dxva_data;
285         dsc11->NumMBsInBuffer       = mb_count;
286
287         type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
288     }
289 #endif
290 #if CONFIG_DXVA2
291     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
292         DXVA2_DecodeBufferDesc *dsc2 = bs;
293         memset(dsc2, 0, sizeof(*dsc2));
294         dsc2->CompressedBufferType = type;
295         dsc2->DataSize             = current - dxva_data;
296         dsc2->NumMBsInBuffer       = mb_count;
297
298         type = DXVA2_SliceControlBufferType;
299     }
300 #endif
301
302     return ff_dxva2_commit_buffer(avctx, ctx, sc,
303                                   type,
304                                   ctx_pic->slice,
305                                   ctx_pic->slice_count * sizeof(*ctx_pic->slice),
306                                   mb_count);
307 }
308
309 static int dxva2_vc1_start_frame(AVCodecContext *avctx,
310                                  av_unused const uint8_t *buffer,
311                                  av_unused uint32_t size)
312 {
313     const VC1Context *v = avctx->priv_data;
314     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
315     struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
316
317     if (!DXVA_CONTEXT_VALID(avctx, ctx))
318         return -1;
319     assert(ctx_pic);
320
321     fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp);
322
323     ctx_pic->slice_count    = 0;
324     ctx_pic->bitstream_size = 0;
325     ctx_pic->bitstream      = NULL;
326     return 0;
327 }
328
329 static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
330                                   const uint8_t *buffer,
331                                   uint32_t size)
332 {
333     const VC1Context *v = avctx->priv_data;
334     const Picture *current_picture = v->s.current_picture_ptr;
335     struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
336     unsigned position;
337
338     if (ctx_pic->slice_count >= MAX_SLICES) {
339         avpriv_request_sample(avctx, "%d slices in dxva2",
340                               ctx_pic->slice_count);
341         return -1;
342     }
343
344     if (avctx->codec_id == AV_CODEC_ID_VC1 &&
345         size >= 4 && IS_MARKER(AV_RB32(buffer))) {
346         buffer += 4;
347         size   -= 4;
348     }
349
350     if (!ctx_pic->bitstream)
351         ctx_pic->bitstream = buffer;
352     ctx_pic->bitstream_size += size;
353
354     position = buffer - ctx_pic->bitstream;
355     fill_slice(avctx, &ctx_pic->slice[ctx_pic->slice_count++], position, size);
356     return 0;
357 }
358
359 static int dxva2_vc1_end_frame(AVCodecContext *avctx)
360 {
361     VC1Context *v = avctx->priv_data;
362     struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
363     int ret;
364
365     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
366         return -1;
367
368     ret = ff_dxva2_common_end_frame(avctx, v->s.current_picture_ptr->f,
369                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
370                                     NULL, 0,
371                                     commit_bitstream_and_slice_buffer);
372     if (!ret)
373         ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
374     return ret;
375 }
376
377 #if CONFIG_WMV3_DXVA2_HWACCEL
378 const AVHWAccel ff_wmv3_dxva2_hwaccel = {
379     .name           = "wmv3_dxva2",
380     .type           = AVMEDIA_TYPE_VIDEO,
381     .id             = AV_CODEC_ID_WMV3,
382     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
383     .init           = ff_dxva2_decode_init,
384     .uninit         = ff_dxva2_decode_uninit,
385     .start_frame    = dxva2_vc1_start_frame,
386     .decode_slice   = dxva2_vc1_decode_slice,
387     .end_frame      = dxva2_vc1_end_frame,
388     .frame_params   = ff_dxva2_common_frame_params,
389     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
390     .priv_data_size = sizeof(FFDXVASharedContext),
391 };
392 #endif
393
394 #if CONFIG_VC1_DXVA2_HWACCEL
395 const AVHWAccel ff_vc1_dxva2_hwaccel = {
396     .name           = "vc1_dxva2",
397     .type           = AVMEDIA_TYPE_VIDEO,
398     .id             = AV_CODEC_ID_VC1,
399     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
400     .init           = ff_dxva2_decode_init,
401     .uninit         = ff_dxva2_decode_uninit,
402     .start_frame    = dxva2_vc1_start_frame,
403     .decode_slice   = dxva2_vc1_decode_slice,
404     .end_frame      = dxva2_vc1_end_frame,
405     .frame_params   = ff_dxva2_common_frame_params,
406     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
407     .priv_data_size = sizeof(FFDXVASharedContext),
408 };
409 #endif
410
411 #if CONFIG_WMV3_D3D11VA_HWACCEL
412 const AVHWAccel ff_wmv3_d3d11va_hwaccel = {
413     .name           = "wmv3_d3d11va",
414     .type           = AVMEDIA_TYPE_VIDEO,
415     .id             = AV_CODEC_ID_WMV3,
416     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
417     .init           = ff_dxva2_decode_init,
418     .uninit         = ff_dxva2_decode_uninit,
419     .start_frame    = dxva2_vc1_start_frame,
420     .decode_slice   = dxva2_vc1_decode_slice,
421     .end_frame      = dxva2_vc1_end_frame,
422     .frame_params   = ff_dxva2_common_frame_params,
423     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
424     .priv_data_size = sizeof(FFDXVASharedContext),
425 };
426 #endif
427
428 #if CONFIG_WMV3_D3D11VA2_HWACCEL
429 const AVHWAccel ff_wmv3_d3d11va2_hwaccel = {
430     .name           = "wmv3_d3d11va2",
431     .type           = AVMEDIA_TYPE_VIDEO,
432     .id             = AV_CODEC_ID_WMV3,
433     .pix_fmt        = AV_PIX_FMT_D3D11,
434     .init           = ff_dxva2_decode_init,
435     .uninit         = ff_dxva2_decode_uninit,
436     .start_frame    = dxva2_vc1_start_frame,
437     .decode_slice   = dxva2_vc1_decode_slice,
438     .end_frame      = dxva2_vc1_end_frame,
439     .frame_params   = ff_dxva2_common_frame_params,
440     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
441     .priv_data_size = sizeof(FFDXVASharedContext),
442 };
443 #endif
444
445 #if CONFIG_VC1_D3D11VA_HWACCEL
446 const AVHWAccel ff_vc1_d3d11va_hwaccel = {
447     .name           = "vc1_d3d11va",
448     .type           = AVMEDIA_TYPE_VIDEO,
449     .id             = AV_CODEC_ID_VC1,
450     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
451     .init           = ff_dxva2_decode_init,
452     .uninit         = ff_dxva2_decode_uninit,
453     .start_frame    = dxva2_vc1_start_frame,
454     .decode_slice   = dxva2_vc1_decode_slice,
455     .end_frame      = dxva2_vc1_end_frame,
456     .frame_params   = ff_dxva2_common_frame_params,
457     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
458     .priv_data_size = sizeof(FFDXVASharedContext),
459 };
460 #endif
461
462 #if CONFIG_VC1_D3D11VA2_HWACCEL
463 const AVHWAccel ff_vc1_d3d11va2_hwaccel = {
464     .name           = "vc1_d3d11va2",
465     .type           = AVMEDIA_TYPE_VIDEO,
466     .id             = AV_CODEC_ID_VC1,
467     .pix_fmt        = AV_PIX_FMT_D3D11,
468     .init           = ff_dxva2_decode_init,
469     .uninit         = ff_dxva2_decode_uninit,
470     .start_frame    = dxva2_vc1_start_frame,
471     .decode_slice   = dxva2_vc1_decode_slice,
472     .end_frame      = dxva2_vc1_end_frame,
473     .frame_params   = ff_dxva2_common_frame_params,
474     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
475     .priv_data_size = sizeof(FFDXVASharedContext),
476 };
477 #endif