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