FFmpeg
qsvenc_hevc.c
Go to the documentation of this file.
1 /*
2  * Intel MediaSDK QSV based HEVC encoder
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 
22 #include <stdint.h>
23 #include <sys/types.h>
24 
25 #include <mfx/mfxvideo.h>
26 
27 #include "libavutil/common.h"
28 #include "libavutil/opt.h"
29 
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "get_bits.h"
33 #include "hevc.h"
34 #include "hevcdec.h"
35 #include "h2645_parse.h"
36 #include "internal.h"
37 #include "qsv.h"
38 #include "qsv_internal.h"
39 #include "qsvenc.h"
40 
41 enum LoadPlugin {
45 };
46 
47 typedef struct QSVHEVCEncContext {
48  AVClass *class;
52 
54 {
55  GetByteContext gbc;
56  PutByteContext pbc;
57 
58  GetBitContext gb;
59  H2645RBSP sps_rbsp = { NULL };
60  H2645NAL sps_nal = { NULL };
61  HEVCSPS sps = { 0 };
62  HEVCVPS vps = { 0 };
63  uint8_t vps_buf[128], vps_rbsp_buf[128];
64  uint8_t *new_extradata;
65  unsigned int sps_id;
66  int ret, i, type, vps_size;
67 
68  if (!avctx->extradata_size) {
69  av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx\n");
70  return AVERROR_UNKNOWN;
71  }
72 
74  if (!sps_rbsp.rbsp_buffer)
75  return AVERROR(ENOMEM);
76 
77  /* parse the SPS */
78  ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_rbsp, &sps_nal, 1);
79  if (ret < 0) {
80  av_log(avctx, AV_LOG_ERROR, "Error unescaping the SPS buffer\n");
81  return ret;
82  }
83 
84  ret = init_get_bits8(&gb, sps_nal.data, sps_nal.size);
85  if (ret < 0) {
86  av_freep(&sps_rbsp.rbsp_buffer);
87  return ret;
88  }
89 
90  get_bits(&gb, 1);
91  type = get_bits(&gb, 6);
92  if (type != HEVC_NAL_SPS) {
93  av_log(avctx, AV_LOG_ERROR, "Unexpected NAL type in the extradata: %d\n",
94  type);
95  av_freep(&sps_rbsp.rbsp_buffer);
96  return AVERROR_INVALIDDATA;
97  }
98  get_bits(&gb, 9);
99 
100  ret = ff_hevc_parse_sps(&sps, &gb, &sps_id, 0, NULL, avctx);
101  av_freep(&sps_rbsp.rbsp_buffer);
102  if (ret < 0) {
103  av_log(avctx, AV_LOG_ERROR, "Error parsing the SPS\n");
104  return ret;
105  }
106 
107  /* generate the VPS */
108  vps.vps_max_layers = 1;
111  memcpy(&vps.ptl, &sps.ptl, sizeof(vps.ptl));
113  for (i = 0; i < HEVC_MAX_SUB_LAYERS; i++) {
117  }
118 
119  vps.vps_num_layer_sets = 1;
125  vps.vps_num_hrd_parameters = 0;
126 
127  /* generate the encoded RBSP form of the VPS */
128  ret = ff_hevc_encode_nal_vps(&vps, sps.vps_id, vps_rbsp_buf, sizeof(vps_rbsp_buf));
129  if (ret < 0) {
130  av_log(avctx, AV_LOG_ERROR, "Error writing the VPS\n");
131  return ret;
132  }
133 
134  /* escape and add the startcode */
135  bytestream2_init(&gbc, vps_rbsp_buf, ret);
136  bytestream2_init_writer(&pbc, vps_buf, sizeof(vps_buf));
137 
138  bytestream2_put_be32(&pbc, 1); // startcode
139  bytestream2_put_byte(&pbc, HEVC_NAL_VPS << 1); // NAL
140  bytestream2_put_byte(&pbc, 1); // header
141 
142  while (bytestream2_get_bytes_left(&gbc)) {
143  if (bytestream2_get_bytes_left(&gbc) >= 3 && bytestream2_peek_be24(&gbc) <= 3) {
144  bytestream2_put_be24(&pbc, 3);
145  bytestream2_skip(&gbc, 2);
146  } else
147  bytestream2_put_byte(&pbc, bytestream2_get_byte(&gbc));
148  }
149 
150  vps_size = bytestream2_tell_p(&pbc);
151  new_extradata = av_mallocz(vps_size + avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
152  if (!new_extradata)
153  return AVERROR(ENOMEM);
154  memcpy(new_extradata, vps_buf, vps_size);
155  memcpy(new_extradata + vps_size, avctx->extradata, avctx->extradata_size);
156 
157  av_freep(&avctx->extradata);
158  avctx->extradata = new_extradata;
159  avctx->extradata_size += vps_size;
160 
161  return 0;
162 }
163 
165 {
166  QSVHEVCEncContext *q = avctx->priv_data;
167  int ret;
168 
169  if (q->load_plugin != LOAD_PLUGIN_NONE) {
170  static const char * const uid_hevcenc_sw = "2fca99749fdb49aeb121a5b63ef568f7";
171  static const char * const uid_hevcenc_hw = "6fadc791a0c2eb479ab6dcd5ea9da347";
172 
173  if (q->qsv.load_plugins[0]) {
174  av_log(avctx, AV_LOG_WARNING,
175  "load_plugins is not empty, but load_plugin is not set to 'none'."
176  "The load_plugin value will be ignored.\n");
177  } else {
179 
181  q->qsv.load_plugins = av_strdup(uid_hevcenc_sw);
182  else
183  q->qsv.load_plugins = av_strdup(uid_hevcenc_hw);
184 
185  if (!q->qsv.load_plugins)
186  return AVERROR(ENOMEM);
187  }
188  }
189 
190  // HEVC and H264 meaning of the value is shifted by 1, make it consistent
191  q->qsv.idr_interval++;
192 
193  ret = ff_qsv_enc_init(avctx, &q->qsv);
194  if (ret < 0)
195  return ret;
196 
197  if (!q->qsv.hevc_vps) {
198  ret = generate_fake_vps(&q->qsv, avctx);
199  if (ret < 0) {
200  ff_qsv_enc_close(avctx, &q->qsv);
201  return ret;
202  }
203  }
204 
205  return 0;
206 }
207 
209  const AVFrame *frame, int *got_packet)
210 {
211  QSVHEVCEncContext *q = avctx->priv_data;
212 
213  return ff_qsv_encode(avctx, &q->qsv, pkt, frame, got_packet);
214 }
215 
217 {
218  QSVHEVCEncContext *q = avctx->priv_data;
219 
220  return ff_qsv_enc_close(avctx, &q->qsv);
221 }
222 
223 #define OFFSET(x) offsetof(QSVHEVCEncContext, x)
224 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
225 static const AVOption options[] = {
227 
228  { "idr_interval", "Distance (in I-frames) between IDR frames", OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, VE, "idr_interval" },
229  { "begin_only", "Output an IDR-frame only at the beginning of the stream", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "idr_interval" },
230  { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VE, "load_plugin" },
231  { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VE, "load_plugin" },
232  { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VE, "load_plugin" },
233  { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VE, "load_plugin" },
234 
235  { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
236  OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VE },
237 
238  { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
239  { "unknown", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" },
240  { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
241  { "main10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN10 }, INT_MIN, INT_MAX, VE, "profile" },
242  { "mainsp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAINSP }, INT_MIN, INT_MAX, VE, "profile" },
243 
244  { "gpb", "1: GPB (generalized P/B frame); 0: regular P frame", OFFSET(qsv.gpb), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE},
245 
246  { NULL },
247 };
248 
249 static const AVClass class = {
250  .class_name = "hevc_qsv encoder",
251  .item_name = av_default_item_name,
252  .option = options,
254 };
255 
257  { "b", "1M" },
258  { "refs", "0" },
259  // same as the x264 default
260  { "g", "248" },
261  { "bf", "8" },
262  { "trellis", "-1" },
263  { "flags", "+cgop" },
264 #if FF_API_PRIVATE_OPT
265  { "b_strategy", "-1" },
266 #endif
267  { NULL },
268 };
269 
271  .name = "hevc_qsv",
272  .long_name = NULL_IF_CONFIG_SMALL("HEVC (Intel Quick Sync Video acceleration)"),
273  .priv_data_size = sizeof(QSVHEVCEncContext),
275  .id = AV_CODEC_ID_HEVC,
276  .init = qsv_enc_init,
277  .encode2 = qsv_enc_frame,
278  .close = qsv_enc_close,
279  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID,
280  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
283  AV_PIX_FMT_NONE },
284  .priv_class = &class,
285  .defaults = qsv_enc_defaults,
286  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
287  .wrapper_name = "qsv",
288 };
#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:48
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
AVCodec ff_hevc_qsv_encoder
Definition: qsvenc_hevc.c:270
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
int size
Definition: h2645_parse.h:35
int vui_num_ticks_poc_diff_one_minus1
Definition: hevc_ps.h:161
int max_dec_pic_buffering
Definition: hevc_ps.h:244
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int vps_num_ticks_poc_diff_one
vps_num_ticks_poc_diff_one_minus1 + 1
Definition: hevc_ps.h:211
int hevc_vps
Definition: qsvenc.h:146
unsigned int vps_max_latency_increase[HEVC_MAX_SUB_LAYERS]
Definition: hevc_ps.h:204
VUI vui
Definition: hevc_ps.h:250
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:143
uint32_t vui_time_scale
Definition: hevc_ps.h:159
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, uint8_t *buf, int buf_size)
Definition: hevc_ps_enc.c:66
static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx)
Definition: qsvenc_hevc.c:53
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
unsigned int vps_max_dec_pic_buffering[HEVC_MAX_SUB_LAYERS]
Definition: hevc_ps.h:202
GLint GLenum type
Definition: opengl_enc.c:104
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition: utils.c:70
int max_latency_increase
Definition: hevc_ps.h:246
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3492
static int qsv_enc_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: qsvenc_hevc.c:208
#define AV_PIX_FMT_P010
Definition: pixfmt.h:436
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
int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: qsvenc.c:1474
uint8_t
#define av_cold
Definition: attributes.h:82
AVOptions.
uint8_t vps_timing_info_present_flag
Definition: hevc_ps.h:207
int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx)
Parse the SPS from the bitstream into the provided HEVCSPS struct.
Definition: hevc_ps.c:870
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1669
int vps_max_sub_layers
vps_max_temporal_layers_minus1 + 1
Definition: hevc_ps.h:198
#define OFFSET(x)
Definition: qsvenc_hevc.c:223
#define QSV_COMMON_OPTS
Definition: qsvenc.h:75
bitstream reader API header.
int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
Definition: qsvenc.c:1566
#define av_log(a,...)
QSVEncContext qsv
Definition: qsvenc_hevc.c:49
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int vps_max_layers
Definition: hevc_ps.h:197
uint8_t temporal_id_nesting_flag
Definition: hevc_ps.h:248
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
int vui_timing_info_present_flag
Definition: hevc_ps.h:157
char * load_plugins
Definition: qsvenc.h:191
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
struct HEVCSPS::@94 temporal_layer[HEVC_MAX_SUB_LAYERS]
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
int vui_poc_proportional_to_timing_flag
Definition: hevc_ps.h:160
uint8_t vps_temporal_id_nesting_flag
Definition: hevc_ps.h:196
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:193
uint32_t vps_num_units_in_tick
Definition: hevc_ps.h:208
int vps_num_layer_sets
vps_num_layer_sets_minus1 + 1
Definition: hevc_ps.h:206
int idr_interval
Definition: qsvenc.h:150
static const AVCodecDefault qsv_enc_defaults[]
Definition: qsvenc_hevc.c:256
uint8_t vps_poc_proportional_to_timing_flag
Definition: hevc_ps.h:210
unsigned int vps_num_reorder_pics[HEVC_MAX_SUB_LAYERS]
Definition: hevc_ps.h:203
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
unsigned vps_id
Definition: hevc_ps.h:226
PTL ptl
Definition: hevc_ps.h:200
uint32_t vps_time_scale
Definition: hevc_ps.h:209
static av_cold int qsv_enc_close(AVCodecContext *avctx)
Definition: qsvenc_hevc.c:216
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
Libavcodec external API header.
PTL ptl
Definition: hevc_ps.h:251
int max_sub_layers
Definition: hevc_ps.h:242
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
main external API structure.
Definition: avcodec.h:1568
const uint8_t * data
Definition: h2645_parse.h:36
int profile
Definition: qsvenc.h:151
uint32_t vui_num_units_in_tick
Definition: hevc_ps.h:158
int extradata_size
Definition: avcodec.h:1670
#define AV_CODEC_CAP_HYBRID
Codec is potentially backed by a hardware implementation, but not necessarily.
Definition: avcodec.h:1088
int rbsp_buffer_alloc_size
Definition: h2645_parse.h:71
Describe the class of an AVClass context structure.
Definition: log.h:67
int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
Definition: qsvenc.c:1054
int vps_num_hrd_parameters
Definition: hevc_ps.h:212
uint8_t * rbsp_buffer
Definition: h2645_parse.h:69
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
static int FUNC() vps(CodedBitstreamContext *ctx, RWContext *rw, H265RawVPS *current)
common internal api header.
common internal and external API header
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:793
void * priv_data
Definition: avcodec.h:1595
static av_cold int qsv_enc_init(AVCodecContext *avctx)
Definition: qsvenc_hevc.c:164
#define VE
Definition: qsvenc_hevc.c:224
#define av_freep(p)
int num_reorder_pics
Definition: hevc_ps.h:245
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
int ff_h2645_extract_rbsp(const uint8_t *src, int length, H2645RBSP *rbsp, H2645NAL *nal, int small_padding)
Extract the raw (unescaped) bitstream.
Definition: h2645_parse.c:34
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1457
LoadPlugin
Definition: qsvdec_h2645.c:40
int vps_sub_layer_ordering_info_present_flag
Definition: hevc_ps.h:201
static const AVOption options[]
Definition: qsvenc_hevc.c:225