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 
176  ctx->roi_quant_range = VP8_MAX_QUANT;
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 
206  ctx->codec = &vaapi_encode_type_vp8;
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  .receive_packet = &ff_vaapi_encode_receive_packet,
256  .close = &ff_vaapi_encode_close,
257  .priv_class = &vaapi_encode_vp8_class,
258  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
260  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
262  .pix_fmts = (const enum AVPixelFormat[]) {
265  },
266  .hw_configs = ff_vaapi_encode_hw_configs,
267  .wrapper_name = "vaapi",
268 };
VAAPIEncodeVP8Context::loop_filter_level
int loop_filter_level
Definition: vaapi_encode_vp8.c:38
AVCodec
AVCodec.
Definition: codec.h:202
PICTURE_TYPE_IDR
@ PICTURE_TYPE_IDR
Definition: vaapi_encode.h:55
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
av_clip
#define av_clip
Definition: common.h:96
AVERROR
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
opt.h
vaapi_encode_vp8_defaults
static const AVCodecDefault vaapi_encode_vp8_defaults[]
Definition: vaapi_encode_vp8.c:232
ff_vp8_vaapi_encoder
const AVCodec ff_vp8_vaapi_encoder
Definition: vaapi_encode_vp8.c:248
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_CODEC_CAP_HARDWARE
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: codec.h:162
VAAPIEncodeVP8Context::common
VAAPIEncodeContext common
Definition: vaapi_encode_vp8.c:35
index
fg index
Definition: ffmpeg_filter.c:167
internal.h
AVOption
AVOption.
Definition: opt.h:247
VAAPIEncodePicture::refs
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:116
data
const char data[16]
Definition: mxf.c:143
VAAPIEncodeVP8Context::q_index_p
int q_index_p
Definition: vaapi_encode_vp8.c:43
ff_vaapi_encode_close
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
Definition: vaapi_encode.c:2531
VAAPIEncodePicture::nb_refs
int nb_refs
Definition: vaapi_encode.h:115
init
static int init
Definition: av_tx.c:47
AVCodecContext::i_quant_factor
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:688
vaapi_encode.h
vaapi_encode_vp8_init
static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx)
Definition: vaapi_encode_vp8.c:202
VAAPIEncodePicture
Definition: vaapi_encode.h:70
VAAPIEncodeVP8Context::loop_filter_sharpness
int loop_filter_sharpness
Definition: vaapi_encode_vp8.c:39
defaults
static const AVCodecDefault defaults[]
Definition: amfenc_h264.c:361
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
quant
static int quant(float coef, const float Q, const float rounding)
Quantize one coefficient.
Definition: aacenc_utils.h:59
avassert.h
vaapi_encode_type_vp8
static const VAAPIEncodeType vaapi_encode_type_vp8
Definition: vaapi_encode_vp8.c:186
av_cold
#define av_cold
Definition: attributes.h:90
VAAPIEncodePicture::codec_picture_params
void * codec_picture_params
Definition: vaapi_encode.h:103
vaapi_encode_vp8_profiles
static const VAAPIEncodeProfile vaapi_encode_vp8_profiles[]
Definition: vaapi_encode_vp8.c:181
VP8_MAX_QUANT
#define VP8_MAX_QUANT
Definition: vp8.h:40
FF_PROFILE_UNKNOWN
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1526
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:296
vaapi_encode_vp8_init_sequence_params
static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
Definition: vaapi_encode_vp8.c:53
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_vaapi_encode_receive_packet
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: vaapi_encode.c:1155
VAAPIEncodeType
Definition: vaapi_encode.h:366
VAAPIEncodeContext
Definition: vaapi_encode.h:175
AVCodecDefault
Definition: internal.h:215
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
VAAPIEncodeType::profiles
const VAAPIEncodeProfile * profiles
Definition: vaapi_encode.h:369
vaapi_encode_vp8_init_picture_params
static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode_vp8.c:75
PICTURE_TYPE_P
@ PICTURE_TYPE_P
Definition: vaapi_encode.h:57
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
vaapi_encode_vp8_configure
static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx)
Definition: vaapi_encode_vp8.c:162
vp8.h
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
vaapi_encode_vp8_options
static const AVOption vaapi_encode_vp8_options[]
Definition: vaapi_encode_vp8.c:221
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
VAAPIEncodePicture::type
int type
Definition: vaapi_encode.h:85
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
VAAPI_ENCODE_RC_OPTIONS
#define VAAPI_ENCODE_RC_OPTIONS
Definition: vaapi_encode.h:463
PICTURE_TYPE_I
@ PICTURE_TYPE_I
Definition: vaapi_encode.h:56
VAAPI_ENCODE_COMMON_OPTIONS
#define VAAPI_ENCODE_COMMON_OPTIONS
Definition: vaapi_encode.h:445
VAAPIEncodePicture::recon_surface
VASurfaceID recon_surface
Definition: vaapi_encode.h:94
VAAPIEncodePicture::output_buffer
VABufferID output_buffer
Definition: vaapi_encode.h:100
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:119
VAAPIEncodeVP8Context
Definition: vaapi_encode_vp8.c:34
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
VAAPIEncodeVP8Context::q_index_i
int q_index_i
Definition: vaapi_encode_vp8.c:42
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:50
internal.h
vaapi_encode_vp8_class
static const AVClass vaapi_encode_vp8_class
Definition: vaapi_encode_vp8.c:241
common.h
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
AVCodecContext::height
int height
Definition: avcodec.h:556
avcodec.h
ff_vaapi_encode_hw_configs
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]
Definition: vaapi_encode.c:32
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2362
pixfmt.h
AVClass::class_name
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:71
FLAGS
#define FLAGS
Definition: vaapi_encode_vp8.c:220
vaapi_encode_vp8_write_quant_table
static int vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode_vp8.c:129
AVCodecContext
main external API structure.
Definition: avcodec.h:383
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
OFFSET
#define OFFSET(x)
Definition: vaapi_encode_vp8.c:219
AVCodecContext::i_quant_offset
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:695
AV_CODEC_CAP_DELAY
#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: codec.h:82
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
VAAPIEncodeProfile
Definition: vaapi_encode.h:130