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