FFmpeg
vaapi_av1.c
Go to the documentation of this file.
1 /*
2  * AV1 HW decode acceleration through VA API
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/pixdesc.h"
22 #include "hwconfig.h"
23 #include "vaapi_decode.h"
24 #include "av1dec.h"
25 
26 static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf)
27 {
28  if (vf)
29  return ff_vaapi_get_surface_id(vf->tf.f);
30  else
31  return VA_INVALID_SURFACE;
32 }
33 
35 {
36  AV1DecContext *s = avctx->priv_data;
37  const AV1RawSequenceHeader *seq = s->raw_seq;
38  int8_t bit_depth = 8;
39 
40  if (seq->seq_profile == 2 && seq->color_config.high_bitdepth)
41  bit_depth = seq->color_config.twelve_bit ? 12 : 10;
42  else if (seq->seq_profile <= 2)
43  bit_depth = seq->color_config.high_bitdepth ? 10 : 8;
44  else {
45  av_log(avctx, AV_LOG_ERROR,
46  "Couldn't get bit depth from profile:%d.\n", seq->seq_profile);
47  return -1;
48  }
49  return bit_depth == 8 ? 0 : bit_depth == 10 ? 1 : 2;
50 }
51 
53  av_unused const uint8_t *buffer,
54  av_unused uint32_t size)
55 {
56  AV1DecContext *s = avctx->priv_data;
57  const AV1RawSequenceHeader *seq = s->raw_seq;
58  const AV1RawFrameHeader *frame_header = s->raw_frame_header;
59  const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain;
60  VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private;
61  VADecPictureParameterBufferAV1 pic_param;
62  int8_t bit_depth_idx;
63  int err = 0;
64  int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain;
66 
67  pic->output_surface = vaapi_av1_surface_id(&s->cur_frame);
68 
69  bit_depth_idx = vaapi_av1_get_bit_depth_idx(avctx);
70  if (bit_depth_idx < 0)
71  goto fail;
72 
73  memset(&pic_param, 0, sizeof(VADecPictureParameterBufferAV1));
74  pic_param = (VADecPictureParameterBufferAV1) {
75  .profile = seq->seq_profile,
76  .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1,
77  .bit_depth_idx = bit_depth_idx,
78  .current_frame = pic->output_surface,
79  .current_display_picture = pic->output_surface,
80  .frame_width_minus1 = frame_header->frame_width_minus_1,
81  .frame_height_minus1 = frame_header->frame_height_minus_1,
82  .primary_ref_frame = frame_header->primary_ref_frame,
83  .order_hint = frame_header->order_hint,
84  .tile_cols = frame_header->tile_cols,
85  .tile_rows = frame_header->tile_rows,
86  .context_update_tile_id = frame_header->context_update_tile_id,
87  .interp_filter = frame_header->interpolation_filter,
88  .filter_level[0] = frame_header->loop_filter_level[0],
89  .filter_level[1] = frame_header->loop_filter_level[1],
90  .filter_level_u = frame_header->loop_filter_level[2],
91  .filter_level_v = frame_header->loop_filter_level[3],
92  .base_qindex = frame_header->base_q_idx,
93  .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3,
94  .cdef_bits = frame_header->cdef_bits,
95  .seq_info_fields.fields = {
96  .still_picture = seq->still_picture,
97  .use_128x128_superblock = seq->use_128x128_superblock,
98  .enable_filter_intra = seq->enable_filter_intra,
99  .enable_intra_edge_filter = seq->enable_intra_edge_filter,
100  .enable_interintra_compound = seq->enable_interintra_compound,
101  .enable_masked_compound = seq->enable_masked_compound,
102  .enable_dual_filter = seq->enable_dual_filter,
103  .enable_order_hint = seq->enable_order_hint,
104  .enable_jnt_comp = seq->enable_jnt_comp,
105  .enable_cdef = seq->enable_cdef,
106  .mono_chrome = seq->color_config.mono_chrome,
107  .color_range = seq->color_config.color_range,
108  .subsampling_x = seq->color_config.subsampling_x,
109  .subsampling_y = seq->color_config.subsampling_y,
110  .chroma_sample_position = seq->color_config.chroma_sample_position,
111  .film_grain_params_present = seq->film_grain_params_present &&
112  !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN),
113  },
114  .seg_info.segment_info_fields.bits = {
115  .enabled = frame_header->segmentation_enabled,
116  .update_map = frame_header->segmentation_update_map,
117  .temporal_update = frame_header->segmentation_temporal_update,
118  .update_data = frame_header->segmentation_update_data,
119  },
120  .film_grain_info = {
121  .film_grain_info_fields.bits = {
122  .apply_grain = apply_grain,
123  .chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma,
124  .grain_scaling_minus_8 = film_grain->grain_scaling_minus_8,
125  .ar_coeff_lag = film_grain->ar_coeff_lag,
126  .ar_coeff_shift_minus_6 = film_grain->ar_coeff_shift_minus_6,
127  .grain_scale_shift = film_grain->grain_scale_shift,
128  .overlap_flag = film_grain->overlap_flag,
129  .clip_to_restricted_range = film_grain->clip_to_restricted_range,
130  },
131  .grain_seed = film_grain->grain_seed,
132  .num_y_points = film_grain->num_y_points,
133  .num_cb_points = film_grain->num_cb_points,
134  .num_cr_points = film_grain->num_cr_points,
135  .cb_mult = film_grain->cb_mult,
136  .cb_luma_mult = film_grain->cb_luma_mult,
137  .cb_offset = film_grain->cb_offset,
138  .cr_mult = film_grain->cr_mult,
139  .cr_luma_mult = film_grain->cr_luma_mult,
140  .cr_offset = film_grain->cr_offset,
141  },
142  .pic_info_fields.bits = {
143  .frame_type = frame_header->frame_type,
144  .show_frame = frame_header->show_frame,
145  .showable_frame = frame_header->showable_frame,
146  .error_resilient_mode = frame_header->error_resilient_mode,
147  .disable_cdf_update = frame_header->disable_cdf_update,
148  .allow_screen_content_tools = frame_header->allow_screen_content_tools,
149  .force_integer_mv = frame_header->force_integer_mv,
150  .allow_intrabc = frame_header->allow_intrabc,
151  .use_superres = frame_header->use_superres,
152  .allow_high_precision_mv = frame_header->allow_high_precision_mv,
153  .is_motion_mode_switchable = frame_header->is_motion_mode_switchable,
154  .use_ref_frame_mvs = frame_header->use_ref_frame_mvs,
155  .disable_frame_end_update_cdf = frame_header->disable_frame_end_update_cdf,
156  .uniform_tile_spacing_flag = frame_header->uniform_tile_spacing_flag,
157  .allow_warped_motion = frame_header->allow_warped_motion,
158  },
159  .loop_filter_info_fields.bits = {
160  .sharpness_level = frame_header->loop_filter_sharpness,
161  .mode_ref_delta_enabled = frame_header->loop_filter_delta_enabled,
162  .mode_ref_delta_update = frame_header->loop_filter_delta_update,
163  },
164  .mode_control_fields.bits = {
165  .delta_q_present_flag = frame_header->delta_q_present,
166  .log2_delta_q_res = frame_header->delta_q_res,
167  .tx_mode = frame_header->tx_mode,
168  .reference_select = frame_header->reference_select,
169  .reduced_tx_set_used = frame_header->reduced_tx_set,
170  .skip_mode_present = frame_header->skip_mode_present,
171  },
172  .loop_restoration_fields.bits = {
173  .yframe_restoration_type = remap_lr_type[frame_header->lr_type[0]],
174  .cbframe_restoration_type = remap_lr_type[frame_header->lr_type[1]],
175  .crframe_restoration_type = remap_lr_type[frame_header->lr_type[2]],
176  .lr_unit_shift = frame_header->lr_unit_shift,
177  .lr_uv_shift = frame_header->lr_uv_shift,
178  },
179  .qmatrix_fields.bits = {
180  .using_qmatrix = frame_header->using_qmatrix,
181  }
182  };
183 
184  for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
185  if (pic_param.pic_info_fields.bits.frame_type == AV1_FRAME_KEY)
186  pic_param.ref_frame_map[i] = VA_INVALID_ID;
187  else
188  pic_param.ref_frame_map[i] = vaapi_av1_surface_id(&s->ref[i]);
189  }
190  for (int i = 0; i < AV1_REFS_PER_FRAME; i++) {
191  pic_param.ref_frame_idx[i] = frame_header->ref_frame_idx[i];
192  }
193  for (int i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) {
194  pic_param.ref_deltas[i] = frame_header->loop_filter_ref_deltas[i];
195  }
196  for (int i = 0; i < 2; i++) {
197  pic_param.mode_deltas[i] = frame_header->loop_filter_mode_deltas[i];
198  }
199  for (int i = 0; i < (1 << frame_header->cdef_bits); i++) {
200  pic_param.cdef_y_strengths[i] =
201  (frame_header->cdef_y_pri_strength[i] << 2) +
202  frame_header->cdef_y_sec_strength[i];
203  pic_param.cdef_uv_strengths[i] =
204  (frame_header->cdef_uv_pri_strength[i] << 2) +
205  frame_header->cdef_uv_sec_strength[i];
206  }
207  for (int i = 0; i < frame_header->tile_cols; i++) {
208  pic_param.width_in_sbs_minus_1[i] =
209  frame_header->width_in_sbs_minus_1[i];
210  }
211  for (int i = 0; i < frame_header->tile_rows; i++) {
212  pic_param.height_in_sbs_minus_1[i] =
213  frame_header->height_in_sbs_minus_1[i];
214  }
215  for (int i = AV1_REF_FRAME_LAST; i <= AV1_REF_FRAME_ALTREF; i++) {
216  pic_param.wm[i - 1].wmtype = s->cur_frame.gm_type[i];
217  for (int j = 0; j < 6; j++)
218  pic_param.wm[i - 1].wmmat[j] = s->cur_frame.gm_params[i][j];
219  }
220  if (apply_grain) {
221  for (int i = 0; i < film_grain->num_y_points; i++) {
222  pic_param.film_grain_info.point_y_value[i] =
223  film_grain->point_y_value[i];
224  pic_param.film_grain_info.point_y_scaling[i] =
225  film_grain->point_y_scaling[i];
226  }
227  for (int i = 0; i < film_grain->num_cb_points; i++) {
228  pic_param.film_grain_info.point_cb_value[i] =
229  film_grain->point_cb_value[i];
230  pic_param.film_grain_info.point_cb_scaling[i] =
231  film_grain->point_cb_scaling[i];
232  }
233  for (int i = 0; i < film_grain->num_cr_points; i++) {
234  pic_param.film_grain_info.point_cr_value[i] =
235  film_grain->point_cr_value[i];
236  pic_param.film_grain_info.point_cr_scaling[i] =
237  film_grain->point_cr_scaling[i];
238  }
239  for (int i = 0; i < 24; i++) {
240  pic_param.film_grain_info.ar_coeffs_y[i] =
241  film_grain->ar_coeffs_y_plus_128[i] - 128;
242  }
243  for (int i = 0; i < 25; i++) {
244  pic_param.film_grain_info.ar_coeffs_cb[i] =
245  film_grain->ar_coeffs_cb_plus_128[i] - 128;
246  pic_param.film_grain_info.ar_coeffs_cr[i] =
247  film_grain->ar_coeffs_cr_plus_128[i] - 128;
248  }
249  }
250  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
251  VAPictureParameterBufferType,
252  &pic_param, sizeof(pic_param));
253  if (err < 0)
254  goto fail;
255 
256  return 0;
257 
258 fail:
259  ff_vaapi_decode_cancel(avctx, pic);
260  return err;
261 }
262 
264 {
265  const AV1DecContext *s = avctx->priv_data;
266  VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private;
267  return ff_vaapi_decode_issue(avctx, pic);
268 }
269 
271  const uint8_t *buffer,
272  uint32_t size)
273 {
274  const AV1DecContext *s = avctx->priv_data;
275  VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private;
276  VASliceParameterBufferAV1 slice_param;
277  int err = 0;
278 
279  for (int i = s->tg_start; i <= s->tg_end; i++) {
280  memset(&slice_param, 0, sizeof(VASliceParameterBufferAV1));
281 
282  slice_param = (VASliceParameterBufferAV1) {
283  .slice_data_size = s->tile_group_info[i].tile_size,
284  .slice_data_offset = s->tile_group_info[i].tile_offset,
285  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
286  .tile_row = s->tile_group_info[i].tile_row,
287  .tile_column = s->tile_group_info[i].tile_column,
288  .tg_start = s->tg_start,
289  .tg_end = s->tg_end,
290  };
291 
292  err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &slice_param,
293  sizeof(VASliceParameterBufferAV1),
294  buffer,
295  s->tile_group_info[i].tile_size);
296  if (err) {
297  ff_vaapi_decode_cancel(avctx, pic);
298  return err;
299  }
300  }
301 
302  return 0;
303 }
304 
306  .name = "av1_vaapi",
307  .type = AVMEDIA_TYPE_VIDEO,
308  .id = AV_CODEC_ID_AV1,
309  .pix_fmt = AV_PIX_FMT_VAAPI,
310  .start_frame = vaapi_av1_start_frame,
311  .end_frame = vaapi_av1_end_frame,
312  .decode_slice = vaapi_av1_decode_slice,
313  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
316  .frame_params = ff_vaapi_common_frame_params,
317  .priv_data_size = sizeof(VAAPIDecodeContext),
318  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
319 };
hwconfig.h
bit_depth
static void bit_depth(AudioStatsContext *s, uint64_t mask, uint64_t imask, AVRational *depth)
Definition: af_astats.c:254
AV1_REFS_PER_FRAME
@ AV1_REFS_PER_FRAME
Definition: av1.h:84
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:30
AV1RawSequenceHeader
Definition: cbs_av1.h:73
VAAPIDecodeContext
Definition: vaapi_decode.h:50
vaapi_decode.h
AV1RawFilmGrainParams::apply_grain
uint8_t apply_grain
Definition: cbs_av1.h:134
av_unused
#define av_unused
Definition: attributes.h:131
VAAPIDecodePicture
Definition: vaapi_decode.h:39
AV1_RESTORE_SGRPROJ
@ AV1_RESTORE_SGRPROJ
Definition: av1.h:167
pixdesc.h
ff_vaapi_decode_make_slice_buffer
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:59
vaapi_av1_end_frame
static int vaapi_av1_end_frame(AVCodecContext *avctx)
Definition: vaapi_av1.c:263
ThreadFrame::f
AVFrame * f
Definition: thread.h:35
AV1RawSequenceHeader::seq_profile
uint8_t seq_profile
Definition: cbs_av1.h:74
AVHWAccel
Definition: avcodec.h:2139
ff_vaapi_decode_make_param_buffer
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:30
fail
#define fail()
Definition: checkasm.h:134
AV1Frame
Definition: av1dec.h:33
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:181
vaapi_av1_decode_slice
static int vaapi_av1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_av1.c:270
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:634
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:610
AV1_RESTORE_WIENER
@ AV1_RESTORE_WIENER
Definition: av1.h:166
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:680
av1dec.h
vaapi_av1_get_bit_depth_idx
static int8_t vaapi_av1_get_bit_depth_idx(AVCodecContext *avctx)
Definition: vaapi_av1.c:34
AV1_REF_FRAME_ALTREF
@ AV1_REF_FRAME_ALTREF
Definition: av1.h:68
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:151
AV1_REF_FRAME_LAST
@ AV1_REF_FRAME_LAST
Definition: av1.h:62
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:278
AV1RawFrameHeader
Definition: cbs_av1.h:165
AV1Frame::tf
ThreadFrame tf
Definition: av1dec.h:34
AV1_RESTORE_SWITCHABLE
@ AV1_RESTORE_SWITCHABLE
Definition: av1.h:168
AV1_TOTAL_REFS_PER_FRAME
@ AV1_TOTAL_REFS_PER_FRAME
Definition: av1.h:85
size
int size
Definition: twinvq_data.h:10344
AV1DecContext
Definition: av1dec.h:62
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:225
AV1_FRAME_KEY
@ AV1_FRAME_KEY
Definition: av1.h:53
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:119
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2145
AV1_NUM_REF_FRAMES
@ AV1_NUM_REF_FRAMES
Definition: av1.h:83
i
int i
Definition: input.c:407
vaapi_av1_surface_id
static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf)
Definition: vaapi_av1.c:26
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwconfig.h:26
AV1RawSequenceHeader::color_config
AV1RawColorConfig color_config
Definition: cbs_av1.h:128
vaapi_av1_start_frame
static int vaapi_av1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_av1.c:52
AV1RawColorConfig::high_bitdepth
uint8_t high_bitdepth
Definition: cbs_av1.h:42
AVCodecContext
main external API structure.
Definition: avcodec.h:501
frame_header
Definition: truemotion1.c:87
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::export_side_data
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition: avcodec.h:2088
ff_av1_vaapi_hwaccel
const AVHWAccel ff_av1_vaapi_hwaccel
Definition: vaapi_av1.c:305
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV1RawColorConfig::twelve_bit
uint8_t twelve_bit
Definition: cbs_av1.h:43
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:528
AV1_RESTORE_NONE
@ AV1_RESTORE_NONE
Definition: av1.h:165
AV1RawFilmGrainParams
Definition: cbs_av1.h:133
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AV_CODEC_EXPORT_DATA_FILM_GRAIN
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition: avcodec.h:394