FFmpeg
vaapi_vp8.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <va/va.h>
20 #include <va/va_dec_vp8.h>
21 
22 #include "hwaccel_internal.h"
23 #include "vaapi_decode.h"
24 #include "vp8.h"
25 
26 static VASurfaceID vaapi_vp8_surface_id(VP8Frame *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  av_unused const uint8_t *buffer,
36  av_unused uint32_t size)
37 {
38  const VP8Context *s = avctx->priv_data;
39  VAAPIDecodePicture *pic = s->framep[VP8_FRAME_CURRENT]->hwaccel_picture_private;
40  VAPictureParameterBufferVP8 pp;
41  VAProbabilityDataBufferVP8 prob;
42  VAIQMatrixBufferVP8 quant;
43  int err, i, j, k;
44 
46 
47  pp = (VAPictureParameterBufferVP8) {
48  .frame_width = avctx->width,
49  .frame_height = avctx->height,
50 
51  .last_ref_frame = vaapi_vp8_surface_id(s->framep[VP8_FRAME_PREVIOUS]),
52  .golden_ref_frame = vaapi_vp8_surface_id(s->framep[VP8_FRAME_GOLDEN]),
53  .alt_ref_frame = vaapi_vp8_surface_id(s->framep[VP8_FRAME_ALTREF]),
54  .out_of_loop_frame = VA_INVALID_SURFACE,
55 
56  .pic_fields.bits = {
57  .key_frame = !s->keyframe,
58  .version = s->profile,
59 
60  .segmentation_enabled = s->segmentation.enabled,
61  .update_mb_segmentation_map = s->segmentation.update_map,
62  .update_segment_feature_data = s->segmentation.update_feature_data,
63 
64  .filter_type = s->filter.simple,
65  .sharpness_level = s->filter.sharpness,
66 
67  .loop_filter_adj_enable = s->lf_delta.enabled,
68  .mode_ref_lf_delta_update = s->lf_delta.update,
69 
70  .sign_bias_golden = s->sign_bias[VP8_FRAME_GOLDEN],
71  .sign_bias_alternate = s->sign_bias[VP8_FRAME_ALTREF],
72 
73  .mb_no_coeff_skip = s->mbskip_enabled,
74  .loop_filter_disable = s->filter.level == 0,
75  },
76 
77  .prob_skip_false = s->prob->mbskip,
78  .prob_intra = s->prob->intra,
79  .prob_last = s->prob->last,
80  .prob_gf = s->prob->golden,
81  };
82 
83  for (i = 0; i < 3; i++)
84  pp.mb_segment_tree_probs[i] = s->prob->segmentid[i];
85 
86  for (i = 0; i < 4; i++) {
87  if (s->segmentation.enabled) {
88  pp.loop_filter_level[i] = s->segmentation.filter_level[i];
89  if (!s->segmentation.absolute_vals)
90  pp.loop_filter_level[i] += s->filter.level;
91  } else {
92  pp.loop_filter_level[i] = s->filter.level;
93  }
94  pp.loop_filter_level[i] = av_clip_uintp2(pp.loop_filter_level[i], 6);
95  }
96 
97  for (i = 0; i < 4; i++) {
98  pp.loop_filter_deltas_ref_frame[i] = s->lf_delta.ref[i];
99  pp.loop_filter_deltas_mode[i] = s->lf_delta.mode[i + 4];
100  }
101 
102  if (s->keyframe) {
103  static const uint8_t keyframe_y_mode_probs[4] = {
104  145, 156, 163, 128
105  };
106  static const uint8_t keyframe_uv_mode_probs[3] = {
107  142, 114, 183
108  };
109  memcpy(pp.y_mode_probs, keyframe_y_mode_probs, 4);
110  memcpy(pp.uv_mode_probs, keyframe_uv_mode_probs, 3);
111  } else {
112  for (i = 0; i < 4; i++)
113  pp.y_mode_probs[i] = s->prob->pred16x16[i];
114  for (i = 0; i < 3; i++)
115  pp.uv_mode_probs[i] = s->prob->pred8x8c[i];
116  }
117  for (i = 0; i < 2; i++)
118  for (j = 0; j < 19; j++)
119  pp.mv_probs[i][j] = s->prob->mvc[i][j];
120 
121  pp.bool_coder_ctx.range = s->coder_state_at_header_end.range;
122  pp.bool_coder_ctx.value = s->coder_state_at_header_end.value;
123  pp.bool_coder_ctx.count = s->coder_state_at_header_end.bit_count;
124 
125  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
126  VAPictureParameterBufferType,
127  &pp, sizeof(pp));
128  if (err < 0)
129  goto fail;
130 
131  for (i = 0; i < 4; i++) {
132  for (j = 0; j < 8; j++) {
133  static const int coeff_bands_inverse[8] = {
134  0, 1, 2, 3, 5, 6, 4, 15
135  };
136  int coeff_pos = coeff_bands_inverse[j];
137 
138  for (k = 0; k < 3; k++) {
139  memcpy(prob.dct_coeff_probs[i][j][k],
140  s->prob->token[i][coeff_pos][k], 11);
141  }
142  }
143  }
144 
145  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
146  VAProbabilityBufferType,
147  &prob, sizeof(prob));
148  if (err < 0)
149  goto fail;
150 
151  for (i = 0; i < 4; i++) {
152  int base_qi = s->segmentation.base_quant[i];
153  if (!s->segmentation.absolute_vals)
154  base_qi += s->quant.yac_qi;
155 
156  quant.quantization_index[i][0] = av_clip_uintp2(base_qi, 7);
157  quant.quantization_index[i][1] = av_clip_uintp2(base_qi + s->quant.ydc_delta, 7);
158  quant.quantization_index[i][2] = av_clip_uintp2(base_qi + s->quant.y2dc_delta, 7);
159  quant.quantization_index[i][3] = av_clip_uintp2(base_qi + s->quant.y2ac_delta, 7);
160  quant.quantization_index[i][4] = av_clip_uintp2(base_qi + s->quant.uvdc_delta, 7);
161  quant.quantization_index[i][5] = av_clip_uintp2(base_qi + s->quant.uvac_delta, 7);
162  }
163 
164  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
165  VAIQMatrixBufferType,
166  &quant, sizeof(quant));
167  if (err < 0)
168  goto fail;
169 
170  return 0;
171 
172 fail:
173  ff_vaapi_decode_cancel(avctx, pic);
174  return err;
175 }
176 
178 {
179  const VP8Context *s = avctx->priv_data;
180  VAAPIDecodePicture *pic = s->framep[VP8_FRAME_CURRENT]->hwaccel_picture_private;
181 
182  return ff_vaapi_decode_issue(avctx, pic);
183 }
184 
186  const uint8_t *buffer,
187  uint32_t size)
188 {
189  const VP8Context *s = avctx->priv_data;
190  VAAPIDecodePicture *pic = s->framep[VP8_FRAME_CURRENT]->hwaccel_picture_private;
191  VASliceParameterBufferVP8 sp;
192  int err, i;
193 
194  unsigned int header_size = 3 + 7 * s->keyframe;
195  const uint8_t *data = buffer + header_size;
196  unsigned int data_size = size - header_size;
197 
198  sp = (VASliceParameterBufferVP8) {
199  .slice_data_size = data_size,
200  .slice_data_offset = 0,
201  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
202 
203  .macroblock_offset = (8 * (s->coder_state_at_header_end.input - data) -
204  s->coder_state_at_header_end.bit_count - 8),
205  .num_of_partitions = s->num_coeff_partitions + 1,
206  };
207 
208  sp.partition_size[0] = s->header_partition_size - ((sp.macroblock_offset + 7) / 8);
209  for (i = 0; i < 8; i++)
210  sp.partition_size[i+1] = s->coeff_partition_size[i];
211 
212  err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, 1, sizeof(sp), data, data_size);
213  if (err)
214  goto fail;
215 
216  return 0;
217 
218 fail:
219  ff_vaapi_decode_cancel(avctx, pic);
220  return err;
221 }
222 
224  .p.name = "vp8_vaapi",
225  .p.type = AVMEDIA_TYPE_VIDEO,
226  .p.id = AV_CODEC_ID_VP8,
227  .p.pix_fmt = AV_PIX_FMT_VAAPI,
228  .start_frame = &vaapi_vp8_start_frame,
229  .end_frame = &vaapi_vp8_end_frame,
230  .decode_slice = &vaapi_vp8_decode_slice,
231  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
234  .frame_params = &ff_vaapi_common_frame_params,
235  .priv_data_size = sizeof(VAAPIDecodeContext),
236  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
237 };
VP8_FRAME_CURRENT
@ VP8_FRAME_CURRENT
Definition: vp8.h:44
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:30
VAAPIDecodeContext
Definition: vaapi_decode.h:50
av_clip_uintp2
#define av_clip_uintp2
Definition: common.h:122
vaapi_decode.h
av_unused
#define av_unused
Definition: attributes.h:131
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
VAAPIDecodePicture
Definition: vaapi_decode.h:39
data
const char data[16]
Definition: mxf.c:148
VP8_FRAME_ALTREF
@ VP8_FRAME_ALTREF
Definition: vp8.h:47
ThreadFrame::f
AVFrame * f
Definition: threadframe.h:28
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:33
FFHWAccel
Definition: hwaccel_internal.h:34
fail
#define fail()
Definition: checkasm.h:179
vaapi_vp8_surface_id
static VASurfaceID vaapi_vp8_surface_id(VP8Frame *vf)
Definition: vaapi_vp8.c:26
vaapi_vp8_start_frame
static int vaapi_vp8_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_vp8.c:34
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:40
quant
static const uint8_t quant[64]
Definition: vmixdec.c:71
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:661
VP8Frame::tf
ThreadFrame tf
Definition: vp8.h:153
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:637
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:707
ff_vp8_vaapi_hwaccel
const FFHWAccel ff_vp8_vaapi_hwaccel
Definition: vaapi_vp8.c:223
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:152
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
vaapi_vp8_end_frame
static int vaapi_vp8_end_frame(AVCodecContext *avctx)
Definition: vaapi_vp8.c:177
hwaccel_internal.h
VP8Frame
Definition: vp8.h:152
vp8.h
VP8_FRAME_GOLDEN
@ VP8_FRAME_GOLDEN
Definition: vp8.h:46
vaapi_vp8_decode_slice
static int vaapi_vp8_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_vp8.c:185
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
sp
#define sp
Definition: regdef.h:63
size
int size
Definition: twinvq_data.h:10344
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:226
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2094
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVCodecContext::height
int height
Definition: avcodec.h:618
prob
#define prob(name, subs,...)
Definition: cbs_vp9.c:325
AVCodecContext
main external API structure.
Definition: avcodec.h:445
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
ff_vaapi_decode_make_slice_buffer
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, int nb_params, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:62
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
VP8Context
Definition: vp8.h:160
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
VP8_FRAME_PREVIOUS
@ VP8_FRAME_PREVIOUS
Definition: vp8.h:45