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/pixdesc.h"
29 
30 #include "vaapi_encode.h"
31 #include "encode.h"
32 #include "avcodec.h"
33 #include "refstruct.h"
34 
36  HW_CONFIG_ENCODER_FRAMES(VAAPI, VAAPI),
37  NULL,
38 };
39 
40 static const char * const picture_type_name[] = { "IDR", "I", "P", "B" };
41 
43  VAAPIEncodePicture *pic,
44  int type, char *data, size_t bit_len)
45 {
47  VAStatus vas;
48  VABufferID param_buffer, data_buffer;
49  VABufferID *tmp;
50  VAEncPackedHeaderParameterBuffer params = {
51  .type = type,
52  .bit_length = bit_len,
53  .has_emulation_bytes = 1,
54  };
55 
56  tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 2);
57  if (!tmp)
58  return AVERROR(ENOMEM);
59  pic->param_buffers = tmp;
60 
61  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
62  VAEncPackedHeaderParameterBufferType,
63  sizeof(params), 1, &params, &param_buffer);
64  if (vas != VA_STATUS_SUCCESS) {
65  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
66  "for packed header (type %d): %d (%s).\n",
67  type, vas, vaErrorStr(vas));
68  return AVERROR(EIO);
69  }
70  pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
71 
72  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
73  VAEncPackedHeaderDataBufferType,
74  (bit_len + 7) / 8, 1, data, &data_buffer);
75  if (vas != VA_STATUS_SUCCESS) {
76  av_log(avctx, AV_LOG_ERROR, "Failed to create data buffer "
77  "for packed header (type %d): %d (%s).\n",
78  type, vas, vaErrorStr(vas));
79  return AVERROR(EIO);
80  }
81  pic->param_buffers[pic->nb_param_buffers++] = data_buffer;
82 
83  av_log(avctx, AV_LOG_DEBUG, "Packed header buffer (%d) is %#x/%#x "
84  "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
85  return 0;
86 }
87 
89  VAAPIEncodePicture *pic,
90  int type, char *data, size_t len)
91 {
93  VAStatus vas;
94  VABufferID *tmp;
95  VABufferID buffer;
96 
97  tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 1);
98  if (!tmp)
99  return AVERROR(ENOMEM);
100  pic->param_buffers = tmp;
101 
102  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
103  type, len, 1, data, &buffer);
104  if (vas != VA_STATUS_SUCCESS) {
105  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
106  "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
107  return AVERROR(EIO);
108  }
109  pic->param_buffers[pic->nb_param_buffers++] = buffer;
110 
111  av_log(avctx, AV_LOG_DEBUG, "Param buffer (%d) is %#x.\n",
112  type, buffer);
113  return 0;
114 }
115 
117  VAAPIEncodePicture *pic,
118  int type,
119  const void *data, size_t len)
120 {
121  // Construct the buffer on the stack - 1KB is much larger than any
122  // current misc parameter buffer type (the largest is EncQuality at
123  // 224 bytes).
124  uint8_t buffer[1024];
125  VAEncMiscParameterBuffer header = {
126  .type = type,
127  };
128  size_t buffer_size = sizeof(header) + len;
129  av_assert0(buffer_size <= sizeof(buffer));
130 
131  memcpy(buffer, &header, sizeof(header));
132  memcpy(buffer + sizeof(header), data, len);
133 
134  return vaapi_encode_make_param_buffer(avctx, pic,
135  VAEncMiscParameterBufferType,
136  buffer, buffer_size);
137 }
138 
140  VAAPIEncodePicture *pic)
141 {
142  VAAPIEncodeContext *ctx = avctx->priv_data;
143  VAStatus vas;
144 
146 
147  if (pic->encode_complete) {
148  // Already waited for this picture.
149  return 0;
150  }
151 
152  av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
153  "(input surface %#x).\n", pic->display_order,
154  pic->encode_order, pic->input_surface);
155 
156 #if VA_CHECK_VERSION(1, 9, 0)
157  if (ctx->has_sync_buffer_func) {
158  vas = vaSyncBuffer(ctx->hwctx->display,
159  pic->output_buffer,
160  VA_TIMEOUT_INFINITE);
161  if (vas != VA_STATUS_SUCCESS) {
162  av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer completion: "
163  "%d (%s).\n", vas, vaErrorStr(vas));
164  return AVERROR(EIO);
165  }
166  } else
167 #endif
168  { // If vaSyncBuffer is not implemented, try old version API.
169  vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
170  if (vas != VA_STATUS_SUCCESS) {
171  av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
172  "%d (%s).\n", vas, vaErrorStr(vas));
173  return AVERROR(EIO);
174  }
175  }
176 
177  // Input is definitely finished with now.
178  av_frame_free(&pic->input_image);
179 
180  pic->encode_complete = 1;
181  return 0;
182 }
183 
185  VAAPIEncodePicture *pic)
186 {
187  VAAPIEncodeContext *ctx = avctx->priv_data;
188  VAAPIEncodeSlice *slice;
189  int i, rounding;
190 
191  for (i = 0; i < pic->nb_slices; i++)
192  pic->slices[i].row_size = ctx->slice_size;
193 
194  rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size;
195  if (rounding > 0) {
196  // Place rounding error at top and bottom of frame.
197  av_assert0(rounding < pic->nb_slices);
198  // Some Intel drivers contain a bug where the encoder will fail
199  // if the last slice is smaller than the one before it. Since
200  // that's straightforward to avoid here, just do so.
201  if (rounding <= 2) {
202  for (i = 0; i < rounding; i++)
203  ++pic->slices[i].row_size;
204  } else {
205  for (i = 0; i < (rounding + 1) / 2; i++)
206  ++pic->slices[pic->nb_slices - i - 1].row_size;
207  for (i = 0; i < rounding / 2; i++)
208  ++pic->slices[i].row_size;
209  }
210  } else if (rounding < 0) {
211  // Remove rounding error from last slice only.
212  av_assert0(rounding < ctx->slice_size);
213  pic->slices[pic->nb_slices - 1].row_size += rounding;
214  }
215 
216  for (i = 0; i < pic->nb_slices; i++) {
217  slice = &pic->slices[i];
218  slice->index = i;
219  if (i == 0) {
220  slice->row_start = 0;
221  slice->block_start = 0;
222  } else {
223  const VAAPIEncodeSlice *prev = &pic->slices[i - 1];
224  slice->row_start = prev->row_start + prev->row_size;
225  slice->block_start = prev->block_start + prev->block_size;
226  }
227  slice->block_size = slice->row_size * ctx->slice_block_cols;
228 
229  av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), "
230  "%d-%d (%d blocks).\n", i, slice->row_start,
231  slice->row_start + slice->row_size - 1, slice->row_size,
232  slice->block_start, slice->block_start + slice->block_size - 1,
233  slice->block_size);
234  }
235 
236  return 0;
237 }
238 
240  VAAPIEncodePicture *pic)
241 {
242  VAAPIEncodeContext *ctx = avctx->priv_data;
243  VAAPIEncodeSlice *slice;
244  int i, j, index;
245 
246  for (i = 0; i < ctx->tile_cols; i++) {
247  for (j = 0; j < ctx->tile_rows; j++) {
248  index = j * ctx->tile_cols + i;
249  slice = &pic->slices[index];
250  slice->index = index;
251 
252  pic->slices[index].block_start = ctx->col_bd[i] +
253  ctx->row_bd[j] * ctx->slice_block_cols;
254  pic->slices[index].block_size = ctx->row_height[j] * ctx->col_width[i];
255 
256  av_log(avctx, AV_LOG_DEBUG, "Slice %2d: (%2d, %2d) start at: %4d "
257  "width:%2d height:%2d (%d blocks).\n", index, ctx->col_bd[i],
258  ctx->row_bd[j], slice->block_start, ctx->col_width[i],
259  ctx->row_height[j], slice->block_size);
260  }
261  }
262 
263  return 0;
264 }
265 
267  VAAPIEncodePicture *pic)
268 {
269  VAAPIEncodeContext *ctx = avctx->priv_data;
270  VAAPIEncodeSlice *slice;
271  VAStatus vas;
272  int err, i;
274  size_t bit_len;
276 
277  av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
278  "as type %s.\n", pic->display_order, pic->encode_order,
279  picture_type_name[pic->type]);
280  if (pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0) {
281  av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
282  } else {
283  av_log(avctx, AV_LOG_DEBUG, "L0 refers to");
284  for (i = 0; i < pic->nb_refs[0]; i++) {
285  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
286  pic->refs[0][i]->display_order, pic->refs[0][i]->encode_order);
287  }
288  av_log(avctx, AV_LOG_DEBUG, ".\n");
289 
290  if (pic->nb_refs[1]) {
291  av_log(avctx, AV_LOG_DEBUG, "L1 refers to");
292  for (i = 0; i < pic->nb_refs[1]; i++) {
293  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
294  pic->refs[1][i]->display_order, pic->refs[1][i]->encode_order);
295  }
296  av_log(avctx, AV_LOG_DEBUG, ".\n");
297  }
298  }
299 
300  av_assert0(!pic->encode_issued);
301  for (i = 0; i < pic->nb_refs[0]; i++) {
302  av_assert0(pic->refs[0][i]);
303  av_assert0(pic->refs[0][i]->encode_issued);
304  }
305  for (i = 0; i < pic->nb_refs[1]; i++) {
306  av_assert0(pic->refs[1][i]);
307  av_assert0(pic->refs[1][i]->encode_issued);
308  }
309 
310  av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
311 
312  pic->recon_image = av_frame_alloc();
313  if (!pic->recon_image) {
314  err = AVERROR(ENOMEM);
315  goto fail;
316  }
317 
318  err = av_hwframe_get_buffer(ctx->recon_frames_ref, pic->recon_image, 0);
319  if (err < 0) {
320  err = AVERROR(ENOMEM);
321  goto fail;
322  }
323  pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
324  av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
325 
326  pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool);
327  if (!pic->output_buffer_ref) {
328  err = AVERROR(ENOMEM);
329  goto fail;
330  }
331  pic->output_buffer = *pic->output_buffer_ref;
332  av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
333  pic->output_buffer);
334 
335  if (ctx->codec->picture_params_size > 0) {
336  pic->codec_picture_params = av_malloc(ctx->codec->picture_params_size);
337  if (!pic->codec_picture_params)
338  goto fail;
339  memcpy(pic->codec_picture_params, ctx->codec_picture_params,
340  ctx->codec->picture_params_size);
341  } else {
342  av_assert0(!ctx->codec_picture_params);
343  }
344 
345  pic->nb_param_buffers = 0;
346 
347  if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
348  err = vaapi_encode_make_param_buffer(avctx, pic,
349  VAEncSequenceParameterBufferType,
350  ctx->codec_sequence_params,
351  ctx->codec->sequence_params_size);
352  if (err < 0)
353  goto fail;
354  }
355 
356  if (pic->type == PICTURE_TYPE_IDR) {
357  for (i = 0; i < ctx->nb_global_params; i++) {
358  err = vaapi_encode_make_misc_param_buffer(avctx, pic,
359  ctx->global_params_type[i],
360  ctx->global_params[i],
361  ctx->global_params_size[i]);
362  if (err < 0)
363  goto fail;
364  }
365  }
366 
367  if (ctx->codec->init_picture_params) {
368  err = ctx->codec->init_picture_params(avctx, pic);
369  if (err < 0) {
370  av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
371  "parameters: %d.\n", err);
372  goto fail;
373  }
374  err = vaapi_encode_make_param_buffer(avctx, pic,
375  VAEncPictureParameterBufferType,
377  ctx->codec->picture_params_size);
378  if (err < 0)
379  goto fail;
380  }
381 
382 #if VA_CHECK_VERSION(1, 5, 0)
383  if (ctx->max_frame_size) {
384  err = vaapi_encode_make_misc_param_buffer(avctx, pic,
385  VAEncMiscParameterTypeMaxFrameSize,
386  &ctx->mfs_params,
387  sizeof(ctx->mfs_params));
388  if (err < 0)
389  goto fail;
390  }
391 #endif
392 
393  if (pic->type == PICTURE_TYPE_IDR) {
394  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
395  ctx->codec->write_sequence_header) {
396  bit_len = 8 * sizeof(data);
397  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
398  if (err < 0) {
399  av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
400  "header: %d.\n", err);
401  goto fail;
402  }
403  err = vaapi_encode_make_packed_header(avctx, pic,
404  ctx->codec->sequence_header_type,
405  data, bit_len);
406  if (err < 0)
407  goto fail;
408  }
409  }
410 
411  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
412  ctx->codec->write_picture_header) {
413  bit_len = 8 * sizeof(data);
414  err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len);
415  if (err < 0) {
416  av_log(avctx, AV_LOG_ERROR, "Failed to write per-picture "
417  "header: %d.\n", err);
418  goto fail;
419  }
420  err = vaapi_encode_make_packed_header(avctx, pic,
421  ctx->codec->picture_header_type,
422  data, bit_len);
423  if (err < 0)
424  goto fail;
425  }
426 
427  if (ctx->codec->write_extra_buffer) {
428  for (i = 0;; i++) {
429  size_t len = sizeof(data);
430  int type;
431  err = ctx->codec->write_extra_buffer(avctx, pic, i, &type,
432  data, &len);
433  if (err == AVERROR_EOF)
434  break;
435  if (err < 0) {
436  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
437  "buffer %d: %d.\n", i, err);
438  goto fail;
439  }
440 
441  err = vaapi_encode_make_param_buffer(avctx, pic, type,
442  data, len);
443  if (err < 0)
444  goto fail;
445  }
446  }
447 
448  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
449  ctx->codec->write_extra_header) {
450  for (i = 0;; i++) {
451  int type;
452  bit_len = 8 * sizeof(data);
453  err = ctx->codec->write_extra_header(avctx, pic, i, &type,
454  data, &bit_len);
455  if (err == AVERROR_EOF)
456  break;
457  if (err < 0) {
458  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
459  "header %d: %d.\n", i, err);
460  goto fail;
461  }
462 
463  err = vaapi_encode_make_packed_header(avctx, pic, type,
464  data, bit_len);
465  if (err < 0)
466  goto fail;
467  }
468  }
469 
470  if (pic->nb_slices == 0)
471  pic->nb_slices = ctx->nb_slices;
472  if (pic->nb_slices > 0) {
473  pic->slices = av_calloc(pic->nb_slices, sizeof(*pic->slices));
474  if (!pic->slices) {
475  err = AVERROR(ENOMEM);
476  goto fail;
477  }
478 
479  if (ctx->tile_rows && ctx->tile_cols)
480  vaapi_encode_make_tile_slice(avctx, pic);
481  else
482  vaapi_encode_make_row_slice(avctx, pic);
483  }
484 
485  for (i = 0; i < pic->nb_slices; i++) {
486  slice = &pic->slices[i];
487 
488  if (ctx->codec->slice_params_size > 0) {
489  slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size);
490  if (!slice->codec_slice_params) {
491  err = AVERROR(ENOMEM);
492  goto fail;
493  }
494  }
495 
496  if (ctx->codec->init_slice_params) {
497  err = ctx->codec->init_slice_params(avctx, pic, slice);
498  if (err < 0) {
499  av_log(avctx, AV_LOG_ERROR, "Failed to initialise slice "
500  "parameters: %d.\n", err);
501  goto fail;
502  }
503  }
504 
505  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
506  ctx->codec->write_slice_header) {
507  bit_len = 8 * sizeof(data);
508  err = ctx->codec->write_slice_header(avctx, pic, slice,
509  data, &bit_len);
510  if (err < 0) {
511  av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
512  "header: %d.\n", err);
513  goto fail;
514  }
515  err = vaapi_encode_make_packed_header(avctx, pic,
516  ctx->codec->slice_header_type,
517  data, bit_len);
518  if (err < 0)
519  goto fail;
520  }
521 
522  if (ctx->codec->init_slice_params) {
523  err = vaapi_encode_make_param_buffer(avctx, pic,
524  VAEncSliceParameterBufferType,
525  slice->codec_slice_params,
526  ctx->codec->slice_params_size);
527  if (err < 0)
528  goto fail;
529  }
530  }
531 
532 #if VA_CHECK_VERSION(1, 0, 0)
535  if (sd && ctx->roi_allowed) {
536  const AVRegionOfInterest *roi;
537  uint32_t roi_size;
538  VAEncMiscParameterBufferROI param_roi;
539  int nb_roi, i, v;
540 
541  roi = (const AVRegionOfInterest*)sd->data;
542  roi_size = roi->self_size;
543  av_assert0(roi_size && sd->size % roi_size == 0);
544  nb_roi = sd->size / roi_size;
545  if (nb_roi > ctx->roi_max_regions) {
546  if (!ctx->roi_warned) {
547  av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
548  "supported by driver (%d > %d).\n",
549  nb_roi, ctx->roi_max_regions);
550  ctx->roi_warned = 1;
551  }
552  nb_roi = ctx->roi_max_regions;
553  }
554 
555  pic->roi = av_calloc(nb_roi, sizeof(*pic->roi));
556  if (!pic->roi) {
557  err = AVERROR(ENOMEM);
558  goto fail;
559  }
560  // For overlapping regions, the first in the array takes priority.
561  for (i = 0; i < nb_roi; i++) {
562  roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
563 
564  av_assert0(roi->qoffset.den != 0);
565  v = roi->qoffset.num * ctx->roi_quant_range / roi->qoffset.den;
566  av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d) -> %+d.\n",
567  roi->top, roi->left, roi->bottom, roi->right, v);
568 
569  pic->roi[i] = (VAEncROI) {
570  .roi_rectangle = {
571  .x = roi->left,
572  .y = roi->top,
573  .width = roi->right - roi->left,
574  .height = roi->bottom - roi->top,
575  },
576  .roi_value = av_clip_int8(v),
577  };
578  }
579 
580  param_roi = (VAEncMiscParameterBufferROI) {
581  .num_roi = nb_roi,
582  .max_delta_qp = INT8_MAX,
583  .min_delta_qp = INT8_MIN,
584  .roi = pic->roi,
585  .roi_flags.bits.roi_value_is_qp_delta = 1,
586  };
587 
588  err = vaapi_encode_make_misc_param_buffer(avctx, pic,
589  VAEncMiscParameterTypeROI,
590  &param_roi,
591  sizeof(param_roi));
592  if (err < 0)
593  goto fail;
594  }
595 #endif
596 
597  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
598  pic->input_surface);
599  if (vas != VA_STATUS_SUCCESS) {
600  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
601  "%d (%s).\n", vas, vaErrorStr(vas));
602  err = AVERROR(EIO);
603  goto fail_with_picture;
604  }
605 
606  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
607  pic->param_buffers, pic->nb_param_buffers);
608  if (vas != VA_STATUS_SUCCESS) {
609  av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
610  "%d (%s).\n", vas, vaErrorStr(vas));
611  err = AVERROR(EIO);
612  goto fail_with_picture;
613  }
614 
615  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
616  if (vas != VA_STATUS_SUCCESS) {
617  av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
618  "%d (%s).\n", vas, vaErrorStr(vas));
619  err = AVERROR(EIO);
620  // vaRenderPicture() has been called here, so we should not destroy
621  // the parameter buffers unless separate destruction is required.
622  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
624  goto fail;
625  else
626  goto fail_at_end;
627  }
628 
629  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
631  for (i = 0; i < pic->nb_param_buffers; i++) {
632  vas = vaDestroyBuffer(ctx->hwctx->display,
633  pic->param_buffers[i]);
634  if (vas != VA_STATUS_SUCCESS) {
635  av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
636  "param buffer %#x: %d (%s).\n",
637  pic->param_buffers[i], vas, vaErrorStr(vas));
638  // And ignore.
639  }
640  }
641  }
642 
643  pic->encode_issued = 1;
644 
645  return 0;
646 
647 fail_with_picture:
648  vaEndPicture(ctx->hwctx->display, ctx->va_context);
649 fail:
650  for(i = 0; i < pic->nb_param_buffers; i++)
651  vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
652  if (pic->slices) {
653  for (i = 0; i < pic->nb_slices; i++)
655  }
656 fail_at_end:
658  av_freep(&pic->param_buffers);
659  av_freep(&pic->slices);
660  av_freep(&pic->roi);
661  av_frame_free(&pic->recon_image);
663  pic->output_buffer = VA_INVALID_ID;
664  return err;
665 }
666 
668  VAAPIEncodePicture *pic,
669  AVPacket *pkt)
670 {
671  VAAPIEncodeContext *ctx = avctx->priv_data;
672 
673  if (pic->type == PICTURE_TYPE_IDR)
675 
676  pkt->pts = pic->pts;
677  pkt->duration = pic->duration;
678 
679  // for no-delay encoders this is handled in generic codec
680  if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY &&
681  avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
682  pkt->opaque = pic->opaque;
683  pkt->opaque_ref = pic->opaque_ref;
684  pic->opaque_ref = NULL;
685  }
686 
687  if (ctx->codec->flags & FLAG_TIMESTAMP_NO_DELAY) {
688  pkt->dts = pkt->pts;
689  return 0;
690  }
691 
692  if (ctx->output_delay == 0) {
693  pkt->dts = pkt->pts;
694  } else if (pic->encode_order < ctx->decode_delay) {
695  if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
696  pkt->dts = INT64_MIN;
697  else
698  pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
699  } else {
700  pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
701  (3 * ctx->output_delay + ctx->async_depth)];
702  }
703 
704  return 0;
705 }
706 
707 static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID buf_id)
708 {
709  VAAPIEncodeContext *ctx = avctx->priv_data;
710  VACodedBufferSegment *buf_list, *buf;
711  int size = 0;
712  VAStatus vas;
713  int err;
714 
715  vas = vaMapBuffer(ctx->hwctx->display, buf_id,
716  (void**)&buf_list);
717  if (vas != VA_STATUS_SUCCESS) {
718  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
719  "%d (%s).\n", vas, vaErrorStr(vas));
720  err = AVERROR(EIO);
721  return err;
722  }
723 
724  for (buf = buf_list; buf; buf = buf->next)
725  size += buf->size;
726 
727  vas = vaUnmapBuffer(ctx->hwctx->display, buf_id);
728  if (vas != VA_STATUS_SUCCESS) {
729  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
730  "%d (%s).\n", vas, vaErrorStr(vas));
731  err = AVERROR(EIO);
732  return err;
733  }
734 
735  return size;
736 }
737 
739  VABufferID buf_id, uint8_t **dst)
740 {
741  VAAPIEncodeContext *ctx = avctx->priv_data;
742  VACodedBufferSegment *buf_list, *buf;
743  VAStatus vas;
744  int err;
745 
746  vas = vaMapBuffer(ctx->hwctx->display, buf_id,
747  (void**)&buf_list);
748  if (vas != VA_STATUS_SUCCESS) {
749  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
750  "%d (%s).\n", vas, vaErrorStr(vas));
751  err = AVERROR(EIO);
752  return err;
753  }
754 
755  for (buf = buf_list; buf; buf = buf->next) {
756  av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
757  "(status %08x).\n", buf->size, buf->status);
758 
759  memcpy(*dst, buf->buf, buf->size);
760  *dst += buf->size;
761  }
762 
763  vas = vaUnmapBuffer(ctx->hwctx->display, buf_id);
764  if (vas != VA_STATUS_SUCCESS) {
765  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
766  "%d (%s).\n", vas, vaErrorStr(vas));
767  err = AVERROR(EIO);
768  return err;
769  }
770 
771  return 0;
772 }
773 
776 {
777  VAAPIEncodeContext *ctx = avctx->priv_data;
778  VABufferID output_buffer_prev;
779  int total_size = 0;
780  uint8_t *ptr;
781  int ret;
782 
783  if (ctx->coded_buffer_ref) {
784  output_buffer_prev = *ctx->coded_buffer_ref;
785  ret = vaapi_encode_get_coded_buffer_size(avctx, output_buffer_prev);
786  if (ret < 0)
787  goto end;
788  total_size += ret;
789  }
790 
792  if (ret < 0)
793  goto end;
794  total_size += ret;
795 
796  ret = ff_get_encode_buffer(avctx, pkt, total_size, 0);
797  if (ret < 0)
798  goto end;
799  ptr = pkt->data;
800 
801  if (ctx->coded_buffer_ref) {
802  ret = vaapi_encode_get_coded_buffer_data(avctx, output_buffer_prev, &ptr);
803  if (ret < 0)
804  goto end;
805  }
806 
808  if (ret < 0)
809  goto end;
810 
811 end:
812  ff_refstruct_unref(&ctx->coded_buffer_ref);
814  pic->output_buffer = VA_INVALID_ID;
815 
816  return ret;
817 }
818 
821 {
822  VAAPIEncodeContext *ctx = avctx->priv_data;
823  AVPacket *pkt_ptr = pkt;
824  int err;
825 
826  err = vaapi_encode_wait(avctx, pic);
827  if (err < 0)
828  return err;
829 
830  if (pic->non_independent_frame) {
831  av_assert0(!ctx->coded_buffer_ref);
832  ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref);
833 
834  if (pic->tail_size) {
835  if (ctx->tail_pkt->size) {
836  err = AVERROR_BUG;
837  goto end;
838  }
839 
840  err = ff_get_encode_buffer(avctx, ctx->tail_pkt, pic->tail_size, 0);
841  if (err < 0)
842  goto end;
843 
844  memcpy(ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
845  pkt_ptr = ctx->tail_pkt;
846  }
847  } else {
848  err = vaapi_encode_get_coded_data(avctx, pic, pkt);
849  if (err < 0)
850  goto end;
851  }
852 
853  av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
854  pic->display_order, pic->encode_order);
855 
856  vaapi_encode_set_output_property(avctx, pic, pkt_ptr);
857 
858 end:
860  pic->output_buffer = VA_INVALID_ID;
861  return err;
862 }
863 
865  VAAPIEncodePicture *pic)
866 {
867  vaapi_encode_wait(avctx, pic);
868 
869  if (pic->output_buffer_ref) {
870  av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
871  "%"PRId64"/%"PRId64".\n",
872  pic->display_order, pic->encode_order);
873 
875  pic->output_buffer = VA_INVALID_ID;
876  }
877 
878  return 0;
879 }
880 
882 {
883  VAAPIEncodeContext *ctx = avctx->priv_data;
884  VAAPIEncodePicture *pic;
885 
886  pic = av_mallocz(sizeof(*pic));
887  if (!pic)
888  return NULL;
889 
890  if (ctx->codec->picture_priv_data_size > 0) {
891  pic->priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
892  if (!pic->priv_data) {
893  av_freep(&pic);
894  return NULL;
895  }
896  }
897 
898  pic->input_surface = VA_INVALID_ID;
899  pic->recon_surface = VA_INVALID_ID;
900  pic->output_buffer = VA_INVALID_ID;
901 
902  return pic;
903 }
904 
906  VAAPIEncodePicture *pic)
907 {
908  int i;
909 
910  if (pic->encode_issued)
911  vaapi_encode_discard(avctx, pic);
912 
913  if (pic->slices) {
914  for (i = 0; i < pic->nb_slices; i++)
916  }
917 
918  av_frame_free(&pic->input_image);
919  av_frame_free(&pic->recon_image);
920 
922 
923  av_freep(&pic->param_buffers);
924  av_freep(&pic->slices);
925  // Output buffer should already be destroyed.
926  av_assert0(pic->output_buffer == VA_INVALID_ID);
927 
928  av_freep(&pic->priv_data);
930  av_freep(&pic->roi);
931 
932  av_free(pic);
933 
934  return 0;
935 }
936 
938  VAAPIEncodePicture *pic,
939  VAAPIEncodePicture *target,
940  int is_ref, int in_dpb, int prev)
941 {
942  int refs = 0;
943 
944  if (is_ref) {
945  av_assert0(pic != target);
947  pic->nb_refs[1] < MAX_PICTURE_REFERENCES);
948  if (target->display_order < pic->display_order)
949  pic->refs[0][pic->nb_refs[0]++] = target;
950  else
951  pic->refs[1][pic->nb_refs[1]++] = target;
952  ++refs;
953  }
954 
955  if (in_dpb) {
957  pic->dpb[pic->nb_dpb_pics++] = target;
958  ++refs;
959  }
960 
961  if (prev) {
962  av_assert0(!pic->prev);
963  pic->prev = target;
964  ++refs;
965  }
966 
967  target->ref_count[0] += refs;
968  target->ref_count[1] += refs;
969 }
970 
972  VAAPIEncodePicture *pic,
973  int level)
974 {
975  int i;
976 
977  if (pic->ref_removed[level])
978  return;
979 
980  for (i = 0; i < pic->nb_refs[0]; i++) {
981  av_assert0(pic->refs[0][i]);
982  --pic->refs[0][i]->ref_count[level];
983  av_assert0(pic->refs[0][i]->ref_count[level] >= 0);
984  }
985 
986  for (i = 0; i < pic->nb_refs[1]; i++) {
987  av_assert0(pic->refs[1][i]);
988  --pic->refs[1][i]->ref_count[level];
989  av_assert0(pic->refs[1][i]->ref_count[level] >= 0);
990  }
991 
992  for (i = 0; i < pic->nb_dpb_pics; i++) {
993  av_assert0(pic->dpb[i]);
994  --pic->dpb[i]->ref_count[level];
995  av_assert0(pic->dpb[i]->ref_count[level] >= 0);
996  }
997 
998  av_assert0(pic->prev || pic->type == PICTURE_TYPE_IDR);
999  if (pic->prev) {
1000  --pic->prev->ref_count[level];
1001  av_assert0(pic->prev->ref_count[level] >= 0);
1002  }
1003 
1004  pic->ref_removed[level] = 1;
1005 }
1006 
1008  VAAPIEncodePicture *start,
1009  VAAPIEncodePicture *end,
1010  VAAPIEncodePicture *prev,
1011  int current_depth,
1012  VAAPIEncodePicture **last)
1013 {
1014  VAAPIEncodeContext *ctx = avctx->priv_data;
1015  VAAPIEncodePicture *pic, *next, *ref;
1016  int i, len;
1017 
1018  av_assert0(start && end && start != end && start->next != end);
1019 
1020  // If we are at the maximum depth then encode all pictures as
1021  // non-referenced B-pictures. Also do this if there is exactly one
1022  // picture left, since there will be nothing to reference it.
1023  if (current_depth == ctx->max_b_depth || start->next->next == end) {
1024  for (pic = start->next; pic; pic = pic->next) {
1025  if (pic == end)
1026  break;
1027  pic->type = PICTURE_TYPE_B;
1028  pic->b_depth = current_depth;
1029 
1030  vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
1031  vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
1032  vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
1033 
1034  for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
1035  vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
1036  }
1037  *last = prev;
1038 
1039  } else {
1040  // Split the current list at the midpoint with a referenced
1041  // B-picture, then descend into each side separately.
1042  len = 0;
1043  for (pic = start->next; pic != end; pic = pic->next)
1044  ++len;
1045  for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
1046 
1047  pic->type = PICTURE_TYPE_B;
1048  pic->b_depth = current_depth;
1049 
1050  pic->is_reference = 1;
1051 
1052  vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
1053  vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
1054  vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
1055  vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
1056 
1057  for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
1058  vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
1059 
1060  if (i > 1)
1061  vaapi_encode_set_b_pictures(avctx, start, pic, pic,
1062  current_depth + 1, &next);
1063  else
1064  next = pic;
1065 
1066  vaapi_encode_set_b_pictures(avctx, pic, end, next,
1067  current_depth + 1, last);
1068  }
1069 }
1070 
1072  VAAPIEncodePicture *pic)
1073 {
1074  VAAPIEncodeContext *ctx = avctx->priv_data;
1075  int i;
1076 
1077  if (!pic)
1078  return;
1079 
1080  if (pic->type == PICTURE_TYPE_IDR) {
1081  for (i = 0; i < ctx->nb_next_prev; i++) {
1082  --ctx->next_prev[i]->ref_count[0];
1083  ctx->next_prev[i] = NULL;
1084  }
1085  ctx->next_prev[0] = pic;
1086  ++pic->ref_count[0];
1087  ctx->nb_next_prev = 1;
1088 
1089  return;
1090  }
1091 
1092  if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) {
1093  ctx->next_prev[ctx->nb_next_prev++] = pic;
1094  ++pic->ref_count[0];
1095  } else {
1096  --ctx->next_prev[0]->ref_count[0];
1097  for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++)
1098  ctx->next_prev[i] = ctx->next_prev[i + 1];
1099  ctx->next_prev[i] = pic;
1100  ++pic->ref_count[0];
1101  }
1102 }
1103 
1105  VAAPIEncodePicture **pic_out)
1106 {
1107  VAAPIEncodeContext *ctx = avctx->priv_data;
1108  VAAPIEncodePicture *pic = NULL, *prev = NULL, *next, *start;
1109  int i, b_counter, closed_gop_end;
1110 
1111  // If there are any B-frames already queued, the next one to encode
1112  // is the earliest not-yet-issued frame for which all references are
1113  // available.
1114  for (pic = ctx->pic_start; pic; pic = pic->next) {
1115  if (pic->encode_issued)
1116  continue;
1117  if (pic->type != PICTURE_TYPE_B)
1118  continue;
1119  for (i = 0; i < pic->nb_refs[0]; i++) {
1120  if (!pic->refs[0][i]->encode_issued)
1121  break;
1122  }
1123  if (i != pic->nb_refs[0])
1124  continue;
1125 
1126  for (i = 0; i < pic->nb_refs[1]; i++) {
1127  if (!pic->refs[1][i]->encode_issued)
1128  break;
1129  }
1130  if (i == pic->nb_refs[1])
1131  break;
1132  }
1133 
1134  if (pic) {
1135  av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
1136  "encode next.\n", pic->b_depth);
1137  *pic_out = pic;
1138  return 0;
1139  }
1140 
1141  // Find the B-per-Pth available picture to become the next picture
1142  // on the top layer.
1143  start = NULL;
1144  b_counter = 0;
1145  closed_gop_end = ctx->closed_gop ||
1146  ctx->idr_counter == ctx->gop_per_idr;
1147  for (pic = ctx->pic_start; pic; pic = next) {
1148  next = pic->next;
1149  if (pic->encode_issued) {
1150  start = pic;
1151  continue;
1152  }
1153  // If the next available picture is force-IDR, encode it to start
1154  // a new GOP immediately.
1155  if (pic->force_idr)
1156  break;
1157  if (b_counter == ctx->b_per_p)
1158  break;
1159  // If this picture ends a closed GOP or starts a new GOP then it
1160  // needs to be in the top layer.
1161  if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
1162  break;
1163  // If the picture after this one is force-IDR, we need to encode
1164  // this one in the top layer.
1165  if (next && next->force_idr)
1166  break;
1167  ++b_counter;
1168  }
1169 
1170  // At the end of the stream the last picture must be in the top layer.
1171  if (!pic && ctx->end_of_stream) {
1172  --b_counter;
1173  pic = ctx->pic_end;
1174  if (pic->encode_complete)
1175  return AVERROR_EOF;
1176  else if (pic->encode_issued)
1177  return AVERROR(EAGAIN);
1178  }
1179 
1180  if (!pic) {
1181  av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
1182  "need more input for reference pictures.\n");
1183  return AVERROR(EAGAIN);
1184  }
1185  if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
1186  av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
1187  "need more input for timestamps.\n");
1188  return AVERROR(EAGAIN);
1189  }
1190 
1191  if (pic->force_idr) {
1192  av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
1193  "encode next.\n");
1194  pic->type = PICTURE_TYPE_IDR;
1195  ctx->idr_counter = 1;
1196  ctx->gop_counter = 1;
1197 
1198  } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
1199  if (ctx->idr_counter == ctx->gop_per_idr) {
1200  av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
1201  "encode next.\n");
1202  pic->type = PICTURE_TYPE_IDR;
1203  ctx->idr_counter = 1;
1204  } else {
1205  av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
1206  "encode next.\n");
1207  pic->type = PICTURE_TYPE_I;
1208  ++ctx->idr_counter;
1209  }
1210  ctx->gop_counter = 1;
1211 
1212  } else {
1213  if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
1214  av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
1215  "encode next.\n");
1216  } else {
1217  av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
1218  "encode next.\n");
1219  }
1220  pic->type = PICTURE_TYPE_P;
1221  av_assert0(start);
1222  ctx->gop_counter += 1 + b_counter;
1223  }
1224  pic->is_reference = 1;
1225  *pic_out = pic;
1226 
1227  vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
1228  if (pic->type != PICTURE_TYPE_IDR) {
1229  // TODO: apply both previous and forward multi reference for all vaapi encoders.
1230  // And L0/L1 reference frame number can be set dynamically through query
1231  // VAConfigAttribEncMaxRefFrames attribute.
1232  if (avctx->codec_id == AV_CODEC_ID_AV1) {
1233  for (i = 0; i < ctx->nb_next_prev; i++)
1234  vaapi_encode_add_ref(avctx, pic, ctx->next_prev[i],
1235  pic->type == PICTURE_TYPE_P,
1236  b_counter > 0, 0);
1237  } else
1238  vaapi_encode_add_ref(avctx, pic, start,
1239  pic->type == PICTURE_TYPE_P,
1240  b_counter > 0, 0);
1241 
1242  vaapi_encode_add_ref(avctx, pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1);
1243  }
1244 
1245  if (b_counter > 0) {
1246  vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1,
1247  &prev);
1248  } else {
1249  prev = pic;
1250  }
1251  vaapi_encode_add_next_prev(avctx, prev);
1252 
1253  return 0;
1254 }
1255 
1257 {
1258  VAAPIEncodeContext *ctx = avctx->priv_data;
1259  VAAPIEncodePicture *pic, *prev, *next;
1260 
1261  av_assert0(ctx->pic_start);
1262 
1263  // Remove direct references once each picture is complete.
1264  for (pic = ctx->pic_start; pic; pic = pic->next) {
1265  if (pic->encode_complete && pic->next)
1266  vaapi_encode_remove_refs(avctx, pic, 0);
1267  }
1268 
1269  // Remove indirect references once a picture has no direct references.
1270  for (pic = ctx->pic_start; pic; pic = pic->next) {
1271  if (pic->encode_complete && pic->ref_count[0] == 0)
1272  vaapi_encode_remove_refs(avctx, pic, 1);
1273  }
1274 
1275  // Clear out all complete pictures with no remaining references.
1276  prev = NULL;
1277  for (pic = ctx->pic_start; pic; pic = next) {
1278  next = pic->next;
1279  if (pic->encode_complete && pic->ref_count[1] == 0) {
1280  av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
1281  if (prev)
1282  prev->next = next;
1283  else
1284  ctx->pic_start = next;
1285  vaapi_encode_free(avctx, pic);
1286  } else {
1287  prev = pic;
1288  }
1289  }
1290 
1291  return 0;
1292 }
1293 
1295  const AVFrame *frame)
1296 {
1297  VAAPIEncodeContext *ctx = avctx->priv_data;
1298 
1299  if ((frame->crop_top || frame->crop_bottom ||
1300  frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
1301  av_log(avctx, AV_LOG_WARNING, "Cropping information on input "
1302  "frames ignored due to lack of API support.\n");
1303  ctx->crop_warned = 1;
1304  }
1305 
1306  if (!ctx->roi_allowed) {
1307  AVFrameSideData *sd =
1309 
1310  if (sd && !ctx->roi_warned) {
1311  av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
1312  "frames ignored due to lack of driver support.\n");
1313  ctx->roi_warned = 1;
1314  }
1315  }
1316 
1317  return 0;
1318 }
1319 
1321 {
1322  VAAPIEncodeContext *ctx = avctx->priv_data;
1323  VAAPIEncodePicture *pic;
1324  int err;
1325 
1326  if (frame) {
1327  av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
1328  frame->width, frame->height, frame->pts);
1329 
1330  err = vaapi_encode_check_frame(avctx, frame);
1331  if (err < 0)
1332  return err;
1333 
1334  pic = vaapi_encode_alloc(avctx);
1335  if (!pic)
1336  return AVERROR(ENOMEM);
1337 
1338  pic->input_image = av_frame_alloc();
1339  if (!pic->input_image) {
1340  err = AVERROR(ENOMEM);
1341  goto fail;
1342  }
1343 
1344  if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I)
1345  pic->force_idr = 1;
1346 
1347  pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3];
1348  pic->pts = frame->pts;
1349  pic->duration = frame->duration;
1350 
1351  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
1353  if (err < 0)
1354  goto fail;
1355 
1356  pic->opaque = frame->opaque;
1357  }
1358 
1360 
1361  if (ctx->input_order == 0)
1362  ctx->first_pts = pic->pts;
1363  if (ctx->input_order == ctx->decode_delay)
1364  ctx->dts_pts_diff = pic->pts - ctx->first_pts;
1365  if (ctx->output_delay > 0)
1366  ctx->ts_ring[ctx->input_order %
1367  (3 * ctx->output_delay + ctx->async_depth)] = pic->pts;
1368 
1369  pic->display_order = ctx->input_order;
1370  ++ctx->input_order;
1371 
1372  if (ctx->pic_start) {
1373  ctx->pic_end->next = pic;
1374  ctx->pic_end = pic;
1375  } else {
1376  ctx->pic_start = pic;
1377  ctx->pic_end = pic;
1378  }
1379 
1380  } else {
1381  ctx->end_of_stream = 1;
1382 
1383  // Fix timestamps if we hit end-of-stream before the initial decode
1384  // delay has elapsed.
1385  if (ctx->input_order < ctx->decode_delay)
1386  ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
1387  }
1388 
1389  return 0;
1390 
1391 fail:
1392  vaapi_encode_free(avctx, pic);
1393  return err;
1394 }
1395 
1397 {
1398  VAAPIEncodeContext *ctx = avctx->priv_data;
1399  VAAPIEncodePicture *pic = NULL;
1400  AVFrame *frame = ctx->frame;
1401  int err;
1402 
1403 start:
1404  /** if no B frame before repeat P frame, sent repeat P frame out. */
1405  if (ctx->tail_pkt->size) {
1406  for (VAAPIEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) {
1407  if (tmp->type == PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts)
1408  break;
1409  else if (!tmp->next) {
1410  av_packet_move_ref(pkt, ctx->tail_pkt);
1411  goto end;
1412  }
1413  }
1414  }
1415 
1416  err = ff_encode_get_frame(avctx, frame);
1417  if (err < 0 && err != AVERROR_EOF)
1418  return err;
1419 
1420  if (err == AVERROR_EOF)
1421  frame = NULL;
1422 
1423  err = vaapi_encode_send_frame(avctx, frame);
1424  if (err < 0)
1425  return err;
1426 
1427  if (!ctx->pic_start) {
1428  if (ctx->end_of_stream)
1429  return AVERROR_EOF;
1430  else
1431  return AVERROR(EAGAIN);
1432  }
1433 
1434  if (ctx->has_sync_buffer_func) {
1435  if (av_fifo_can_write(ctx->encode_fifo)) {
1436  err = vaapi_encode_pick_next(avctx, &pic);
1437  if (!err) {
1438  av_assert0(pic);
1439  pic->encode_order = ctx->encode_order +
1440  av_fifo_can_read(ctx->encode_fifo);
1441  err = vaapi_encode_issue(avctx, pic);
1442  if (err < 0) {
1443  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1444  return err;
1445  }
1446  av_fifo_write(ctx->encode_fifo, &pic, 1);
1447  }
1448  }
1449 
1450  if (!av_fifo_can_read(ctx->encode_fifo))
1451  return err;
1452 
1453  // More frames can be buffered
1454  if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream)
1455  return AVERROR(EAGAIN);
1456 
1457  av_fifo_read(ctx->encode_fifo, &pic, 1);
1458  ctx->encode_order = pic->encode_order + 1;
1459  } else {
1460  err = vaapi_encode_pick_next(avctx, &pic);
1461  if (err < 0)
1462  return err;
1463  av_assert0(pic);
1464 
1465  pic->encode_order = ctx->encode_order++;
1466 
1467  err = vaapi_encode_issue(avctx, pic);
1468  if (err < 0) {
1469  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1470  return err;
1471  }
1472  }
1473 
1474  err = vaapi_encode_output(avctx, pic, pkt);
1475  if (err < 0) {
1476  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
1477  return err;
1478  }
1479 
1480  ctx->output_order = pic->encode_order;
1481  vaapi_encode_clear_old(avctx);
1482 
1483  /** loop to get an available pkt in encoder flushing. */
1484  if (ctx->end_of_stream && !pkt->size)
1485  goto start;
1486 
1487 end:
1488  if (pkt->size)
1489  av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", "
1490  "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size);
1491 
1492  return 0;
1493 }
1494 
1496  void *buffer, size_t size)
1497 {
1498  VAAPIEncodeContext *ctx = avctx->priv_data;
1499 
1500  av_assert0(ctx->nb_global_params < MAX_GLOBAL_PARAMS);
1501 
1502  ctx->global_params_type[ctx->nb_global_params] = type;
1503  ctx->global_params [ctx->nb_global_params] = buffer;
1504  ctx->global_params_size[ctx->nb_global_params] = size;
1505 
1506  ++ctx->nb_global_params;
1507 }
1508 
1509 typedef struct VAAPIEncodeRTFormat {
1510  const char *name;
1511  unsigned int value;
1512  int depth;
1517 
1519  { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1520  { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1521  { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1522 #if VA_CHECK_VERSION(1, 2, 0)
1523  { "YUV420_12", VA_RT_FORMAT_YUV420_12, 12, 3, 1, 1 },
1524  { "YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 },
1525  { "YUV422_12", VA_RT_FORMAT_YUV422_12, 12, 3, 1, 0 },
1526  { "YUV444_10", VA_RT_FORMAT_YUV444_10, 10, 3, 0, 0 },
1527  { "YUV444_12", VA_RT_FORMAT_YUV444_12, 12, 3, 0, 0 },
1528 #endif
1529  { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1530  { "XYUV", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1531  { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1532 #if VA_CHECK_VERSION(0, 38, 1)
1533  { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1534 #endif
1535 };
1536 
1537 static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
1538  VAEntrypointEncSlice,
1539  VAEntrypointEncPicture,
1540 #if VA_CHECK_VERSION(0, 39, 2)
1541  VAEntrypointEncSliceLP,
1542 #endif
1543  0
1544 };
1545 #if VA_CHECK_VERSION(0, 39, 2)
1546 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1547  VAEntrypointEncSliceLP,
1548  0
1549 };
1550 #endif
1551 
1553 {
1554  VAAPIEncodeContext *ctx = avctx->priv_data;
1555  VAProfile *va_profiles = NULL;
1556  VAEntrypoint *va_entrypoints = NULL;
1557  VAStatus vas;
1558  const VAEntrypoint *usable_entrypoints;
1559  const VAAPIEncodeProfile *profile;
1560  const AVPixFmtDescriptor *desc;
1561  VAConfigAttrib rt_format_attr;
1562  const VAAPIEncodeRTFormat *rt_format;
1563  const char *profile_string, *entrypoint_string;
1564  int i, j, n, depth, err;
1565 
1566 
1567  if (ctx->low_power) {
1568 #if VA_CHECK_VERSION(0, 39, 2)
1569  usable_entrypoints = vaapi_encode_entrypoints_low_power;
1570 #else
1571  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
1572  "supported with this VAAPI version.\n");
1573  return AVERROR(EINVAL);
1574 #endif
1575  } else {
1576  usable_entrypoints = vaapi_encode_entrypoints_normal;
1577  }
1578 
1579  desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format);
1580  if (!desc) {
1581  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
1582  ctx->input_frames->sw_format);
1583  return AVERROR(EINVAL);
1584  }
1585  depth = desc->comp[0].depth;
1586  for (i = 1; i < desc->nb_components; i++) {
1587  if (desc->comp[i].depth != depth) {
1588  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
1589  desc->name);
1590  return AVERROR(EINVAL);
1591  }
1592  }
1593  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
1594  desc->name);
1595 
1596  n = vaMaxNumProfiles(ctx->hwctx->display);
1597  va_profiles = av_malloc_array(n, sizeof(VAProfile));
1598  if (!va_profiles) {
1599  err = AVERROR(ENOMEM);
1600  goto fail;
1601  }
1602  vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
1603  if (vas != VA_STATUS_SUCCESS) {
1604  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
1605  vas, vaErrorStr(vas));
1606  err = AVERROR_EXTERNAL;
1607  goto fail;
1608  }
1609 
1610  av_assert0(ctx->codec->profiles);
1611  for (i = 0; (ctx->codec->profiles[i].av_profile !=
1612  AV_PROFILE_UNKNOWN); i++) {
1613  profile = &ctx->codec->profiles[i];
1614  if (depth != profile->depth ||
1615  desc->nb_components != profile->nb_components)
1616  continue;
1617  if (desc->nb_components > 1 &&
1618  (desc->log2_chroma_w != profile->log2_chroma_w ||
1619  desc->log2_chroma_h != profile->log2_chroma_h))
1620  continue;
1621  if (avctx->profile != profile->av_profile &&
1622  avctx->profile != AV_PROFILE_UNKNOWN)
1623  continue;
1624 
1625 #if VA_CHECK_VERSION(1, 0, 0)
1626  profile_string = vaProfileStr(profile->va_profile);
1627 #else
1628  profile_string = "(no profile names)";
1629 #endif
1630 
1631  for (j = 0; j < n; j++) {
1632  if (va_profiles[j] == profile->va_profile)
1633  break;
1634  }
1635  if (j >= n) {
1636  av_log(avctx, AV_LOG_VERBOSE, "Compatible profile %s (%d) "
1637  "is not supported by driver.\n", profile_string,
1638  profile->va_profile);
1639  continue;
1640  }
1641 
1642  ctx->profile = profile;
1643  break;
1644  }
1645  if (!ctx->profile) {
1646  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1647  err = AVERROR(ENOSYS);
1648  goto fail;
1649  }
1650 
1651  avctx->profile = profile->av_profile;
1652  ctx->va_profile = profile->va_profile;
1653  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1654  profile_string, ctx->va_profile);
1655 
1656  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1657  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1658  if (!va_entrypoints) {
1659  err = AVERROR(ENOMEM);
1660  goto fail;
1661  }
1662  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1663  va_entrypoints, &n);
1664  if (vas != VA_STATUS_SUCCESS) {
1665  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1666  "profile %s (%d): %d (%s).\n", profile_string,
1667  ctx->va_profile, vas, vaErrorStr(vas));
1668  err = AVERROR_EXTERNAL;
1669  goto fail;
1670  }
1671 
1672  for (i = 0; i < n; i++) {
1673  for (j = 0; usable_entrypoints[j]; j++) {
1674  if (va_entrypoints[i] == usable_entrypoints[j])
1675  break;
1676  }
1677  if (usable_entrypoints[j])
1678  break;
1679  }
1680  if (i >= n) {
1681  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1682  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1683  err = AVERROR(ENOSYS);
1684  goto fail;
1685  }
1686 
1687  ctx->va_entrypoint = va_entrypoints[i];
1688 #if VA_CHECK_VERSION(1, 0, 0)
1689  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1690 #else
1691  entrypoint_string = "(no entrypoint names)";
1692 #endif
1693  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1694  entrypoint_string, ctx->va_entrypoint);
1695 
1696  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1697  rt_format = &vaapi_encode_rt_formats[i];
1698  if (rt_format->depth == depth &&
1699  rt_format->nb_components == profile->nb_components &&
1700  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1701  rt_format->log2_chroma_h == profile->log2_chroma_h)
1702  break;
1703  }
1705  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1706  "found for profile %s (%d) entrypoint %s (%d).\n",
1707  profile_string, ctx->va_profile,
1708  entrypoint_string, ctx->va_entrypoint);
1709  err = AVERROR(ENOSYS);
1710  goto fail;
1711  }
1712 
1713  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1714  vas = vaGetConfigAttributes(ctx->hwctx->display,
1715  ctx->va_profile, ctx->va_entrypoint,
1716  &rt_format_attr, 1);
1717  if (vas != VA_STATUS_SUCCESS) {
1718  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1719  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1720  err = AVERROR_EXTERNAL;
1721  goto fail;
1722  }
1723 
1724  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1725  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1726  "supported by driver: assuming surface RT format %s "
1727  "is valid.\n", rt_format->name);
1728  } else if (!(rt_format_attr.value & rt_format->value)) {
1729  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1730  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1731  rt_format->name, profile_string, ctx->va_profile,
1732  entrypoint_string, ctx->va_entrypoint);
1733  err = AVERROR(ENOSYS);
1734  goto fail;
1735  } else {
1736  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1737  "format %s (%#x).\n", rt_format->name, rt_format->value);
1738  ctx->config_attributes[ctx->nb_config_attributes++] =
1739  (VAConfigAttrib) {
1740  .type = VAConfigAttribRTFormat,
1741  .value = rt_format->value,
1742  };
1743  }
1744 
1745  err = 0;
1746 fail:
1747  av_freep(&va_profiles);
1748  av_freep(&va_entrypoints);
1749  return err;
1750 }
1751 
1753  // Bitrate Quality
1754  // | Maxrate | HRD/VBV
1755  { 0 }, // | | | |
1756  { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
1757  { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
1758  { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
1759 #if VA_CHECK_VERSION(1, 1, 0)
1760  { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
1761 #else
1762  { RC_MODE_ICQ, "ICQ", 0 },
1763 #endif
1764 #if VA_CHECK_VERSION(1, 3, 0)
1765  { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
1766  { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
1767 #else
1768  { RC_MODE_QVBR, "QVBR", 0 },
1769  { RC_MODE_AVBR, "AVBR", 0 },
1770 #endif
1771 };
1772 
1774 {
1775  VAAPIEncodeContext *ctx = avctx->priv_data;
1776  uint32_t supported_va_rc_modes;
1777  const VAAPIEncodeRCMode *rc_mode;
1778  int64_t rc_bits_per_second;
1779  int rc_target_percentage;
1780  int rc_window_size;
1781  int rc_quality;
1782  int64_t hrd_buffer_size;
1783  int64_t hrd_initial_buffer_fullness;
1784  int fr_num, fr_den;
1785  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1786  VAStatus vas;
1787  char supported_rc_modes_string[64];
1788 
1789  vas = vaGetConfigAttributes(ctx->hwctx->display,
1790  ctx->va_profile, ctx->va_entrypoint,
1791  &rc_attr, 1);
1792  if (vas != VA_STATUS_SUCCESS) {
1793  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1794  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1795  return AVERROR_EXTERNAL;
1796  }
1797  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1798  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1799  "supported rate control modes: assuming CQP only.\n");
1800  supported_va_rc_modes = VA_RC_CQP;
1801  strcpy(supported_rc_modes_string, "unknown");
1802  } else {
1803  char *str = supported_rc_modes_string;
1804  size_t len = sizeof(supported_rc_modes_string);
1805  int i, first = 1, res;
1806 
1807  supported_va_rc_modes = rc_attr.value;
1808  if (ctx->blbrc && !(supported_va_rc_modes & VA_RC_MB)) {
1809  ctx->blbrc = 0;
1810  av_log(avctx, AV_LOG_WARNING, "Driver does not support BLBRC.\n");
1811  }
1812 
1813  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1815  if (supported_va_rc_modes & rc_mode->va_mode) {
1816  res = snprintf(str, len, "%s%s",
1817  first ? "" : ", ", rc_mode->name);
1818  first = 0;
1819  if (res < 0) {
1820  *str = 0;
1821  break;
1822  }
1823  len -= res;
1824  str += res;
1825  if (len == 0)
1826  break;
1827  }
1828  }
1829 
1830  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1831  supported_rc_modes_string);
1832  }
1833 
1834  // Rate control mode selection:
1835  // * If the user has set a mode explicitly with the rc_mode option,
1836  // use it and fail if it is not available.
1837  // * If an explicit QP option has been set, use CQP.
1838  // * If the codec is CQ-only, use CQP.
1839  // * If the QSCALE avcodec option is set, use CQP.
1840  // * If bitrate and quality are both set, try QVBR.
1841  // * If quality is set, try ICQ, then CQP.
1842  // * If bitrate and maxrate are set and have the same value, try CBR.
1843  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1844  // * If no bitrate is set, try ICQ, then CQP.
1845 
1846 #define TRY_RC_MODE(mode, fail) do { \
1847  rc_mode = &vaapi_encode_rc_modes[mode]; \
1848  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1849  if (fail) { \
1850  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1851  "RC mode (supported modes: %s).\n", rc_mode->name, \
1852  supported_rc_modes_string); \
1853  return AVERROR(EINVAL); \
1854  } \
1855  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1856  "RC mode.\n", rc_mode->name); \
1857  rc_mode = NULL; \
1858  } else { \
1859  goto rc_mode_found; \
1860  } \
1861  } while (0)
1862 
1863  if (ctx->explicit_rc_mode)
1864  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1865 
1866  if (ctx->explicit_qp)
1868 
1869  if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY)
1871 
1872  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1874 
1875  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1877 
1878  if (avctx->global_quality > 0) {
1881  }
1882 
1883  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1885 
1886  if (avctx->bit_rate > 0) {
1890  } else {
1893  }
1894 
1895  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1896  "RC mode compatible with selected options "
1897  "(supported modes: %s).\n", supported_rc_modes_string);
1898  return AVERROR(EINVAL);
1899 
1900 rc_mode_found:
1901  if (rc_mode->bitrate) {
1902  if (avctx->bit_rate <= 0) {
1903  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1904  "RC mode.\n", rc_mode->name);
1905  return AVERROR(EINVAL);
1906  }
1907 
1908  if (rc_mode->mode == RC_MODE_AVBR) {
1909  // For maximum confusion AVBR is hacked into the existing API
1910  // by overloading some of the fields with completely different
1911  // meanings.
1912 
1913  // Target percentage does not apply in AVBR mode.
1914  rc_bits_per_second = avctx->bit_rate;
1915 
1916  // Accuracy tolerance range for meeting the specified target
1917  // bitrate. It's very unclear how this is actually intended
1918  // to work - since we do want to get the specified bitrate,
1919  // set the accuracy to 100% for now.
1920  rc_target_percentage = 100;
1921 
1922  // Convergence period in frames. The GOP size reflects the
1923  // user's intended block size for cutting, so reusing that
1924  // as the convergence period seems a reasonable default.
1925  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1926 
1927  } else if (rc_mode->maxrate) {
1928  if (avctx->rc_max_rate > 0) {
1929  if (avctx->rc_max_rate < avctx->bit_rate) {
1930  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1931  "bitrate (%"PRId64") must not be greater than "
1932  "maxrate (%"PRId64").\n", avctx->bit_rate,
1933  avctx->rc_max_rate);
1934  return AVERROR(EINVAL);
1935  }
1936  rc_bits_per_second = avctx->rc_max_rate;
1937  rc_target_percentage = (avctx->bit_rate * 100) /
1938  avctx->rc_max_rate;
1939  } else {
1940  // We only have a target bitrate, but this mode requires
1941  // that a maximum rate be supplied as well. Since the
1942  // user does not want this to be a constraint, arbitrarily
1943  // pick a maximum rate of double the target rate.
1944  rc_bits_per_second = 2 * avctx->bit_rate;
1945  rc_target_percentage = 50;
1946  }
1947  } else {
1948  if (avctx->rc_max_rate > avctx->bit_rate) {
1949  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1950  "in %s RC mode.\n", rc_mode->name);
1951  }
1952  rc_bits_per_second = avctx->bit_rate;
1953  rc_target_percentage = 100;
1954  }
1955  } else {
1956  rc_bits_per_second = 0;
1957  rc_target_percentage = 100;
1958  }
1959 
1960  if (rc_mode->quality) {
1961  if (ctx->explicit_qp) {
1962  rc_quality = ctx->explicit_qp;
1963  } else if (avctx->global_quality > 0) {
1964  rc_quality = avctx->global_quality;
1965  } else {
1966  rc_quality = ctx->codec->default_quality;
1967  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1968  "using default (%d).\n", rc_quality);
1969  }
1970  } else {
1971  rc_quality = 0;
1972  }
1973 
1974  if (rc_mode->hrd) {
1975  if (avctx->rc_buffer_size)
1976  hrd_buffer_size = avctx->rc_buffer_size;
1977  else if (avctx->rc_max_rate > 0)
1978  hrd_buffer_size = avctx->rc_max_rate;
1979  else
1980  hrd_buffer_size = avctx->bit_rate;
1981  if (avctx->rc_initial_buffer_occupancy) {
1982  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1983  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1984  "must have initial buffer size (%d) <= "
1985  "buffer size (%"PRId64").\n",
1986  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1987  return AVERROR(EINVAL);
1988  }
1989  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1990  } else {
1991  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1992  }
1993 
1994  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1995  } else {
1996  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
1997  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
1998  "in %s RC mode.\n", rc_mode->name);
1999  }
2000 
2001  hrd_buffer_size = 0;
2002  hrd_initial_buffer_fullness = 0;
2003 
2004  if (rc_mode->mode != RC_MODE_AVBR) {
2005  // Already set (with completely different meaning) for AVBR.
2006  rc_window_size = 1000;
2007  }
2008  }
2009 
2010  if (rc_bits_per_second > UINT32_MAX ||
2011  hrd_buffer_size > UINT32_MAX ||
2012  hrd_initial_buffer_fullness > UINT32_MAX) {
2013  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
2014  "greater are not supported by VAAPI.\n");
2015  return AVERROR(EINVAL);
2016  }
2017 
2018  ctx->rc_mode = rc_mode;
2019  ctx->rc_quality = rc_quality;
2020  ctx->va_rc_mode = rc_mode->va_mode;
2021  ctx->va_bit_rate = rc_bits_per_second;
2022 
2023  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
2024 
2025  if (ctx->blbrc && ctx->va_rc_mode == VA_RC_CQP)
2026  ctx->blbrc = 0;
2027  av_log(avctx, AV_LOG_VERBOSE, "Block Level bitrate control: %s.\n", ctx->blbrc ? "ON" : "OFF");
2028 
2029  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2030  // This driver does not want the RC mode attribute to be set.
2031  } else {
2032  ctx->config_attributes[ctx->nb_config_attributes++] =
2033  (VAConfigAttrib) {
2034  .type = VAConfigAttribRateControl,
2035  .value = ctx->blbrc ? ctx->va_rc_mode | VA_RC_MB : ctx->va_rc_mode,
2036  };
2037  }
2038 
2039  if (rc_mode->quality)
2040  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
2041 
2042  if (rc_mode->va_mode != VA_RC_CQP) {
2043  if (rc_mode->mode == RC_MODE_AVBR) {
2044  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
2045  "converging in %d frames with %d%% accuracy.\n",
2046  rc_bits_per_second, rc_window_size,
2047  rc_target_percentage);
2048  } else if (rc_mode->bitrate) {
2049  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
2050  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
2051  rc_bits_per_second, rc_window_size);
2052  }
2053 
2054  ctx->rc_params = (VAEncMiscParameterRateControl) {
2055  .bits_per_second = rc_bits_per_second,
2056  .target_percentage = rc_target_percentage,
2057  .window_size = rc_window_size,
2058  .initial_qp = 0,
2059  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
2060  .basic_unit_size = 0,
2061 #if VA_CHECK_VERSION(1, 1, 0)
2062  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
2063  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
2064  .rc_flags.bits.mb_rate_control = ctx->blbrc ? 1 : 2,
2065 #endif
2066 #if VA_CHECK_VERSION(1, 3, 0)
2067  .quality_factor = rc_quality,
2068 #endif
2069  };
2071  VAEncMiscParameterTypeRateControl,
2072  &ctx->rc_params,
2073  sizeof(ctx->rc_params));
2074  }
2075 
2076  if (rc_mode->hrd) {
2077  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
2078  "initial fullness %"PRId64" bits.\n",
2079  hrd_buffer_size, hrd_initial_buffer_fullness);
2080 
2081  ctx->hrd_params = (VAEncMiscParameterHRD) {
2082  .initial_buffer_fullness = hrd_initial_buffer_fullness,
2083  .buffer_size = hrd_buffer_size,
2084  };
2086  VAEncMiscParameterTypeHRD,
2087  &ctx->hrd_params,
2088  sizeof(ctx->hrd_params));
2089  }
2090 
2091  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
2092  av_reduce(&fr_num, &fr_den,
2093  avctx->framerate.num, avctx->framerate.den, 65535);
2094  else
2095  av_reduce(&fr_num, &fr_den,
2096  avctx->time_base.den, avctx->time_base.num, 65535);
2097 
2098  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
2099  fr_num, fr_den, (double)fr_num / fr_den);
2100 
2101  ctx->fr_params = (VAEncMiscParameterFrameRate) {
2102  .framerate = (unsigned int)fr_den << 16 | fr_num,
2103  };
2104 #if VA_CHECK_VERSION(0, 40, 0)
2106  VAEncMiscParameterTypeFrameRate,
2107  &ctx->fr_params,
2108  sizeof(ctx->fr_params));
2109 #endif
2110 
2111  return 0;
2112 }
2113 
2115 {
2116 #if VA_CHECK_VERSION(1, 5, 0)
2117  VAAPIEncodeContext *ctx = avctx->priv_data;
2118  VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
2119  VAStatus vas;
2120 
2121  if (ctx->va_rc_mode == VA_RC_CQP) {
2122  ctx->max_frame_size = 0;
2123  av_log(avctx, AV_LOG_ERROR, "Max frame size is invalid in CQP rate "
2124  "control mode.\n");
2125  return AVERROR(EINVAL);
2126  }
2127 
2128  vas = vaGetConfigAttributes(ctx->hwctx->display,
2129  ctx->va_profile,
2130  ctx->va_entrypoint,
2131  &attr, 1);
2132  if (vas != VA_STATUS_SUCCESS) {
2133  ctx->max_frame_size = 0;
2134  av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
2135  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2136  return AVERROR_EXTERNAL;
2137  }
2138 
2139  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2140  ctx->max_frame_size = 0;
2141  av_log(avctx, AV_LOG_ERROR, "Max frame size attribute "
2142  "is not supported.\n");
2143  return AVERROR(EINVAL);
2144  } else {
2145  VAConfigAttribValMaxFrameSize attr_mfs;
2146  attr_mfs.value = attr.value;
2147  // Prefer to use VAEncMiscParameterTypeMaxFrameSize for max frame size.
2148  if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
2149  ctx->max_frame_size = 0;
2150  av_log(avctx, AV_LOG_ERROR, "Driver only supports multiple pass "
2151  "max frame size which has not been implemented in FFmpeg.\n");
2152  return AVERROR(EINVAL);
2153  }
2154 
2155  ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
2156  .max_frame_size = ctx->max_frame_size * 8,
2157  };
2158 
2159  av_log(avctx, AV_LOG_VERBOSE, "Set max frame size: %d bytes.\n",
2160  ctx->max_frame_size);
2161  }
2162 #else
2163  av_log(avctx, AV_LOG_ERROR, "The max frame size option is not supported with "
2164  "this VAAPI version.\n");
2165  return AVERROR(EINVAL);
2166 #endif
2167 
2168  return 0;
2169 }
2170 
2172 {
2173  VAAPIEncodeContext *ctx = avctx->priv_data;
2174  VAStatus vas;
2175  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
2176  uint32_t ref_l0, ref_l1;
2177  int prediction_pre_only;
2178 
2179  vas = vaGetConfigAttributes(ctx->hwctx->display,
2180  ctx->va_profile,
2181  ctx->va_entrypoint,
2182  &attr, 1);
2183  if (vas != VA_STATUS_SUCCESS) {
2184  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
2185  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2186  return AVERROR_EXTERNAL;
2187  }
2188 
2189  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2190  ref_l0 = ref_l1 = 0;
2191  } else {
2192  ref_l0 = attr.value & 0xffff;
2193  ref_l1 = attr.value >> 16 & 0xffff;
2194  }
2195 
2196  ctx->p_to_gpb = 0;
2197  prediction_pre_only = 0;
2198 
2199 #if VA_CHECK_VERSION(1, 9, 0)
2200  if (!(ctx->codec->flags & FLAG_INTRA_ONLY ||
2201  avctx->gop_size <= 1)) {
2202  attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
2203  vas = vaGetConfigAttributes(ctx->hwctx->display,
2204  ctx->va_profile,
2205  ctx->va_entrypoint,
2206  &attr, 1);
2207  if (vas != VA_STATUS_SUCCESS) {
2208  av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
2209  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2210  return AVERROR_EXTERNAL;
2211  } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2212  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
2213  "prediction constraints.\n");
2214  } else {
2215  if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
2216  ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
2217  av_log(avctx, AV_LOG_ERROR, "Driver report incorrect prediction "
2218  "direction attribute.\n");
2219  return AVERROR_EXTERNAL;
2220  }
2221 
2222  if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
2223  if (ref_l0 > 0 && ref_l1 > 0) {
2224  prediction_pre_only = 1;
2225  av_log(avctx, AV_LOG_VERBOSE, "Driver only support same reference "
2226  "lists for B-frames.\n");
2227  }
2228  }
2229 
2230  if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
2231  if (ref_l0 > 0 && ref_l1 > 0) {
2232  ctx->p_to_gpb = 1;
2233  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
2234  "replacing them with B-frames.\n");
2235  }
2236  }
2237  }
2238  }
2239 #endif
2240 
2241  if (ctx->codec->flags & FLAG_INTRA_ONLY ||
2242  avctx->gop_size <= 1) {
2243  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
2244  ctx->gop_size = 1;
2245  } else if (ref_l0 < 1) {
2246  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
2247  "reference frames.\n");
2248  return AVERROR(EINVAL);
2249  } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
2250  ref_l1 < 1 || avctx->max_b_frames < 1 ||
2251  prediction_pre_only) {
2252  if (ctx->p_to_gpb)
2253  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2254  "(supported references: %d / %d).\n",
2255  ref_l0, ref_l1);
2256  else
2257  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
2258  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2259  ctx->gop_size = avctx->gop_size;
2260  ctx->p_per_i = INT_MAX;
2261  ctx->b_per_p = 0;
2262  } else {
2263  if (ctx->p_to_gpb)
2264  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2265  "(supported references: %d / %d).\n",
2266  ref_l0, ref_l1);
2267  else
2268  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
2269  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2270  ctx->gop_size = avctx->gop_size;
2271  ctx->p_per_i = INT_MAX;
2272  ctx->b_per_p = avctx->max_b_frames;
2273  if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
2274  ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
2275  av_log2(ctx->b_per_p) + 1);
2276  } else {
2277  ctx->max_b_depth = 1;
2278  }
2279  }
2280 
2281  if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
2282  ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
2283  ctx->gop_per_idr = ctx->idr_interval + 1;
2284  } else {
2285  ctx->closed_gop = 1;
2286  ctx->gop_per_idr = 1;
2287  }
2288 
2289  return 0;
2290 }
2291 
2293  uint32_t slice_structure)
2294 {
2295  VAAPIEncodeContext *ctx = avctx->priv_data;
2296  int req_slices;
2297 
2298  // For fixed-size slices currently we only support whole rows, making
2299  // rectangular slices. This could be extended to arbitrary runs of
2300  // blocks, but since slices tend to be a conformance requirement and
2301  // most cases (such as broadcast or bluray) want rectangular slices
2302  // only it would need to be gated behind another option.
2303  if (avctx->slices > ctx->slice_block_rows) {
2304  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
2305  "configured number of slices (%d < %d); using "
2306  "maximum.\n", ctx->slice_block_rows, avctx->slices);
2307  req_slices = ctx->slice_block_rows;
2308  } else {
2309  req_slices = avctx->slices;
2310  }
2311  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
2312  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
2313  ctx->nb_slices = req_slices;
2314  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
2315  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
2316  int k;
2317  for (k = 1;; k *= 2) {
2318  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
2319  break;
2320  }
2321  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
2322  ctx->slice_size = k;
2323 #if VA_CHECK_VERSION(1, 0, 0)
2324  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
2325  ctx->nb_slices = ctx->slice_block_rows;
2326  ctx->slice_size = 1;
2327 #endif
2328  } else {
2329  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
2330  "slice structure modes (%#x).\n", slice_structure);
2331  return AVERROR(EINVAL);
2332  }
2333 
2334  return 0;
2335 }
2336 
2338  uint32_t slice_structure)
2339 {
2340  VAAPIEncodeContext *ctx = avctx->priv_data;
2341  int i, req_tiles;
2342 
2343  if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
2344  (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
2345  ctx->tile_cols == 1))) {
2346  av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
2347  "current tile requirement.\n", slice_structure);
2348  return AVERROR(EINVAL);
2349  }
2350 
2351  if (ctx->tile_rows > ctx->slice_block_rows ||
2352  ctx->tile_cols > ctx->slice_block_cols) {
2353  av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
2354  "for configured number of tile (%d x %d); ",
2355  ctx->slice_block_rows, ctx->slice_block_cols,
2356  ctx->tile_rows, ctx->tile_cols);
2357  ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
2358  ctx->slice_block_rows : ctx->tile_rows;
2359  ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
2360  ctx->slice_block_cols : ctx->tile_cols;
2361  av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
2362  ctx->tile_rows, ctx->tile_cols);
2363  }
2364 
2365  req_tiles = ctx->tile_rows * ctx->tile_cols;
2366 
2367  // Tile slice is not allowed to cross the boundary of a tile due to
2368  // the constraints of media-driver. Currently we support one slice
2369  // per tile. This could be extended to multiple slices per tile.
2370  if (avctx->slices != req_tiles)
2371  av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
2372  "mismatches with configured number of tile (%d != %d); "
2373  "using requested tile number for slice.\n",
2374  avctx->slices, req_tiles);
2375 
2376  ctx->nb_slices = req_tiles;
2377 
2378  // Default in uniform spacing
2379  // 6-3, 6-5
2380  for (i = 0; i < ctx->tile_cols; i++) {
2381  ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
2382  i * ctx->slice_block_cols / ctx->tile_cols;
2383  ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
2384  }
2385  // 6-4, 6-6
2386  for (i = 0; i < ctx->tile_rows; i++) {
2387  ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
2388  i * ctx->slice_block_rows / ctx->tile_rows;
2389  ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
2390  }
2391 
2392  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
2393  ctx->tile_rows, ctx->tile_cols);
2394 
2395  return 0;
2396 }
2397 
2399 {
2400  VAAPIEncodeContext *ctx = avctx->priv_data;
2401  VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
2402  { VAConfigAttribEncSliceStructure },
2403 #if VA_CHECK_VERSION(1, 1, 0)
2404  { VAConfigAttribEncTileSupport },
2405 #endif
2406  };
2407  VAStatus vas;
2408  uint32_t max_slices, slice_structure;
2409  int ret;
2410 
2411  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
2412  if (avctx->slices > 0) {
2413  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
2414  "but this codec does not support controlling slices.\n");
2415  }
2416  return 0;
2417  }
2418 
2419  av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0);
2420 
2421  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
2422  ctx->slice_block_height;
2423  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
2424  ctx->slice_block_width;
2425 
2426  if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
2427  ctx->nb_slices = 1;
2428  ctx->slice_size = ctx->slice_block_rows;
2429  return 0;
2430  }
2431 
2432  vas = vaGetConfigAttributes(ctx->hwctx->display,
2433  ctx->va_profile,
2434  ctx->va_entrypoint,
2435  attr, FF_ARRAY_ELEMS(attr));
2436  if (vas != VA_STATUS_SUCCESS) {
2437  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
2438  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
2439  return AVERROR_EXTERNAL;
2440  }
2441  max_slices = attr[0].value;
2442  slice_structure = attr[1].value;
2443  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
2444  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
2445  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2446  "pictures as multiple slices.\n.");
2447  return AVERROR(EINVAL);
2448  }
2449 
2450  if (ctx->tile_rows && ctx->tile_cols) {
2451 #if VA_CHECK_VERSION(1, 1, 0)
2452  uint32_t tile_support = attr[2].value;
2453  if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
2454  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2455  "pictures as multiple tiles.\n.");
2456  return AVERROR(EINVAL);
2457  }
2458 #else
2459  av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
2460  "not supported with this VAAPI version.\n");
2461  return AVERROR(EINVAL);
2462 #endif
2463  }
2464 
2465  if (ctx->tile_rows && ctx->tile_cols)
2466  ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
2467  else
2468  ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
2469  if (ret < 0)
2470  return ret;
2471 
2472  if (ctx->nb_slices > avctx->slices) {
2473  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
2474  "%d (from %d) due to driver constraints on slice "
2475  "structure.\n", ctx->nb_slices, avctx->slices);
2476  }
2477  if (ctx->nb_slices > max_slices) {
2478  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
2479  "encoding with %d slices (max %"PRIu32").\n",
2480  ctx->nb_slices, max_slices);
2481  return AVERROR(EINVAL);
2482  }
2483 
2484  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
2485  ctx->nb_slices);
2486  return 0;
2487 }
2488 
2490 {
2491  VAAPIEncodeContext *ctx = avctx->priv_data;
2492  VAStatus vas;
2493  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
2494 
2495  vas = vaGetConfigAttributes(ctx->hwctx->display,
2496  ctx->va_profile,
2497  ctx->va_entrypoint,
2498  &attr, 1);
2499  if (vas != VA_STATUS_SUCCESS) {
2500  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
2501  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2502  return AVERROR_EXTERNAL;
2503  }
2504 
2505  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2506  if (ctx->desired_packed_headers) {
2507  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
2508  "packed headers (wanted %#x).\n",
2509  ctx->desired_packed_headers);
2510  } else {
2511  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
2512  "packed headers (none wanted).\n");
2513  }
2514  ctx->va_packed_headers = 0;
2515  } else {
2516  if (ctx->desired_packed_headers & ~attr.value) {
2517  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
2518  "wanted packed headers (wanted %#x, found %#x).\n",
2519  ctx->desired_packed_headers, attr.value);
2520  } else {
2521  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
2522  "available (wanted %#x, found %#x).\n",
2523  ctx->desired_packed_headers, attr.value);
2524  }
2525  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
2526  }
2527 
2528  if (ctx->va_packed_headers) {
2529  ctx->config_attributes[ctx->nb_config_attributes++] =
2530  (VAConfigAttrib) {
2531  .type = VAConfigAttribEncPackedHeaders,
2532  .value = ctx->va_packed_headers,
2533  };
2534  }
2535 
2536  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2537  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2538  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
2539  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
2540  "sequence headers, but a global header is requested.\n");
2541  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
2542  "this may result in a stream which is not usable for some "
2543  "purposes (e.g. not muxable to some containers).\n");
2544  }
2545 
2546  return 0;
2547 }
2548 
2550 {
2551 #if VA_CHECK_VERSION(0, 36, 0)
2552  VAAPIEncodeContext *ctx = avctx->priv_data;
2553  VAStatus vas;
2554  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
2555  int quality = avctx->compression_level;
2556 
2557  vas = vaGetConfigAttributes(ctx->hwctx->display,
2558  ctx->va_profile,
2559  ctx->va_entrypoint,
2560  &attr, 1);
2561  if (vas != VA_STATUS_SUCCESS) {
2562  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
2563  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2564  return AVERROR_EXTERNAL;
2565  }
2566 
2567  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2568  if (quality != 0) {
2569  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
2570  "supported: will use default quality level.\n");
2571  }
2572  } else {
2573  if (quality > attr.value) {
2574  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
2575  "valid range is 0-%d, using %d.\n",
2576  attr.value, attr.value);
2577  quality = attr.value;
2578  }
2579 
2580  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2581  .quality_level = quality,
2582  };
2584  VAEncMiscParameterTypeQualityLevel,
2585  &ctx->quality_params,
2586  sizeof(ctx->quality_params));
2587  }
2588 #else
2589  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
2590  "not supported with this VAAPI version.\n");
2591 #endif
2592 
2593  return 0;
2594 }
2595 
2597 {
2598 #if VA_CHECK_VERSION(1, 0, 0)
2599  VAAPIEncodeContext *ctx = avctx->priv_data;
2600  VAStatus vas;
2601  VAConfigAttrib attr = { VAConfigAttribEncROI };
2602 
2603  vas = vaGetConfigAttributes(ctx->hwctx->display,
2604  ctx->va_profile,
2605  ctx->va_entrypoint,
2606  &attr, 1);
2607  if (vas != VA_STATUS_SUCCESS) {
2608  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
2609  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2610  return AVERROR_EXTERNAL;
2611  }
2612 
2613  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2614  ctx->roi_allowed = 0;
2615  } else {
2616  VAConfigAttribValEncROI roi = {
2617  .value = attr.value,
2618  };
2619 
2620  ctx->roi_max_regions = roi.bits.num_roi_regions;
2621  ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2622  (ctx->va_rc_mode == VA_RC_CQP ||
2623  roi.bits.roi_rc_qp_delta_support);
2624  }
2625 #endif
2626  return 0;
2627 }
2628 
2630  void *obj)
2631 {
2632  AVCodecContext *avctx = opaque.nc;
2633  VAAPIEncodeContext *ctx = avctx->priv_data;
2634  VABufferID *buffer_id_ref = obj;
2635  VABufferID buffer_id = *buffer_id_ref;
2636 
2637  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2638 
2639  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2640 }
2641 
2643 {
2644  AVCodecContext *avctx = opaque.nc;
2645  VAAPIEncodeContext *ctx = avctx->priv_data;
2646  VABufferID *buffer_id = obj;
2647  VAStatus vas;
2648 
2649  // The output buffer size is fixed, so it needs to be large enough
2650  // to hold the largest possible compressed frame. We assume here
2651  // that the uncompressed frame plus some header data is an upper
2652  // bound on that.
2653  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2654  VAEncCodedBufferType,
2655  3 * ctx->surface_width * ctx->surface_height +
2656  (1 << 16), 1, 0, buffer_id);
2657  if (vas != VA_STATUS_SUCCESS) {
2658  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2659  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2660  return AVERROR(ENOMEM);
2661  }
2662 
2663  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", *buffer_id);
2664 
2665  return 0;
2666 }
2667 
2669 {
2670  VAAPIEncodeContext *ctx = avctx->priv_data;
2671  AVVAAPIHWConfig *hwconfig = NULL;
2672  AVHWFramesConstraints *constraints = NULL;
2673  enum AVPixelFormat recon_format;
2674  int err, i;
2675 
2676  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
2677  if (!hwconfig) {
2678  err = AVERROR(ENOMEM);
2679  goto fail;
2680  }
2681  hwconfig->config_id = ctx->va_config;
2682 
2683  constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
2684  hwconfig);
2685  if (!constraints) {
2686  err = AVERROR(ENOMEM);
2687  goto fail;
2688  }
2689 
2690  // Probably we can use the input surface format as the surface format
2691  // of the reconstructed frames. If not, we just pick the first (only?)
2692  // format in the valid list and hope that it all works.
2693  recon_format = AV_PIX_FMT_NONE;
2694  if (constraints->valid_sw_formats) {
2695  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
2696  if (ctx->input_frames->sw_format ==
2697  constraints->valid_sw_formats[i]) {
2698  recon_format = ctx->input_frames->sw_format;
2699  break;
2700  }
2701  }
2702  if (recon_format == AV_PIX_FMT_NONE) {
2703  // No match. Just use the first in the supported list and
2704  // hope for the best.
2705  recon_format = constraints->valid_sw_formats[0];
2706  }
2707  } else {
2708  // No idea what to use; copy input format.
2709  recon_format = ctx->input_frames->sw_format;
2710  }
2711  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
2712  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
2713 
2714  if (ctx->surface_width < constraints->min_width ||
2715  ctx->surface_height < constraints->min_height ||
2716  ctx->surface_width > constraints->max_width ||
2717  ctx->surface_height > constraints->max_height) {
2718  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
2719  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2720  ctx->surface_width, ctx->surface_height,
2721  constraints->min_width, constraints->max_width,
2722  constraints->min_height, constraints->max_height);
2723  err = AVERROR(EINVAL);
2724  goto fail;
2725  }
2726 
2727  av_freep(&hwconfig);
2728  av_hwframe_constraints_free(&constraints);
2729 
2730  ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
2731  if (!ctx->recon_frames_ref) {
2732  err = AVERROR(ENOMEM);
2733  goto fail;
2734  }
2735  ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
2736 
2737  ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
2738  ctx->recon_frames->sw_format = recon_format;
2739  ctx->recon_frames->width = ctx->surface_width;
2740  ctx->recon_frames->height = ctx->surface_height;
2741 
2742  err = av_hwframe_ctx_init(ctx->recon_frames_ref);
2743  if (err < 0) {
2744  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2745  "frame context: %d.\n", err);
2746  goto fail;
2747  }
2748 
2749  err = 0;
2750  fail:
2751  av_freep(&hwconfig);
2752  av_hwframe_constraints_free(&constraints);
2753  return err;
2754 }
2755 
2757 {
2758  VAAPIEncodeContext *ctx = avctx->priv_data;
2759  AVVAAPIFramesContext *recon_hwctx = NULL;
2760  VAStatus vas;
2761  int err;
2762 
2763  ctx->va_config = VA_INVALID_ID;
2764  ctx->va_context = VA_INVALID_ID;
2765 
2766  /* If you add something that can fail above this av_frame_alloc(),
2767  * modify ff_vaapi_encode_close() accordingly. */
2768  ctx->frame = av_frame_alloc();
2769  if (!ctx->frame) {
2770  return AVERROR(ENOMEM);
2771  }
2772 
2773  if (!avctx->hw_frames_ctx) {
2774  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
2775  "required to associate the encoding device.\n");
2776  return AVERROR(EINVAL);
2777  }
2778 
2779  ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
2780  if (!ctx->input_frames_ref) {
2781  err = AVERROR(ENOMEM);
2782  goto fail;
2783  }
2784  ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
2785 
2786  ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
2787  if (!ctx->device_ref) {
2788  err = AVERROR(ENOMEM);
2789  goto fail;
2790  }
2791  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
2792  ctx->hwctx = ctx->device->hwctx;
2793 
2794  ctx->tail_pkt = av_packet_alloc();
2795  if (!ctx->tail_pkt) {
2796  err = AVERROR(ENOMEM);
2797  goto fail;
2798  }
2799 
2800  err = vaapi_encode_profile_entrypoint(avctx);
2801  if (err < 0)
2802  goto fail;
2803 
2804  if (ctx->codec->get_encoder_caps) {
2805  err = ctx->codec->get_encoder_caps(avctx);
2806  if (err < 0)
2807  goto fail;
2808  } else {
2809  // Assume 16x16 blocks.
2810  ctx->surface_width = FFALIGN(avctx->width, 16);
2811  ctx->surface_height = FFALIGN(avctx->height, 16);
2812  if (ctx->codec->flags & FLAG_SLICE_CONTROL) {
2813  ctx->slice_block_width = 16;
2814  ctx->slice_block_height = 16;
2815  }
2816  }
2817 
2818  err = vaapi_encode_init_rate_control(avctx);
2819  if (err < 0)
2820  goto fail;
2821 
2822  err = vaapi_encode_init_gop_structure(avctx);
2823  if (err < 0)
2824  goto fail;
2825 
2826  err = vaapi_encode_init_slice_structure(avctx);
2827  if (err < 0)
2828  goto fail;
2829 
2830  err = vaapi_encode_init_packed_headers(avctx);
2831  if (err < 0)
2832  goto fail;
2833 
2834  err = vaapi_encode_init_roi(avctx);
2835  if (err < 0)
2836  goto fail;
2837 
2838  if (avctx->compression_level >= 0) {
2839  err = vaapi_encode_init_quality(avctx);
2840  if (err < 0)
2841  goto fail;
2842  }
2843 
2844  if (ctx->max_frame_size) {
2845  err = vaapi_encode_init_max_frame_size(avctx);
2846  if (err < 0)
2847  goto fail;
2848  }
2849 
2850  vas = vaCreateConfig(ctx->hwctx->display,
2851  ctx->va_profile, ctx->va_entrypoint,
2852  ctx->config_attributes, ctx->nb_config_attributes,
2853  &ctx->va_config);
2854  if (vas != VA_STATUS_SUCCESS) {
2855  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2856  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2857  err = AVERROR(EIO);
2858  goto fail;
2859  }
2860 
2861  err = vaapi_encode_create_recon_frames(avctx);
2862  if (err < 0)
2863  goto fail;
2864 
2865  recon_hwctx = ctx->recon_frames->hwctx;
2866  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2867  ctx->surface_width, ctx->surface_height,
2868  VA_PROGRESSIVE,
2869  recon_hwctx->surface_ids,
2870  recon_hwctx->nb_surfaces,
2871  &ctx->va_context);
2872  if (vas != VA_STATUS_SUCCESS) {
2873  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2874  "context: %d (%s).\n", vas, vaErrorStr(vas));
2875  err = AVERROR(EIO);
2876  goto fail;
2877  }
2878 
2879  ctx->output_buffer_pool =
2880  ff_refstruct_pool_alloc_ext(sizeof(VABufferID), 0, avctx,
2883  if (!ctx->output_buffer_pool) {
2884  err = AVERROR(ENOMEM);
2885  goto fail;
2886  }
2887 
2888  if (ctx->codec->configure) {
2889  err = ctx->codec->configure(avctx);
2890  if (err < 0)
2891  goto fail;
2892  }
2893 
2894  ctx->output_delay = ctx->b_per_p;
2895  ctx->decode_delay = ctx->max_b_depth;
2896 
2897  if (ctx->codec->sequence_params_size > 0) {
2898  ctx->codec_sequence_params =
2899  av_mallocz(ctx->codec->sequence_params_size);
2900  if (!ctx->codec_sequence_params) {
2901  err = AVERROR(ENOMEM);
2902  goto fail;
2903  }
2904  }
2905  if (ctx->codec->picture_params_size > 0) {
2906  ctx->codec_picture_params =
2907  av_mallocz(ctx->codec->picture_params_size);
2908  if (!ctx->codec_picture_params) {
2909  err = AVERROR(ENOMEM);
2910  goto fail;
2911  }
2912  }
2913 
2914  if (ctx->codec->init_sequence_params) {
2915  err = ctx->codec->init_sequence_params(avctx);
2916  if (err < 0) {
2917  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2918  "failed: %d.\n", err);
2919  goto fail;
2920  }
2921  }
2922 
2923  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2924  ctx->codec->write_sequence_header &&
2927  size_t bit_len = 8 * sizeof(data);
2928 
2929  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2930  if (err < 0) {
2931  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2932  "for extradata: %d.\n", err);
2933  goto fail;
2934  } else {
2935  avctx->extradata_size = (bit_len + 7) / 8;
2936  avctx->extradata = av_mallocz(avctx->extradata_size +
2938  if (!avctx->extradata) {
2939  err = AVERROR(ENOMEM);
2940  goto fail;
2941  }
2942  memcpy(avctx->extradata, data, avctx->extradata_size);
2943  }
2944  }
2945 
2946 #if VA_CHECK_VERSION(1, 9, 0)
2947  // check vaSyncBuffer function
2948  vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2949  if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2950  ctx->has_sync_buffer_func = 1;
2951  ctx->encode_fifo = av_fifo_alloc2(ctx->async_depth,
2952  sizeof(VAAPIEncodePicture *),
2953  0);
2954  if (!ctx->encode_fifo)
2955  return AVERROR(ENOMEM);
2956  }
2957 #endif
2958 
2959  return 0;
2960 
2961 fail:
2962  return err;
2963 }
2964 
2966 {
2967  VAAPIEncodeContext *ctx = avctx->priv_data;
2968  VAAPIEncodePicture *pic, *next;
2969 
2970  /* We check ctx->frame to know whether ff_vaapi_encode_init()
2971  * has been called and va_config/va_context initialized. */
2972  if (!ctx->frame)
2973  return 0;
2974 
2975  for (pic = ctx->pic_start; pic; pic = next) {
2976  next = pic->next;
2977  vaapi_encode_free(avctx, pic);
2978  }
2979 
2980  ff_refstruct_pool_uninit(&ctx->output_buffer_pool);
2981 
2982  if (ctx->va_context != VA_INVALID_ID) {
2983  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2984  ctx->va_context = VA_INVALID_ID;
2985  }
2986 
2987  if (ctx->va_config != VA_INVALID_ID) {
2988  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2989  ctx->va_config = VA_INVALID_ID;
2990  }
2991 
2992  av_frame_free(&ctx->frame);
2993  av_packet_free(&ctx->tail_pkt);
2994 
2995  av_freep(&ctx->codec_sequence_params);
2996  av_freep(&ctx->codec_picture_params);
2997  av_fifo_freep2(&ctx->encode_fifo);
2998 
2999  av_buffer_unref(&ctx->recon_frames_ref);
3000  av_buffer_unref(&ctx->input_frames_ref);
3001  av_buffer_unref(&ctx->device_ref);
3002 
3003  return 0;
3004 }
RC_MODE_ICQ
@ RC_MODE_ICQ
Definition: vaapi_encode.h:170
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
VAAPIEncodeSlice::codec_slice_params
void * codec_slice_params
Definition: vaapi_encode.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
level
uint8_t level
Definition: svq3.c:204
av_clip
#define av_clip
Definition: common.h:98
vaapi_encode_init_roi
static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
Definition: vaapi_encode.c:2596
ff_refstruct_ref
void * ff_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
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
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
AVVAAPIHWConfig
VAAPI hardware pipeline configuration details.
Definition: hwcontext_vaapi.h:110
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:716
av_clip_int8
#define av_clip_int8
Definition: common.h:107
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
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:746
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
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:184
VAAPIEncodePicture::tail_size
size_t tail_size
Byte length of tail_data.
Definition: vaapi_encode.h:147
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:224
vaapi_encode_entrypoints_normal
static const VAEntrypoint vaapi_encode_entrypoints_normal[]
Definition: vaapi_encode.c:1537
av_unused
#define av_unused
Definition: attributes.h:131
FLAG_B_PICTURES
@ FLAG_B_PICTURES
Definition: vaapi_encode.h:408
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:88
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:488
vaapi_encode_init_slice_structure
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:2398
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:340
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
AVFrame::width
int width
Definition: frame.h:412
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:206
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:522
VAAPIEncodeSlice
Definition: vaapi_encode.h:64
encode.h
data
const char data[16]
Definition: mxf.c:148
VAAPIEncodePicture::force_idr
int force_idr
Definition: vaapi_encode.h:80
VAAPIEncodeSlice::block_start
int block_start
Definition: vaapi_encode.h:68
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
VAAPIEncodePicture::ref_count
int ref_count[2]
Definition: vaapi_encode.h:132
ff_vaapi_encode_close
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
Definition: vaapi_encode.c:2965
FLAG_B_PICTURE_REFERENCES
@ FLAG_B_PICTURE_REFERENCES
Definition: vaapi_encode.h:410
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:540
FFRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
vaapi_encode_init_rate_control
static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
Definition: vaapi_encode.c:1773
VAAPIEncodeSlice::index
int index
Definition: vaapi_encode.h:65
PICTURE_TYPE_IDR
@ PICTURE_TYPE_IDR
Definition: vaapi_encode.h:58
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1263
av_hwdevice_get_hwframe_constraints
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
Definition: hwcontext.c:566
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:74
VAAPIEncodeRTFormat::value
unsigned int value
Definition: vaapi_encode.c:1511
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:361
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
VAAPIEncodePicture::refs
struct VAAPIEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:125
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:441
AVFrame::opaque_ref
AVBufferRef * opaque_ref
Frame owner's private data.
Definition: frame.h:707
MAX_DPB_SIZE
@ MAX_DPB_SIZE
Definition: vaapi_encode.h:43
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:560
AVVAAPIHWConfig::config_id
VAConfigID config_id
ID of a VAAPI pipeline configuration.
Definition: hwcontext_vaapi.h:114
VAAPIEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: vaapi_encode.h:124
AVVAAPIFramesContext::surface_ids
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
Definition: hwcontext_vaapi.h:101
AV_CODEC_FLAG_COPY_OPAQUE
#define AV_CODEC_FLAG_COPY_OPAQUE
Definition: avcodec.h:299
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:454
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:558
VAAPIEncodeSlice::row_start
int row_start
Definition: vaapi_encode.h:66
vaapi_encode.h
vaapi_encode_init_gop_structure
static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:2171
vaapi_encode_make_tile_slice
static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:239
fail
#define fail()
Definition: checkasm.h:179
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
ff_refstruct_pool_uninit
static void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
VAAPIEncodePicture
Definition: vaapi_encode.h:73
AVHWFramesConstraints::min_width
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:459
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:143
vaapi_encode_pick_next
static int vaapi_encode_pick_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
Definition: vaapi_encode.c:1104
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:502
VAAPIEncodeRTFormat
Definition: vaapi_encode.c:1509
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
FLAG_TIMESTAMP_NO_DELAY
@ FLAG_TIMESTAMP_NO_DELAY
Definition: vaapi_encode.h:416
TRY_RC_MODE
#define TRY_RC_MODE(mode, fail)
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
MAX_PICTURE_REFERENCES
@ MAX_PICTURE_REFERENCES
Definition: vaapi_encode.h:44
AVRational::num
int num
Numerator.
Definition: rational.h:59
refstruct.h
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
FLAG_INTRA_ONLY
@ FLAG_INTRA_ONLY
Definition: vaapi_encode.h:406
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:76
vaapi_encode_rt_formats
static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[]
Definition: vaapi_encode.c:1518
picture_type_name
static const char *const picture_type_name[]
Definition: vaapi_encode.c:40
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:1514
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:265
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
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:1320
AVHWFramesConstraints::valid_sw_formats
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:453
VAAPIEncodeSlice::row_size
int row_size
Definition: vaapi_encode.h:67
av_hwframe_constraints_free
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:591
VAAPIEncodePicture::codec_picture_params
void * codec_picture_params
Definition: vaapi_encode.h:111
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:524
FLAG_SLICE_CONTROL
@ FLAG_SLICE_CONTROL
Definition: vaapi_encode.h:402
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1239
PICTURE_TYPE_I
@ PICTURE_TYPE_I
Definition: vaapi_encode.h:59
AVRegionOfInterest::bottom
int bottom
Definition: frame.h:281
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:215
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1406
vaapi_encode_get_coded_data
static int vaapi_encode_get_coded_data(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:774
VAAPIEncodePicture::encode_complete
int encode_complete
Definition: vaapi_encode.h:95
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:88
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
VAAPIEncodePicture::pts
int64_t pts
Definition: vaapi_encode.h:78
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_vaapi_encode_receive_packet
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: vaapi_encode.c:1396
vaapi_encode_alloc
static VAAPIEncodePicture * vaapi_encode_alloc(AVCodecContext *avctx)
Definition: vaapi_encode.c:881
vaapi_encode_set_b_pictures
static void vaapi_encode_set_b_pictures(AVCodecContext *avctx, VAAPIEncodePicture *start, VAAPIEncodePicture *end, VAAPIEncodePicture *prev, int current_depth, VAAPIEncodePicture **last)
Definition: vaapi_encode.c:1007
AVFrame::crop_right
size_t crop_right
Definition: frame.h:720
vaapi_encode_add_next_prev
static void vaapi_encode_add_next_prev(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:1071
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1292
VAAPIEncodePicture::opaque
void * opaque
Definition: vaapi_encode.h:82
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:547
frame
static AVFrame * frame
Definition: demux_decode.c:54
vaapi_encode_discard
static int vaapi_encode_discard(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:864
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:455
VAAPIEncodeContext
Definition: vaapi_encode.h:195
VAAPIEncodePicture::prev
struct VAAPIEncodePicture * prev
Definition: vaapi_encode.h:128
if
if(ret)
Definition: filter_design.txt:179
vaapi_encode_add_ref
static void vaapi_encode_add_ref(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodePicture *target, int is_ref, int in_dpb, int prev)
Definition: vaapi_encode.c:937
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1277
vaapi_encode_issue
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:266
NULL
#define NULL
Definition: coverity.c:32
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
VAAPIEncodePicture::dpb
struct VAAPIEncodePicture * dpb[MAX_DPB_SIZE]
Definition: vaapi_encode.h:120
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:495
AVRegionOfInterest::self_size
uint32_t self_size
Must be set to the size of this data structure (that is, sizeof(AVRegionOfInterest)).
Definition: frame.h:270
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
vaapi_encode_remove_refs
static void vaapi_encode_remove_refs(AVCodecContext *avctx, VAAPIEncodePicture *pic, int level)
Definition: vaapi_encode.c:971
VAAPIEncodePicture::opaque_ref
AVBufferRef * opaque_ref
Definition: vaapi_encode.h:83
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:484
VAAPIEncodePicture::duration
int64_t duration
Definition: vaapi_encode.h:79
index
int index
Definition: gxfenc.c:89
VAAPIEncodeRTFormat::name
const char * name
Definition: vaapi_encode.c:1510
VAAPIEncodePicture::encode_issued
int encode_issued
Definition: vaapi_encode.h:94
AVFrame::crop_bottom
size_t crop_bottom
Definition: frame.h:718
vaapi_encode_get_coded_buffer_size
static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID buf_id)
Definition: vaapi_encode.c:707
FLAG_CONSTANT_QUALITY_ONLY
@ FLAG_CONSTANT_QUALITY_ONLY
Definition: vaapi_encode.h:404
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:544
VAAPIEncodePicture::slices
VAAPIEncodeSlice * slices
Definition: vaapi_encode.h:136
AVFrame::crop_left
size_t crop_left
Definition: frame.h:719
VAAPIEncodePicture::input_surface
VASurfaceID input_surface
Definition: vaapi_encode.h:98
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:442
VAAPIEncodePicture::type
int type
Definition: vaapi_encode.h:92
AVPacket::size
int size
Definition: packet.h:523
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1031
vaapi_encode_init_quality
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
Definition: vaapi_encode.c:2549
RC_MODE_VBR
@ RC_MODE_VBR
Definition: vaapi_encode.h:169
MAX_GLOBAL_PARAMS
@ MAX_GLOBAL_PARAMS
Definition: vaapi_encode.h:42
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
vaapi_encode_make_misc_param_buffer
static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, const void *data, size_t len)
Definition: vaapi_encode.c:116
vaapi_encode_rc_modes
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[]
Definition: vaapi_encode.c:1752
size
int size
Definition: twinvq_data.h:10344
FFRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
VAAPIEncodeRTFormat::nb_components
int nb_components
Definition: vaapi_encode.c:1513
AVCodecHWConfigInternal
Definition: hwconfig.h:25
header
static const uint8_t header[24]
Definition: sdr2.c:68
VAAPIEncodeRTFormat::log2_chroma_h
int log2_chroma_h
Definition: vaapi_encode.c:1515
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:521
VAAPIEncodePicture::recon_surface
VASurfaceID recon_surface
Definition: vaapi_encode.h:101
vaapi_encode_free_output_buffer
static void vaapi_encode_free_output_buffer(FFRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:2629
vaapi_encode_init_packed_headers
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
Definition: vaapi_encode.c:2489
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:108
AVHWFramesConstraints::max_width
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:466
vaapi_encode_create_recon_frames
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
Definition: vaapi_encode.c:2668
VAAPIEncodePicture::priv_data
void * priv_data
Definition: vaapi_encode.h:110
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:63
AVRegionOfInterest::right
int right
Definition: frame.h:283
VAAPIEncodePicture::display_order
int64_t display_order
Definition: vaapi_encode.h:76
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
VAAPIEncodePicture::nb_dpb_pics
int nb_dpb_pics
Definition: vaapi_encode.h:119
VAAPIEncodePicture::b_depth
int b_depth
Definition: vaapi_encode.h:93
vaapi_encode_free
static int vaapi_encode_free(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:905
VAAPIEncodePicture::ref_removed
int ref_removed[2]
Definition: vaapi_encode.h:133
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:98
MAX_PARAM_BUFFER_SIZE
@ MAX_PARAM_BUFFER_SIZE
Definition: vaapi_encode.h:46
AVRegionOfInterest::left
int left
Definition: frame.h:282
PICTURE_TYPE_B
@ PICTURE_TYPE_B
Definition: vaapi_encode.h:61
FLAG_NON_IDR_KEY_PICTURES
@ FLAG_NON_IDR_KEY_PICTURES
Definition: vaapi_encode.h:413
vaapi_encode_check_frame
static int vaapi_encode_check_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: vaapi_encode.c:1294
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:515
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:523
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:280
internal.h
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
VAAPIEncodePicture::roi
void * roi
Definition: vaapi_encode.h:89
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_move_ref
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:561
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:254
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:233
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2226
AVCodecContext::height
int height
Definition: avcodec.h:618
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1475
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
VAAPIEncodePicture::tail_data
char tail_data[MAX_PARAM_BUFFER_SIZE]
Tail data of current pic, used only for repeat header of AV1.
Definition: vaapi_encode.h:145
ff_vaapi_encode_hw_configs
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]
Definition: vaapi_encode.c:35
AV_CODEC_FLAG_CLOSED_GOP
#define AV_CODEC_FLAG_CLOSED_GOP
Definition: avcodec.h:352
vaapi_encode_alloc_output_buffer
static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:2642
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2756
ret
ret
Definition: filter_design.txt:187
VAAPIEncodeRTFormat::depth
int depth
Definition: vaapi_encode.c:1512
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:1495
vaapi_encode_output
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:819
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
AVHWFramesConstraints::max_height
int max_height
Definition: hwcontext.h:467
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:104
AVCodecContext
main external API structure.
Definition: avcodec.h:445
AVFrame::height
int height
Definition: frame.h:412
AVHWFramesConstraints::min_height
int min_height
Definition: hwcontext.h:460
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:105
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1256
AVRational::den
int den
Denominator.
Definition: rational.h:60
VAAPIEncodePicture::is_reference
int is_reference
Definition: vaapi_encode.h:114
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
vaapi_encode_set_output_property
static int vaapi_encode_set_output_property(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:667
VAAPIEncodePicture::recon_image
AVFrame * recon_image
Definition: vaapi_encode.h:100
ff_refstruct_pool_alloc_ext
static FFRefStructPool * ff_refstruct_pool_alloc_ext(size_t size, unsigned flags, void *opaque, int(*init_cb)(FFRefStructOpaque opaque, void *obj), void(*reset_cb)(FFRefStructOpaque opaque, void *obj), void(*free_entry_cb)(FFRefStructOpaque opaque, void *obj), void(*free_cb)(FFRefStructOpaque opaque))
A wrapper around ff_refstruct_pool_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:258
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1639
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:76
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:2337
VAAPIEncodePicture::output_buffer_ref
VABufferID * output_buffer_ref
Definition: vaapi_encode.h:107
VAAPIEncodePicture::next
struct VAAPIEncodePicture * next
Definition: vaapi_encode.h:74
desc
const char * desc
Definition: libsvtav1.c:73
AVCodecContext::max_b_frames
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:795
ff_encode_get_frame
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition: encode.c:204
VAAPIEncodePicture::input_image
AVFrame * input_image
Definition: vaapi_encode.h:97
VAAPIEncodeSlice::block_size
int block_size
Definition: vaapi_encode.h:69
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:246
VAAPIEncodeRCMode
Definition: vaapi_encode.h:176
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
RC_MODE_AVBR
@ RC_MODE_AVBR
Definition: vaapi_encode.h:172
vaapi_encode_send_frame
static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: vaapi_encode.c:1320
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
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:738
vaapi_encode_profile_entrypoint
static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
Definition: vaapi_encode.c:1552
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1047
AVPacket
This structure stores compressed data.
Definition: packet.h:499
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
VAAPIEncodePicture::encode_order
int64_t encode_order
Definition: vaapi_encode.h:77
RC_MODE_CQP
@ RC_MODE_CQP
Definition: vaapi_encode.h:167
AVFrame::crop_top
size_t crop_top
Definition: frame.h:717
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
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:2114
RC_MODE_CBR
@ RC_MODE_CBR
Definition: vaapi_encode.h:168
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
VAAPIEncodePicture::nb_param_buffers
int nb_param_buffers
Definition: vaapi_encode.h:103
vaapi_encode_clear_old
static int vaapi_encode_clear_old(AVCodecContext *avctx)
Definition: vaapi_encode.c:1256
RC_MODE_QVBR
@ RC_MODE_QVBR
Definition: vaapi_encode.h:171
rc_mode
mfxU16 rc_mode
Definition: qsvenc.c:141
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:42
vaapi_encode_wait
static int vaapi_encode_wait(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:139
int
int
Definition: ffmpeg_filter.c:425
PICTURE_TYPE_P
@ PICTURE_TYPE_P
Definition: vaapi_encode.h:60
av_hwframe_get_buffer
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:491
AVRegionOfInterest::qoffset
AVRational qoffset
Quantisation offset.
Definition: frame.h:307
snprintf
#define snprintf
Definition: snprintf.h:34
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
vaapi_encode_init_row_slice_structure
static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx, uint32_t slice_structure)
Definition: vaapi_encode.c:2292
VAAPIEncodeProfile
Definition: vaapi_encode.h:150
ff_refstruct_pool_get
void * ff_refstruct_pool_get(FFRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2882
AVCodecContext::compression_level
int compression_level
Definition: avcodec.h:1245
VAAPIEncodePicture::nb_slices
int nb_slices
Definition: vaapi_encode.h:135