FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 {
109  VAAPIEncodeContext *ctx = avctx->priv_data;
110  VAStatus vas;
111 
113 
114  if (pic->encode_complete) {
115  // Already waited for this picture.
116  return 0;
117  }
118 
119  av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
120  "(input surface %#x).\n", pic->display_order,
121  pic->encode_order, pic->input_surface);
122 
123  vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
124  if (vas != VA_STATUS_SUCCESS) {
125  av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
126  "%d (%s).\n", vas, vaErrorStr(vas));
127  return AVERROR(EIO);
128  }
129 
130  // Input is definitely finished with now.
131  av_frame_free(&pic->input_image);
132 
133  pic->encode_complete = 1;
134  return 0;
135 }
136 
138  VAAPIEncodePicture *pic)
139 {
140  VAAPIEncodeContext *ctx = avctx->priv_data;
141  VAAPIEncodeSlice *slice;
142  VAStatus vas;
143  int err, i;
145  size_t bit_len;
146 
147  av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
148  "as type %s.\n", pic->display_order, pic->encode_order,
149  picture_type_name[pic->type]);
150  if (pic->nb_refs == 0) {
151  av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
152  } else {
153  av_log(avctx, AV_LOG_DEBUG, "Refers to:");
154  for (i = 0; i < pic->nb_refs; i++) {
155  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
156  pic->refs[i]->display_order, pic->refs[i]->encode_order);
157  }
158  av_log(avctx, AV_LOG_DEBUG, ".\n");
159  }
160 
162  for (i = 0; i < pic->nb_refs; i++) {
163  av_assert0(pic->refs[i]);
164  // If we are serialised then the references must have already
165  // completed. If not, they must have been issued but need not
166  // have completed yet.
167  if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
168  av_assert0(pic->refs[i]->encode_complete);
169  else
170  av_assert0(pic->refs[i]->encode_issued);
171  }
172 
173  av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
174 
175  pic->recon_image = av_frame_alloc();
176  if (!pic->recon_image) {
177  err = AVERROR(ENOMEM);
178  goto fail;
179  }
180 
182  if (err < 0) {
183  err = AVERROR(ENOMEM);
184  goto fail;
185  }
186  pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
187  av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
188 
190  if (!pic->output_buffer_ref) {
191  err = AVERROR(ENOMEM);
192  goto fail;
193  }
194  pic->output_buffer = (VABufferID)(uintptr_t)pic->output_buffer_ref->data;
195  av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
196  pic->output_buffer);
197 
198  if (ctx->codec->picture_params_size > 0) {
200  if (!pic->codec_picture_params)
201  goto fail;
202  memcpy(pic->codec_picture_params, ctx->codec_picture_params,
203  ctx->codec->picture_params_size);
204  } else {
206  }
207 
208  pic->nb_param_buffers = 0;
209 
210  if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
211  err = vaapi_encode_make_param_buffer(avctx, pic,
212  VAEncSequenceParameterBufferType,
215  if (err < 0)
216  goto fail;
217  }
218 
219  if (pic->type == PICTURE_TYPE_IDR) {
220  for (i = 0; i < ctx->nb_global_params; i++) {
221  err = vaapi_encode_make_param_buffer(avctx, pic,
222  VAEncMiscParameterBufferType,
223  (char*)ctx->global_params[i],
224  ctx->global_params_size[i]);
225  if (err < 0)
226  goto fail;
227  }
228  }
229 
230  if (ctx->codec->init_picture_params) {
231  err = ctx->codec->init_picture_params(avctx, pic);
232  if (err < 0) {
233  av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
234  "parameters: %d.\n", err);
235  goto fail;
236  }
237  err = vaapi_encode_make_param_buffer(avctx, pic,
238  VAEncPictureParameterBufferType,
240  ctx->codec->picture_params_size);
241  if (err < 0)
242  goto fail;
243  }
244 
245  if (pic->type == PICTURE_TYPE_IDR) {
246  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
248  bit_len = 8 * sizeof(data);
249  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
250  if (err < 0) {
251  av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
252  "header: %d.\n", err);
253  goto fail;
254  }
255  err = vaapi_encode_make_packed_header(avctx, pic,
257  data, bit_len);
258  if (err < 0)
259  goto fail;
260  }
261  }
262 
263  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
264  ctx->codec->write_picture_header) {
265  bit_len = 8 * sizeof(data);
266  err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len);
267  if (err < 0) {
268  av_log(avctx, AV_LOG_ERROR, "Failed to write per-picture "
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  if (ctx->codec->write_extra_buffer) {
280  for (i = 0;; i++) {
281  size_t len = sizeof(data);
282  int type;
283  err = ctx->codec->write_extra_buffer(avctx, pic, i, &type,
284  data, &len);
285  if (err == AVERROR_EOF)
286  break;
287  if (err < 0) {
288  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
289  "buffer %d: %d.\n", i, err);
290  goto fail;
291  }
292 
293  err = vaapi_encode_make_param_buffer(avctx, pic, type,
294  data, len);
295  if (err < 0)
296  goto fail;
297  }
298  }
299 
300  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
301  ctx->codec->write_extra_header) {
302  for (i = 0;; i++) {
303  int type;
304  bit_len = 8 * sizeof(data);
305  err = ctx->codec->write_extra_header(avctx, pic, i, &type,
306  data, &bit_len);
307  if (err == AVERROR_EOF)
308  break;
309  if (err < 0) {
310  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
311  "header %d: %d.\n", i, err);
312  goto fail;
313  }
314 
315  err = vaapi_encode_make_packed_header(avctx, pic, type,
316  data, bit_len);
317  if (err < 0)
318  goto fail;
319  }
320  }
321 
322  if (pic->nb_slices == 0)
323  pic->nb_slices = ctx->nb_slices;
324  if (pic->nb_slices > 0) {
325  int rounding;
326 
327  pic->slices = av_mallocz_array(pic->nb_slices, sizeof(*pic->slices));
328  if (!pic->slices) {
329  err = AVERROR(ENOMEM);
330  goto fail;
331  }
332 
333  for (i = 0; i < pic->nb_slices; i++)
334  pic->slices[i].row_size = ctx->slice_size;
335 
336  rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size;
337  if (rounding > 0) {
338  // Place rounding error at top and bottom of frame.
339  av_assert0(rounding < pic->nb_slices);
340  // Some Intel drivers contain a bug where the encoder will fail
341  // if the last slice is smaller than the one before it. Since
342  // that's straightforward to avoid here, just do so.
343  if (rounding <= 2) {
344  for (i = 0; i < rounding; i++)
345  ++pic->slices[i].row_size;
346  } else {
347  for (i = 0; i < (rounding + 1) / 2; i++)
348  ++pic->slices[pic->nb_slices - i - 1].row_size;
349  for (i = 0; i < rounding / 2; i++)
350  ++pic->slices[i].row_size;
351  }
352  } else if (rounding < 0) {
353  // Remove rounding error from last slice only.
354  av_assert0(rounding < ctx->slice_size);
355  pic->slices[pic->nb_slices - 1].row_size += rounding;
356  }
357  }
358  for (i = 0; i < pic->nb_slices; i++) {
359  slice = &pic->slices[i];
360  slice->index = i;
361  if (i == 0) {
362  slice->row_start = 0;
363  slice->block_start = 0;
364  } else {
365  const VAAPIEncodeSlice *prev = &pic->slices[i - 1];
366  slice->row_start = prev->row_start + prev->row_size;
367  slice->block_start = prev->block_start + prev->block_size;
368  }
369  slice->block_size = slice->row_size * ctx->slice_block_cols;
370 
371  av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), "
372  "%d-%d (%d blocks).\n", i, slice->row_start,
373  slice->row_start + slice->row_size - 1, slice->row_size,
374  slice->block_start, slice->block_start + slice->block_size - 1,
375  slice->block_size);
376 
377  if (ctx->codec->slice_params_size > 0) {
379  if (!slice->codec_slice_params) {
380  err = AVERROR(ENOMEM);
381  goto fail;
382  }
383  }
384 
385  if (ctx->codec->init_slice_params) {
386  err = ctx->codec->init_slice_params(avctx, pic, slice);
387  if (err < 0) {
388  av_log(avctx, AV_LOG_ERROR, "Failed to initialise slice "
389  "parameters: %d.\n", err);
390  goto fail;
391  }
392  }
393 
394  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
395  ctx->codec->write_slice_header) {
396  bit_len = 8 * sizeof(data);
397  err = ctx->codec->write_slice_header(avctx, pic, slice,
398  data, &bit_len);
399  if (err < 0) {
400  av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
401  "header: %d.\n", err);
402  goto fail;
403  }
404  err = vaapi_encode_make_packed_header(avctx, pic,
405  ctx->codec->slice_header_type,
406  data, bit_len);
407  if (err < 0)
408  goto fail;
409  }
410 
411  if (ctx->codec->init_slice_params) {
412  err = vaapi_encode_make_param_buffer(avctx, pic,
413  VAEncSliceParameterBufferType,
414  slice->codec_slice_params,
415  ctx->codec->slice_params_size);
416  if (err < 0)
417  goto fail;
418  }
419  }
420 
421  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
422  pic->input_surface);
423  if (vas != VA_STATUS_SUCCESS) {
424  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
425  "%d (%s).\n", vas, vaErrorStr(vas));
426  err = AVERROR(EIO);
427  goto fail_with_picture;
428  }
429 
430  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
431  pic->param_buffers, pic->nb_param_buffers);
432  if (vas != VA_STATUS_SUCCESS) {
433  av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
434  "%d (%s).\n", vas, vaErrorStr(vas));
435  err = AVERROR(EIO);
436  goto fail_with_picture;
437  }
438 
439  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
440  if (vas != VA_STATUS_SUCCESS) {
441  av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
442  "%d (%s).\n", vas, vaErrorStr(vas));
443  err = AVERROR(EIO);
444  // vaRenderPicture() has been called here, so we should not destroy
445  // the parameter buffers unless separate destruction is required.
446  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
448  goto fail;
449  else
450  goto fail_at_end;
451  }
452 
453  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
455  for (i = 0; i < pic->nb_param_buffers; i++) {
456  vas = vaDestroyBuffer(ctx->hwctx->display,
457  pic->param_buffers[i]);
458  if (vas != VA_STATUS_SUCCESS) {
459  av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
460  "param buffer %#x: %d (%s).\n",
461  pic->param_buffers[i], vas, vaErrorStr(vas));
462  // And ignore.
463  }
464  }
465  }
466 
467  pic->encode_issued = 1;
468 
469  if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
470  return vaapi_encode_wait(avctx, pic);
471  else
472  return 0;
473 
474 fail_with_picture:
475  vaEndPicture(ctx->hwctx->display, ctx->va_context);
476 fail:
477  for(i = 0; i < pic->nb_param_buffers; i++)
478  vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
479  for (i = 0; i < pic->nb_slices; i++) {
480  if (pic->slices) {
481  av_freep(&pic->slices[i].priv_data);
483  }
484  }
485 fail_at_end:
487  av_freep(&pic->param_buffers);
488  av_freep(&pic->slices);
489  av_frame_free(&pic->recon_image);
491  pic->output_buffer = VA_INVALID_ID;
492  return err;
493 }
494 
497 {
498  VAAPIEncodeContext *ctx = avctx->priv_data;
499  VACodedBufferSegment *buf_list, *buf;
500  VAStatus vas;
501  int err;
502 
503  err = vaapi_encode_wait(avctx, pic);
504  if (err < 0)
505  return err;
506 
507  buf_list = NULL;
508  vas = vaMapBuffer(ctx->hwctx->display, pic->output_buffer,
509  (void**)&buf_list);
510  if (vas != VA_STATUS_SUCCESS) {
511  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
512  "%d (%s).\n", vas, vaErrorStr(vas));
513  err = AVERROR(EIO);
514  goto fail;
515  }
516 
517  for (buf = buf_list; buf; buf = buf->next) {
518  av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
519  "(status %08x).\n", buf->size, buf->status);
520 
521  err = av_new_packet(pkt, buf->size);
522  if (err < 0)
523  goto fail_mapped;
524 
525  memcpy(pkt->data, buf->buf, buf->size);
526  }
527 
528  if (pic->type == PICTURE_TYPE_IDR)
529  pkt->flags |= AV_PKT_FLAG_KEY;
530 
531  pkt->pts = pic->pts;
532 
533  vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
534  if (vas != VA_STATUS_SUCCESS) {
535  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
536  "%d (%s).\n", vas, vaErrorStr(vas));
537  err = AVERROR(EIO);
538  goto fail;
539  }
540 
542  pic->output_buffer = VA_INVALID_ID;
543 
544  av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
545  pic->display_order, pic->encode_order);
546  return 0;
547 
548 fail_mapped:
549  vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
550 fail:
552  pic->output_buffer = VA_INVALID_ID;
553  return err;
554 }
555 
557  VAAPIEncodePicture *pic)
558 {
559  vaapi_encode_wait(avctx, pic);
560 
561  if (pic->output_buffer_ref) {
562  av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
563  "%"PRId64"/%"PRId64".\n",
564  pic->display_order, pic->encode_order);
565 
567  pic->output_buffer = VA_INVALID_ID;
568  }
569 
570  return 0;
571 }
572 
574 {
575  VAAPIEncodePicture *pic;
576 
577  pic = av_mallocz(sizeof(*pic));
578  if (!pic)
579  return NULL;
580 
581  pic->input_surface = VA_INVALID_ID;
582  pic->recon_surface = VA_INVALID_ID;
583  pic->output_buffer = VA_INVALID_ID;
584 
585  return pic;
586 }
587 
589  VAAPIEncodePicture *pic)
590 {
591  int i;
592 
593  if (pic->encode_issued)
594  vaapi_encode_discard(avctx, pic);
595 
596  for (i = 0; i < pic->nb_slices; i++) {
597  if (pic->slices) {
598  av_freep(&pic->slices[i].priv_data);
600  }
601  }
603 
604  av_frame_free(&pic->input_image);
605  av_frame_free(&pic->recon_image);
606 
607  av_freep(&pic->param_buffers);
608  av_freep(&pic->slices);
609  // Output buffer should already be destroyed.
610  av_assert0(pic->output_buffer == VA_INVALID_ID);
611 
612  av_freep(&pic->priv_data);
614 
615  av_free(pic);
616 
617  return 0;
618 }
619 
621  VAAPIEncodePicture *target)
622 {
623  VAAPIEncodeContext *ctx = avctx->priv_data;
624  VAAPIEncodePicture *pic;
625  int i, err;
626 
627  if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING ||
628  ctx->issue_mode == ISSUE_MODE_MINIMISE_LATENCY) {
629  // These two modes are equivalent, except that we wait for
630  // immediate completion on each operation if serialised.
631 
632  if (!target) {
633  // No target, nothing to do yet.
634  return 0;
635  }
636 
637  if (target->encode_complete) {
638  // Already done.
639  return 0;
640  }
641 
642  pic = target;
643  for (i = 0; i < pic->nb_refs; i++) {
644  if (!pic->refs[i]->encode_complete) {
645  err = vaapi_encode_step(avctx, pic->refs[i]);
646  if (err < 0)
647  return err;
648  }
649  }
650 
651  err = vaapi_encode_issue(avctx, pic);
652  if (err < 0)
653  return err;
654 
655  } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
656  int activity;
657 
658  // Run through the list of all available pictures repeatedly
659  // and issue the first one found which has all dependencies
660  // available (including previously-issued but not necessarily
661  // completed pictures).
662  do {
663  activity = 0;
664  for (pic = ctx->pic_start; pic; pic = pic->next) {
665  if (!pic->input_available || pic->encode_issued)
666  continue;
667  for (i = 0; i < pic->nb_refs; i++) {
668  if (!pic->refs[i]->encode_issued)
669  break;
670  }
671  if (i < pic->nb_refs)
672  continue;
673  err = vaapi_encode_issue(avctx, pic);
674  if (err < 0)
675  return err;
676  activity = 1;
677  // Start again from the beginning of the list,
678  // because issuing this picture may have satisfied
679  // forward dependencies of earlier ones.
680  break;
681  }
682  } while(activity);
683 
684  // If we had a defined target for this step then it will
685  // always have been issued by now.
686  if (target) {
687  av_assert0(target->encode_issued && "broken dependencies?");
688  }
689 
690  } else {
691  av_assert0(0);
692  }
693 
694  return 0;
695 }
696 
698  VAAPIEncodePicture **pic_out)
699 {
700  VAAPIEncodeContext *ctx = avctx->priv_data;
701  VAAPIEncodePicture *start, *end, *pic;
702  int i;
703 
704  for (pic = ctx->pic_start; pic; pic = pic->next) {
705  if (pic->next)
706  av_assert0(pic->display_order + 1 == pic->next->display_order);
707  if (pic->display_order == ctx->input_order) {
708  *pic_out = pic;
709  return 0;
710  }
711  }
712 
713  pic = vaapi_encode_alloc();
714  if (!pic)
715  return AVERROR(ENOMEM);
716 
717  if (ctx->input_order == 0 || ctx->force_idr ||
718  ctx->gop_counter >= ctx->gop_size) {
719  pic->type = PICTURE_TYPE_IDR;
720  ctx->force_idr = 0;
721  ctx->gop_counter = 1;
722  ctx->p_counter = 0;
723  } else if (ctx->p_counter >= ctx->p_per_i) {
724  pic->type = PICTURE_TYPE_I;
725  ++ctx->gop_counter;
726  ctx->p_counter = 0;
727  } else {
728  pic->type = PICTURE_TYPE_P;
729  pic->refs[0] = ctx->pic_end;
730  pic->nb_refs = 1;
731  ++ctx->gop_counter;
732  ++ctx->p_counter;
733  }
734  start = end = pic;
735 
736  if (pic->type != PICTURE_TYPE_IDR) {
737  // If that was not an IDR frame, add B-frames display-before and
738  // encode-after it, but not exceeding the GOP size.
739 
740  for (i = 0; i < ctx->b_per_p &&
741  ctx->gop_counter < ctx->gop_size; i++) {
742  pic = vaapi_encode_alloc();
743  if (!pic)
744  goto fail;
745 
746  pic->type = PICTURE_TYPE_B;
747  pic->refs[0] = ctx->pic_end;
748  pic->refs[1] = end;
749  pic->nb_refs = 2;
750 
751  pic->next = start;
752  pic->display_order = ctx->input_order + ctx->b_per_p - i - 1;
753  pic->encode_order = pic->display_order + 1;
754  start = pic;
755 
756  ++ctx->gop_counter;
757  }
758  }
759 
760  if (ctx->input_order == 0) {
761  pic->display_order = 0;
762  pic->encode_order = 0;
763 
764  ctx->pic_start = ctx->pic_end = pic;
765 
766  } else {
767  for (i = 0, pic = start; pic; i++, pic = pic->next) {
768  pic->display_order = ctx->input_order + i;
769  if (end->type == PICTURE_TYPE_IDR)
770  pic->encode_order = ctx->input_order + i;
771  else if (pic == end)
772  pic->encode_order = ctx->input_order;
773  else
774  pic->encode_order = ctx->input_order + i + 1;
775  }
776 
777  av_assert0(ctx->pic_end);
778  ctx->pic_end->next = start;
779  ctx->pic_end = end;
780  }
781  *pic_out = start;
782 
783  av_log(avctx, AV_LOG_DEBUG, "Pictures:");
784  for (pic = ctx->pic_start; pic; pic = pic->next) {
785  av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
786  picture_type_name[pic->type],
787  pic->display_order, pic->encode_order);
788  }
789  av_log(avctx, AV_LOG_DEBUG, "\n");
790 
791  return 0;
792 
793 fail:
794  while (start) {
795  pic = start->next;
796  vaapi_encode_free(avctx, start);
797  start = pic;
798  }
799  return AVERROR(ENOMEM);
800 }
801 
803 {
804  VAAPIEncodeContext *ctx = avctx->priv_data;
805  VAAPIEncodePicture *pic, *last_pic, *next;
806 
808 
809  // Find the last picture we actually have input for.
810  for (pic = ctx->pic_start; pic; pic = pic->next) {
811  if (!pic->input_available)
812  break;
813  last_pic = pic;
814  }
815 
816  if (pic) {
817  if (last_pic->type == PICTURE_TYPE_B) {
818  // Some fixing up is required. Change the type of this
819  // picture to P, then modify preceding B references which
820  // point beyond it to point at it instead.
821 
822  last_pic->type = PICTURE_TYPE_P;
823  last_pic->encode_order = last_pic->refs[1]->encode_order;
824 
825  for (pic = ctx->pic_start; pic != last_pic; pic = pic->next) {
826  if (pic->type == PICTURE_TYPE_B &&
827  pic->refs[1] == last_pic->refs[1])
828  pic->refs[1] = last_pic;
829  }
830 
831  last_pic->nb_refs = 1;
832  last_pic->refs[1] = NULL;
833  } else {
834  // We can use the current structure (no references point
835  // beyond the end), but there are unused pics to discard.
836  }
837 
838  // Discard all following pics, they will never be used.
839  for (pic = last_pic->next; pic; pic = next) {
840  next = pic->next;
841  vaapi_encode_free(avctx, pic);
842  }
843 
844  last_pic->next = NULL;
845  ctx->pic_end = last_pic;
846 
847  } else {
848  // Input is available for all pictures, so we don't need to
849  // mangle anything.
850  }
851 
852  av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:");
853  for (pic = ctx->pic_start; pic; pic = pic->next) {
854  av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
855  picture_type_name[pic->type],
856  pic->display_order, pic->encode_order);
857  }
858  av_log(avctx, AV_LOG_DEBUG, "\n");
859 
860  return 0;
861 }
862 
864 {
865  VAAPIEncodeContext *ctx = avctx->priv_data;
866  VAAPIEncodePicture *pic, *old;
867  int i;
868 
869  while (ctx->pic_start != ctx->pic_end) {
870  old = ctx->pic_start;
871  if (old->encode_order > ctx->output_order)
872  break;
873 
874  for (pic = old->next; pic; pic = pic->next) {
875  if (pic->encode_complete)
876  continue;
877  for (i = 0; i < pic->nb_refs; i++) {
878  if (pic->refs[i] == old) {
879  // We still need this picture because it's referred to
880  // directly by a later one, so it and all following
881  // pictures have to stay.
882  return 0;
883  }
884  }
885  }
886 
887  pic = ctx->pic_start;
888  ctx->pic_start = pic->next;
889  vaapi_encode_free(avctx, pic);
890  }
891 
892  return 0;
893 }
894 
896  const AVFrame *input_image, int *got_packet)
897 {
898  VAAPIEncodeContext *ctx = avctx->priv_data;
899  VAAPIEncodePicture *pic;
900  int err;
901 
902  if (input_image) {
903  av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
904  input_image->width, input_image->height, input_image->pts);
905 
906  if (input_image->pict_type == AV_PICTURE_TYPE_I) {
907  err = vaapi_encode_truncate_gop(avctx);
908  if (err < 0)
909  goto fail;
910  ctx->force_idr = 1;
911  }
912 
913  err = vaapi_encode_get_next(avctx, &pic);
914  if (err) {
915  av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
916  return err;
917  }
918 
919  pic->input_image = av_frame_alloc();
920  if (!pic->input_image) {
921  err = AVERROR(ENOMEM);
922  goto fail;
923  }
924  err = av_frame_ref(pic->input_image, input_image);
925  if (err < 0)
926  goto fail;
927  pic->input_surface = (VASurfaceID)(uintptr_t)input_image->data[3];
928  pic->pts = input_image->pts;
929 
930  if (ctx->input_order == 0)
931  ctx->first_pts = pic->pts;
932  if (ctx->input_order == ctx->decode_delay)
933  ctx->dts_pts_diff = pic->pts - ctx->first_pts;
934  if (ctx->output_delay > 0)
935  ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;
936 
937  pic->input_available = 1;
938 
939  } else {
940  if (!ctx->end_of_stream) {
941  err = vaapi_encode_truncate_gop(avctx);
942  if (err < 0)
943  goto fail;
944  ctx->end_of_stream = 1;
945  }
946  }
947 
948  ++ctx->input_order;
949  ++ctx->output_order;
950  av_assert0(ctx->output_order + ctx->output_delay + 1 == ctx->input_order);
951 
952  for (pic = ctx->pic_start; pic; pic = pic->next)
953  if (pic->encode_order == ctx->output_order)
954  break;
955 
956  // pic can be null here if we don't have a specific target in this
957  // iteration. We might still issue encodes if things can be overlapped,
958  // even though we don't intend to output anything.
959 
960  err = vaapi_encode_step(avctx, pic);
961  if (err < 0) {
962  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
963  goto fail;
964  }
965 
966  if (!pic) {
967  *got_packet = 0;
968  } else {
969  err = vaapi_encode_output(avctx, pic, pkt);
970  if (err < 0) {
971  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
972  goto fail;
973  }
974 
975  if (ctx->output_delay == 0) {
976  pkt->dts = pkt->pts;
977  } else if (ctx->output_order < ctx->decode_delay) {
978  if (ctx->ts_ring[ctx->output_order] < INT64_MIN + ctx->dts_pts_diff)
979  pkt->dts = INT64_MIN;
980  else
981  pkt->dts = ctx->ts_ring[ctx->output_order] - ctx->dts_pts_diff;
982  } else {
983  pkt->dts = ctx->ts_ring[(ctx->output_order - ctx->decode_delay) %
984  (3 * ctx->output_delay)];
985  }
986 
987  *got_packet = 1;
988  }
989 
990  err = vaapi_encode_clear_old(avctx);
991  if (err < 0) {
992  av_log(avctx, AV_LOG_ERROR, "List clearing failed: %d.\n", err);
993  goto fail;
994  }
995 
996  return 0;
997 
998 fail:
999  // Unclear what to clean up on failure. There are probably some things we
1000  // could do usefully clean up here, but for now just leave them for uninit()
1001  // to do instead.
1002  return err;
1003 }
1004 
1006  VAEncMiscParameterBuffer *buffer,
1007  size_t size)
1008 {
1009  VAAPIEncodeContext *ctx = avctx->priv_data;
1010 
1012 
1013  ctx->global_params [ctx->nb_global_params] = buffer;
1015 
1016  ++ctx->nb_global_params;
1017 }
1018 
1019 typedef struct VAAPIEncodeRTFormat {
1020  const char *name;
1021  unsigned int value;
1022  int depth;
1027 
1029  { "YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1030  { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1031  { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1032  { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1033  { "YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1034 #if VA_CHECK_VERSION(0, 38, 1)
1035  { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1036 #endif
1037 };
1038 
1039 static const VAEntrypoint vaapi_encode_entrypoints_normal[] = {
1040  VAEntrypointEncSlice,
1041  VAEntrypointEncPicture,
1042 #if VA_CHECK_VERSION(0, 39, 2)
1043  VAEntrypointEncSliceLP,
1044 #endif
1045  0
1046 };
1047 #if VA_CHECK_VERSION(0, 39, 2)
1048 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1049  VAEntrypointEncSliceLP,
1050  0
1051 };
1052 #endif
1053 
1055 {
1056  VAAPIEncodeContext *ctx = avctx->priv_data;
1057  VAProfile *va_profiles = NULL;
1058  VAEntrypoint *va_entrypoints = NULL;
1059  VAStatus vas;
1060  const VAEntrypoint *usable_entrypoints;
1061  const VAAPIEncodeProfile *profile;
1062  const AVPixFmtDescriptor *desc;
1063  VAConfigAttrib rt_format_attr;
1064  const VAAPIEncodeRTFormat *rt_format;
1065  const char *profile_string, *entrypoint_string;
1066  int i, j, n, depth, err;
1067 
1068 
1069  if (ctx->low_power) {
1070 #if VA_CHECK_VERSION(0, 39, 2)
1071  usable_entrypoints = vaapi_encode_entrypoints_low_power;
1072 #else
1073  av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
1074  "supported with this VAAPI version.\n");
1075  return AVERROR(EINVAL);
1076 #endif
1077  } else {
1078  usable_entrypoints = vaapi_encode_entrypoints_normal;
1079  }
1080 
1082  if (!desc) {
1083  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
1084  ctx->input_frames->sw_format);
1085  return AVERROR(EINVAL);
1086  }
1087  depth = desc->comp[0].depth;
1088  for (i = 1; i < desc->nb_components; i++) {
1089  if (desc->comp[i].depth != depth) {
1090  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
1091  desc->name);
1092  return AVERROR(EINVAL);
1093  }
1094  }
1095  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
1096  desc->name);
1097 
1098  n = vaMaxNumProfiles(ctx->hwctx->display);
1099  va_profiles = av_malloc_array(n, sizeof(VAProfile));
1100  if (!va_profiles) {
1101  err = AVERROR(ENOMEM);
1102  goto fail;
1103  }
1104  vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
1105  if (vas != VA_STATUS_SUCCESS) {
1106  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
1107  vas, vaErrorStr(vas));
1108  err = AVERROR_EXTERNAL;
1109  goto fail;
1110  }
1111 
1112  av_assert0(ctx->codec->profiles);
1113  for (i = 0; (ctx->codec->profiles[i].av_profile !=
1114  FF_PROFILE_UNKNOWN); i++) {
1115  profile = &ctx->codec->profiles[i];
1116  if (depth != profile->depth ||
1117  desc->nb_components != profile->nb_components)
1118  continue;
1119  if (desc->nb_components > 1 &&
1120  (desc->log2_chroma_w != profile->log2_chroma_w ||
1121  desc->log2_chroma_h != profile->log2_chroma_h))
1122  continue;
1123  if (avctx->profile != profile->av_profile &&
1124  avctx->profile != FF_PROFILE_UNKNOWN)
1125  continue;
1126 
1127 #if VA_CHECK_VERSION(1, 0, 0)
1128  profile_string = vaProfileStr(profile->va_profile);
1129 #else
1130  profile_string = "(no profile names)";
1131 #endif
1132 
1133  for (j = 0; j < n; j++) {
1134  if (va_profiles[j] == profile->va_profile)
1135  break;
1136  }
1137  if (j >= n) {
1138  av_log(avctx, AV_LOG_VERBOSE, "Matching profile %d is "
1139  "not supported by driver.\n", profile->va_profile);
1140  continue;
1141  }
1142 
1143  ctx->profile = profile;
1144  break;
1145  }
1146  if (!ctx->profile) {
1147  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1148  err = AVERROR(ENOSYS);
1149  goto fail;
1150  }
1151 
1152  avctx->profile = profile->av_profile;
1153  ctx->va_profile = profile->va_profile;
1154  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1155  profile_string, ctx->va_profile);
1156 
1157  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1158  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1159  if (!va_entrypoints) {
1160  err = AVERROR(ENOMEM);
1161  goto fail;
1162  }
1163  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1164  va_entrypoints, &n);
1165  if (vas != VA_STATUS_SUCCESS) {
1166  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1167  "profile %s (%d): %d (%s).\n", profile_string,
1168  ctx->va_profile, vas, vaErrorStr(vas));
1169  err = AVERROR_EXTERNAL;
1170  goto fail;
1171  }
1172 
1173  for (i = 0; i < n; i++) {
1174  for (j = 0; usable_entrypoints[j]; j++) {
1175  if (va_entrypoints[i] == usable_entrypoints[j])
1176  break;
1177  }
1178  if (usable_entrypoints[j])
1179  break;
1180  }
1181  if (i >= n) {
1182  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1183  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1184  err = AVERROR(ENOSYS);
1185  goto fail;
1186  }
1187 
1188  ctx->va_entrypoint = va_entrypoints[i];
1189 #if VA_CHECK_VERSION(1, 0, 0)
1190  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1191 #else
1192  entrypoint_string = "(no entrypoint names)";
1193 #endif
1194  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1195  entrypoint_string, ctx->va_entrypoint);
1196 
1197  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1198  rt_format = &vaapi_encode_rt_formats[i];
1199  if (rt_format->depth == depth &&
1200  rt_format->nb_components == profile->nb_components &&
1201  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1202  rt_format->log2_chroma_h == profile->log2_chroma_h)
1203  break;
1204  }
1205  if (i >= FF_ARRAY_ELEMS(vaapi_encode_rt_formats)) {
1206  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1207  "found for profile %s (%d) entrypoint %s (%d).\n",
1208  profile_string, ctx->va_profile,
1209  entrypoint_string, ctx->va_entrypoint);
1210  err = AVERROR(ENOSYS);
1211  goto fail;
1212  }
1213 
1214  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1215  vas = vaGetConfigAttributes(ctx->hwctx->display,
1216  ctx->va_profile, ctx->va_entrypoint,
1217  &rt_format_attr, 1);
1218  if (vas != VA_STATUS_SUCCESS) {
1219  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1220  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1221  err = AVERROR_EXTERNAL;
1222  goto fail;
1223  }
1224 
1225  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1226  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1227  "supported by driver: assuming surface RT format %s "
1228  "is valid.\n", rt_format->name);
1229  } else if (!(rt_format_attr.value & rt_format->value)) {
1230  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1231  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1232  rt_format->name, profile_string, ctx->va_profile,
1233  entrypoint_string, ctx->va_entrypoint);
1234  err = AVERROR(ENOSYS);
1235  goto fail;
1236  } else {
1237  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1238  "format %s (%#x).\n", rt_format->name, rt_format->value);
1240  (VAConfigAttrib) {
1241  .type = VAConfigAttribRTFormat,
1242  .value = rt_format->value,
1243  };
1244  }
1245 
1246  err = 0;
1247 fail:
1248  av_freep(&va_profiles);
1249  av_freep(&va_entrypoints);
1250  return err;
1251 }
1252 
1254 {
1255  VAAPIEncodeContext *ctx = avctx->priv_data;
1256  int64_t rc_bits_per_second;
1257  int rc_target_percentage;
1258  int rc_window_size;
1259  int64_t hrd_buffer_size;
1260  int64_t hrd_initial_buffer_fullness;
1261  int fr_num, fr_den;
1262  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1263  VAStatus vas;
1264 
1265  vas = vaGetConfigAttributes(ctx->hwctx->display,
1266  ctx->va_profile, ctx->va_entrypoint,
1267  &rc_attr, 1);
1268  if (vas != VA_STATUS_SUCCESS) {
1269  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1270  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1271  return AVERROR_EXTERNAL;
1272  }
1273 
1274  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1275  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1276  "supported rate control modes: assuming constant-quality.\n");
1277  ctx->va_rc_mode = VA_RC_CQP;
1278  return 0;
1279  }
1280  if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY ||
1281  avctx->flags & AV_CODEC_FLAG_QSCALE ||
1282  avctx->bit_rate <= 0) {
1283  if (rc_attr.value & VA_RC_CQP) {
1284  av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
1285  ctx->va_rc_mode = VA_RC_CQP;
1286  if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) {
1287  av_log(avctx, AV_LOG_WARNING, "Bitrate target parameters "
1288  "ignored in constant-quality mode.\n");
1289  }
1290  return 0;
1291  } else {
1292  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1293  "constant-quality mode (%#x).\n", rc_attr.value);
1294  return AVERROR(EINVAL);
1295  }
1296  }
1297 
1298  if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
1299  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1300  "bitrate-targetted rate control modes.\n");
1301  return AVERROR(EINVAL);
1302  }
1303 
1304  if (avctx->rc_buffer_size)
1305  hrd_buffer_size = avctx->rc_buffer_size;
1306  else if (avctx->rc_max_rate > 0)
1307  hrd_buffer_size = avctx->rc_max_rate;
1308  else
1309  hrd_buffer_size = avctx->bit_rate;
1310  if (avctx->rc_initial_buffer_occupancy) {
1311  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1312  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1313  "must have initial buffer size (%d) < "
1314  "buffer size (%"PRId64").\n",
1315  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1316  return AVERROR(EINVAL);
1317  }
1318  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1319  } else {
1320  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1321  }
1322 
1323  if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
1324  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have "
1325  "bitrate (%"PRId64") <= maxrate (%"PRId64").\n",
1326  avctx->bit_rate, avctx->rc_max_rate);
1327  return AVERROR(EINVAL);
1328  }
1329 
1330  if (avctx->rc_max_rate > avctx->bit_rate) {
1331  if (!(rc_attr.value & VA_RC_VBR)) {
1332  av_log(avctx, AV_LOG_WARNING, "Driver does not support "
1333  "VBR mode (%#x), using CBR mode instead.\n",
1334  rc_attr.value);
1335  ctx->va_rc_mode = VA_RC_CBR;
1336 
1337  rc_bits_per_second = avctx->bit_rate;
1338  rc_target_percentage = 100;
1339  } else {
1340  ctx->va_rc_mode = VA_RC_VBR;
1341 
1342  rc_bits_per_second = avctx->rc_max_rate;
1343  rc_target_percentage = (avctx->bit_rate * 100) /
1344  avctx->rc_max_rate;
1345  }
1346 
1347  } else if (avctx->rc_max_rate == avctx->bit_rate) {
1348  if (!(rc_attr.value & VA_RC_CBR)) {
1349  av_log(avctx, AV_LOG_WARNING, "Driver does not support "
1350  "CBR mode (%#x), using VBR mode instead.\n",
1351  rc_attr.value);
1352  ctx->va_rc_mode = VA_RC_VBR;
1353  } else {
1354  ctx->va_rc_mode = VA_RC_CBR;
1355  }
1356 
1357  rc_bits_per_second = avctx->bit_rate;
1358  rc_target_percentage = 100;
1359 
1360  } else {
1361  if (rc_attr.value & VA_RC_VBR) {
1362  ctx->va_rc_mode = VA_RC_VBR;
1363 
1364  // We only have a target bitrate, but VAAPI requires that a
1365  // maximum rate be supplied as well. Since the user has
1366  // offered no particular constraint, arbitrarily pick a
1367  // maximum rate of double the target rate.
1368  rc_bits_per_second = 2 * avctx->bit_rate;
1369  rc_target_percentage = 50;
1370  } else {
1371  ctx->va_rc_mode = VA_RC_CBR;
1372 
1373  rc_bits_per_second = avctx->bit_rate;
1374  rc_target_percentage = 100;
1375  }
1376  }
1377 
1378  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1379 
1380  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps "
1381  "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR",
1382  rc_target_percentage, rc_bits_per_second, rc_window_size);
1383  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1384  "initial fullness %"PRId64" bits.\n",
1385  hrd_buffer_size, hrd_initial_buffer_fullness);
1386 
1387  if (rc_bits_per_second > UINT32_MAX ||
1388  hrd_buffer_size > UINT32_MAX ||
1389  hrd_initial_buffer_fullness > UINT32_MAX) {
1390  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1391  "greater are not supported by VAAPI.\n");
1392  return AVERROR(EINVAL);
1393  }
1394 
1395  ctx->va_bit_rate = rc_bits_per_second;
1396 
1398  (VAConfigAttrib) {
1399  .type = VAConfigAttribRateControl,
1400  .value = ctx->va_rc_mode,
1401  };
1402 
1403  ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
1404  ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
1405  .bits_per_second = rc_bits_per_second,
1406  .target_percentage = rc_target_percentage,
1407  .window_size = rc_window_size,
1408  .initial_qp = 0,
1409  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
1410  .basic_unit_size = 0,
1411 #if VA_CHECK_VERSION(1, 1, 0)
1412  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
1413 #endif
1414  };
1416  sizeof(ctx->rc_params));
1417 
1418  ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
1419  ctx->hrd_params.hrd = (VAEncMiscParameterHRD) {
1420  .initial_buffer_fullness = hrd_initial_buffer_fullness,
1421  .buffer_size = hrd_buffer_size,
1422  };
1424  sizeof(ctx->hrd_params));
1425 
1426  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1427  av_reduce(&fr_num, &fr_den,
1428  avctx->framerate.num, avctx->framerate.den, 65535);
1429  else
1430  av_reduce(&fr_num, &fr_den,
1431  avctx->time_base.den, avctx->time_base.num, 65535);
1432 
1433  ctx->fr_params.misc.type = VAEncMiscParameterTypeFrameRate;
1434  ctx->fr_params.fr.framerate = (unsigned int)fr_den << 16 | fr_num;
1435 
1436 #if VA_CHECK_VERSION(0, 40, 0)
1438  sizeof(ctx->fr_params));
1439 #endif
1440 
1441  return 0;
1442 }
1443 
1445 {
1446  VAAPIEncodeContext *ctx = avctx->priv_data;
1447  VAStatus vas;
1448  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1449  uint32_t ref_l0, ref_l1;
1450 
1451  vas = vaGetConfigAttributes(ctx->hwctx->display,
1452  ctx->va_profile,
1453  ctx->va_entrypoint,
1454  &attr, 1);
1455  if (vas != VA_STATUS_SUCCESS) {
1456  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
1457  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1458  return AVERROR_EXTERNAL;
1459  }
1460 
1461  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1462  ref_l0 = ref_l1 = 0;
1463  } else {
1464  ref_l0 = attr.value & 0xffff;
1465  ref_l1 = attr.value >> 16 & 0xffff;
1466  }
1467 
1468  if (avctx->gop_size <= 1) {
1469  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
1470  ctx->gop_size = 1;
1471  } else if (ref_l0 < 1) {
1472  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1473  "reference frames.\n");
1474  return AVERROR(EINVAL);
1475  } else if (ref_l1 < 1 || avctx->max_b_frames < 1) {
1476  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
1477  "(supported references: %d / %d).\n", ref_l0, ref_l1);
1478  ctx->gop_size = avctx->gop_size;
1479  ctx->p_per_i = INT_MAX;
1480  ctx->b_per_p = 0;
1481  } else {
1482  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
1483  "(supported references: %d / %d).\n", ref_l0, ref_l1);
1484  ctx->gop_size = avctx->gop_size;
1485  ctx->p_per_i = INT_MAX;
1486  ctx->b_per_p = avctx->max_b_frames;
1487  }
1488 
1489  return 0;
1490 }
1491 
1493 {
1494  VAAPIEncodeContext *ctx = avctx->priv_data;
1495  VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
1496  { VAConfigAttribEncSliceStructure } };
1497  VAStatus vas;
1498  uint32_t max_slices, slice_structure;
1499  int req_slices;
1500 
1501  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
1502  if (avctx->slices > 0) {
1503  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
1504  "but this codec does not support controlling slices.\n");
1505  }
1506  return 0;
1507  }
1508 
1509  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
1510  ctx->slice_block_height;
1511  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
1512  ctx->slice_block_width;
1513 
1514  if (avctx->slices <= 1) {
1515  ctx->nb_slices = 1;
1516  ctx->slice_size = ctx->slice_block_rows;
1517  return 0;
1518  }
1519 
1520  vas = vaGetConfigAttributes(ctx->hwctx->display,
1521  ctx->va_profile,
1522  ctx->va_entrypoint,
1523  attr, FF_ARRAY_ELEMS(attr));
1524  if (vas != VA_STATUS_SUCCESS) {
1525  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
1526  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1527  return AVERROR_EXTERNAL;
1528  }
1529  max_slices = attr[0].value;
1530  slice_structure = attr[1].value;
1531  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1532  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1533  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1534  "pictures as multiple slices.\n.");
1535  return AVERROR(EINVAL);
1536  }
1537 
1538  // For fixed-size slices currently we only support whole rows, making
1539  // rectangular slices. This could be extended to arbitrary runs of
1540  // blocks, but since slices tend to be a conformance requirement and
1541  // most cases (such as broadcast or bluray) want rectangular slices
1542  // only it would need to be gated behind another option.
1543  if (avctx->slices > ctx->slice_block_rows) {
1544  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1545  "configured number of slices (%d < %d); using "
1546  "maximum.\n", ctx->slice_block_rows, avctx->slices);
1547  req_slices = ctx->slice_block_rows;
1548  } else {
1549  req_slices = avctx->slices;
1550  }
1551  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1552  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1553  ctx->nb_slices = req_slices;
1554  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1555  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1556  int k;
1557  for (k = 1;; k *= 2) {
1558  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1559  break;
1560  }
1561  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1562  ctx->slice_size = k;
1563 #if VA_CHECK_VERSION(1, 0, 0)
1564  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1565  ctx->nb_slices = ctx->slice_block_rows;
1566  ctx->slice_size = 1;
1567 #endif
1568  } else {
1569  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1570  "slice structure modes (%#x).\n", slice_structure);
1571  return AVERROR(EINVAL);
1572  }
1573 
1574  if (ctx->nb_slices > avctx->slices) {
1575  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
1576  "%d (from %d) due to driver constraints on slice "
1577  "structure.\n", ctx->nb_slices, avctx->slices);
1578  }
1579  if (ctx->nb_slices > max_slices) {
1580  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1581  "encoding with %d slices (max %"PRIu32").\n",
1582  ctx->nb_slices, max_slices);
1583  return AVERROR(EINVAL);
1584  }
1585 
1586  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices "
1587  "(default size %d block rows).\n",
1588  ctx->nb_slices, ctx->slice_size);
1589  return 0;
1590 }
1591 
1593 {
1594  VAAPIEncodeContext *ctx = avctx->priv_data;
1595  VAStatus vas;
1596  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1597 
1598  vas = vaGetConfigAttributes(ctx->hwctx->display,
1599  ctx->va_profile,
1600  ctx->va_entrypoint,
1601  &attr, 1);
1602  if (vas != VA_STATUS_SUCCESS) {
1603  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
1604  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1605  return AVERROR_EXTERNAL;
1606  }
1607 
1608  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1609  if (ctx->desired_packed_headers) {
1610  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
1611  "packed headers (wanted %#x).\n",
1612  ctx->desired_packed_headers);
1613  } else {
1614  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
1615  "packed headers (none wanted).\n");
1616  }
1617  ctx->va_packed_headers = 0;
1618  } else {
1619  if (ctx->desired_packed_headers & ~attr.value) {
1620  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
1621  "wanted packed headers (wanted %#x, found %#x).\n",
1622  ctx->desired_packed_headers, attr.value);
1623  } else {
1624  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
1625  "available (wanted %#x, found %#x).\n",
1626  ctx->desired_packed_headers, attr.value);
1627  }
1628  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
1629  }
1630 
1631  if (ctx->va_packed_headers) {
1633  (VAConfigAttrib) {
1634  .type = VAConfigAttribEncPackedHeaders,
1635  .value = ctx->va_packed_headers,
1636  };
1637  }
1638 
1639  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1640  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1641  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
1642  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
1643  "sequence headers, but a global header is requested.\n");
1644  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
1645  "this may result in a stream which is not usable for some "
1646  "purposes (e.g. not muxable to some containers).\n");
1647  }
1648 
1649  return 0;
1650 }
1651 
1653 {
1654 #if VA_CHECK_VERSION(0, 36, 0)
1655  VAAPIEncodeContext *ctx = avctx->priv_data;
1656  VAStatus vas;
1657  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1658  int quality = avctx->compression_level;
1659 
1660  vas = vaGetConfigAttributes(ctx->hwctx->display,
1661  ctx->va_profile,
1662  ctx->va_entrypoint,
1663  &attr, 1);
1664  if (vas != VA_STATUS_SUCCESS) {
1665  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
1666  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1667  return AVERROR_EXTERNAL;
1668  }
1669 
1670  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1671  if (quality != 0) {
1672  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
1673  "supported: will use default quality level.\n");
1674  }
1675  } else {
1676  if (quality > attr.value) {
1677  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
1678  "valid range is 0-%d, using %d.\n",
1679  attr.value, attr.value);
1680  quality = attr.value;
1681  }
1682 
1683  ctx->quality_params.misc.type = VAEncMiscParameterTypeQualityLevel;
1684  ctx->quality_params.quality.quality_level = quality;
1685 
1686  vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc,
1687  sizeof(ctx->quality_params));
1688  }
1689 #else
1690  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
1691  "not supported with this VAAPI version.\n");
1692 #endif
1693 
1694  return 0;
1695 }
1696 
1697 static void vaapi_encode_free_output_buffer(void *opaque,
1698  uint8_t *data)
1699 {
1700  AVCodecContext *avctx = opaque;
1701  VAAPIEncodeContext *ctx = avctx->priv_data;
1702  VABufferID buffer_id;
1703 
1704  buffer_id = (VABufferID)(uintptr_t)data;
1705 
1706  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1707 
1708  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
1709 }
1710 
1712  int size)
1713 {
1714  AVCodecContext *avctx = opaque;
1715  VAAPIEncodeContext *ctx = avctx->priv_data;
1716  VABufferID buffer_id;
1717  VAStatus vas;
1718  AVBufferRef *ref;
1719 
1720  // The output buffer size is fixed, so it needs to be large enough
1721  // to hold the largest possible compressed frame. We assume here
1722  // that the uncompressed frame plus some header data is an upper
1723  // bound on that.
1724  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
1725  VAEncCodedBufferType,
1726  3 * ctx->surface_width * ctx->surface_height +
1727  (1 << 16), 1, 0, &buffer_id);
1728  if (vas != VA_STATUS_SUCCESS) {
1729  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
1730  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
1731  return NULL;
1732  }
1733 
1734  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
1735 
1736  ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
1737  sizeof(buffer_id),
1739  avctx, AV_BUFFER_FLAG_READONLY);
1740  if (!ref) {
1741  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1742  return NULL;
1743  }
1744 
1745  return ref;
1746 }
1747 
1749 {
1750  VAAPIEncodeContext *ctx = avctx->priv_data;
1751  AVVAAPIHWConfig *hwconfig = NULL;
1752  AVHWFramesConstraints *constraints = NULL;
1753  enum AVPixelFormat recon_format;
1754  int err, i;
1755 
1756  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
1757  if (!hwconfig) {
1758  err = AVERROR(ENOMEM);
1759  goto fail;
1760  }
1761  hwconfig->config_id = ctx->va_config;
1762 
1764  hwconfig);
1765  if (!constraints) {
1766  err = AVERROR(ENOMEM);
1767  goto fail;
1768  }
1769 
1770  // Probably we can use the input surface format as the surface format
1771  // of the reconstructed frames. If not, we just pick the first (only?)
1772  // format in the valid list and hope that it all works.
1773  recon_format = AV_PIX_FMT_NONE;
1774  if (constraints->valid_sw_formats) {
1775  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
1776  if (ctx->input_frames->sw_format ==
1777  constraints->valid_sw_formats[i]) {
1778  recon_format = ctx->input_frames->sw_format;
1779  break;
1780  }
1781  }
1782  if (recon_format == AV_PIX_FMT_NONE) {
1783  // No match. Just use the first in the supported list and
1784  // hope for the best.
1785  recon_format = constraints->valid_sw_formats[0];
1786  }
1787  } else {
1788  // No idea what to use; copy input format.
1789  recon_format = ctx->input_frames->sw_format;
1790  }
1791  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
1792  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
1793 
1794  if (ctx->surface_width < constraints->min_width ||
1795  ctx->surface_height < constraints->min_height ||
1796  ctx->surface_width > constraints->max_width ||
1797  ctx->surface_height > constraints->max_height) {
1798  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
1799  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
1800  ctx->surface_width, ctx->surface_height,
1801  constraints->min_width, constraints->max_width,
1802  constraints->min_height, constraints->max_height);
1803  err = AVERROR(EINVAL);
1804  goto fail;
1805  }
1806 
1807  av_freep(&hwconfig);
1808  av_hwframe_constraints_free(&constraints);
1809 
1811  if (!ctx->recon_frames_ref) {
1812  err = AVERROR(ENOMEM);
1813  goto fail;
1814  }
1816 
1818  ctx->recon_frames->sw_format = recon_format;
1819  ctx->recon_frames->width = ctx->surface_width;
1820  ctx->recon_frames->height = ctx->surface_height;
1821  // At most three IDR/I/P frames and two runs of B frames can be in
1822  // flight at any one time.
1823  ctx->recon_frames->initial_pool_size = 3 + 2 * ctx->b_per_p;
1824 
1826  if (err < 0) {
1827  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
1828  "frame context: %d.\n", err);
1829  goto fail;
1830  }
1831 
1832  err = 0;
1833  fail:
1834  av_freep(&hwconfig);
1835  av_hwframe_constraints_free(&constraints);
1836  return err;
1837 }
1838 
1840 {
1841  VAAPIEncodeContext *ctx = avctx->priv_data;
1842  AVVAAPIFramesContext *recon_hwctx = NULL;
1843  VAStatus vas;
1844  int err;
1845 
1846  if (!avctx->hw_frames_ctx) {
1847  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
1848  "required to associate the encoding device.\n");
1849  return AVERROR(EINVAL);
1850  }
1851 
1852  ctx->va_config = VA_INVALID_ID;
1853  ctx->va_context = VA_INVALID_ID;
1854 
1856  if (!ctx->input_frames_ref) {
1857  err = AVERROR(ENOMEM);
1858  goto fail;
1859  }
1861 
1863  if (!ctx->device_ref) {
1864  err = AVERROR(ENOMEM);
1865  goto fail;
1866  }
1867  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
1868  ctx->hwctx = ctx->device->hwctx;
1869 
1870  err = vaapi_encode_profile_entrypoint(avctx);
1871  if (err < 0)
1872  goto fail;
1873 
1874  err = vaapi_encode_init_rate_control(avctx);
1875  if (err < 0)
1876  goto fail;
1877 
1878  err = vaapi_encode_init_gop_structure(avctx);
1879  if (err < 0)
1880  goto fail;
1881 
1882  err = vaapi_encode_init_slice_structure(avctx);
1883  if (err < 0)
1884  goto fail;
1885 
1886  err = vaapi_encode_init_packed_headers(avctx);
1887  if (err < 0)
1888  goto fail;
1889 
1890  if (avctx->compression_level >= 0) {
1891  err = vaapi_encode_init_quality(avctx);
1892  if (err < 0)
1893  goto fail;
1894  }
1895 
1896  vas = vaCreateConfig(ctx->hwctx->display,
1897  ctx->va_profile, ctx->va_entrypoint,
1899  &ctx->va_config);
1900  if (vas != VA_STATUS_SUCCESS) {
1901  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1902  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1903  err = AVERROR(EIO);
1904  goto fail;
1905  }
1906 
1907  err = vaapi_encode_create_recon_frames(avctx);
1908  if (err < 0)
1909  goto fail;
1910 
1911  recon_hwctx = ctx->recon_frames->hwctx;
1912  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
1913  ctx->surface_width, ctx->surface_height,
1914  VA_PROGRESSIVE,
1915  recon_hwctx->surface_ids,
1916  recon_hwctx->nb_surfaces,
1917  &ctx->va_context);
1918  if (vas != VA_STATUS_SUCCESS) {
1919  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1920  "context: %d (%s).\n", vas, vaErrorStr(vas));
1921  err = AVERROR(EIO);
1922  goto fail;
1923  }
1924 
1925  ctx->output_buffer_pool =
1926  av_buffer_pool_init2(sizeof(VABufferID), avctx,
1928  if (!ctx->output_buffer_pool) {
1929  err = AVERROR(ENOMEM);
1930  goto fail;
1931  }
1932 
1933  if (ctx->codec->configure) {
1934  err = ctx->codec->configure(avctx);
1935  if (err < 0)
1936  goto fail;
1937  }
1938 
1939  ctx->input_order = 0;
1940  ctx->output_delay = ctx->b_per_p;
1941  ctx->decode_delay = 1;
1942  ctx->output_order = - ctx->output_delay - 1;
1943 
1944  if (ctx->codec->sequence_params_size > 0) {
1945  ctx->codec_sequence_params =
1947  if (!ctx->codec_sequence_params) {
1948  err = AVERROR(ENOMEM);
1949  goto fail;
1950  }
1951  }
1952  if (ctx->codec->picture_params_size > 0) {
1953  ctx->codec_picture_params =
1955  if (!ctx->codec_picture_params) {
1956  err = AVERROR(ENOMEM);
1957  goto fail;
1958  }
1959  }
1960 
1961  if (ctx->codec->init_sequence_params) {
1962  err = ctx->codec->init_sequence_params(avctx);
1963  if (err < 0) {
1964  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
1965  "failed: %d.\n", err);
1966  goto fail;
1967  }
1968  }
1969 
1970  // This should be configurable somehow. (Needs testing on a machine
1971  // where it actually overlaps properly, though.)
1972  ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;
1973 
1974  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
1975  ctx->codec->write_sequence_header &&
1978  size_t bit_len = 8 * sizeof(data);
1979 
1980  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
1981  if (err < 0) {
1982  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
1983  "for extradata: %d.\n", err);
1984  goto fail;
1985  } else {
1986  avctx->extradata_size = (bit_len + 7) / 8;
1987  avctx->extradata = av_mallocz(avctx->extradata_size +
1989  if (!avctx->extradata) {
1990  err = AVERROR(ENOMEM);
1991  goto fail;
1992  }
1993  memcpy(avctx->extradata, data, avctx->extradata_size);
1994  }
1995  }
1996 
1997  return 0;
1998 
1999 fail:
2000  ff_vaapi_encode_close(avctx);
2001  return err;
2002 }
2003 
2005 {
2006  VAAPIEncodeContext *ctx = avctx->priv_data;
2007  VAAPIEncodePicture *pic, *next;
2008 
2009  for (pic = ctx->pic_start; pic; pic = next) {
2010  next = pic->next;
2011  vaapi_encode_free(avctx, pic);
2012  }
2013 
2015 
2016  if (ctx->va_context != VA_INVALID_ID) {
2017  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2018  ctx->va_context = VA_INVALID_ID;
2019  }
2020 
2021  if (ctx->va_config != VA_INVALID_ID) {
2022  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2023  ctx->va_config = VA_INVALID_ID;
2024  }
2025 
2028 
2031  av_buffer_unref(&ctx->device_ref);
2032 
2033  return 0;
2034 }
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:3056
VASurfaceID input_surface
Definition: vaapi_encode.h:76
VAProfile va_profile
Definition: vaapi_encode.h:143
VAEncMiscParameterBuffer misc
Definition: vaapi_encode.h:183
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:2446
VAAPI-specific data associated with a frame pool.
This structure describes decoded (raw) audio or video data.
Definition: frame.h:226
VAEntrypoint va_entrypoint
Definition: vaapi_encode.h:145
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
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:1583
const char * desc
Definition: nvenc.c:65
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:1793
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:2435
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1446
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
int(* write_slice_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice, char *data, size_t *data_len)
Definition: vaapi_encode.h:299
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:202
AVBufferRef * input_frames_ref
Definition: vaapi_encode.h:165
static AVPacket pkt
VAEncMiscParameterHRD hrd
Definition: vaapi_encode.h:188
size_t picture_params_size
Definition: vaapi_encode.h:274
AVHWDeviceContext * device
Definition: vaapi_encode.h:161
static int vaapi_encode_clear_old(AVCodecContext *avctx)
Definition: vaapi_encode.c:863
int profile
profile
Definition: avcodec.h:2859
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:106
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:556
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:1656
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:562
unsigned int va_packed_headers
Definition: vaapi_encode.h:151
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
VAEncMiscParameterFrameRate fr
Definition: vaapi_encode.h:192
static VAAPIEncodePicture * vaapi_encode_alloc(void)
Definition: vaapi_encode.c:573
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
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:137
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int(* write_picture_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, char *data, size_t *data_len)
Definition: vaapi_encode.h:296
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:319
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1634
AVBufferRef * output_buffer_ref
Definition: vaapi_encode.h:84
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:82
uint8_t * data
Definition: avcodec.h:1445
struct VAAPIEncodeContext::@161 rc_params
VAContextID va_context
Definition: vaapi_encode.h:158
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
VASurfaceID recon_surface
Definition: vaapi_encode.h:79
#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:101
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
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:1477
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:147
VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]
Definition: vaapi_encode.h:154
AVHWFramesContext * input_frames
Definition: vaapi_encode.h:166
int width
Definition: frame.h:284
#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
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:2378
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
VAEncMiscParameterBuffer * global_params[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:177
int(* configure)(AVCodecContext *avctx)
Definition: vaapi_encode.h:269
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1613
GLenum GLint * params
Definition: opengl_enc.c:114
struct VAAPIEncodeContext::@163 fr_params
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:149
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:329
int(* init_picture_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.h:279
void * codec_picture_params
Definition: vaapi_encode.h:88
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:117
int(* write_extra_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode.h:316
VAConfigID va_config
Definition: vaapi_encode.h:157
AVHWFramesContext * recon_frames
Definition: vaapi_encode.h:170
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1451
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:2392
static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
VAAPIEncodeSlice * slices
Definition: vaapi_encode.h:94
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:198
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:83
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:309
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:842
unsigned int value
int width
picture width / height.
Definition: avcodec.h:1706
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:3213
const VAAPIEncodeProfile * profile
Definition: vaapi_encode.h:140
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2860
const VAAPIEncodeProfile * profiles
Definition: vaapi_encode.h:261
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
AVFormatContext * ctx
Definition: movenc.c:48
struct VAAPIEncodePicture * next
Definition: vaapi_encode.h:64
AVFrame * input_image
Definition: vaapi_encode.h:75
void * codec_picture_params
Definition: vaapi_encode.h:206
int n
Definition: avisynth_c.h:684
int64_t ts_ring[MAX_REORDER_DELAY *3]
Definition: vaapi_encode.h:233
AVBufferPool * output_buffer_pool
Definition: vaapi_encode.h:173
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)
VADisplay display
The VADisplay handle, to be filled by the user.
int(* write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len)
Definition: vaapi_encode.h:294
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:91
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:450
const struct VAAPIEncodeType * codec
Definition: vaapi_encode.h:116
Libavcodec external API header.
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:1605
VAAPIEncodePicture * pic_start
Definition: vaapi_encode.h:209
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:1533
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(* write_extra_buffer)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode.h:308
int qmin
minimum quantizer
Definition: avcodec.h:2371
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:275
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:690
GLint GLenum type
Definition: opengl_enc.c:105
int extradata_size
Definition: avcodec.h:1635
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
static int vaapi_encode_step(AVCodecContext *avctx, VAAPIEncodePicture *target)
Definition: vaapi_encode.c:620
AVBufferRef * recon_frames_ref
Definition: vaapi_encode.h:169
static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, VAEncMiscParameterBuffer *buffer, size_t size)
static int vaapi_encode_truncate_gop(AVCodecContext *avctx)
Definition: vaapi_encode.c:802
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
mfxU16 profile
Definition: qsvenc.c:44
AVBufferRef * device_ref
Definition: vaapi_encode.h:160
VAAPIEncodePicture * pic_end
Definition: vaapi_encode.h:209
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:240
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:891
size_t global_params_size[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:178
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1728
VAEncMiscParameterRateControl rc
Definition: vaapi_encode.h:184
A reference to a data buffer.
Definition: buffer.h:81
size_t sequence_params_size
Definition: vaapi_encode.h:273
VAProfile va_profile
Definition: vaapi_encode.h:109
int
common internal and external API header
if(ret< 0)
Definition: vf_mcdeint.c:279
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
struct VAAPIEncodeContext::@162 hrd_params
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:243
static int vaapi_encode_get_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
Definition: vaapi_encode.c:697
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet)
Definition: vaapi_encode.c:895
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:782
int slices
Number of slices.
Definition: avcodec.h:2180
void * priv_data
Definition: avcodec.h:1560
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
#define av_free(p)
static const VAEntrypoint vaapi_encode_entrypoints_normal[]
int len
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:60
AVFrame * recon_image
Definition: vaapi_encode.h:78
static int vaapi_encode_free(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:588
int(* init_slice_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice)
Definition: vaapi_encode.h:281
VAConfigID config_id
ID of a VAAPI pipeline configuration.
int(* init_sequence_params)(AVCodecContext *avctx)
Definition: vaapi_encode.h:278
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:1444
unsigned int desired_packed_headers
Definition: vaapi_encode.h:124
int height
Definition: frame.h:284
enum VAAPIEncodeContext::@164 issue_mode
#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:690
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)
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:2362
int depth
Number of bits in the component.
Definition: pixdesc.h:58
VABufferID output_buffer
Definition: vaapi_encode.h:85
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:1422
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1438
for(j=16;j >0;--j)
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
GLuint buffer
Definition: opengl_enc.c:102
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:2407
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:495
AVVAAPIDeviceContext * hwctx
Definition: vaapi_encode.h:162
static uint8_t tmp[11]
Definition: aes_ctr.c:26