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] == 0 && pic->nb_refs[1] == 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][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  CODEC_LONG_NAME("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_NOT_INIT_THREADSAFE |
259  .defaults = vaapi_encode_vp8_defaults,
260  .p.pix_fmts = (const enum AVPixelFormat[]) {
263  },
264  .hw_configs = ff_vaapi_encode_hw_configs,
265  .p.wrapper_name = "vaapi",
266 };
VAAPIEncodeVP8Context::loop_filter_level
int loop_filter_level
Definition: vaapi_encode_vp8.c:38
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
av_clip
#define av_clip
Definition: common.h:98
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:42
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
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:145
VAAPIEncodeVP8Context::common
VAAPIEncodeContext common
Definition: vaapi_encode_vp8.c:35
AVOption
AVOption.
Definition: opt.h:346
data
const char data[16]
Definition: mxf.c:148
FF_CODEC_CAP_NOT_INIT_THREADSAFE
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
Definition: codec_internal.h:34
FFCodec
Definition: codec_internal.h:127
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:2982
PICTURE_TYPE_IDR
@ PICTURE_TYPE_IDR
Definition: vaapi_encode.h:58
VAAPIEncodePicture::refs
struct VAAPIEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:125
VAAPIEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: vaapi_encode.h:124
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:820
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
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:73
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 const uint8_t quant[64]
Definition: vmixdec.c:71
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
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
VAAPIEncodePicture::codec_picture_params
void * codec_picture_params
Definition: vaapi_encode.h:111
vaapi_encode_vp8_profiles
static const VAAPIEncodeProfile vaapi_encode_vp8_profiles[]
Definition: vaapi_encode_vp8.c:181
PICTURE_TYPE_I
@ PICTURE_TYPE_I
Definition: vaapi_encode.h:59
VP8_MAX_QUANT
#define VP8_MAX_QUANT
Definition: vp8.h:40
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition: codec.h:159
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
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:1396
VAAPIEncodeType
Definition: vaapi_encode.h:419
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
VAAPIEncodeContext
Definition: vaapi_encode.h:195
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:422
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:302
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
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
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:92
codec_internal.h
VAAPI_ENCODE_RC_OPTIONS
#define VAAPI_ENCODE_RC_OPTIONS
Definition: vaapi_encode.h:532
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:505
VAAPIEncodePicture::recon_surface
VASurfaceID recon_surface
Definition: vaapi_encode.h:101
VAAPIEncodePicture::output_buffer
VABufferID output_buffer
Definition: vaapi_encode.h:108
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
VAAPIEncodeVP8Context
Definition: vaapi_encode_vp8.c:34
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
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:194
AVCodecContext::height
int height
Definition: avcodec.h:618
avcodec.h
ff_vaapi_encode_hw_configs
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]
Definition: vaapi_encode.c:35
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2773
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:445
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
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:827
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:76
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
PICTURE_TYPE_P
@ PICTURE_TYPE_P
Definition: vaapi_encode.h:60
VAAPIEncodeProfile
Definition: vaapi_encode.h:150
vaapi_encode_vp8_defaults
static const FFCodecDefault vaapi_encode_vp8_defaults[]
Definition: vaapi_encode_vp8.c:229