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 "codec_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  return ff_vaapi_encode_init(avctx);
214 }
215 
216 #define OFFSET(x) offsetof(VAAPIEncodeVP8Context, x)
217 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
221 
222  { "loop_filter_level", "Loop filter level",
223  OFFSET(loop_filter_level), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 63, FLAGS },
224  { "loop_filter_sharpness", "Loop filter sharpness",
225  OFFSET(loop_filter_sharpness), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, 15, FLAGS },
226  { NULL },
227 };
228 
230  { "b", "0" },
231  { "bf", "0" },
232  { "g", "120" },
233  { "qmin", "-1" },
234  { "qmax", "-1" },
235  { NULL },
236 };
237 
239  .class_name = "vp8_vaapi",
240  .item_name = av_default_item_name,
241  .option = vaapi_encode_vp8_options,
242  .version = LIBAVUTIL_VERSION_INT,
243 };
244 
246  .p.name = "vp8_vaapi",
247  .p.long_name = NULL_IF_CONFIG_SMALL("VP8 (VAAPI)"),
248  .p.type = AVMEDIA_TYPE_VIDEO,
249  .p.id = AV_CODEC_ID_VP8,
250  .priv_data_size = sizeof(VAAPIEncodeVP8Context),
253  .close = &ff_vaapi_encode_close,
254  .p.priv_class = &vaapi_encode_vp8_class,
255  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
257  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
258  .defaults = vaapi_encode_vp8_defaults,
259  .p.pix_fmts = (const enum AVPixelFormat[]) {
262  },
263  .hw_configs = ff_vaapi_encode_hw_configs,
264  .p.wrapper_name = "vaapi",
265 };
VAAPIEncodeVP8Context::loop_filter_level
int loop_filter_level
Definition: vaapi_encode_vp8.c:38
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
av_clip
#define av_clip
Definition: common.h:95
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: codec_internal.h:39
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
PICTURE_TYPE_I
@ PICTURE_TYPE_I
Definition: vaapi_encode.h:58
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
AVOption
AVOption.
Definition: opt.h:251
VAAPIEncodePicture::refs
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:118
data
const char data[16]
Definition: mxf.c:143
PICTURE_TYPE_P
@ PICTURE_TYPE_P
Definition: vaapi_encode.h:59
FFCodec
Definition: codec_internal.h:112
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:2739
VAAPIEncodePicture::nb_refs
int nb_refs
Definition: vaapi_encode.h:117
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:694
FFCodecDefault
Definition: codec_internal.h:82
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
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:72
VAAPIEncodeVP8Context::loop_filter_sharpness
int loop_filter_sharpness
Definition: vaapi_encode_vp8.c:39
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:105
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:1548
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:1185
VAAPIEncodeType
Definition: vaapi_encode.h:381
VAAPIEncodeContext
Definition: vaapi_encode.h:177
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
ff_vp8_vaapi_encoder
const FFCodec ff_vp8_vaapi_encoder
Definition: vaapi_encode_vp8.c:245
VAAPIEncodeType::profiles
const VAAPIEncodeProfile * profiles
Definition: vaapi_encode.h:384
vaapi_encode_vp8_init_picture_params
static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode_vp8.c:75
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:269
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
vaapi_encode_vp8_configure
static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx)
Definition: vaapi_encode_vp8.c:162
index
int index
Definition: gxfenc.c:89
vp8.h
vaapi_encode_vp8_options
static const AVOption vaapi_encode_vp8_options[]
Definition: vaapi_encode_vp8.c:218
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:87
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
codec_internal.h
VAAPI_ENCODE_RC_OPTIONS
#define VAAPI_ENCODE_RC_OPTIONS
Definition: vaapi_encode.h:494
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
VAAPI_ENCODE_COMMON_OPTIONS
#define VAAPI_ENCODE_COMMON_OPTIONS
Definition: vaapi_encode.h:467
VAAPIEncodePicture::recon_surface
VASurfaceID recon_surface
Definition: vaapi_encode.h:96
VAAPIEncodePicture::output_buffer
VABufferID output_buffer
Definition: vaapi_encode.h:102
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:269
VAAPIEncodeVP8Context::q_index_i
int q_index_i
Definition: vaapi_encode_vp8.c:42
internal.h
vaapi_encode_vp8_class
static const AVClass vaapi_encode_vp8_class
Definition: vaapi_encode_vp8.c:238
common.h
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
AVCodecContext::height
int height
Definition: avcodec.h:562
avcodec.h
ff_vaapi_encode_hw_configs
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]
Definition: vaapi_encode.c:34
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2537
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:217
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:389
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
OFFSET
#define OFFSET(x)
Definition: vaapi_encode_vp8.c:216
AVCodecContext::i_quant_offset
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:701
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
PICTURE_TYPE_IDR
@ PICTURE_TYPE_IDR
Definition: vaapi_encode.h:57
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
VAAPIEncodeProfile
Definition: vaapi_encode.h:132
vaapi_encode_vp8_defaults
static const FFCodecDefault vaapi_encode_vp8_defaults[]
Definition: vaapi_encode_vp8.c:229