FFmpeg  4.0
vaapi_encode_vp9.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_enc_vp9.h>
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/common.h"
24 #include "libavutil/internal.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixfmt.h"
27 
28 #include "avcodec.h"
29 #include "internal.h"
30 #include "vaapi_encode.h"
31 
32 #define VP9_MAX_QUANT 255
33 
34 
35 typedef struct VAAPIEncodeVP9Context {
36  int q_idx_idr;
37  int q_idx_p;
38  int q_idx_b;
39 
40  // Reference direction for B-like frames:
41  // 0 - most recent P/IDR frame is last.
42  // 1 - most recent P frame is golden.
45 
46 typedef struct VAAPIEncodeVP9Options {
50 
51 
52 #define vseq_var(name) vseq->name, name
53 #define vseq_field(name) vseq->seq_fields.bits.name, name
54 #define vpic_var(name) vpic->name, name
55 #define vpic_field(name) vpic->pic_fields.bits.name, name
56 
57 
59 {
61  VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params;
62  VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params;
63 
64  vseq->max_frame_width = avctx->width;
65  vseq->max_frame_height = avctx->height;
66 
67  vseq->kf_auto = 0;
68 
69  if (!(ctx->va_rc_mode & VA_RC_CQP)) {
70  vseq->bits_per_second = avctx->bit_rate;
71  vseq->intra_period = avctx->gop_size;
72  }
73 
74  vpic->frame_width_src = avctx->width;
75  vpic->frame_height_src = avctx->height;
76  vpic->frame_width_dst = avctx->width;
77  vpic->frame_height_dst = avctx->height;
78 
79  return 0;
80 }
81 
83  VAAPIEncodePicture *pic)
84 {
86  VAEncPictureParameterBufferVP9 *vpic = pic->codec_picture_params;
87  VAAPIEncodeVP9Context *priv = ctx->priv_data;
89  int i;
90 
91  vpic->reconstructed_frame = pic->recon_surface;
92  vpic->coded_buf = pic->output_buffer;
93 
94  switch (pic->type) {
95  case PICTURE_TYPE_IDR:
96  av_assert0(pic->nb_refs == 0);
97  vpic->ref_flags.bits.force_kf = 1;
98  vpic->refresh_frame_flags = 0x01;
99  priv->last_ref_dir = 0;
100  break;
101  case PICTURE_TYPE_P:
102  av_assert0(pic->nb_refs == 1);
103  if (avctx->max_b_frames > 0) {
104  if (priv->last_ref_dir) {
105  vpic->ref_flags.bits.ref_frame_ctrl_l0 = 2;
106  vpic->ref_flags.bits.ref_gf_idx = 1;
107  vpic->ref_flags.bits.ref_gf_sign_bias = 1;
108  vpic->refresh_frame_flags = 0x01;
109  } else {
110  vpic->ref_flags.bits.ref_frame_ctrl_l0 = 1;
111  vpic->ref_flags.bits.ref_last_idx = 0;
112  vpic->ref_flags.bits.ref_last_sign_bias = 1;
113  vpic->refresh_frame_flags = 0x02;
114  }
115  } else {
116  vpic->ref_flags.bits.ref_frame_ctrl_l0 = 1;
117  vpic->ref_flags.bits.ref_last_idx = 0;
118  vpic->ref_flags.bits.ref_last_sign_bias = 1;
119  vpic->refresh_frame_flags = 0x01;
120  }
121  break;
122  case PICTURE_TYPE_B:
123  av_assert0(pic->nb_refs == 2);
124  if (priv->last_ref_dir) {
125  vpic->ref_flags.bits.ref_frame_ctrl_l0 = 1;
126  vpic->ref_flags.bits.ref_frame_ctrl_l1 = 2;
127  vpic->ref_flags.bits.ref_last_idx = 0;
128  vpic->ref_flags.bits.ref_last_sign_bias = 1;
129  vpic->ref_flags.bits.ref_gf_idx = 1;
130  vpic->ref_flags.bits.ref_gf_sign_bias = 0;
131  } else {
132  vpic->ref_flags.bits.ref_frame_ctrl_l0 = 2;
133  vpic->ref_flags.bits.ref_frame_ctrl_l1 = 1;
134  vpic->ref_flags.bits.ref_last_idx = 0;
135  vpic->ref_flags.bits.ref_last_sign_bias = 0;
136  vpic->ref_flags.bits.ref_gf_idx = 1;
137  vpic->ref_flags.bits.ref_gf_sign_bias = 1;
138  }
139  vpic->refresh_frame_flags = 0x00;
140  break;
141  default:
142  av_assert0(0 && "invalid picture type");
143  }
144 
145  for (i = 0; i < FF_ARRAY_ELEMS(vpic->reference_frames); i++)
146  vpic->reference_frames[i] = VA_INVALID_SURFACE;
147  if (pic->type == PICTURE_TYPE_P) {
148  av_assert0(pic->refs[0]);
149  vpic->reference_frames[priv->last_ref_dir] =
150  pic->refs[0]->recon_surface;
151  } else if (pic->type == PICTURE_TYPE_B) {
152  av_assert0(pic->refs[0] && pic->refs[1]);
153  vpic->reference_frames[!priv->last_ref_dir] =
154  pic->refs[0]->recon_surface;
155  vpic->reference_frames[priv->last_ref_dir] =
156  pic->refs[1]->recon_surface;
157  }
158 
159  vpic->pic_flags.bits.frame_type = (pic->type != PICTURE_TYPE_IDR);
160  vpic->pic_flags.bits.show_frame = pic->display_order <= pic->encode_order;
161 
162  if (pic->type == PICTURE_TYPE_IDR)
163  vpic->luma_ac_qindex = priv->q_idx_idr;
164  else if (pic->type == PICTURE_TYPE_P)
165  vpic->luma_ac_qindex = priv->q_idx_p;
166  else
167  vpic->luma_ac_qindex = priv->q_idx_b;
168  vpic->luma_dc_qindex_delta = 0;
169  vpic->chroma_ac_qindex_delta = 0;
170  vpic->chroma_dc_qindex_delta = 0;
171 
172  vpic->filter_level = opt->loop_filter_level;
173  vpic->sharpness_level = opt->loop_filter_sharpness;
174 
175  if (avctx->max_b_frames > 0 && pic->type == PICTURE_TYPE_P)
176  priv->last_ref_dir = !priv->last_ref_dir;
177 
178  return 0;
179 }
180 
182 {
183  VAAPIEncodeContext *ctx = avctx->priv_data;
184  VAAPIEncodeVP9Context *priv = ctx->priv_data;
185 
186  priv->q_idx_p = av_clip(avctx->global_quality, 0, VP9_MAX_QUANT);
187  if (avctx->i_quant_factor > 0.0)
188  priv->q_idx_idr = av_clip((avctx->global_quality *
189  avctx->i_quant_factor +
190  avctx->i_quant_offset) + 0.5,
191  0, VP9_MAX_QUANT);
192  else
193  priv->q_idx_idr = priv->q_idx_p;
194  if (avctx->b_quant_factor > 0.0)
195  priv->q_idx_b = av_clip((avctx->global_quality *
196  avctx->b_quant_factor +
197  avctx->b_quant_offset) + 0.5,
198  0, VP9_MAX_QUANT);
199  else
200  priv->q_idx_b = priv->q_idx_p;
201 
202  return 0;
203 }
204 
207 
208  .priv_data_size = sizeof(VAAPIEncodeVP9Context),
209 
210  .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9),
211  .init_sequence_params = &vaapi_encode_vp9_init_sequence_params,
212 
213  .picture_params_size = sizeof(VAEncPictureParameterBufferVP9),
214  .init_picture_params = &vaapi_encode_vp9_init_picture_params,
215 };
216 
218 {
219  VAAPIEncodeContext *ctx = avctx->priv_data;
220 
222 
223  switch (avctx->profile) {
224  case FF_PROFILE_VP9_0:
225  case FF_PROFILE_UNKNOWN:
226  ctx->va_profile = VAProfileVP9Profile0;
227  ctx->va_rt_format = VA_RT_FORMAT_YUV420;
228  break;
229  case FF_PROFILE_VP9_1:
230  av_log(avctx, AV_LOG_ERROR, "VP9 profile 1 is not "
231  "supported.\n");
232  return AVERROR_PATCHWELCOME;
233  case FF_PROFILE_VP9_2:
234  ctx->va_profile = VAProfileVP9Profile2;
235  ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP;
236  break;
237  case FF_PROFILE_VP9_3:
238  av_log(avctx, AV_LOG_ERROR, "VP9 profile 3 is not "
239  "supported.\n");
240  return AVERROR_PATCHWELCOME;
241  default:
242  av_log(avctx, AV_LOG_ERROR, "Unknown VP9 profile %d.\n",
243  avctx->profile);
244  return AVERROR(EINVAL);
245  }
246  ctx->va_entrypoint = VAEntrypointEncSlice;
247 
248  if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
249  ctx->va_rc_mode = VA_RC_CQP;
250  } else if (avctx->bit_rate > 0) {
251  if (avctx->bit_rate == avctx->rc_max_rate)
252  ctx->va_rc_mode = VA_RC_CBR;
253  else
254  ctx->va_rc_mode = VA_RC_VBR;
255  } else {
256  ctx->va_rc_mode = VA_RC_CQP;
257  }
258 
259  // Packed headers are not currently supported.
260  ctx->va_packed_headers = 0;
261 
262  // Surfaces must be aligned to superblock boundaries.
263  ctx->surface_width = FFALIGN(avctx->width, 64);
264  ctx->surface_height = FFALIGN(avctx->height, 64);
265 
266  return ff_vaapi_encode_init(avctx);
267 }
268 
269 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
270  offsetof(VAAPIEncodeVP9Options, x))
271 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
273  { "loop_filter_level", "Loop filter level",
274  OFFSET(loop_filter_level), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 63, FLAGS },
275  { "loop_filter_sharpness", "Loop filter sharpness",
276  OFFSET(loop_filter_sharpness), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, 15, FLAGS },
277  { NULL },
278 };
279 
281  { "profile", "0" },
282  { "b", "0" },
283  { "bf", "0" },
284  { "g", "250" },
285  { "global_quality", "100" },
286  { NULL },
287 };
288 
290  .class_name = "vp9_vaapi",
291  .item_name = av_default_item_name,
292  .option = vaapi_encode_vp9_options,
293  .version = LIBAVUTIL_VERSION_INT,
294 };
295 
297  .name = "vp9_vaapi",
298  .long_name = NULL_IF_CONFIG_SMALL("VP9 (VAAPI)"),
299  .type = AVMEDIA_TYPE_VIDEO,
300  .id = AV_CODEC_ID_VP9,
301  .priv_data_size = (sizeof(VAAPIEncodeContext) +
302  sizeof(VAAPIEncodeVP9Options)),
304  .encode2 = &ff_vaapi_encode2,
305  .close = &ff_vaapi_encode_close,
306  .priv_class = &vaapi_encode_vp9_class,
307  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
308  .defaults = vaapi_encode_vp9_defaults,
309  .pix_fmts = (const enum AVPixelFormat[]) {
312  },
313  .wrapper_name = "vaapi",
314 };
#define NULL
Definition: coverity.c:32
VAProfile va_profile
Definition: vaapi_encode.h:96
static av_cold int vaapi_encode_vp9_init(AVCodecContext *avctx)
VAEntrypoint va_entrypoint
Definition: vaapi_encode.h:98
AVOption.
Definition: opt.h:246
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1568
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:1777
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: avcodec.h:1056
static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, VAAPIEncodePicture *pic)
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
void * codec_sequence_params
Definition: vaapi_encode.h:168
int profile
profile
Definition: avcodec.h:2843
AVCodec.
Definition: avcodec.h:3408
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:1829
unsigned int va_packed_headers
Definition: vaapi_encode.h:105
#define FF_PROFILE_VP9_0
Definition: avcodec.h:2926
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:984
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define av_cold
Definition: attributes.h:82
AVOptions.
float b_quant_factor
qscale factor between IP and B-frames If > 0 then the last P-frame quantizer will be used (q= lastp_q...
Definition: avcodec.h:1786
#define VP9_MAX_QUANT
#define FLAGS
VASurfaceID recon_surface
Definition: vaapi_encode.h:71
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
#define OFFSET(x)
unsigned int va_rc_mode
Definition: vaapi_encode.h:102
int(* configure)(AVCodecContext *avctx)
Definition: vaapi_encode.h:223
static const VAAPIEncodeType vaapi_encode_type_vp9
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
#define FF_PROFILE_VP9_3
Definition: avcodec.h:2929
static const AVCodecDefault vaapi_encode_vp9_defaults[]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1598
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: avcodec.h:3415
float i_quant_factor
qscale factor between P- and I-frames If > 0 then the last P-frame quantizer will be used (q = lastp_...
Definition: avcodec.h:1822
static const AVCodecDefault defaults[]
Definition: amfenc_h264.c:361
void * codec_picture_params
Definition: vaapi_encode.h:80
#define FF_PROFILE_VP9_2
Definition: avcodec.h:2928
common internal API header
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:833
int width
picture width / height.
Definition: avcodec.h:1690
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2844
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
AVFormatContext * ctx
Definition: movenc.c:48
unsigned int va_rt_format
Definition: vaapi_encode.h:100
void * codec_picture_params
Definition: vaapi_encode.h:172
if(ret< 0)
Definition: vf_mcdeint.c:279
#define FF_ARRAY_ELEMS(a)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:83
#define FF_PROFILE_VP9_1
Definition: avcodec.h:2927
const struct VAAPIEncodeType * codec
Definition: vaapi_encode.h:93
Libavcodec external API header.
main external API structure.
Definition: avcodec.h:1518
Describe the class of an AVClass context structure.
Definition: log.h:67
float b_quant_offset
qscale offset between IP and B-frames
Definition: avcodec.h:1799
static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx)
AVCodec ff_vp9_vaapi_encoder
static const AVClass vaapi_encode_vp9_class
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:266
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1584
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1712
common internal api header.
common internal and external API header
static const AVOption vaapi_encode_vp9_options[]
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet)
Definition: vaapi_encode.c:853
void * priv_data
Definition: avcodec.h:1545
pixel format definitions
static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)
VABufferID output_buffer
Definition: vaapi_encode.h:77
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:2391