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_internal.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;
42  VAAPIDecodePicture *pic = h->frames[CUR_FRAME].hwaccel_picture_private;
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;
123  VAAPIDecodePicture *pic = h->frames[CUR_FRAME].hwaccel_picture_private;
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;
133  VAAPIDecodePicture *pic = h->frames[CUR_FRAME].hwaccel_picture_private;
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, 1, 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  .p.name = "vp9_vaapi",
173  .p.type = AVMEDIA_TYPE_VIDEO,
174  .p.id = AV_CODEC_ID_VP9,
175  .p.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 };
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
VP9Frame
Definition: vp9shared.h:65
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
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
pixdesc.h
vaapi_vp9_end_frame
static int vaapi_vp9_end_frame(AVCodecContext *avctx)
Definition: vaapi_vp9.c:120
ThreadFrame::f
AVFrame * f
Definition: threadframe.h:28
VP9Frame::tf
ThreadFrame tf
Definition: vp9shared.h:66
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
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:40
vp9shared.h
vaapi_vp9_decode_slice
static int vaapi_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_vp9.c:128
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:661
VP9SharedContext
Definition: vp9shared.h:164
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:220
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:637
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:707
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:152
if
if(ret)
Definition: filter_design.txt:179
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
hwaccel_internal.h
vaapi_vp9_surface_id
static VASurfaceID vaapi_vp9_surface_id(const VP9Frame *vf)
Definition: vaapi_vp9.c:29
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
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
vaapi_vp9_start_frame
static int vaapi_vp9_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_vp9.c:37
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
ff_vp9_vaapi_hwaccel
const FFHWAccel ff_vp9_vaapi_hwaccel
Definition: vaapi_vp9.c:171
AVCodecContext::height
int height
Definition: avcodec.h:618
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
CUR_FRAME
#define CUR_FRAME
Definition: vp9shared.h:168
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
h
h
Definition: vp9dsp_template.c:2038
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:664
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89