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