FFmpeg
d3d12va_vp9.c
Go to the documentation of this file.
1 /*
2  * Direct3D 12 VP9 HW acceleration
3  *
4  * copyright (c) 2022-2023 Wu Jianhua <toqsxw@outlook.com>
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 "config_components.h"
24 
25 #include "libavutil/avassert.h"
26 #include "libavutil/pixdesc.h"
28 
29 #include "vp9shared.h"
30 #include "dxva2_internal.h"
31 #include "d3d12va_decode.h"
32 
33 typedef struct VP9DecodePictureContext {
34  DXVA_PicParams_VP9 pp;
35  DXVA_Slice_VPx_Short slice;
36  const uint8_t *bitstream;
37  unsigned bitstream_size;
39 
40 static void fill_slice_short(DXVA_Slice_VPx_Short *slice, unsigned position, unsigned size)
41 {
42  memset(slice, 0, sizeof(*slice));
43  slice->BSNALunitDataLocation = position;
44  slice->SliceBytesInBuffer = size;
45  slice->wBadSliceChopping = 0;
46 }
47 
48 static int d3d12va_vp9_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
49 {
50  const VP9SharedContext *h = avctx->priv_data;
52  VP9DecodePictureContext *ctx_pic = h->frames[CUR_FRAME].hwaccel_picture_private;
53 
54  if (!ctx)
55  return -1;
56 
57  av_assert0(ctx_pic);
58 
59  ctx->used_mask = 0;
60 
61  if (ff_dxva2_vp9_fill_picture_parameters(avctx, (AVDXVAContext *)ctx, &ctx_pic->pp) < 0)
62  return -1;
63 
64  ctx_pic->bitstream_size = 0;
65  ctx_pic->bitstream = NULL;
66 
67  return 0;
68 }
69 
70 static int d3d12va_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
71 {
72  const VP9SharedContext *h = avctx->priv_data;
73  VP9DecodePictureContext *ctx_pic = h->frames[CUR_FRAME].hwaccel_picture_private;
74  unsigned position;
75 
76  if (!ctx_pic->bitstream)
77  ctx_pic->bitstream = buffer;
78  ctx_pic->bitstream_size += size;
79 
80  position = buffer - ctx_pic->bitstream;
81  fill_slice_short(&ctx_pic->slice, position, size);
82 
83  return 0;
84 }
85 
86 static int update_input_arguments(AVCodecContext *avctx, D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS *input_args, ID3D12Resource *buffer)
87 {
88  const VP9SharedContext *h = avctx->priv_data;
89  VP9DecodePictureContext *ctx_pic = h->frames[CUR_FRAME].hwaccel_picture_private;
90 
91  void *mapped_data;
92  D3D12_VIDEO_DECODE_FRAME_ARGUMENT *args;
93 
94  if (FAILED(ID3D12Resource_Map(buffer, 0, NULL, &mapped_data))) {
95  av_log(avctx, AV_LOG_ERROR, "Failed to map D3D12 Buffer resource!\n");
96  return AVERROR(EINVAL);
97  }
98 
99  args = &input_args->FrameArguments[input_args->NumFrameArguments++];
100  args->Type = D3D12_VIDEO_DECODE_ARGUMENT_TYPE_SLICE_CONTROL;
101  args->Size = sizeof(ctx_pic->slice);
102  args->pData = &ctx_pic->slice;
103 
104  memcpy(mapped_data, ctx_pic->bitstream, ctx_pic->slice.SliceBytesInBuffer);
105 
106  ID3D12Resource_Unmap(buffer, 0, NULL);
107 
108  input_args->CompressedBitstream = (D3D12_VIDEO_DECODE_COMPRESSED_BITSTREAM){
109  .pBuffer = buffer,
110  .Offset = 0,
111  .Size = ctx_pic->slice.SliceBytesInBuffer,
112  };
113 
114  return 0;
115 }
116 
118 {
119  VP9SharedContext *h = avctx->priv_data;
120  VP9DecodePictureContext *ctx_pic = h->frames[CUR_FRAME].hwaccel_picture_private;
121 
122  if (ctx_pic->bitstream_size <= 0)
123  return -1;
124 
125  return ff_d3d12va_common_end_frame(avctx, h->frames[CUR_FRAME].tf.f,
126  &ctx_pic->pp, sizeof(ctx_pic->pp), NULL, 0, update_input_arguments);
127 }
128 
130 {
132  DXVA_PicParams_VP9 pp;
133 
134  switch (avctx->profile) {
135  case AV_PROFILE_VP9_2:
136  case AV_PROFILE_VP9_3:
137  ctx->cfg.DecodeProfile = D3D12_VIDEO_DECODE_PROFILE_VP9_10BIT_PROFILE2;
138  break;
139 
140  case AV_PROFILE_VP9_0:
141  case AV_PROFILE_VP9_1:
142  default:
143  ctx->cfg.DecodeProfile = D3D12_VIDEO_DECODE_PROFILE_VP9;
144  break;
145  };
146 
147  ctx->max_num_ref = FF_ARRAY_ELEMS(pp.ref_frame_map) + 1;
148 
149  return ff_d3d12va_decode_init(avctx);
150 }
151 
152 #if CONFIG_VP9_D3D12VA_HWACCEL
154  .p.name = "vp9_d3d12va",
155  .p.type = AVMEDIA_TYPE_VIDEO,
156  .p.id = AV_CODEC_ID_VP9,
157  .p.pix_fmt = AV_PIX_FMT_D3D12,
158  .init = d3d12va_vp9_decode_init,
159  .uninit = ff_d3d12va_decode_uninit,
160  .start_frame = d3d12va_vp9_start_frame,
161  .decode_slice = d3d12va_vp9_decode_slice,
162  .end_frame = d3d12va_vp9_end_frame,
163  .frame_params = ff_d3d12va_common_frame_params,
164  .frame_priv_data_size = sizeof(VP9DecodePictureContext),
165  .priv_data_size = sizeof(D3D12VADecodeContext),
166 };
167 #endif
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
update_input_arguments
static int update_input_arguments(AVCodecContext *avctx, D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS *input_args, ID3D12Resource *buffer)
Definition: d3d12va_vp9.c:86
AV_PROFILE_VP9_1
#define AV_PROFILE_VP9_1
Definition: defs.h:155
av_unused
#define av_unused
Definition: attributes.h:131
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
pixdesc.h
VP9DecodePictureContext::pp
DXVA_PicParams_VP9 pp
Definition: d3d12va_vp9.c:34
ff_d3d12va_decode_uninit
int ff_d3d12va_decode_uninit(AVCodecContext *avctx)
uninit D3D12VADecodeContext
Definition: d3d12va_decode.c:373
VP9DecodePictureContext::bitstream
const uint8_t * bitstream
Definition: d3d12va_vp9.c:36
FFHWAccel
Definition: hwaccel_internal.h:34
AV_PROFILE_VP9_3
#define AV_PROFILE_VP9_3
Definition: defs.h:157
vp9shared.h
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
VP9SharedContext
Definition: vp9shared.h:164
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ff_d3d12va_common_frame_params
int ff_d3d12va_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
d3d12va common frame params
Definition: d3d12va_decode.c:271
dxva2_internal.h
ff_vp9_d3d12va_hwaccel
const struct FFHWAccel ff_vp9_d3d12va_hwaccel
NULL
#define NULL
Definition: coverity.c:32
ff_d3d12va_common_end_frame
int ff_d3d12va_common_end_frame(AVCodecContext *avctx, AVFrame *frame, const void *pp, unsigned pp_size, const void *qm, unsigned qm_size, int(*update_input_arguments)(AVCodecContext *, D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS *, ID3D12Resource *))
d3d12va common end frame
Definition: d3d12va_decode.c:434
d3d12va_vp9_decode_slice
static int d3d12va_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: d3d12va_vp9.c:70
AV_PIX_FMT_D3D12
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
Definition: pixfmt.h:440
VP9DecodePictureContext
Definition: d3d12va_vp9.c:33
D3D12VA_DECODE_CONTEXT
#define D3D12VA_DECODE_CONTEXT(avctx)
Definition: d3d12va_decode.h:128
VP9DecodePictureContext::slice
DXVA_Slice_VPx_Short slice
Definition: d3d12va_vp9.c:35
d3d12va_vp9_end_frame
static int d3d12va_vp9_end_frame(AVCodecContext *avctx)
Definition: d3d12va_vp9.c:117
VP9DecodePictureContext::bitstream_size
unsigned bitstream_size
Definition: d3d12va_vp9.c:37
size
int size
Definition: twinvq_data.h:10344
d3d12va_vp9_start_frame
static int d3d12va_vp9_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: d3d12va_vp9.c:48
AVDXVAContext
Definition: dxva2_internal.h:74
fill_slice_short
static void fill_slice_short(DXVA_Slice_VPx_Short *slice, unsigned position, unsigned size)
Definition: d3d12va_vp9.c:40
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2105
d3d12va_vp9_decode_init
static int d3d12va_vp9_decode_init(AVCodecContext *avctx)
Definition: d3d12va_vp9.c:129
AV_PROFILE_VP9_2
#define AV_PROFILE_VP9_2
Definition: defs.h:156
ff_dxva2_vp9_fill_picture_parameters
int ff_dxva2_vp9_fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, DXVA_PicParams_VP9 *pp)
Definition: dxva2_vp9.c:46
AVCodecContext
main external API structure.
Definition: avcodec.h:451
buffer
the frame and frame 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 AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1650
AV_PROFILE_VP9_0
#define AV_PROFILE_VP9_0
Definition: defs.h:154
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
CUR_FRAME
#define CUR_FRAME
Definition: vp9shared.h:168
D3D12VADecodeContext
This structure is used to provide the necessary configurations and data to the FFmpeg Direct3D 12 HWA...
Definition: d3d12va_decode.h:37
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
hwcontext_d3d12va_internal.h
ff_d3d12va_decode_init
int ff_d3d12va_decode_init(AVCodecContext *avctx)
init D3D12VADecodeContext
Definition: d3d12va_decode.c:283
d3d12va_decode.h