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