FFmpeg
vaapi_encode.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 <inttypes.h>
20 #include <string.h>
21 
22 #include "config.h"
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/log.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/pixdesc.h"
30 
31 #include "vaapi_encode.h"
32 #include "encode.h"
33 #include "avcodec.h"
34 #include "refstruct.h"
35 
37  HW_CONFIG_ENCODER_FRAMES(VAAPI, VAAPI),
38  NULL,
39 };
40 
42  VAAPIEncodePicture *pic,
43  int type, char *data, size_t bit_len)
44 {
46  VAStatus vas;
47  VABufferID param_buffer, data_buffer;
48  VABufferID *tmp;
49  VAEncPackedHeaderParameterBuffer params = {
50  .type = type,
51  .bit_length = bit_len,
52  .has_emulation_bytes = 1,
53  };
54 
55  tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 2);
56  if (!tmp)
57  return AVERROR(ENOMEM);
58  pic->param_buffers = tmp;
59 
60  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
61  VAEncPackedHeaderParameterBufferType,
62  sizeof(params), 1, &params, &param_buffer);
63  if (vas != VA_STATUS_SUCCESS) {
64  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
65  "for packed header (type %d): %d (%s).\n",
66  type, vas, vaErrorStr(vas));
67  return AVERROR(EIO);
68  }
69  pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
70 
71  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
72  VAEncPackedHeaderDataBufferType,
73  (bit_len + 7) / 8, 1, data, &data_buffer);
74  if (vas != VA_STATUS_SUCCESS) {
75  av_log(avctx, AV_LOG_ERROR, "Failed to create data buffer "
76  "for packed header (type %d): %d (%s).\n",
77  type, vas, vaErrorStr(vas));
78  return AVERROR(EIO);
79  }
80  pic->param_buffers[pic->nb_param_buffers++] = data_buffer;
81 
82  av_log(avctx, AV_LOG_DEBUG, "Packed header buffer (%d) is %#x/%#x "
83  "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
84  return 0;
85 }
86 
88  VAAPIEncodePicture *pic,
89  int type, char *data, size_t len)
90 {
92  VAStatus vas;
93  VABufferID *tmp;
94  VABufferID buffer;
95 
96  tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 1);
97  if (!tmp)
98  return AVERROR(ENOMEM);
99  pic->param_buffers = tmp;
100 
101  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
102  type, len, 1, data, &buffer);
103  if (vas != VA_STATUS_SUCCESS) {
104  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
105  "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
106  return AVERROR(EIO);
107  }
108  pic->param_buffers[pic->nb_param_buffers++] = buffer;
109 
110  av_log(avctx, AV_LOG_DEBUG, "Param buffer (%d) is %#x.\n",
111  type, buffer);
112  return 0;
113 }
114 
116  VAAPIEncodePicture *pic,
117  int type,
118  const void *data, size_t len)
119 {
120  // Construct the buffer on the stack - 1KB is much larger than any
121  // current misc parameter buffer type (the largest is EncQuality at
122  // 224 bytes).
123  uint8_t buffer[1024];
124  VAEncMiscParameterBuffer header = {
125  .type = type,
126  };
127  size_t buffer_size = sizeof(header) + len;
128  av_assert0(buffer_size <= sizeof(buffer));
129 
130  memcpy(buffer, &header, sizeof(header));
131  memcpy(buffer + sizeof(header), data, len);
132 
133  return vaapi_encode_make_param_buffer(avctx, pic,
134  VAEncMiscParameterBufferType,
135  buffer, buffer_size);
136 }
137 
139 {
140 #if VA_CHECK_VERSION(1, 9, 0)
141  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
142 #endif
143  VAAPIEncodeContext *ctx = avctx->priv_data;
144  VAAPIEncodePicture *pic = base_pic->priv;
145  VAStatus vas;
146 
147  av_assert0(base_pic->encode_issued);
148 
149  if (base_pic->encode_complete) {
150  // Already waited for this picture.
151  return 0;
152  }
153 
154  av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
155  "(input surface %#x).\n", base_pic->display_order,
156  base_pic->encode_order, pic->input_surface);
157 
158 #if VA_CHECK_VERSION(1, 9, 0)
159  if (base_ctx->async_encode) {
160  vas = vaSyncBuffer(ctx->hwctx->display,
161  pic->output_buffer,
162  VA_TIMEOUT_INFINITE);
163  if (vas != VA_STATUS_SUCCESS) {
164  av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer completion: "
165  "%d (%s).\n", vas, vaErrorStr(vas));
166  return AVERROR(EIO);
167  }
168  } else
169 #endif
170  { // If vaSyncBuffer is not implemented, try old version API.
171  vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
172  if (vas != VA_STATUS_SUCCESS) {
173  av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
174  "%d (%s).\n", vas, vaErrorStr(vas));
175  return AVERROR(EIO);
176  }
177  }
178 
179  // Input is definitely finished with now.
180  av_frame_free(&base_pic->input_image);
181 
182  base_pic->encode_complete = 1;
183  return 0;
184 }
185 
187  VAAPIEncodePicture *pic)
188 {
189  VAAPIEncodeContext *ctx = avctx->priv_data;
190  VAAPIEncodeSlice *slice;
191  int i, rounding;
192 
193  for (i = 0; i < pic->nb_slices; i++)
194  pic->slices[i].row_size = ctx->slice_size;
195 
196  rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size;
197  if (rounding > 0) {
198  // Place rounding error at top and bottom of frame.
199  av_assert0(rounding < pic->nb_slices);
200  // Some Intel drivers contain a bug where the encoder will fail
201  // if the last slice is smaller than the one before it. Since
202  // that's straightforward to avoid here, just do so.
203  if (rounding <= 2) {
204  for (i = 0; i < rounding; i++)
205  ++pic->slices[i].row_size;
206  } else {
207  for (i = 0; i < (rounding + 1) / 2; i++)
208  ++pic->slices[pic->nb_slices - i - 1].row_size;
209  for (i = 0; i < rounding / 2; i++)
210  ++pic->slices[i].row_size;
211  }
212  } else if (rounding < 0) {
213  // Remove rounding error from last slice only.
214  av_assert0(rounding < ctx->slice_size);
215  pic->slices[pic->nb_slices - 1].row_size += rounding;
216  }
217 
218  for (i = 0; i < pic->nb_slices; i++) {
219  slice = &pic->slices[i];
220  slice->index = i;
221  if (i == 0) {
222  slice->row_start = 0;
223  slice->block_start = 0;
224  } else {
225  const VAAPIEncodeSlice *prev = &pic->slices[i - 1];
226  slice->row_start = prev->row_start + prev->row_size;
227  slice->block_start = prev->block_start + prev->block_size;
228  }
229  slice->block_size = slice->row_size * ctx->slice_block_cols;
230 
231  av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), "
232  "%d-%d (%d blocks).\n", i, slice->row_start,
233  slice->row_start + slice->row_size - 1, slice->row_size,
234  slice->block_start, slice->block_start + slice->block_size - 1,
235  slice->block_size);
236  }
237 
238  return 0;
239 }
240 
242  VAAPIEncodePicture *pic)
243 {
244  VAAPIEncodeContext *ctx = avctx->priv_data;
245  VAAPIEncodeSlice *slice;
246  int i, j, index;
247 
248  for (i = 0; i < ctx->tile_cols; i++) {
249  for (j = 0; j < ctx->tile_rows; j++) {
250  index = j * ctx->tile_cols + i;
251  slice = &pic->slices[index];
252  slice->index = index;
253 
254  pic->slices[index].block_start = ctx->col_bd[i] +
255  ctx->row_bd[j] * ctx->slice_block_cols;
256  pic->slices[index].block_size = ctx->row_height[j] * ctx->col_width[i];
257 
258  av_log(avctx, AV_LOG_DEBUG, "Slice %2d: (%2d, %2d) start at: %4d "
259  "width:%2d height:%2d (%d blocks).\n", index, ctx->col_bd[i],
260  ctx->row_bd[j], slice->block_start, ctx->col_width[i],
261  ctx->row_height[j], slice->block_size);
262  }
263  }
264 
265  return 0;
266 }
267 
269  FFHWBaseEncodePicture *base_pic)
270 {
271  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
272  VAAPIEncodeContext *ctx = avctx->priv_data;
273  VAAPIEncodePicture *pic = base_pic->priv;
274  VAAPIEncodeSlice *slice;
275  VAStatus vas;
276  int err = 0, i;
278  size_t bit_len;
280 
281  av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
282  "as type %s.\n", base_pic->display_order, base_pic->encode_order,
284  if (base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0) {
285  av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
286  } else {
287  av_log(avctx, AV_LOG_DEBUG, "L0 refers to");
288  for (i = 0; i < base_pic->nb_refs[0]; i++) {
289  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
290  base_pic->refs[0][i]->display_order, base_pic->refs[0][i]->encode_order);
291  }
292  av_log(avctx, AV_LOG_DEBUG, ".\n");
293 
294  if (base_pic->nb_refs[1]) {
295  av_log(avctx, AV_LOG_DEBUG, "L1 refers to");
296  for (i = 0; i < base_pic->nb_refs[1]; i++) {
297  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
298  base_pic->refs[1][i]->display_order, base_pic->refs[1][i]->encode_order);
299  }
300  av_log(avctx, AV_LOG_DEBUG, ".\n");
301  }
302  }
303 
304  av_assert0(!base_pic->encode_issued);
305  for (i = 0; i < base_pic->nb_refs[0]; i++) {
306  av_assert0(base_pic->refs[0][i]);
307  av_assert0(base_pic->refs[0][i]->encode_issued);
308  }
309  for (i = 0; i < base_pic->nb_refs[1]; i++) {
310  av_assert0(base_pic->refs[1][i]);
311  av_assert0(base_pic->refs[1][i]->encode_issued);
312  }
313 
314  av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
315 
316  pic->recon_surface = (VASurfaceID)(uintptr_t)base_pic->recon_image->data[3];
317  av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
318 
319  pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool);
320  if (!pic->output_buffer_ref) {
321  err = AVERROR(ENOMEM);
322  goto fail;
323  }
324  pic->output_buffer = *pic->output_buffer_ref;
325  av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
326  pic->output_buffer);
327 
328  if (ctx->codec->picture_params_size > 0) {
329  pic->codec_picture_params = av_malloc(ctx->codec->picture_params_size);
330  if (!pic->codec_picture_params)
331  goto fail;
332  memcpy(pic->codec_picture_params, ctx->codec_picture_params,
333  ctx->codec->picture_params_size);
334  } else {
335  av_assert0(!ctx->codec_picture_params);
336  }
337 
338  pic->nb_param_buffers = 0;
339 
340  if (base_pic->type == FF_HW_PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
341  err = vaapi_encode_make_param_buffer(avctx, pic,
342  VAEncSequenceParameterBufferType,
343  ctx->codec_sequence_params,
344  ctx->codec->sequence_params_size);
345  if (err < 0)
346  goto fail;
347  }
348 
349  if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
350  for (i = 0; i < ctx->nb_global_params; i++) {
351  err = vaapi_encode_make_misc_param_buffer(avctx, pic,
352  ctx->global_params_type[i],
353  ctx->global_params[i],
354  ctx->global_params_size[i]);
355  if (err < 0)
356  goto fail;
357  }
358  }
359 
360  if (ctx->codec->init_picture_params) {
361  err = ctx->codec->init_picture_params(avctx, base_pic);
362  if (err < 0) {
363  av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
364  "parameters: %d.\n", err);
365  goto fail;
366  }
367  err = vaapi_encode_make_param_buffer(avctx, pic,
368  VAEncPictureParameterBufferType,
370  ctx->codec->picture_params_size);
371  if (err < 0)
372  goto fail;
373  }
374 
375 #if VA_CHECK_VERSION(1, 5, 0)
376  if (ctx->max_frame_size) {
377  err = vaapi_encode_make_misc_param_buffer(avctx, pic,
378  VAEncMiscParameterTypeMaxFrameSize,
379  &ctx->mfs_params,
380  sizeof(ctx->mfs_params));
381  if (err < 0)
382  goto fail;
383  }
384 #endif
385 
386  if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
387  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
388  ctx->codec->write_sequence_header) {
389  bit_len = 8 * sizeof(data);
390  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
391  if (err < 0) {
392  av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
393  "header: %d.\n", err);
394  goto fail;
395  }
396  err = vaapi_encode_make_packed_header(avctx, pic,
397  ctx->codec->sequence_header_type,
398  data, bit_len);
399  if (err < 0)
400  goto fail;
401  }
402  }
403 
404  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
405  ctx->codec->write_picture_header) {
406  bit_len = 8 * sizeof(data);
407  err = ctx->codec->write_picture_header(avctx, base_pic, data, &bit_len);
408  if (err < 0) {
409  av_log(avctx, AV_LOG_ERROR, "Failed to write per-picture "
410  "header: %d.\n", err);
411  goto fail;
412  }
413  err = vaapi_encode_make_packed_header(avctx, pic,
414  ctx->codec->picture_header_type,
415  data, bit_len);
416  if (err < 0)
417  goto fail;
418  }
419 
420  if (ctx->codec->write_extra_buffer) {
421  for (i = 0;; i++) {
422  size_t len = sizeof(data);
423  int type;
424  err = ctx->codec->write_extra_buffer(avctx, base_pic, i, &type,
425  data, &len);
426  if (err == AVERROR_EOF)
427  break;
428  if (err < 0) {
429  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
430  "buffer %d: %d.\n", i, err);
431  goto fail;
432  }
433 
434  err = vaapi_encode_make_param_buffer(avctx, pic, type,
435  data, len);
436  if (err < 0)
437  goto fail;
438  }
439  }
440 
441  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
442  ctx->codec->write_extra_header) {
443  for (i = 0;; i++) {
444  int type;
445  bit_len = 8 * sizeof(data);
446  err = ctx->codec->write_extra_header(avctx, base_pic, i, &type,
447  data, &bit_len);
448  if (err == AVERROR_EOF)
449  break;
450  if (err < 0) {
451  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
452  "header %d: %d.\n", i, err);
453  goto fail;
454  }
455 
456  err = vaapi_encode_make_packed_header(avctx, pic, type,
457  data, bit_len);
458  if (err < 0)
459  goto fail;
460  }
461  }
462 
463  if (pic->nb_slices == 0)
464  pic->nb_slices = ctx->nb_slices;
465  if (pic->nb_slices > 0) {
466  pic->slices = av_calloc(pic->nb_slices, sizeof(*pic->slices));
467  if (!pic->slices) {
468  err = AVERROR(ENOMEM);
469  goto fail;
470  }
471 
472  if (ctx->tile_rows && ctx->tile_cols)
473  vaapi_encode_make_tile_slice(avctx, pic);
474  else
475  vaapi_encode_make_row_slice(avctx, pic);
476  }
477 
478  for (i = 0; i < pic->nb_slices; i++) {
479  slice = &pic->slices[i];
480 
481  if (ctx->codec->slice_params_size > 0) {
482  slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size);
483  if (!slice->codec_slice_params) {
484  err = AVERROR(ENOMEM);
485  goto fail;
486  }
487  }
488 
489  if (ctx->codec->init_slice_params) {
490  err = ctx->codec->init_slice_params(avctx, base_pic, slice);
491  if (err < 0) {
492  av_log(avctx, AV_LOG_ERROR, "Failed to initialise slice "
493  "parameters: %d.\n", err);
494  goto fail;
495  }
496  }
497 
498  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
499  ctx->codec->write_slice_header) {
500  bit_len = 8 * sizeof(data);
501  err = ctx->codec->write_slice_header(avctx, pic, slice,
502  data, &bit_len);
503  if (err < 0) {
504  av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
505  "header: %d.\n", err);
506  goto fail;
507  }
508  err = vaapi_encode_make_packed_header(avctx, pic,
509  ctx->codec->slice_header_type,
510  data, bit_len);
511  if (err < 0)
512  goto fail;
513  }
514 
515  if (ctx->codec->init_slice_params) {
516  err = vaapi_encode_make_param_buffer(avctx, pic,
517  VAEncSliceParameterBufferType,
518  slice->codec_slice_params,
519  ctx->codec->slice_params_size);
520  if (err < 0)
521  goto fail;
522  }
523  }
524 
525 #if VA_CHECK_VERSION(1, 0, 0)
526  sd = av_frame_get_side_data(base_pic->input_image,
528  if (sd && base_ctx->roi_allowed) {
529  const AVRegionOfInterest *roi;
530  uint32_t roi_size;
531  VAEncMiscParameterBufferROI param_roi;
532  int nb_roi, i, v;
533 
534  roi = (const AVRegionOfInterest*)sd->data;
535  roi_size = roi->self_size;
536  av_assert0(roi_size && sd->size % roi_size == 0);
537  nb_roi = sd->size / roi_size;
538  if (nb_roi > ctx->roi_max_regions) {
539  if (!base_ctx->roi_warned) {
540  av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
541  "supported by driver (%d > %d).\n",
542  nb_roi, ctx->roi_max_regions);
543  base_ctx->roi_warned = 1;
544  }
545  nb_roi = ctx->roi_max_regions;
546  }
547 
548  pic->roi = av_calloc(nb_roi, sizeof(*pic->roi));
549  if (!pic->roi) {
550  err = AVERROR(ENOMEM);
551  goto fail;
552  }
553  // For overlapping regions, the first in the array takes priority.
554  for (i = 0; i < nb_roi; i++) {
555  roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
556 
557  av_assert0(roi->qoffset.den != 0);
558  v = roi->qoffset.num * ctx->roi_quant_range / roi->qoffset.den;
559  av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d) -> %+d.\n",
560  roi->top, roi->left, roi->bottom, roi->right, v);
561 
562  pic->roi[i] = (VAEncROI) {
563  .roi_rectangle = {
564  .x = roi->left,
565  .y = roi->top,
566  .width = roi->right - roi->left,
567  .height = roi->bottom - roi->top,
568  },
569  .roi_value = av_clip_int8(v),
570  };
571  }
572 
573  param_roi = (VAEncMiscParameterBufferROI) {
574  .num_roi = nb_roi,
575  .max_delta_qp = INT8_MAX,
576  .min_delta_qp = INT8_MIN,
577  .roi = pic->roi,
578  .roi_flags.bits.roi_value_is_qp_delta = 1,
579  };
580 
581  err = vaapi_encode_make_misc_param_buffer(avctx, pic,
582  VAEncMiscParameterTypeROI,
583  &param_roi,
584  sizeof(param_roi));
585  if (err < 0)
586  goto fail;
587  }
588 #endif
589 
590  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
591  pic->input_surface);
592  if (vas != VA_STATUS_SUCCESS) {
593  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
594  "%d (%s).\n", vas, vaErrorStr(vas));
595  err = AVERROR(EIO);
596  goto fail_with_picture;
597  }
598 
599  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
600  pic->param_buffers, pic->nb_param_buffers);
601  if (vas != VA_STATUS_SUCCESS) {
602  av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
603  "%d (%s).\n", vas, vaErrorStr(vas));
604  err = AVERROR(EIO);
605  goto fail_with_picture;
606  }
607 
608  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
609  if (vas != VA_STATUS_SUCCESS) {
610  av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
611  "%d (%s).\n", vas, vaErrorStr(vas));
612  err = AVERROR(EIO);
613  // vaRenderPicture() has been called here, so we should not destroy
614  // the parameter buffers unless separate destruction is required.
615  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
617  goto fail;
618  else
619  goto fail_at_end;
620  }
621 
622  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
624  for (i = 0; i < pic->nb_param_buffers; i++) {
625  vas = vaDestroyBuffer(ctx->hwctx->display,
626  pic->param_buffers[i]);
627  if (vas != VA_STATUS_SUCCESS) {
628  av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
629  "param buffer %#x: %d (%s).\n",
630  pic->param_buffers[i], vas, vaErrorStr(vas));
631  // And ignore.
632  }
633  }
634  }
635 
636  return 0;
637 
638 fail_with_picture:
639  vaEndPicture(ctx->hwctx->display, ctx->va_context);
640 fail:
641  for(i = 0; i < pic->nb_param_buffers; i++)
642  vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
643  if (pic->slices) {
644  for (i = 0; i < pic->nb_slices; i++)
646  }
647 fail_at_end:
649  av_freep(&pic->param_buffers);
650  av_freep(&pic->slices);
651  av_freep(&pic->roi);
653  pic->output_buffer = VA_INVALID_ID;
654  return err;
655 }
656 
657 static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID buf_id)
658 {
659  VAAPIEncodeContext *ctx = avctx->priv_data;
660  VACodedBufferSegment *buf_list, *buf;
661  int size = 0;
662  VAStatus vas;
663  int err;
664 
665  vas = vaMapBuffer(ctx->hwctx->display, buf_id,
666  (void**)&buf_list);
667  if (vas != VA_STATUS_SUCCESS) {
668  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
669  "%d (%s).\n", vas, vaErrorStr(vas));
670  err = AVERROR(EIO);
671  return err;
672  }
673 
674  for (buf = buf_list; buf; buf = buf->next)
675  size += buf->size;
676 
677  vas = vaUnmapBuffer(ctx->hwctx->display, buf_id);
678  if (vas != VA_STATUS_SUCCESS) {
679  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
680  "%d (%s).\n", vas, vaErrorStr(vas));
681  err = AVERROR(EIO);
682  return err;
683  }
684 
685  return size;
686 }
687 
689  VABufferID buf_id, uint8_t **dst)
690 {
691  VAAPIEncodeContext *ctx = avctx->priv_data;
692  VACodedBufferSegment *buf_list, *buf;
693  VAStatus vas;
694  int err;
695 
696  vas = vaMapBuffer(ctx->hwctx->display, buf_id,
697  (void**)&buf_list);
698  if (vas != VA_STATUS_SUCCESS) {
699  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
700  "%d (%s).\n", vas, vaErrorStr(vas));
701  err = AVERROR(EIO);
702  return err;
703  }
704 
705  for (buf = buf_list; buf; buf = buf->next) {
706  av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
707  "(status %08x).\n", buf->size, buf->status);
708 
709  memcpy(*dst, buf->buf, buf->size);
710  *dst += buf->size;
711  }
712 
713  vas = vaUnmapBuffer(ctx->hwctx->display, buf_id);
714  if (vas != VA_STATUS_SUCCESS) {
715  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
716  "%d (%s).\n", vas, vaErrorStr(vas));
717  err = AVERROR(EIO);
718  return err;
719  }
720 
721  return 0;
722 }
723 
726 {
727  VAAPIEncodeContext *ctx = avctx->priv_data;
728  VABufferID output_buffer_prev;
729  int total_size = 0;
730  uint8_t *ptr;
731  int ret;
732 
733  if (ctx->coded_buffer_ref) {
734  output_buffer_prev = *ctx->coded_buffer_ref;
735  ret = vaapi_encode_get_coded_buffer_size(avctx, output_buffer_prev);
736  if (ret < 0)
737  goto end;
738  total_size += ret;
739  }
740 
742  if (ret < 0)
743  goto end;
744  total_size += ret;
745 
746  ret = ff_get_encode_buffer(avctx, pkt, total_size, 0);
747  if (ret < 0)
748  goto end;
749  ptr = pkt->data;
750 
751  if (ctx->coded_buffer_ref) {
752  ret = vaapi_encode_get_coded_buffer_data(avctx, output_buffer_prev, &ptr);
753  if (ret < 0)
754  goto end;
755  }
756 
758  if (ret < 0)
759  goto end;
760 
761 end:
762  ff_refstruct_unref(&ctx->coded_buffer_ref);
764  pic->output_buffer = VA_INVALID_ID;
765 
766  return ret;
767 }
768 
770  FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
771 {
772  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
773  VAAPIEncodeContext *ctx = avctx->priv_data;
774  VAAPIEncodePicture *pic = base_pic->priv;
775  AVPacket *pkt_ptr = pkt;
776  int err;
777 
778  err = vaapi_encode_wait(avctx, base_pic);
779  if (err < 0)
780  return err;
781 
782  if (pic->non_independent_frame) {
783  av_assert0(!ctx->coded_buffer_ref);
784  ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref);
785 
786  if (pic->tail_size) {
787  if (base_ctx->tail_pkt->size) {
788  err = AVERROR_BUG;
789  goto end;
790  }
791 
792  err = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, pic->tail_size, 0);
793  if (err < 0)
794  goto end;
795 
796  memcpy(base_ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
797  pkt_ptr = base_ctx->tail_pkt;
798  }
799  } else {
800  err = vaapi_encode_get_coded_data(avctx, pic, pkt);
801  if (err < 0)
802  goto end;
803  }
804 
805  av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
806  base_pic->display_order, base_pic->encode_order);
807 
808  ff_hw_base_encode_set_output_property(base_ctx, avctx, (FFHWBaseEncodePicture*)base_pic, pkt_ptr,
809  ctx->codec->flags & FLAG_TIMESTAMP_NO_DELAY);
810 
811 end:
813  pic->output_buffer = VA_INVALID_ID;
814  return err;
815 }
816 
818 {
819  VAAPIEncodePicture *pic = base_pic->priv;
820 
821  vaapi_encode_wait(avctx, base_pic);
822 
823  if (pic->output_buffer_ref) {
824  av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
825  "%"PRId64"/%"PRId64".\n",
826  base_pic->display_order, base_pic->encode_order);
827 
829  pic->output_buffer = VA_INVALID_ID;
830  }
831 
832  return 0;
833 }
834 
836 {
837  VAAPIEncodeContext *ctx = avctx->priv_data;
838  VAAPIEncodePicture *priv = pic->priv;
839  AVFrame *frame = pic->input_image;
840 
841  if (ctx->codec->picture_priv_data_size > 0) {
842  pic->codec_priv = av_mallocz(ctx->codec->picture_priv_data_size);
843  if (!pic->codec_priv)
844  return AVERROR(ENOMEM);
845  }
846 
847  priv->input_surface = (VASurfaceID)(uintptr_t)frame->data[3];
848  priv->recon_surface = VA_INVALID_ID;
849  priv->output_buffer = VA_INVALID_ID;
850 
851  return 0;
852 }
853 
855 {
856  VAAPIEncodePicture *priv = pic->priv;
857  int i;
858 
859  if (pic->encode_issued)
860  vaapi_encode_discard(avctx, pic);
861 
862  if (priv->slices) {
863  for (i = 0; i < priv->nb_slices; i++)
865  }
866 
867  av_freep(&priv->param_buffers);
868  av_freep(&priv->slices);
869  // Output buffer should already be destroyed.
870  av_assert0(priv->output_buffer == VA_INVALID_ID);
871 
873  av_freep(&priv->roi);
874 
875  return 0;
876 }
877 
879  void *buffer, size_t size)
880 {
881  VAAPIEncodeContext *ctx = avctx->priv_data;
882 
883  av_assert0(ctx->nb_global_params < MAX_GLOBAL_PARAMS);
884 
885  ctx->global_params_type[ctx->nb_global_params] = type;
886  ctx->global_params [ctx->nb_global_params] = buffer;
887  ctx->global_params_size[ctx->nb_global_params] = size;
888 
889  ++ctx->nb_global_params;
890 }
891 
892 typedef struct VAAPIEncodeRTFormat {
893  const char *name;
894  unsigned int value;
895  int depth;
900 
902  { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
903  { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
904  { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
905 #if VA_CHECK_VERSION(1, 2, 0)
906  { "YUV420_12", VA_RT_FORMAT_YUV420_12, 12, 3, 1, 1 },
907  { "YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 },
908  { "YUV422_12", VA_RT_FORMAT_YUV422_12, 12, 3, 1, 0 },
909  { "YUV444_10", VA_RT_FORMAT_YUV444_10, 10, 3, 0, 0 },
910  { "YUV444_12", VA_RT_FORMAT_YUV444_12, 12, 3, 0, 0 },
911 #endif
912  { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
913  { "XYUV", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
914  { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
915 #if VA_CHECK_VERSION(0, 38, 1)
916  { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
917 #endif
918 };
919 
920 static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
921  VAEntrypointEncSlice,
922  VAEntrypointEncPicture,
923 #if VA_CHECK_VERSION(0, 39, 2)
924  VAEntrypointEncSliceLP,
925 #endif
926  0
927 };
928 #if VA_CHECK_VERSION(0, 39, 2)
929 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
930  VAEntrypointEncSliceLP,
931  0
932 };
933 #endif
934 
936 {
937  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
938  VAAPIEncodeContext *ctx = avctx->priv_data;
939  VAProfile *va_profiles = NULL;
940  VAEntrypoint *va_entrypoints = NULL;
941  VAStatus vas;
942  const VAEntrypoint *usable_entrypoints;
944  const AVPixFmtDescriptor *desc;
945  VAConfigAttrib rt_format_attr;
946  const VAAPIEncodeRTFormat *rt_format;
947  const char *profile_string, *entrypoint_string;
948  int i, j, n, depth, err;
949 
950 
951  if (ctx->low_power) {
952 #if VA_CHECK_VERSION(0, 39, 2)
953  usable_entrypoints = vaapi_encode_entrypoints_low_power;
954 #else
955  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
956  "supported with this VAAPI version.\n");
957  return AVERROR(EINVAL);
958 #endif
959  } else {
960  usable_entrypoints = vaapi_encode_entrypoints_normal;
961  }
962 
964  if (!desc) {
965  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
966  base_ctx->input_frames->sw_format);
967  return AVERROR(EINVAL);
968  }
969  depth = desc->comp[0].depth;
970  for (i = 1; i < desc->nb_components; i++) {
971  if (desc->comp[i].depth != depth) {
972  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
973  desc->name);
974  return AVERROR(EINVAL);
975  }
976  }
977  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
978  desc->name);
979 
980  n = vaMaxNumProfiles(ctx->hwctx->display);
981  va_profiles = av_malloc_array(n, sizeof(VAProfile));
982  if (!va_profiles) {
983  err = AVERROR(ENOMEM);
984  goto fail;
985  }
986  vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
987  if (vas != VA_STATUS_SUCCESS) {
988  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
989  vas, vaErrorStr(vas));
990  err = AVERROR_EXTERNAL;
991  goto fail;
992  }
993 
994  av_assert0(ctx->codec->profiles);
995  for (i = 0; (ctx->codec->profiles[i].av_profile !=
996  AV_PROFILE_UNKNOWN); i++) {
997  profile = &ctx->codec->profiles[i];
998  if (depth != profile->depth ||
999  desc->nb_components != profile->nb_components)
1000  continue;
1001  if (desc->nb_components > 1 &&
1002  (desc->log2_chroma_w != profile->log2_chroma_w ||
1003  desc->log2_chroma_h != profile->log2_chroma_h))
1004  continue;
1005  if (avctx->profile != profile->av_profile &&
1006  avctx->profile != AV_PROFILE_UNKNOWN)
1007  continue;
1008 
1009 #if VA_CHECK_VERSION(1, 0, 0)
1010  profile_string = vaProfileStr(profile->va_profile);
1011 #else
1012  profile_string = "(no profile names)";
1013 #endif
1014 
1015  for (j = 0; j < n; j++) {
1016  if (va_profiles[j] == profile->va_profile)
1017  break;
1018  }
1019  if (j >= n) {
1020  av_log(avctx, AV_LOG_VERBOSE, "Compatible profile %s (%d) "
1021  "is not supported by driver.\n", profile_string,
1022  profile->va_profile);
1023  continue;
1024  }
1025 
1026  ctx->profile = profile;
1027  break;
1028  }
1029  if (!ctx->profile) {
1030  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1031  err = AVERROR(ENOSYS);
1032  goto fail;
1033  }
1034 
1035  avctx->profile = profile->av_profile;
1036  ctx->va_profile = profile->va_profile;
1037  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1038  profile_string, ctx->va_profile);
1039 
1040  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1041  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1042  if (!va_entrypoints) {
1043  err = AVERROR(ENOMEM);
1044  goto fail;
1045  }
1046  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1047  va_entrypoints, &n);
1048  if (vas != VA_STATUS_SUCCESS) {
1049  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1050  "profile %s (%d): %d (%s).\n", profile_string,
1051  ctx->va_profile, vas, vaErrorStr(vas));
1052  err = AVERROR_EXTERNAL;
1053  goto fail;
1054  }
1055 
1056  for (i = 0; i < n; i++) {
1057  for (j = 0; usable_entrypoints[j]; j++) {
1058  if (va_entrypoints[i] == usable_entrypoints[j])
1059  break;
1060  }
1061  if (usable_entrypoints[j])
1062  break;
1063  }
1064  if (i >= n) {
1065  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1066  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1067  err = AVERROR(ENOSYS);
1068  goto fail;
1069  }
1070 
1071  ctx->va_entrypoint = va_entrypoints[i];
1072 #if VA_CHECK_VERSION(1, 0, 0)
1073  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1074 #else
1075  entrypoint_string = "(no entrypoint names)";
1076 #endif
1077  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1078  entrypoint_string, ctx->va_entrypoint);
1079 
1080  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1081  rt_format = &vaapi_encode_rt_formats[i];
1082  if (rt_format->depth == depth &&
1083  rt_format->nb_components == profile->nb_components &&
1084  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1085  rt_format->log2_chroma_h == profile->log2_chroma_h)
1086  break;
1087  }
1089  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1090  "found for profile %s (%d) entrypoint %s (%d).\n",
1091  profile_string, ctx->va_profile,
1092  entrypoint_string, ctx->va_entrypoint);
1093  err = AVERROR(ENOSYS);
1094  goto fail;
1095  }
1096 
1097  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1098  vas = vaGetConfigAttributes(ctx->hwctx->display,
1099  ctx->va_profile, ctx->va_entrypoint,
1100  &rt_format_attr, 1);
1101  if (vas != VA_STATUS_SUCCESS) {
1102  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1103  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1104  err = AVERROR_EXTERNAL;
1105  goto fail;
1106  }
1107 
1108  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1109  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1110  "supported by driver: assuming surface RT format %s "
1111  "is valid.\n", rt_format->name);
1112  } else if (!(rt_format_attr.value & rt_format->value)) {
1113  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1114  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1115  rt_format->name, profile_string, ctx->va_profile,
1116  entrypoint_string, ctx->va_entrypoint);
1117  err = AVERROR(ENOSYS);
1118  goto fail;
1119  } else {
1120  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1121  "format %s (%#x).\n", rt_format->name, rt_format->value);
1122  ctx->config_attributes[ctx->nb_config_attributes++] =
1123  (VAConfigAttrib) {
1124  .type = VAConfigAttribRTFormat,
1125  .value = rt_format->value,
1126  };
1127  }
1128 
1129  err = 0;
1130 fail:
1131  av_freep(&va_profiles);
1132  av_freep(&va_entrypoints);
1133  return err;
1134 }
1135 
1137  // Bitrate Quality
1138  // | Maxrate | HRD/VBV
1139  { 0 }, // | | | |
1140  { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
1141  { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
1142  { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
1143 #if VA_CHECK_VERSION(1, 1, 0)
1144  { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
1145 #else
1146  { RC_MODE_ICQ, "ICQ", 0 },
1147 #endif
1148 #if VA_CHECK_VERSION(1, 3, 0)
1149  { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
1150  { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
1151 #else
1152  { RC_MODE_QVBR, "QVBR", 0 },
1153  { RC_MODE_AVBR, "AVBR", 0 },
1154 #endif
1155 };
1156 
1158 {
1159  VAAPIEncodeContext *ctx = avctx->priv_data;
1160  uint32_t supported_va_rc_modes;
1161  const VAAPIEncodeRCMode *rc_mode;
1162  int64_t rc_bits_per_second;
1163  int rc_target_percentage;
1164  int rc_window_size;
1165  int rc_quality;
1166  int64_t hrd_buffer_size;
1167  int64_t hrd_initial_buffer_fullness;
1168  int fr_num, fr_den;
1169  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1170  VAStatus vas;
1171  char supported_rc_modes_string[64];
1172 
1173  vas = vaGetConfigAttributes(ctx->hwctx->display,
1174  ctx->va_profile, ctx->va_entrypoint,
1175  &rc_attr, 1);
1176  if (vas != VA_STATUS_SUCCESS) {
1177  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1178  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1179  return AVERROR_EXTERNAL;
1180  }
1181  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1182  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1183  "supported rate control modes: assuming CQP only.\n");
1184  supported_va_rc_modes = VA_RC_CQP;
1185  strcpy(supported_rc_modes_string, "unknown");
1186  } else {
1187  char *str = supported_rc_modes_string;
1188  size_t len = sizeof(supported_rc_modes_string);
1189  int i, first = 1, res;
1190 
1191  supported_va_rc_modes = rc_attr.value;
1192  if (ctx->blbrc) {
1193 #if VA_CHECK_VERSION(0, 39, 2)
1194  if (!(supported_va_rc_modes & VA_RC_MB)) {
1195  ctx->blbrc = 0;
1196  av_log(avctx, AV_LOG_WARNING, "Driver does not support BLBRC.\n");
1197  }
1198 #else
1199  ctx->blbrc = 0;
1200  av_log(avctx, AV_LOG_WARNING, "Please consider to update to VAAPI 0.39.2 "
1201  "or above, which can support BLBRC.\n");
1202 #endif
1203  }
1204 
1205  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1207  if (supported_va_rc_modes & rc_mode->va_mode) {
1208  res = snprintf(str, len, "%s%s",
1209  first ? "" : ", ", rc_mode->name);
1210  first = 0;
1211  if (res < 0) {
1212  *str = 0;
1213  break;
1214  }
1215  len -= res;
1216  str += res;
1217  if (len == 0)
1218  break;
1219  }
1220  }
1221 
1222  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1223  supported_rc_modes_string);
1224  }
1225 
1226  // Rate control mode selection:
1227  // * If the user has set a mode explicitly with the rc_mode option,
1228  // use it and fail if it is not available.
1229  // * If an explicit QP option has been set, use CQP.
1230  // * If the codec is CQ-only, use CQP.
1231  // * If the QSCALE avcodec option is set, use CQP.
1232  // * If bitrate and quality are both set, try QVBR.
1233  // * If quality is set, try ICQ, then CQP.
1234  // * If bitrate and maxrate are set and have the same value, try CBR.
1235  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1236  // * If no bitrate is set, try ICQ, then CQP.
1237 
1238 #define TRY_RC_MODE(mode, fail) do { \
1239  rc_mode = &vaapi_encode_rc_modes[mode]; \
1240  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1241  if (fail) { \
1242  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1243  "RC mode (supported modes: %s).\n", rc_mode->name, \
1244  supported_rc_modes_string); \
1245  return AVERROR(EINVAL); \
1246  } \
1247  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1248  "RC mode.\n", rc_mode->name); \
1249  rc_mode = NULL; \
1250  } else { \
1251  goto rc_mode_found; \
1252  } \
1253  } while (0)
1254 
1255  if (ctx->explicit_rc_mode)
1256  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1257 
1258  if (ctx->explicit_qp)
1260 
1263 
1264  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1266 
1267  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1269 
1270  if (avctx->global_quality > 0) {
1273  }
1274 
1275  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1277 
1278  if (avctx->bit_rate > 0) {
1282  } else {
1285  }
1286 
1287  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1288  "RC mode compatible with selected options "
1289  "(supported modes: %s).\n", supported_rc_modes_string);
1290  return AVERROR(EINVAL);
1291 
1292 rc_mode_found:
1293  if (rc_mode->bitrate) {
1294  if (avctx->bit_rate <= 0) {
1295  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1296  "RC mode.\n", rc_mode->name);
1297  return AVERROR(EINVAL);
1298  }
1299 
1300  if (rc_mode->mode == RC_MODE_AVBR) {
1301  // For maximum confusion AVBR is hacked into the existing API
1302  // by overloading some of the fields with completely different
1303  // meanings.
1304 
1305  // Target percentage does not apply in AVBR mode.
1306  rc_bits_per_second = avctx->bit_rate;
1307 
1308  // Accuracy tolerance range for meeting the specified target
1309  // bitrate. It's very unclear how this is actually intended
1310  // to work - since we do want to get the specified bitrate,
1311  // set the accuracy to 100% for now.
1312  rc_target_percentage = 100;
1313 
1314  // Convergence period in frames. The GOP size reflects the
1315  // user's intended block size for cutting, so reusing that
1316  // as the convergence period seems a reasonable default.
1317  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1318 
1319  } else if (rc_mode->maxrate) {
1320  if (avctx->rc_max_rate > 0) {
1321  if (avctx->rc_max_rate < avctx->bit_rate) {
1322  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1323  "bitrate (%"PRId64") must not be greater than "
1324  "maxrate (%"PRId64").\n", avctx->bit_rate,
1325  avctx->rc_max_rate);
1326  return AVERROR(EINVAL);
1327  }
1328  rc_bits_per_second = avctx->rc_max_rate;
1329  rc_target_percentage = (avctx->bit_rate * 100) /
1330  avctx->rc_max_rate;
1331  } else {
1332  // We only have a target bitrate, but this mode requires
1333  // that a maximum rate be supplied as well. Since the
1334  // user does not want this to be a constraint, arbitrarily
1335  // pick a maximum rate of double the target rate.
1336  rc_bits_per_second = 2 * avctx->bit_rate;
1337  rc_target_percentage = 50;
1338  }
1339  } else {
1340  if (avctx->rc_max_rate > avctx->bit_rate) {
1341  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1342  "in %s RC mode.\n", rc_mode->name);
1343  }
1344  rc_bits_per_second = avctx->bit_rate;
1345  rc_target_percentage = 100;
1346  }
1347  } else {
1348  rc_bits_per_second = 0;
1349  rc_target_percentage = 100;
1350  }
1351 
1352  if (rc_mode->quality) {
1353  if (ctx->explicit_qp) {
1354  rc_quality = ctx->explicit_qp;
1355  } else if (avctx->global_quality > 0) {
1356  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1357  rc_quality = avctx->global_quality / FF_QP2LAMBDA;
1358  else
1359  rc_quality = avctx->global_quality;
1360  } else {
1361  rc_quality = ctx->codec->default_quality;
1362  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1363  "using default (%d).\n", rc_quality);
1364  }
1365  } else {
1366  rc_quality = 0;
1367  }
1368 
1369  if (rc_mode->hrd) {
1370  if (avctx->rc_buffer_size)
1371  hrd_buffer_size = avctx->rc_buffer_size;
1372  else if (avctx->rc_max_rate > 0)
1373  hrd_buffer_size = avctx->rc_max_rate;
1374  else
1375  hrd_buffer_size = avctx->bit_rate;
1376  if (avctx->rc_initial_buffer_occupancy) {
1377  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1378  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1379  "must have initial buffer size (%d) <= "
1380  "buffer size (%"PRId64").\n",
1381  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1382  return AVERROR(EINVAL);
1383  }
1384  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1385  } else {
1386  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1387  }
1388 
1389  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1390  } else {
1391  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
1392  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
1393  "in %s RC mode.\n", rc_mode->name);
1394  }
1395 
1396  hrd_buffer_size = 0;
1397  hrd_initial_buffer_fullness = 0;
1398 
1399  if (rc_mode->mode != RC_MODE_AVBR) {
1400  // Already set (with completely different meaning) for AVBR.
1401  rc_window_size = 1000;
1402  }
1403  }
1404 
1405  if (rc_bits_per_second > UINT32_MAX ||
1406  hrd_buffer_size > UINT32_MAX ||
1407  hrd_initial_buffer_fullness > UINT32_MAX) {
1408  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1409  "greater are not supported by VAAPI.\n");
1410  return AVERROR(EINVAL);
1411  }
1412 
1413  ctx->rc_mode = rc_mode;
1414  ctx->rc_quality = rc_quality;
1415  ctx->va_rc_mode = rc_mode->va_mode;
1416  ctx->va_bit_rate = rc_bits_per_second;
1417 
1418  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
1419 
1420  if (ctx->blbrc && ctx->va_rc_mode == VA_RC_CQP)
1421  ctx->blbrc = 0;
1422  av_log(avctx, AV_LOG_VERBOSE, "Block Level bitrate control: %s.\n", ctx->blbrc ? "ON" : "OFF");
1423 
1424  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1425  // This driver does not want the RC mode attribute to be set.
1426  } else {
1427  ctx->config_attributes[ctx->nb_config_attributes++] =
1428  (VAConfigAttrib) {
1429  .type = VAConfigAttribRateControl,
1430 #if VA_CHECK_VERSION(0, 39, 2)
1431  .value = ctx->blbrc ? ctx->va_rc_mode | VA_RC_MB : ctx->va_rc_mode,
1432 #else
1433  .value = ctx->va_rc_mode,
1434 #endif
1435  };
1436  }
1437 
1438  if (rc_mode->quality)
1439  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
1440 
1441  if (rc_mode->va_mode != VA_RC_CQP) {
1442  if (rc_mode->mode == RC_MODE_AVBR) {
1443  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
1444  "converging in %d frames with %d%% accuracy.\n",
1445  rc_bits_per_second, rc_window_size,
1446  rc_target_percentage);
1447  } else if (rc_mode->bitrate) {
1448  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
1449  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
1450  rc_bits_per_second, rc_window_size);
1451  }
1452 
1453  ctx->rc_params = (VAEncMiscParameterRateControl) {
1454  .bits_per_second = rc_bits_per_second,
1455  .target_percentage = rc_target_percentage,
1456  .window_size = rc_window_size,
1457  .initial_qp = 0,
1458  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
1459  .basic_unit_size = 0,
1460 #if VA_CHECK_VERSION(1, 1, 0)
1461  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
1462  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
1463 #endif
1464 #if VA_CHECK_VERSION(1, 3, 0)
1465  .quality_factor = rc_quality,
1466 #endif
1467 #if VA_CHECK_VERSION(0, 39, 2)
1468  .rc_flags.bits.mb_rate_control = ctx->blbrc ? 1 : 2,
1469 #endif
1470  };
1472  VAEncMiscParameterTypeRateControl,
1473  &ctx->rc_params,
1474  sizeof(ctx->rc_params));
1475  }
1476 
1477  if (rc_mode->hrd) {
1478  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1479  "initial fullness %"PRId64" bits.\n",
1480  hrd_buffer_size, hrd_initial_buffer_fullness);
1481 
1482  ctx->hrd_params = (VAEncMiscParameterHRD) {
1483  .initial_buffer_fullness = hrd_initial_buffer_fullness,
1484  .buffer_size = hrd_buffer_size,
1485  };
1487  VAEncMiscParameterTypeHRD,
1488  &ctx->hrd_params,
1489  sizeof(ctx->hrd_params));
1490  }
1491 
1492  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1493  av_reduce(&fr_num, &fr_den,
1494  avctx->framerate.num, avctx->framerate.den, 65535);
1495  else
1496  av_reduce(&fr_num, &fr_den,
1497  avctx->time_base.den, avctx->time_base.num, 65535);
1498 
1499  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
1500  fr_num, fr_den, (double)fr_num / fr_den);
1501 
1502  ctx->fr_params = (VAEncMiscParameterFrameRate) {
1503  .framerate = (unsigned int)fr_den << 16 | fr_num,
1504  };
1505 #if VA_CHECK_VERSION(0, 40, 0)
1507  VAEncMiscParameterTypeFrameRate,
1508  &ctx->fr_params,
1509  sizeof(ctx->fr_params));
1510 #endif
1511 
1512  return 0;
1513 }
1514 
1516 {
1517 #if VA_CHECK_VERSION(1, 5, 0)
1518  VAAPIEncodeContext *ctx = avctx->priv_data;
1519  VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
1520  VAStatus vas;
1521 
1522  if (ctx->va_rc_mode == VA_RC_CQP) {
1523  ctx->max_frame_size = 0;
1524  av_log(avctx, AV_LOG_ERROR, "Max frame size is invalid in CQP rate "
1525  "control mode.\n");
1526  return AVERROR(EINVAL);
1527  }
1528 
1529  vas = vaGetConfigAttributes(ctx->hwctx->display,
1530  ctx->va_profile,
1531  ctx->va_entrypoint,
1532  &attr, 1);
1533  if (vas != VA_STATUS_SUCCESS) {
1534  ctx->max_frame_size = 0;
1535  av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
1536  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1537  return AVERROR_EXTERNAL;
1538  }
1539 
1540  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1541  ctx->max_frame_size = 0;
1542  av_log(avctx, AV_LOG_ERROR, "Max frame size attribute "
1543  "is not supported.\n");
1544  return AVERROR(EINVAL);
1545  } else {
1546  VAConfigAttribValMaxFrameSize attr_mfs;
1547  attr_mfs.value = attr.value;
1548  // Prefer to use VAEncMiscParameterTypeMaxFrameSize for max frame size.
1549  if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
1550  ctx->max_frame_size = 0;
1551  av_log(avctx, AV_LOG_ERROR, "Driver only supports multiple pass "
1552  "max frame size which has not been implemented in FFmpeg.\n");
1553  return AVERROR(EINVAL);
1554  }
1555 
1556  ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
1557  .max_frame_size = ctx->max_frame_size * 8,
1558  };
1559 
1560  av_log(avctx, AV_LOG_VERBOSE, "Set max frame size: %d bytes.\n",
1561  ctx->max_frame_size);
1562  }
1563 #else
1564  av_log(avctx, AV_LOG_ERROR, "The max frame size option is not supported with "
1565  "this VAAPI version.\n");
1566  return AVERROR(EINVAL);
1567 #endif
1568 
1569  return 0;
1570 }
1571 
1573 {
1574  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1575  VAAPIEncodeContext *ctx = avctx->priv_data;
1576  VAStatus vas;
1577  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1578  uint32_t ref_l0, ref_l1;
1579  int prediction_pre_only, err;
1580 
1581  vas = vaGetConfigAttributes(ctx->hwctx->display,
1582  ctx->va_profile,
1583  ctx->va_entrypoint,
1584  &attr, 1);
1585  if (vas != VA_STATUS_SUCCESS) {
1586  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
1587  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1588  return AVERROR_EXTERNAL;
1589  }
1590 
1591  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1592  ref_l0 = ref_l1 = 0;
1593  } else {
1594  ref_l0 = attr.value & 0xffff;
1595  ref_l1 = attr.value >> 16 & 0xffff;
1596  }
1597 
1598  base_ctx->p_to_gpb = 0;
1599  prediction_pre_only = 0;
1600 
1601 #if VA_CHECK_VERSION(1, 9, 0)
1602  if (!(ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||
1603  avctx->gop_size <= 1)) {
1604  attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
1605  vas = vaGetConfigAttributes(ctx->hwctx->display,
1606  ctx->va_profile,
1607  ctx->va_entrypoint,
1608  &attr, 1);
1609  if (vas != VA_STATUS_SUCCESS) {
1610  av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
1611  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1612  return AVERROR_EXTERNAL;
1613  } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1614  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
1615  "prediction constraints.\n");
1616  } else {
1617  if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
1618  ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
1619  av_log(avctx, AV_LOG_ERROR, "Driver report incorrect prediction "
1620  "direction attribute.\n");
1621  return AVERROR_EXTERNAL;
1622  }
1623 
1624  if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
1625  if (ref_l0 > 0 && ref_l1 > 0) {
1626  prediction_pre_only = 1;
1627  av_log(avctx, AV_LOG_VERBOSE, "Driver only support same reference "
1628  "lists for B-frames.\n");
1629  }
1630  }
1631 
1632  if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
1633  if (ref_l0 > 0 && ref_l1 > 0) {
1634  base_ctx->p_to_gpb = 1;
1635  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
1636  "replacing them with B-frames.\n");
1637  }
1638  }
1639  }
1640  }
1641 #endif
1642 
1643  err = ff_hw_base_init_gop_structure(base_ctx, avctx, ref_l0, ref_l1,
1644  ctx->codec->flags, prediction_pre_only);
1645  if (err < 0)
1646  return err;
1647 
1648  return 0;
1649 }
1650 
1652  uint32_t slice_structure)
1653 {
1654  VAAPIEncodeContext *ctx = avctx->priv_data;
1655  int req_slices;
1656 
1657  // For fixed-size slices currently we only support whole rows, making
1658  // rectangular slices. This could be extended to arbitrary runs of
1659  // blocks, but since slices tend to be a conformance requirement and
1660  // most cases (such as broadcast or bluray) want rectangular slices
1661  // only it would need to be gated behind another option.
1662  if (avctx->slices > ctx->slice_block_rows) {
1663  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1664  "configured number of slices (%d < %d); using "
1665  "maximum.\n", ctx->slice_block_rows, avctx->slices);
1666  req_slices = ctx->slice_block_rows;
1667  } else {
1668  req_slices = avctx->slices;
1669  }
1670  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1671  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1672  ctx->nb_slices = req_slices;
1673  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1674  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1675  int k;
1676  for (k = 1;; k *= 2) {
1677  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1678  break;
1679  }
1680  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1681  ctx->slice_size = k;
1682 #if VA_CHECK_VERSION(1, 0, 0)
1683  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1684  ctx->nb_slices = ctx->slice_block_rows;
1685  ctx->slice_size = 1;
1686 #endif
1687  } else {
1688  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1689  "slice structure modes (%#x).\n", slice_structure);
1690  return AVERROR(EINVAL);
1691  }
1692 
1693  return 0;
1694 }
1695 
1697  uint32_t slice_structure)
1698 {
1699  VAAPIEncodeContext *ctx = avctx->priv_data;
1700  int i, req_tiles;
1701 
1702  if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
1703  (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
1704  ctx->tile_cols == 1))) {
1705  av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
1706  "current tile requirement.\n", slice_structure);
1707  return AVERROR(EINVAL);
1708  }
1709 
1710  if (ctx->tile_rows > ctx->slice_block_rows ||
1711  ctx->tile_cols > ctx->slice_block_cols) {
1712  av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
1713  "for configured number of tile (%d x %d); ",
1714  ctx->slice_block_rows, ctx->slice_block_cols,
1715  ctx->tile_rows, ctx->tile_cols);
1716  ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
1717  ctx->slice_block_rows : ctx->tile_rows;
1718  ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
1719  ctx->slice_block_cols : ctx->tile_cols;
1720  av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
1721  ctx->tile_rows, ctx->tile_cols);
1722  }
1723 
1724  req_tiles = ctx->tile_rows * ctx->tile_cols;
1725 
1726  // Tile slice is not allowed to cross the boundary of a tile due to
1727  // the constraints of media-driver. Currently we support one slice
1728  // per tile. This could be extended to multiple slices per tile.
1729  if (avctx->slices != req_tiles)
1730  av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
1731  "mismatches with configured number of tile (%d != %d); "
1732  "using requested tile number for slice.\n",
1733  avctx->slices, req_tiles);
1734 
1735  ctx->nb_slices = req_tiles;
1736 
1737  // Default in uniform spacing
1738  // 6-3, 6-5
1739  for (i = 0; i < ctx->tile_cols; i++) {
1740  ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
1741  i * ctx->slice_block_cols / ctx->tile_cols;
1742  ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
1743  }
1744  // 6-4, 6-6
1745  for (i = 0; i < ctx->tile_rows; i++) {
1746  ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
1747  i * ctx->slice_block_rows / ctx->tile_rows;
1748  ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
1749  }
1750 
1751  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
1752  ctx->tile_rows, ctx->tile_cols);
1753 
1754  return 0;
1755 }
1756 
1758 {
1759  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1760  VAAPIEncodeContext *ctx = avctx->priv_data;
1761  VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
1762  { VAConfigAttribEncSliceStructure },
1763 #if VA_CHECK_VERSION(1, 1, 0)
1764  { VAConfigAttribEncTileSupport },
1765 #endif
1766  };
1767  VAStatus vas;
1768  uint32_t max_slices, slice_structure;
1769  int ret;
1770 
1771  if (!(ctx->codec->flags & FF_HW_FLAG_SLICE_CONTROL)) {
1772  if (avctx->slices > 0) {
1773  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
1774  "but this codec does not support controlling slices.\n");
1775  }
1776  return 0;
1777  }
1778 
1779  av_assert0(base_ctx->slice_block_height > 0 && base_ctx->slice_block_width > 0);
1780 
1781  ctx->slice_block_rows = (avctx->height + base_ctx->slice_block_height - 1) /
1782  base_ctx->slice_block_height;
1783  ctx->slice_block_cols = (avctx->width + base_ctx->slice_block_width - 1) /
1784  base_ctx->slice_block_width;
1785 
1786  if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
1787  ctx->nb_slices = 1;
1788  ctx->slice_size = ctx->slice_block_rows;
1789  return 0;
1790  }
1791 
1792  vas = vaGetConfigAttributes(ctx->hwctx->display,
1793  ctx->va_profile,
1794  ctx->va_entrypoint,
1795  attr, FF_ARRAY_ELEMS(attr));
1796  if (vas != VA_STATUS_SUCCESS) {
1797  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
1798  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1799  return AVERROR_EXTERNAL;
1800  }
1801  max_slices = attr[0].value;
1802  slice_structure = attr[1].value;
1803  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1804  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1805  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1806  "pictures as multiple slices.\n.");
1807  return AVERROR(EINVAL);
1808  }
1809 
1810  if (ctx->tile_rows && ctx->tile_cols) {
1811 #if VA_CHECK_VERSION(1, 1, 0)
1812  uint32_t tile_support = attr[2].value;
1813  if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
1814  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1815  "pictures as multiple tiles.\n.");
1816  return AVERROR(EINVAL);
1817  }
1818 #else
1819  av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
1820  "not supported with this VAAPI version.\n");
1821  return AVERROR(EINVAL);
1822 #endif
1823  }
1824 
1825  if (ctx->tile_rows && ctx->tile_cols)
1826  ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
1827  else
1828  ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
1829  if (ret < 0)
1830  return ret;
1831 
1832  if (ctx->nb_slices > avctx->slices) {
1833  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
1834  "%d (from %d) due to driver constraints on slice "
1835  "structure.\n", ctx->nb_slices, avctx->slices);
1836  }
1837  if (ctx->nb_slices > max_slices) {
1838  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1839  "encoding with %d slices (max %"PRIu32").\n",
1840  ctx->nb_slices, max_slices);
1841  return AVERROR(EINVAL);
1842  }
1843 
1844  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
1845  ctx->nb_slices);
1846  return 0;
1847 }
1848 
1850 {
1851  VAAPIEncodeContext *ctx = avctx->priv_data;
1852  VAStatus vas;
1853  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1854 
1855  vas = vaGetConfigAttributes(ctx->hwctx->display,
1856  ctx->va_profile,
1857  ctx->va_entrypoint,
1858  &attr, 1);
1859  if (vas != VA_STATUS_SUCCESS) {
1860  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
1861  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1862  return AVERROR_EXTERNAL;
1863  }
1864 
1865  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1866  if (ctx->desired_packed_headers) {
1867  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
1868  "packed headers (wanted %#x).\n",
1869  ctx->desired_packed_headers);
1870  } else {
1871  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
1872  "packed headers (none wanted).\n");
1873  }
1874  ctx->va_packed_headers = 0;
1875  } else {
1876  if (ctx->desired_packed_headers & ~attr.value) {
1877  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
1878  "wanted packed headers (wanted %#x, found %#x).\n",
1879  ctx->desired_packed_headers, attr.value);
1880  } else {
1881  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
1882  "available (wanted %#x, found %#x).\n",
1883  ctx->desired_packed_headers, attr.value);
1884  }
1885  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
1886  }
1887 
1888  if (ctx->va_packed_headers) {
1889  ctx->config_attributes[ctx->nb_config_attributes++] =
1890  (VAConfigAttrib) {
1891  .type = VAConfigAttribEncPackedHeaders,
1892  .value = ctx->va_packed_headers,
1893  };
1894  }
1895 
1896  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1897  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1898  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
1899  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
1900  "sequence headers, but a global header is requested.\n");
1901  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
1902  "this may result in a stream which is not usable for some "
1903  "purposes (e.g. not muxable to some containers).\n");
1904  }
1905 
1906  return 0;
1907 }
1908 
1910 {
1911 #if VA_CHECK_VERSION(0, 36, 0)
1912  VAAPIEncodeContext *ctx = avctx->priv_data;
1913  VAStatus vas;
1914  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1915  int quality = avctx->compression_level;
1916 
1917  vas = vaGetConfigAttributes(ctx->hwctx->display,
1918  ctx->va_profile,
1919  ctx->va_entrypoint,
1920  &attr, 1);
1921  if (vas != VA_STATUS_SUCCESS) {
1922  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
1923  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1924  return AVERROR_EXTERNAL;
1925  }
1926 
1927  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1928  if (quality != 0) {
1929  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
1930  "supported: will use default quality level.\n");
1931  }
1932  } else {
1933  if (quality > attr.value) {
1934  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
1935  "valid range is 0-%d, using %d.\n",
1936  attr.value, attr.value);
1937  quality = attr.value;
1938  }
1939 
1940  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
1941  .quality_level = quality,
1942  };
1944  VAEncMiscParameterTypeQualityLevel,
1945  &ctx->quality_params,
1946  sizeof(ctx->quality_params));
1947  }
1948 #else
1949  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
1950  "not supported with this VAAPI version.\n");
1951 #endif
1952 
1953  return 0;
1954 }
1955 
1957 {
1958 #if VA_CHECK_VERSION(1, 0, 0)
1959  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1960  VAAPIEncodeContext *ctx = avctx->priv_data;
1961  VAStatus vas;
1962  VAConfigAttrib attr = { VAConfigAttribEncROI };
1963 
1964  vas = vaGetConfigAttributes(ctx->hwctx->display,
1965  ctx->va_profile,
1966  ctx->va_entrypoint,
1967  &attr, 1);
1968  if (vas != VA_STATUS_SUCCESS) {
1969  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
1970  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1971  return AVERROR_EXTERNAL;
1972  }
1973 
1974  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1975  base_ctx->roi_allowed = 0;
1976  } else {
1977  VAConfigAttribValEncROI roi = {
1978  .value = attr.value,
1979  };
1980 
1981  ctx->roi_max_regions = roi.bits.num_roi_regions;
1982  base_ctx->roi_allowed = ctx->roi_max_regions > 0 &&
1983  (ctx->va_rc_mode == VA_RC_CQP ||
1984  roi.bits.roi_rc_qp_delta_support);
1985  }
1986 #endif
1987  return 0;
1988 }
1989 
1991  void *obj)
1992 {
1993  AVCodecContext *avctx = opaque.nc;
1994  VAAPIEncodeContext *ctx = avctx->priv_data;
1995  VABufferID *buffer_id_ref = obj;
1996  VABufferID buffer_id = *buffer_id_ref;
1997 
1998  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1999 
2000  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2001 }
2002 
2004 {
2005  AVCodecContext *avctx = opaque.nc;
2006  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2007  VAAPIEncodeContext *ctx = avctx->priv_data;
2008  VABufferID *buffer_id = obj;
2009  VAStatus vas;
2010 
2011  // The output buffer size is fixed, so it needs to be large enough
2012  // to hold the largest possible compressed frame. We assume here
2013  // that the uncompressed frame plus some header data is an upper
2014  // bound on that.
2015  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2016  VAEncCodedBufferType,
2017  3 * base_ctx->surface_width * base_ctx->surface_height +
2018  (1 << 16), 1, 0, buffer_id);
2019  if (vas != VA_STATUS_SUCCESS) {
2020  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2021  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2022  return AVERROR(ENOMEM);
2023  }
2024 
2025  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", *buffer_id);
2026 
2027  return 0;
2028 }
2029 
2031 {
2032  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2033  VAAPIEncodeContext *ctx = avctx->priv_data;
2034  AVVAAPIHWConfig *hwconfig = NULL;
2035  enum AVPixelFormat recon_format;
2036  int err;
2037 
2038  hwconfig = av_hwdevice_hwconfig_alloc(base_ctx->device_ref);
2039  if (!hwconfig) {
2040  err = AVERROR(ENOMEM);
2041  goto fail;
2042  }
2043  hwconfig->config_id = ctx->va_config;
2044 
2045  err = ff_hw_base_get_recon_format(base_ctx, (const void*)hwconfig, &recon_format);
2046  if (err < 0)
2047  goto fail;
2048 
2049  base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
2050  if (!base_ctx->recon_frames_ref) {
2051  err = AVERROR(ENOMEM);
2052  goto fail;
2053  }
2054  base_ctx->recon_frames = (AVHWFramesContext*)base_ctx->recon_frames_ref->data;
2055 
2056  base_ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
2057  base_ctx->recon_frames->sw_format = recon_format;
2058  base_ctx->recon_frames->width = base_ctx->surface_width;
2059  base_ctx->recon_frames->height = base_ctx->surface_height;
2060 
2061  err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
2062  if (err < 0) {
2063  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2064  "frame context: %d.\n", err);
2065  goto fail;
2066  }
2067 
2068  err = 0;
2069  fail:
2070  av_freep(&hwconfig);
2071  return err;
2072 }
2073 
2075  .priv_size = sizeof(VAAPIEncodePicture),
2076 
2077  .init = &vaapi_encode_init,
2078 
2079  .issue = &vaapi_encode_issue,
2080 
2082 
2083  .free = &vaapi_encode_free,
2084 };
2085 
2087 {
2088  return ff_hw_base_encode_receive_packet(avctx->priv_data, avctx, pkt);
2089 }
2090 
2092 {
2093  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2094  VAAPIEncodeContext *ctx = avctx->priv_data;
2095  AVVAAPIFramesContext *recon_hwctx = NULL;
2096  VAStatus vas;
2097  int err;
2098 
2099  err = ff_hw_base_encode_init(avctx, base_ctx);
2100  if (err < 0)
2101  goto fail;
2102 
2103  ctx->va_config = VA_INVALID_ID;
2104  ctx->va_context = VA_INVALID_ID;
2105 
2106  base_ctx->op = &vaapi_op;
2107 
2108  ctx->hwctx = base_ctx->device->hwctx;
2109 
2110  err = vaapi_encode_profile_entrypoint(avctx);
2111  if (err < 0)
2112  goto fail;
2113 
2114  if (ctx->codec->get_encoder_caps) {
2115  err = ctx->codec->get_encoder_caps(avctx);
2116  if (err < 0)
2117  goto fail;
2118  } else {
2119  // Assume 16x16 blocks.
2120  base_ctx->surface_width = FFALIGN(avctx->width, 16);
2121  base_ctx->surface_height = FFALIGN(avctx->height, 16);
2122  if (ctx->codec->flags & FF_HW_FLAG_SLICE_CONTROL) {
2123  base_ctx->slice_block_width = 16;
2124  base_ctx->slice_block_height = 16;
2125  }
2126  }
2127 
2128  err = vaapi_encode_init_rate_control(avctx);
2129  if (err < 0)
2130  goto fail;
2131 
2132  err = vaapi_encode_init_gop_structure(avctx);
2133  if (err < 0)
2134  goto fail;
2135 
2136  err = vaapi_encode_init_slice_structure(avctx);
2137  if (err < 0)
2138  goto fail;
2139 
2140  err = vaapi_encode_init_packed_headers(avctx);
2141  if (err < 0)
2142  goto fail;
2143 
2144  err = vaapi_encode_init_roi(avctx);
2145  if (err < 0)
2146  goto fail;
2147 
2148  if (avctx->compression_level >= 0) {
2149  err = vaapi_encode_init_quality(avctx);
2150  if (err < 0)
2151  goto fail;
2152  }
2153 
2154  if (ctx->max_frame_size) {
2155  err = vaapi_encode_init_max_frame_size(avctx);
2156  if (err < 0)
2157  goto fail;
2158  }
2159 
2160  vas = vaCreateConfig(ctx->hwctx->display,
2161  ctx->va_profile, ctx->va_entrypoint,
2162  ctx->config_attributes, ctx->nb_config_attributes,
2163  &ctx->va_config);
2164  if (vas != VA_STATUS_SUCCESS) {
2165  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2166  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2167  err = AVERROR(EIO);
2168  goto fail;
2169  }
2170 
2171  err = vaapi_encode_create_recon_frames(avctx);
2172  if (err < 0)
2173  goto fail;
2174 
2175  recon_hwctx = base_ctx->recon_frames->hwctx;
2176  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2177  base_ctx->surface_width, base_ctx->surface_height,
2178  VA_PROGRESSIVE,
2179  recon_hwctx->surface_ids,
2180  recon_hwctx->nb_surfaces,
2181  &ctx->va_context);
2182  if (vas != VA_STATUS_SUCCESS) {
2183  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2184  "context: %d (%s).\n", vas, vaErrorStr(vas));
2185  err = AVERROR(EIO);
2186  goto fail;
2187  }
2188 
2189  ctx->output_buffer_pool =
2190  ff_refstruct_pool_alloc_ext(sizeof(VABufferID), 0, avctx,
2193  if (!ctx->output_buffer_pool) {
2194  err = AVERROR(ENOMEM);
2195  goto fail;
2196  }
2197 
2198  if (ctx->codec->configure) {
2199  err = ctx->codec->configure(avctx);
2200  if (err < 0)
2201  goto fail;
2202  }
2203 
2204  base_ctx->output_delay = base_ctx->b_per_p;
2205  base_ctx->decode_delay = base_ctx->max_b_depth;
2206 
2207  if (ctx->codec->sequence_params_size > 0) {
2208  ctx->codec_sequence_params =
2209  av_mallocz(ctx->codec->sequence_params_size);
2210  if (!ctx->codec_sequence_params) {
2211  err = AVERROR(ENOMEM);
2212  goto fail;
2213  }
2214  }
2215  if (ctx->codec->picture_params_size > 0) {
2216  ctx->codec_picture_params =
2217  av_mallocz(ctx->codec->picture_params_size);
2218  if (!ctx->codec_picture_params) {
2219  err = AVERROR(ENOMEM);
2220  goto fail;
2221  }
2222  }
2223 
2224  if (ctx->codec->init_sequence_params) {
2225  err = ctx->codec->init_sequence_params(avctx);
2226  if (err < 0) {
2227  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2228  "failed: %d.\n", err);
2229  goto fail;
2230  }
2231  }
2232 
2233  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2234  ctx->codec->write_sequence_header &&
2237  size_t bit_len = 8 * sizeof(data);
2238 
2239  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2240  if (err < 0) {
2241  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2242  "for extradata: %d.\n", err);
2243  goto fail;
2244  } else {
2245  avctx->extradata_size = (bit_len + 7) / 8;
2246  avctx->extradata = av_mallocz(avctx->extradata_size +
2248  if (!avctx->extradata) {
2249  err = AVERROR(ENOMEM);
2250  goto fail;
2251  }
2252  memcpy(avctx->extradata, data, avctx->extradata_size);
2253  }
2254  }
2255 
2256 #if VA_CHECK_VERSION(1, 9, 0)
2257  // check vaSyncBuffer function
2258  vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2259  if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2260  base_ctx->async_encode = 1;
2261  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
2262  sizeof(VAAPIEncodePicture*),
2263  0);
2264  if (!base_ctx->encode_fifo)
2265  return AVERROR(ENOMEM);
2266  }
2267 #endif
2268 
2269  return 0;
2270 
2271 fail:
2272  return err;
2273 }
2274 
2276 {
2277  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2278  VAAPIEncodeContext *ctx = avctx->priv_data;
2279  FFHWBaseEncodePicture *pic, *next;
2280 
2281  /* We check ctx->frame to know whether ff_vaapi_encode_init()
2282  * has been called and va_config/va_context initialized. */
2283  if (!base_ctx->frame)
2284  return 0;
2285 
2286  for (pic = base_ctx->pic_start; pic; pic = next) {
2287  next = pic->next;
2288  vaapi_encode_free(avctx, pic);
2289  }
2290 
2291  ff_refstruct_pool_uninit(&ctx->output_buffer_pool);
2292 
2293  if (ctx->va_context != VA_INVALID_ID) {
2294  if (ctx->hwctx)
2295  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2296  ctx->va_context = VA_INVALID_ID;
2297  }
2298 
2299  if (ctx->va_config != VA_INVALID_ID) {
2300  if (ctx->hwctx)
2301  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2302  ctx->va_config = VA_INVALID_ID;
2303  }
2304 
2305  av_freep(&ctx->codec_sequence_params);
2306  av_freep(&ctx->codec_picture_params);
2307 
2308  ff_hw_base_encode_close(base_ctx);
2309 
2310  return 0;
2311 }
FFHWBaseEncodeContext::output_delay
int64_t output_delay
Definition: hw_base_encode.h:169
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
VAAPIEncodeSlice::codec_slice_params
void * codec_slice_params
Definition: vaapi_encode.h:62
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
FFHWBaseEncodeContext::recon_frames_ref
AVBufferRef * recon_frames_ref
Definition: hw_base_encode.h:156
av_clip
#define av_clip
Definition: common.h:100
FF_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:39
RC_MODE_CBR
@ RC_MODE_CBR
Definition: d3d12va_encode.h:95
vaapi_encode_init_roi
static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
Definition: vaapi_encode.c:1956
ff_refstruct_ref
void * ff_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
FFHWBaseEncodePicture::next
struct FFHWBaseEncodePicture * next
Definition: hw_base_encode.h:67
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
AVVAAPIHWConfig
VAAPI hardware pipeline configuration details.
Definition: hwcontext_vaapi.h:110
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:951
FFHWBaseEncodePicture::priv
void * priv
Definition: hw_base_encode.h:63
av_clip_int8
#define av_clip_int8
Definition: common.h:109
av_hwdevice_hwconfig_alloc
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:555
FFHWBaseEncodePicture::codec_priv
void * codec_priv
Definition: hw_base_encode.h:65
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2965
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
vaapi_encode_make_row_slice
static int vaapi_encode_make_row_slice(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:186
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
VAAPIEncodePicture::tail_size
size_t tail_size
Byte length of tail_data.
Definition: vaapi_encode.h:97
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:197
AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
@ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
Definition: hwcontext_vaapi.h:47
RC_MODE_CQP
@ RC_MODE_CQP
Definition: d3d12va_encode.h:94
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:224
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
vaapi_encode_entrypoints_normal
static const VAEntrypoint vaapi_encode_entrypoints_normal[]
Definition: vaapi_encode.c:920
av_unused
#define av_unused
Definition: attributes.h:131
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
vaapi_encode_init_slice_structure
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:1757
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:322
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:248
AVPacket::data
uint8_t * data
Definition: packet.h:539
ff_hw_base_encode_init
int ff_hw_base_encode_init(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:772
VAAPIEncodeSlice
Definition: vaapi_encode.h:56
vaapi_encode_output
static int vaapi_encode_output(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
Definition: vaapi_encode.c:769
encode.h
data
const char data[16]
Definition: mxf.c:148
VAAPIEncodeSlice::block_start
int block_start
Definition: vaapi_encode.h:60
FFHWBaseEncodePicture::recon_image
AVFrame * recon_image
Definition: hw_base_encode.h:84
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
ff_vaapi_encode_close
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
Definition: vaapi_encode.c:2275
FFHWBaseEncodeContext::slice_block_width
int slice_block_width
Definition: hw_base_encode.h:144
FFRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
vaapi_encode_init_rate_control
static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
Definition: vaapi_encode.c:1157
VAAPIEncodeSlice::index
int index
Definition: vaapi_encode.h:57
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:217
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1273
FFHWBaseEncodeContext::roi_warned
int roi_warned
Definition: hw_base_encode.h:204
FFHWBaseEncodeContext::slice_block_height
int slice_block_height
Definition: hw_base_encode.h:145
VAAPIEncodeRTFormat::value
unsigned int value
Definition: vaapi_encode.c:894
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:338
FFHWBaseEncodeContext
Definition: hw_base_encode.h:122
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:566
AVVAAPIHWConfig::config_id
VAConfigID config_id
ID of a VAAPI pipeline configuration.
Definition: hwcontext_vaapi.h:114
AVVAAPIFramesContext::surface_ids
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
Definition: hwcontext_vaapi.h:101
FFHWBaseEncodePicture::type
int type
Definition: hw_base_encode.h:78
VAAPIEncodeSlice::row_start
int row_start
Definition: vaapi_encode.h:58
vaapi_encode.h
ff_hw_base_encode_close
int ff_hw_base_encode_close(FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:805
vaapi_encode_init_gop_structure
static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:1572
vaapi_encode_make_tile_slice
static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:241
fail
#define fail()
Definition: checkasm.h:188
ff_refstruct_pool_uninit
static void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
VAAPIEncodePicture
Definition: vaapi_encode.h:65
VAAPIEncodePicture::non_independent_frame
int non_independent_frame
indicate if current frame is an independent frame that the coded data can be pushed to downstream dir...
Definition: vaapi_encode.h:93
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:508
VAAPIEncodeRTFormat
Definition: vaapi_encode.c:892
FFHWBaseEncodePicture::input_image
AVFrame * input_image
Definition: hw_base_encode.h:83
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
TRY_RC_MODE
#define TRY_RC_MODE(mode, fail)
ff_hw_base_init_gop_structure
int ff_hw_base_init_gop_structure(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, uint32_t ref_l0, uint32_t ref_l1, int flags, int prediction_pre_only)
Definition: hw_base_encode.c:661
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
AVRational::num
int num
Numerator.
Definition: rational.h:59
refstruct.h
vaapi_encode_free
static int vaapi_encode_free(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: vaapi_encode.c:854
FFHWBaseEncodeContext::device
AVHWDeviceContext * device
Definition: hw_base_encode.h:149
vaapi_encode_rt_formats
static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[]
Definition: vaapi_encode.c:901
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
avassert.h
VAAPIEncodeRTFormat::log2_chroma_w
int log2_chroma_w
Definition: vaapi_encode.c:897
MAX_GLOBAL_PARAMS
@ MAX_GLOBAL_PARAMS
Definition: vaapi_encode.h:46
ff_hw_base_get_recon_format
int ff_hw_base_get_recon_format(FFHWBaseEncodeContext *ctx, const void *hwconfig, enum AVPixelFormat *fmt)
Definition: hw_base_encode.c:714
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
AVRegionOfInterest
Structure describing a single Region Of Interest.
Definition: frame.h:315
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
AVCodecContext::rc_initial_buffer_occupancy
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:1330
AVHWFramesContext::height
int height
Definition: hwcontext.h:217
VAAPIEncodeSlice::row_size
int row_size
Definition: vaapi_encode.h:59
VAAPIEncodePicture::codec_picture_params
void * codec_picture_params
Definition: vaapi_encode.h:83
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:530
FLAG_TIMESTAMP_NO_DELAY
#define FLAG_TIMESTAMP_NO_DELAY
Definition: vaapi_encode.h:42
FFHWBaseEncodeContext::tail_pkt
AVPacket * tail_pkt
Tail data of a pic, now only used for av1 repeat frame header.
Definition: hw_base_encode.h:220
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1249
vaapi_op
static const FFHWEncodePictureOperation vaapi_op
Definition: vaapi_encode.c:2074
AVRegionOfInterest::bottom
int bottom
Definition: frame.h:331
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1451
vaapi_encode_get_coded_data
static int vaapi_encode_get_coded_data(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:724
FFHWBaseEncodeContext::max_b_depth
int max_b_depth
Definition: hw_base_encode.h:188
vaapi_encode_make_param_buffer
static int vaapi_encode_make_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t len)
Definition: vaapi_encode.c:87
FFHWBaseEncodeContext::async_encode
int async_encode
Definition: hw_base_encode.h:212
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ff_vaapi_encode_receive_packet
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: vaapi_encode.c:2086
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1302
FFHWBaseEncodeContext::pic_start
FFHWBaseEncodePicture * pic_start
Definition: hw_base_encode.h:160
RC_MODE_ICQ
@ RC_MODE_ICQ
Definition: vaapi_encode.h:120
FFHWBaseEncodeContext::b_per_p
int b_per_p
Definition: hw_base_encode.h:189
VAAPIEncodeContext
Definition: vaapi_encode.h:145
if
if(ret)
Definition: filter_design.txt:179
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1287
FF_HW_FLAG_CONSTANT_QUALITY_ONLY
@ FF_HW_FLAG_CONSTANT_QUALITY_ONLY
Definition: hw_base_encode.h:49
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:210
FF_HW_FLAG_INTRA_ONLY
@ FF_HW_FLAG_INTRA_ONLY
Definition: hw_base_encode.h:51
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:501
RC_MODE_AVBR
@ RC_MODE_AVBR
Definition: vaapi_encode.h:122
MAX_PARAM_BUFFER_SIZE
@ MAX_PARAM_BUFFER_SIZE
Definition: vaapi_encode.h:47
AVRegionOfInterest::self_size
uint32_t self_size
Must be set to the size of this data structure (that is, sizeof(AVRegionOfInterest)).
Definition: frame.h:320
FFHWEncodePictureOperation
Definition: hw_base_encode.h:109
RC_MODE_VBR
@ RC_MODE_VBR
Definition: d3d12va_encode.h:96
index
int index
Definition: gxfenc.c:90
VAAPIEncodeRTFormat::name
const char * name
Definition: vaapi_encode.c:893
vaapi_encode_get_coded_buffer_size
static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID buf_id)
Definition: vaapi_encode.c:657
RC_MODE_QVBR
@ RC_MODE_QVBR
Definition: d3d12va_encode.h:97
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:550
ff_hw_base_encode_set_output_property
int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, FFHWBaseEncodePicture *pic, AVPacket *pkt, int flag_no_delay)
Definition: hw_base_encode.c:518
VAAPIEncodePicture::slices
VAAPIEncodeSlice * slices
Definition: vaapi_encode.h:86
VAAPIEncodePicture::input_surface
VASurfaceID input_surface
Definition: vaapi_encode.h:73
FFHWEncodePictureOperation::priv_size
size_t priv_size
Definition: hw_base_encode.h:111
vaapi_encode_discard
static int vaapi_encode_discard(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: vaapi_encode.c:817
FFHWBaseEncodeContext::frame
AVFrame * frame
Definition: hw_base_encode.h:207
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AVPacket::size
int size
Definition: packet.h:540
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1037
vaapi_encode_init_quality
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
Definition: vaapi_encode.c:1909
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
FFHWBaseEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: hw_base_encode.h:97
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
vaapi_encode_make_misc_param_buffer
static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, const void *data, size_t len)
Definition: vaapi_encode.c:115
vaapi_encode_rc_modes
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[]
Definition: vaapi_encode.c:1136
FFHWBaseEncodeContext::decode_delay
int64_t decode_delay
Definition: hw_base_encode.h:173
size
int size
Definition: twinvq_data.h:10344
ff_hw_base_encode_receive_packet
int ff_hw_base_encode_receive_packet(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, AVPacket *pkt)
Definition: hw_base_encode.c:557
FFRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
VAAPIEncodeRTFormat::nb_components
int nb_components
Definition: vaapi_encode.c:896
AVCodecHWConfigInternal
Definition: hwconfig.h:25
FFHWBaseEncodeContext::p_to_gpb
int p_to_gpb
Definition: hw_base_encode.h:194
vaapi_encode_issue
static int vaapi_encode_issue(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: vaapi_encode.c:268
header
static const uint8_t header[24]
Definition: sdr2.c:68
FFHWBaseEncodePicture::encode_order
int64_t encode_order
Definition: hw_base_encode.h:70
VAAPIEncodeRTFormat::log2_chroma_h
int log2_chroma_h
Definition: vaapi_encode.c:898
FF_HW_FLAG_SLICE_CONTROL
@ FF_HW_FLAG_SLICE_CONTROL
Definition: hw_base_encode.h:47
VAAPIEncodePicture::recon_surface
VASurfaceID recon_surface
Definition: vaapi_encode.h:74
vaapi_encode_free_output_buffer
static void vaapi_encode_free_output_buffer(FFRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:1990
vaapi_encode_init_packed_headers
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
Definition: vaapi_encode.c:1849
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
VAAPIEncodePicture::output_buffer
VABufferID output_buffer
Definition: vaapi_encode.h:81
vaapi_encode_create_recon_frames
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
Definition: vaapi_encode.c:2030
FFHWBaseEncodeContext::roi_allowed
int roi_allowed
Definition: hw_base_encode.h:197
AVRegionOfInterest::right
int right
Definition: frame.h:333
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:98
AVRegionOfInterest::left
int left
Definition: frame.h:332
log.h
FFHWBaseEncodeContext::op
const struct FFHWEncodePictureOperation * op
Definition: hw_base_encode.h:127
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:529
AVRegionOfInterest::top
int top
Distance in pixels from the top edge of the frame to the top and bottom edges and from the left edge ...
Definition: frame.h:330
internal.h
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
VAAPIEncodePicture::roi
void * roi
Definition: vaapi_encode.h:70
common.h
FFHWBaseEncodePicture::refs
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: hw_base_encode.h:98
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2228
AVCodecContext::height
int height
Definition: avcodec.h:624
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
VAAPIEncodePicture::tail_data
char tail_data[MAX_PARAM_BUFFER_SIZE]
Tail data of current pic, used only for repeat header of AV1.
Definition: vaapi_encode.h:95
ff_vaapi_encode_hw_configs
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]
Definition: vaapi_encode.c:36
vaapi_encode_alloc_output_buffer
static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:2003
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2091
ret
ret
Definition: filter_design.txt:187
VAAPIEncodeRTFormat::depth
int depth
Definition: vaapi_encode.c:895
vaapi_encode_add_global_param
static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type, void *buffer, size_t size)
Definition: vaapi_encode.c:878
FFHWBaseEncodePicture
Definition: hw_base_encode.h:61
frame
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
Definition: filter_design.txt:264
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:150
FFHWBaseEncodeContext::device_ref
AVBufferRef * device_ref
Definition: hw_base_encode.h:148
FFHWBaseEncodeContext::encode_fifo
AVFifo * encode_fifo
Definition: hw_base_encode.h:215
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
VAAPIEncodePicture::param_buffers
VABufferID * param_buffers
Definition: vaapi_encode.h:77
ff_hw_base_encode_get_pictype_name
static const char * ff_hw_base_encode_get_pictype_name(const int type)
Definition: hw_base_encode.h:32
FFHWBaseEncodeContext::surface_height
int surface_height
Definition: hw_base_encode.h:141
FFHWBaseEncodeContext::async_depth
int async_depth
Definition: hw_base_encode.h:217
AVCodecContext
main external API structure.
Definition: avcodec.h:451
AVVAAPIFramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_vaapi.h:102
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:106
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1266
AVRational::den
int den
Denominator.
Definition: rational.h:60
ff_refstruct_pool_alloc_ext
static FFRefStructPool * ff_refstruct_pool_alloc_ext(size_t size, unsigned flags, void *opaque, int(*init_cb)(FFRefStructOpaque opaque, void *obj), void(*reset_cb)(FFRefStructOpaque opaque, void *obj), void(*free_entry_cb)(FFRefStructOpaque opaque, void *obj), void(*free_cb)(FFRefStructOpaque opaque))
A wrapper around ff_refstruct_pool_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:258
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1650
vaapi_encode_wait
static int vaapi_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: vaapi_encode.c:138
FFHWBaseEncodeContext::input_frames
AVHWFramesContext * input_frames
Definition: hw_base_encode.h:153
FFHWBaseEncodeContext::surface_width
int surface_width
Definition: hw_base_encode.h:140
vaapi_encode_init_tile_slice_structure
static av_cold int vaapi_encode_init_tile_slice_structure(AVCodecContext *avctx, uint32_t slice_structure)
Definition: vaapi_encode.c:1696
VAAPIEncodePicture::output_buffer_ref
VABufferID * output_buffer_ref
Definition: vaapi_encode.h:80
desc
const char * desc
Definition: libsvtav1.c:79
FFHWBaseEncodePicture::encode_complete
int encode_complete
Definition: hw_base_encode.h:81
mem.h
VAAPIEncodeSlice::block_size
int block_size
Definition: vaapi_encode.h:61
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:265
VAAPIEncodeRCMode
Definition: vaapi_encode.h:126
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVVAAPIFramesContext
VAAPI-specific data associated with a frame pool.
Definition: hwcontext_vaapi.h:88
vaapi_encode_get_coded_buffer_data
static int vaapi_encode_get_coded_buffer_data(AVCodecContext *avctx, VABufferID buf_id, uint8_t **dst)
Definition: vaapi_encode.c:688
vaapi_encode_profile_entrypoint
static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
Definition: vaapi_encode.c:935
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1053
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:624
FFHWBaseEncodeContext::recon_frames
AVHWFramesContext * recon_frames
Definition: hw_base_encode.h:157
AV_FRAME_DATA_REGIONS_OF_INTEREST
@ AV_FRAME_DATA_REGIONS_OF_INTEREST
Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of array element is ...
Definition: frame.h:165
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
vaapi_encode_init_max_frame_size
static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
Definition: vaapi_encode.c:1515
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAAPIEncodePicture::nb_param_buffers
int nb_param_buffers
Definition: vaapi_encode.h:76
FFHWBaseEncodePicture::encode_issued
int encode_issued
Definition: hw_base_encode.h:80
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:227
rc_mode
mfxU16 rc_mode
Definition: qsvenc.c:143
FFHWBaseEncodePicture::display_order
int64_t display_order
Definition: hw_base_encode.h:69
vaapi_encode_make_packed_header
static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t bit_len)
Definition: vaapi_encode.c:41
AVRegionOfInterest::qoffset
AVRational qoffset
Quantisation offset.
Definition: frame.h:357
snprintf
#define snprintf
Definition: snprintf.h:34
vaapi_encode_init
static int vaapi_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: vaapi_encode.c:835
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
vaapi_encode_init_row_slice_structure
static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx, uint32_t slice_structure)
Definition: vaapi_encode.c:1651
VAAPIEncodeProfile
Definition: vaapi_encode.h:100
ff_refstruct_pool_get
void * ff_refstruct_pool_get(FFRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297
AVCodecContext::compression_level
int compression_level
Definition: avcodec.h:1255
VAAPIEncodePicture::nb_slices
int nb_slices
Definition: vaapi_encode.h:85