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  { "YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 },
1309 #endif
1310  { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1311  { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1312 #if VA_CHECK_VERSION(0, 38, 1)
1313  { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1314 #endif
1315 };
1316 
1317 static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
1318  VAEntrypointEncSlice,
1319  VAEntrypointEncPicture,
1320 #if VA_CHECK_VERSION(0, 39, 2)
1321  VAEntrypointEncSliceLP,
1322 #endif
1323  0
1324 };
1325 #if VA_CHECK_VERSION(0, 39, 2)
1326 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1327  VAEntrypointEncSliceLP,
1328  0
1329 };
1330 #endif
1331 
1333 {
1334  VAAPIEncodeContext *ctx = avctx->priv_data;
1335  VAProfile *va_profiles = NULL;
1336  VAEntrypoint *va_entrypoints = NULL;
1337  VAStatus vas;
1338  const VAEntrypoint *usable_entrypoints;
1339  const VAAPIEncodeProfile *profile;
1340  const AVPixFmtDescriptor *desc;
1341  VAConfigAttrib rt_format_attr;
1342  const VAAPIEncodeRTFormat *rt_format;
1343  const char *profile_string, *entrypoint_string;
1344  int i, j, n, depth, err;
1345 
1346 
1347  if (ctx->low_power) {
1348 #if VA_CHECK_VERSION(0, 39, 2)
1349  usable_entrypoints = vaapi_encode_entrypoints_low_power;
1350 #else
1351  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
1352  "supported with this VAAPI version.\n");
1353  return AVERROR(EINVAL);
1354 #endif
1355  } else {
1356  usable_entrypoints = vaapi_encode_entrypoints_normal;
1357  }
1358 
1359  desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format);
1360  if (!desc) {
1361  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
1362  ctx->input_frames->sw_format);
1363  return AVERROR(EINVAL);
1364  }
1365  depth = desc->comp[0].depth;
1366  for (i = 1; i < desc->nb_components; i++) {
1367  if (desc->comp[i].depth != depth) {
1368  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
1369  desc->name);
1370  return AVERROR(EINVAL);
1371  }
1372  }
1373  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
1374  desc->name);
1375 
1376  n = vaMaxNumProfiles(ctx->hwctx->display);
1377  va_profiles = av_malloc_array(n, sizeof(VAProfile));
1378  if (!va_profiles) {
1379  err = AVERROR(ENOMEM);
1380  goto fail;
1381  }
1382  vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
1383  if (vas != VA_STATUS_SUCCESS) {
1384  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
1385  vas, vaErrorStr(vas));
1386  err = AVERROR_EXTERNAL;
1387  goto fail;
1388  }
1389 
1390  av_assert0(ctx->codec->profiles);
1391  for (i = 0; (ctx->codec->profiles[i].av_profile !=
1392  FF_PROFILE_UNKNOWN); i++) {
1393  profile = &ctx->codec->profiles[i];
1394  if (depth != profile->depth ||
1395  desc->nb_components != profile->nb_components)
1396  continue;
1397  if (desc->nb_components > 1 &&
1398  (desc->log2_chroma_w != profile->log2_chroma_w ||
1399  desc->log2_chroma_h != profile->log2_chroma_h))
1400  continue;
1401  if (avctx->profile != profile->av_profile &&
1402  avctx->profile != FF_PROFILE_UNKNOWN)
1403  continue;
1404 
1405 #if VA_CHECK_VERSION(1, 0, 0)
1406  profile_string = vaProfileStr(profile->va_profile);
1407 #else
1408  profile_string = "(no profile names)";
1409 #endif
1410 
1411  for (j = 0; j < n; j++) {
1412  if (va_profiles[j] == profile->va_profile)
1413  break;
1414  }
1415  if (j >= n) {
1416  av_log(avctx, AV_LOG_VERBOSE, "Compatible profile %s (%d) "
1417  "is not supported by driver.\n", profile_string,
1418  profile->va_profile);
1419  continue;
1420  }
1421 
1422  ctx->profile = profile;
1423  break;
1424  }
1425  if (!ctx->profile) {
1426  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1427  err = AVERROR(ENOSYS);
1428  goto fail;
1429  }
1430 
1431  avctx->profile = profile->av_profile;
1432  ctx->va_profile = profile->va_profile;
1433  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1434  profile_string, ctx->va_profile);
1435 
1436  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1437  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1438  if (!va_entrypoints) {
1439  err = AVERROR(ENOMEM);
1440  goto fail;
1441  }
1442  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1443  va_entrypoints, &n);
1444  if (vas != VA_STATUS_SUCCESS) {
1445  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1446  "profile %s (%d): %d (%s).\n", profile_string,
1447  ctx->va_profile, vas, vaErrorStr(vas));
1448  err = AVERROR_EXTERNAL;
1449  goto fail;
1450  }
1451 
1452  for (i = 0; i < n; i++) {
1453  for (j = 0; usable_entrypoints[j]; j++) {
1454  if (va_entrypoints[i] == usable_entrypoints[j])
1455  break;
1456  }
1457  if (usable_entrypoints[j])
1458  break;
1459  }
1460  if (i >= n) {
1461  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1462  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1463  err = AVERROR(ENOSYS);
1464  goto fail;
1465  }
1466 
1467  ctx->va_entrypoint = va_entrypoints[i];
1468 #if VA_CHECK_VERSION(1, 0, 0)
1469  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1470 #else
1471  entrypoint_string = "(no entrypoint names)";
1472 #endif
1473  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1474  entrypoint_string, ctx->va_entrypoint);
1475 
1476  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1477  rt_format = &vaapi_encode_rt_formats[i];
1478  if (rt_format->depth == depth &&
1479  rt_format->nb_components == profile->nb_components &&
1480  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1481  rt_format->log2_chroma_h == profile->log2_chroma_h)
1482  break;
1483  }
1485  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1486  "found for profile %s (%d) entrypoint %s (%d).\n",
1487  profile_string, ctx->va_profile,
1488  entrypoint_string, ctx->va_entrypoint);
1489  err = AVERROR(ENOSYS);
1490  goto fail;
1491  }
1492 
1493  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1494  vas = vaGetConfigAttributes(ctx->hwctx->display,
1495  ctx->va_profile, ctx->va_entrypoint,
1496  &rt_format_attr, 1);
1497  if (vas != VA_STATUS_SUCCESS) {
1498  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1499  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1500  err = AVERROR_EXTERNAL;
1501  goto fail;
1502  }
1503 
1504  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1505  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1506  "supported by driver: assuming surface RT format %s "
1507  "is valid.\n", rt_format->name);
1508  } else if (!(rt_format_attr.value & rt_format->value)) {
1509  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1510  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1511  rt_format->name, profile_string, ctx->va_profile,
1512  entrypoint_string, ctx->va_entrypoint);
1513  err = AVERROR(ENOSYS);
1514  goto fail;
1515  } else {
1516  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1517  "format %s (%#x).\n", rt_format->name, rt_format->value);
1518  ctx->config_attributes[ctx->nb_config_attributes++] =
1519  (VAConfigAttrib) {
1520  .type = VAConfigAttribRTFormat,
1521  .value = rt_format->value,
1522  };
1523  }
1524 
1525  err = 0;
1526 fail:
1527  av_freep(&va_profiles);
1528  av_freep(&va_entrypoints);
1529  return err;
1530 }
1531 
1533  // Bitrate Quality
1534  // | Maxrate | HRD/VBV
1535  { 0 }, // | | | |
1536  { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
1537  { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
1538  { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
1539 #if VA_CHECK_VERSION(1, 1, 0)
1540  { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
1541 #else
1542  { RC_MODE_ICQ, "ICQ", 0 },
1543 #endif
1544 #if VA_CHECK_VERSION(1, 3, 0)
1545  { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
1546  { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
1547 #else
1548  { RC_MODE_QVBR, "QVBR", 0 },
1549  { RC_MODE_AVBR, "AVBR", 0 },
1550 #endif
1551 };
1552 
1554 {
1555  VAAPIEncodeContext *ctx = avctx->priv_data;
1556  uint32_t supported_va_rc_modes;
1557  const VAAPIEncodeRCMode *rc_mode;
1558  int64_t rc_bits_per_second;
1559  int rc_target_percentage;
1560  int rc_window_size;
1561  int rc_quality;
1562  int64_t hrd_buffer_size;
1563  int64_t hrd_initial_buffer_fullness;
1564  int fr_num, fr_den;
1565  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1566  VAStatus vas;
1567  char supported_rc_modes_string[64];
1568 
1569  vas = vaGetConfigAttributes(ctx->hwctx->display,
1570  ctx->va_profile, ctx->va_entrypoint,
1571  &rc_attr, 1);
1572  if (vas != VA_STATUS_SUCCESS) {
1573  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1574  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1575  return AVERROR_EXTERNAL;
1576  }
1577  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1578  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1579  "supported rate control modes: assuming CQP only.\n");
1580  supported_va_rc_modes = VA_RC_CQP;
1581  strcpy(supported_rc_modes_string, "unknown");
1582  } else {
1583  char *str = supported_rc_modes_string;
1584  size_t len = sizeof(supported_rc_modes_string);
1585  int i, first = 1, res;
1586 
1587  supported_va_rc_modes = rc_attr.value;
1588  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1590  if (supported_va_rc_modes & rc_mode->va_mode) {
1591  res = snprintf(str, len, "%s%s",
1592  first ? "" : ", ", rc_mode->name);
1593  first = 0;
1594  if (res < 0) {
1595  *str = 0;
1596  break;
1597  }
1598  len -= res;
1599  str += res;
1600  if (len == 0)
1601  break;
1602  }
1603  }
1604 
1605  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1606  supported_rc_modes_string);
1607  }
1608 
1609  // Rate control mode selection:
1610  // * If the user has set a mode explicitly with the rc_mode option,
1611  // use it and fail if it is not available.
1612  // * If an explicit QP option has been set, use CQP.
1613  // * If the codec is CQ-only, use CQP.
1614  // * If the QSCALE avcodec option is set, use CQP.
1615  // * If bitrate and quality are both set, try QVBR.
1616  // * If quality is set, try ICQ, then CQP.
1617  // * If bitrate and maxrate are set and have the same value, try CBR.
1618  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1619  // * If no bitrate is set, try ICQ, then CQP.
1620 
1621 #define TRY_RC_MODE(mode, fail) do { \
1622  rc_mode = &vaapi_encode_rc_modes[mode]; \
1623  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1624  if (fail) { \
1625  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1626  "RC mode (supported modes: %s).\n", rc_mode->name, \
1627  supported_rc_modes_string); \
1628  return AVERROR(EINVAL); \
1629  } \
1630  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1631  "RC mode.\n", rc_mode->name); \
1632  rc_mode = NULL; \
1633  } else { \
1634  goto rc_mode_found; \
1635  } \
1636  } while (0)
1637 
1638  if (ctx->explicit_rc_mode)
1639  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1640 
1641  if (ctx->explicit_qp)
1643 
1644  if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY)
1646 
1647  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1649 
1650  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1652 
1653  if (avctx->global_quality > 0) {
1656  }
1657 
1658  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1660 
1661  if (avctx->bit_rate > 0) {
1665  } else {
1668  }
1669 
1670  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1671  "RC mode compatible with selected options "
1672  "(supported modes: %s).\n", supported_rc_modes_string);
1673  return AVERROR(EINVAL);
1674 
1675 rc_mode_found:
1676  if (rc_mode->bitrate) {
1677  if (avctx->bit_rate <= 0) {
1678  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1679  "RC mode.\n", rc_mode->name);
1680  return AVERROR(EINVAL);
1681  }
1682 
1683  if (rc_mode->mode == RC_MODE_AVBR) {
1684  // For maximum confusion AVBR is hacked into the existing API
1685  // by overloading some of the fields with completely different
1686  // meanings.
1687 
1688  // Target percentage does not apply in AVBR mode.
1689  rc_bits_per_second = avctx->bit_rate;
1690 
1691  // Accuracy tolerance range for meeting the specified target
1692  // bitrate. It's very unclear how this is actually intended
1693  // to work - since we do want to get the specified bitrate,
1694  // set the accuracy to 100% for now.
1695  rc_target_percentage = 100;
1696 
1697  // Convergence period in frames. The GOP size reflects the
1698  // user's intended block size for cutting, so reusing that
1699  // as the convergence period seems a reasonable default.
1700  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1701 
1702  } else if (rc_mode->maxrate) {
1703  if (avctx->rc_max_rate > 0) {
1704  if (avctx->rc_max_rate < avctx->bit_rate) {
1705  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1706  "bitrate (%"PRId64") must not be greater than "
1707  "maxrate (%"PRId64").\n", avctx->bit_rate,
1708  avctx->rc_max_rate);
1709  return AVERROR(EINVAL);
1710  }
1711  rc_bits_per_second = avctx->rc_max_rate;
1712  rc_target_percentage = (avctx->bit_rate * 100) /
1713  avctx->rc_max_rate;
1714  } else {
1715  // We only have a target bitrate, but this mode requires
1716  // that a maximum rate be supplied as well. Since the
1717  // user does not want this to be a constraint, arbitrarily
1718  // pick a maximum rate of double the target rate.
1719  rc_bits_per_second = 2 * avctx->bit_rate;
1720  rc_target_percentage = 50;
1721  }
1722  } else {
1723  if (avctx->rc_max_rate > avctx->bit_rate) {
1724  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1725  "in %s RC mode.\n", rc_mode->name);
1726  }
1727  rc_bits_per_second = avctx->bit_rate;
1728  rc_target_percentage = 100;
1729  }
1730  } else {
1731  rc_bits_per_second = 0;
1732  rc_target_percentage = 100;
1733  }
1734 
1735  if (rc_mode->quality) {
1736  if (ctx->explicit_qp) {
1737  rc_quality = ctx->explicit_qp;
1738  } else if (avctx->global_quality > 0) {
1739  rc_quality = avctx->global_quality;
1740  } else {
1741  rc_quality = ctx->codec->default_quality;
1742  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1743  "using default (%d).\n", rc_quality);
1744  }
1745  } else {
1746  rc_quality = 0;
1747  }
1748 
1749  if (rc_mode->hrd) {
1750  if (avctx->rc_buffer_size)
1751  hrd_buffer_size = avctx->rc_buffer_size;
1752  else if (avctx->rc_max_rate > 0)
1753  hrd_buffer_size = avctx->rc_max_rate;
1754  else
1755  hrd_buffer_size = avctx->bit_rate;
1756  if (avctx->rc_initial_buffer_occupancy) {
1757  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1758  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1759  "must have initial buffer size (%d) <= "
1760  "buffer size (%"PRId64").\n",
1761  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1762  return AVERROR(EINVAL);
1763  }
1764  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1765  } else {
1766  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1767  }
1768 
1769  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1770  } else {
1771  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
1772  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
1773  "in %s RC mode.\n", rc_mode->name);
1774  }
1775 
1776  hrd_buffer_size = 0;
1777  hrd_initial_buffer_fullness = 0;
1778 
1779  if (rc_mode->mode != RC_MODE_AVBR) {
1780  // Already set (with completely different meaning) for AVBR.
1781  rc_window_size = 1000;
1782  }
1783  }
1784 
1785  if (rc_bits_per_second > UINT32_MAX ||
1786  hrd_buffer_size > UINT32_MAX ||
1787  hrd_initial_buffer_fullness > UINT32_MAX) {
1788  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1789  "greater are not supported by VAAPI.\n");
1790  return AVERROR(EINVAL);
1791  }
1792 
1793  ctx->rc_mode = rc_mode;
1794  ctx->rc_quality = rc_quality;
1795  ctx->va_rc_mode = rc_mode->va_mode;
1796  ctx->va_bit_rate = rc_bits_per_second;
1797 
1798  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
1799  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1800  // This driver does not want the RC mode attribute to be set.
1801  } else {
1802  ctx->config_attributes[ctx->nb_config_attributes++] =
1803  (VAConfigAttrib) {
1804  .type = VAConfigAttribRateControl,
1805  .value = ctx->va_rc_mode,
1806  };
1807  }
1808 
1809  if (rc_mode->quality)
1810  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
1811 
1812  if (rc_mode->va_mode != VA_RC_CQP) {
1813  if (rc_mode->mode == RC_MODE_AVBR) {
1814  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
1815  "converging in %d frames with %d%% accuracy.\n",
1816  rc_bits_per_second, rc_window_size,
1817  rc_target_percentage);
1818  } else if (rc_mode->bitrate) {
1819  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
1820  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
1821  rc_bits_per_second, rc_window_size);
1822  }
1823 
1824  ctx->rc_params = (VAEncMiscParameterRateControl) {
1825  .bits_per_second = rc_bits_per_second,
1826  .target_percentage = rc_target_percentage,
1827  .window_size = rc_window_size,
1828  .initial_qp = 0,
1829  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
1830  .basic_unit_size = 0,
1831 #if VA_CHECK_VERSION(1, 1, 0)
1832  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
1833  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
1834 #endif
1835 #if VA_CHECK_VERSION(1, 3, 0)
1836  .quality_factor = rc_quality,
1837 #endif
1838  };
1840  VAEncMiscParameterTypeRateControl,
1841  &ctx->rc_params,
1842  sizeof(ctx->rc_params));
1843  }
1844 
1845  if (rc_mode->hrd) {
1846  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1847  "initial fullness %"PRId64" bits.\n",
1848  hrd_buffer_size, hrd_initial_buffer_fullness);
1849 
1850  ctx->hrd_params = (VAEncMiscParameterHRD) {
1851  .initial_buffer_fullness = hrd_initial_buffer_fullness,
1852  .buffer_size = hrd_buffer_size,
1853  };
1855  VAEncMiscParameterTypeHRD,
1856  &ctx->hrd_params,
1857  sizeof(ctx->hrd_params));
1858  }
1859 
1860  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1861  av_reduce(&fr_num, &fr_den,
1862  avctx->framerate.num, avctx->framerate.den, 65535);
1863  else
1864  av_reduce(&fr_num, &fr_den,
1865  avctx->time_base.den, avctx->time_base.num, 65535);
1866 
1867  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
1868  fr_num, fr_den, (double)fr_num / fr_den);
1869 
1870  ctx->fr_params = (VAEncMiscParameterFrameRate) {
1871  .framerate = (unsigned int)fr_den << 16 | fr_num,
1872  };
1873 #if VA_CHECK_VERSION(0, 40, 0)
1875  VAEncMiscParameterTypeFrameRate,
1876  &ctx->fr_params,
1877  sizeof(ctx->fr_params));
1878 #endif
1879 
1880  return 0;
1881 }
1882 
1884 {
1885 #if VA_CHECK_VERSION(1, 5, 0)
1886  VAAPIEncodeContext *ctx = avctx->priv_data;
1887  VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
1888  VAStatus vas;
1889 
1890  if (ctx->va_rc_mode == VA_RC_CQP) {
1891  ctx->max_frame_size = 0;
1892  av_log(avctx, AV_LOG_ERROR, "Max frame size is invalid in CQP rate "
1893  "control mode.\n");
1894  return AVERROR(EINVAL);
1895  }
1896 
1897  vas = vaGetConfigAttributes(ctx->hwctx->display,
1898  ctx->va_profile,
1899  ctx->va_entrypoint,
1900  &attr, 1);
1901  if (vas != VA_STATUS_SUCCESS) {
1902  ctx->max_frame_size = 0;
1903  av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
1904  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1905  return AVERROR_EXTERNAL;
1906  }
1907 
1908  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1909  ctx->max_frame_size = 0;
1910  av_log(avctx, AV_LOG_ERROR, "Max frame size attribute "
1911  "is not supported.\n");
1912  return AVERROR(EINVAL);
1913  } else {
1914  VAConfigAttribValMaxFrameSize attr_mfs;
1915  attr_mfs.value = attr.value;
1916  // Prefer to use VAEncMiscParameterTypeMaxFrameSize for max frame size.
1917  if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
1918  ctx->max_frame_size = 0;
1919  av_log(avctx, AV_LOG_ERROR, "Driver only supports multiple pass "
1920  "max frame size which has not been implemented in FFmpeg.\n");
1921  return AVERROR(EINVAL);
1922  }
1923 
1924  ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
1925  .max_frame_size = ctx->max_frame_size * 8,
1926  };
1927 
1928  av_log(avctx, AV_LOG_VERBOSE, "Set max frame size: %d bytes.\n",
1929  ctx->max_frame_size);
1930  }
1931 #else
1932  av_log(avctx, AV_LOG_ERROR, "The max frame size option is not supported with "
1933  "this VAAPI version.\n");
1934  return AVERROR(EINVAL);
1935 #endif
1936 
1937  return 0;
1938 }
1939 
1941 {
1942  VAAPIEncodeContext *ctx = avctx->priv_data;
1943  VAStatus vas;
1944  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1945  uint32_t ref_l0, ref_l1;
1946  int prediction_pre_only;
1947 
1948  vas = vaGetConfigAttributes(ctx->hwctx->display,
1949  ctx->va_profile,
1950  ctx->va_entrypoint,
1951  &attr, 1);
1952  if (vas != VA_STATUS_SUCCESS) {
1953  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
1954  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1955  return AVERROR_EXTERNAL;
1956  }
1957 
1958  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1959  ref_l0 = ref_l1 = 0;
1960  } else {
1961  ref_l0 = attr.value & 0xffff;
1962  ref_l1 = attr.value >> 16 & 0xffff;
1963  }
1964 
1965  ctx->p_to_gpb = 0;
1966  prediction_pre_only = 0;
1967 
1968 #if VA_CHECK_VERSION(1, 9, 0)
1969  if (!(ctx->codec->flags & FLAG_INTRA_ONLY ||
1970  avctx->gop_size <= 1)) {
1971  attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
1972  vas = vaGetConfigAttributes(ctx->hwctx->display,
1973  ctx->va_profile,
1974  ctx->va_entrypoint,
1975  &attr, 1);
1976  if (vas != VA_STATUS_SUCCESS) {
1977  av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
1978  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1979  return AVERROR_EXTERNAL;
1980  } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1981  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
1982  "prediction constraints.\n");
1983  } else {
1984  if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
1985  ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
1986  av_log(avctx, AV_LOG_ERROR, "Driver report incorrect prediction "
1987  "direction attribute.\n");
1988  return AVERROR_EXTERNAL;
1989  }
1990 
1991  if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
1992  if (ref_l0 > 0 && ref_l1 > 0) {
1993  prediction_pre_only = 1;
1994  av_log(avctx, AV_LOG_VERBOSE, "Driver only support same reference "
1995  "lists for B-frames.\n");
1996  }
1997  }
1998 
1999  if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
2000  if (ref_l0 > 0 && ref_l1 > 0) {
2001  ctx->p_to_gpb = 1;
2002  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
2003  "replacing them with B-frames.\n");
2004  }
2005  }
2006  }
2007  }
2008 #endif
2009 
2010  if (ctx->codec->flags & FLAG_INTRA_ONLY ||
2011  avctx->gop_size <= 1) {
2012  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
2013  ctx->gop_size = 1;
2014  } else if (ref_l0 < 1) {
2015  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
2016  "reference frames.\n");
2017  return AVERROR(EINVAL);
2018  } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
2019  ref_l1 < 1 || avctx->max_b_frames < 1 ||
2020  prediction_pre_only) {
2021  if (ctx->p_to_gpb)
2022  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2023  "(supported references: %d / %d).\n",
2024  ref_l0, ref_l1);
2025  else
2026  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
2027  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2028  ctx->gop_size = avctx->gop_size;
2029  ctx->p_per_i = INT_MAX;
2030  ctx->b_per_p = 0;
2031  } else {
2032  if (ctx->p_to_gpb)
2033  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2034  "(supported references: %d / %d).\n",
2035  ref_l0, ref_l1);
2036  else
2037  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
2038  "(supported references: %d / %d).\n", ref_l0, ref_l1);
2039  ctx->gop_size = avctx->gop_size;
2040  ctx->p_per_i = INT_MAX;
2041  ctx->b_per_p = avctx->max_b_frames;
2042  if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
2043  ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
2044  av_log2(ctx->b_per_p) + 1);
2045  } else {
2046  ctx->max_b_depth = 1;
2047  }
2048  }
2049 
2050  if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
2051  ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
2052  ctx->gop_per_idr = ctx->idr_interval + 1;
2053  } else {
2054  ctx->closed_gop = 1;
2055  ctx->gop_per_idr = 1;
2056  }
2057 
2058  return 0;
2059 }
2060 
2062  uint32_t slice_structure)
2063 {
2064  VAAPIEncodeContext *ctx = avctx->priv_data;
2065  int req_slices;
2066 
2067  // For fixed-size slices currently we only support whole rows, making
2068  // rectangular slices. This could be extended to arbitrary runs of
2069  // blocks, but since slices tend to be a conformance requirement and
2070  // most cases (such as broadcast or bluray) want rectangular slices
2071  // only it would need to be gated behind another option.
2072  if (avctx->slices > ctx->slice_block_rows) {
2073  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
2074  "configured number of slices (%d < %d); using "
2075  "maximum.\n", ctx->slice_block_rows, avctx->slices);
2076  req_slices = ctx->slice_block_rows;
2077  } else {
2078  req_slices = avctx->slices;
2079  }
2080  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
2081  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
2082  ctx->nb_slices = req_slices;
2083  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
2084  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
2085  int k;
2086  for (k = 1;; k *= 2) {
2087  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
2088  break;
2089  }
2090  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
2091  ctx->slice_size = k;
2092 #if VA_CHECK_VERSION(1, 0, 0)
2093  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
2094  ctx->nb_slices = ctx->slice_block_rows;
2095  ctx->slice_size = 1;
2096 #endif
2097  } else {
2098  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
2099  "slice structure modes (%#x).\n", slice_structure);
2100  return AVERROR(EINVAL);
2101  }
2102 
2103  return 0;
2104 }
2105 
2107  uint32_t slice_structure)
2108 {
2109  VAAPIEncodeContext *ctx = avctx->priv_data;
2110  int i, req_tiles;
2111 
2112  if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
2113  (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
2114  ctx->tile_cols == 1))) {
2115  av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
2116  "current tile requirement.\n", slice_structure);
2117  return AVERROR(EINVAL);
2118  }
2119 
2120  if (ctx->tile_rows > ctx->slice_block_rows ||
2121  ctx->tile_cols > ctx->slice_block_cols) {
2122  av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
2123  "for configured number of tile (%d x %d); ",
2124  ctx->slice_block_rows, ctx->slice_block_cols,
2125  ctx->tile_rows, ctx->tile_cols);
2126  ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
2127  ctx->slice_block_rows : ctx->tile_rows;
2128  ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
2129  ctx->slice_block_cols : ctx->tile_cols;
2130  av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
2131  ctx->tile_rows, ctx->tile_cols);
2132  }
2133 
2134  req_tiles = ctx->tile_rows * ctx->tile_cols;
2135 
2136  // Tile slice is not allowed to cross the boundary of a tile due to
2137  // the constraints of media-driver. Currently we support one slice
2138  // per tile. This could be extended to multiple slices per tile.
2139  if (avctx->slices != req_tiles)
2140  av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
2141  "mismatches with configured number of tile (%d != %d); "
2142  "using requested tile number for slice.\n",
2143  avctx->slices, req_tiles);
2144 
2145  ctx->nb_slices = req_tiles;
2146 
2147  // Default in uniform spacing
2148  // 6-3, 6-5
2149  for (i = 0; i < ctx->tile_cols; i++) {
2150  ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
2151  i * ctx->slice_block_cols / ctx->tile_cols;
2152  ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
2153  }
2154  // 6-4, 6-6
2155  for (i = 0; i < ctx->tile_rows; i++) {
2156  ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
2157  i * ctx->slice_block_rows / ctx->tile_rows;
2158  ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
2159  }
2160 
2161  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
2162  ctx->tile_rows, ctx->tile_cols);
2163 
2164  return 0;
2165 }
2166 
2168 {
2169  VAAPIEncodeContext *ctx = avctx->priv_data;
2170  VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
2171  { VAConfigAttribEncSliceStructure },
2172 #if VA_CHECK_VERSION(1, 1, 0)
2173  { VAConfigAttribEncTileSupport },
2174 #endif
2175  };
2176  VAStatus vas;
2177  uint32_t max_slices, slice_structure;
2178  int ret;
2179 
2180  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
2181  if (avctx->slices > 0) {
2182  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
2183  "but this codec does not support controlling slices.\n");
2184  }
2185  return 0;
2186  }
2187 
2188  av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0);
2189 
2190  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
2191  ctx->slice_block_height;
2192  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
2193  ctx->slice_block_width;
2194 
2195  if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
2196  ctx->nb_slices = 1;
2197  ctx->slice_size = ctx->slice_block_rows;
2198  return 0;
2199  }
2200 
2201  vas = vaGetConfigAttributes(ctx->hwctx->display,
2202  ctx->va_profile,
2203  ctx->va_entrypoint,
2204  attr, FF_ARRAY_ELEMS(attr));
2205  if (vas != VA_STATUS_SUCCESS) {
2206  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
2207  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
2208  return AVERROR_EXTERNAL;
2209  }
2210  max_slices = attr[0].value;
2211  slice_structure = attr[1].value;
2212  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
2213  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
2214  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2215  "pictures as multiple slices.\n.");
2216  return AVERROR(EINVAL);
2217  }
2218 
2219  if (ctx->tile_rows && ctx->tile_cols) {
2220 #if VA_CHECK_VERSION(1, 1, 0)
2221  uint32_t tile_support = attr[2].value;
2222  if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
2223  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2224  "pictures as multiple tiles.\n.");
2225  return AVERROR(EINVAL);
2226  }
2227 #else
2228  av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
2229  "not supported with this VAAPI version.\n");
2230  return AVERROR(EINVAL);
2231 #endif
2232  }
2233 
2234  if (ctx->tile_rows && ctx->tile_cols)
2235  ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
2236  else
2237  ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
2238  if (ret < 0)
2239  return ret;
2240 
2241  if (ctx->nb_slices > avctx->slices) {
2242  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
2243  "%d (from %d) due to driver constraints on slice "
2244  "structure.\n", ctx->nb_slices, avctx->slices);
2245  }
2246  if (ctx->nb_slices > max_slices) {
2247  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
2248  "encoding with %d slices (max %"PRIu32").\n",
2249  ctx->nb_slices, max_slices);
2250  return AVERROR(EINVAL);
2251  }
2252 
2253  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
2254  ctx->nb_slices);
2255  return 0;
2256 }
2257 
2259 {
2260  VAAPIEncodeContext *ctx = avctx->priv_data;
2261  VAStatus vas;
2262  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
2263 
2264  vas = vaGetConfigAttributes(ctx->hwctx->display,
2265  ctx->va_profile,
2266  ctx->va_entrypoint,
2267  &attr, 1);
2268  if (vas != VA_STATUS_SUCCESS) {
2269  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
2270  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2271  return AVERROR_EXTERNAL;
2272  }
2273 
2274  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2275  if (ctx->desired_packed_headers) {
2276  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
2277  "packed headers (wanted %#x).\n",
2278  ctx->desired_packed_headers);
2279  } else {
2280  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
2281  "packed headers (none wanted).\n");
2282  }
2283  ctx->va_packed_headers = 0;
2284  } else {
2285  if (ctx->desired_packed_headers & ~attr.value) {
2286  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
2287  "wanted packed headers (wanted %#x, found %#x).\n",
2288  ctx->desired_packed_headers, attr.value);
2289  } else {
2290  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
2291  "available (wanted %#x, found %#x).\n",
2292  ctx->desired_packed_headers, attr.value);
2293  }
2294  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
2295  }
2296 
2297  if (ctx->va_packed_headers) {
2298  ctx->config_attributes[ctx->nb_config_attributes++] =
2299  (VAConfigAttrib) {
2300  .type = VAConfigAttribEncPackedHeaders,
2301  .value = ctx->va_packed_headers,
2302  };
2303  }
2304 
2305  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2306  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2307  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
2308  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
2309  "sequence headers, but a global header is requested.\n");
2310  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
2311  "this may result in a stream which is not usable for some "
2312  "purposes (e.g. not muxable to some containers).\n");
2313  }
2314 
2315  return 0;
2316 }
2317 
2319 {
2320 #if VA_CHECK_VERSION(0, 36, 0)
2321  VAAPIEncodeContext *ctx = avctx->priv_data;
2322  VAStatus vas;
2323  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
2324  int quality = avctx->compression_level;
2325 
2326  vas = vaGetConfigAttributes(ctx->hwctx->display,
2327  ctx->va_profile,
2328  ctx->va_entrypoint,
2329  &attr, 1);
2330  if (vas != VA_STATUS_SUCCESS) {
2331  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
2332  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2333  return AVERROR_EXTERNAL;
2334  }
2335 
2336  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2337  if (quality != 0) {
2338  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
2339  "supported: will use default quality level.\n");
2340  }
2341  } else {
2342  if (quality > attr.value) {
2343  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
2344  "valid range is 0-%d, using %d.\n",
2345  attr.value, attr.value);
2346  quality = attr.value;
2347  }
2348 
2349  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2350  .quality_level = quality,
2351  };
2353  VAEncMiscParameterTypeQualityLevel,
2354  &ctx->quality_params,
2355  sizeof(ctx->quality_params));
2356  }
2357 #else
2358  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
2359  "not supported with this VAAPI version.\n");
2360 #endif
2361 
2362  return 0;
2363 }
2364 
2366 {
2367 #if VA_CHECK_VERSION(1, 0, 0)
2368  VAAPIEncodeContext *ctx = avctx->priv_data;
2369  VAStatus vas;
2370  VAConfigAttrib attr = { VAConfigAttribEncROI };
2371 
2372  vas = vaGetConfigAttributes(ctx->hwctx->display,
2373  ctx->va_profile,
2374  ctx->va_entrypoint,
2375  &attr, 1);
2376  if (vas != VA_STATUS_SUCCESS) {
2377  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
2378  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2379  return AVERROR_EXTERNAL;
2380  }
2381 
2382  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2383  ctx->roi_allowed = 0;
2384  } else {
2385  VAConfigAttribValEncROI roi = {
2386  .value = attr.value,
2387  };
2388 
2389  ctx->roi_max_regions = roi.bits.num_roi_regions;
2390  ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2391  (ctx->va_rc_mode == VA_RC_CQP ||
2392  roi.bits.roi_rc_qp_delta_support);
2393  }
2394 #endif
2395  return 0;
2396 }
2397 
2398 static void vaapi_encode_free_output_buffer(void *opaque,
2399  uint8_t *data)
2400 {
2401  AVCodecContext *avctx = opaque;
2402  VAAPIEncodeContext *ctx = avctx->priv_data;
2403  VABufferID buffer_id;
2404 
2405  buffer_id = (VABufferID)(uintptr_t)data;
2406 
2407  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2408 
2409  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2410 }
2411 
2413  size_t size)
2414 {
2415  AVCodecContext *avctx = opaque;
2416  VAAPIEncodeContext *ctx = avctx->priv_data;
2417  VABufferID buffer_id;
2418  VAStatus vas;
2419  AVBufferRef *ref;
2420 
2421  // The output buffer size is fixed, so it needs to be large enough
2422  // to hold the largest possible compressed frame. We assume here
2423  // that the uncompressed frame plus some header data is an upper
2424  // bound on that.
2425  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2426  VAEncCodedBufferType,
2427  3 * ctx->surface_width * ctx->surface_height +
2428  (1 << 16), 1, 0, &buffer_id);
2429  if (vas != VA_STATUS_SUCCESS) {
2430  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2431  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2432  return NULL;
2433  }
2434 
2435  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
2436 
2437  ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
2438  sizeof(buffer_id),
2440  avctx, AV_BUFFER_FLAG_READONLY);
2441  if (!ref) {
2442  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2443  return NULL;
2444  }
2445 
2446  return ref;
2447 }
2448 
2450 {
2451  VAAPIEncodeContext *ctx = avctx->priv_data;
2452  AVVAAPIHWConfig *hwconfig = NULL;
2453  AVHWFramesConstraints *constraints = NULL;
2454  enum AVPixelFormat recon_format;
2455  int err, i;
2456 
2457  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
2458  if (!hwconfig) {
2459  err = AVERROR(ENOMEM);
2460  goto fail;
2461  }
2462  hwconfig->config_id = ctx->va_config;
2463 
2464  constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
2465  hwconfig);
2466  if (!constraints) {
2467  err = AVERROR(ENOMEM);
2468  goto fail;
2469  }
2470 
2471  // Probably we can use the input surface format as the surface format
2472  // of the reconstructed frames. If not, we just pick the first (only?)
2473  // format in the valid list and hope that it all works.
2474  recon_format = AV_PIX_FMT_NONE;
2475  if (constraints->valid_sw_formats) {
2476  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
2477  if (ctx->input_frames->sw_format ==
2478  constraints->valid_sw_formats[i]) {
2479  recon_format = ctx->input_frames->sw_format;
2480  break;
2481  }
2482  }
2483  if (recon_format == AV_PIX_FMT_NONE) {
2484  // No match. Just use the first in the supported list and
2485  // hope for the best.
2486  recon_format = constraints->valid_sw_formats[0];
2487  }
2488  } else {
2489  // No idea what to use; copy input format.
2490  recon_format = ctx->input_frames->sw_format;
2491  }
2492  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
2493  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
2494 
2495  if (ctx->surface_width < constraints->min_width ||
2496  ctx->surface_height < constraints->min_height ||
2497  ctx->surface_width > constraints->max_width ||
2498  ctx->surface_height > constraints->max_height) {
2499  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
2500  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2501  ctx->surface_width, ctx->surface_height,
2502  constraints->min_width, constraints->max_width,
2503  constraints->min_height, constraints->max_height);
2504  err = AVERROR(EINVAL);
2505  goto fail;
2506  }
2507 
2508  av_freep(&hwconfig);
2509  av_hwframe_constraints_free(&constraints);
2510 
2511  ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
2512  if (!ctx->recon_frames_ref) {
2513  err = AVERROR(ENOMEM);
2514  goto fail;
2515  }
2516  ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
2517 
2518  ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
2519  ctx->recon_frames->sw_format = recon_format;
2520  ctx->recon_frames->width = ctx->surface_width;
2521  ctx->recon_frames->height = ctx->surface_height;
2522 
2523  err = av_hwframe_ctx_init(ctx->recon_frames_ref);
2524  if (err < 0) {
2525  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2526  "frame context: %d.\n", err);
2527  goto fail;
2528  }
2529 
2530  err = 0;
2531  fail:
2532  av_freep(&hwconfig);
2533  av_hwframe_constraints_free(&constraints);
2534  return err;
2535 }
2536 
2538 {
2539  VAAPIEncodeContext *ctx = avctx->priv_data;
2540  AVVAAPIFramesContext *recon_hwctx = NULL;
2541  VAStatus vas;
2542  int err;
2543 
2544  ctx->va_config = VA_INVALID_ID;
2545  ctx->va_context = VA_INVALID_ID;
2546 
2547  /* If you add something that can fail above this av_frame_alloc(),
2548  * modify ff_vaapi_encode_close() accordingly. */
2549  ctx->frame = av_frame_alloc();
2550  if (!ctx->frame) {
2551  return AVERROR(ENOMEM);
2552  }
2553 
2554  if (!avctx->hw_frames_ctx) {
2555  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
2556  "required to associate the encoding device.\n");
2557  return AVERROR(EINVAL);
2558  }
2559 
2560  ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
2561  if (!ctx->input_frames_ref) {
2562  err = AVERROR(ENOMEM);
2563  goto fail;
2564  }
2565  ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
2566 
2567  ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
2568  if (!ctx->device_ref) {
2569  err = AVERROR(ENOMEM);
2570  goto fail;
2571  }
2572  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
2573  ctx->hwctx = ctx->device->hwctx;
2574 
2575  err = vaapi_encode_profile_entrypoint(avctx);
2576  if (err < 0)
2577  goto fail;
2578 
2579  if (ctx->codec->get_encoder_caps) {
2580  err = ctx->codec->get_encoder_caps(avctx);
2581  if (err < 0)
2582  goto fail;
2583  } else {
2584  // Assume 16x16 blocks.
2585  ctx->surface_width = FFALIGN(avctx->width, 16);
2586  ctx->surface_height = FFALIGN(avctx->height, 16);
2587  if (ctx->codec->flags & FLAG_SLICE_CONTROL) {
2588  ctx->slice_block_width = 16;
2589  ctx->slice_block_height = 16;
2590  }
2591  }
2592 
2593  err = vaapi_encode_init_rate_control(avctx);
2594  if (err < 0)
2595  goto fail;
2596 
2597  err = vaapi_encode_init_gop_structure(avctx);
2598  if (err < 0)
2599  goto fail;
2600 
2601  err = vaapi_encode_init_slice_structure(avctx);
2602  if (err < 0)
2603  goto fail;
2604 
2605  err = vaapi_encode_init_packed_headers(avctx);
2606  if (err < 0)
2607  goto fail;
2608 
2609  err = vaapi_encode_init_roi(avctx);
2610  if (err < 0)
2611  goto fail;
2612 
2613  if (avctx->compression_level >= 0) {
2614  err = vaapi_encode_init_quality(avctx);
2615  if (err < 0)
2616  goto fail;
2617  }
2618 
2619  if (ctx->max_frame_size) {
2620  err = vaapi_encode_init_max_frame_size(avctx);
2621  if (err < 0)
2622  goto fail;
2623  }
2624 
2625  vas = vaCreateConfig(ctx->hwctx->display,
2626  ctx->va_profile, ctx->va_entrypoint,
2627  ctx->config_attributes, ctx->nb_config_attributes,
2628  &ctx->va_config);
2629  if (vas != VA_STATUS_SUCCESS) {
2630  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2631  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2632  err = AVERROR(EIO);
2633  goto fail;
2634  }
2635 
2636  err = vaapi_encode_create_recon_frames(avctx);
2637  if (err < 0)
2638  goto fail;
2639 
2640  recon_hwctx = ctx->recon_frames->hwctx;
2641  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2642  ctx->surface_width, ctx->surface_height,
2643  VA_PROGRESSIVE,
2644  recon_hwctx->surface_ids,
2645  recon_hwctx->nb_surfaces,
2646  &ctx->va_context);
2647  if (vas != VA_STATUS_SUCCESS) {
2648  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2649  "context: %d (%s).\n", vas, vaErrorStr(vas));
2650  err = AVERROR(EIO);
2651  goto fail;
2652  }
2653 
2654  ctx->output_buffer_pool =
2655  av_buffer_pool_init2(sizeof(VABufferID), avctx,
2657  if (!ctx->output_buffer_pool) {
2658  err = AVERROR(ENOMEM);
2659  goto fail;
2660  }
2661 
2662  if (ctx->codec->configure) {
2663  err = ctx->codec->configure(avctx);
2664  if (err < 0)
2665  goto fail;
2666  }
2667 
2668  ctx->output_delay = ctx->b_per_p;
2669  ctx->decode_delay = ctx->max_b_depth;
2670 
2671  if (ctx->codec->sequence_params_size > 0) {
2672  ctx->codec_sequence_params =
2673  av_mallocz(ctx->codec->sequence_params_size);
2674  if (!ctx->codec_sequence_params) {
2675  err = AVERROR(ENOMEM);
2676  goto fail;
2677  }
2678  }
2679  if (ctx->codec->picture_params_size > 0) {
2680  ctx->codec_picture_params =
2681  av_mallocz(ctx->codec->picture_params_size);
2682  if (!ctx->codec_picture_params) {
2683  err = AVERROR(ENOMEM);
2684  goto fail;
2685  }
2686  }
2687 
2688  if (ctx->codec->init_sequence_params) {
2689  err = ctx->codec->init_sequence_params(avctx);
2690  if (err < 0) {
2691  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2692  "failed: %d.\n", err);
2693  goto fail;
2694  }
2695  }
2696 
2697  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2698  ctx->codec->write_sequence_header &&
2701  size_t bit_len = 8 * sizeof(data);
2702 
2703  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2704  if (err < 0) {
2705  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2706  "for extradata: %d.\n", err);
2707  goto fail;
2708  } else {
2709  avctx->extradata_size = (bit_len + 7) / 8;
2710  avctx->extradata = av_mallocz(avctx->extradata_size +
2712  if (!avctx->extradata) {
2713  err = AVERROR(ENOMEM);
2714  goto fail;
2715  }
2716  memcpy(avctx->extradata, data, avctx->extradata_size);
2717  }
2718  }
2719 
2720 #if VA_CHECK_VERSION(1, 9, 0)
2721  // check vaSyncBuffer function
2722  vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2723  if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2724  ctx->has_sync_buffer_func = 1;
2725  ctx->encode_fifo = av_fifo_alloc2(ctx->async_depth,
2726  sizeof(VAAPIEncodePicture *),
2727  0);
2728  if (!ctx->encode_fifo)
2729  return AVERROR(ENOMEM);
2730  }
2731 #endif
2732 
2733  return 0;
2734 
2735 fail:
2736  return err;
2737 }
2738 
2740 {
2741  VAAPIEncodeContext *ctx = avctx->priv_data;
2742  VAAPIEncodePicture *pic, *next;
2743 
2744  /* We check ctx->frame to know whether ff_vaapi_encode_init()
2745  * has been called and va_config/va_context initialized. */
2746  if (!ctx->frame)
2747  return 0;
2748 
2749  for (pic = ctx->pic_start; pic; pic = next) {
2750  next = pic->next;
2751  vaapi_encode_free(avctx, pic);
2752  }
2753 
2754  av_buffer_pool_uninit(&ctx->output_buffer_pool);
2755 
2756  if (ctx->va_context != VA_INVALID_ID) {
2757  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2758  ctx->va_context = VA_INVALID_ID;
2759  }
2760 
2761  if (ctx->va_config != VA_INVALID_ID) {
2762  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2763  ctx->va_config = VA_INVALID_ID;
2764  }
2765 
2766  av_frame_free(&ctx->frame);
2767 
2768  av_freep(&ctx->codec_sequence_params);
2769  av_freep(&ctx->codec_picture_params);
2770  av_fifo_freep2(&ctx->encode_fifo);
2771 
2772  av_buffer_unref(&ctx->recon_frames_ref);
2773  av_buffer_unref(&ctx->input_frames_ref);
2774  av_buffer_unref(&ctx->device_ref);
2775 
2776  return 0;
2777 }
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
level
uint8_t level
Definition: svq3.c:206
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:2365
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
PICTURE_TYPE_I
@ PICTURE_TYPE_I
Definition: vaapi_encode.h:58
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:684
av_clip_int8
#define av_clip_int8
Definition: common.h:104
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
RC_MODE_QVBR
@ RC_MODE_QVBR
Definition: vaapi_encode.h:153
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2662
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:1317
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:111
vaapi_encode_init_slice_structure
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
Definition: vaapi_encode.c:2167
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
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
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
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:143
VAAPIEncodePicture::force_idr
int force_idr
Definition: vaapi_encode.h:78
PICTURE_TYPE_P
@ PICTURE_TYPE_P
Definition: vaapi_encode.h:59
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
ff_vaapi_encode_close
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
Definition: vaapi_encode.c:2739
RC_MODE_CBR
@ RC_MODE_CBR
Definition: vaapi_encode.h:150
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
vaapi_encode_init_rate_control
static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
Definition: vaapi_encode.c:1553
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:1185
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
FLAG_INTRA_ONLY
@ FLAG_INTRA_ONLY
Definition: vaapi_encode.h:371
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
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:274
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:1732
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_PICTURE_REFERENCES
@ MAX_PICTURE_REFERENCES
Definition: vaapi_encode.h:44
MAX_GLOBAL_PARAMS
@ MAX_GLOBAL_PARAMS
Definition: vaapi_encode.h:42
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:1940
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:131
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:469
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:99
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
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:1242
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
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:387
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:491
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:455
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:1331
MAX_PARAM_BUFFER_SIZE
@ MAX_PARAM_BUFFER_SIZE
Definition: vaapi_encode.h:46
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:1548
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
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
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:1214
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:1199
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:439
MAX_DPB_SIZE
@ MAX_DPB_SIZE
Definition: vaapi_encode.h:43
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
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
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:512
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:584
vaapi_encode_init_quality
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
Definition: vaapi_encode.c:2318
FLAG_B_PICTURE_REFERENCES
@ FLAG_B_PICTURE_REFERENCES
Definition: vaapi_encode.h:375
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:1532
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
FLAG_NON_IDR_KEY_PICTURES
@ FLAG_NON_IDR_KEY_PICTURES
Definition: vaapi_encode.h:378
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:2258
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:2449
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:2398
vaapi_encode_check_frame
static int vaapi_encode_check_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: vaapi_encode.c:1092
log.h
RC_MODE_VBR
@ RC_MODE_VBR
Definition: vaapi_encode.h:151
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:490
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_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
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
FLAG_SLICE_CONTROL
@ FLAG_SLICE_CONTROL
Definition: vaapi_encode.h:367
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:506
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
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2005
AVCodecContext::height
int height
Definition: avcodec.h:562
RC_MODE_ICQ
@ RC_MODE_ICQ
Definition: vaapi_encode.h:152
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
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:1880
avcodec.h
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
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:288
ff_vaapi_encode_init
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
Definition: vaapi_encode.c:2537
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
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
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
RC_MODE_AVBR
@ RC_MODE_AVBR
Definition: vaapi_encode.h:154
AVCodecContext
main external API structure.
Definition: avcodec.h:389
RC_MODE_CQP
@ RC_MODE_CQP
Definition: vaapi_encode.h:149
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:1178
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:1547
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
PICTURE_TYPE_B
@ PICTURE_TYPE_B
Definition: vaapi_encode.h:60
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:2106
VAAPIEncodePicture::next
struct VAAPIEncodePicture * next
Definition: vaapi_encode.h:73
desc
const char * desc
Definition: libsvtav1.c:83
FLAG_CONSTANT_QUALITY_ONLY
@ FLAG_CONSTANT_QUALITY_ONLY
Definition: vaapi_encode.h:369
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:661
PICTURE_TYPE_IDR
@ PICTURE_TYPE_IDR
Definition: vaapi_encode.h:57
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:160
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
FLAG_B_PICTURES
@ FLAG_B_PICTURES
Definition: vaapi_encode.h:373
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:2412
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:1332
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:989
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
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:562
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:1883
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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
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
int
int
Definition: ffmpeg_filter.c:153
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:2061
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:2582
AVCodecContext::compression_level
int compression_level
Definition: avcodec.h:461
VAAPIEncodePicture::nb_slices
int nb_slices
Definition: vaapi_encode.h:128