FFmpeg
vaapi_encode.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <inttypes.h>
20 #include <string.h>
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/common.h"
24 #include "libavutil/log.h"
25 #include "libavutil/pixdesc.h"
26 
27 #include "vaapi_encode.h"
28 #include "avcodec.h"
29 
30 static const char * const picture_type_name[] = { "IDR", "I", "P", "B" };
31 
33  VAAPIEncodePicture *pic,
34  int type, char *data, size_t bit_len)
35 {
37  VAStatus vas;
38  VABufferID param_buffer, data_buffer;
39  VABufferID *tmp;
40  VAEncPackedHeaderParameterBuffer params = {
41  .type = type,
42  .bit_length = bit_len,
43  .has_emulation_bytes = 1,
44  };
45 
46  tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 2);
47  if (!tmp)
48  return AVERROR(ENOMEM);
49  pic->param_buffers = tmp;
50 
51  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
52  VAEncPackedHeaderParameterBufferType,
53  sizeof(params), 1, &params, &param_buffer);
54  if (vas != VA_STATUS_SUCCESS) {
55  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
56  "for packed header (type %d): %d (%s).\n",
57  type, vas, vaErrorStr(vas));
58  return AVERROR(EIO);
59  }
60  pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
61 
62  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
63  VAEncPackedHeaderDataBufferType,
64  (bit_len + 7) / 8, 1, data, &data_buffer);
65  if (vas != VA_STATUS_SUCCESS) {
66  av_log(avctx, AV_LOG_ERROR, "Failed to create data buffer "
67  "for packed header (type %d): %d (%s).\n",
68  type, vas, vaErrorStr(vas));
69  return AVERROR(EIO);
70  }
71  pic->param_buffers[pic->nb_param_buffers++] = data_buffer;
72 
73  av_log(avctx, AV_LOG_DEBUG, "Packed header buffer (%d) is %#x/%#x "
74  "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
75  return 0;
76 }
77 
79  VAAPIEncodePicture *pic,
80  int type, char *data, size_t len)
81 {
83  VAStatus vas;
84  VABufferID *tmp;
85  VABufferID buffer;
86 
87  tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 1);
88  if (!tmp)
89  return AVERROR(ENOMEM);
90  pic->param_buffers = tmp;
91 
92  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
93  type, len, 1, data, &buffer);
94  if (vas != VA_STATUS_SUCCESS) {
95  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
96  "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
97  return AVERROR(EIO);
98  }
99  pic->param_buffers[pic->nb_param_buffers++] = buffer;
100 
101  av_log(avctx, AV_LOG_DEBUG, "Param buffer (%d) is %#x.\n",
102  type, buffer);
103  return 0;
104 }
105 
107  VAAPIEncodePicture *pic,
108  int type,
109  const void *data, size_t len)
110 {
111  // Construct the buffer on the stack - 1KB is much larger than any
112  // current misc parameter buffer type (the largest is EncQuality at
113  // 224 bytes).
114  uint8_t buffer[1024];
115  VAEncMiscParameterBuffer header = {
116  .type = type,
117  };
118  size_t buffer_size = sizeof(header) + len;
119  av_assert0(buffer_size <= sizeof(buffer));
120 
121  memcpy(buffer, &header, sizeof(header));
122  memcpy(buffer + sizeof(header), data, len);
123 
124  return vaapi_encode_make_param_buffer(avctx, pic,
125  VAEncMiscParameterBufferType,
126  buffer, buffer_size);
127 }
128 
130  VAAPIEncodePicture *pic)
131 {
132  VAAPIEncodeContext *ctx = avctx->priv_data;
133  VAStatus vas;
134 
136 
137  if (pic->encode_complete) {
138  // Already waited for this picture.
139  return 0;
140  }
141 
142  av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
143  "(input surface %#x).\n", pic->display_order,
144  pic->encode_order, pic->input_surface);
145 
146  vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
147  if (vas != VA_STATUS_SUCCESS) {
148  av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
149  "%d (%s).\n", vas, vaErrorStr(vas));
150  return AVERROR(EIO);
151  }
152 
153  // Input is definitely finished with now.
154  av_frame_free(&pic->input_image);
155 
156  pic->encode_complete = 1;
157  return 0;
158 }
159 
161  VAAPIEncodePicture *pic)
162 {
163  VAAPIEncodeContext *ctx = avctx->priv_data;
164  VAAPIEncodeSlice *slice;
165  VAStatus vas;
166  int err, i;
168  size_t bit_len;
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:3101
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
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
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: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:2467
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1478
int av_log2(unsigned v)
Definition: intmath.c:26
static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:228
static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t bit_len)
Definition: vaapi_encode.c:32
static const char *const picture_type_name[]
Definition: vaapi_encode.c:30
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:526
GLint GLenum type
Definition: opengl_enc.c:104
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
void * codec_sequence_params
Definition: vaapi_encode.h: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:2894
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
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
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: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
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:91
VABufferID * param_buffers
Definition: vaapi_encode.h:84
uint8_t * data
Definition: avcodec.h:1477
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
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
static const uint8_t header[24]
Definition: sdr2.c:67
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:198
#define av_log(a,...)
const char * name
Definition: pixdesc.h:82
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h: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
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:2410
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
GLenum GLint * params
Definition: opengl_enc.c:113
simple assert() macros that are a bit more flexible than ISO C assert().
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c: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:2424
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:3258
const VAAPIEncodeProfile * profile
Definition: vaapi_encode.h:204
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2895
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
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:271
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
struct VAAPIEncodePicture * next
Definition: vaapi_encode.h:65
int(* write_extra_buffer)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode.h: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)
AVBufferPool * av_buffer_pool_init2(int size, void *opaque, AVBufferRef *(*alloc)(void *opaque, int size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition: buffer.c:218
#define FF_ARRAY_ELEMS(a)
if(ret)
static void vaapi_encode_add_ref(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodePicture *target, int is_ref, int in_dpb, int prev)
Definition: vaapi_encode.c: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:2403
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
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
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:2212
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
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: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)
GLuint buffer
Definition: opengl_enc.c:101
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:2439
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c: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