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