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 "libavutil/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 = av_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  av_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 = av_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 {
1138 #if VA_CHECK_VERSION(1, 21, 0)
1139  VAAPIEncodeContext *ctx = avctx->priv_data;
1140  VASurfaceAttrib *attr_list = NULL;
1141  unsigned int attr_count = 0;
1142  VAConfigID va_config;
1143  VAStatus vas;
1144  int err = 0;
1145 
1146  vas = vaCreateConfig(ctx->hwctx->display,
1147  ctx->va_profile, ctx->va_entrypoint,
1148  NULL, 0, &va_config);
1149  if (vas != VA_STATUS_SUCCESS) {
1150  av_log(avctx, AV_LOG_ERROR, "Failed to create temp encode pipeline "
1151  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1152  return AVERROR(EIO);
1153  }
1154 
1155  vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
1156  0, &attr_count);
1157  if (vas != VA_STATUS_SUCCESS) {
1158  av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
1159  "%d (%s).\n", vas, vaErrorStr(vas));
1160  err = AVERROR_EXTERNAL;
1161  goto fail;
1162  }
1163 
1164  attr_list = av_malloc(attr_count * sizeof(*attr_list));
1165  if (!attr_list) {
1166  err = AVERROR(ENOMEM);
1167  goto fail;
1168  }
1169 
1170  vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
1171  attr_list, &attr_count);
1172  if (vas != VA_STATUS_SUCCESS) {
1173  av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
1174  "%d (%s).\n", vas, vaErrorStr(vas));
1175  err = AVERROR_EXTERNAL;
1176  goto fail;
1177  }
1178 
1179  for (unsigned int i = 0; i < attr_count; i++) {
1180  if (attr_list[i].type == VASurfaceAttribAlignmentSize) {
1181  ctx->surface_alignment_width =
1182  1 << (attr_list[i].value.value.i & 0xf);
1183  ctx->surface_alignment_height =
1184  1 << ((attr_list[i].value.value.i & 0xf0) >> 4);
1185  break;
1186  }
1187  }
1188 
1189 fail:
1190  av_freep(&attr_list);
1191  vaDestroyConfig(ctx->hwctx->display, va_config);
1192  return err;
1193 #else
1194  return 0;
1195 #endif
1196 }
1197 
1199  // Bitrate Quality
1200  // | Maxrate | HRD/VBV
1201  { 0 }, // | | | |
1202  { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
1203  { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
1204  { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
1205 #if VA_CHECK_VERSION(1, 1, 0)
1206  { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
1207 #else
1208  { RC_MODE_ICQ, "ICQ", 0 },
1209 #endif
1210 #if VA_CHECK_VERSION(1, 3, 0)
1211  { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
1212  { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
1213 #else
1214  { RC_MODE_QVBR, "QVBR", 0 },
1215  { RC_MODE_AVBR, "AVBR", 0 },
1216 #endif
1217 };
1218 
1220 {
1221  VAAPIEncodeContext *ctx = avctx->priv_data;
1222  uint32_t supported_va_rc_modes;
1223  const VAAPIEncodeRCMode *rc_mode;
1224  int64_t rc_bits_per_second;
1225  int rc_target_percentage;
1226  int rc_window_size;
1227  int rc_quality;
1228  int64_t hrd_buffer_size;
1229  int64_t hrd_initial_buffer_fullness;
1230  int fr_num, fr_den;
1231  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1232  VAStatus vas;
1233  char supported_rc_modes_string[64];
1234 
1235  vas = vaGetConfigAttributes(ctx->hwctx->display,
1236  ctx->va_profile, ctx->va_entrypoint,
1237  &rc_attr, 1);
1238  if (vas != VA_STATUS_SUCCESS) {
1239  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1240  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1241  return AVERROR_EXTERNAL;
1242  }
1243  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1244  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1245  "supported rate control modes: assuming CQP only.\n");
1246  supported_va_rc_modes = VA_RC_CQP;
1247  strcpy(supported_rc_modes_string, "unknown");
1248  } else {
1249  char *str = supported_rc_modes_string;
1250  size_t len = sizeof(supported_rc_modes_string);
1251  int i, first = 1, res;
1252 
1253  supported_va_rc_modes = rc_attr.value;
1254  if (ctx->blbrc) {
1255 #if VA_CHECK_VERSION(0, 39, 2)
1256  if (!(supported_va_rc_modes & VA_RC_MB)) {
1257  ctx->blbrc = 0;
1258  av_log(avctx, AV_LOG_WARNING, "Driver does not support BLBRC.\n");
1259  }
1260 #else
1261  ctx->blbrc = 0;
1262  av_log(avctx, AV_LOG_WARNING, "Please consider to update to VAAPI 0.39.2 "
1263  "or above, which can support BLBRC.\n");
1264 #endif
1265  }
1266 
1267  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1269  if (supported_va_rc_modes & rc_mode->va_mode) {
1270  res = snprintf(str, len, "%s%s",
1271  first ? "" : ", ", rc_mode->name);
1272  first = 0;
1273  if (res < 0) {
1274  *str = 0;
1275  break;
1276  }
1277  len -= res;
1278  str += res;
1279  if (len == 0)
1280  break;
1281  }
1282  }
1283 
1284  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1285  supported_rc_modes_string);
1286  }
1287 
1288  // Rate control mode selection:
1289  // * If the user has set a mode explicitly with the rc_mode option,
1290  // use it and fail if it is not available.
1291  // * If an explicit QP option has been set, use CQP.
1292  // * If the codec is CQ-only, use CQP.
1293  // * If the QSCALE avcodec option is set, use CQP.
1294  // * If bitrate and quality are both set, try QVBR.
1295  // * If quality is set, try ICQ, then CQP.
1296  // * If bitrate and maxrate are set and have the same value, try CBR.
1297  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1298  // * If no bitrate is set, try ICQ, then CQP.
1299 
1300 #define TRY_RC_MODE(mode, fail) do { \
1301  rc_mode = &vaapi_encode_rc_modes[mode]; \
1302  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1303  if (fail) { \
1304  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1305  "RC mode (supported modes: %s).\n", rc_mode->name, \
1306  supported_rc_modes_string); \
1307  return AVERROR(EINVAL); \
1308  } \
1309  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1310  "RC mode.\n", rc_mode->name); \
1311  rc_mode = NULL; \
1312  } else { \
1313  goto rc_mode_found; \
1314  } \
1315  } while (0)
1316 
1317  if (ctx->explicit_rc_mode)
1318  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1319 
1320  if (ctx->explicit_qp)
1322 
1325 
1326  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1328 
1329  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1331 
1332  if (avctx->global_quality > 0) {
1335  }
1336 
1337  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1339 
1340  if (avctx->bit_rate > 0) {
1344  } else {
1347  }
1348 
1349  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1350  "RC mode compatible with selected options "
1351  "(supported modes: %s).\n", supported_rc_modes_string);
1352  return AVERROR(EINVAL);
1353 
1354 rc_mode_found:
1355  if (rc_mode->bitrate) {
1356  if (avctx->bit_rate <= 0) {
1357  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1358  "RC mode.\n", rc_mode->name);
1359  return AVERROR(EINVAL);
1360  }
1361 
1362  if (rc_mode->mode == RC_MODE_AVBR) {
1363  // For maximum confusion AVBR is hacked into the existing API
1364  // by overloading some of the fields with completely different
1365  // meanings.
1366 
1367  // Target percentage does not apply in AVBR mode.
1368  rc_bits_per_second = avctx->bit_rate;
1369 
1370  // Accuracy tolerance range for meeting the specified target
1371  // bitrate. It's very unclear how this is actually intended
1372  // to work - since we do want to get the specified bitrate,
1373  // set the accuracy to 100% for now.
1374  rc_target_percentage = 100;
1375 
1376  // Convergence period in frames. The GOP size reflects the
1377  // user's intended block size for cutting, so reusing that
1378  // as the convergence period seems a reasonable default.
1379  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1380 
1381  } else if (rc_mode->maxrate) {
1382  if (avctx->rc_max_rate > 0) {
1383  if (avctx->rc_max_rate < avctx->bit_rate) {
1384  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1385  "bitrate (%"PRId64") must not be greater than "
1386  "maxrate (%"PRId64").\n", avctx->bit_rate,
1387  avctx->rc_max_rate);
1388  return AVERROR(EINVAL);
1389  }
1390  rc_bits_per_second = avctx->rc_max_rate;
1391  rc_target_percentage = (avctx->bit_rate * 100) /
1392  avctx->rc_max_rate;
1393  } else {
1394  // We only have a target bitrate, but this mode requires
1395  // that a maximum rate be supplied as well. Since the
1396  // user does not want this to be a constraint, arbitrarily
1397  // pick a maximum rate of double the target rate.
1398  rc_bits_per_second = 2 * avctx->bit_rate;
1399  rc_target_percentage = 50;
1400  }
1401  } else {
1402  if (avctx->rc_max_rate > avctx->bit_rate) {
1403  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1404  "in %s RC mode.\n", rc_mode->name);
1405  }
1406  rc_bits_per_second = avctx->bit_rate;
1407  rc_target_percentage = 100;
1408  }
1409  } else {
1410  rc_bits_per_second = 0;
1411  rc_target_percentage = 100;
1412  }
1413 
1414  if (rc_mode->quality) {
1415  if (ctx->explicit_qp) {
1416  rc_quality = ctx->explicit_qp;
1417  } else if (avctx->global_quality > 0) {
1418  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1419  rc_quality = avctx->global_quality / FF_QP2LAMBDA;
1420  else
1421  rc_quality = avctx->global_quality;
1422  } else {
1423  rc_quality = ctx->codec->default_quality;
1424  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1425  "using default (%d).\n", rc_quality);
1426  }
1427  } else {
1428  rc_quality = 0;
1429  }
1430 
1431  if (rc_mode->hrd) {
1432  if (avctx->rc_buffer_size)
1433  hrd_buffer_size = avctx->rc_buffer_size;
1434  else if (avctx->rc_max_rate > 0)
1435  hrd_buffer_size = avctx->rc_max_rate;
1436  else
1437  hrd_buffer_size = avctx->bit_rate;
1438  if (avctx->rc_initial_buffer_occupancy) {
1439  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1440  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1441  "must have initial buffer size (%d) <= "
1442  "buffer size (%"PRId64").\n",
1443  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1444  return AVERROR(EINVAL);
1445  }
1446  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1447  } else {
1448  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1449  }
1450 
1451  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1452  } else {
1453  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
1454  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
1455  "in %s RC mode.\n", rc_mode->name);
1456  }
1457 
1458  hrd_buffer_size = 0;
1459  hrd_initial_buffer_fullness = 0;
1460 
1461  if (rc_mode->mode != RC_MODE_AVBR) {
1462  // Already set (with completely different meaning) for AVBR.
1463  rc_window_size = 1000;
1464  }
1465  }
1466 
1467  if (rc_bits_per_second > UINT32_MAX ||
1468  hrd_buffer_size > UINT32_MAX ||
1469  hrd_initial_buffer_fullness > UINT32_MAX) {
1470  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1471  "greater are not supported by VAAPI.\n");
1472  return AVERROR(EINVAL);
1473  }
1474 
1475  ctx->rc_mode = rc_mode;
1476  ctx->rc_quality = rc_quality;
1477  ctx->va_rc_mode = rc_mode->va_mode;
1478  ctx->va_bit_rate = rc_bits_per_second;
1479 
1480  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
1481 
1482  if (ctx->blbrc && ctx->va_rc_mode == VA_RC_CQP)
1483  ctx->blbrc = 0;
1484  av_log(avctx, AV_LOG_VERBOSE, "Block Level bitrate control: %s.\n", ctx->blbrc ? "ON" : "OFF");
1485 
1486  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1487  // This driver does not want the RC mode attribute to be set.
1488  } else {
1489  ctx->config_attributes[ctx->nb_config_attributes++] =
1490  (VAConfigAttrib) {
1491  .type = VAConfigAttribRateControl,
1492 #if VA_CHECK_VERSION(0, 39, 2)
1493  .value = ctx->blbrc ? ctx->va_rc_mode | VA_RC_MB : ctx->va_rc_mode,
1494 #else
1495  .value = ctx->va_rc_mode,
1496 #endif
1497  };
1498  }
1499 
1500  if (rc_mode->quality)
1501  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
1502 
1503  if (rc_mode->va_mode != VA_RC_CQP) {
1504  if (rc_mode->mode == RC_MODE_AVBR) {
1505  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
1506  "converging in %d frames with %d%% accuracy.\n",
1507  rc_bits_per_second, rc_window_size,
1508  rc_target_percentage);
1509  } else if (rc_mode->bitrate) {
1510  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
1511  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
1512  rc_bits_per_second, rc_window_size);
1513  }
1514 
1515  ctx->rc_params = (VAEncMiscParameterRateControl) {
1516  .bits_per_second = rc_bits_per_second,
1517  .target_percentage = rc_target_percentage,
1518  .window_size = rc_window_size,
1519  .initial_qp = 0,
1520  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
1521  .basic_unit_size = 0,
1522 #if VA_CHECK_VERSION(1, 1, 0)
1523  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
1524  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
1525 #endif
1526 #if VA_CHECK_VERSION(1, 3, 0)
1527  .quality_factor = rc_quality,
1528 #endif
1529 #if VA_CHECK_VERSION(0, 39, 2)
1530  .rc_flags.bits.mb_rate_control = ctx->blbrc ? 1 : 2,
1531 #endif
1532  };
1534  VAEncMiscParameterTypeRateControl,
1535  &ctx->rc_params,
1536  sizeof(ctx->rc_params));
1537  }
1538 
1539  if (rc_mode->hrd) {
1540  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1541  "initial fullness %"PRId64" bits.\n",
1542  hrd_buffer_size, hrd_initial_buffer_fullness);
1543 
1544  ctx->hrd_params = (VAEncMiscParameterHRD) {
1545  .initial_buffer_fullness = hrd_initial_buffer_fullness,
1546  .buffer_size = hrd_buffer_size,
1547  };
1549  VAEncMiscParameterTypeHRD,
1550  &ctx->hrd_params,
1551  sizeof(ctx->hrd_params));
1552  }
1553 
1554  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1555  av_reduce(&fr_num, &fr_den,
1556  avctx->framerate.num, avctx->framerate.den, 65535);
1557  else
1558  av_reduce(&fr_num, &fr_den,
1559  avctx->time_base.den, avctx->time_base.num, 65535);
1560 
1561  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
1562  fr_num, fr_den, (double)fr_num / fr_den);
1563 
1564  ctx->fr_params = (VAEncMiscParameterFrameRate) {
1565  .framerate = (unsigned int)fr_den << 16 | fr_num,
1566  };
1567 #if VA_CHECK_VERSION(0, 40, 0)
1569  VAEncMiscParameterTypeFrameRate,
1570  &ctx->fr_params,
1571  sizeof(ctx->fr_params));
1572 #endif
1573 
1574  return 0;
1575 }
1576 
1578 {
1579 #if VA_CHECK_VERSION(1, 5, 0)
1580  VAAPIEncodeContext *ctx = avctx->priv_data;
1581  VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
1582  VAStatus vas;
1583 
1584  if (ctx->va_rc_mode == VA_RC_CQP) {
1585  ctx->max_frame_size = 0;
1586  av_log(avctx, AV_LOG_ERROR, "Max frame size is invalid in CQP rate "
1587  "control mode.\n");
1588  return AVERROR(EINVAL);
1589  }
1590 
1591  vas = vaGetConfigAttributes(ctx->hwctx->display,
1592  ctx->va_profile,
1593  ctx->va_entrypoint,
1594  &attr, 1);
1595  if (vas != VA_STATUS_SUCCESS) {
1596  ctx->max_frame_size = 0;
1597  av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
1598  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1599  return AVERROR_EXTERNAL;
1600  }
1601 
1602  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1603  ctx->max_frame_size = 0;
1604  av_log(avctx, AV_LOG_ERROR, "Max frame size attribute "
1605  "is not supported.\n");
1606  return AVERROR(EINVAL);
1607  } else {
1608  VAConfigAttribValMaxFrameSize attr_mfs;
1609  attr_mfs.value = attr.value;
1610  // Prefer to use VAEncMiscParameterTypeMaxFrameSize for max frame size.
1611  if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
1612  ctx->max_frame_size = 0;
1613  av_log(avctx, AV_LOG_ERROR, "Driver only supports multiple pass "
1614  "max frame size which has not been implemented in FFmpeg.\n");
1615  return AVERROR(EINVAL);
1616  }
1617 
1618  ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
1619  .max_frame_size = ctx->max_frame_size * 8,
1620  };
1621 
1622  av_log(avctx, AV_LOG_VERBOSE, "Set max frame size: %d bytes.\n",
1623  ctx->max_frame_size);
1624  }
1625 #else
1626  av_log(avctx, AV_LOG_ERROR, "The max frame size option is not supported with "
1627  "this VAAPI version.\n");
1628  return AVERROR(EINVAL);
1629 #endif
1630 
1631  return 0;
1632 }
1633 
1635 {
1636  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1637  VAAPIEncodeContext *ctx = avctx->priv_data;
1638  VAStatus vas;
1639  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1640  uint32_t ref_l0, ref_l1;
1641  int prediction_pre_only, err;
1642 
1643  vas = vaGetConfigAttributes(ctx->hwctx->display,
1644  ctx->va_profile,
1645  ctx->va_entrypoint,
1646  &attr, 1);
1647  if (vas != VA_STATUS_SUCCESS) {
1648  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
1649  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1650  return AVERROR_EXTERNAL;
1651  }
1652 
1653  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1654  ref_l0 = ref_l1 = 0;
1655  } else {
1656  ref_l0 = attr.value & 0xffff;
1657  ref_l1 = attr.value >> 16 & 0xffff;
1658  }
1659 
1660  base_ctx->p_to_gpb = 0;
1661  prediction_pre_only = 0;
1662 
1663 #if VA_CHECK_VERSION(1, 9, 0)
1664  if (!(ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||
1665  avctx->gop_size <= 1)) {
1666  attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
1667  vas = vaGetConfigAttributes(ctx->hwctx->display,
1668  ctx->va_profile,
1669  ctx->va_entrypoint,
1670  &attr, 1);
1671  if (vas != VA_STATUS_SUCCESS) {
1672  av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
1673  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1674  return AVERROR_EXTERNAL;
1675  } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1676  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
1677  "prediction constraints.\n");
1678  } else {
1679  if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
1680  ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
1681  av_log(avctx, AV_LOG_ERROR, "Driver report incorrect prediction "
1682  "direction attribute.\n");
1683  return AVERROR_EXTERNAL;
1684  }
1685 
1686  if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
1687  if (ref_l0 > 0 && ref_l1 > 0) {
1688  prediction_pre_only = 1;
1689  av_log(avctx, AV_LOG_VERBOSE, "Driver only support same reference "
1690  "lists for B-frames.\n");
1691  }
1692  }
1693 
1694  if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
1695  if (ref_l0 > 0 && ref_l1 > 0) {
1696  base_ctx->p_to_gpb = 1;
1697  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
1698  "replacing them with B-frames.\n");
1699  }
1700  }
1701  }
1702  }
1703 #endif
1704 
1705  err = ff_hw_base_init_gop_structure(base_ctx, avctx, ref_l0, ref_l1,
1706  ctx->codec->flags, prediction_pre_only);
1707  if (err < 0)
1708  return err;
1709 
1710  return 0;
1711 }
1712 
1714  uint32_t slice_structure)
1715 {
1716  VAAPIEncodeContext *ctx = avctx->priv_data;
1717  int req_slices;
1718 
1719  // For fixed-size slices currently we only support whole rows, making
1720  // rectangular slices. This could be extended to arbitrary runs of
1721  // blocks, but since slices tend to be a conformance requirement and
1722  // most cases (such as broadcast or bluray) want rectangular slices
1723  // only it would need to be gated behind another option.
1724  if (avctx->slices > ctx->slice_block_rows) {
1725  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1726  "configured number of slices (%d < %d); using "
1727  "maximum.\n", ctx->slice_block_rows, avctx->slices);
1728  req_slices = ctx->slice_block_rows;
1729  } else {
1730  req_slices = avctx->slices;
1731  }
1732  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1733  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1734  ctx->nb_slices = req_slices;
1735  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1736  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1737  int k;
1738  for (k = 1;; k *= 2) {
1739  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1740  break;
1741  }
1742  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1743  ctx->slice_size = k;
1744 #if VA_CHECK_VERSION(1, 0, 0)
1745  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1746  ctx->nb_slices = ctx->slice_block_rows;
1747  ctx->slice_size = 1;
1748 #endif
1749  } else {
1750  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1751  "slice structure modes (%#x).\n", slice_structure);
1752  return AVERROR(EINVAL);
1753  }
1754 
1755  return 0;
1756 }
1757 
1759  uint32_t slice_structure)
1760 {
1761  VAAPIEncodeContext *ctx = avctx->priv_data;
1762  int i, req_tiles;
1763 
1764  if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
1765  (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
1766  ctx->tile_cols == 1))) {
1767  av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
1768  "current tile requirement.\n", slice_structure);
1769  return AVERROR(EINVAL);
1770  }
1771 
1772  if (ctx->tile_rows > ctx->slice_block_rows ||
1773  ctx->tile_cols > ctx->slice_block_cols) {
1774  av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
1775  "for configured number of tile (%d x %d); ",
1776  ctx->slice_block_rows, ctx->slice_block_cols,
1777  ctx->tile_rows, ctx->tile_cols);
1778  ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
1779  ctx->slice_block_rows : ctx->tile_rows;
1780  ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
1781  ctx->slice_block_cols : ctx->tile_cols;
1782  av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
1783  ctx->tile_rows, ctx->tile_cols);
1784  }
1785 
1786  req_tiles = ctx->tile_rows * ctx->tile_cols;
1787 
1788  // Tile slice is not allowed to cross the boundary of a tile due to
1789  // the constraints of media-driver. Currently we support one slice
1790  // per tile. This could be extended to multiple slices per tile.
1791  if (avctx->slices != req_tiles)
1792  av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
1793  "mismatches with configured number of tile (%d != %d); "
1794  "using requested tile number for slice.\n",
1795  avctx->slices, req_tiles);
1796 
1797  ctx->nb_slices = req_tiles;
1798 
1799  // Default in uniform spacing
1800  // 6-3, 6-5
1801  for (i = 0; i < ctx->tile_cols; i++) {
1802  ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
1803  i * ctx->slice_block_cols / ctx->tile_cols;
1804  ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
1805  }
1806  // 6-4, 6-6
1807  for (i = 0; i < ctx->tile_rows; i++) {
1808  ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
1809  i * ctx->slice_block_rows / ctx->tile_rows;
1810  ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
1811  }
1812 
1813  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
1814  ctx->tile_rows, ctx->tile_cols);
1815 
1816  return 0;
1817 }
1818 
1820 {
1821  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1822  VAAPIEncodeContext *ctx = avctx->priv_data;
1823  VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
1824  { VAConfigAttribEncSliceStructure },
1825 #if VA_CHECK_VERSION(1, 1, 0)
1826  { VAConfigAttribEncTileSupport },
1827 #endif
1828  };
1829  VAStatus vas;
1830  uint32_t max_slices, slice_structure;
1831  int ret;
1832 
1833  if (!(ctx->codec->flags & FF_HW_FLAG_SLICE_CONTROL)) {
1834  if (avctx->slices > 0) {
1835  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
1836  "but this codec does not support controlling slices.\n");
1837  }
1838  return 0;
1839  }
1840 
1841  av_assert0(base_ctx->slice_block_height > 0 && base_ctx->slice_block_width > 0);
1842 
1843  ctx->slice_block_rows = (avctx->height + base_ctx->slice_block_height - 1) /
1844  base_ctx->slice_block_height;
1845  ctx->slice_block_cols = (avctx->width + base_ctx->slice_block_width - 1) /
1846  base_ctx->slice_block_width;
1847 
1848  if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
1849  ctx->nb_slices = 1;
1850  ctx->slice_size = ctx->slice_block_rows;
1851  return 0;
1852  }
1853 
1854  vas = vaGetConfigAttributes(ctx->hwctx->display,
1855  ctx->va_profile,
1856  ctx->va_entrypoint,
1857  attr, FF_ARRAY_ELEMS(attr));
1858  if (vas != VA_STATUS_SUCCESS) {
1859  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
1860  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1861  return AVERROR_EXTERNAL;
1862  }
1863  max_slices = attr[0].value;
1864  slice_structure = attr[1].value;
1865  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1866  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1867  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1868  "pictures as multiple slices.\n.");
1869  return AVERROR(EINVAL);
1870  }
1871 
1872  if (ctx->tile_rows && ctx->tile_cols) {
1873 #if VA_CHECK_VERSION(1, 1, 0)
1874  uint32_t tile_support = attr[2].value;
1875  if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
1876  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1877  "pictures as multiple tiles.\n.");
1878  return AVERROR(EINVAL);
1879  }
1880 #else
1881  av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
1882  "not supported with this VAAPI version.\n");
1883  return AVERROR(EINVAL);
1884 #endif
1885  }
1886 
1887  if (ctx->tile_rows && ctx->tile_cols)
1888  ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
1889  else
1890  ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
1891  if (ret < 0)
1892  return ret;
1893 
1894  if (ctx->nb_slices > avctx->slices) {
1895  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
1896  "%d (from %d) due to driver constraints on slice "
1897  "structure.\n", ctx->nb_slices, avctx->slices);
1898  }
1899  if (ctx->nb_slices > max_slices) {
1900  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1901  "encoding with %d slices (max %"PRIu32").\n",
1902  ctx->nb_slices, max_slices);
1903  return AVERROR(EINVAL);
1904  }
1905 
1906  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
1907  ctx->nb_slices);
1908  return 0;
1909 }
1910 
1912 {
1913  VAAPIEncodeContext *ctx = avctx->priv_data;
1914  VAStatus vas;
1915  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
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 packed headers "
1923  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1924  return AVERROR_EXTERNAL;
1925  }
1926 
1927  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1928  if (ctx->desired_packed_headers) {
1929  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
1930  "packed headers (wanted %#x).\n",
1931  ctx->desired_packed_headers);
1932  } else {
1933  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
1934  "packed headers (none wanted).\n");
1935  }
1936  ctx->va_packed_headers = 0;
1937  } else {
1938  if (ctx->desired_packed_headers & ~attr.value) {
1939  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
1940  "wanted packed headers (wanted %#x, found %#x).\n",
1941  ctx->desired_packed_headers, attr.value);
1942  } else {
1943  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
1944  "available (wanted %#x, found %#x).\n",
1945  ctx->desired_packed_headers, attr.value);
1946  }
1947  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
1948  }
1949 
1950  if (ctx->va_packed_headers) {
1951  ctx->config_attributes[ctx->nb_config_attributes++] =
1952  (VAConfigAttrib) {
1953  .type = VAConfigAttribEncPackedHeaders,
1954  .value = ctx->va_packed_headers,
1955  };
1956  }
1957 
1958  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1959  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1960  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
1961  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
1962  "sequence headers, but a global header is requested.\n");
1963  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
1964  "this may result in a stream which is not usable for some "
1965  "purposes (e.g. not muxable to some containers).\n");
1966  }
1967 
1968  return 0;
1969 }
1970 
1972 {
1973 #if VA_CHECK_VERSION(0, 36, 0)
1974  VAAPIEncodeContext *ctx = avctx->priv_data;
1975  VAStatus vas;
1976  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1977  int quality = avctx->compression_level;
1978 
1979  vas = vaGetConfigAttributes(ctx->hwctx->display,
1980  ctx->va_profile,
1981  ctx->va_entrypoint,
1982  &attr, 1);
1983  if (vas != VA_STATUS_SUCCESS) {
1984  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
1985  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1986  return AVERROR_EXTERNAL;
1987  }
1988 
1989  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1990  if (quality != 0) {
1991  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
1992  "supported: will use default quality level.\n");
1993  }
1994  } else {
1995  if (quality > attr.value) {
1996  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
1997  "valid range is 0-%d, using %d.\n",
1998  attr.value, attr.value);
1999  quality = attr.value;
2000  }
2001 
2002  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2003  .quality_level = quality,
2004  };
2006  VAEncMiscParameterTypeQualityLevel,
2007  &ctx->quality_params,
2008  sizeof(ctx->quality_params));
2009  }
2010 #else
2011  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
2012  "not supported with this VAAPI version.\n");
2013 #endif
2014 
2015  return 0;
2016 }
2017 
2019 {
2020 #if VA_CHECK_VERSION(1, 0, 0)
2021  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2022  VAAPIEncodeContext *ctx = avctx->priv_data;
2023  VAStatus vas;
2024  VAConfigAttrib attr = { VAConfigAttribEncROI };
2025 
2026  vas = vaGetConfigAttributes(ctx->hwctx->display,
2027  ctx->va_profile,
2028  ctx->va_entrypoint,
2029  &attr, 1);
2030  if (vas != VA_STATUS_SUCCESS) {
2031  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
2032  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2033  return AVERROR_EXTERNAL;
2034  }
2035 
2036  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2037  base_ctx->roi_allowed = 0;
2038  } else {
2039  VAConfigAttribValEncROI roi = {
2040  .value = attr.value,
2041  };
2042 
2043  ctx->roi_max_regions = roi.bits.num_roi_regions;
2044  base_ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2045  (ctx->va_rc_mode == VA_RC_CQP ||
2046  roi.bits.roi_rc_qp_delta_support);
2047  }
2048 #endif
2049  return 0;
2050 }
2051 
2053  void *obj)
2054 {
2055  AVCodecContext *avctx = opaque.nc;
2056  VAAPIEncodeContext *ctx = avctx->priv_data;
2057  VABufferID *buffer_id_ref = obj;
2058  VABufferID buffer_id = *buffer_id_ref;
2059 
2060  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2061 
2062  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2063 }
2064 
2066 {
2067  AVCodecContext *avctx = opaque.nc;
2068  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2069  VAAPIEncodeContext *ctx = avctx->priv_data;
2070  VABufferID *buffer_id = obj;
2071  VAStatus vas;
2072 
2073  // The output buffer size is fixed, so it needs to be large enough
2074  // to hold the largest possible compressed frame. We assume here
2075  // that the uncompressed frame plus some header data is an upper
2076  // bound on that.
2077  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2078  VAEncCodedBufferType,
2079  3 * base_ctx->surface_width * base_ctx->surface_height +
2080  (1 << 16), 1, 0, buffer_id);
2081  if (vas != VA_STATUS_SUCCESS) {
2082  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2083  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2084  return AVERROR(ENOMEM);
2085  }
2086 
2087  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", *buffer_id);
2088 
2089  return 0;
2090 }
2091 
2093 {
2094  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2095  VAAPIEncodeContext *ctx = avctx->priv_data;
2096  AVVAAPIHWConfig *hwconfig = NULL;
2097  enum AVPixelFormat recon_format;
2098  int err;
2099 
2100  hwconfig = av_hwdevice_hwconfig_alloc(base_ctx->device_ref);
2101  if (!hwconfig) {
2102  err = AVERROR(ENOMEM);
2103  goto fail;
2104  }
2105  hwconfig->config_id = ctx->va_config;
2106 
2107  err = ff_hw_base_get_recon_format(base_ctx, (const void*)hwconfig, &recon_format);
2108  if (err < 0)
2109  goto fail;
2110 
2111  base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
2112  if (!base_ctx->recon_frames_ref) {
2113  err = AVERROR(ENOMEM);
2114  goto fail;
2115  }
2116  base_ctx->recon_frames = (AVHWFramesContext*)base_ctx->recon_frames_ref->data;
2117 
2118  base_ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
2119  base_ctx->recon_frames->sw_format = recon_format;
2120  base_ctx->recon_frames->width = base_ctx->surface_width;
2121  base_ctx->recon_frames->height = base_ctx->surface_height;
2122 
2123  err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
2124  if (err < 0) {
2125  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2126  "frame context: %d.\n", err);
2127  goto fail;
2128  }
2129 
2130  err = 0;
2131  fail:
2132  av_freep(&hwconfig);
2133  return err;
2134 }
2135 
2137  .priv_size = sizeof(VAAPIEncodePicture),
2138 
2139  .init = &vaapi_encode_init,
2140 
2141  .issue = &vaapi_encode_issue,
2142 
2144 
2145  .free = &vaapi_encode_free,
2146 };
2147 
2149 {
2150  return ff_hw_base_encode_receive_packet(avctx->priv_data, avctx, pkt);
2151 }
2152 
2154 {
2155  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2156  VAAPIEncodeContext *ctx = avctx->priv_data;
2157  AVVAAPIFramesContext *recon_hwctx = NULL;
2158  VAStatus vas;
2159  int err;
2160 
2161  err = ff_hw_base_encode_init(avctx, base_ctx);
2162  if (err < 0)
2163  goto fail;
2164 
2165  ctx->va_config = VA_INVALID_ID;
2166  ctx->va_context = VA_INVALID_ID;
2167 
2168  base_ctx->op = &vaapi_op;
2169 
2170  ctx->hwctx = base_ctx->device->hwctx;
2171 
2172  err = vaapi_encode_profile_entrypoint(avctx);
2173  if (err < 0)
2174  goto fail;
2175 
2176  err = vaapi_encode_surface_alignment(avctx);
2177  if (err < 0)
2178  goto fail;
2179 
2180  if (ctx->codec->get_encoder_caps) {
2181  err = ctx->codec->get_encoder_caps(avctx);
2182  if (err < 0)
2183  goto fail;
2184  } else {
2185  // Assume 16x16 blocks.
2186  base_ctx->surface_width = FFALIGN(avctx->width, 16);
2187  base_ctx->surface_height = FFALIGN(avctx->height, 16);
2188  if (ctx->codec->flags & FF_HW_FLAG_SLICE_CONTROL) {
2189  base_ctx->slice_block_width = 16;
2190  base_ctx->slice_block_height = 16;
2191  }
2192  }
2193 
2194  err = vaapi_encode_init_rate_control(avctx);
2195  if (err < 0)
2196  goto fail;
2197 
2198  err = vaapi_encode_init_gop_structure(avctx);
2199  if (err < 0)
2200  goto fail;
2201 
2202  err = vaapi_encode_init_slice_structure(avctx);
2203  if (err < 0)
2204  goto fail;
2205 
2206  err = vaapi_encode_init_packed_headers(avctx);
2207  if (err < 0)
2208  goto fail;
2209 
2210  err = vaapi_encode_init_roi(avctx);
2211  if (err < 0)
2212  goto fail;
2213 
2214  if (avctx->compression_level >= 0) {
2215  err = vaapi_encode_init_quality(avctx);
2216  if (err < 0)
2217  goto fail;
2218  }
2219 
2220  if (ctx->max_frame_size) {
2221  err = vaapi_encode_init_max_frame_size(avctx);
2222  if (err < 0)
2223  goto fail;
2224  }
2225 
2226  vas = vaCreateConfig(ctx->hwctx->display,
2227  ctx->va_profile, ctx->va_entrypoint,
2228  ctx->config_attributes, ctx->nb_config_attributes,
2229  &ctx->va_config);
2230  if (vas != VA_STATUS_SUCCESS) {
2231  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2232  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2233  err = AVERROR(EIO);
2234  goto fail;
2235  }
2236 
2237  err = vaapi_encode_create_recon_frames(avctx);
2238  if (err < 0)
2239  goto fail;
2240 
2241  recon_hwctx = base_ctx->recon_frames->hwctx;
2242  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2243  base_ctx->surface_width, base_ctx->surface_height,
2244  VA_PROGRESSIVE,
2245  recon_hwctx->surface_ids,
2246  recon_hwctx->nb_surfaces,
2247  &ctx->va_context);
2248  if (vas != VA_STATUS_SUCCESS) {
2249  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2250  "context: %d (%s).\n", vas, vaErrorStr(vas));
2251  err = AVERROR(EIO);
2252  goto fail;
2253  }
2254 
2255  ctx->output_buffer_pool =
2256  av_refstruct_pool_alloc_ext(sizeof(VABufferID), 0, avctx,
2259  if (!ctx->output_buffer_pool) {
2260  err = AVERROR(ENOMEM);
2261  goto fail;
2262  }
2263 
2264  if (ctx->codec->configure) {
2265  err = ctx->codec->configure(avctx);
2266  if (err < 0)
2267  goto fail;
2268  }
2269 
2270  base_ctx->output_delay = base_ctx->b_per_p;
2271  base_ctx->decode_delay = base_ctx->max_b_depth;
2272 
2273  if (ctx->codec->sequence_params_size > 0) {
2274  ctx->codec_sequence_params =
2275  av_mallocz(ctx->codec->sequence_params_size);
2276  if (!ctx->codec_sequence_params) {
2277  err = AVERROR(ENOMEM);
2278  goto fail;
2279  }
2280  }
2281  if (ctx->codec->picture_params_size > 0) {
2282  ctx->codec_picture_params =
2283  av_mallocz(ctx->codec->picture_params_size);
2284  if (!ctx->codec_picture_params) {
2285  err = AVERROR(ENOMEM);
2286  goto fail;
2287  }
2288  }
2289 
2290  if (ctx->codec->init_sequence_params) {
2291  err = ctx->codec->init_sequence_params(avctx);
2292  if (err < 0) {
2293  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2294  "failed: %d.\n", err);
2295  goto fail;
2296  }
2297  }
2298 
2299  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2300  ctx->codec->write_sequence_header &&
2303  size_t bit_len = 8 * sizeof(data);
2304 
2305  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2306  if (err < 0) {
2307  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2308  "for extradata: %d.\n", err);
2309  goto fail;
2310  } else {
2311  avctx->extradata_size = (bit_len + 7) / 8;
2312  avctx->extradata = av_mallocz(avctx->extradata_size +
2314  if (!avctx->extradata) {
2315  err = AVERROR(ENOMEM);
2316  goto fail;
2317  }
2318  memcpy(avctx->extradata, data, avctx->extradata_size);
2319  }
2320  }
2321 
2322 #if VA_CHECK_VERSION(1, 9, 0)
2323  // check vaSyncBuffer function
2324  vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2325  if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2326  base_ctx->async_encode = 1;
2327  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
2328  sizeof(VAAPIEncodePicture*),
2329  0);
2330  if (!base_ctx->encode_fifo)
2331  return AVERROR(ENOMEM);
2332  }
2333 #endif
2334 
2335  return 0;
2336 
2337 fail:
2338  return err;
2339 }
2340 
2342 {
2343  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2344  VAAPIEncodeContext *ctx = avctx->priv_data;
2345  FFHWBaseEncodePicture *pic, *next;
2346 
2347  /* We check ctx->frame to know whether ff_vaapi_encode_init()
2348  * has been called and va_config/va_context initialized. */
2349  if (!base_ctx->frame)
2350  return 0;
2351 
2352  for (pic = base_ctx->pic_start; pic; pic = next) {
2353  next = pic->next;
2354  vaapi_encode_free(avctx, pic);
2355  }
2356 
2357  av_refstruct_pool_uninit(&ctx->output_buffer_pool);
2358 
2359  if (ctx->va_context != VA_INVALID_ID) {
2360  if (ctx->hwctx)
2361  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2362  ctx->va_context = VA_INVALID_ID;
2363  }
2364 
2365  if (ctx->va_config != VA_INVALID_ID) {
2366  if (ctx->hwctx)
2367  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2368  ctx->va_config = VA_INVALID_ID;
2369  }
2370 
2371  av_freep(&ctx->codec_sequence_params);
2372  av_freep(&ctx->codec_picture_params);
2373 
2374  ff_hw_base_encode_close(base_ctx);
2375 
2376  return 0;
2377 }
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
vaapi_encode_alloc_output_buffer
static int vaapi_encode_alloc_output_buffer(AVRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:2065
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
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:2018
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
RC_MODE_ICQ
@ RC_MODE_ICQ
Definition: vaapi_encode.h:120
vaapi_encode_free_output_buffer
static void vaapi_encode_free_output_buffer(AVRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:2052
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:979
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:3170
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
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
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
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
AVRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
av_unused
#define av_unused
Definition: attributes.h:131
vaapi_encode_surface_alignment
static av_cold int vaapi_encode_surface_alignment(av_unused AVCodecContext *avctx)
Definition: vaapi_encode.c:1136
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:163
vaapi_encode_init_slice_structure
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:1819
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:403
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:775
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:149
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:2341
FFHWBaseEncodeContext::slice_block_width
int slice_block_width
Definition: hw_base_encode.h:144
vaapi_encode_init_rate_control
static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
Definition: vaapi_encode.c:1219
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:1281
FFHWBaseEncodeContext::roi_warned
int roi_warned
Definition: hw_base_encode.h:208
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:424
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:574
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:808
vaapi_encode_init_gop_structure
static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:1634
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:193
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
FF_HW_FLAG_SLICE_CONTROL
@ FF_HW_FLAG_SLICE_CONTROL
Definition: hw_base_encode.h:47
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
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:717
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:329
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:1338
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:538
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:224
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1257
vaapi_op
static const FFHWEncodePictureOperation vaapi_op
Definition: vaapi_encode.c:2136
AVRegionOfInterest::bottom
int bottom
Definition: frame.h:345
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:216
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_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:39
ff_vaapi_encode_receive_packet
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: vaapi_encode.c:2148
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1310
FFHWBaseEncodeContext::pic_start
FFHWBaseEncodePicture * pic_start
Definition: hw_base_encode.h:160
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:1295
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
MAX_GLOBAL_PARAMS
@ MAX_GLOBAL_PARAMS
Definition: vaapi_encode.h:46
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:501
AVRegionOfInterest::self_size
uint32_t self_size
Must be set to the size of this data structure (that is, sizeof(AVRegionOfInterest)).
Definition: frame.h:334
av_refstruct_pool_alloc_ext
static AVRefStructPool * av_refstruct_pool_alloc_ext(size_t size, unsigned flags, void *opaque, int(*init_cb)(AVRefStructOpaque opaque, void *obj), void(*reset_cb)(AVRefStructOpaque opaque, void *obj), void(*free_entry_cb)(AVRefStructOpaque opaque, void *obj), void(*free_cb)(AVRefStructOpaque opaque))
A wrapper around av_refstruct_pool_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:258
FFHWEncodePictureOperation
Definition: hw_base_encode.h:109
RC_MODE_VBR
@ RC_MODE_VBR
Definition: d3d12va_encode.h:96
av_refstruct_pool_get
void * av_refstruct_pool_get(AVRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297
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:558
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:211
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:1045
vaapi_encode_init_quality
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
Definition: vaapi_encode.c:1971
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:424
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:1198
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
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
MAX_PARAM_BUFFER_SIZE
@ MAX_PARAM_BUFFER_SIZE
Definition: vaapi_encode.h:47
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
av_refstruct_ref
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
VAAPIEncodePicture::recon_surface
VASurfaceID recon_surface
Definition: vaapi_encode.h:74
vaapi_encode_init_packed_headers
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
Definition: vaapi_encode.c:1911
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:2092
FFHWBaseEncodeContext::roi_allowed
int roi_allowed
Definition: hw_base_encode.h:201
AVRegionOfInterest::right
int right
Definition: frame.h:347
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:98
AVRegionOfInterest::left
int left
Definition: frame.h:346
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
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:537
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:344
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:2233
AVCodecContext::height
int height
Definition: avcodec.h:632
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
RC_MODE_AVBR
@ RC_MODE_AVBR
Definition: vaapi_encode.h:122
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
FF_HW_FLAG_INTRA_ONLY
@ FF_HW_FLAG_INTRA_ONLY
Definition: hw_base_encode.h:51
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2153
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:219
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:221
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:1274
AVRational::den
int den
Denominator.
Definition: rational.h:60
FF_HW_FLAG_CONSTANT_QUALITY_ONLY
@ FF_HW_FLAG_CONSTANT_QUALITY_ONLY
Definition: hw_base_encode.h:49
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1658
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:1758
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
av_refstruct_pool_uninit
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
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:1061
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:632
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:1577
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:371
snprintf
#define snprintf
Definition: snprintf.h:34
vaapi_encode_init
static int vaapi_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: vaapi_encode.c:835
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1328
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:1713
VAAPIEncodeProfile
Definition: vaapi_encode.h:100
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
AVCodecContext::compression_level
int compression_level
Definition: avcodec.h:1263
VAAPIEncodePicture::nb_slices
int nb_slices
Definition: vaapi_encode.h:85