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