FFmpeg  4.0
dxva2_vp9.c
Go to the documentation of this file.
1 /*
2  * DXVA2 VP9 HW acceleration.
3  *
4  * copyright (c) 2015 Hendrik Leppkes
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 "libavutil/avassert.h"
24 #include "libavutil/pixdesc.h"
25 
26 #include "dxva2_internal.h"
27 #include "vp9shared.h"
28 
30  DXVA_PicParams_VP9 pp;
31  DXVA_Slice_VPx_Short slice;
33  unsigned bitstream_size;
34 };
35 
36 static void fill_picture_entry(DXVA_PicEntry_VPx *pic,
37  unsigned index, unsigned flag)
38 {
39  av_assert0((index & 0x7f) == index && (flag & 0x01) == flag);
40  pic->bPicEntry = index | (flag << 7);
41 }
42 
44  DXVA_PicParams_VP9 *pp)
45 {
46  int i;
47  const AVPixFmtDescriptor * pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
48 
49  if (!pixdesc)
50  return -1;
51 
52  memset(pp, 0, sizeof(*pp));
53 
54  fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(avctx, ctx, h->frames[CUR_FRAME].tf.f), 0);
55 
56  pp->profile = h->h.profile;
57  pp->wFormatAndPictureInfoFlags = ((h->h.keyframe == 0) << 0) |
58  ((h->h.invisible == 0) << 1) |
59  (h->h.errorres << 2) |
60  (pixdesc->log2_chroma_w << 3) | /* subsampling_x */
61  (pixdesc->log2_chroma_h << 4) | /* subsampling_y */
62  (0 << 5) | /* extra_plane */
63  (h->h.refreshctx << 6) |
64  (h->h.parallelmode << 7) |
65  (h->h.intraonly << 8) |
66  (h->h.framectxid << 9) |
67  (h->h.resetctx << 11) |
68  ((h->h.keyframe ? 0 : h->h.highprecisionmvs) << 13) |
69  (0 << 14); /* ReservedFormatInfo2Bits */
70 
71  pp->width = avctx->width;
72  pp->height = avctx->height;
73  pp->BitDepthMinus8Luma = pixdesc->comp[0].depth - 8;
74  pp->BitDepthMinus8Chroma = pixdesc->comp[1].depth - 8;
75  /* swap 0/1 to match the reference */
76  pp->interp_filter = h->h.filtermode ^ (h->h.filtermode <= 1);
77  pp->Reserved8Bits = 0;
78 
79  for (i = 0; i < 8; i++) {
80  if (h->refs[i].f->buf[0]) {
81  fill_picture_entry(&pp->ref_frame_map[i], ff_dxva2_get_surface_index(avctx, ctx, h->refs[i].f), 0);
82  pp->ref_frame_coded_width[i] = h->refs[i].f->width;
83  pp->ref_frame_coded_height[i] = h->refs[i].f->height;
84  } else
85  pp->ref_frame_map[i].bPicEntry = 0xFF;
86  }
87 
88  for (i = 0; i < 3; i++) {
89  uint8_t refidx = h->h.refidx[i];
90  if (h->refs[refidx].f->buf[0])
91  fill_picture_entry(&pp->frame_refs[i], ff_dxva2_get_surface_index(avctx, ctx, h->refs[refidx].f), 0);
92  else
93  pp->frame_refs[i].bPicEntry = 0xFF;
94 
95  pp->ref_frame_sign_bias[i + 1] = h->h.signbias[i];
96  }
97 
98  pp->filter_level = h->h.filter.level;
99  pp->sharpness_level = h->h.filter.sharpness;
100 
101  pp->wControlInfoFlags = (h->h.lf_delta.enabled << 0) |
102  (h->h.lf_delta.updated << 1) |
103  (h->h.use_last_frame_mvs << 2) |
104  (0 << 3); /* ReservedControlInfo5Bits */
105 
106  for (i = 0; i < 4; i++)
107  pp->ref_deltas[i] = h->h.lf_delta.ref[i];
108 
109  for (i = 0; i < 2; i++)
110  pp->mode_deltas[i] = h->h.lf_delta.mode[i];
111 
112  pp->base_qindex = h->h.yac_qi;
113  pp->y_dc_delta_q = h->h.ydc_qdelta;
114  pp->uv_dc_delta_q = h->h.uvdc_qdelta;
115  pp->uv_ac_delta_q = h->h.uvac_qdelta;
116 
117  /* segmentation data */
118  pp->stVP9Segments.wSegmentInfoFlags = (h->h.segmentation.enabled << 0) |
119  (h->h.segmentation.update_map << 1) |
120  (h->h.segmentation.temporal << 2) |
121  (h->h.segmentation.absolute_vals << 3) |
122  (0 << 4); /* ReservedSegmentFlags4Bits */
123 
124  for (i = 0; i < 7; i++)
125  pp->stVP9Segments.tree_probs[i] = h->h.segmentation.prob[i];
126 
128  for (i = 0; i < 3; i++)
129  pp->stVP9Segments.pred_probs[i] = h->h.segmentation.pred_prob[i];
130  else
131  memset(pp->stVP9Segments.pred_probs, 255, sizeof(pp->stVP9Segments.pred_probs));
132 
133  for (i = 0; i < 8; i++) {
134  pp->stVP9Segments.feature_mask[i] = (h->h.segmentation.feat[i].q_enabled << 0) |
135  (h->h.segmentation.feat[i].lf_enabled << 1) |
136  (h->h.segmentation.feat[i].ref_enabled << 2) |
137  (h->h.segmentation.feat[i].skip_enabled << 3);
138 
139  pp->stVP9Segments.feature_data[i][0] = h->h.segmentation.feat[i].q_val;
140  pp->stVP9Segments.feature_data[i][1] = h->h.segmentation.feat[i].lf_val;
141  pp->stVP9Segments.feature_data[i][2] = h->h.segmentation.feat[i].ref_val;
142  pp->stVP9Segments.feature_data[i][3] = 0; /* no data for skip */
143  }
144 
145  pp->log2_tile_cols = h->h.tiling.log2_tile_cols;
146  pp->log2_tile_rows = h->h.tiling.log2_tile_rows;
147 
148  pp->uncompressed_header_size_byte_aligned = h->h.uncompressed_header_size;
149  pp->first_partition_size = h->h.compressed_header_size;
150 
151  pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
152  return 0;
153 }
154 
155 static void fill_slice_short(DXVA_Slice_VPx_Short *slice,
156  unsigned position, unsigned size)
157 {
158  memset(slice, 0, sizeof(*slice));
159  slice->BSNALunitDataLocation = position;
160  slice->SliceBytesInBuffer = size;
161  slice->wBadSliceChopping = 0;
162 }
163 
167 {
168  const VP9SharedContext *h = avctx->priv_data;
169  AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
171  void *dxva_data_ptr;
172  uint8_t *dxva_data;
173  unsigned dxva_size;
174  unsigned padding;
175  unsigned type;
176 
177 #if CONFIG_D3D11VA
178  if (ff_dxva2_is_d3d11(avctx)) {
179  type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
180  if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
181  D3D11VA_CONTEXT(ctx)->decoder,
182  type,
183  &dxva_size, &dxva_data_ptr)))
184  return -1;
185  }
186 #endif
187 #if CONFIG_DXVA2
188  if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
189  type = DXVA2_BitStreamDateBufferType;
190  if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
191  type,
192  &dxva_data_ptr, &dxva_size)))
193  return -1;
194  }
195 #endif
196 
197  dxva_data = dxva_data_ptr;
198 
199  if (ctx_pic->slice.SliceBytesInBuffer > dxva_size) {
200  av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
201  return -1;
202  }
203 
204  memcpy(dxva_data, ctx_pic->bitstream, ctx_pic->slice.SliceBytesInBuffer);
205 
206  padding = FFMIN(128 - ((ctx_pic->slice.SliceBytesInBuffer) & 127), dxva_size - ctx_pic->slice.SliceBytesInBuffer);
207  if (padding > 0) {
208  memset(dxva_data + ctx_pic->slice.SliceBytesInBuffer, 0, padding);
209  ctx_pic->slice.SliceBytesInBuffer += padding;
210  }
211 
212 #if CONFIG_D3D11VA
213  if (ff_dxva2_is_d3d11(avctx))
214  if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
215  return -1;
216 #endif
217 #if CONFIG_DXVA2
218  if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
219  if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
220  return -1;
221 #endif
222 
223 #if CONFIG_D3D11VA
224  if (ff_dxva2_is_d3d11(avctx)) {
225  D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
226  memset(dsc11, 0, sizeof(*dsc11));
227  dsc11->BufferType = type;
228  dsc11->DataSize = ctx_pic->slice.SliceBytesInBuffer;
229  dsc11->NumMBsInBuffer = 0;
230 
231  type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
232  }
233 #endif
234 #if CONFIG_DXVA2
235  if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
236  DXVA2_DecodeBufferDesc *dsc2 = bs;
237  memset(dsc2, 0, sizeof(*dsc2));
238  dsc2->CompressedBufferType = type;
239  dsc2->DataSize = ctx_pic->slice.SliceBytesInBuffer;
240  dsc2->NumMBsInBuffer = 0;
241 
242  type = DXVA2_SliceControlBufferType;
243  }
244 #endif
245 
246  return ff_dxva2_commit_buffer(avctx, ctx, sc,
247  type,
248  &ctx_pic->slice, sizeof(ctx_pic->slice), 0);
249 }
250 
251 
253  av_unused const uint8_t *buffer,
254  av_unused uint32_t size)
255 {
256  const VP9SharedContext *h = avctx->priv_data;
257  AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
259 
260  if (!DXVA_CONTEXT_VALID(avctx, ctx))
261  return -1;
262  av_assert0(ctx_pic);
263 
264  /* Fill up DXVA_PicParams_VP9 */
265  if (fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp) < 0)
266  return -1;
267 
268  ctx_pic->bitstream_size = 0;
269  ctx_pic->bitstream = NULL;
270  return 0;
271 }
272 
274  const uint8_t *buffer,
275  uint32_t size)
276 {
277  const VP9SharedContext *h = avctx->priv_data;
279  unsigned position;
280 
281  if (!ctx_pic->bitstream)
282  ctx_pic->bitstream = buffer;
283  ctx_pic->bitstream_size += size;
284 
285  position = buffer - ctx_pic->bitstream;
286  fill_slice_short(&ctx_pic->slice, position, size);
287 
288  return 0;
289 }
290 
292 {
293  VP9SharedContext *h = avctx->priv_data;
295  int ret;
296 
297  if (ctx_pic->bitstream_size <= 0)
298  return -1;
299 
300  ret = ff_dxva2_common_end_frame(avctx, h->frames[CUR_FRAME].tf.f,
301  &ctx_pic->pp, sizeof(ctx_pic->pp),
302  NULL, 0,
304  return ret;
305 }
306 
307 #if CONFIG_VP9_DXVA2_HWACCEL
309  .name = "vp9_dxva2",
310  .type = AVMEDIA_TYPE_VIDEO,
311  .id = AV_CODEC_ID_VP9,
312  .pix_fmt = AV_PIX_FMT_DXVA2_VLD,
313  .init = ff_dxva2_decode_init,
314  .uninit = ff_dxva2_decode_uninit,
315  .start_frame = dxva2_vp9_start_frame,
316  .decode_slice = dxva2_vp9_decode_slice,
317  .end_frame = dxva2_vp9_end_frame,
318  .frame_params = ff_dxva2_common_frame_params,
319  .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
320  .priv_data_size = sizeof(FFDXVASharedContext),
321 };
322 #endif
323 
324 #if CONFIG_VP9_D3D11VA_HWACCEL
326  .name = "vp9_d3d11va",
327  .type = AVMEDIA_TYPE_VIDEO,
328  .id = AV_CODEC_ID_VP9,
329  .pix_fmt = AV_PIX_FMT_D3D11VA_VLD,
330  .init = ff_dxva2_decode_init,
331  .uninit = ff_dxva2_decode_uninit,
332  .start_frame = dxva2_vp9_start_frame,
333  .decode_slice = dxva2_vp9_decode_slice,
334  .end_frame = dxva2_vp9_end_frame,
335  .frame_params = ff_dxva2_common_frame_params,
336  .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
337  .priv_data_size = sizeof(FFDXVASharedContext),
338 };
339 #endif
340 
341 #if CONFIG_VP9_D3D11VA2_HWACCEL
343  .name = "vp9_d3d11va2",
344  .type = AVMEDIA_TYPE_VIDEO,
345  .id = AV_CODEC_ID_VP9,
346  .pix_fmt = AV_PIX_FMT_D3D11,
347  .init = ff_dxva2_decode_init,
348  .uninit = ff_dxva2_decode_uninit,
349  .start_frame = dxva2_vp9_start_frame,
350  .decode_slice = dxva2_vp9_decode_slice,
351  .end_frame = dxva2_vp9_end_frame,
352  .frame_params = ff_dxva2_common_frame_params,
353  .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
354  .priv_data_size = sizeof(FFDXVASharedContext),
355 };
356 #endif
ThreadFrame tf
Definition: vp9shared.h:60
#define NULL
Definition: coverity.c:32
uint8_t parallelmode
Definition: vp9shared.h:108
int size
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2363
#define flag(name)
Definition: cbs_h2645.c:346
uint8_t update_map
Definition: vp9shared.h:133
AVFrame * f
Definition: thread.h:35
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:410
VP9BitstreamHeader h
Definition: vp9shared.h:160
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, DECODER_BUFFER_DESC *bs, DECODER_BUFFER_DESC *sc)
Definition: dxva2_vp9.c:164
DXVA_PicParams_VP9 pp
Definition: dxva2_vp9.c:30
uint8_t prob[7]
Definition: vp9shared.h:134
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1727
uint8_t framectxid
Definition: vp9shared.h:109
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
#define D3D11VA_CONTEXT(ctx)
unsigned log2_tile_rows
Definition: vp9shared.h:151
int uncompressed_header_size
Definition: vp9shared.h:155
enum FilterMode filtermode
Definition: vp9shared.h:105
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static void fill_slice_short(DXVA_Slice_VPx_Short *slice, unsigned position, unsigned size)
Definition: dxva2_vp9.c:155
int ff_dxva2_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: dxva2.c:586
static char buffer[20]
Definition: seek.c:32
int ff_dxva2_decode_uninit(AVCodecContext *avctx)
Definition: dxva2.c:724
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
uint8_t absolute_vals
Definition: vp9shared.h:132
VP9Frame frames[3]
Definition: vp9shared.h:166
int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, const void *pp, unsigned pp_size, const void *qm, unsigned qm_size, int(*commit_bs_si)(AVCodecContext *, DECODER_BUFFER_DESC *bs, DECODER_BUFFER_DESC *slice))
Definition: dxva2.c:880
unsigned log2_tile_cols
Definition: vp9shared.h:151
uint8_t refidx[3]
Definition: vp9shared.h:111
const AVHWAccel ff_vp9_d3d11va2_hwaccel
#define av_log(a,...)
struct VP9BitstreamHeader::@161::@163 feat[MAX_SEGMENT]
int width
Definition: frame.h:276
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
const uint8_t * bitstream
Definition: dxva2_vp9.c:32
uint8_t signbias[3]
Definition: vp9shared.h:112
uint8_t refreshctx
Definition: vp9shared.h:107
int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
Definition: dxva2.c:1045
#define DXVA2_CONTEXT(ctx)
void * hwaccel_picture_private
Definition: vp9shared.h:67
simple assert() macros that are a bit more flexible than ISO C assert().
struct VP9BitstreamHeader::@159 filter
struct VP9BitstreamHeader::@160 lf_delta
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3582
struct VP9BitstreamHeader::@162 tiling
#define FFMIN(a, b)
Definition: common.h:96
uint8_t keyframe
Definition: vp9shared.h:98
static const chunk_decoder decoder[8]
Definition: dfa.c:330
int width
picture width / height.
Definition: avcodec.h:1690
AVFormatContext * ctx
Definition: movenc.c:48
int ff_dxva2_decode_init(AVCodecContext *avctx)
Definition: dxva2.c:649
if(ret< 0)
Definition: vf_mcdeint.c:279
struct VP9BitstreamHeader::@161 segmentation
static void fill_picture_entry(DXVA_PicEntry_VPx *pic, unsigned index, unsigned flag)
Definition: dxva2_vp9.c:36
unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, const AVDXVAContext *ctx, const AVFrame *frame)
Definition: dxva2.c:764
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
main external API structure.
Definition: avcodec.h:1518
int8_t mode[2]
Definition: vp9shared.h:122
#define CUR_FRAME
Definition: vp9shared.h:163
int ff_dxva2_commit_buffer(AVCodecContext *avctx, AVDXVAContext *ctx, DECODER_BUFFER_DESC *dsc, unsigned type, const void *data, unsigned size, unsigned mb_count)
Definition: dxva2.c:791
int index
Definition: gxfenc.c:89
cl_device_type type
static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const VP9SharedContext *h, DXVA_PicParams_VP9 *pp)
Definition: dxva2_vp9.c:43
void DECODER_BUFFER_DESC
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer. ...
Definition: pixfmt.h:133
#define FAILED(hr)
Definition: windows2linux.h:48
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:309
const AVHWAccel ff_vp9_dxva2_hwaccel
static int dxva2_vp9_end_frame(AVCodecContext *avctx)
Definition: dxva2_vp9.c:291
DXVA_Slice_VPx_Short slice
Definition: dxva2_vp9.c:31
void * priv_data
Definition: avcodec.h:1545
static int dxva2_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: dxva2_vp9.c:273
#define DXVA_CONTEXT(avctx)
static int dxva2_vp9_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: dxva2_vp9.c:252
uint8_t invisible
Definition: vp9shared.h:99
uint8_t use_last_frame_mvs
Definition: vp9shared.h:110
int height
Definition: frame.h:276
ThreadFrame refs[8]
Definition: vp9shared.h:162
uint8_t pred_prob[3]
Definition: vp9shared.h:135
const AVHWAccel ff_vp9_d3d11va_hwaccel
HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView p...
Definition: pixfmt.h:225
int depth
Number of bits in the component.
Definition: pixdesc.h:58
uint8_t highprecisionmvs
Definition: vp9shared.h:104
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:3047
for(j=16;j >0;--j)
#define av_unused
Definition: attributes.h:125
int compressed_header_size
Definition: vp9shared.h:156