FFmpeg
vaapi_encode_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_enc_vp8.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 #include "vp8.h"
32 
33 
34 typedef struct VAAPIEncodeVP8Context {
36 
37  // User options.
40 
41  // Derived settings.
42  int q_index_i;
43  int q_index_p;
45 
46 
47 #define vseq_var(name) vseq->name, name
48 #define vseq_field(name) vseq->seq_fields.bits.name, name
49 #define vpic_var(name) vpic->name, name
50 #define vpic_field(name) vpic->pic_fields.bits.name, name
51 
52 
54 {
56  VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params;
57 
58  vseq->frame_width = avctx->width;
59  vseq->frame_height = avctx->height;
60 
61  vseq->frame_width_scale = 0;
62  vseq->frame_height_scale = 0;
63 
64  vseq->error_resilient = 0;
65  vseq->kf_auto = 0;
66 
67  if (!(ctx->va_rc_mode & VA_RC_CQP)) {
68  vseq->bits_per_second = ctx->va_bit_rate;
69  vseq->intra_period = ctx->gop_size;
70  }
71 
72  return 0;
73 }
74 
76  VAAPIEncodePicture *pic)
77 {
78  VAAPIEncodeVP8Context *priv = avctx->priv_data;
79  VAEncPictureParameterBufferVP8 *vpic = pic->codec_picture_params;
80  int i;
81 
82  vpic->reconstructed_frame = pic->recon_surface;
83 
84  vpic->coded_buf = pic->output_buffer;
85 
86  switch (pic->type) {
87  case PICTURE_TYPE_IDR:
88  case PICTURE_TYPE_I:
89  av_assert0(pic->nb_refs == 0);
90  vpic->ref_flags.bits.force_kf = 1;
91  vpic->ref_last_frame =
92  vpic->ref_gf_frame =
93  vpic->ref_arf_frame =
94  VA_INVALID_SURFACE;
95  break;
96  case PICTURE_TYPE_P:
97  av_assert0(pic->nb_refs == 1);
98  vpic->ref_flags.bits.no_ref_last = 0;
99  vpic->ref_flags.bits.no_ref_gf = 1;
100  vpic->ref_flags.bits.no_ref_arf = 1;
101  vpic->ref_last_frame =
102  vpic->ref_gf_frame =
103  vpic->ref_arf_frame =
104  pic->refs[0]->recon_surface;
105  break;
106  default:
107  av_assert0(0 && "invalid picture type");
108  }
109 
110  vpic->pic_flags.bits.frame_type = (pic->type != PICTURE_TYPE_IDR);
111  vpic->pic_flags.bits.show_frame = 1;
112 
113  vpic->pic_flags.bits.refresh_last = 1;
114  vpic->pic_flags.bits.refresh_golden_frame = 1;
115  vpic->pic_flags.bits.refresh_alternate_frame = 1;
116 
117  vpic->pic_flags.bits.version = 0;
118  vpic->pic_flags.bits.loop_filter_type = 0;
119  for (i = 0; i < 4; i++)
120  vpic->loop_filter_level[i] = priv->loop_filter_level;
121  vpic->sharpness_level = priv->loop_filter_sharpness;
122 
123  vpic->clamp_qindex_low = 0;
124  vpic->clamp_qindex_high = 127;
125 
126  return 0;
127 }
128 
130  VAAPIEncodePicture *pic,
131  int index, int *type,
132  char *data, size_t *data_len)
133 {
134  VAAPIEncodeVP8Context *priv = avctx->priv_data;
135  VAQMatrixBufferVP8 quant;
136  int i, q;
137 
138  if (index > 0)
139  return AVERROR_EOF;
140 
141  if (*data_len < sizeof(quant))
142  return AVERROR(EINVAL);
143  *type = VAQMatrixBufferType;
144  *data_len = sizeof(quant);
145 
146  memset(&quant, 0, sizeof(quant));
147 
148  if (pic->type == PICTURE_TYPE_P)
149  q = priv->q_index_p;
150  else
151  q = priv->q_index_i;
152 
153  for (i = 0; i < 4; i++)
154  quant.quantization_index[i] = q;
155  for (i = 0; i < 5; i++)
156  quant.quantization_index_delta[i] = 0;
157 
158  memcpy(data, &quant, sizeof(quant));
159  return 0;
160 }
161 
163 {
164  VAAPIEncodeContext *ctx = avctx->priv_data;
165  VAAPIEncodeVP8Context *priv = avctx->priv_data;
166 
167  priv->q_index_p = av_clip(ctx->rc_quality, 0, VP8_MAX_QUANT);
168  if (avctx->i_quant_factor > 0.0)
169  priv->q_index_i =
170  av_clip((avctx->i_quant_factor * priv->q_index_p +
171  avctx->i_quant_offset) + 0.5,
172  0, VP8_MAX_QUANT);
173  else
174  priv->q_index_i = priv->q_index_p;
175 
177 
178  return 0;
179 }
180 
182  { 0 /* VP8 has no profiles */, 8, 3, 1, 1, VAProfileVP8Version0_3 },
184 };
185 
188 
189  .configure = &vaapi_encode_vp8_configure,
190 
191  .default_quality = 40,
192 
193  .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP8),
194  .init_sequence_params = &vaapi_encode_vp8_init_sequence_params,
195 
196  .picture_params_size = sizeof(VAEncPictureParameterBufferVP8),
197  .init_picture_params = &vaapi_encode_vp8_init_picture_params,
198 
199  .write_extra_buffer = &vaapi_encode_vp8_write_quant_table,
200 };
201 
203 {
204  VAAPIEncodeContext *ctx = avctx->priv_data;
205 
207 
208  // No packed headers are currently desired. VP8 has no metadata
209  // which would be useful to write, and no existing driver supports
210  // adding them anyway.
211  ctx->desired_packed_headers = 0;
212 
213  ctx->surface_width = FFALIGN(avctx->width, 16);
214  ctx->surface_height = FFALIGN(avctx->height, 16);
215 
216  return ff_vaapi_encode_init(avctx);
217 }
218 
219 #define OFFSET(x) offsetof(VAAPIEncodeVP8Context, x)
220 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
224 
225  { "loop_filter_level", "Loop filter level",
226  OFFSET(loop_filter_level), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 63, FLAGS },
227  { "loop_filter_sharpness", "Loop filter sharpness",
228  OFFSET(loop_filter_sharpness), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, 15, FLAGS },
229  { NULL },
230 };
231 
233  { "b", "0" },
234  { "bf", "0" },
235  { "g", "120" },
236  { "qmin", "-1" },
237  { "qmax", "-1" },
238  { NULL },
239 };
240 
242  .class_name = "vp8_vaapi",
243  .item_name = av_default_item_name,
244  .option = vaapi_encode_vp8_options,
245  .version = LIBAVUTIL_VERSION_INT,
246 };
247 
249  .name = "vp8_vaapi",
250  .long_name = NULL_IF_CONFIG_SMALL("VP8 (VAAPI)"),
251  .type = AVMEDIA_TYPE_VIDEO,
252  .id = AV_CODEC_ID_VP8,
253  .priv_data_size = sizeof(VAAPIEncodeVP8Context),
255  .send_frame = &ff_vaapi_encode_send_frame,
256  .receive_packet = &ff_vaapi_encode_receive_packet,
257  .close = &ff_vaapi_encode_close,
258  .priv_class = &vaapi_encode_vp8_class,
259  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
260  .defaults = vaapi_encode_vp8_defaults,
261  .pix_fmts = (const enum AVPixelFormat[]) {
264  },
265  .wrapper_name = "vaapi",
266 };
#define NULL
Definition: coverity.c:32
static const AVCodecDefault vaapi_encode_vp8_defaults[]
#define VP8_MAX_QUANT
Definition: vp8.h:39
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static const VAAPIEncodeProfile vaapi_encode_vp8_profiles[]
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: avcodec.h:1081
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
VAAPIEncodeContext common
GLint GLenum type
Definition: opengl_enc.c:104
static int vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
void * codec_sequence_params
Definition: vaapi_encode.h:268
AVCodec.
Definition: avcodec.h:3492
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:1880
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:1009
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame)
#define av_cold
Definition: attributes.h:82
AVOptions.
AVCodec ff_vp8_vaapi_encoder
#define AVERROR_EOF
End of file.
Definition: error.h:55
VASurfaceID recon_surface
Definition: vaapi_encode.h:88
#define FFALIGN(x, a)
Definition: macros.h:48
unsigned int va_rc_mode
Definition: vaapi_encode.h:224
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
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:1873
static const AVCodecDefault defaults[]
Definition: amfenc_h264.c:361
unsigned int va_bit_rate
Definition: vaapi_encode.h:226
void * codec_picture_params
Definition: vaapi_encode.h:97
static const AVClass vaapi_encode_vp8_class
common internal API header
int width
picture width / height.
Definition: avcodec.h:1741
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2902
const VAAPIEncodeProfile * profiles
Definition: vaapi_encode.h:349
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
AVFormatContext * ctx
Definition: movenc.c:48
static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx)
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:110
const struct VAAPIEncodeType * codec
Definition: vaapi_encode.h:173
Libavcodec external API header.
#define VAAPI_ENCODE_RC_OPTIONS
Definition: vaapi_encode.h:444
main external API structure.
Definition: avcodec.h:1568
Describe the class of an AVClass context structure.
Definition: log.h:67
int index
Definition: gxfenc.c:89
#define OFFSET(x)
static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
#define FLAGS
const uint8_t * quant
#define VAAPI_ENCODE_COMMON_OPTIONS
Definition: vaapi_encode.h:426
static const AVOption vaapi_encode_vp8_options[]
common internal api header.
common internal and external API header
void * priv_data
Definition: avcodec.h:1595
pixel format definitions
unsigned int desired_packed_headers
Definition: vaapi_encode.h:195
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
static const VAAPIEncodeType vaapi_encode_type_vp8
VABufferID output_buffer
Definition: vaapi_encode.h:94
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
for(j=16;j >0;--j)
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx)