FFmpeg
vaapi_vp9.c
Go to the documentation of this file.
1 /*
2  * VP9 HW decode acceleration through VA API
3  *
4  * Copyright (C) 2015 Timo Rothenpieler <timo@rothenpieler.org>
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/pixdesc.h"
24 
25 #include "hwaccel.h"
26 #include "vaapi_decode.h"
27 #include "vp9shared.h"
28 
29 static VASurfaceID vaapi_vp9_surface_id(const VP9Frame *vf)
30 {
31  if (vf)
32  return ff_vaapi_get_surface_id(vf->tf.f);
33  else
34  return VA_INVALID_SURFACE;
35 }
36 
38  av_unused const uint8_t *buffer,
39  av_unused uint32_t size)
40 {
41  const VP9SharedContext *h = avctx->priv_data;
43  VADecPictureParameterBufferVP9 pic_param;
44  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
45  int err, i;
46 
48 
49  pic_param = (VADecPictureParameterBufferVP9) {
50  .frame_width = avctx->width,
51  .frame_height = avctx->height,
52 
53  .pic_fields.bits = {
54  .subsampling_x = pixdesc->log2_chroma_w,
55  .subsampling_y = pixdesc->log2_chroma_h,
56  .frame_type = !h->h.keyframe,
57  .show_frame = !h->h.invisible,
58  .error_resilient_mode = h->h.errorres,
59  .intra_only = h->h.intraonly,
60  .allow_high_precision_mv = h->h.keyframe ? 0 : h->h.highprecisionmvs,
61  .mcomp_filter_type = h->h.filtermode ^ (h->h.filtermode <= 1),
62  .frame_parallel_decoding_mode = h->h.parallelmode,
63  .reset_frame_context = h->h.resetctx,
64  .refresh_frame_context = h->h.refreshctx,
65  .frame_context_idx = h->h.framectxid,
66 
67  .segmentation_enabled = h->h.segmentation.enabled,
68  .segmentation_temporal_update = h->h.segmentation.temporal,
69  .segmentation_update_map = h->h.segmentation.update_map,
70 
71  .last_ref_frame = h->h.refidx[0],
72  .last_ref_frame_sign_bias = h->h.signbias[0],
73  .golden_ref_frame = h->h.refidx[1],
74  .golden_ref_frame_sign_bias = h->h.signbias[1],
75  .alt_ref_frame = h->h.refidx[2],
76  .alt_ref_frame_sign_bias = h->h.signbias[2],
77  .lossless_flag = h->h.lossless,
78  },
79 
80  .filter_level = h->h.filter.level,
81  .sharpness_level = h->h.filter.sharpness,
82  .log2_tile_rows = h->h.tiling.log2_tile_rows,
83  .log2_tile_columns = h->h.tiling.log2_tile_cols,
84 
85  .frame_header_length_in_bytes = h->h.uncompressed_header_size,
86  .first_partition_size = h->h.compressed_header_size,
87 
88  .profile = h->h.profile,
89  .bit_depth = h->h.bpp,
90  };
91 
92  for (i = 0; i < 7; i++)
93  pic_param.mb_segment_tree_probs[i] = h->h.segmentation.prob[i];
94 
95  if (h->h.segmentation.temporal) {
96  for (i = 0; i < 3; i++)
97  pic_param.segment_pred_probs[i] = h->h.segmentation.pred_prob[i];
98  } else {
99  memset(pic_param.segment_pred_probs, 255, sizeof(pic_param.segment_pred_probs));
100  }
101 
102  for (i = 0; i < 8; i++) {
103  if (h->refs[i].f->buf[0])
104  pic_param.reference_frames[i] = ff_vaapi_get_surface_id(h->refs[i].f);
105  else
106  pic_param.reference_frames[i] = VA_INVALID_ID;
107  }
108 
109  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
110  VAPictureParameterBufferType,
111  &pic_param, sizeof(pic_param));
112  if (err < 0) {
113  ff_vaapi_decode_cancel(avctx, pic);
114  return err;
115  }
116 
117  return 0;
118 }
119 
121 {
122  const VP9SharedContext *h = avctx->priv_data;
124 
125  return ff_vaapi_decode_issue(avctx, pic);
126 }
127 
129  const uint8_t *buffer,
130  uint32_t size)
131 {
132  const VP9SharedContext *h = avctx->priv_data;
134  VASliceParameterBufferVP9 slice_param;
135  int err, i;
136 
137  slice_param = (VASliceParameterBufferVP9) {
138  .slice_data_size = size,
139  .slice_data_offset = 0,
140  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
141  };
142 
143  for (i = 0; i < 8; i++) {
144  slice_param.seg_param[i] = (VASegmentParameterVP9) {
145  .segment_flags.fields = {
146  .segment_reference_enabled = h->h.segmentation.feat[i].ref_enabled,
147  .segment_reference = h->h.segmentation.feat[i].ref_val,
148  .segment_reference_skipped = h->h.segmentation.feat[i].skip_enabled,
149  },
150 
151  .luma_dc_quant_scale = h->h.segmentation.feat[i].qmul[0][0],
152  .luma_ac_quant_scale = h->h.segmentation.feat[i].qmul[0][1],
153  .chroma_dc_quant_scale = h->h.segmentation.feat[i].qmul[1][0],
154  .chroma_ac_quant_scale = h->h.segmentation.feat[i].qmul[1][1],
155  };
156 
157  memcpy(slice_param.seg_param[i].filter_level, h->h.segmentation.feat[i].lflvl, sizeof(slice_param.seg_param[i].filter_level));
158  }
159 
160  err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
161  &slice_param, sizeof(slice_param),
162  buffer, size);
163  if (err) {
164  ff_vaapi_decode_cancel(avctx, pic);
165  return err;
166  }
167 
168  return 0;
169 }
170 
172  .name = "vp9_vaapi",
173  .type = AVMEDIA_TYPE_VIDEO,
174  .id = AV_CODEC_ID_VP9,
175  .pix_fmt = AV_PIX_FMT_VAAPI,
176  .start_frame = vaapi_vp9_start_frame,
177  .end_frame = vaapi_vp9_end_frame,
178  .decode_slice = vaapi_vp9_decode_slice,
179  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
182  .frame_params = ff_vaapi_common_frame_params,
183  .priv_data_size = sizeof(VAAPIDecodeContext),
184  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
185 };
ThreadFrame tf
Definition: vp9shared.h:60
struct VP9BitstreamHeader::@197::@199 feat[MAX_SEGMENT]
uint8_t parallelmode
Definition: vp9shared.h:108
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
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:486
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:29
VP9BitstreamHeader h
Definition: vp9shared.h:160
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:35
struct VP9BitstreamHeader::@195 filter
struct VP9BitstreamHeader::@197 segmentation
uint8_t prob[7]
Definition: vp9shared.h:134
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
unsigned log2_tile_rows
Definition: vp9shared.h:151
int uncompressed_header_size
Definition: vp9shared.h:155
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:586
enum FilterMode filtermode
Definition: vp9shared.h:105
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:699
const AVHWAccel ff_vp9_vaapi_hwaccel
Definition: vaapi_vp9.c:171
uint8_t
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:150
VP9Frame frames[3]
Definition: vp9shared.h:166
ptrdiff_t size
Definition: opengl_enc.c:100
unsigned log2_tile_cols
Definition: vp9shared.h:151
uint8_t refidx[3]
Definition: vp9shared.h:111
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
static VASurfaceID vaapi_vp9_surface_id(const VP9Frame *vf)
Definition: vaapi_vp9.c:29
static int vaapi_vp9_end_frame(AVCodecContext *avctx)
Definition: vaapi_vp9.c:120
uint8_t signbias[3]
Definition: vp9shared.h:112
uint8_t refreshctx
Definition: vp9shared.h:107
void * hwaccel_picture_private
Definition: vp9shared.h:67
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3655
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:610
uint8_t keyframe
Definition: vp9shared.h:98
int width
picture width / height.
Definition: avcodec.h:1738
if(ret)
VASurfaceID output_surface
Definition: vaapi_decode.h:45
struct VP9BitstreamHeader::@198 tiling
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:1565
#define CUR_FRAME
Definition: vp9shared.h:163
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:224
static int vaapi_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_vp9.c:128
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwaccel.h:26
void * priv_data
Definition: avcodec.h:1592
uint8_t invisible
Definition: vp9shared.h:99
ThreadFrame refs[8]
Definition: vp9shared.h:162
uint8_t pred_prob[3]
Definition: vp9shared.h:135
uint8_t highprecisionmvs
Definition: vp9shared.h:104
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:58
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:3112
GLuint buffer
Definition: opengl_enc.c:101
#define av_unused
Definition: attributes.h:125
int compressed_header_size
Definition: vp9shared.h:156
static int vaapi_vp9_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_vp9.c:37