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