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