FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 AVBufferRef *buffer_ref,
36  av_unused const uint8_t *buffer,
37  av_unused uint32_t size)
38 {
39  const VP8Context *s = avctx->priv_data;
40  VAAPIDecodePicture *pic = s->framep[VP8_FRAME_CURRENT]->hwaccel_picture_private;
41  VAPictureParameterBufferVP8 pp;
42  VAProbabilityDataBufferVP8 prob;
43  VAIQMatrixBufferVP8 quant;
44  int err, i, j, k;
45 
47 
48  pp = (VAPictureParameterBufferVP8) {
49  .frame_width = avctx->width,
50  .frame_height = avctx->height,
51 
52  .last_ref_frame = vaapi_vp8_surface_id(s->framep[VP8_FRAME_PREVIOUS]),
53  .golden_ref_frame = vaapi_vp8_surface_id(s->framep[VP8_FRAME_GOLDEN]),
54  .alt_ref_frame = vaapi_vp8_surface_id(s->framep[VP8_FRAME_ALTREF]),
55  .out_of_loop_frame = VA_INVALID_SURFACE,
56 
57  .pic_fields.bits = {
58  .key_frame = !s->keyframe,
59  .version = s->profile,
60 
61  .segmentation_enabled = s->segmentation.enabled,
62  .update_mb_segmentation_map = s->segmentation.update_map,
63  .update_segment_feature_data = s->segmentation.update_feature_data,
64 
65  .filter_type = s->filter.simple,
66  .sharpness_level = s->filter.sharpness,
67 
68  .loop_filter_adj_enable = s->lf_delta.enabled,
69  .mode_ref_lf_delta_update = s->lf_delta.update,
70 
71  .sign_bias_golden = s->sign_bias[VP8_FRAME_GOLDEN],
72  .sign_bias_alternate = s->sign_bias[VP8_FRAME_ALTREF],
73 
74  .mb_no_coeff_skip = s->mbskip_enabled,
75  .loop_filter_disable = s->filter.level == 0,
76  },
77 
78  .prob_skip_false = s->prob->mbskip,
79  .prob_intra = s->prob->intra,
80  .prob_last = s->prob->last,
81  .prob_gf = s->prob->golden,
82  };
83 
84  for (i = 0; i < 3; i++)
85  pp.mb_segment_tree_probs[i] = s->prob->segmentid[i];
86 
87  for (i = 0; i < 4; i++) {
88  if (s->segmentation.enabled) {
89  pp.loop_filter_level[i] = s->segmentation.filter_level[i];
90  if (!s->segmentation.absolute_vals)
91  pp.loop_filter_level[i] += s->filter.level;
92  } else {
93  pp.loop_filter_level[i] = s->filter.level;
94  }
95  pp.loop_filter_level[i] = av_clip_uintp2(pp.loop_filter_level[i], 6);
96  }
97 
98  for (i = 0; i < 4; i++) {
99  pp.loop_filter_deltas_ref_frame[i] = s->lf_delta.ref[i];
100  pp.loop_filter_deltas_mode[i] = s->lf_delta.mode[i + 4];
101  }
102 
103  if (s->keyframe) {
104  static const uint8_t keyframe_y_mode_probs[4] = {
105  145, 156, 163, 128
106  };
107  static const uint8_t keyframe_uv_mode_probs[3] = {
108  142, 114, 183
109  };
110  memcpy(pp.y_mode_probs, keyframe_y_mode_probs, 4);
111  memcpy(pp.uv_mode_probs, keyframe_uv_mode_probs, 3);
112  } else {
113  for (i = 0; i < 4; i++)
114  pp.y_mode_probs[i] = s->prob->pred16x16[i];
115  for (i = 0; i < 3; i++)
116  pp.uv_mode_probs[i] = s->prob->pred8x8c[i];
117  }
118  for (i = 0; i < 2; i++)
119  for (j = 0; j < 19; j++)
120  pp.mv_probs[i][j] = s->prob->mvc[i][j];
121 
122  pp.bool_coder_ctx.range = s->coder_state_at_header_end.range;
123  pp.bool_coder_ctx.value = s->coder_state_at_header_end.value;
124  pp.bool_coder_ctx.count = s->coder_state_at_header_end.bit_count;
125 
126  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
127  VAPictureParameterBufferType,
128  &pp, sizeof(pp));
129  if (err < 0)
130  goto fail;
131 
132  for (i = 0; i < 4; i++) {
133  for (j = 0; j < 8; j++) {
134  static const int coeff_bands_inverse[8] = {
135  0, 1, 2, 3, 5, 6, 4, 15
136  };
137  int coeff_pos = coeff_bands_inverse[j];
138 
139  for (k = 0; k < 3; k++) {
140  memcpy(prob.dct_coeff_probs[i][j][k],
141  s->prob->token[i][coeff_pos][k], 11);
142  }
143  }
144  }
145 
146  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
147  VAProbabilityBufferType,
148  &prob, sizeof(prob));
149  if (err < 0)
150  goto fail;
151 
152  for (i = 0; i < 4; i++) {
153  int base_qi = s->segmentation.base_quant[i];
154  if (!s->segmentation.absolute_vals)
155  base_qi += s->quant.yac_qi;
156 
157  quant.quantization_index[i][0] = av_clip_uintp2(base_qi, 7);
158  quant.quantization_index[i][1] = av_clip_uintp2(base_qi + s->quant.ydc_delta, 7);
159  quant.quantization_index[i][2] = av_clip_uintp2(base_qi + s->quant.y2dc_delta, 7);
160  quant.quantization_index[i][3] = av_clip_uintp2(base_qi + s->quant.y2ac_delta, 7);
161  quant.quantization_index[i][4] = av_clip_uintp2(base_qi + s->quant.uvdc_delta, 7);
162  quant.quantization_index[i][5] = av_clip_uintp2(base_qi + s->quant.uvac_delta, 7);
163  }
164 
165  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
166  VAIQMatrixBufferType,
167  &quant, sizeof(quant));
168  if (err < 0)
169  goto fail;
170 
171  return 0;
172 
173 fail:
174  ff_vaapi_decode_cancel(avctx, pic);
175  return err;
176 }
177 
179 {
180  const VP8Context *s = avctx->priv_data;
181  VAAPIDecodePicture *pic = s->framep[VP8_FRAME_CURRENT]->hwaccel_picture_private;
182 
183  return ff_vaapi_decode_issue(avctx, pic);
184 }
185 
187  const uint8_t *buffer,
188  uint32_t size)
189 {
190  const VP8Context *s = avctx->priv_data;
191  VAAPIDecodePicture *pic = s->framep[VP8_FRAME_CURRENT]->hwaccel_picture_private;
192  VASliceParameterBufferVP8 sp;
193  int err, i;
194 
195  unsigned int header_size = 3 + 7 * s->keyframe;
196  const uint8_t *data = buffer + header_size;
197  unsigned int data_size = size - header_size;
198 
199  sp = (VASliceParameterBufferVP8) {
200  .slice_data_size = data_size,
201  .slice_data_offset = 0,
202  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
203 
204  .macroblock_offset = (8 * (s->coder_state_at_header_end.input - data) -
205  s->coder_state_at_header_end.bit_count - 8),
206  .num_of_partitions = s->num_coeff_partitions + 1,
207  };
208 
209  sp.partition_size[0] = s->header_partition_size - ((sp.macroblock_offset + 7) / 8);
210  for (i = 0; i < 8; i++)
211  sp.partition_size[i+1] = s->coeff_partition_size[i];
212 
213  err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, 1, sizeof(sp), data, data_size);
214  if (err)
215  goto fail;
216 
217  return 0;
218 
219 fail:
220  ff_vaapi_decode_cancel(avctx, pic);
221  return err;
222 }
223 
225  .p.name = "vp8_vaapi",
226  .p.type = AVMEDIA_TYPE_VIDEO,
227  .p.id = AV_CODEC_ID_VP8,
228  .p.pix_fmt = AV_PIX_FMT_VAAPI,
229  .start_frame = &vaapi_vp8_start_frame,
230  .end_frame = &vaapi_vp8_end_frame,
231  .decode_slice = &vaapi_vp8_decode_slice,
232  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
235  .frame_params = &ff_vaapi_common_frame_params,
236  .priv_data_size = sizeof(VAAPIDecodeContext),
237  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
238 };
VP8_FRAME_CURRENT
@ VP8_FRAME_CURRENT
Definition: vp8.h:45
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:30
VAAPIDecodeContext
Definition: vaapi_decode.h:47
av_clip_uintp2
#define av_clip_uintp2
Definition: common.h:124
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:35
data
const char data[16]
Definition: mxf.c:149
VP8_FRAME_ALTREF
@ VP8_FRAME_ALTREF
Definition: vp8.h:48
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:34
FFHWAccel
Definition: hwaccel_internal.h:34
fail
#define fail()
Definition: checkasm.h:193
vaapi_vp8_surface_id
static VASurfaceID vaapi_vp8_surface_id(VP8Frame *vf)
Definition: vaapi_vp8.c:26
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:36
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:692
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:668
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:738
ff_vp8_vaapi_hwaccel
const FFHWAccel ff_vp8_vaapi_hwaccel
Definition: vaapi_vp8.c:224
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:166
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:178
hwaccel_internal.h
vaapi_vp8_start_frame
static int vaapi_vp8_start_frame(AVCodecContext *avctx, av_unused const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_vp8.c:34
VP8Frame
Definition: vp8.h:153
vp8.h
VP8_FRAME_GOLDEN
@ VP8_FRAME_GOLDEN
Definition: vp8.h:47
vaapi_vp8_decode_slice
static int vaapi_vp8_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_vp8.c:186
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
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:247
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:2124
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVCodecContext::height
int height
Definition: avcodec.h:632
prob
#define prob(name, subs,...)
Definition: cbs_vp9.c:325
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
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:75
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
VP8Context
Definition: vp8.h:161
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:632
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
vf
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t const int8_t * vf
Definition: dsp.h:249
VP8_FRAME_PREVIOUS
@ VP8_FRAME_PREVIOUS
Definition: vp8.h:46