dxva2_vc1.c
Go to the documentation of this file.
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 
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 != AV_PICTURE_TYPE_I && !v->bi_type)
46  pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->last_picture);
47  else
48  pp->wForwardRefPictureIndex = 0xffff;
49  if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_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;
68  pp->bPicStructure |= 0x01;
70  pp->bPicStructure |= 0x02;
71  pp->bSecondField = v->interlace && v->fcm == ILACE_FIELD && v->second_field;
72  pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type;
73  pp->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_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 == PROGRESSIVE) ? 1 : 2;
104  pp->bPicDeblocked = ((!pp->bPicBackwardPrediction && v->overlap) << 6) |
105  ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) |
106  (s->loop_filter << 1);
107  pp->bPicDeblockConfined = (v->postprocflag << 7) |
108  (v->broadcast << 6) |
109  (v->interlace << 5) |
110  (v->tfcntrflag << 4) |
111  (v->finterpflag << 3) |
112  ((s->pict_type != AV_PICTURE_TYPE_B) << 2) |
113  (v->psf << 1) |
114  (v->extended_dmv );
115  if (s->pict_type != AV_PICTURE_TYPE_I)
116  pp->bPic4MVallowed = v->mv_mode == MV_PMODE_MIXED_MV ||
119  if (v->profile == PROFILE_ADVANCED)
120  pp->bPicOBMC = (v->range_mapy_flag << 7) |
121  (v->range_mapy << 4) |
122  (v->range_mapuv_flag << 3) |
123  (v->range_mapuv );
124  pp->bPicBinPB = 0;
125  pp->bMV_RPS = 0;
126  pp->bReservedBits = 0;
127  if (s->picture_structure == PICT_FRAME) {
128  pp->wBitstreamFcodes = v->lumscale;
129  pp->wBitstreamPCEelements = v->lumshift;
130  } else {
131  /* Syntax: (top_field_param << 8) | bottom_field_param */
132  pp->wBitstreamFcodes = (v->lumscale << 8) | v->lumscale;
133  pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift;
134  }
135  pp->bBitstreamConcealmentNeed = 0;
136  pp->bBitstreamConcealmentMethod = 0;
137 }
138 
139 static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
140  unsigned position, unsigned size)
141 {
142  const VC1Context *v = avctx->priv_data;
143  const MpegEncContext *s = &v->s;
144 
145  memset(slice, 0, sizeof(*slice));
146  slice->wHorizontalPosition = 0;
147  slice->wVerticalPosition = s->mb_y;
148  slice->dwSliceBitsInBuffer = 8 * size;
149  slice->dwSliceDataLocation = position;
150  slice->bStartCodeBitOffset = 0;
151  slice->bReservedBits = 0;
152  slice->wMBbitOffset = get_bits_count(&s->gb);
153  slice->wNumberMBsInSlice = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
154  slice->wQuantizerScaleCode = v->pq;
155  slice->wBadSliceChopping = 0;
156 }
157 
159  DXVA2_DecodeBufferDesc *bs,
160  DXVA2_DecodeBufferDesc *sc)
161 {
162  const VC1Context *v = avctx->priv_data;
163  struct dxva_context *ctx = avctx->hwaccel_context;
164  const MpegEncContext *s = &v->s;
166 
167  DXVA_SliceInfo *slice = &ctx_pic->si;
168 
169  static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
170  const unsigned start_code_size = avctx->codec_id == AV_CODEC_ID_VC1 ? sizeof(start_code) : 0;
171  const unsigned slice_size = slice->dwSliceBitsInBuffer / 8;
172  const unsigned padding = 128 - ((start_code_size + slice_size) & 127);
173  const unsigned data_size = start_code_size + slice_size + padding;
174 
175  uint8_t *dxva_data;
176  unsigned dxva_size;
177  int result;
178 
179  if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
180  DXVA2_BitStreamDateBufferType,
181  (void **)&dxva_data, &dxva_size)))
182  return -1;
183 
184  result = data_size <= dxva_size ? 0 : -1;
185  if (!result) {
186  if (start_code_size > 0) {
187  memcpy(dxva_data, start_code, start_code_size);
188  if (v->second_field)
189  dxva_data[3] = 0x0c;
190  }
191  memcpy(dxva_data + start_code_size,
192  ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size);
193  if (padding > 0)
194  memset(dxva_data + start_code_size + slice_size, 0, padding);
195  slice->dwSliceBitsInBuffer = 8 * data_size;
196  }
197  if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
198  DXVA2_BitStreamDateBufferType)))
199  return -1;
200  if (result)
201  return result;
202 
203  memset(bs, 0, sizeof(*bs));
204  bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
205  bs->DataSize = data_size;
206  bs->NumMBsInBuffer = s->mb_width * s->mb_height;
207  assert((bs->DataSize & 127) == 0);
208 
209  return ff_dxva2_commit_buffer(avctx, ctx, sc,
210  DXVA2_SliceControlBufferType,
211  slice, sizeof(*slice), bs->NumMBsInBuffer);
212 }
213 
215  av_unused const uint8_t *buffer,
216  av_unused uint32_t size)
217 {
218  const VC1Context *v = avctx->priv_data;
219  struct dxva_context *ctx = avctx->hwaccel_context;
221 
222  if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
223  return -1;
224  assert(ctx_pic);
225 
226  fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp);
227 
228  ctx_pic->bitstream_size = 0;
229  ctx_pic->bitstream = NULL;
230  return 0;
231 }
232 
234  const uint8_t *buffer,
235  uint32_t size)
236 {
237  const VC1Context *v = avctx->priv_data;
238  const Picture *current_picture = v->s.current_picture_ptr;
239  struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
240 
241  if (ctx_pic->bitstream_size > 0)
242  return -1;
243 
244  if (avctx->codec_id == AV_CODEC_ID_VC1 &&
245  size >= 4 && IS_MARKER(AV_RB32(buffer))) {
246  buffer += 4;
247  size -= 4;
248  }
249 
250  ctx_pic->bitstream_size = size;
251  ctx_pic->bitstream = buffer;
252 
253  fill_slice(avctx, &ctx_pic->si, 0, size);
254  return 0;
255 }
256 
258 {
259  VC1Context *v = avctx->priv_data;
261  int ret;
262 
263  if (ctx_pic->bitstream_size <= 0)
264  return -1;
265 
267  &ctx_pic->pp, sizeof(ctx_pic->pp),
268  NULL, 0,
270  if (!ret)
271  ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
272  return ret;
273 }
274 
275 #if CONFIG_WMV3_DXVA2_HWACCEL
276 AVHWAccel ff_wmv3_dxva2_hwaccel = {
277  .name = "wmv3_dxva2",
278  .type = AVMEDIA_TYPE_VIDEO,
279  .id = AV_CODEC_ID_WMV3,
280  .pix_fmt = AV_PIX_FMT_DXVA2_VLD,
281  .start_frame = dxva2_vc1_start_frame,
282  .decode_slice = dxva2_vc1_decode_slice,
283  .end_frame = dxva2_vc1_end_frame,
284  .priv_data_size = sizeof(struct dxva2_picture_context),
285 };
286 #endif
287 
289  .name = "vc1_dxva2",
290  .type = AVMEDIA_TYPE_VIDEO,
291  .id = AV_CODEC_ID_VC1,
292  .pix_fmt = AV_PIX_FMT_DXVA2_VLD,
293  .start_frame = dxva2_vc1_start_frame,
294  .decode_slice = dxva2_vc1_decode_slice,
295  .end_frame = dxva2_vc1_end_frame,
296  .priv_data_size = sizeof(struct dxva2_picture_context),
297 };
#define PICT_BOTTOM_FIELD
Definition: mpegvideo.h:663
in the bitstream is reported as 00b
Definition: vc1.h:173
#define PICT_TOP_FIELD
Definition: mpegvideo.h:662
float v
const char * s
Definition: avisynth_c.h:668
The VC1 Context.
Definition: vc1.h:182
DXVA_SliceInfo si
Definition: dxva2_vc1.c:29
int extended_mv
Ext MV in P/B (not in Simple)
Definition: vc1.h:229
int broadcast
TFF/RFF present.
Definition: vc1.h:209
uint8_t rangeredfrm
Frame decoding info for S/M profiles only.
Definition: vc1.h:305
DXVA_PicParams_H264 pp
Definition: dxva2_h264.c:28
int fastuvmc
Rounding of qpel vector to hpel ? (not in Simple)
Definition: vc1.h:228
const DXVA2_ConfigPictureDecode * cfg
DXVA2 configuration used to create the decoder.
Definition: dxva2.h:68
unsigned surface_count
The number of surface in the surface array.
Definition: dxva2.h:73
DXVA_SliceInfo slice[MAX_SLICES]
Definition: dxva2_mpeg2.c:30
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo.c:2996
VC-1 tables.
int bi_type
Definition: vc1.h:386
uint8_t
void * hwaccel_context
Hardware accelerator context.
#define PICT_FRAME
Definition: mpegvideo.h:664
int panscanflag
NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present.
Definition: vc1.h:212
#define AV_RB32
int interlace
Progressive/interlaced (RPTFTM syntax element)
Definition: vc1.h:210
int second_field
Definition: vc1.h:359
int resync_marker
could this stream contain resync markers
Definition: mpegvideo.h:591
int profile
Sequence header data for all Profiles TODO: choose between ints, uint8_ts and monobit flags...
Definition: vc1.h:224
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:193
int refdist_flag
REFDIST syntax element present in II, IP, PI or PP field picture headers.
Definition: vc1.h:213
int mb_height
number of MBs horizontally & vertically
Definition: mpegvideo.h:277
static int dxva2_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: dxva2_vc1.c:233
int psf
Progressive Segmented Frame.
Definition: vc1.h:217
int overlap
overlapped transforms in use
Definition: vc1.h:232
in the bitstream is reported as 11b
Definition: vc1.h:175
#define IS_MARKER(state, i, buf, buf_size)
Definition: dca_parser.c:37
int quarter_sample
1->qpel, 0->half pel ME/MC
Definition: mpegvideo.h:579
GetBitContext gb
Definition: mpegvideo.h:649
int postprocflag
Per-frame processing suggestion flag present.
Definition: vc1.h:208
int size
int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic, const void *pp, unsigned pp_size, const void *qm, unsigned qm_size, int(*commit_bs_si)(AVCodecContext *, DXVA2_DecodeBufferDesc *bs, DXVA2_DecodeBufferDesc *slice))
Definition: dxva2.c:79
const char * name
Name of the hardware accelerated codec.
int tfcntrflag
TFCNTR present.
Definition: vc1.h:211
ret
Definition: avfilter.c:821
int width
picture width / height.
uint8_t mv_mode
Frame decoding info for all profiles.
Definition: vc1.h:239
Picture * current_picture_ptr
pointer to the current picture
Definition: mpegvideo.h:347
Picture.
Definition: mpegvideo.h:97
void * hwaccel_picture_private
hardware accelerator private data
Definition: mpegvideo.h:132
int ff_dxva2_commit_buffer(AVCodecContext *avctx, struct dxva_context *ctx, DXVA2_DecodeBufferDesc *dsc, unsigned type, const void *data, unsigned size, unsigned mb_count)
Definition: dxva2.c:44
uint8_t lumscale
Luma compensation parameters.
Definition: vc1.h:275
uint8_t range_mapuv_flag
Definition: vc1.h:332
unsigned bitstream_size
Definition: dxva2_h264.c:34
static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice, unsigned position, unsigned size)
Definition: dxva2_vc1.c:139
unsigned report_id
Private to the FFmpeg AVHWAccel implementation.
Definition: dxva2.h:88
int rangered
RANGEREDFRM (range reduction) syntax element present at frame level.
Definition: vc1.h:198
int finterpflag
INTERPFRM present.
Definition: vc1.h:234
NULL
Definition: eval.c:55
unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx, const Picture *picture)
Definition: dxva2.c:30
int chromaformat
2bits, 2=4:2:0, only defined
Definition: vc1.h:207
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, DXVA2_DecodeBufferDesc *bs, DXVA2_DecodeBufferDesc *sc)
Definition: dxva2_vc1.c:158
enum AVCodecID codec_id
AVHWAccel.
int multires
frame-level RESPIC syntax element present
Definition: vc1.h:195
main external API structure.
uint8_t range_mapy
Definition: vc1.h:333
int extended_dmv
Additional extended dmv range at P/B frame-level.
Definition: vc1.h:214
int quantizer_mode
2bits, quantizer mode used for sequence, see QUANT_*
Definition: vc1.h:233
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer. ...
Definition: pixfmt.h:135
int max_b_frames
max number of b-frames for encoding
Definition: mpegvideo.h:262
int pict_type
AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
Definition: mpegvideo.h:377
int vstransform
variable-size [48]x[48] transform type + info
Definition: vc1.h:231
uint8_t range_mapuv
Definition: vc1.h:334
#define FAILED(hr)
Definition: windows2linux.h:48
MpegEncContext s
Definition: vc1.h:183
MpegEncContext.
Definition: mpegvideo.h:241
static int dxva2_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: dxva2_vc1.c:214
const uint8_t * bitstream
Definition: dxva2_h264.c:33
uint8_t pq
Definition: vc1.h:244
enum FrameCodingMode fcm
Frame decoding info for Advanced profile.
Definition: vc1.h:311
Picture last_picture
copy of the previous picture structure.
Definition: mpegvideo.h:325
uint8_t lumshift
Definition: vc1.h:276
Bi-dir predicted.
Definition: avutil.h:218
the buffer and buffer reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFilterBuffer structures They must not be accessed but through references stored in AVFilterBufferRef structures Several references can point to the same buffer
int picture_structure
Definition: mpegvideo.h:660
int rnd
rounding control
Definition: vc1.h:301
static int dxva2_vc1_end_frame(AVCodecContext *avctx)
Definition: dxva2_vc1.c:257
Picture next_picture
copy of the next picture structure.
Definition: mpegvideo.h:331
uint8_t range_mapy_flag
Definition: vc1.h:331
AVHWAccel ff_vc1_dxva2_hwaccel
Definition: dxva2_vc1.c:288
int dquant
How qscale varies with MBs, 2bits (not in Simple)
Definition: vc1.h:230
uint8_t mv_mode2
Secondary MV coding mode (B frames)
Definition: vc1.h:240
IDirectXVideoDecoder * decoder
DXVA2 decoder object.
Definition: dxva2.h:63
static void fill_picture_parameters(AVCodecContext *avctx, struct dxva_context *ctx, const VC1Context *v, DXVA_PictureParameters *pp)
Definition: dxva2_vc1.c:35
#define av_unused
Definition: attributes.h:114
This structure is used to provides the necessary configurations and data to the DXVA2 FFmpeg HWAccel ...
Definition: dxva2.h:59