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(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  }
918 
919  av_frame_free(&pic->input_image);
920  av_frame_free(&pic->recon_image);
921 
923 
924  av_freep(&pic->param_buffers);
925  av_freep(&pic->slices);
926  // Output buffer should already be destroyed.
927  av_assert0(pic->output_buffer == VA_INVALID_ID);
928 
929  av_freep(&pic->priv_data);
931  av_freep(&pic->roi);
932 
933  av_free(pic);
934 
935  return 0;
936 }
937 
939  VAAPIEncodePicture *pic,
940  VAAPIEncodePicture *target,
941  int is_ref, int in_dpb, int prev)
942 {
943  int refs = 0;
944 
945  if (is_ref) {
946  av_assert0(pic != target);
948  pic->nb_refs[1] < MAX_PICTURE_REFERENCES);
949  if (target->display_order < pic->display_order)
950  pic->refs[0][pic->nb_refs[0]++] = target;
951  else
952  pic->refs[1][pic->nb_refs[1]++] = target;
953  ++refs;
954  }
955 
956  if (in_dpb) {
958  pic->dpb[pic->nb_dpb_pics++] = target;
959  ++refs;
960  }
961 
962  if (prev) {
963  av_assert0(!pic->prev);
964  pic->prev = target;
965  ++refs;
966  }
967 
968  target->ref_count[0] += refs;
969  target->ref_count[1] += refs;
970 }
971 
973  VAAPIEncodePicture *pic,
974  int level)
975 {
976  int i;
977 
978  if (pic->ref_removed[level])
979  return;
980 
981  for (i = 0; i < pic->nb_refs[0]; i++) {
982  av_assert0(pic->refs[0][i]);
983  --pic->refs[0][i]->ref_count[level];
984  av_assert0(pic->refs[0][i]->ref_count[level] >= 0);
985  }
986 
987  for (i = 0; i < pic->nb_refs[1]; i++) {
988  av_assert0(pic->refs[1][i]);
989  --pic->refs[1][i]->ref_count[level];
990  av_assert0(pic->refs[1][i]->ref_count[level] >= 0);
991  }
992 
993  for (i = 0; i < pic->nb_dpb_pics; i++) {
994  av_assert0(pic->dpb[i]);
995  --pic->dpb[i]->ref_count[level];
996  av_assert0(pic->dpb[i]->ref_count[level] >= 0);
997  }
998 
999  av_assert0(pic->prev || pic->type == PICTURE_TYPE_IDR);
1000  if (pic->prev) {
1001  --pic->prev->ref_count[level];
1002  av_assert0(pic->prev->ref_count[level] >= 0);
1003  }
1004 
1005  pic->ref_removed[level] = 1;
1006 }
1007 
1009  VAAPIEncodePicture *start,
1010  VAAPIEncodePicture *end,
1011  VAAPIEncodePicture *prev,
1012  int current_depth,
1013  VAAPIEncodePicture **last)
1014 {
1015  VAAPIEncodeContext *ctx = avctx->priv_data;
1016  VAAPIEncodePicture *pic, *next, *ref;
1017  int i, len;
1018 
1019  av_assert0(start && end && start != end && start->next != end);
1020 
1021  // If we are at the maximum depth then encode all pictures as
1022  // non-referenced B-pictures. Also do this if there is exactly one
1023  // picture left, since there will be nothing to reference it.
1024  if (current_depth == ctx->max_b_depth || start->next->next == end) {
1025  for (pic = start->next; pic; pic = pic->next) {
1026  if (pic == end)
1027  break;
1028  pic->type = PICTURE_TYPE_B;
1029  pic->b_depth = current_depth;
1030 
1031  vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
1032  vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
1033  vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
1034 
1035  for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
1036  vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
1037  }
1038  *last = prev;
1039 
1040  } else {
1041  // Split the current list at the midpoint with a referenced
1042  // B-picture, then descend into each side separately.
1043  len = 0;
1044  for (pic = start->next; pic != end; pic = pic->next)
1045  ++len;
1046  for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
1047 
1048  pic->type = PICTURE_TYPE_B;
1049  pic->b_depth = current_depth;
1050 
1051  pic->is_reference = 1;
1052 
1053  vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
1054  vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
1055  vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
1056  vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
1057 
1058  for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
1059  vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
1060 
1061  if (i > 1)
1062  vaapi_encode_set_b_pictures(avctx, start, pic, pic,
1063  current_depth + 1, &next);
1064  else
1065  next = pic;
1066 
1067  vaapi_encode_set_b_pictures(avctx, pic, end, next,
1068  current_depth + 1, last);
1069  }
1070 }
1071 
1073  VAAPIEncodePicture *pic)
1074 {
1075  VAAPIEncodeContext *ctx = avctx->priv_data;
1076  int i;
1077 
1078  if (!pic)
1079  return;
1080 
1081  if (pic->type == PICTURE_TYPE_IDR) {
1082  for (i = 0; i < ctx->nb_next_prev; i++) {
1083  --ctx->next_prev[i]->ref_count[0];
1084  ctx->next_prev[i] = NULL;
1085  }
1086  ctx->next_prev[0] = pic;
1087  ++pic->ref_count[0];
1088  ctx->nb_next_prev = 1;
1089 
1090  return;
1091  }
1092 
1093  if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) {
1094  ctx->next_prev[ctx->nb_next_prev++] = pic;
1095  ++pic->ref_count[0];
1096  } else {
1097  --ctx->next_prev[0]->ref_count[0];
1098  for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++)
1099  ctx->next_prev[i] = ctx->next_prev[i + 1];
1100  ctx->next_prev[i] = pic;
1101  ++pic->ref_count[0];
1102  }
1103 }
1104 
1106  VAAPIEncodePicture **pic_out)
1107 {
1108  VAAPIEncodeContext *ctx = avctx->priv_data;
1109  VAAPIEncodePicture *pic = NULL, *prev = NULL, *next, *start;
1110  int i, b_counter, closed_gop_end;
1111 
1112  // If there are any B-frames already queued, the next one to encode
1113  // is the earliest not-yet-issued frame for which all references are
1114  // available.
1115  for (pic = ctx->pic_start; pic; pic = pic->next) {
1116  if (pic->encode_issued)
1117  continue;
1118  if (pic->type != PICTURE_TYPE_B)
1119  continue;
1120  for (i = 0; i < pic->nb_refs[0]; i++) {
1121  if (!pic->refs[0][i]->encode_issued)
1122  break;
1123  }
1124  if (i != pic->nb_refs[0])
1125  continue;
1126 
1127  for (i = 0; i < pic->nb_refs[1]; i++) {
1128  if (!pic->refs[1][i]->encode_issued)
1129  break;
1130  }
1131  if (i == pic->nb_refs[1])
1132  break;
1133  }
1134 
1135  if (pic) {
1136  av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
1137  "encode next.\n", pic->b_depth);
1138  *pic_out = pic;
1139  return 0;
1140  }
1141 
1142  // Find the B-per-Pth available picture to become the next picture
1143  // on the top layer.
1144  start = NULL;
1145  b_counter = 0;
1146  closed_gop_end = ctx->closed_gop ||
1147  ctx->idr_counter == ctx->gop_per_idr;
1148  for (pic = ctx->pic_start; pic; pic = next) {
1149  next = pic->next;
1150  if (pic->encode_issued) {
1151  start = pic;
1152  continue;
1153  }
1154  // If the next available picture is force-IDR, encode it to start
1155  // a new GOP immediately.
1156  if (pic->force_idr)
1157  break;
1158  if (b_counter == ctx->b_per_p)
1159  break;
1160  // If this picture ends a closed GOP or starts a new GOP then it
1161  // needs to be in the top layer.
1162  if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
1163  break;
1164  // If the picture after this one is force-IDR, we need to encode
1165  // this one in the top layer.
1166  if (next && next->force_idr)
1167  break;
1168  ++b_counter;
1169  }
1170 
1171  // At the end of the stream the last picture must be in the top layer.
1172  if (!pic && ctx->end_of_stream) {
1173  --b_counter;
1174  pic = ctx->pic_end;
1175  if (pic->encode_complete)
1176  return AVERROR_EOF;
1177  else if (pic->encode_issued)
1178  return AVERROR(EAGAIN);
1179  }
1180 
1181  if (!pic) {
1182  av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
1183  "need more input for reference pictures.\n");
1184  return AVERROR(EAGAIN);
1185  }
1186  if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
1187  av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
1188  "need more input for timestamps.\n");
1189  return AVERROR(EAGAIN);
1190  }
1191 
1192  if (pic->force_idr) {
1193  av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
1194  "encode next.\n");
1195  pic->type = PICTURE_TYPE_IDR;
1196  ctx->idr_counter = 1;
1197  ctx->gop_counter = 1;
1198 
1199  } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
1200  if (ctx->idr_counter == ctx->gop_per_idr) {
1201  av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
1202  "encode next.\n");
1203  pic->type = PICTURE_TYPE_IDR;
1204  ctx->idr_counter = 1;
1205  } else {
1206  av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
1207  "encode next.\n");
1208  pic->type = PICTURE_TYPE_I;
1209  ++ctx->idr_counter;
1210  }
1211  ctx->gop_counter = 1;
1212 
1213  } else {
1214  if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
1215  av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
1216  "encode next.\n");
1217  } else {
1218  av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
1219  "encode next.\n");
1220  }
1221  pic->type = PICTURE_TYPE_P;
1222  av_assert0(start);
1223  ctx->gop_counter += 1 + b_counter;
1224  }
1225  pic->is_reference = 1;
1226  *pic_out = pic;
1227 
1228  vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
1229  if (pic->type != PICTURE_TYPE_IDR) {
1230  // TODO: apply both previous and forward multi reference for all vaapi encoders.
1231  // And L0/L1 reference frame number can be set dynamically through query
1232  // VAConfigAttribEncMaxRefFrames attribute.
1233  if (avctx->codec_id == AV_CODEC_ID_AV1) {
1234  for (i = 0; i < ctx->nb_next_prev; i++)
1235  vaapi_encode_add_ref(avctx, pic, ctx->next_prev[i],
1236  pic->type == PICTURE_TYPE_P,
1237  b_counter > 0, 0);
1238  } else
1239  vaapi_encode_add_ref(avctx, pic, start,
1240  pic->type == PICTURE_TYPE_P,
1241  b_counter > 0, 0);
1242 
1243  vaapi_encode_add_ref(avctx, pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1);
1244  }
1245 
1246  if (b_counter > 0) {
1247  vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1,
1248  &prev);
1249  } else {
1250  prev = pic;
1251  }
1252  vaapi_encode_add_next_prev(avctx, prev);
1253 
1254  return 0;
1255 }
1256 
1258 {
1259  VAAPIEncodeContext *ctx = avctx->priv_data;
1260  VAAPIEncodePicture *pic, *prev, *next;
1261 
1262  av_assert0(ctx->pic_start);
1263 
1264  // Remove direct references once each picture is complete.
1265  for (pic = ctx->pic_start; pic; pic = pic->next) {
1266  if (pic->encode_complete && pic->next)
1267  vaapi_encode_remove_refs(avctx, pic, 0);
1268  }
1269 
1270  // Remove indirect references once a picture has no direct references.
1271  for (pic = ctx->pic_start; pic; pic = pic->next) {
1272  if (pic->encode_complete && pic->ref_count[0] == 0)
1273  vaapi_encode_remove_refs(avctx, pic, 1);
1274  }
1275 
1276  // Clear out all complete pictures with no remaining references.
1277  prev = NULL;
1278  for (pic = ctx->pic_start; pic; pic = next) {
1279  next = pic->next;
1280  if (pic->encode_complete && pic->ref_count[1] == 0) {
1281  av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
1282  if (prev)
1283  prev->next = next;
1284  else
1285  ctx->pic_start = next;
1286  vaapi_encode_free(avctx, pic);
1287  } else {
1288  prev = pic;
1289  }
1290  }
1291 
1292  return 0;
1293 }
1294 
1296  const AVFrame *frame)
1297 {
1298  VAAPIEncodeContext *ctx = avctx->priv_data;
1299 
1300  if ((frame->crop_top || frame->crop_bottom ||
1301  frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
1302  av_log(avctx, AV_LOG_WARNING, "Cropping information on input "
1303  "frames ignored due to lack of API support.\n");
1304  ctx->crop_warned = 1;
1305  }
1306 
1307  if (!ctx->roi_allowed) {
1308  AVFrameSideData *sd =
1310 
1311  if (sd && !ctx->roi_warned) {
1312  av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
1313  "frames ignored due to lack of driver support.\n");
1314  ctx->roi_warned = 1;
1315  }
1316  }
1317 
1318  return 0;
1319 }
1320 
1322 {
1323  VAAPIEncodeContext *ctx = avctx->priv_data;
1324  VAAPIEncodePicture *pic;
1325  int err;
1326 
1327  if (frame) {
1328  av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
1329  frame->width, frame->height, frame->pts);
1330 
1331  err = vaapi_encode_check_frame(avctx, frame);
1332  if (err < 0)
1333  return err;
1334 
1335  pic = vaapi_encode_alloc(avctx);
1336  if (!pic)
1337  return AVERROR(ENOMEM);
1338 
1339  pic->input_image = av_frame_alloc();
1340  if (!pic->input_image) {
1341  err = AVERROR(ENOMEM);
1342  goto fail;
1343  }
1344 
1345  if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I)
1346  pic->force_idr = 1;
1347 
1348  pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3];
1349  pic->pts = frame->pts;
1350  pic->duration = frame->duration;
1351 
1352  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
1354  if (err < 0)
1355  goto fail;
1356 
1357  pic->opaque = frame->opaque;
1358  }
1359 
1361 
1362  if (ctx->input_order == 0)
1363  ctx->first_pts = pic->pts;
1364  if (ctx->input_order == ctx->decode_delay)
1365  ctx->dts_pts_diff = pic->pts - ctx->first_pts;
1366  if (ctx->output_delay > 0)
1367  ctx->ts_ring[ctx->input_order %
1368  (3 * ctx->output_delay + ctx->async_depth)] = pic->pts;
1369 
1370  pic->display_order = ctx->input_order;
1371  ++ctx->input_order;
1372 
1373  if (ctx->pic_start) {
1374  ctx->pic_end->next = pic;
1375  ctx->pic_end = pic;
1376  } else {
1377  ctx->pic_start = pic;
1378  ctx->pic_end = pic;
1379  }
1380 
1381  } else {
1382  ctx->end_of_stream = 1;
1383 
1384  // Fix timestamps if we hit end-of-stream before the initial decode
1385  // delay has elapsed.
1386  if (ctx->input_order < ctx->decode_delay)
1387  ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
1388  }
1389 
1390  return 0;
1391 
1392 fail:
1393  vaapi_encode_free(avctx, pic);
1394  return err;
1395 }
1396 
1398 {
1399  VAAPIEncodeContext *ctx = avctx->priv_data;
1400  VAAPIEncodePicture *pic = NULL;
1401  AVFrame *frame = ctx->frame;
1402  int err;
1403 
1404 start:
1405  /** if no B frame before repeat P frame, sent repeat P frame out. */
1406  if (ctx->tail_pkt->size) {
1407  for (VAAPIEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) {
1408  if (tmp->type == PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts)
1409  break;
1410  else if (!tmp->next) {
1411  av_packet_move_ref(pkt, ctx->tail_pkt);
1412  goto end;
1413  }
1414  }
1415  }
1416 
1417  err = ff_encode_get_frame(avctx, frame);
1418  if (err < 0 && err != AVERROR_EOF)
1419  return err;
1420 
1421  if (err == AVERROR_EOF)
1422  frame = NULL;
1423 
1424  err = vaapi_encode_send_frame(avctx, frame);
1425  if (err < 0)
1426  return err;
1427 
1428  if (!ctx->pic_start) {
1429  if (ctx->end_of_stream)
1430  return AVERROR_EOF;
1431  else
1432  return AVERROR(EAGAIN);
1433  }
1434 
1435  if (ctx->has_sync_buffer_func) {
1436  if (av_fifo_can_write(ctx->encode_fifo)) {
1437  err = vaapi_encode_pick_next(avctx, &pic);
1438  if (!err) {
1439  av_assert0(pic);
1440  pic->encode_order = ctx->encode_order +
1441  av_fifo_can_read(ctx->encode_fifo);
1442  err = vaapi_encode_issue(avctx, pic);
1443  if (err < 0) {
1444  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1445  return err;
1446  }
1447  av_fifo_write(ctx->encode_fifo, &pic, 1);
1448  }
1449  }
1450 
1451  if (!av_fifo_can_read(ctx->encode_fifo))
1452  return err;
1453 
1454  // More frames can be buffered
1455  if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream)
1456  return AVERROR(EAGAIN);
1457 
1458  av_fifo_read(ctx->encode_fifo, &pic, 1);
1459  ctx->encode_order = pic->encode_order + 1;
1460  } else {
1461  err = vaapi_encode_pick_next(avctx, &pic);
1462  if (err < 0)
1463  return err;
1464  av_assert0(pic);
1465 
1466  pic->encode_order = ctx->encode_order++;
1467 
1468  err = vaapi_encode_issue(avctx, pic);
1469  if (err < 0) {
1470  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1471  return err;
1472  }
1473  }
1474 
1475  err = vaapi_encode_output(avctx, pic, pkt);
1476  if (err < 0) {
1477  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
1478  return err;
1479  }
1480 
1481  ctx->output_order = pic->encode_order;
1482  vaapi_encode_clear_old(avctx);
1483 
1484  /** loop to get an available pkt in encoder flushing. */
1485  if (ctx->end_of_stream && !pkt->size)
1486  goto start;
1487 
1488 end:
1489  if (pkt->size)
1490  av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", "
1491  "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size);
1492 
1493  return 0;
1494 }
1495 
1497  void *buffer, size_t size)
1498 {
1499  VAAPIEncodeContext *ctx = avctx->priv_data;
1500 
1501  av_assert0(ctx->nb_global_params < MAX_GLOBAL_PARAMS);
1502 
1503  ctx->global_params_type[ctx->nb_global_params] = type;
1504  ctx->global_params [ctx->nb_global_params] = buffer;
1505  ctx->global_params_size[ctx->nb_global_params] = size;
1506 
1507  ++ctx->nb_global_params;
1508 }
1509 
1510 typedef struct VAAPIEncodeRTFormat {
1511  const char *name;
1512  unsigned int value;
1513  int depth;
1518 
1520  { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1521  { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1522  { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1523 #if VA_CHECK_VERSION(1, 2, 0)
1524  { "YUV420_12", VA_RT_FORMAT_YUV420_12, 12, 3, 1, 1 },
1525  { "YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 },
1526  { "YUV422_12", VA_RT_FORMAT_YUV422_12, 12, 3, 1, 0 },
1527  { "YUV444_10", VA_RT_FORMAT_YUV444_10, 10, 3, 0, 0 },
1528  { "YUV444_12", VA_RT_FORMAT_YUV444_12, 12, 3, 0, 0 },
1529 #endif
1530  { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1531  { "XYUV", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1532  { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1533 #if VA_CHECK_VERSION(0, 38, 1)
1534  { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1535 #endif
1536 };
1537 
1538 static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
1539  VAEntrypointEncSlice,
1540  VAEntrypointEncPicture,
1541 #if VA_CHECK_VERSION(0, 39, 2)
1542  VAEntrypointEncSliceLP,
1543 #endif
1544  0
1545 };
1546 #if VA_CHECK_VERSION(0, 39, 2)
1547 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1548  VAEntrypointEncSliceLP,
1549  0
1550 };
1551 #endif
1552 
1554 {
1555  VAAPIEncodeContext *ctx = avctx->priv_data;
1556  VAProfile *va_profiles = NULL;
1557  VAEntrypoint *va_entrypoints = NULL;
1558  VAStatus vas;
1559  const VAEntrypoint *usable_entrypoints;
1560  const VAAPIEncodeProfile *profile;
1561  const AVPixFmtDescriptor *desc;
1562  VAConfigAttrib rt_format_attr;
1563  const VAAPIEncodeRTFormat *rt_format;
1564  const char *profile_string, *entrypoint_string;
1565  int i, j, n, depth, err;
1566 
1567 
1568  if (ctx->low_power) {
1569 #if VA_CHECK_VERSION(0, 39, 2)
1570  usable_entrypoints = vaapi_encode_entrypoints_low_power;
1571 #else
1572  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
1573  "supported with this VAAPI version.\n");
1574  return AVERROR(EINVAL);
1575 #endif
1576  } else {
1577  usable_entrypoints = vaapi_encode_entrypoints_normal;
1578  }
1579 
1580  desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format);
1581  if (!desc) {
1582  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
1583  ctx->input_frames->sw_format);
1584  return AVERROR(EINVAL);
1585  }
1586  depth = desc->comp[0].depth;
1587  for (i = 1; i < desc->nb_components; i++) {
1588  if (desc->comp[i].depth != depth) {
1589  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
1590  desc->name);
1591  return AVERROR(EINVAL);
1592  }
1593  }
1594  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
1595  desc->name);
1596 
1597  n = vaMaxNumProfiles(ctx->hwctx->display);
1598  va_profiles = av_malloc_array(n, sizeof(VAProfile));
1599  if (!va_profiles) {
1600  err = AVERROR(ENOMEM);
1601  goto fail;
1602  }
1603  vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
1604  if (vas != VA_STATUS_SUCCESS) {
1605  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
1606  vas, vaErrorStr(vas));
1607  err = AVERROR_EXTERNAL;
1608  goto fail;
1609  }
1610 
1611  av_assert0(ctx->codec->profiles);
1612  for (i = 0; (ctx->codec->profiles[i].av_profile !=
1613  AV_PROFILE_UNKNOWN); i++) {
1614  profile = &ctx->codec->profiles[i];
1615  if (depth != profile->depth ||
1616  desc->nb_components != profile->nb_components)
1617  continue;
1618  if (desc->nb_components > 1 &&
1619  (desc->log2_chroma_w != profile->log2_chroma_w ||
1620  desc->log2_chroma_h != profile->log2_chroma_h))
1621  continue;
1622  if (avctx->profile != profile->av_profile &&
1623  avctx->profile != AV_PROFILE_UNKNOWN)
1624  continue;
1625 
1626 #if VA_CHECK_VERSION(1, 0, 0)
1627  profile_string = vaProfileStr(profile->va_profile);
1628 #else
1629  profile_string = "(no profile names)";
1630 #endif
1631 
1632  for (j = 0; j < n; j++) {
1633  if (va_profiles[j] == profile->va_profile)
1634  break;
1635  }
1636  if (j >= n) {
1637  av_log(avctx, AV_LOG_VERBOSE, "Compatible profile %s (%d) "
1638  "is not supported by driver.\n", profile_string,
1639  profile->va_profile);
1640  continue;
1641  }
1642 
1643  ctx->profile = profile;
1644  break;
1645  }
1646  if (!ctx->profile) {
1647  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1648  err = AVERROR(ENOSYS);
1649  goto fail;
1650  }
1651 
1652  avctx->profile = profile->av_profile;
1653  ctx->va_profile = profile->va_profile;
1654  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1655  profile_string, ctx->va_profile);
1656 
1657  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1658  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1659  if (!va_entrypoints) {
1660  err = AVERROR(ENOMEM);
1661  goto fail;
1662  }
1663  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1664  va_entrypoints, &n);
1665  if (vas != VA_STATUS_SUCCESS) {
1666  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1667  "profile %s (%d): %d (%s).\n", profile_string,
1668  ctx->va_profile, vas, vaErrorStr(vas));
1669  err = AVERROR_EXTERNAL;
1670  goto fail;
1671  }
1672 
1673  for (i = 0; i < n; i++) {
1674  for (j = 0; usable_entrypoints[j]; j++) {
1675  if (va_entrypoints[i] == usable_entrypoints[j])
1676  break;
1677  }
1678  if (usable_entrypoints[j])
1679  break;
1680  }
1681  if (i >= n) {
1682  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1683  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1684  err = AVERROR(ENOSYS);
1685  goto fail;
1686  }
1687 
1688  ctx->va_entrypoint = va_entrypoints[i];
1689 #if VA_CHECK_VERSION(1, 0, 0)
1690  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1691 #else
1692  entrypoint_string = "(no entrypoint names)";
1693 #endif
1694  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1695  entrypoint_string, ctx->va_entrypoint);
1696 
1697  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1698  rt_format = &vaapi_encode_rt_formats[i];
1699  if (rt_format->depth == depth &&
1700  rt_format->nb_components == profile->nb_components &&
1701  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1702  rt_format->log2_chroma_h == profile->log2_chroma_h)
1703  break;
1704  }
1706  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1707  "found for profile %s (%d) entrypoint %s (%d).\n",
1708  profile_string, ctx->va_profile,
1709  entrypoint_string, ctx->va_entrypoint);
1710  err = AVERROR(ENOSYS);
1711  goto fail;
1712  }
1713 
1714  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1715  vas = vaGetConfigAttributes(ctx->hwctx->display,
1716  ctx->va_profile, ctx->va_entrypoint,
1717  &rt_format_attr, 1);
1718  if (vas != VA_STATUS_SUCCESS) {
1719  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1720  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1721  err = AVERROR_EXTERNAL;
1722  goto fail;
1723  }
1724 
1725  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1726  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1727  "supported by driver: assuming surface RT format %s "
1728  "is valid.\n", rt_format->name);
1729  } else if (!(rt_format_attr.value & rt_format->value)) {
1730  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1731  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1732  rt_format->name, profile_string, ctx->va_profile,
1733  entrypoint_string, ctx->va_entrypoint);
1734  err = AVERROR(ENOSYS);
1735  goto fail;
1736  } else {
1737  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1738  "format %s (%#x).\n", rt_format->name, rt_format->value);
1739  ctx->config_attributes[ctx->nb_config_attributes++] =
1740  (VAConfigAttrib) {
1741  .type = VAConfigAttribRTFormat,
1742  .value = rt_format->value,
1743  };
1744  }
1745 
1746  err = 0;
1747 fail:
1748  av_freep(&va_profiles);
1749  av_freep(&va_entrypoints);
1750  return err;
1751 }
1752 
1754  // Bitrate Quality
1755  // | Maxrate | HRD/VBV
1756  { 0 }, // | | | |
1757  { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
1758  { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
1759  { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
1760 #if VA_CHECK_VERSION(1, 1, 0)
1761  { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
1762 #else
1763  { RC_MODE_ICQ, "ICQ", 0 },
1764 #endif
1765 #if VA_CHECK_VERSION(1, 3, 0)
1766  { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
1767  { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
1768 #else
1769  { RC_MODE_QVBR, "QVBR", 0 },
1770  { RC_MODE_AVBR, "AVBR", 0 },
1771 #endif
1772 };
1773 
1775 {
1776  VAAPIEncodeContext *ctx = avctx->priv_data;
1777  uint32_t supported_va_rc_modes;
1778  const VAAPIEncodeRCMode *rc_mode;
1779  int64_t rc_bits_per_second;
1780  int rc_target_percentage;
1781  int rc_window_size;
1782  int rc_quality;
1783  int64_t hrd_buffer_size;
1784  int64_t hrd_initial_buffer_fullness;
1785  int fr_num, fr_den;
1786  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1787  VAStatus vas;
1788  char supported_rc_modes_string[64];
1789 
1790  vas = vaGetConfigAttributes(ctx->hwctx->display,
1791  ctx->va_profile, ctx->va_entrypoint,
1792  &rc_attr, 1);
1793  if (vas != VA_STATUS_SUCCESS) {
1794  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1795  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1796  return AVERROR_EXTERNAL;
1797  }
1798  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1799  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1800  "supported rate control modes: assuming CQP only.\n");
1801  supported_va_rc_modes = VA_RC_CQP;
1802  strcpy(supported_rc_modes_string, "unknown");
1803  } else {
1804  char *str = supported_rc_modes_string;
1805  size_t len = sizeof(supported_rc_modes_string);
1806  int i, first = 1, res;
1807 
1808  supported_va_rc_modes = rc_attr.value;
1809  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1811  if (supported_va_rc_modes & rc_mode->va_mode) {
1812  res = snprintf(str, len, "%s%s",
1813  first ? "" : ", ", rc_mode->name);
1814  first = 0;
1815  if (res < 0) {
1816  *str = 0;
1817  break;
1818  }
1819  len -= res;
1820  str += res;
1821  if (len == 0)
1822  break;
1823  }
1824  }
1825 
1826  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1827  supported_rc_modes_string);
1828  }
1829 
1830  // Rate control mode selection:
1831  // * If the user has set a mode explicitly with the rc_mode option,
1832  // use it and fail if it is not available.
1833  // * If an explicit QP option has been set, use CQP.
1834  // * If the codec is CQ-only, use CQP.
1835  // * If the QSCALE avcodec option is set, use CQP.
1836  // * If bitrate and quality are both set, try QVBR.
1837  // * If quality is set, try ICQ, then CQP.
1838  // * If bitrate and maxrate are set and have the same value, try CBR.
1839  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1840  // * If no bitrate is set, try ICQ, then CQP.
1841 
1842 #define TRY_RC_MODE(mode, fail) do { \
1843  rc_mode = &vaapi_encode_rc_modes[mode]; \
1844  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1845  if (fail) { \
1846  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1847  "RC mode (supported modes: %s).\n", rc_mode->name, \
1848  supported_rc_modes_string); \
1849  return AVERROR(EINVAL); \
1850  } \
1851  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1852  "RC mode.\n", rc_mode->name); \
1853  rc_mode = NULL; \
1854  } else { \
1855  goto rc_mode_found; \
1856  } \
1857  } while (0)
1858 
1859  if (ctx->explicit_rc_mode)
1860  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1861 
1862  if (ctx->explicit_qp)
1864 
1865  if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY)
1867 
1868  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1870 
1871  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1873 
1874  if (avctx->global_quality > 0) {
1877  }
1878 
1879  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1881 
1882  if (avctx->bit_rate > 0) {
1886  } else {
1889  }
1890 
1891  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1892  "RC mode compatible with selected options "
1893  "(supported modes: %s).\n", supported_rc_modes_string);
1894  return AVERROR(EINVAL);
1895 
1896 rc_mode_found:
1897  if (rc_mode->bitrate) {
1898  if (avctx->bit_rate <= 0) {
1899  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1900  "RC mode.\n", rc_mode->name);
1901  return AVERROR(EINVAL);
1902  }
1903 
1904  if (rc_mode->mode == RC_MODE_AVBR) {
1905  // For maximum confusion AVBR is hacked into the existing API
1906  // by overloading some of the fields with completely different
1907  // meanings.
1908 
1909  // Target percentage does not apply in AVBR mode.
1910  rc_bits_per_second = avctx->bit_rate;
1911 
1912  // Accuracy tolerance range for meeting the specified target
1913  // bitrate. It's very unclear how this is actually intended
1914  // to work - since we do want to get the specified bitrate,
1915  // set the accuracy to 100% for now.
1916  rc_target_percentage = 100;
1917 
1918  // Convergence period in frames. The GOP size reflects the
1919  // user's intended block size for cutting, so reusing that
1920  // as the convergence period seems a reasonable default.
1921  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1922 
1923  } else if (rc_mode->maxrate) {
1924  if (avctx->rc_max_rate > 0) {
1925  if (avctx->rc_max_rate < avctx->bit_rate) {
1926  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1927  "bitrate (%"PRId64") must not be greater than "
1928  "maxrate (%"PRId64").\n", avctx->bit_rate,
1929  avctx->rc_max_rate);
1930  return AVERROR(EINVAL);
1931  }
1932  rc_bits_per_second = avctx->rc_max_rate;
1933  rc_target_percentage = (avctx->bit_rate * 100) /
1934  avctx->rc_max_rate;
1935  } else {
1936  // We only have a target bitrate, but this mode requires
1937  // that a maximum rate be supplied as well. Since the
1938  // user does not want this to be a constraint, arbitrarily
1939  // pick a maximum rate of double the target rate.
1940  rc_bits_per_second = 2 * avctx->bit_rate;
1941  rc_target_percentage = 50;
1942  }
1943  } else {
1944  if (avctx->rc_max_rate > avctx->bit_rate) {
1945  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1946  "in %s RC mode.\n", rc_mode->name);
1947  }
1948  rc_bits_per_second = avctx->bit_rate;
1949  rc_target_percentage = 100;
1950  }
1951  } else {
1952  rc_bits_per_second = 0;
1953  rc_target_percentage = 100;
1954  }
1955 
1956  if (rc_mode->quality) {
1957  if (ctx->explicit_qp) {
1958  rc_quality = ctx->explicit_qp;
1959  } else if (avctx->global_quality > 0) {
1960  rc_quality = avctx->global_quality;
1961  } else {
1962  rc_quality = ctx->codec->default_quality;
1963  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1964  "using default (%d).\n", rc_quality);
1965  }
1966  } else {
1967  rc_quality = 0;
1968  }
1969 
1970  if (rc_mode->hrd) {
1971  if (avctx->rc_buffer_size)
1972  hrd_buffer_size = avctx->rc_buffer_size;
1973  else if (avctx->rc_max_rate > 0)
1974  hrd_buffer_size = avctx->rc_max_rate;
1975  else
1976  hrd_buffer_size = avctx->bit_rate;
1977  if (avctx->rc_initial_buffer_occupancy) {
1978  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1979  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1980  "must have initial buffer size (%d) <= "
1981  "buffer size (%"PRId64").\n",
1982  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1983  return AVERROR(EINVAL);
1984  }
1985  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1986  } else {
1987  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1988  }
1989 
1990  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1991  } else {
1992  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
1993  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
1994  "in %s RC mode.\n", rc_mode->name);
1995  }
1996 
1997  hrd_buffer_size = 0;
1998  hrd_initial_buffer_fullness = 0;
1999 
2000  if (rc_mode->mode != RC_MODE_AVBR) {
2001  // Already set (with completely different meaning) for AVBR.
2002  rc_window_size = 1000;
2003  }
2004  }
2005 
2006  if (rc_bits_per_second > UINT32_MAX ||
2007  hrd_buffer_size > UINT32_MAX ||
2008  hrd_initial_buffer_fullness > UINT32_MAX) {
2009  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
2010  "greater are not supported by VAAPI.\n");
2011  return AVERROR(EINVAL);
2012  }
2013 
2014  ctx->rc_mode = rc_mode;
2015  ctx->rc_quality = rc_quality;
2016  ctx->va_rc_mode = rc_mode->va_mode;
2017  ctx->va_bit_rate = rc_bits_per_second;
2018 
2019  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
2020  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2021  // This driver does not want the RC mode attribute to be set.
2022  } else {
2023  ctx->config_attributes[ctx->nb_config_attributes++] =
2024  (VAConfigAttrib) {
2025  .type = VAConfigAttribRateControl,
2026  .value = ctx->va_rc_mode,
2027  };
2028  }
2029 
2030  if (rc_mode->quality)
2031  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
2032 
2033  if (rc_mode->va_mode != VA_RC_CQP) {
2034  if (rc_mode->mode == RC_MODE_AVBR) {
2035  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
2036  "converging in %d frames with %d%% accuracy.\n",
2037  rc_bits_per_second, rc_window_size,
2038  rc_target_percentage);
2039  } else if (rc_mode->bitrate) {
2040  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
2041  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
2042  rc_bits_per_second, rc_window_size);
2043  }
2044 
2045  ctx->rc_params = (VAEncMiscParameterRateControl) {
2046  .bits_per_second = rc_bits_per_second,
2047  .target_percentage = rc_target_percentage,
2048  .window_size = rc_window_size,
2049  .initial_qp = 0,
2050  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
2051  .basic_unit_size = 0,
2052 #if VA_CHECK_VERSION(1, 1, 0)
2053  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
2054  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
2055 #endif
2056 #if VA_CHECK_VERSION(1, 3, 0)
2057  .quality_factor = rc_quality,
2058 #endif
2059  };
2061  VAEncMiscParameterTypeRateControl,
2062  &ctx->rc_params,
2063  sizeof(ctx->rc_params));
2064  }
2065 
2066  if (rc_mode->hrd) {
2067  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
2068  "initial fullness %"PRId64" bits.\n",
2069  hrd_buffer_size, hrd_initial_buffer_fullness);
2070 
2071  ctx->hrd_params = (VAEncMiscParameterHRD) {
2072  .initial_buffer_fullness = hrd_initial_buffer_fullness,
2073  .buffer_size = hrd_buffer_size,
2074  };
2076  VAEncMiscParameterTypeHRD,
2077  &ctx->hrd_params,
2078  sizeof(ctx->hrd_params));
2079  }
2080 
2081  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
2082  av_reduce(&fr_num, &fr_den,
2083  avctx->framerate.num, avctx->framerate.den, 65535);
2084  else
2085  av_reduce(&fr_num, &fr_den,
2086  avctx->time_base.den, avctx->time_base.num, 65535);
2087 
2088  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
2089  fr_num, fr_den, (double)fr_num / fr_den);
2090 
2091  ctx->fr_params = (VAEncMiscParameterFrameRate) {
2092  .framerate = (unsigned int)fr_den << 16 | fr_num,
2093  };
2094 #if VA_CHECK_VERSION(0, 40, 0)
2096  VAEncMiscParameterTypeFrameRate,
2097  &ctx->fr_params,
2098  sizeof(ctx->fr_params));
2099 #endif
2100 
2101  return 0;
2102 }
2103 
2105 {
2106 #if VA_CHECK_VERSION(1, 5, 0)
2107  VAAPIEncodeContext *ctx = avctx->priv_data;
2108  VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
2109  VAStatus vas;
2110 
2111  if (ctx->va_rc_mode == VA_RC_CQP) {
2112  ctx->max_frame_size = 0;
2113  av_log(avctx, AV_LOG_ERROR, "Max frame size is invalid in CQP rate "
2114  "control mode.\n");
2115  return AVERROR(EINVAL);
2116  }
2117 
2118  vas = vaGetConfigAttributes(ctx->hwctx->display,
2119  ctx->va_profile,
2120  ctx->va_entrypoint,
2121  &attr, 1);
2122  if (vas != VA_STATUS_SUCCESS) {
2123  ctx->max_frame_size = 0;
2124  av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
2125  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2126  return AVERROR_EXTERNAL;
2127  }
2128 
2129  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2130  ctx->max_frame_size = 0;
2131  av_log(avctx, AV_LOG_ERROR, "Max frame size attribute "
2132  "is not supported.\n");
2133  return AVERROR(EINVAL);
2134  } else {
2135  VAConfigAttribValMaxFrameSize attr_mfs;
2136  attr_mfs.value = attr.value;
2137  // Prefer to use VAEncMiscParameterTypeMaxFrameSize for max frame size.
2138  if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
2139  ctx->max_frame_size = 0;
2140  av_log(avctx, AV_LOG_ERROR, "Driver only supports multiple pass "
2141  "max frame size which has not been implemented in FFmpeg.\n");
2142  return AVERROR(EINVAL);
2143  }
2144 
2145  ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
2146  .max_frame_size = ctx->max_frame_size * 8,
2147  };
2148 
2149  av_log(avctx, AV_LOG_VERBOSE, "Set max frame size: %d bytes.\n",
2150  ctx->max_frame_size);
2151  }
2152 #else
2153  av_log(avctx, AV_LOG_ERROR, "The max frame size option is not supported with "
2154  "this VAAPI version.\n");
2155  return AVERROR(EINVAL);
2156 #endif
2157 
2158  return 0;
2159 }
2160 
2162 {
2163  VAAPIEncodeContext *ctx = avctx->priv_data;
2164  VAStatus vas;
2165  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
2166  uint32_t ref_l0, ref_l1;
2167  int prediction_pre_only;
2168 
2169  vas = vaGetConfigAttributes(ctx->hwctx->display,
2170  ctx->va_profile,
2171  ctx->va_entrypoint,
2172  &attr, 1);
2173  if (vas != VA_STATUS_SUCCESS) {
2174  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
2175  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2176  return AVERROR_EXTERNAL;
2177  }
2178 
2179  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2180  ref_l0 = ref_l1 = 0;
2181  } else {
2182  ref_l0 = attr.value & 0xffff;
2183  ref_l1 = attr.value >> 16 & 0xffff;
2184  }
2185 
2186  ctx->p_to_gpb = 0;
2187  prediction_pre_only = 0;
2188 
2189 #if VA_CHECK_VERSION(1, 9, 0)
2190  if (!(ctx->codec->flags & FLAG_INTRA_ONLY ||
2191  avctx->gop_size <= 1)) {
2192  attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
2193  vas = vaGetConfigAttributes(ctx->hwctx->display,
2194  ctx->va_profile,
2195  ctx->va_entrypoint,
2196  &attr, 1);
2197  if (vas != VA_STATUS_SUCCESS) {
2198  av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
2199  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2200  return AVERROR_EXTERNAL;
2201  } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2202  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
2203  "prediction constraints.\n");
2204  } else {
2205  if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
2206  ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
2207  av_log(avctx, AV_LOG_ERROR, "Driver report incorrect prediction "
2208  "direction attribute.\n");
2209  return AVERROR_EXTERNAL;
2210  }
2211 
2212  if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
2213  if (ref_l0 > 0 && ref_l1 > 0) {
2214  prediction_pre_only = 1;
2215  av_log(avctx, AV_LOG_VERBOSE, "Driver only support same reference "
2216  "lists for B-frames.\n");
2217  }
2218  }
2219 
2220  if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
2221  if (ref_l0 > 0 && ref_l1 > 0) {
2222  ctx->p_to_gpb = 1;
2223  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
2224  "replacing them with B-frames.\n");
2225  }
2226  }
2227  }
2228  }
2229 #endif
2230 
2231  if (ctx->codec->flags & FLAG_INTRA_ONLY ||
2232  avctx->gop_size <= 1) {
2233  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
2234  ctx->gop_size = 1;
2235  } else if (ref_l0 < 1) {
2236  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
2237  "reference frames.\n");
2238  return AVERROR(EINVAL);
2239  } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
2240  ref_l1 < 1 || avctx->max_b_frames < 1 ||
2241  prediction_pre_only) {
2242  if (ctx->p_to_gpb)
2243  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2244  "(supported references: %d / %d).\n",
2245  ref_l0, ref_l1);
2246  else
2247  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
2248  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2249  ctx->gop_size = avctx->gop_size;
2250  ctx->p_per_i = INT_MAX;
2251  ctx->b_per_p = 0;
2252  } else {
2253  if (ctx->p_to_gpb)
2254  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2255  "(supported references: %d / %d).\n",
2256  ref_l0, ref_l1);
2257  else
2258  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
2259  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2260  ctx->gop_size = avctx->gop_size;
2261  ctx->p_per_i = INT_MAX;
2262  ctx->b_per_p = avctx->max_b_frames;
2263  if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
2264  ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
2265  av_log2(ctx->b_per_p) + 1);
2266  } else {
2267  ctx->max_b_depth = 1;
2268  }
2269  }
2270 
2271  if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
2272  ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
2273  ctx->gop_per_idr = ctx->idr_interval + 1;
2274  } else {
2275  ctx->closed_gop = 1;
2276  ctx->gop_per_idr = 1;
2277  }
2278 
2279  return 0;
2280 }
2281 
2283  uint32_t slice_structure)
2284 {
2285  VAAPIEncodeContext *ctx = avctx->priv_data;
2286  int req_slices;
2287 
2288  // For fixed-size slices currently we only support whole rows, making
2289  // rectangular slices. This could be extended to arbitrary runs of
2290  // blocks, but since slices tend to be a conformance requirement and
2291  // most cases (such as broadcast or bluray) want rectangular slices
2292  // only it would need to be gated behind another option.
2293  if (avctx->slices > ctx->slice_block_rows) {
2294  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
2295  "configured number of slices (%d < %d); using "
2296  "maximum.\n", ctx->slice_block_rows, avctx->slices);
2297  req_slices = ctx->slice_block_rows;
2298  } else {
2299  req_slices = avctx->slices;
2300  }
2301  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
2302  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
2303  ctx->nb_slices = req_slices;
2304  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
2305  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
2306  int k;
2307  for (k = 1;; k *= 2) {
2308  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
2309  break;
2310  }
2311  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
2312  ctx->slice_size = k;
2313 #if VA_CHECK_VERSION(1, 0, 0)
2314  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
2315  ctx->nb_slices = ctx->slice_block_rows;
2316  ctx->slice_size = 1;
2317 #endif
2318  } else {
2319  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
2320  "slice structure modes (%#x).\n", slice_structure);
2321  return AVERROR(EINVAL);
2322  }
2323 
2324  return 0;
2325 }
2326 
2328  uint32_t slice_structure)
2329 {
2330  VAAPIEncodeContext *ctx = avctx->priv_data;
2331  int i, req_tiles;
2332 
2333  if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
2334  (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
2335  ctx->tile_cols == 1))) {
2336  av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
2337  "current tile requirement.\n", slice_structure);
2338  return AVERROR(EINVAL);
2339  }
2340 
2341  if (ctx->tile_rows > ctx->slice_block_rows ||
2342  ctx->tile_cols > ctx->slice_block_cols) {
2343  av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
2344  "for configured number of tile (%d x %d); ",
2345  ctx->slice_block_rows, ctx->slice_block_cols,
2346  ctx->tile_rows, ctx->tile_cols);
2347  ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
2348  ctx->slice_block_rows : ctx->tile_rows;
2349  ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
2350  ctx->slice_block_cols : ctx->tile_cols;
2351  av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
2352  ctx->tile_rows, ctx->tile_cols);
2353  }
2354 
2355  req_tiles = ctx->tile_rows * ctx->tile_cols;
2356 
2357  // Tile slice is not allowed to cross the boundary of a tile due to
2358  // the constraints of media-driver. Currently we support one slice
2359  // per tile. This could be extended to multiple slices per tile.
2360  if (avctx->slices != req_tiles)
2361  av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
2362  "mismatches with configured number of tile (%d != %d); "
2363  "using requested tile number for slice.\n",
2364  avctx->slices, req_tiles);
2365 
2366  ctx->nb_slices = req_tiles;
2367 
2368  // Default in uniform spacing
2369  // 6-3, 6-5
2370  for (i = 0; i < ctx->tile_cols; i++) {
2371  ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
2372  i * ctx->slice_block_cols / ctx->tile_cols;
2373  ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
2374  }
2375  // 6-4, 6-6
2376  for (i = 0; i < ctx->tile_rows; i++) {
2377  ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
2378  i * ctx->slice_block_rows / ctx->tile_rows;
2379  ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
2380  }
2381 
2382  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
2383  ctx->tile_rows, ctx->tile_cols);
2384 
2385  return 0;
2386 }
2387 
2389 {
2390  VAAPIEncodeContext *ctx = avctx->priv_data;
2391  VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
2392  { VAConfigAttribEncSliceStructure },
2393 #if VA_CHECK_VERSION(1, 1, 0)
2394  { VAConfigAttribEncTileSupport },
2395 #endif
2396  };
2397  VAStatus vas;
2398  uint32_t max_slices, slice_structure;
2399  int ret;
2400 
2401  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
2402  if (avctx->slices > 0) {
2403  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
2404  "but this codec does not support controlling slices.\n");
2405  }
2406  return 0;
2407  }
2408 
2409  av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0);
2410 
2411  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
2412  ctx->slice_block_height;
2413  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
2414  ctx->slice_block_width;
2415 
2416  if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
2417  ctx->nb_slices = 1;
2418  ctx->slice_size = ctx->slice_block_rows;
2419  return 0;
2420  }
2421 
2422  vas = vaGetConfigAttributes(ctx->hwctx->display,
2423  ctx->va_profile,
2424  ctx->va_entrypoint,
2425  attr, FF_ARRAY_ELEMS(attr));
2426  if (vas != VA_STATUS_SUCCESS) {
2427  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
2428  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
2429  return AVERROR_EXTERNAL;
2430  }
2431  max_slices = attr[0].value;
2432  slice_structure = attr[1].value;
2433  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
2434  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
2435  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2436  "pictures as multiple slices.\n.");
2437  return AVERROR(EINVAL);
2438  }
2439 
2440  if (ctx->tile_rows && ctx->tile_cols) {
2441 #if VA_CHECK_VERSION(1, 1, 0)
2442  uint32_t tile_support = attr[2].value;
2443  if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
2444  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2445  "pictures as multiple tiles.\n.");
2446  return AVERROR(EINVAL);
2447  }
2448 #else
2449  av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
2450  "not supported with this VAAPI version.\n");
2451  return AVERROR(EINVAL);
2452 #endif
2453  }
2454 
2455  if (ctx->tile_rows && ctx->tile_cols)
2456  ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
2457  else
2458  ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
2459  if (ret < 0)
2460  return ret;
2461 
2462  if (ctx->nb_slices > avctx->slices) {
2463  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
2464  "%d (from %d) due to driver constraints on slice "
2465  "structure.\n", ctx->nb_slices, avctx->slices);
2466  }
2467  if (ctx->nb_slices > max_slices) {
2468  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
2469  "encoding with %d slices (max %"PRIu32").\n",
2470  ctx->nb_slices, max_slices);
2471  return AVERROR(EINVAL);
2472  }
2473 
2474  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
2475  ctx->nb_slices);
2476  return 0;
2477 }
2478 
2480 {
2481  VAAPIEncodeContext *ctx = avctx->priv_data;
2482  VAStatus vas;
2483  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
2484 
2485  vas = vaGetConfigAttributes(ctx->hwctx->display,
2486  ctx->va_profile,
2487  ctx->va_entrypoint,
2488  &attr, 1);
2489  if (vas != VA_STATUS_SUCCESS) {
2490  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
2491  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2492  return AVERROR_EXTERNAL;
2493  }
2494 
2495  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2496  if (ctx->desired_packed_headers) {
2497  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
2498  "packed headers (wanted %#x).\n",
2499  ctx->desired_packed_headers);
2500  } else {
2501  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
2502  "packed headers (none wanted).\n");
2503  }
2504  ctx->va_packed_headers = 0;
2505  } else {
2506  if (ctx->desired_packed_headers & ~attr.value) {
2507  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
2508  "wanted packed headers (wanted %#x, found %#x).\n",
2509  ctx->desired_packed_headers, attr.value);
2510  } else {
2511  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
2512  "available (wanted %#x, found %#x).\n",
2513  ctx->desired_packed_headers, attr.value);
2514  }
2515  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
2516  }
2517 
2518  if (ctx->va_packed_headers) {
2519  ctx->config_attributes[ctx->nb_config_attributes++] =
2520  (VAConfigAttrib) {
2521  .type = VAConfigAttribEncPackedHeaders,
2522  .value = ctx->va_packed_headers,
2523  };
2524  }
2525 
2526  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2527  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2528  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
2529  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
2530  "sequence headers, but a global header is requested.\n");
2531  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
2532  "this may result in a stream which is not usable for some "
2533  "purposes (e.g. not muxable to some containers).\n");
2534  }
2535 
2536  return 0;
2537 }
2538 
2540 {
2541 #if VA_CHECK_VERSION(0, 36, 0)
2542  VAAPIEncodeContext *ctx = avctx->priv_data;
2543  VAStatus vas;
2544  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
2545  int quality = avctx->compression_level;
2546 
2547  vas = vaGetConfigAttributes(ctx->hwctx->display,
2548  ctx->va_profile,
2549  ctx->va_entrypoint,
2550  &attr, 1);
2551  if (vas != VA_STATUS_SUCCESS) {
2552  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
2553  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2554  return AVERROR_EXTERNAL;
2555  }
2556 
2557  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2558  if (quality != 0) {
2559  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
2560  "supported: will use default quality level.\n");
2561  }
2562  } else {
2563  if (quality > attr.value) {
2564  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
2565  "valid range is 0-%d, using %d.\n",
2566  attr.value, attr.value);
2567  quality = attr.value;
2568  }
2569 
2570  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2571  .quality_level = quality,
2572  };
2574  VAEncMiscParameterTypeQualityLevel,
2575  &ctx->quality_params,
2576  sizeof(ctx->quality_params));
2577  }
2578 #else
2579  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
2580  "not supported with this VAAPI version.\n");
2581 #endif
2582 
2583  return 0;
2584 }
2585 
2587 {
2588 #if VA_CHECK_VERSION(1, 0, 0)
2589  VAAPIEncodeContext *ctx = avctx->priv_data;
2590  VAStatus vas;
2591  VAConfigAttrib attr = { VAConfigAttribEncROI };
2592 
2593  vas = vaGetConfigAttributes(ctx->hwctx->display,
2594  ctx->va_profile,
2595  ctx->va_entrypoint,
2596  &attr, 1);
2597  if (vas != VA_STATUS_SUCCESS) {
2598  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
2599  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2600  return AVERROR_EXTERNAL;
2601  }
2602 
2603  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2604  ctx->roi_allowed = 0;
2605  } else {
2606  VAConfigAttribValEncROI roi = {
2607  .value = attr.value,
2608  };
2609 
2610  ctx->roi_max_regions = roi.bits.num_roi_regions;
2611  ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2612  (ctx->va_rc_mode == VA_RC_CQP ||
2613  roi.bits.roi_rc_qp_delta_support);
2614  }
2615 #endif
2616  return 0;
2617 }
2618 
2620  void *obj)
2621 {
2622  AVCodecContext *avctx = opaque.nc;
2623  VAAPIEncodeContext *ctx = avctx->priv_data;
2624  VABufferID *buffer_id_ref = obj;
2625  VABufferID buffer_id = *buffer_id_ref;
2626 
2627  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2628 
2629  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2630 }
2631 
2633 {
2634  AVCodecContext *avctx = opaque.nc;
2635  VAAPIEncodeContext *ctx = avctx->priv_data;
2636  VABufferID *buffer_id = obj;
2637  VAStatus vas;
2638 
2639  // The output buffer size is fixed, so it needs to be large enough
2640  // to hold the largest possible compressed frame. We assume here
2641  // that the uncompressed frame plus some header data is an upper
2642  // bound on that.
2643  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2644  VAEncCodedBufferType,
2645  3 * ctx->surface_width * ctx->surface_height +
2646  (1 << 16), 1, 0, buffer_id);
2647  if (vas != VA_STATUS_SUCCESS) {
2648  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2649  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2650  return AVERROR(ENOMEM);
2651  }
2652 
2653  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", *buffer_id);
2654 
2655  return 0;
2656 }
2657 
2659 {
2660  VAAPIEncodeContext *ctx = avctx->priv_data;
2661  AVVAAPIHWConfig *hwconfig = NULL;
2662  AVHWFramesConstraints *constraints = NULL;
2663  enum AVPixelFormat recon_format;
2664  int err, i;
2665 
2666  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
2667  if (!hwconfig) {
2668  err = AVERROR(ENOMEM);
2669  goto fail;
2670  }
2671  hwconfig->config_id = ctx->va_config;
2672 
2673  constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
2674  hwconfig);
2675  if (!constraints) {
2676  err = AVERROR(ENOMEM);
2677  goto fail;
2678  }
2679 
2680  // Probably we can use the input surface format as the surface format
2681  // of the reconstructed frames. If not, we just pick the first (only?)
2682  // format in the valid list and hope that it all works.
2683  recon_format = AV_PIX_FMT_NONE;
2684  if (constraints->valid_sw_formats) {
2685  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
2686  if (ctx->input_frames->sw_format ==
2687  constraints->valid_sw_formats[i]) {
2688  recon_format = ctx->input_frames->sw_format;
2689  break;
2690  }
2691  }
2692  if (recon_format == AV_PIX_FMT_NONE) {
2693  // No match. Just use the first in the supported list and
2694  // hope for the best.
2695  recon_format = constraints->valid_sw_formats[0];
2696  }
2697  } else {
2698  // No idea what to use; copy input format.
2699  recon_format = ctx->input_frames->sw_format;
2700  }
2701  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
2702  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
2703 
2704  if (ctx->surface_width < constraints->min_width ||
2705  ctx->surface_height < constraints->min_height ||
2706  ctx->surface_width > constraints->max_width ||
2707  ctx->surface_height > constraints->max_height) {
2708  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
2709  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2710  ctx->surface_width, ctx->surface_height,
2711  constraints->min_width, constraints->max_width,
2712  constraints->min_height, constraints->max_height);
2713  err = AVERROR(EINVAL);
2714  goto fail;
2715  }
2716 
2717  av_freep(&hwconfig);
2718  av_hwframe_constraints_free(&constraints);
2719 
2720  ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
2721  if (!ctx->recon_frames_ref) {
2722  err = AVERROR(ENOMEM);
2723  goto fail;
2724  }
2725  ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
2726 
2727  ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
2728  ctx->recon_frames->sw_format = recon_format;
2729  ctx->recon_frames->width = ctx->surface_width;
2730  ctx->recon_frames->height = ctx->surface_height;
2731 
2732  err = av_hwframe_ctx_init(ctx->recon_frames_ref);
2733  if (err < 0) {
2734  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2735  "frame context: %d.\n", err);
2736  goto fail;
2737  }
2738 
2739  err = 0;
2740  fail:
2741  av_freep(&hwconfig);
2742  av_hwframe_constraints_free(&constraints);
2743  return err;
2744 }
2745 
2747 {
2748  VAAPIEncodeContext *ctx = avctx->priv_data;
2749  AVVAAPIFramesContext *recon_hwctx = NULL;
2750  VAStatus vas;
2751  int err;
2752 
2753  ctx->va_config = VA_INVALID_ID;
2754  ctx->va_context = VA_INVALID_ID;
2755 
2756  /* If you add something that can fail above this av_frame_alloc(),
2757  * modify ff_vaapi_encode_close() accordingly. */
2758  ctx->frame = av_frame_alloc();
2759  if (!ctx->frame) {
2760  return AVERROR(ENOMEM);
2761  }
2762 
2763  if (!avctx->hw_frames_ctx) {
2764  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
2765  "required to associate the encoding device.\n");
2766  return AVERROR(EINVAL);
2767  }
2768 
2769  ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
2770  if (!ctx->input_frames_ref) {
2771  err = AVERROR(ENOMEM);
2772  goto fail;
2773  }
2774  ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
2775 
2776  ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
2777  if (!ctx->device_ref) {
2778  err = AVERROR(ENOMEM);
2779  goto fail;
2780  }
2781  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
2782  ctx->hwctx = ctx->device->hwctx;
2783 
2784  ctx->tail_pkt = av_packet_alloc();
2785  if (!ctx->tail_pkt) {
2786  err = AVERROR(ENOMEM);
2787  goto fail;
2788  }
2789 
2790  err = vaapi_encode_profile_entrypoint(avctx);
2791  if (err < 0)
2792  goto fail;
2793 
2794  if (ctx->codec->get_encoder_caps) {
2795  err = ctx->codec->get_encoder_caps(avctx);
2796  if (err < 0)
2797  goto fail;
2798  } else {
2799  // Assume 16x16 blocks.
2800  ctx->surface_width = FFALIGN(avctx->width, 16);
2801  ctx->surface_height = FFALIGN(avctx->height, 16);
2802  if (ctx->codec->flags & FLAG_SLICE_CONTROL) {
2803  ctx->slice_block_width = 16;
2804  ctx->slice_block_height = 16;
2805  }
2806  }
2807 
2808  err = vaapi_encode_init_rate_control(avctx);
2809  if (err < 0)
2810  goto fail;
2811 
2812  err = vaapi_encode_init_gop_structure(avctx);
2813  if (err < 0)
2814  goto fail;
2815 
2816  err = vaapi_encode_init_slice_structure(avctx);
2817  if (err < 0)
2818  goto fail;
2819 
2820  err = vaapi_encode_init_packed_headers(avctx);
2821  if (err < 0)
2822  goto fail;
2823 
2824  err = vaapi_encode_init_roi(avctx);
2825  if (err < 0)
2826  goto fail;
2827 
2828  if (avctx->compression_level >= 0) {
2829  err = vaapi_encode_init_quality(avctx);
2830  if (err < 0)
2831  goto fail;
2832  }
2833 
2834  if (ctx->max_frame_size) {
2835  err = vaapi_encode_init_max_frame_size(avctx);
2836  if (err < 0)
2837  goto fail;
2838  }
2839 
2840  vas = vaCreateConfig(ctx->hwctx->display,
2841  ctx->va_profile, ctx->va_entrypoint,
2842  ctx->config_attributes, ctx->nb_config_attributes,
2843  &ctx->va_config);
2844  if (vas != VA_STATUS_SUCCESS) {
2845  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2846  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2847  err = AVERROR(EIO);
2848  goto fail;
2849  }
2850 
2851  err = vaapi_encode_create_recon_frames(avctx);
2852  if (err < 0)
2853  goto fail;
2854 
2855  recon_hwctx = ctx->recon_frames->hwctx;
2856  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2857  ctx->surface_width, ctx->surface_height,
2858  VA_PROGRESSIVE,
2859  recon_hwctx->surface_ids,
2860  recon_hwctx->nb_surfaces,
2861  &ctx->va_context);
2862  if (vas != VA_STATUS_SUCCESS) {
2863  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2864  "context: %d (%s).\n", vas, vaErrorStr(vas));
2865  err = AVERROR(EIO);
2866  goto fail;
2867  }
2868 
2869  ctx->output_buffer_pool =
2870  ff_refstruct_pool_alloc_ext(sizeof(VABufferID), 0, avctx,
2873  if (!ctx->output_buffer_pool) {
2874  err = AVERROR(ENOMEM);
2875  goto fail;
2876  }
2877 
2878  if (ctx->codec->configure) {
2879  err = ctx->codec->configure(avctx);
2880  if (err < 0)
2881  goto fail;
2882  }
2883 
2884  ctx->output_delay = ctx->b_per_p;
2885  ctx->decode_delay = ctx->max_b_depth;
2886 
2887  if (ctx->codec->sequence_params_size > 0) {
2888  ctx->codec_sequence_params =
2889  av_mallocz(ctx->codec->sequence_params_size);
2890  if (!ctx->codec_sequence_params) {
2891  err = AVERROR(ENOMEM);
2892  goto fail;
2893  }
2894  }
2895  if (ctx->codec->picture_params_size > 0) {
2896  ctx->codec_picture_params =
2897  av_mallocz(ctx->codec->picture_params_size);
2898  if (!ctx->codec_picture_params) {
2899  err = AVERROR(ENOMEM);
2900  goto fail;
2901  }
2902  }
2903 
2904  if (ctx->codec->init_sequence_params) {
2905  err = ctx->codec->init_sequence_params(avctx);
2906  if (err < 0) {
2907  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2908  "failed: %d.\n", err);
2909  goto fail;
2910  }
2911  }
2912 
2913  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2914  ctx->codec->write_sequence_header &&
2917  size_t bit_len = 8 * sizeof(data);
2918 
2919  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2920  if (err < 0) {
2921  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2922  "for extradata: %d.\n", err);
2923  goto fail;
2924  } else {
2925  avctx->extradata_size = (bit_len + 7) / 8;
2926  avctx->extradata = av_mallocz(avctx->extradata_size +
2928  if (!avctx->extradata) {
2929  err = AVERROR(ENOMEM);
2930  goto fail;
2931  }
2932  memcpy(avctx->extradata, data, avctx->extradata_size);
2933  }
2934  }
2935 
2936 #if VA_CHECK_VERSION(1, 9, 0)
2937  // check vaSyncBuffer function
2938  vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2939  if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2940  ctx->has_sync_buffer_func = 1;
2941  ctx->encode_fifo = av_fifo_alloc2(ctx->async_depth,
2942  sizeof(VAAPIEncodePicture *),
2943  0);
2944  if (!ctx->encode_fifo)
2945  return AVERROR(ENOMEM);
2946  }
2947 #endif
2948 
2949  return 0;
2950 
2951 fail:
2952  return err;
2953 }
2954 
2956 {
2957  VAAPIEncodeContext *ctx = avctx->priv_data;
2958  VAAPIEncodePicture *pic, *next;
2959 
2960  /* We check ctx->frame to know whether ff_vaapi_encode_init()
2961  * has been called and va_config/va_context initialized. */
2962  if (!ctx->frame)
2963  return 0;
2964 
2965  for (pic = ctx->pic_start; pic; pic = next) {
2966  next = pic->next;
2967  vaapi_encode_free(avctx, pic);
2968  }
2969 
2970  ff_refstruct_pool_uninit(&ctx->output_buffer_pool);
2971 
2972  if (ctx->va_context != VA_INVALID_ID) {
2973  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2974  ctx->va_context = VA_INVALID_ID;
2975  }
2976 
2977  if (ctx->va_config != VA_INVALID_ID) {
2978  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2979  ctx->va_config = VA_INVALID_ID;
2980  }
2981 
2982  av_frame_free(&ctx->frame);
2983  av_packet_free(&ctx->tail_pkt);
2984 
2985  av_freep(&ctx->codec_sequence_params);
2986  av_freep(&ctx->codec_picture_params);
2987  av_fifo_freep2(&ctx->encode_fifo);
2988 
2989  av_buffer_unref(&ctx->recon_frames_ref);
2990  av_buffer_unref(&ctx->input_frames_ref);
2991  av_buffer_unref(&ctx->device_ref);
2992 
2993  return 0;
2994 }
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:64
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:96
vaapi_encode_init_roi
static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
Definition: vaapi_encode.c:2586
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:824
FLAG_B_PICTURE_REFERENCES
@ FLAG_B_PICTURE_REFERENCES
Definition: vaapi_encode.h:407
av_clip_int8
#define av_clip_int8
Definition: common.h:105
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:570
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:807
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2964
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:220
vaapi_encode_entrypoints_normal
static const VAEntrypoint vaapi_encode_entrypoints_normal[]
Definition: vaapi_encode.c:1538
av_unused
#define av_unused
Definition: attributes.h:131
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:501
vaapi_encode_init_slice_structure
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:2388
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:334
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
AVFrame::width
int width
Definition: frame.h:412
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:206
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:248
AVPacket::data
uint8_t * data
Definition: packet.h:491
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
RC_MODE_ICQ
@ RC_MODE_ICQ
Definition: vaapi_encode.h:170
VAAPIEncodeSlice::block_start
int block_start
Definition: vaapi_encode.h:68
RC_MODE_VBR
@ RC_MODE_VBR
Definition: vaapi_encode.h:169
MAX_GLOBAL_PARAMS
@ MAX_GLOBAL_PARAMS
Definition: vaapi_encode.h:42
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:2955
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:509
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:1774
VAAPIEncodeSlice::index
int index
Definition: vaapi_encode.h:65
FLAG_INTRA_ONLY
@ FLAG_INTRA_ONLY
Definition: vaapi_encode.h:403
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:1255
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:581
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:546
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:1512
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:334
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:453
AVFrame::opaque_ref
AVBufferRef * opaque_ref
Frame owner's private data.
Definition: frame.h:768
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1803
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:295
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:450
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:527
VAAPIEncodeSlice::row_start
int row_start
Definition: vaapi_encode.h:66
vaapi_encode.h
FLAG_B_PICTURES
@ FLAG_B_PICTURES
Definition: vaapi_encode.h:405
vaapi_encode_init_gop_structure
static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:2161
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:142
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:471
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
FLAG_CONSTANT_QUALITY_ONLY
@ FLAG_CONSTANT_QUALITY_ONLY
Definition: vaapi_encode.h:401
vaapi_encode_pick_next
static int vaapi_encode_pick_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
Definition: vaapi_encode.c:1105
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:521
VAAPIEncodeRTFormat
Definition: vaapi_encode.c:1510
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
TRY_RC_MODE
#define TRY_RC_MODE(mode, fail)
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
AVRational::num
int num
Numerator.
Definition: rational.h:59
refstruct.h
PICTURE_TYPE_B
@ PICTURE_TYPE_B
Definition: vaapi_encode.h:61
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:88
vaapi_encode_rt_formats
static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[]
Definition: vaapi_encode.c:1519
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:1515
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
AVRegionOfInterest
Structure describing a single Region Of Interest.
Definition: frame.h:265
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
AVCodecContext::rc_initial_buffer_occupancy
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:1312
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:465
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:606
VAAPIEncodePicture::codec_picture_params
void * codec_picture_params
Definition: vaapi_encode.h:111
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:543
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:507
AVRegionOfInterest::bottom
int bottom
Definition: frame.h:281
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:215
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1233
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
FLAG_SLICE_CONTROL
@ FLAG_SLICE_CONTROL
Definition: vaapi_encode.h:399
ff_vaapi_encode_receive_packet
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: vaapi_encode.c:1397
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:1008
AVFrame::crop_right
size_t crop_right
Definition: frame.h:781
vaapi_encode_add_next_prev
static void vaapi_encode_add_next_prev(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:1072
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1284
MAX_PICTURE_REFERENCES
@ MAX_PICTURE_REFERENCES
Definition: vaapi_encode.h:44
VAAPIEncodePicture::opaque
void * opaque
Definition: vaapi_encode.h:82
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:516
MAX_PARAM_BUFFER_SIZE
@ MAX_PARAM_BUFFER_SIZE
Definition: vaapi_encode.h:46
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:451
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:938
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1269
vaapi_encode_issue
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:266
FLAG_NON_IDR_KEY_PICTURES
@ FLAG_NON_IDR_KEY_PICTURES
Definition: vaapi_encode.h:410
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:283
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:491
AVRegionOfInterest::self_size
uint32_t self_size
Must be set to the size of this data structure (that is, sizeof(AVRegionOfInterest)).
Definition: frame.h:270
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
vaapi_encode_remove_refs
static void vaapi_encode_remove_refs(AVCodecContext *avctx, VAAPIEncodePicture *pic, int level)
Definition: vaapi_encode.c:972
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
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:480
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:1511
VAAPIEncodePicture::encode_issued
int encode_issued
Definition: vaapi_encode.h:94
AVFrame::crop_bottom
size_t crop_bottom
Definition: frame.h:779
vaapi_encode_get_coded_buffer_size
static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID buf_id)
Definition: vaapi_encode.c:707
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:563
VAAPIEncodePicture::slices
VAAPIEncodeSlice * slices
Definition: vaapi_encode.h:136
AVFrame::crop_left
size_t crop_left
Definition: frame.h:780
VAAPIEncodePicture::input_surface
VASurfaceID input_surface
Definition: vaapi_encode.h:98
FLAG_TIMESTAMP_NO_DELAY
@ FLAG_TIMESTAMP_NO_DELAY
Definition: vaapi_encode.h:413
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:442
VAAPIEncodePicture::type
int type
Definition: vaapi_encode.h:92
AVPacket::size
int size
Definition: packet.h:492
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:643
vaapi_encode_init_quality
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
Definition: vaapi_encode.c:2539
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:1753
PICTURE_TYPE_IDR
@ PICTURE_TYPE_IDR
Definition: vaapi_encode.h:58
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:1514
AVCodecHWConfigInternal
Definition: hwconfig.h:25
header
static const uint8_t header[24]
Definition: sdr2.c:67
VAAPIEncodeRTFormat::log2_chroma_h
int log2_chroma_h
Definition: vaapi_encode.c:1516
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
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:2619
vaapi_encode_init_packed_headers
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
Definition: vaapi_encode.c:2479
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:478
vaapi_encode_create_recon_frames
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
Definition: vaapi_encode.c:2658
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:497
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:63
PICTURE_TYPE_P
@ PICTURE_TYPE_P
Definition: vaapi_encode.h:60
AVRegionOfInterest::right
int right
Definition: frame.h:283
VAAPIEncodePicture::display_order
int64_t display_order
Definition: vaapi_encode.h:76
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:119
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:96
AVRegionOfInterest::left
int left
Definition: frame.h:282
vaapi_encode_check_frame
static int vaapi_encode_check_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: vaapi_encode.c:1295
PICTURE_TYPE_I
@ PICTURE_TYPE_I
Definition: vaapi_encode.h:59
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:245
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:484
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:542
AVRegionOfInterest::top
int top
Distance in pixels from the top edge of the frame to the top and bottom edges and from the left edge ...
Definition: frame.h:280
internal.h
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
VAAPIEncodePicture::roi
void * roi
Definition: vaapi_encode.h:89
common.h
RC_MODE_CBR
@ RC_MODE_CBR
Definition: vaapi_encode.h:168
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:649
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:2115
AVCodecContext::height
int height
Definition: avcodec.h:621
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:1940
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
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:348
vaapi_encode_alloc_output_buffer
static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
Definition: vaapi_encode.c:2632
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2746
ret
ret
Definition: filter_design.txt:187
VAAPIEncodeRTFormat::depth
int depth
Definition: vaapi_encode.c:1513
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:1496
vaapi_encode_output
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:819
RC_MODE_QVBR
@ RC_MODE_QVBR
Definition: vaapi_encode.h:171
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:479
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:441
AVFrame::height
int height
Definition: frame.h:412
AVHWFramesConstraints::min_height
int min_height
Definition: hwcontext.h:472
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:1248
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:65
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:1596
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:2327
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:83
RC_MODE_AVBR
@ RC_MODE_AVBR
Definition: vaapi_encode.h:172
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:720
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:209
VAAPIEncodePicture::input_image
AVFrame * input_image
Definition: vaapi_encode.h:97
VAAPIEncodeSlice::block_size
int block_size
Definition: vaapi_encode.h:69
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:246
VAAPIEncodeRCMode
Definition: vaapi_encode.h:176
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVVAAPIFramesContext
VAAPI-specific data associated with a frame pool.
Definition: hwcontext_vaapi.h:88
vaapi_encode_send_frame
static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: vaapi_encode.c:1321
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:1553
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1055
AVPacket
This structure stores compressed data.
Definition: packet.h:468
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
VAAPIEncodePicture::encode_order
int64_t encode_order
Definition: vaapi_encode.h:77
AVFrame::crop_top
size_t crop_top
Definition: frame.h:778
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:621
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:2104
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:1257
RC_MODE_CQP
@ RC_MODE_CQP
Definition: vaapi_encode.h:167
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:372
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:507
AVRegionOfInterest::qoffset
AVRational qoffset
Quantisation offset.
Definition: frame.h:307
MAX_DPB_SIZE
@ MAX_DPB_SIZE
Definition: vaapi_encode.h:43
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:2282
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:2884
AVCodecContext::compression_level
int compression_level
Definition: avcodec.h:513
VAAPIEncodePicture::nb_slices
int nb_slices
Definition: vaapi_encode.h:135