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) {
1809 #if VA_CHECK_VERSION(0, 39, 2)
1810  if (!(supported_va_rc_modes & VA_RC_MB)) {
1811  ctx->blbrc = 0;
1812  av_log(avctx, AV_LOG_WARNING, "Driver does not support BLBRC.\n");
1813  }
1814 #else
1815  ctx->blbrc = 0;
1816  av_log(avctx, AV_LOG_WARNING, "Please consider to update to VAAPI 0.39.2 "
1817  "or above, which can support BLBRC.\n");
1818 #endif
1819  }
1820 
1821  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1823  if (supported_va_rc_modes & rc_mode->va_mode) {
1824  res = snprintf(str, len, "%s%s",
1825  first ? "" : ", ", rc_mode->name);
1826  first = 0;
1827  if (res < 0) {
1828  *str = 0;
1829  break;
1830  }
1831  len -= res;
1832  str += res;
1833  if (len == 0)
1834  break;
1835  }
1836  }
1837 
1838  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1839  supported_rc_modes_string);
1840  }
1841 
1842  // Rate control mode selection:
1843  // * If the user has set a mode explicitly with the rc_mode option,
1844  // use it and fail if it is not available.
1845  // * If an explicit QP option has been set, use CQP.
1846  // * If the codec is CQ-only, use CQP.
1847  // * If the QSCALE avcodec option is set, use CQP.
1848  // * If bitrate and quality are both set, try QVBR.
1849  // * If quality is set, try ICQ, then CQP.
1850  // * If bitrate and maxrate are set and have the same value, try CBR.
1851  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1852  // * If no bitrate is set, try ICQ, then CQP.
1853 
1854 #define TRY_RC_MODE(mode, fail) do { \
1855  rc_mode = &vaapi_encode_rc_modes[mode]; \
1856  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1857  if (fail) { \
1858  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1859  "RC mode (supported modes: %s).\n", rc_mode->name, \
1860  supported_rc_modes_string); \
1861  return AVERROR(EINVAL); \
1862  } \
1863  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1864  "RC mode.\n", rc_mode->name); \
1865  rc_mode = NULL; \
1866  } else { \
1867  goto rc_mode_found; \
1868  } \
1869  } while (0)
1870 
1871  if (ctx->explicit_rc_mode)
1872  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1873 
1874  if (ctx->explicit_qp)
1876 
1877  if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY)
1879 
1880  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1882 
1883  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1885 
1886  if (avctx->global_quality > 0) {
1889  }
1890 
1891  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1893 
1894  if (avctx->bit_rate > 0) {
1898  } else {
1901  }
1902 
1903  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1904  "RC mode compatible with selected options "
1905  "(supported modes: %s).\n", supported_rc_modes_string);
1906  return AVERROR(EINVAL);
1907 
1908 rc_mode_found:
1909  if (rc_mode->bitrate) {
1910  if (avctx->bit_rate <= 0) {
1911  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1912  "RC mode.\n", rc_mode->name);
1913  return AVERROR(EINVAL);
1914  }
1915 
1916  if (rc_mode->mode == RC_MODE_AVBR) {
1917  // For maximum confusion AVBR is hacked into the existing API
1918  // by overloading some of the fields with completely different
1919  // meanings.
1920 
1921  // Target percentage does not apply in AVBR mode.
1922  rc_bits_per_second = avctx->bit_rate;
1923 
1924  // Accuracy tolerance range for meeting the specified target
1925  // bitrate. It's very unclear how this is actually intended
1926  // to work - since we do want to get the specified bitrate,
1927  // set the accuracy to 100% for now.
1928  rc_target_percentage = 100;
1929 
1930  // Convergence period in frames. The GOP size reflects the
1931  // user's intended block size for cutting, so reusing that
1932  // as the convergence period seems a reasonable default.
1933  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1934 
1935  } else if (rc_mode->maxrate) {
1936  if (avctx->rc_max_rate > 0) {
1937  if (avctx->rc_max_rate < avctx->bit_rate) {
1938  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1939  "bitrate (%"PRId64") must not be greater than "
1940  "maxrate (%"PRId64").\n", avctx->bit_rate,
1941  avctx->rc_max_rate);
1942  return AVERROR(EINVAL);
1943  }
1944  rc_bits_per_second = avctx->rc_max_rate;
1945  rc_target_percentage = (avctx->bit_rate * 100) /
1946  avctx->rc_max_rate;
1947  } else {
1948  // We only have a target bitrate, but this mode requires
1949  // that a maximum rate be supplied as well. Since the
1950  // user does not want this to be a constraint, arbitrarily
1951  // pick a maximum rate of double the target rate.
1952  rc_bits_per_second = 2 * avctx->bit_rate;
1953  rc_target_percentage = 50;
1954  }
1955  } else {
1956  if (avctx->rc_max_rate > avctx->bit_rate) {
1957  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1958  "in %s RC mode.\n", rc_mode->name);
1959  }
1960  rc_bits_per_second = avctx->bit_rate;
1961  rc_target_percentage = 100;
1962  }
1963  } else {
1964  rc_bits_per_second = 0;
1965  rc_target_percentage = 100;
1966  }
1967 
1968  if (rc_mode->quality) {
1969  if (ctx->explicit_qp) {
1970  rc_quality = ctx->explicit_qp;
1971  } else if (avctx->global_quality > 0) {
1972  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1973  rc_quality = avctx->global_quality / FF_QP2LAMBDA;
1974  else
1975  rc_quality = avctx->global_quality;
1976  } else {
1977  rc_quality = ctx->codec->default_quality;
1978  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1979  "using default (%d).\n", rc_quality);
1980  }
1981  } else {
1982  rc_quality = 0;
1983  }
1984 
1985  if (rc_mode->hrd) {
1986  if (avctx->rc_buffer_size)
1987  hrd_buffer_size = avctx->rc_buffer_size;
1988  else if (avctx->rc_max_rate > 0)
1989  hrd_buffer_size = avctx->rc_max_rate;
1990  else
1991  hrd_buffer_size = avctx->bit_rate;
1992  if (avctx->rc_initial_buffer_occupancy) {
1993  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1994  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1995  "must have initial buffer size (%d) <= "
1996  "buffer size (%"PRId64").\n",
1997  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1998  return AVERROR(EINVAL);
1999  }
2000  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
2001  } else {
2002  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
2003  }
2004 
2005  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
2006  } else {
2007  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
2008  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
2009  "in %s RC mode.\n", rc_mode->name);
2010  }
2011 
2012  hrd_buffer_size = 0;
2013  hrd_initial_buffer_fullness = 0;
2014 
2015  if (rc_mode->mode != RC_MODE_AVBR) {
2016  // Already set (with completely different meaning) for AVBR.
2017  rc_window_size = 1000;
2018  }
2019  }
2020 
2021  if (rc_bits_per_second > UINT32_MAX ||
2022  hrd_buffer_size > UINT32_MAX ||
2023  hrd_initial_buffer_fullness > UINT32_MAX) {
2024  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
2025  "greater are not supported by VAAPI.\n");
2026  return AVERROR(EINVAL);
2027  }
2028 
2029  ctx->rc_mode = rc_mode;
2030  ctx->rc_quality = rc_quality;
2031  ctx->va_rc_mode = rc_mode->va_mode;
2032  ctx->va_bit_rate = rc_bits_per_second;
2033 
2034  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
2035 
2036  if (ctx->blbrc && ctx->va_rc_mode == VA_RC_CQP)
2037  ctx->blbrc = 0;
2038  av_log(avctx, AV_LOG_VERBOSE, "Block Level bitrate control: %s.\n", ctx->blbrc ? "ON" : "OFF");
2039 
2040  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2041  // This driver does not want the RC mode attribute to be set.
2042  } else {
2043  ctx->config_attributes[ctx->nb_config_attributes++] =
2044  (VAConfigAttrib) {
2045  .type = VAConfigAttribRateControl,
2046 #if VA_CHECK_VERSION(0, 39, 2)
2047  .value = ctx->blbrc ? ctx->va_rc_mode | VA_RC_MB : ctx->va_rc_mode,
2048 #else
2049  .value = ctx->va_rc_mode,
2050 #endif
2051  };
2052  }
2053 
2054  if (rc_mode->quality)
2055  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
2056 
2057  if (rc_mode->va_mode != VA_RC_CQP) {
2058  if (rc_mode->mode == RC_MODE_AVBR) {
2059  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
2060  "converging in %d frames with %d%% accuracy.\n",
2061  rc_bits_per_second, rc_window_size,
2062  rc_target_percentage);
2063  } else if (rc_mode->bitrate) {
2064  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
2065  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
2066  rc_bits_per_second, rc_window_size);
2067  }
2068 
2069  ctx->rc_params = (VAEncMiscParameterRateControl) {
2070  .bits_per_second = rc_bits_per_second,
2071  .target_percentage = rc_target_percentage,
2072  .window_size = rc_window_size,
2073  .initial_qp = 0,
2074  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
2075  .basic_unit_size = 0,
2076 #if VA_CHECK_VERSION(1, 1, 0)
2077  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
2078  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
2079 #endif
2080 #if VA_CHECK_VERSION(1, 3, 0)
2081  .quality_factor = rc_quality,
2082 #endif
2083 #if VA_CHECK_VERSION(0, 39, 2)
2084  .rc_flags.bits.mb_rate_control = ctx->blbrc ? 1 : 2,
2085 #endif
2086  };
2088  VAEncMiscParameterTypeRateControl,
2089  &ctx->rc_params,
2090  sizeof(ctx->rc_params));
2091  }
2092 
2093  if (rc_mode->hrd) {
2094  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
2095  "initial fullness %"PRId64" bits.\n",
2096  hrd_buffer_size, hrd_initial_buffer_fullness);
2097 
2098  ctx->hrd_params = (VAEncMiscParameterHRD) {
2099  .initial_buffer_fullness = hrd_initial_buffer_fullness,
2100  .buffer_size = hrd_buffer_size,
2101  };
2103  VAEncMiscParameterTypeHRD,
2104  &ctx->hrd_params,
2105  sizeof(ctx->hrd_params));
2106  }
2107 
2108  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
2109  av_reduce(&fr_num, &fr_den,
2110  avctx->framerate.num, avctx->framerate.den, 65535);
2111  else
2112  av_reduce(&fr_num, &fr_den,
2113  avctx->time_base.den, avctx->time_base.num, 65535);
2114 
2115  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
2116  fr_num, fr_den, (double)fr_num / fr_den);
2117 
2118  ctx->fr_params = (VAEncMiscParameterFrameRate) {
2119  .framerate = (unsigned int)fr_den << 16 | fr_num,
2120  };
2121 #if VA_CHECK_VERSION(0, 40, 0)
2123  VAEncMiscParameterTypeFrameRate,
2124  &ctx->fr_params,
2125  sizeof(ctx->fr_params));
2126 #endif
2127 
2128  return 0;
2129 }
2130 
2132 {
2133 #if VA_CHECK_VERSION(1, 5, 0)
2134  VAAPIEncodeContext *ctx = avctx->priv_data;
2135  VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
2136  VAStatus vas;
2137 
2138  if (ctx->va_rc_mode == VA_RC_CQP) {
2139  ctx->max_frame_size = 0;
2140  av_log(avctx, AV_LOG_ERROR, "Max frame size is invalid in CQP rate "
2141  "control mode.\n");
2142  return AVERROR(EINVAL);
2143  }
2144 
2145  vas = vaGetConfigAttributes(ctx->hwctx->display,
2146  ctx->va_profile,
2147  ctx->va_entrypoint,
2148  &attr, 1);
2149  if (vas != VA_STATUS_SUCCESS) {
2150  ctx->max_frame_size = 0;
2151  av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
2152  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2153  return AVERROR_EXTERNAL;
2154  }
2155 
2156  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2157  ctx->max_frame_size = 0;
2158  av_log(avctx, AV_LOG_ERROR, "Max frame size attribute "
2159  "is not supported.\n");
2160  return AVERROR(EINVAL);
2161  } else {
2162  VAConfigAttribValMaxFrameSize attr_mfs;
2163  attr_mfs.value = attr.value;
2164  // Prefer to use VAEncMiscParameterTypeMaxFrameSize for max frame size.
2165  if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
2166  ctx->max_frame_size = 0;
2167  av_log(avctx, AV_LOG_ERROR, "Driver only supports multiple pass "
2168  "max frame size which has not been implemented in FFmpeg.\n");
2169  return AVERROR(EINVAL);
2170  }
2171 
2172  ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
2173  .max_frame_size = ctx->max_frame_size * 8,
2174  };
2175 
2176  av_log(avctx, AV_LOG_VERBOSE, "Set max frame size: %d bytes.\n",
2177  ctx->max_frame_size);
2178  }
2179 #else
2180  av_log(avctx, AV_LOG_ERROR, "The max frame size option is not supported with "
2181  "this VAAPI version.\n");
2182  return AVERROR(EINVAL);
2183 #endif
2184 
2185  return 0;
2186 }
2187 
2189 {
2190  VAAPIEncodeContext *ctx = avctx->priv_data;
2191  VAStatus vas;
2192  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
2193  uint32_t ref_l0, ref_l1;
2194  int prediction_pre_only;
2195 
2196  vas = vaGetConfigAttributes(ctx->hwctx->display,
2197  ctx->va_profile,
2198  ctx->va_entrypoint,
2199  &attr, 1);
2200  if (vas != VA_STATUS_SUCCESS) {
2201  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
2202  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2203  return AVERROR_EXTERNAL;
2204  }
2205 
2206  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2207  ref_l0 = ref_l1 = 0;
2208  } else {
2209  ref_l0 = attr.value & 0xffff;
2210  ref_l1 = attr.value >> 16 & 0xffff;
2211  }
2212 
2213  ctx->p_to_gpb = 0;
2214  prediction_pre_only = 0;
2215 
2216 #if VA_CHECK_VERSION(1, 9, 0)
2217  if (!(ctx->codec->flags & FLAG_INTRA_ONLY ||
2218  avctx->gop_size <= 1)) {
2219  attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
2220  vas = vaGetConfigAttributes(ctx->hwctx->display,
2221  ctx->va_profile,
2222  ctx->va_entrypoint,
2223  &attr, 1);
2224  if (vas != VA_STATUS_SUCCESS) {
2225  av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
2226  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2227  return AVERROR_EXTERNAL;
2228  } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2229  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
2230  "prediction constraints.\n");
2231  } else {
2232  if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
2233  ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
2234  av_log(avctx, AV_LOG_ERROR, "Driver report incorrect prediction "
2235  "direction attribute.\n");
2236  return AVERROR_EXTERNAL;
2237  }
2238 
2239  if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
2240  if (ref_l0 > 0 && ref_l1 > 0) {
2241  prediction_pre_only = 1;
2242  av_log(avctx, AV_LOG_VERBOSE, "Driver only support same reference "
2243  "lists for B-frames.\n");
2244  }
2245  }
2246 
2247  if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
2248  if (ref_l0 > 0 && ref_l1 > 0) {
2249  ctx->p_to_gpb = 1;
2250  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
2251  "replacing them with B-frames.\n");
2252  }
2253  }
2254  }
2255  }
2256 #endif
2257 
2258  if (ctx->codec->flags & FLAG_INTRA_ONLY ||
2259  avctx->gop_size <= 1) {
2260  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
2261  ctx->gop_size = 1;
2262  } else if (ref_l0 < 1) {
2263  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
2264  "reference frames.\n");
2265  return AVERROR(EINVAL);
2266  } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
2267  ref_l1 < 1 || avctx->max_b_frames < 1 ||
2268  prediction_pre_only) {
2269  if (ctx->p_to_gpb)
2270  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2271  "(supported references: %d / %d).\n",
2272  ref_l0, ref_l1);
2273  else
2274  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
2275  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2276  ctx->gop_size = avctx->gop_size;
2277  ctx->p_per_i = INT_MAX;
2278  ctx->b_per_p = 0;
2279  } else {
2280  if (ctx->p_to_gpb)
2281  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2282  "(supported references: %d / %d).\n",
2283  ref_l0, ref_l1);
2284  else
2285  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
2286  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2287  ctx->gop_size = avctx->gop_size;
2288  ctx->p_per_i = INT_MAX;
2289  ctx->b_per_p = avctx->max_b_frames;
2290  if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
2291  ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
2292  av_log2(ctx->b_per_p) + 1);
2293  } else {
2294  ctx->max_b_depth = 1;
2295  }
2296  }
2297 
2298  if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
2299  ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
2300  ctx->gop_per_idr = ctx->idr_interval + 1;
2301  } else {
2302  ctx->closed_gop = 1;
2303  ctx->gop_per_idr = 1;
2304  }
2305 
2306  return 0;
2307 }
2308 
2310  uint32_t slice_structure)
2311 {
2312  VAAPIEncodeContext *ctx = avctx->priv_data;
2313  int req_slices;
2314 
2315  // For fixed-size slices currently we only support whole rows, making
2316  // rectangular slices. This could be extended to arbitrary runs of
2317  // blocks, but since slices tend to be a conformance requirement and
2318  // most cases (such as broadcast or bluray) want rectangular slices
2319  // only it would need to be gated behind another option.
2320  if (avctx->slices > ctx->slice_block_rows) {
2321  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
2322  "configured number of slices (%d < %d); using "
2323  "maximum.\n", ctx->slice_block_rows, avctx->slices);
2324  req_slices = ctx->slice_block_rows;
2325  } else {
2326  req_slices = avctx->slices;
2327  }
2328  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
2329  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
2330  ctx->nb_slices = req_slices;
2331  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
2332  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
2333  int k;
2334  for (k = 1;; k *= 2) {
2335  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
2336  break;
2337  }
2338  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
2339  ctx->slice_size = k;
2340 #if VA_CHECK_VERSION(1, 0, 0)
2341  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
2342  ctx->nb_slices = ctx->slice_block_rows;
2343  ctx->slice_size = 1;
2344 #endif
2345  } else {
2346  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
2347  "slice structure modes (%#x).\n", slice_structure);
2348  return AVERROR(EINVAL);
2349  }
2350 
2351  return 0;
2352 }
2353 
2355  uint32_t slice_structure)
2356 {
2357  VAAPIEncodeContext *ctx = avctx->priv_data;
2358  int i, req_tiles;
2359 
2360  if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
2361  (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
2362  ctx->tile_cols == 1))) {
2363  av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
2364  "current tile requirement.\n", slice_structure);
2365  return AVERROR(EINVAL);
2366  }
2367 
2368  if (ctx->tile_rows > ctx->slice_block_rows ||
2369  ctx->tile_cols > ctx->slice_block_cols) {
2370  av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
2371  "for configured number of tile (%d x %d); ",
2372  ctx->slice_block_rows, ctx->slice_block_cols,
2373  ctx->tile_rows, ctx->tile_cols);
2374  ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
2375  ctx->slice_block_rows : ctx->tile_rows;
2376  ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
2377  ctx->slice_block_cols : ctx->tile_cols;
2378  av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
2379  ctx->tile_rows, ctx->tile_cols);
2380  }
2381 
2382  req_tiles = ctx->tile_rows * ctx->tile_cols;
2383 
2384  // Tile slice is not allowed to cross the boundary of a tile due to
2385  // the constraints of media-driver. Currently we support one slice
2386  // per tile. This could be extended to multiple slices per tile.
2387  if (avctx->slices != req_tiles)
2388  av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
2389  "mismatches with configured number of tile (%d != %d); "
2390  "using requested tile number for slice.\n",
2391  avctx->slices, req_tiles);
2392 
2393  ctx->nb_slices = req_tiles;
2394 
2395  // Default in uniform spacing
2396  // 6-3, 6-5
2397  for (i = 0; i < ctx->tile_cols; i++) {
2398  ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
2399  i * ctx->slice_block_cols / ctx->tile_cols;
2400  ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
2401  }
2402  // 6-4, 6-6
2403  for (i = 0; i < ctx->tile_rows; i++) {
2404  ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
2405  i * ctx->slice_block_rows / ctx->tile_rows;
2406  ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
2407  }
2408 
2409  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
2410  ctx->tile_rows, ctx->tile_cols);
2411 
2412  return 0;
2413 }
2414 
2416 {
2417  VAAPIEncodeContext *ctx = avctx->priv_data;
2418  VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
2419  { VAConfigAttribEncSliceStructure },
2420 #if VA_CHECK_VERSION(1, 1, 0)
2421  { VAConfigAttribEncTileSupport },
2422 #endif
2423  };
2424  VAStatus vas;
2425  uint32_t max_slices, slice_structure;
2426  int ret;
2427 
2428  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
2429  if (avctx->slices > 0) {
2430  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
2431  "but this codec does not support controlling slices.\n");
2432  }
2433  return 0;
2434  }
2435 
2436  av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0);
2437 
2438  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
2439  ctx->slice_block_height;
2440  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
2441  ctx->slice_block_width;
2442 
2443  if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
2444  ctx->nb_slices = 1;
2445  ctx->slice_size = ctx->slice_block_rows;
2446  return 0;
2447  }
2448 
2449  vas = vaGetConfigAttributes(ctx->hwctx->display,
2450  ctx->va_profile,
2451  ctx->va_entrypoint,
2452  attr, FF_ARRAY_ELEMS(attr));
2453  if (vas != VA_STATUS_SUCCESS) {
2454  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
2455  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
2456  return AVERROR_EXTERNAL;
2457  }
2458  max_slices = attr[0].value;
2459  slice_structure = attr[1].value;
2460  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
2461  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
2462  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2463  "pictures as multiple slices.\n.");
2464  return AVERROR(EINVAL);
2465  }
2466 
2467  if (ctx->tile_rows && ctx->tile_cols) {
2468 #if VA_CHECK_VERSION(1, 1, 0)
2469  uint32_t tile_support = attr[2].value;
2470  if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
2471  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2472  "pictures as multiple tiles.\n.");
2473  return AVERROR(EINVAL);
2474  }
2475 #else
2476  av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
2477  "not supported with this VAAPI version.\n");
2478  return AVERROR(EINVAL);
2479 #endif
2480  }
2481 
2482  if (ctx->tile_rows && ctx->tile_cols)
2483  ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
2484  else
2485  ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
2486  if (ret < 0)
2487  return ret;
2488 
2489  if (ctx->nb_slices > avctx->slices) {
2490  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
2491  "%d (from %d) due to driver constraints on slice "
2492  "structure.\n", ctx->nb_slices, avctx->slices);
2493  }
2494  if (ctx->nb_slices > max_slices) {
2495  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
2496  "encoding with %d slices (max %"PRIu32").\n",
2497  ctx->nb_slices, max_slices);
2498  return AVERROR(EINVAL);
2499  }
2500 
2501  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
2502  ctx->nb_slices);
2503  return 0;
2504 }
2505 
2507 {
2508  VAAPIEncodeContext *ctx = avctx->priv_data;
2509  VAStatus vas;
2510  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
2511 
2512  vas = vaGetConfigAttributes(ctx->hwctx->display,
2513  ctx->va_profile,
2514  ctx->va_entrypoint,
2515  &attr, 1);
2516  if (vas != VA_STATUS_SUCCESS) {
2517  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
2518  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2519  return AVERROR_EXTERNAL;
2520  }
2521 
2522  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2523  if (ctx->desired_packed_headers) {
2524  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
2525  "packed headers (wanted %#x).\n",
2526  ctx->desired_packed_headers);
2527  } else {
2528  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
2529  "packed headers (none wanted).\n");
2530  }
2531  ctx->va_packed_headers = 0;
2532  } else {
2533  if (ctx->desired_packed_headers & ~attr.value) {
2534  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
2535  "wanted packed headers (wanted %#x, found %#x).\n",
2536  ctx->desired_packed_headers, attr.value);
2537  } else {
2538  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
2539  "available (wanted %#x, found %#x).\n",
2540  ctx->desired_packed_headers, attr.value);
2541  }
2542  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
2543  }
2544 
2545  if (ctx->va_packed_headers) {
2546  ctx->config_attributes[ctx->nb_config_attributes++] =
2547  (VAConfigAttrib) {
2548  .type = VAConfigAttribEncPackedHeaders,
2549  .value = ctx->va_packed_headers,
2550  };
2551  }
2552 
2553  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2554  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2555  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
2556  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
2557  "sequence headers, but a global header is requested.\n");
2558  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
2559  "this may result in a stream which is not usable for some "
2560  "purposes (e.g. not muxable to some containers).\n");
2561  }
2562 
2563  return 0;
2564 }
2565 
2567 {
2568 #if VA_CHECK_VERSION(0, 36, 0)
2569  VAAPIEncodeContext *ctx = avctx->priv_data;
2570  VAStatus vas;
2571  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
2572  int quality = avctx->compression_level;
2573 
2574  vas = vaGetConfigAttributes(ctx->hwctx->display,
2575  ctx->va_profile,
2576  ctx->va_entrypoint,
2577  &attr, 1);
2578  if (vas != VA_STATUS_SUCCESS) {
2579  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
2580  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2581  return AVERROR_EXTERNAL;
2582  }
2583 
2584  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2585  if (quality != 0) {
2586  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
2587  "supported: will use default quality level.\n");
2588  }
2589  } else {
2590  if (quality > attr.value) {
2591  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
2592  "valid range is 0-%d, using %d.\n",
2593  attr.value, attr.value);
2594  quality = attr.value;
2595  }
2596 
2597  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2598  .quality_level = quality,
2599  };
2601  VAEncMiscParameterTypeQualityLevel,
2602  &ctx->quality_params,
2603  sizeof(ctx->quality_params));
2604  }
2605 #else
2606  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
2607  "not supported with this VAAPI version.\n");
2608 #endif
2609 
2610  return 0;
2611 }
2612 
2614 {
2615 #if VA_CHECK_VERSION(1, 0, 0)
2616  VAAPIEncodeContext *ctx = avctx->priv_data;
2617  VAStatus vas;
2618  VAConfigAttrib attr = { VAConfigAttribEncROI };
2619 
2620  vas = vaGetConfigAttributes(ctx->hwctx->display,
2621  ctx->va_profile,
2622  ctx->va_entrypoint,
2623  &attr, 1);
2624  if (vas != VA_STATUS_SUCCESS) {
2625  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
2626  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2627  return AVERROR_EXTERNAL;
2628  }
2629 
2630  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2631  ctx->roi_allowed = 0;
2632  } else {
2633  VAConfigAttribValEncROI roi = {
2634  .value = attr.value,
2635  };
2636 
2637  ctx->roi_max_regions = roi.bits.num_roi_regions;
2638  ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2639  (ctx->va_rc_mode == VA_RC_CQP ||
2640  roi.bits.roi_rc_qp_delta_support);
2641  }
2642 #endif
2643  return 0;
2644 }
2645 
2647  void *obj)
2648 {
2649  AVCodecContext *avctx = opaque.nc;
2650  VAAPIEncodeContext *ctx = avctx->priv_data;
2651  VABufferID *buffer_id_ref = obj;
2652  VABufferID buffer_id = *buffer_id_ref;
2653 
2654  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2655 
2656  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2657 }
2658 
2660 {
2661  AVCodecContext *avctx = opaque.nc;
2662  VAAPIEncodeContext *ctx = avctx->priv_data;
2663  VABufferID *buffer_id = obj;
2664  VAStatus vas;
2665 
2666  // The output buffer size is fixed, so it needs to be large enough
2667  // to hold the largest possible compressed frame. We assume here
2668  // that the uncompressed frame plus some header data is an upper
2669  // bound on that.
2670  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2671  VAEncCodedBufferType,
2672  3 * ctx->surface_width * ctx->surface_height +
2673  (1 << 16), 1, 0, buffer_id);
2674  if (vas != VA_STATUS_SUCCESS) {
2675  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2676  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2677  return AVERROR(ENOMEM);
2678  }
2679 
2680  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", *buffer_id);
2681 
2682  return 0;
2683 }
2684 
2686 {
2687  VAAPIEncodeContext *ctx = avctx->priv_data;
2688  AVVAAPIHWConfig *hwconfig = NULL;
2689  AVHWFramesConstraints *constraints = NULL;
2690  enum AVPixelFormat recon_format;
2691  int err, i;
2692 
2693  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
2694  if (!hwconfig) {
2695  err = AVERROR(ENOMEM);
2696  goto fail;
2697  }
2698  hwconfig->config_id = ctx->va_config;
2699 
2700  constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
2701  hwconfig);
2702  if (!constraints) {
2703  err = AVERROR(ENOMEM);
2704  goto fail;
2705  }
2706 
2707  // Probably we can use the input surface format as the surface format
2708  // of the reconstructed frames. If not, we just pick the first (only?)
2709  // format in the valid list and hope that it all works.
2710  recon_format = AV_PIX_FMT_NONE;
2711  if (constraints->valid_sw_formats) {
2712  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
2713  if (ctx->input_frames->sw_format ==
2714  constraints->valid_sw_formats[i]) {
2715  recon_format = ctx->input_frames->sw_format;
2716  break;
2717  }
2718  }
2719  if (recon_format == AV_PIX_FMT_NONE) {
2720  // No match. Just use the first in the supported list and
2721  // hope for the best.
2722  recon_format = constraints->valid_sw_formats[0];
2723  }
2724  } else {
2725  // No idea what to use; copy input format.
2726  recon_format = ctx->input_frames->sw_format;
2727  }
2728  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
2729  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
2730 
2731  if (ctx->surface_width < constraints->min_width ||
2732  ctx->surface_height < constraints->min_height ||
2733  ctx->surface_width > constraints->max_width ||
2734  ctx->surface_height > constraints->max_height) {
2735  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
2736  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2737  ctx->surface_width, ctx->surface_height,
2738  constraints->min_width, constraints->max_width,
2739  constraints->min_height, constraints->max_height);
2740  err = AVERROR(EINVAL);
2741  goto fail;
2742  }
2743 
2744  av_freep(&hwconfig);
2745  av_hwframe_constraints_free(&constraints);
2746 
2747  ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
2748  if (!ctx->recon_frames_ref) {
2749  err = AVERROR(ENOMEM);
2750  goto fail;
2751  }
2752  ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
2753 
2754  ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
2755  ctx->recon_frames->sw_format = recon_format;
2756  ctx->recon_frames->width = ctx->surface_width;
2757  ctx->recon_frames->height = ctx->surface_height;
2758 
2759  err = av_hwframe_ctx_init(ctx->recon_frames_ref);
2760  if (err < 0) {
2761  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2762  "frame context: %d.\n", err);
2763  goto fail;
2764  }
2765 
2766  err = 0;
2767  fail:
2768  av_freep(&hwconfig);
2769  av_hwframe_constraints_free(&constraints);
2770  return err;
2771 }
2772 
2774 {
2775  VAAPIEncodeContext *ctx = avctx->priv_data;
2776  AVVAAPIFramesContext *recon_hwctx = NULL;
2777  VAStatus vas;
2778  int err;
2779 
2780  ctx->va_config = VA_INVALID_ID;
2781  ctx->va_context = VA_INVALID_ID;
2782 
2783  /* If you add something that can fail above this av_frame_alloc(),
2784  * modify ff_vaapi_encode_close() accordingly. */
2785  ctx->frame = av_frame_alloc();
2786  if (!ctx->frame) {
2787  return AVERROR(ENOMEM);
2788  }
2789 
2790  if (!avctx->hw_frames_ctx) {
2791  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
2792  "required to associate the encoding device.\n");
2793  return AVERROR(EINVAL);
2794  }
2795 
2796  ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
2797  if (!ctx->input_frames_ref) {
2798  err = AVERROR(ENOMEM);
2799  goto fail;
2800  }
2801  ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
2802 
2803  ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
2804  if (!ctx->device_ref) {
2805  err = AVERROR(ENOMEM);
2806  goto fail;
2807  }
2808  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
2809  ctx->hwctx = ctx->device->hwctx;
2810 
2811  ctx->tail_pkt = av_packet_alloc();
2812  if (!ctx->tail_pkt) {
2813  err = AVERROR(ENOMEM);
2814  goto fail;
2815  }
2816 
2817  err = vaapi_encode_profile_entrypoint(avctx);
2818  if (err < 0)
2819  goto fail;
2820 
2821  if (ctx->codec->get_encoder_caps) {
2822  err = ctx->codec->get_encoder_caps(avctx);
2823  if (err < 0)
2824  goto fail;
2825  } else {
2826  // Assume 16x16 blocks.
2827  ctx->surface_width = FFALIGN(avctx->width, 16);
2828  ctx->surface_height = FFALIGN(avctx->height, 16);
2829  if (ctx->codec->flags & FLAG_SLICE_CONTROL) {
2830  ctx->slice_block_width = 16;
2831  ctx->slice_block_height = 16;
2832  }
2833  }
2834 
2835  err = vaapi_encode_init_rate_control(avctx);
2836  if (err < 0)
2837  goto fail;
2838 
2839  err = vaapi_encode_init_gop_structure(avctx);
2840  if (err < 0)
2841  goto fail;
2842 
2843  err = vaapi_encode_init_slice_structure(avctx);
2844  if (err < 0)
2845  goto fail;
2846 
2847  err = vaapi_encode_init_packed_headers(avctx);
2848  if (err < 0)
2849  goto fail;
2850 
2851  err = vaapi_encode_init_roi(avctx);
2852  if (err < 0)
2853  goto fail;
2854 
2855  if (avctx->compression_level >= 0) {
2856  err = vaapi_encode_init_quality(avctx);
2857  if (err < 0)
2858  goto fail;
2859  }
2860 
2861  if (ctx->max_frame_size) {
2862  err = vaapi_encode_init_max_frame_size(avctx);
2863  if (err < 0)
2864  goto fail;
2865  }
2866 
2867  vas = vaCreateConfig(ctx->hwctx->display,
2868  ctx->va_profile, ctx->va_entrypoint,
2869  ctx->config_attributes, ctx->nb_config_attributes,
2870  &ctx->va_config);
2871  if (vas != VA_STATUS_SUCCESS) {
2872  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2873  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2874  err = AVERROR(EIO);
2875  goto fail;
2876  }
2877 
2878  err = vaapi_encode_create_recon_frames(avctx);
2879  if (err < 0)
2880  goto fail;
2881 
2882  recon_hwctx = ctx->recon_frames->hwctx;
2883  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2884  ctx->surface_width, ctx->surface_height,
2885  VA_PROGRESSIVE,
2886  recon_hwctx->surface_ids,
2887  recon_hwctx->nb_surfaces,
2888  &ctx->va_context);
2889  if (vas != VA_STATUS_SUCCESS) {
2890  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2891  "context: %d (%s).\n", vas, vaErrorStr(vas));
2892  err = AVERROR(EIO);
2893  goto fail;
2894  }
2895 
2896  ctx->output_buffer_pool =
2897  ff_refstruct_pool_alloc_ext(sizeof(VABufferID), 0, avctx,
2900  if (!ctx->output_buffer_pool) {
2901  err = AVERROR(ENOMEM);
2902  goto fail;
2903  }
2904 
2905  if (ctx->codec->configure) {
2906  err = ctx->codec->configure(avctx);
2907  if (err < 0)
2908  goto fail;
2909  }
2910 
2911  ctx->output_delay = ctx->b_per_p;
2912  ctx->decode_delay = ctx->max_b_depth;
2913 
2914  if (ctx->codec->sequence_params_size > 0) {
2915  ctx->codec_sequence_params =
2916  av_mallocz(ctx->codec->sequence_params_size);
2917  if (!ctx->codec_sequence_params) {
2918  err = AVERROR(ENOMEM);
2919  goto fail;
2920  }
2921  }
2922  if (ctx->codec->picture_params_size > 0) {
2923  ctx->codec_picture_params =
2924  av_mallocz(ctx->codec->picture_params_size);
2925  if (!ctx->codec_picture_params) {
2926  err = AVERROR(ENOMEM);
2927  goto fail;
2928  }
2929  }
2930 
2931  if (ctx->codec->init_sequence_params) {
2932  err = ctx->codec->init_sequence_params(avctx);
2933  if (err < 0) {
2934  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2935  "failed: %d.\n", err);
2936  goto fail;
2937  }
2938  }
2939 
2940  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2941  ctx->codec->write_sequence_header &&
2944  size_t bit_len = 8 * sizeof(data);
2945 
2946  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2947  if (err < 0) {
2948  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2949  "for extradata: %d.\n", err);
2950  goto fail;
2951  } else {
2952  avctx->extradata_size = (bit_len + 7) / 8;
2953  avctx->extradata = av_mallocz(avctx->extradata_size +
2955  if (!avctx->extradata) {
2956  err = AVERROR(ENOMEM);
2957  goto fail;
2958  }
2959  memcpy(avctx->extradata, data, avctx->extradata_size);
2960  }
2961  }
2962 
2963 #if VA_CHECK_VERSION(1, 9, 0)
2964  // check vaSyncBuffer function
2965  vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2966  if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2967  ctx->has_sync_buffer_func = 1;
2968  ctx->encode_fifo = av_fifo_alloc2(ctx->async_depth,
2969  sizeof(VAAPIEncodePicture *),
2970  0);
2971  if (!ctx->encode_fifo)
2972  return AVERROR(ENOMEM);
2973  }
2974 #endif
2975 
2976  return 0;
2977 
2978 fail:
2979  return err;
2980 }
2981 
2983 {
2984  VAAPIEncodeContext *ctx = avctx->priv_data;
2985  VAAPIEncodePicture *pic, *next;
2986 
2987  /* We check ctx->frame to know whether ff_vaapi_encode_init()
2988  * has been called and va_config/va_context initialized. */
2989  if (!ctx->frame)
2990  return 0;
2991 
2992  for (pic = ctx->pic_start; pic; pic = next) {
2993  next = pic->next;
2994  vaapi_encode_free(avctx, pic);
2995  }
2996 
2997  ff_refstruct_pool_uninit(&ctx->output_buffer_pool);
2998 
2999  if (ctx->va_context != VA_INVALID_ID) {
3000  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
3001  ctx->va_context = VA_INVALID_ID;
3002  }
3003 
3004  if (ctx->va_config != VA_INVALID_ID) {
3005  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
3006  ctx->va_config = VA_INVALID_ID;
3007  }
3008 
3009  av_frame_free(&ctx->frame);
3010  av_packet_free(&ctx->tail_pkt);
3011 
3012  av_freep(&ctx->codec_sequence_params);
3013  av_freep(&ctx->codec_picture_params);
3014  av_fifo_freep2(&ctx->encode_fifo);
3015 
3016  av_buffer_unref(&ctx->recon_frames_ref);
3017  av_buffer_unref(&ctx->input_frames_ref);
3018  av_buffer_unref(&ctx->device_ref);
3019 
3020  return 0;
3021 }
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:2613
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
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:838
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:750
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:130
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:492
vaapi_encode_init_slice_structure
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:2415
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:344
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:456
AVFrame::width
int width
Definition: frame.h:416
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:2982
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:365
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:711
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:2188
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:118
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:269
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:285
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
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
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:724
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:274
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:722
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:723
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:446
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:2566
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:2646
vaapi_encode_init_packed_headers
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
Definition: vaapi_encode.c:2506
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:2685
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:287
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:286
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:284
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:603
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:2659
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2773
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:416
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:2354
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:75
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:250
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:721
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:2131
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
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:227
rc_mode
mfxU16 rc_mode
Definition: qsvenc.c: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:409
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:311
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:2309
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