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  return err;
1105 }
1106 
1108 {
1109  VAAPIEncodeContext *ctx = avctx->priv_data;
1110  VAAPIEncodePicture *pic;
1111  int err;
1112 
1113  if (!ctx->pic_start) {
1114  if (ctx->end_of_stream)
1115  return AVERROR_EOF;
1116  else
1117  return AVERROR(EAGAIN);
1118  }
1119 
1120  pic = NULL;
1121  err = vaapi_encode_pick_next(avctx, &pic);
1122  if (err < 0)
1123  return err;
1124  av_assert0(pic);
1125 
1126  pic->encode_order = ctx->encode_order++;
1127 
1128  err = vaapi_encode_issue(avctx, pic);
1129  if (err < 0) {
1130  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1131  return err;
1132  }
1133 
1134  err = vaapi_encode_output(avctx, pic, pkt);
1135  if (err < 0) {
1136  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
1137  return err;
1138  }
1139 
1140  if (ctx->output_delay == 0) {
1141  pkt->dts = pkt->pts;
1142  } else if (pic->encode_order < ctx->decode_delay) {
1143  if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
1144  pkt->dts = INT64_MIN;
1145  else
1146  pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
1147  } else {
1148  pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
1149  (3 * ctx->output_delay)];
1150  }
1151  av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64" dts %"PRId64".\n",
1152  pkt->pts, pkt->dts);
1153 
1154  ctx->output_order = pic->encode_order;
1155  vaapi_encode_clear_old(avctx);
1156 
1157  return 0;
1158 }
1159 
1160 
1162  void *buffer, size_t size)
1163 {
1164  VAAPIEncodeContext *ctx = avctx->priv_data;
1165 
1167 
1169  ctx->global_params [ctx->nb_global_params] = buffer;
1171 
1172  ++ctx->nb_global_params;
1173 }
1174 
1175 typedef struct VAAPIEncodeRTFormat {
1176  const char *name;
1177  unsigned int value;
1178  int depth;
1183 
1185  { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1186  { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1187  { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1188  { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1189  { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1190 #if VA_CHECK_VERSION(0, 38, 1)
1191  { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1192 #endif
1193 };
1194 
1195 static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
1196  VAEntrypointEncSlice,
1197  VAEntrypointEncPicture,
1198 #if VA_CHECK_VERSION(0, 39, 2)
1199  VAEntrypointEncSliceLP,
1200 #endif
1201  0
1202 };
1203 #if VA_CHECK_VERSION(0, 39, 2)
1204 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1205  VAEntrypointEncSliceLP,
1206  0
1207 };
1208 #endif
1209 
1211 {
1212  VAAPIEncodeContext *ctx = avctx->priv_data;
1213  VAProfile *va_profiles = NULL;
1214  VAEntrypoint *va_entrypoints = NULL;
1215  VAStatus vas;
1216  const VAEntrypoint *usable_entrypoints;
1217  const VAAPIEncodeProfile *profile;
1218  const AVPixFmtDescriptor *desc;
1219  VAConfigAttrib rt_format_attr;
1220  const VAAPIEncodeRTFormat *rt_format;
1221  const char *profile_string, *entrypoint_string;
1222  int i, j, n, depth, err;
1223 
1224 
1225  if (ctx->low_power) {
1226 #if VA_CHECK_VERSION(0, 39, 2)
1227  usable_entrypoints = vaapi_encode_entrypoints_low_power;
1228 #else
1229  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
1230  "supported with this VAAPI version.\n");
1231  return AVERROR(EINVAL);
1232 #endif
1233  } else {
1234  usable_entrypoints = vaapi_encode_entrypoints_normal;
1235  }
1236 
1238  if (!desc) {
1239  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
1240  ctx->input_frames->sw_format);
1241  return AVERROR(EINVAL);
1242  }
1243  depth = desc->comp[0].depth;
1244  for (i = 1; i < desc->nb_components; i++) {
1245  if (desc->comp[i].depth != depth) {
1246  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
1247  desc->name);
1248  return AVERROR(EINVAL);
1249  }
1250  }
1251  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
1252  desc->name);
1253 
1254  n = vaMaxNumProfiles(ctx->hwctx->display);
1255  va_profiles = av_malloc_array(n, sizeof(VAProfile));
1256  if (!va_profiles) {
1257  err = AVERROR(ENOMEM);
1258  goto fail;
1259  }
1260  vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
1261  if (vas != VA_STATUS_SUCCESS) {
1262  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
1263  vas, vaErrorStr(vas));
1264  err = AVERROR_EXTERNAL;
1265  goto fail;
1266  }
1267 
1268  av_assert0(ctx->codec->profiles);
1269  for (i = 0; (ctx->codec->profiles[i].av_profile !=
1270  FF_PROFILE_UNKNOWN); i++) {
1271  profile = &ctx->codec->profiles[i];
1272  if (depth != profile->depth ||
1273  desc->nb_components != profile->nb_components)
1274  continue;
1275  if (desc->nb_components > 1 &&
1276  (desc->log2_chroma_w != profile->log2_chroma_w ||
1277  desc->log2_chroma_h != profile->log2_chroma_h))
1278  continue;
1279  if (avctx->profile != profile->av_profile &&
1280  avctx->profile != FF_PROFILE_UNKNOWN)
1281  continue;
1282 
1283 #if VA_CHECK_VERSION(1, 0, 0)
1284  profile_string = vaProfileStr(profile->va_profile);
1285 #else
1286  profile_string = "(no profile names)";
1287 #endif
1288 
1289  for (j = 0; j < n; j++) {
1290  if (va_profiles[j] == profile->va_profile)
1291  break;
1292  }
1293  if (j >= n) {
1294  av_log(avctx, AV_LOG_VERBOSE, "Compatible profile %s (%d) "
1295  "is not supported by driver.\n", profile_string,
1296  profile->va_profile);
1297  continue;
1298  }
1299 
1300  ctx->profile = profile;
1301  break;
1302  }
1303  if (!ctx->profile) {
1304  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1305  err = AVERROR(ENOSYS);
1306  goto fail;
1307  }
1308 
1309  avctx->profile = profile->av_profile;
1310  ctx->va_profile = profile->va_profile;
1311  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1312  profile_string, ctx->va_profile);
1313 
1314  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1315  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1316  if (!va_entrypoints) {
1317  err = AVERROR(ENOMEM);
1318  goto fail;
1319  }
1320  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1321  va_entrypoints, &n);
1322  if (vas != VA_STATUS_SUCCESS) {
1323  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1324  "profile %s (%d): %d (%s).\n", profile_string,
1325  ctx->va_profile, vas, vaErrorStr(vas));
1326  err = AVERROR_EXTERNAL;
1327  goto fail;
1328  }
1329 
1330  for (i = 0; i < n; i++) {
1331  for (j = 0; usable_entrypoints[j]; j++) {
1332  if (va_entrypoints[i] == usable_entrypoints[j])
1333  break;
1334  }
1335  if (usable_entrypoints[j])
1336  break;
1337  }
1338  if (i >= n) {
1339  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1340  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1341  err = AVERROR(ENOSYS);
1342  goto fail;
1343  }
1344 
1345  ctx->va_entrypoint = va_entrypoints[i];
1346 #if VA_CHECK_VERSION(1, 0, 0)
1347  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1348 #else
1349  entrypoint_string = "(no entrypoint names)";
1350 #endif
1351  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1352  entrypoint_string, ctx->va_entrypoint);
1353 
1354  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1355  rt_format = &vaapi_encode_rt_formats[i];
1356  if (rt_format->depth == depth &&
1357  rt_format->nb_components == profile->nb_components &&
1358  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1359  rt_format->log2_chroma_h == profile->log2_chroma_h)
1360  break;
1361  }
1362  if (i >= FF_ARRAY_ELEMS(vaapi_encode_rt_formats)) {
1363  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1364  "found for profile %s (%d) entrypoint %s (%d).\n",
1365  profile_string, ctx->va_profile,
1366  entrypoint_string, ctx->va_entrypoint);
1367  err = AVERROR(ENOSYS);
1368  goto fail;
1369  }
1370 
1371  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1372  vas = vaGetConfigAttributes(ctx->hwctx->display,
1373  ctx->va_profile, ctx->va_entrypoint,
1374  &rt_format_attr, 1);
1375  if (vas != VA_STATUS_SUCCESS) {
1376  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1377  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1378  err = AVERROR_EXTERNAL;
1379  goto fail;
1380  }
1381 
1382  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1383  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1384  "supported by driver: assuming surface RT format %s "
1385  "is valid.\n", rt_format->name);
1386  } else if (!(rt_format_attr.value & rt_format->value)) {
1387  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1388  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1389  rt_format->name, profile_string, ctx->va_profile,
1390  entrypoint_string, ctx->va_entrypoint);
1391  err = AVERROR(ENOSYS);
1392  goto fail;
1393  } else {
1394  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1395  "format %s (%#x).\n", rt_format->name, rt_format->value);
1397  (VAConfigAttrib) {
1398  .type = VAConfigAttribRTFormat,
1399  .value = rt_format->value,
1400  };
1401  }
1402 
1403  err = 0;
1404 fail:
1405  av_freep(&va_profiles);
1406  av_freep(&va_entrypoints);
1407  return err;
1408 }
1409 
1411  // Bitrate Quality
1412  // | Maxrate | HRD/VBV
1413  { 0 }, // | | | |
1414  { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
1415  { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
1416  { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
1417 #if VA_CHECK_VERSION(1, 1, 0)
1418  { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
1419 #else
1420  { RC_MODE_ICQ, "ICQ", 0 },
1421 #endif
1422 #if VA_CHECK_VERSION(1, 3, 0)
1423  { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
1424  { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
1425 #else
1426  { RC_MODE_QVBR, "QVBR", 0 },
1427  { RC_MODE_AVBR, "AVBR", 0 },
1428 #endif
1429 };
1430 
1432 {
1433  VAAPIEncodeContext *ctx = avctx->priv_data;
1434  uint32_t supported_va_rc_modes;
1435  const VAAPIEncodeRCMode *rc_mode;
1436  int64_t rc_bits_per_second;
1437  int rc_target_percentage;
1438  int rc_window_size;
1439  int rc_quality;
1440  int64_t hrd_buffer_size;
1441  int64_t hrd_initial_buffer_fullness;
1442  int fr_num, fr_den;
1443  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1444  VAStatus vas;
1445  char supported_rc_modes_string[64];
1446 
1447  vas = vaGetConfigAttributes(ctx->hwctx->display,
1448  ctx->va_profile, ctx->va_entrypoint,
1449  &rc_attr, 1);
1450  if (vas != VA_STATUS_SUCCESS) {
1451  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1452  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1453  return AVERROR_EXTERNAL;
1454  }
1455  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1456  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1457  "supported rate control modes: assuming CQP only.\n");
1458  supported_va_rc_modes = VA_RC_CQP;
1459  strcpy(supported_rc_modes_string, "unknown");
1460  } else {
1461  char *str = supported_rc_modes_string;
1462  size_t len = sizeof(supported_rc_modes_string);
1463  int i, first = 1, res;
1464 
1465  supported_va_rc_modes = rc_attr.value;
1466  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
1467  rc_mode = &vaapi_encode_rc_modes[i];
1468  if (supported_va_rc_modes & rc_mode->va_mode) {
1469  res = snprintf(str, len, "%s%s",
1470  first ? "" : ", ", rc_mode->name);
1471  first = 0;
1472  if (res < 0) {
1473  *str = 0;
1474  break;
1475  }
1476  len -= res;
1477  str += res;
1478  if (len == 0)
1479  break;
1480  }
1481  }
1482 
1483  av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
1484  supported_rc_modes_string);
1485  }
1486 
1487  // Rate control mode selection:
1488  // * If the user has set a mode explicitly with the rc_mode option,
1489  // use it and fail if it is not available.
1490  // * If an explicit QP option has been set, use CQP.
1491  // * If the codec is CQ-only, use CQP.
1492  // * If the QSCALE avcodec option is set, use CQP.
1493  // * If bitrate and quality are both set, try QVBR.
1494  // * If quality is set, try ICQ, then CQP.
1495  // * If bitrate and maxrate are set and have the same value, try CBR.
1496  // * If a bitrate is set, try AVBR, then VBR, then CBR.
1497  // * If no bitrate is set, try ICQ, then CQP.
1498 
1499 #define TRY_RC_MODE(mode, fail) do { \
1500  rc_mode = &vaapi_encode_rc_modes[mode]; \
1501  if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1502  if (fail) { \
1503  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1504  "RC mode (supported modes: %s).\n", rc_mode->name, \
1505  supported_rc_modes_string); \
1506  return AVERROR(EINVAL); \
1507  } \
1508  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1509  "RC mode.\n", rc_mode->name); \
1510  rc_mode = NULL; \
1511  } else { \
1512  goto rc_mode_found; \
1513  } \
1514  } while (0)
1515 
1516  if (ctx->explicit_rc_mode)
1517  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
1518 
1519  if (ctx->explicit_qp)
1521 
1524 
1525  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
1527 
1528  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
1530 
1531  if (avctx->global_quality > 0) {
1534  }
1535 
1536  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
1538 
1539  if (avctx->bit_rate > 0) {
1543  } else {
1546  }
1547 
1548  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1549  "RC mode compatible with selected options "
1550  "(supported modes: %s).\n", supported_rc_modes_string);
1551  return AVERROR(EINVAL);
1552 
1553 rc_mode_found:
1554  if (rc_mode->bitrate) {
1555  if (avctx->bit_rate <= 0) {
1556  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
1557  "RC mode.\n", rc_mode->name);
1558  return AVERROR(EINVAL);
1559  }
1560 
1561  if (rc_mode->mode == RC_MODE_AVBR) {
1562  // For maximum confusion AVBR is hacked into the existing API
1563  // by overloading some of the fields with completely different
1564  // meanings.
1565 
1566  // Target percentage does not apply in AVBR mode.
1567  rc_bits_per_second = avctx->bit_rate;
1568 
1569  // Accuracy tolerance range for meeting the specified target
1570  // bitrate. It's very unclear how this is actually intended
1571  // to work - since we do want to get the specified bitrate,
1572  // set the accuracy to 100% for now.
1573  rc_target_percentage = 100;
1574 
1575  // Convergence period in frames. The GOP size reflects the
1576  // user's intended block size for cutting, so reusing that
1577  // as the convergence period seems a reasonable default.
1578  rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
1579 
1580  } else if (rc_mode->maxrate) {
1581  if (avctx->rc_max_rate > 0) {
1582  if (avctx->rc_max_rate < avctx->bit_rate) {
1583  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
1584  "bitrate (%"PRId64") must not be greater than "
1585  "maxrate (%"PRId64").\n", avctx->bit_rate,
1586  avctx->rc_max_rate);
1587  return AVERROR(EINVAL);
1588  }
1589  rc_bits_per_second = avctx->rc_max_rate;
1590  rc_target_percentage = (avctx->bit_rate * 100) /
1591  avctx->rc_max_rate;
1592  } else {
1593  // We only have a target bitrate, but this mode requires
1594  // that a maximum rate be supplied as well. Since the
1595  // user does not want this to be a constraint, arbitrarily
1596  // pick a maximum rate of double the target rate.
1597  rc_bits_per_second = 2 * avctx->bit_rate;
1598  rc_target_percentage = 50;
1599  }
1600  } else {
1601  if (avctx->rc_max_rate > avctx->bit_rate) {
1602  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
1603  "in %s RC mode.\n", rc_mode->name);
1604  }
1605  rc_bits_per_second = avctx->bit_rate;
1606  rc_target_percentage = 100;
1607  }
1608  } else {
1609  rc_bits_per_second = 0;
1610  rc_target_percentage = 100;
1611  }
1612 
1613  if (rc_mode->quality) {
1614  if (ctx->explicit_qp) {
1615  rc_quality = ctx->explicit_qp;
1616  } else if (avctx->global_quality > 0) {
1617  rc_quality = avctx->global_quality;
1618  } else {
1619  rc_quality = ctx->codec->default_quality;
1620  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
1621  "using default (%d).\n", rc_quality);
1622  }
1623  } else {
1624  rc_quality = 0;
1625  }
1626 
1627  if (rc_mode->hrd) {
1628  if (avctx->rc_buffer_size)
1629  hrd_buffer_size = avctx->rc_buffer_size;
1630  else if (avctx->rc_max_rate > 0)
1631  hrd_buffer_size = avctx->rc_max_rate;
1632  else
1633  hrd_buffer_size = avctx->bit_rate;
1634  if (avctx->rc_initial_buffer_occupancy) {
1635  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1636  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1637  "must have initial buffer size (%d) <= "
1638  "buffer size (%"PRId64").\n",
1639  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1640  return AVERROR(EINVAL);
1641  }
1642  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1643  } else {
1644  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1645  }
1646 
1647  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1648  } else {
1649  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
1650  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
1651  "in %s RC mode.\n", rc_mode->name);
1652  }
1653 
1654  hrd_buffer_size = 0;
1655  hrd_initial_buffer_fullness = 0;
1656 
1657  if (rc_mode->mode != RC_MODE_AVBR) {
1658  // Already set (with completely different meaning) for AVBR.
1659  rc_window_size = 1000;
1660  }
1661  }
1662 
1663  if (rc_bits_per_second > UINT32_MAX ||
1664  hrd_buffer_size > UINT32_MAX ||
1665  hrd_initial_buffer_fullness > UINT32_MAX) {
1666  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1667  "greater are not supported by VAAPI.\n");
1668  return AVERROR(EINVAL);
1669  }
1670 
1671  ctx->rc_mode = rc_mode;
1672  ctx->rc_quality = rc_quality;
1673  ctx->va_rc_mode = rc_mode->va_mode;
1674  ctx->va_bit_rate = rc_bits_per_second;
1675 
1676  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
1677  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1678  // This driver does not want the RC mode attribute to be set.
1679  } else {
1681  (VAConfigAttrib) {
1682  .type = VAConfigAttribRateControl,
1683  .value = ctx->va_rc_mode,
1684  };
1685  }
1686 
1687  if (rc_mode->quality)
1688  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
1689 
1690  if (rc_mode->va_mode != VA_RC_CQP) {
1691  if (rc_mode->mode == RC_MODE_AVBR) {
1692  av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
1693  "converging in %d frames with %d%% accuracy.\n",
1694  rc_bits_per_second, rc_window_size,
1695  rc_target_percentage);
1696  } else if (rc_mode->bitrate) {
1697  av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
1698  "%"PRId64" bps over %d ms.\n", rc_target_percentage,
1699  rc_bits_per_second, rc_window_size);
1700  }
1701 
1702  ctx->rc_params = (VAEncMiscParameterRateControl) {
1703  .bits_per_second = rc_bits_per_second,
1704  .target_percentage = rc_target_percentage,
1705  .window_size = rc_window_size,
1706  .initial_qp = 0,
1707  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
1708  .basic_unit_size = 0,
1709 #if VA_CHECK_VERSION(1, 1, 0)
1710  .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
1711  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
1712 #endif
1713 #if VA_CHECK_VERSION(1, 3, 0)
1714  .quality_factor = rc_quality,
1715 #endif
1716  };
1718  VAEncMiscParameterTypeRateControl,
1719  &ctx->rc_params,
1720  sizeof(ctx->rc_params));
1721  }
1722 
1723  if (rc_mode->hrd) {
1724  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1725  "initial fullness %"PRId64" bits.\n",
1726  hrd_buffer_size, hrd_initial_buffer_fullness);
1727 
1728  ctx->hrd_params = (VAEncMiscParameterHRD) {
1729  .initial_buffer_fullness = hrd_initial_buffer_fullness,
1730  .buffer_size = hrd_buffer_size,
1731  };
1733  VAEncMiscParameterTypeHRD,
1734  &ctx->hrd_params,
1735  sizeof(ctx->hrd_params));
1736  }
1737 
1738  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1739  av_reduce(&fr_num, &fr_den,
1740  avctx->framerate.num, avctx->framerate.den, 65535);
1741  else
1742  av_reduce(&fr_num, &fr_den,
1743  avctx->time_base.den, avctx->time_base.num, 65535);
1744 
1745  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
1746  fr_num, fr_den, (double)fr_num / fr_den);
1747 
1748  ctx->fr_params = (VAEncMiscParameterFrameRate) {
1749  .framerate = (unsigned int)fr_den << 16 | fr_num,
1750  };
1751 #if VA_CHECK_VERSION(0, 40, 0)
1753  VAEncMiscParameterTypeFrameRate,
1754  &ctx->fr_params,
1755  sizeof(ctx->fr_params));
1756 #endif
1757 
1758  return 0;
1759 }
1760 
1762 {
1763  VAAPIEncodeContext *ctx = avctx->priv_data;
1764  VAStatus vas;
1765  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1766  uint32_t ref_l0, ref_l1;
1767 
1768  vas = vaGetConfigAttributes(ctx->hwctx->display,
1769  ctx->va_profile,
1770  ctx->va_entrypoint,
1771  &attr, 1);
1772  if (vas != VA_STATUS_SUCCESS) {
1773  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
1774  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1775  return AVERROR_EXTERNAL;
1776  }
1777 
1778  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1779  ref_l0 = ref_l1 = 0;
1780  } else {
1781  ref_l0 = attr.value & 0xffff;
1782  ref_l1 = attr.value >> 16 & 0xffff;
1783  }
1784 
1785  if (ctx->codec->flags & FLAG_INTRA_ONLY ||
1786  avctx->gop_size <= 1) {
1787  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
1788  ctx->gop_size = 1;
1789  } else if (ref_l0 < 1) {
1790  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1791  "reference frames.\n");
1792  return AVERROR(EINVAL);
1793  } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
1794  ref_l1 < 1 || avctx->max_b_frames < 1) {
1795  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
1796  "(supported references: %d / %d).\n", ref_l0, ref_l1);
1797  ctx->gop_size = avctx->gop_size;
1798  ctx->p_per_i = INT_MAX;
1799  ctx->b_per_p = 0;
1800  } else {
1801  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
1802  "(supported references: %d / %d).\n", ref_l0, ref_l1);
1803  ctx->gop_size = avctx->gop_size;
1804  ctx->p_per_i = INT_MAX;
1805  ctx->b_per_p = avctx->max_b_frames;
1806  if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
1807  ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
1808  av_log2(ctx->b_per_p) + 1);
1809  } else {
1810  ctx->max_b_depth = 1;
1811  }
1812  }
1813 
1814  if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
1815  ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
1816  ctx->gop_per_idr = ctx->idr_interval + 1;
1817  } else {
1818  ctx->closed_gop = 1;
1819  ctx->gop_per_idr = 1;
1820  }
1821 
1822  return 0;
1823 }
1824 
1826 {
1827  VAAPIEncodeContext *ctx = avctx->priv_data;
1828  VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
1829  { VAConfigAttribEncSliceStructure } };
1830  VAStatus vas;
1831  uint32_t max_slices, slice_structure;
1832  int req_slices;
1833 
1834  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
1835  if (avctx->slices > 0) {
1836  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
1837  "but this codec does not support controlling slices.\n");
1838  }
1839  return 0;
1840  }
1841 
1842  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
1843  ctx->slice_block_height;
1844  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
1845  ctx->slice_block_width;
1846 
1847  if (avctx->slices <= 1) {
1848  ctx->nb_slices = 1;
1849  ctx->slice_size = ctx->slice_block_rows;
1850  return 0;
1851  }
1852 
1853  vas = vaGetConfigAttributes(ctx->hwctx->display,
1854  ctx->va_profile,
1855  ctx->va_entrypoint,
1856  attr, FF_ARRAY_ELEMS(attr));
1857  if (vas != VA_STATUS_SUCCESS) {
1858  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
1859  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1860  return AVERROR_EXTERNAL;
1861  }
1862  max_slices = attr[0].value;
1863  slice_structure = attr[1].value;
1864  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1865  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1866  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1867  "pictures as multiple slices.\n.");
1868  return AVERROR(EINVAL);
1869  }
1870 
1871  // For fixed-size slices currently we only support whole rows, making
1872  // rectangular slices. This could be extended to arbitrary runs of
1873  // blocks, but since slices tend to be a conformance requirement and
1874  // most cases (such as broadcast or bluray) want rectangular slices
1875  // only it would need to be gated behind another option.
1876  if (avctx->slices > ctx->slice_block_rows) {
1877  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1878  "configured number of slices (%d < %d); using "
1879  "maximum.\n", ctx->slice_block_rows, avctx->slices);
1880  req_slices = ctx->slice_block_rows;
1881  } else {
1882  req_slices = avctx->slices;
1883  }
1884  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1885  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1886  ctx->nb_slices = req_slices;
1887  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1888  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1889  int k;
1890  for (k = 1;; k *= 2) {
1891  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1892  break;
1893  }
1894  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1895  ctx->slice_size = k;
1896 #if VA_CHECK_VERSION(1, 0, 0)
1897  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1898  ctx->nb_slices = ctx->slice_block_rows;
1899  ctx->slice_size = 1;
1900 #endif
1901  } else {
1902  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1903  "slice structure modes (%#x).\n", slice_structure);
1904  return AVERROR(EINVAL);
1905  }
1906 
1907  if (ctx->nb_slices > avctx->slices) {
1908  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
1909  "%d (from %d) due to driver constraints on slice "
1910  "structure.\n", ctx->nb_slices, avctx->slices);
1911  }
1912  if (ctx->nb_slices > max_slices) {
1913  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1914  "encoding with %d slices (max %"PRIu32").\n",
1915  ctx->nb_slices, max_slices);
1916  return AVERROR(EINVAL);
1917  }
1918 
1919  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices "
1920  "(default size %d block rows).\n",
1921  ctx->nb_slices, ctx->slice_size);
1922  return 0;
1923 }
1924 
1926 {
1927  VAAPIEncodeContext *ctx = avctx->priv_data;
1928  VAStatus vas;
1929  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1930 
1931  vas = vaGetConfigAttributes(ctx->hwctx->display,
1932  ctx->va_profile,
1933  ctx->va_entrypoint,
1934  &attr, 1);
1935  if (vas != VA_STATUS_SUCCESS) {
1936  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
1937  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1938  return AVERROR_EXTERNAL;
1939  }
1940 
1941  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1942  if (ctx->desired_packed_headers) {
1943  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
1944  "packed headers (wanted %#x).\n",
1945  ctx->desired_packed_headers);
1946  } else {
1947  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
1948  "packed headers (none wanted).\n");
1949  }
1950  ctx->va_packed_headers = 0;
1951  } else {
1952  if (ctx->desired_packed_headers & ~attr.value) {
1953  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
1954  "wanted packed headers (wanted %#x, found %#x).\n",
1955  ctx->desired_packed_headers, attr.value);
1956  } else {
1957  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
1958  "available (wanted %#x, found %#x).\n",
1959  ctx->desired_packed_headers, attr.value);
1960  }
1961  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
1962  }
1963 
1964  if (ctx->va_packed_headers) {
1966  (VAConfigAttrib) {
1967  .type = VAConfigAttribEncPackedHeaders,
1968  .value = ctx->va_packed_headers,
1969  };
1970  }
1971 
1972  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1973  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1974  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
1975  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
1976  "sequence headers, but a global header is requested.\n");
1977  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
1978  "this may result in a stream which is not usable for some "
1979  "purposes (e.g. not muxable to some containers).\n");
1980  }
1981 
1982  return 0;
1983 }
1984 
1986 {
1987 #if VA_CHECK_VERSION(0, 36, 0)
1988  VAAPIEncodeContext *ctx = avctx->priv_data;
1989  VAStatus vas;
1990  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1991  int quality = avctx->compression_level;
1992 
1993  vas = vaGetConfigAttributes(ctx->hwctx->display,
1994  ctx->va_profile,
1995  ctx->va_entrypoint,
1996  &attr, 1);
1997  if (vas != VA_STATUS_SUCCESS) {
1998  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
1999  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2000  return AVERROR_EXTERNAL;
2001  }
2002 
2003  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2004  if (quality != 0) {
2005  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
2006  "supported: will use default quality level.\n");
2007  }
2008  } else {
2009  if (quality > attr.value) {
2010  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
2011  "valid range is 0-%d, using %d.\n",
2012  attr.value, attr.value);
2013  quality = attr.value;
2014  }
2015 
2016  ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2017  .quality_level = quality,
2018  };
2020  VAEncMiscParameterTypeQualityLevel,
2021  &ctx->quality_params,
2022  sizeof(ctx->quality_params));
2023  }
2024 #else
2025  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
2026  "not supported with this VAAPI version.\n");
2027 #endif
2028 
2029  return 0;
2030 }
2031 
2033 {
2034 #if VA_CHECK_VERSION(1, 0, 0)
2035  VAAPIEncodeContext *ctx = avctx->priv_data;
2036  VAStatus vas;
2037  VAConfigAttrib attr = { VAConfigAttribEncROI };
2038 
2039  vas = vaGetConfigAttributes(ctx->hwctx->display,
2040  ctx->va_profile,
2041  ctx->va_entrypoint,
2042  &attr, 1);
2043  if (vas != VA_STATUS_SUCCESS) {
2044  av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
2045  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2046  return AVERROR_EXTERNAL;
2047  }
2048 
2049  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2050  ctx->roi_allowed = 0;
2051  } else {
2052  VAConfigAttribValEncROI roi = {
2053  .value = attr.value,
2054  };
2055 
2056  ctx->roi_max_regions = roi.bits.num_roi_regions;
2057  ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2058  (ctx->va_rc_mode == VA_RC_CQP ||
2059  roi.bits.roi_rc_qp_delta_support);
2060  }
2061 #endif
2062  return 0;
2063 }
2064 
2065 static void vaapi_encode_free_output_buffer(void *opaque,
2066  uint8_t *data)
2067 {
2068  AVCodecContext *avctx = opaque;
2069  VAAPIEncodeContext *ctx = avctx->priv_data;
2070  VABufferID buffer_id;
2071 
2072  buffer_id = (VABufferID)(uintptr_t)data;
2073 
2074  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2075 
2076  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
2077 }
2078 
2080  int size)
2081 {
2082  AVCodecContext *avctx = opaque;
2083  VAAPIEncodeContext *ctx = avctx->priv_data;
2084  VABufferID buffer_id;
2085  VAStatus vas;
2086  AVBufferRef *ref;
2087 
2088  // The output buffer size is fixed, so it needs to be large enough
2089  // to hold the largest possible compressed frame. We assume here
2090  // that the uncompressed frame plus some header data is an upper
2091  // bound on that.
2092  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
2093  VAEncCodedBufferType,
2094  3 * ctx->surface_width * ctx->surface_height +
2095  (1 << 16), 1, 0, &buffer_id);
2096  if (vas != VA_STATUS_SUCCESS) {
2097  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
2098  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2099  return NULL;
2100  }
2101 
2102  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
2103 
2104  ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
2105  sizeof(buffer_id),
2107  avctx, AV_BUFFER_FLAG_READONLY);
2108  if (!ref) {
2109  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
2110  return NULL;
2111  }
2112 
2113  return ref;
2114 }
2115 
2117 {
2118  VAAPIEncodeContext *ctx = avctx->priv_data;
2119  AVVAAPIHWConfig *hwconfig = NULL;
2120  AVHWFramesConstraints *constraints = NULL;
2121  enum AVPixelFormat recon_format;
2122  int err, i;
2123 
2124  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
2125  if (!hwconfig) {
2126  err = AVERROR(ENOMEM);
2127  goto fail;
2128  }
2129  hwconfig->config_id = ctx->va_config;
2130 
2132  hwconfig);
2133  if (!constraints) {
2134  err = AVERROR(ENOMEM);
2135  goto fail;
2136  }
2137 
2138  // Probably we can use the input surface format as the surface format
2139  // of the reconstructed frames. If not, we just pick the first (only?)
2140  // format in the valid list and hope that it all works.
2141  recon_format = AV_PIX_FMT_NONE;
2142  if (constraints->valid_sw_formats) {
2143  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
2144  if (ctx->input_frames->sw_format ==
2145  constraints->valid_sw_formats[i]) {
2146  recon_format = ctx->input_frames->sw_format;
2147  break;
2148  }
2149  }
2150  if (recon_format == AV_PIX_FMT_NONE) {
2151  // No match. Just use the first in the supported list and
2152  // hope for the best.
2153  recon_format = constraints->valid_sw_formats[0];
2154  }
2155  } else {
2156  // No idea what to use; copy input format.
2157  recon_format = ctx->input_frames->sw_format;
2158  }
2159  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
2160  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
2161 
2162  if (ctx->surface_width < constraints->min_width ||
2163  ctx->surface_height < constraints->min_height ||
2164  ctx->surface_width > constraints->max_width ||
2165  ctx->surface_height > constraints->max_height) {
2166  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
2167  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2168  ctx->surface_width, ctx->surface_height,
2169  constraints->min_width, constraints->max_width,
2170  constraints->min_height, constraints->max_height);
2171  err = AVERROR(EINVAL);
2172  goto fail;
2173  }
2174 
2175  av_freep(&hwconfig);
2176  av_hwframe_constraints_free(&constraints);
2177 
2179  if (!ctx->recon_frames_ref) {
2180  err = AVERROR(ENOMEM);
2181  goto fail;
2182  }
2184 
2186  ctx->recon_frames->sw_format = recon_format;
2187  ctx->recon_frames->width = ctx->surface_width;
2188  ctx->recon_frames->height = ctx->surface_height;
2189 
2191  if (err < 0) {
2192  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
2193  "frame context: %d.\n", err);
2194  goto fail;
2195  }
2196 
2197  err = 0;
2198  fail:
2199  av_freep(&hwconfig);
2200  av_hwframe_constraints_free(&constraints);
2201  return err;
2202 }
2203 
2205 {
2206  VAAPIEncodeContext *ctx = avctx->priv_data;
2207  AVVAAPIFramesContext *recon_hwctx = NULL;
2208  VAStatus vas;
2209  int err;
2210 
2211  if (!avctx->hw_frames_ctx) {
2212  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
2213  "required to associate the encoding device.\n");
2214  return AVERROR(EINVAL);
2215  }
2216 
2217  ctx->va_config = VA_INVALID_ID;
2218  ctx->va_context = VA_INVALID_ID;
2219 
2221  if (!ctx->input_frames_ref) {
2222  err = AVERROR(ENOMEM);
2223  goto fail;
2224  }
2226 
2228  if (!ctx->device_ref) {
2229  err = AVERROR(ENOMEM);
2230  goto fail;
2231  }
2232  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
2233  ctx->hwctx = ctx->device->hwctx;
2234 
2235  err = vaapi_encode_profile_entrypoint(avctx);
2236  if (err < 0)
2237  goto fail;
2238 
2239  err = vaapi_encode_init_rate_control(avctx);
2240  if (err < 0)
2241  goto fail;
2242 
2243  err = vaapi_encode_init_gop_structure(avctx);
2244  if (err < 0)
2245  goto fail;
2246 
2247  err = vaapi_encode_init_slice_structure(avctx);
2248  if (err < 0)
2249  goto fail;
2250 
2251  err = vaapi_encode_init_packed_headers(avctx);
2252  if (err < 0)
2253  goto fail;
2254 
2255  err = vaapi_encode_init_roi(avctx);
2256  if (err < 0)
2257  goto fail;
2258 
2259  if (avctx->compression_level >= 0) {
2260  err = vaapi_encode_init_quality(avctx);
2261  if (err < 0)
2262  goto fail;
2263  }
2264 
2265  vas = vaCreateConfig(ctx->hwctx->display,
2266  ctx->va_profile, ctx->va_entrypoint,
2268  &ctx->va_config);
2269  if (vas != VA_STATUS_SUCCESS) {
2270  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2271  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2272  err = AVERROR(EIO);
2273  goto fail;
2274  }
2275 
2276  err = vaapi_encode_create_recon_frames(avctx);
2277  if (err < 0)
2278  goto fail;
2279 
2280  recon_hwctx = ctx->recon_frames->hwctx;
2281  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
2282  ctx->surface_width, ctx->surface_height,
2283  VA_PROGRESSIVE,
2284  recon_hwctx->surface_ids,
2285  recon_hwctx->nb_surfaces,
2286  &ctx->va_context);
2287  if (vas != VA_STATUS_SUCCESS) {
2288  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
2289  "context: %d (%s).\n", vas, vaErrorStr(vas));
2290  err = AVERROR(EIO);
2291  goto fail;
2292  }
2293 
2294  ctx->output_buffer_pool =
2295  av_buffer_pool_init2(sizeof(VABufferID), avctx,
2297  if (!ctx->output_buffer_pool) {
2298  err = AVERROR(ENOMEM);
2299  goto fail;
2300  }
2301 
2302  if (ctx->codec->configure) {
2303  err = ctx->codec->configure(avctx);
2304  if (err < 0)
2305  goto fail;
2306  }
2307 
2308  ctx->output_delay = ctx->b_per_p;
2309  ctx->decode_delay = ctx->max_b_depth;
2310 
2311  if (ctx->codec->sequence_params_size > 0) {
2312  ctx->codec_sequence_params =
2314  if (!ctx->codec_sequence_params) {
2315  err = AVERROR(ENOMEM);
2316  goto fail;
2317  }
2318  }
2319  if (ctx->codec->picture_params_size > 0) {
2320  ctx->codec_picture_params =
2322  if (!ctx->codec_picture_params) {
2323  err = AVERROR(ENOMEM);
2324  goto fail;
2325  }
2326  }
2327 
2328  if (ctx->codec->init_sequence_params) {
2329  err = ctx->codec->init_sequence_params(avctx);
2330  if (err < 0) {
2331  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
2332  "failed: %d.\n", err);
2333  goto fail;
2334  }
2335  }
2336 
2337  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2338  ctx->codec->write_sequence_header &&
2341  size_t bit_len = 8 * sizeof(data);
2342 
2343  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
2344  if (err < 0) {
2345  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
2346  "for extradata: %d.\n", err);
2347  goto fail;
2348  } else {
2349  avctx->extradata_size = (bit_len + 7) / 8;
2350  avctx->extradata = av_mallocz(avctx->extradata_size +
2352  if (!avctx->extradata) {
2353  err = AVERROR(ENOMEM);
2354  goto fail;
2355  }
2356  memcpy(avctx->extradata, data, avctx->extradata_size);
2357  }
2358  }
2359 
2360  return 0;
2361 
2362 fail:
2363  ff_vaapi_encode_close(avctx);
2364  return err;
2365 }
2366 
2368 {
2369  VAAPIEncodeContext *ctx = avctx->priv_data;
2370  VAAPIEncodePicture *pic, *next;
2371 
2372  for (pic = ctx->pic_start; pic; pic = next) {
2373  next = pic->next;
2374  vaapi_encode_free(avctx, pic);
2375  }
2376 
2378 
2379  if (ctx->va_context != VA_INVALID_ID) {
2380  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2381  ctx->va_context = VA_INVALID_ID;
2382  }
2383 
2384  if (ctx->va_config != VA_INVALID_ID) {
2385  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2386  ctx->va_config = VA_INVALID_ID;
2387  }
2388 
2391 
2394  av_buffer_unref(&ctx->device_ref);
2395 
2396  return 0;
2397 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
#define NULL
Definition: coverity.c:32
AVRational framerate
Definition: avcodec.h:3121
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:2522
const void * global_params[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:255
VAAPI-specific data associated with a frame pool.
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
VAEntrypoint va_entrypoint
Definition: vaapi_encode.h:222
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[]
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1631
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:1841
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:2487
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:228
static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t bit_len)
Definition: vaapi_encode.c:32
static const char *const picture_type_name[]
Definition: vaapi_encode.c:30
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:526
GLint GLenum type
Definition: opengl_enc.c:104
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
void * codec_sequence_params
Definition: vaapi_encode.h:268
AVBufferRef * input_frames_ref
Definition: vaapi_encode.h:242
size_t crop_bottom
Definition: frame.h:656
static AVPacket pkt
size_t picture_params_size
Definition: vaapi_encode.h:370
AVHWDeviceContext * device
Definition: vaapi_encode.h:238
static int vaapi_encode_clear_old(AVCodecContext *avctx)
Definition: vaapi_encode.c:977
int profile
profile
Definition: avcodec.h:2914
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
static int vaapi_encode_wait(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:129
int(* init_picture_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.h:375
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:457
static int vaapi_encode_discard(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c: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:1704
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:734
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:562
unsigned int va_packed_headers
Definition: vaapi_encode.h:228
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame)
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:189
const VAAPIEncodeRCMode * rc_mode
Definition: vaapi_encode.h:214
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:160
size_t crop_left
Definition: frame.h:657
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
int(* write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len)
Definition: vaapi_encode.h:390
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:443
static AVBufferRef * vaapi_encode_alloc_output_buffer(void *opaque, int size)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1682
AVBufferRef * output_buffer_ref
Definition: vaapi_encode.h:93
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:91
Structure to hold side data for an AVFrame.
Definition: frame.h:201
VABufferID * param_buffers
Definition: vaapi_encode.h:91
uint8_t * data
Definition: avcodec.h:1493
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
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
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:1525
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:202
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
int qmax
maximum quantizer
Definition: avcodec.h:2430
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:1661
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:329
static int vaapi_encode_check_frame(AVCodecContext *avctx, const AVFrame *frame)
void * codec_picture_params
Definition: vaapi_encode.h:97
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:465
#define fail()
Definition: checkasm.h: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:1499
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:2444
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:856
#define FFMIN(a, b)
Definition: common.h:96
unsigned int value
int width
picture width / height.
Definition: avcodec.h:1754
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:3278
const VAAPIEncodeProfile * profile
Definition: vaapi_encode.h:211
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2915
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:450
int(* init_slice_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice)
Definition: vaapi_encode.h:377
const struct VAAPIEncodeType * codec
Definition: vaapi_encode.h:173
static VAAPIEncodePicture * vaapi_encode_alloc(AVCodecContext *avctx)
Definition: vaapi_encode.c: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:432
int compression_level
Definition: avcodec.h:1653
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:1581
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
Definition: hwcontext.c:537
uint8_t * data
The data buffer.
Definition: buffer.h:89
int qmin
minimum quantizer
Definition: avcodec.h:2423
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:161
size_t slice_params_size
Definition: vaapi_encode.h:371
unsigned int driver_quirks
Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), with reference to a table of known...
void * buf
Definition: avisynth_c.h:766
size_t crop_right
Definition: frame.h:658
int extradata_size
Definition: avcodec.h:1683
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:123
int(* write_extra_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode.h:412
#define snprintf
Definition: snprintf.h:34
AVBufferRef * recon_frames_ref
Definition: vaapi_encode.h:246
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
mfxU16 profile
Definition: qsvenc.c:44
AVBufferRef * device_ref
Definition: vaapi_encode.h:237
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1647
VAAPIEncodePicture * pic_end
Definition: vaapi_encode.h:275
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[]
size_t picture_priv_data_size
Definition: vaapi_encode.h:365
const char * name
Definition: vaapi_encode.h:154
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
uint8_t level
Definition: svq3.c:207
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:140
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:910
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:1776
A reference to a data buffer.
Definition: buffer.h:81
size_t sequence_params_size
Definition: vaapi_encode.h:369
VAEncMiscParameterHRD hrd_params
Definition: vaapi_encode.h:261
VAProfile va_profile
Definition: vaapi_encode.h:136
int
common internal and external API header
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:243
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c: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:796
static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
int slices
Number of slices.
Definition: avcodec.h:2232
void * priv_data
Definition: avcodec.h:1608
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
#define av_free(p)
static const VAEntrypoint vaapi_encode_entrypoints_normal[]
int len
VAEncMiscParameterFrameRate fr_params
Definition: vaapi_encode.h:262
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:444
void * codec_slice_params
Definition: vaapi_encode.h:61
AVFrame * recon_image
Definition: vaapi_encode.h:87
static int vaapi_encode_free(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c: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:1492
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:924
static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2438
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
int depth
Number of bits in the component.
Definition: pixdesc.h:58
VABufferID output_buffer
Definition: vaapi_encode.h:94
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:221
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1470
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:1486
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:2459
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