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