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