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