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;
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, 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 };
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwaccel.h:26
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:35
VAAPIDecodeContext
Definition: vaapi_decode.h:55
VP9Frame
Definition: vp9shared.h:59
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
vaapi_decode.h
av_unused
#define av_unused
Definition: attributes.h:125
VAAPIDecodePicture
Definition: vaapi_decode.h:44
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:58
vaapi_vp9_end_frame
static int vaapi_vp9_end_frame(AVCodecContext *avctx)
Definition: vaapi_vp9.c:120
ThreadFrame::f
AVFrame * f
Definition: thread.h:35
VP9Frame::tf
ThreadFrame tf
Definition: vp9shared.h:60
AVHWAccel
Definition: avcodec.h:3649
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:29
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:45
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
hwaccel.h
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:610
VP9SharedContext
Definition: vp9shared.h:159
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: avcodec.h:386
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:586
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:699
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:150
if
if(ret)
Definition: filter_design.txt:179
vaapi_vp9_surface_id
static VASurfaceID vaapi_vp9_surface_id(const VP9Frame *vf)
Definition: vaapi_vp9.c:29
size
int size
Definition: twinvq_data.h:11134
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:224
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
Definition: pixfmt.h:122
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3655
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodecContext::height
int height
Definition: avcodec.h:1738
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
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_vp9_vaapi_hwaccel
const AVHWAccel ff_vp9_vaapi_hwaccel
Definition: vaapi_vp9.c:171
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
CUR_FRAME
#define CUR_FRAME
Definition: vp9shared.h:163
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:1738
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
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:3112
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101