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