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, "Compatible profile %s (%d) "
1139  "is not supported by driver.\n", profile_string,
1140  profile->va_profile);
1141  continue;
1142  }
1143 
1144  ctx->profile = profile;
1145  break;
1146  }
1147  if (!ctx->profile) {
1148  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
1149  err = AVERROR(ENOSYS);
1150  goto fail;
1151  }
1152 
1153  avctx->profile = profile->av_profile;
1154  ctx->va_profile = profile->va_profile;
1155  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
1156  profile_string, ctx->va_profile);
1157 
1158  n = vaMaxNumEntrypoints(ctx->hwctx->display);
1159  va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
1160  if (!va_entrypoints) {
1161  err = AVERROR(ENOMEM);
1162  goto fail;
1163  }
1164  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
1165  va_entrypoints, &n);
1166  if (vas != VA_STATUS_SUCCESS) {
1167  av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
1168  "profile %s (%d): %d (%s).\n", profile_string,
1169  ctx->va_profile, vas, vaErrorStr(vas));
1170  err = AVERROR_EXTERNAL;
1171  goto fail;
1172  }
1173 
1174  for (i = 0; i < n; i++) {
1175  for (j = 0; usable_entrypoints[j]; j++) {
1176  if (va_entrypoints[i] == usable_entrypoints[j])
1177  break;
1178  }
1179  if (usable_entrypoints[j])
1180  break;
1181  }
1182  if (i >= n) {
1183  av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found "
1184  "for profile %s (%d).\n", profile_string, ctx->va_profile);
1185  err = AVERROR(ENOSYS);
1186  goto fail;
1187  }
1188 
1189  ctx->va_entrypoint = va_entrypoints[i];
1190 #if VA_CHECK_VERSION(1, 0, 0)
1191  entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
1192 #else
1193  entrypoint_string = "(no entrypoint names)";
1194 #endif
1195  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n",
1196  entrypoint_string, ctx->va_entrypoint);
1197 
1198  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) {
1199  rt_format = &vaapi_encode_rt_formats[i];
1200  if (rt_format->depth == depth &&
1201  rt_format->nb_components == profile->nb_components &&
1202  rt_format->log2_chroma_w == profile->log2_chroma_w &&
1203  rt_format->log2_chroma_h == profile->log2_chroma_h)
1204  break;
1205  }
1206  if (i >= FF_ARRAY_ELEMS(vaapi_encode_rt_formats)) {
1207  av_log(avctx, AV_LOG_ERROR, "No usable render target format "
1208  "found for profile %s (%d) entrypoint %s (%d).\n",
1209  profile_string, ctx->va_profile,
1210  entrypoint_string, ctx->va_entrypoint);
1211  err = AVERROR(ENOSYS);
1212  goto fail;
1213  }
1214 
1215  rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1216  vas = vaGetConfigAttributes(ctx->hwctx->display,
1217  ctx->va_profile, ctx->va_entrypoint,
1218  &rt_format_attr, 1);
1219  if (vas != VA_STATUS_SUCCESS) {
1220  av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
1221  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1222  err = AVERROR_EXTERNAL;
1223  goto fail;
1224  }
1225 
1226  if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1227  av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not "
1228  "supported by driver: assuming surface RT format %s "
1229  "is valid.\n", rt_format->name);
1230  } else if (!(rt_format_attr.value & rt_format->value)) {
1231  av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported "
1232  "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1233  rt_format->name, profile_string, ctx->va_profile,
1234  entrypoint_string, ctx->va_entrypoint);
1235  err = AVERROR(ENOSYS);
1236  goto fail;
1237  } else {
1238  av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target "
1239  "format %s (%#x).\n", rt_format->name, rt_format->value);
1241  (VAConfigAttrib) {
1242  .type = VAConfigAttribRTFormat,
1243  .value = rt_format->value,
1244  };
1245  }
1246 
1247  err = 0;
1248 fail:
1249  av_freep(&va_profiles);
1250  av_freep(&va_entrypoints);
1251  return err;
1252 }
1253 
1255 {
1256  VAAPIEncodeContext *ctx = avctx->priv_data;
1257  int64_t rc_bits_per_second;
1258  int rc_target_percentage;
1259  int rc_window_size;
1260  int64_t hrd_buffer_size;
1261  int64_t hrd_initial_buffer_fullness;
1262  int fr_num, fr_den;
1263  VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1264  VAStatus vas;
1265 
1266  vas = vaGetConfigAttributes(ctx->hwctx->display,
1267  ctx->va_profile, ctx->va_entrypoint,
1268  &rc_attr, 1);
1269  if (vas != VA_STATUS_SUCCESS) {
1270  av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1271  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1272  return AVERROR_EXTERNAL;
1273  }
1274 
1275  if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1276  av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1277  "supported rate control modes: assuming constant-quality.\n");
1278  ctx->va_rc_mode = VA_RC_CQP;
1279  return 0;
1280  }
1281  if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY ||
1282  avctx->flags & AV_CODEC_FLAG_QSCALE ||
1283  avctx->bit_rate <= 0) {
1284  if (rc_attr.value & VA_RC_CQP) {
1285  av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
1286  ctx->va_rc_mode = VA_RC_CQP;
1287  if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) {
1288  av_log(avctx, AV_LOG_WARNING, "Bitrate target parameters "
1289  "ignored in constant-quality mode.\n");
1290  }
1291  return 0;
1292  } else {
1293  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1294  "constant-quality mode (%#x).\n", rc_attr.value);
1295  return AVERROR(EINVAL);
1296  }
1297  }
1298 
1299  if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
1300  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1301  "bitrate-targetted rate control modes.\n");
1302  return AVERROR(EINVAL);
1303  }
1304 
1305  if (avctx->rc_buffer_size)
1306  hrd_buffer_size = avctx->rc_buffer_size;
1307  else if (avctx->rc_max_rate > 0)
1308  hrd_buffer_size = avctx->rc_max_rate;
1309  else
1310  hrd_buffer_size = avctx->bit_rate;
1311  if (avctx->rc_initial_buffer_occupancy) {
1312  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1313  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1314  "must have initial buffer size (%d) < "
1315  "buffer size (%"PRId64").\n",
1316  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1317  return AVERROR(EINVAL);
1318  }
1319  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1320  } else {
1321  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1322  }
1323 
1324  if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
1325  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have "
1326  "bitrate (%"PRId64") <= maxrate (%"PRId64").\n",
1327  avctx->bit_rate, avctx->rc_max_rate);
1328  return AVERROR(EINVAL);
1329  }
1330 
1331  if (avctx->rc_max_rate > avctx->bit_rate) {
1332  if (!(rc_attr.value & VA_RC_VBR)) {
1333  av_log(avctx, AV_LOG_WARNING, "Driver does not support "
1334  "VBR mode (%#x), using CBR mode instead.\n",
1335  rc_attr.value);
1336  ctx->va_rc_mode = VA_RC_CBR;
1337 
1338  rc_bits_per_second = avctx->bit_rate;
1339  rc_target_percentage = 100;
1340  } else {
1341  ctx->va_rc_mode = VA_RC_VBR;
1342 
1343  rc_bits_per_second = avctx->rc_max_rate;
1344  rc_target_percentage = (avctx->bit_rate * 100) /
1345  avctx->rc_max_rate;
1346  }
1347 
1348  } else if (avctx->rc_max_rate == avctx->bit_rate) {
1349  if (!(rc_attr.value & VA_RC_CBR)) {
1350  av_log(avctx, AV_LOG_WARNING, "Driver does not support "
1351  "CBR mode (%#x), using VBR mode instead.\n",
1352  rc_attr.value);
1353  ctx->va_rc_mode = VA_RC_VBR;
1354  } else {
1355  ctx->va_rc_mode = VA_RC_CBR;
1356  }
1357 
1358  rc_bits_per_second = avctx->bit_rate;
1359  rc_target_percentage = 100;
1360 
1361  } else {
1362  if (rc_attr.value & VA_RC_VBR) {
1363  ctx->va_rc_mode = VA_RC_VBR;
1364 
1365  // We only have a target bitrate, but VAAPI requires that a
1366  // maximum rate be supplied as well. Since the user has
1367  // offered no particular constraint, arbitrarily pick a
1368  // maximum rate of double the target rate.
1369  rc_bits_per_second = 2 * avctx->bit_rate;
1370  rc_target_percentage = 50;
1371  } else {
1372  ctx->va_rc_mode = VA_RC_CBR;
1373 
1374  rc_bits_per_second = avctx->bit_rate;
1375  rc_target_percentage = 100;
1376  }
1377  }
1378 
1379  rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1380 
1381  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps "
1382  "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR",
1383  rc_target_percentage, rc_bits_per_second, rc_window_size);
1384  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1385  "initial fullness %"PRId64" bits.\n",
1386  hrd_buffer_size, hrd_initial_buffer_fullness);
1387 
1388  if (rc_bits_per_second > UINT32_MAX ||
1389  hrd_buffer_size > UINT32_MAX ||
1390  hrd_initial_buffer_fullness > UINT32_MAX) {
1391  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1392  "greater are not supported by VAAPI.\n");
1393  return AVERROR(EINVAL);
1394  }
1395 
1396  ctx->va_bit_rate = rc_bits_per_second;
1397 
1399  (VAConfigAttrib) {
1400  .type = VAConfigAttribRateControl,
1401  .value = ctx->va_rc_mode,
1402  };
1403 
1404  ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
1405  ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
1406  .bits_per_second = rc_bits_per_second,
1407  .target_percentage = rc_target_percentage,
1408  .window_size = rc_window_size,
1409  .initial_qp = 0,
1410  .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
1411  .basic_unit_size = 0,
1412 #if VA_CHECK_VERSION(1, 1, 0)
1413  .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
1414 #endif
1415  };
1417  sizeof(ctx->rc_params));
1418 
1419  ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
1420  ctx->hrd_params.hrd = (VAEncMiscParameterHRD) {
1421  .initial_buffer_fullness = hrd_initial_buffer_fullness,
1422  .buffer_size = hrd_buffer_size,
1423  };
1425  sizeof(ctx->hrd_params));
1426 
1427  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1428  av_reduce(&fr_num, &fr_den,
1429  avctx->framerate.num, avctx->framerate.den, 65535);
1430  else
1431  av_reduce(&fr_num, &fr_den,
1432  avctx->time_base.den, avctx->time_base.num, 65535);
1433 
1434  ctx->fr_params.misc.type = VAEncMiscParameterTypeFrameRate;
1435  ctx->fr_params.fr.framerate = (unsigned int)fr_den << 16 | fr_num;
1436 
1437 #if VA_CHECK_VERSION(0, 40, 0)
1439  sizeof(ctx->fr_params));
1440 #endif
1441 
1442  return 0;
1443 }
1444 
1446 {
1447  VAAPIEncodeContext *ctx = avctx->priv_data;
1448  VAStatus vas;
1449  VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1450  uint32_t ref_l0, ref_l1;
1451 
1452  vas = vaGetConfigAttributes(ctx->hwctx->display,
1453  ctx->va_profile,
1454  ctx->va_entrypoint,
1455  &attr, 1);
1456  if (vas != VA_STATUS_SUCCESS) {
1457  av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
1458  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1459  return AVERROR_EXTERNAL;
1460  }
1461 
1462  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1463  ref_l0 = ref_l1 = 0;
1464  } else {
1465  ref_l0 = attr.value & 0xffff;
1466  ref_l1 = attr.value >> 16 & 0xffff;
1467  }
1468 
1469  if (avctx->gop_size <= 1) {
1470  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
1471  ctx->gop_size = 1;
1472  } else if (ref_l0 < 1) {
1473  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1474  "reference frames.\n");
1475  return AVERROR(EINVAL);
1476  } else if (ref_l1 < 1 || avctx->max_b_frames < 1) {
1477  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
1478  "(supported references: %d / %d).\n", ref_l0, ref_l1);
1479  ctx->gop_size = avctx->gop_size;
1480  ctx->p_per_i = INT_MAX;
1481  ctx->b_per_p = 0;
1482  } else {
1483  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
1484  "(supported references: %d / %d).\n", ref_l0, ref_l1);
1485  ctx->gop_size = avctx->gop_size;
1486  ctx->p_per_i = INT_MAX;
1487  ctx->b_per_p = avctx->max_b_frames;
1488  }
1489 
1490  return 0;
1491 }
1492 
1494 {
1495  VAAPIEncodeContext *ctx = avctx->priv_data;
1496  VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
1497  { VAConfigAttribEncSliceStructure } };
1498  VAStatus vas;
1499  uint32_t max_slices, slice_structure;
1500  int req_slices;
1501 
1502  if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
1503  if (avctx->slices > 0) {
1504  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
1505  "but this codec does not support controlling slices.\n");
1506  }
1507  return 0;
1508  }
1509 
1510  ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
1511  ctx->slice_block_height;
1512  ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
1513  ctx->slice_block_width;
1514 
1515  if (avctx->slices <= 1) {
1516  ctx->nb_slices = 1;
1517  ctx->slice_size = ctx->slice_block_rows;
1518  return 0;
1519  }
1520 
1521  vas = vaGetConfigAttributes(ctx->hwctx->display,
1522  ctx->va_profile,
1523  ctx->va_entrypoint,
1524  attr, FF_ARRAY_ELEMS(attr));
1525  if (vas != VA_STATUS_SUCCESS) {
1526  av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
1527  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1528  return AVERROR_EXTERNAL;
1529  }
1530  max_slices = attr[0].value;
1531  slice_structure = attr[1].value;
1532  if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1533  slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1534  av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
1535  "pictures as multiple slices.\n.");
1536  return AVERROR(EINVAL);
1537  }
1538 
1539  // For fixed-size slices currently we only support whole rows, making
1540  // rectangular slices. This could be extended to arbitrary runs of
1541  // blocks, but since slices tend to be a conformance requirement and
1542  // most cases (such as broadcast or bluray) want rectangular slices
1543  // only it would need to be gated behind another option.
1544  if (avctx->slices > ctx->slice_block_rows) {
1545  av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1546  "configured number of slices (%d < %d); using "
1547  "maximum.\n", ctx->slice_block_rows, avctx->slices);
1548  req_slices = ctx->slice_block_rows;
1549  } else {
1550  req_slices = avctx->slices;
1551  }
1552  if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1553  slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1554  ctx->nb_slices = req_slices;
1555  ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1556  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1557  int k;
1558  for (k = 1;; k *= 2) {
1559  if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1560  break;
1561  }
1562  ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1563  ctx->slice_size = k;
1564 #if VA_CHECK_VERSION(1, 0, 0)
1565  } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1566  ctx->nb_slices = ctx->slice_block_rows;
1567  ctx->slice_size = 1;
1568 #endif
1569  } else {
1570  av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1571  "slice structure modes (%#x).\n", slice_structure);
1572  return AVERROR(EINVAL);
1573  }
1574 
1575  if (ctx->nb_slices > avctx->slices) {
1576  av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "
1577  "%d (from %d) due to driver constraints on slice "
1578  "structure.\n", ctx->nb_slices, avctx->slices);
1579  }
1580  if (ctx->nb_slices > max_slices) {
1581  av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1582  "encoding with %d slices (max %"PRIu32").\n",
1583  ctx->nb_slices, max_slices);
1584  return AVERROR(EINVAL);
1585  }
1586 
1587  av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices "
1588  "(default size %d block rows).\n",
1589  ctx->nb_slices, ctx->slice_size);
1590  return 0;
1591 }
1592 
1594 {
1595  VAAPIEncodeContext *ctx = avctx->priv_data;
1596  VAStatus vas;
1597  VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1598 
1599  vas = vaGetConfigAttributes(ctx->hwctx->display,
1600  ctx->va_profile,
1601  ctx->va_entrypoint,
1602  &attr, 1);
1603  if (vas != VA_STATUS_SUCCESS) {
1604  av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
1605  "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1606  return AVERROR_EXTERNAL;
1607  }
1608 
1609  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1610  if (ctx->desired_packed_headers) {
1611  av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
1612  "packed headers (wanted %#x).\n",
1613  ctx->desired_packed_headers);
1614  } else {
1615  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
1616  "packed headers (none wanted).\n");
1617  }
1618  ctx->va_packed_headers = 0;
1619  } else {
1620  if (ctx->desired_packed_headers & ~attr.value) {
1621  av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
1622  "wanted packed headers (wanted %#x, found %#x).\n",
1623  ctx->desired_packed_headers, attr.value);
1624  } else {
1625  av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
1626  "available (wanted %#x, found %#x).\n",
1627  ctx->desired_packed_headers, attr.value);
1628  }
1629  ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
1630  }
1631 
1632  if (ctx->va_packed_headers) {
1634  (VAConfigAttrib) {
1635  .type = VAConfigAttribEncPackedHeaders,
1636  .value = ctx->va_packed_headers,
1637  };
1638  }
1639 
1640  if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1641  !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1642  (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
1643  av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
1644  "sequence headers, but a global header is requested.\n");
1645  av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
1646  "this may result in a stream which is not usable for some "
1647  "purposes (e.g. not muxable to some containers).\n");
1648  }
1649 
1650  return 0;
1651 }
1652 
1654 {
1655 #if VA_CHECK_VERSION(0, 36, 0)
1656  VAAPIEncodeContext *ctx = avctx->priv_data;
1657  VAStatus vas;
1658  VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1659  int quality = avctx->compression_level;
1660 
1661  vas = vaGetConfigAttributes(ctx->hwctx->display,
1662  ctx->va_profile,
1663  ctx->va_entrypoint,
1664  &attr, 1);
1665  if (vas != VA_STATUS_SUCCESS) {
1666  av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
1667  "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1668  return AVERROR_EXTERNAL;
1669  }
1670 
1671  if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1672  if (quality != 0) {
1673  av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
1674  "supported: will use default quality level.\n");
1675  }
1676  } else {
1677  if (quality > attr.value) {
1678  av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
1679  "valid range is 0-%d, using %d.\n",
1680  attr.value, attr.value);
1681  quality = attr.value;
1682  }
1683 
1684  ctx->quality_params.misc.type = VAEncMiscParameterTypeQualityLevel;
1685  ctx->quality_params.quality.quality_level = quality;
1686 
1687  vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc,
1688  sizeof(ctx->quality_params));
1689  }
1690 #else
1691  av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
1692  "not supported with this VAAPI version.\n");
1693 #endif
1694 
1695  return 0;
1696 }
1697 
1698 static void vaapi_encode_free_output_buffer(void *opaque,
1699  uint8_t *data)
1700 {
1701  AVCodecContext *avctx = opaque;
1702  VAAPIEncodeContext *ctx = avctx->priv_data;
1703  VABufferID buffer_id;
1704 
1705  buffer_id = (VABufferID)(uintptr_t)data;
1706 
1707  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1708 
1709  av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
1710 }
1711 
1713  int size)
1714 {
1715  AVCodecContext *avctx = opaque;
1716  VAAPIEncodeContext *ctx = avctx->priv_data;
1717  VABufferID buffer_id;
1718  VAStatus vas;
1719  AVBufferRef *ref;
1720 
1721  // The output buffer size is fixed, so it needs to be large enough
1722  // to hold the largest possible compressed frame. We assume here
1723  // that the uncompressed frame plus some header data is an upper
1724  // bound on that.
1725  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
1726  VAEncCodedBufferType,
1727  3 * ctx->surface_width * ctx->surface_height +
1728  (1 << 16), 1, 0, &buffer_id);
1729  if (vas != VA_STATUS_SUCCESS) {
1730  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
1731  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
1732  return NULL;
1733  }
1734 
1735  av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
1736 
1737  ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
1738  sizeof(buffer_id),
1740  avctx, AV_BUFFER_FLAG_READONLY);
1741  if (!ref) {
1742  vaDestroyBuffer(ctx->hwctx->display, buffer_id);
1743  return NULL;
1744  }
1745 
1746  return ref;
1747 }
1748 
1750 {
1751  VAAPIEncodeContext *ctx = avctx->priv_data;
1752  AVVAAPIHWConfig *hwconfig = NULL;
1753  AVHWFramesConstraints *constraints = NULL;
1754  enum AVPixelFormat recon_format;
1755  int err, i;
1756 
1757  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
1758  if (!hwconfig) {
1759  err = AVERROR(ENOMEM);
1760  goto fail;
1761  }
1762  hwconfig->config_id = ctx->va_config;
1763 
1765  hwconfig);
1766  if (!constraints) {
1767  err = AVERROR(ENOMEM);
1768  goto fail;
1769  }
1770 
1771  // Probably we can use the input surface format as the surface format
1772  // of the reconstructed frames. If not, we just pick the first (only?)
1773  // format in the valid list and hope that it all works.
1774  recon_format = AV_PIX_FMT_NONE;
1775  if (constraints->valid_sw_formats) {
1776  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
1777  if (ctx->input_frames->sw_format ==
1778  constraints->valid_sw_formats[i]) {
1779  recon_format = ctx->input_frames->sw_format;
1780  break;
1781  }
1782  }
1783  if (recon_format == AV_PIX_FMT_NONE) {
1784  // No match. Just use the first in the supported list and
1785  // hope for the best.
1786  recon_format = constraints->valid_sw_formats[0];
1787  }
1788  } else {
1789  // No idea what to use; copy input format.
1790  recon_format = ctx->input_frames->sw_format;
1791  }
1792  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
1793  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
1794 
1795  if (ctx->surface_width < constraints->min_width ||
1796  ctx->surface_height < constraints->min_height ||
1797  ctx->surface_width > constraints->max_width ||
1798  ctx->surface_height > constraints->max_height) {
1799  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
1800  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
1801  ctx->surface_width, ctx->surface_height,
1802  constraints->min_width, constraints->max_width,
1803  constraints->min_height, constraints->max_height);
1804  err = AVERROR(EINVAL);
1805  goto fail;
1806  }
1807 
1808  av_freep(&hwconfig);
1809  av_hwframe_constraints_free(&constraints);
1810 
1812  if (!ctx->recon_frames_ref) {
1813  err = AVERROR(ENOMEM);
1814  goto fail;
1815  }
1817 
1819  ctx->recon_frames->sw_format = recon_format;
1820  ctx->recon_frames->width = ctx->surface_width;
1821  ctx->recon_frames->height = ctx->surface_height;
1822  // At most three IDR/I/P frames and two runs of B frames can be in
1823  // flight at any one time.
1824  ctx->recon_frames->initial_pool_size = 3 + 2 * ctx->b_per_p;
1825 
1827  if (err < 0) {
1828  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
1829  "frame context: %d.\n", err);
1830  goto fail;
1831  }
1832 
1833  err = 0;
1834  fail:
1835  av_freep(&hwconfig);
1836  av_hwframe_constraints_free(&constraints);
1837  return err;
1838 }
1839 
1841 {
1842  VAAPIEncodeContext *ctx = avctx->priv_data;
1843  AVVAAPIFramesContext *recon_hwctx = NULL;
1844  VAStatus vas;
1845  int err;
1846 
1847  if (!avctx->hw_frames_ctx) {
1848  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
1849  "required to associate the encoding device.\n");
1850  return AVERROR(EINVAL);
1851  }
1852 
1853  ctx->va_config = VA_INVALID_ID;
1854  ctx->va_context = VA_INVALID_ID;
1855 
1857  if (!ctx->input_frames_ref) {
1858  err = AVERROR(ENOMEM);
1859  goto fail;
1860  }
1862 
1864  if (!ctx->device_ref) {
1865  err = AVERROR(ENOMEM);
1866  goto fail;
1867  }
1868  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
1869  ctx->hwctx = ctx->device->hwctx;
1870 
1871  err = vaapi_encode_profile_entrypoint(avctx);
1872  if (err < 0)
1873  goto fail;
1874 
1875  err = vaapi_encode_init_rate_control(avctx);
1876  if (err < 0)
1877  goto fail;
1878 
1879  err = vaapi_encode_init_gop_structure(avctx);
1880  if (err < 0)
1881  goto fail;
1882 
1883  err = vaapi_encode_init_slice_structure(avctx);
1884  if (err < 0)
1885  goto fail;
1886 
1887  err = vaapi_encode_init_packed_headers(avctx);
1888  if (err < 0)
1889  goto fail;
1890 
1891  if (avctx->compression_level >= 0) {
1892  err = vaapi_encode_init_quality(avctx);
1893  if (err < 0)
1894  goto fail;
1895  }
1896 
1897  vas = vaCreateConfig(ctx->hwctx->display,
1898  ctx->va_profile, ctx->va_entrypoint,
1900  &ctx->va_config);
1901  if (vas != VA_STATUS_SUCCESS) {
1902  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1903  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1904  err = AVERROR(EIO);
1905  goto fail;
1906  }
1907 
1908  err = vaapi_encode_create_recon_frames(avctx);
1909  if (err < 0)
1910  goto fail;
1911 
1912  recon_hwctx = ctx->recon_frames->hwctx;
1913  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
1914  ctx->surface_width, ctx->surface_height,
1915  VA_PROGRESSIVE,
1916  recon_hwctx->surface_ids,
1917  recon_hwctx->nb_surfaces,
1918  &ctx->va_context);
1919  if (vas != VA_STATUS_SUCCESS) {
1920  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1921  "context: %d (%s).\n", vas, vaErrorStr(vas));
1922  err = AVERROR(EIO);
1923  goto fail;
1924  }
1925 
1926  ctx->output_buffer_pool =
1927  av_buffer_pool_init2(sizeof(VABufferID), avctx,
1929  if (!ctx->output_buffer_pool) {
1930  err = AVERROR(ENOMEM);
1931  goto fail;
1932  }
1933 
1934  if (ctx->codec->configure) {
1935  err = ctx->codec->configure(avctx);
1936  if (err < 0)
1937  goto fail;
1938  }
1939 
1940  ctx->input_order = 0;
1941  ctx->output_delay = ctx->b_per_p;
1942  ctx->decode_delay = 1;
1943  ctx->output_order = - ctx->output_delay - 1;
1944 
1945  if (ctx->codec->sequence_params_size > 0) {
1946  ctx->codec_sequence_params =
1948  if (!ctx->codec_sequence_params) {
1949  err = AVERROR(ENOMEM);
1950  goto fail;
1951  }
1952  }
1953  if (ctx->codec->picture_params_size > 0) {
1954  ctx->codec_picture_params =
1956  if (!ctx->codec_picture_params) {
1957  err = AVERROR(ENOMEM);
1958  goto fail;
1959  }
1960  }
1961 
1962  if (ctx->codec->init_sequence_params) {
1963  err = ctx->codec->init_sequence_params(avctx);
1964  if (err < 0) {
1965  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
1966  "failed: %d.\n", err);
1967  goto fail;
1968  }
1969  }
1970 
1971  // This should be configurable somehow. (Needs testing on a machine
1972  // where it actually overlaps properly, though.)
1973  ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;
1974 
1975  if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
1976  ctx->codec->write_sequence_header &&
1979  size_t bit_len = 8 * sizeof(data);
1980 
1981  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
1982  if (err < 0) {
1983  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
1984  "for extradata: %d.\n", err);
1985  goto fail;
1986  } else {
1987  avctx->extradata_size = (bit_len + 7) / 8;
1988  avctx->extradata = av_mallocz(avctx->extradata_size +
1990  if (!avctx->extradata) {
1991  err = AVERROR(ENOMEM);
1992  goto fail;
1993  }
1994  memcpy(avctx->extradata, data, avctx->extradata_size);
1995  }
1996  }
1997 
1998  return 0;
1999 
2000 fail:
2001  ff_vaapi_encode_close(avctx);
2002  return err;
2003 }
2004 
2006 {
2007  VAAPIEncodeContext *ctx = avctx->priv_data;
2008  VAAPIEncodePicture *pic, *next;
2009 
2010  for (pic = ctx->pic_start; pic; pic = next) {
2011  next = pic->next;
2012  vaapi_encode_free(avctx, pic);
2013  }
2014 
2016 
2017  if (ctx->va_context != VA_INVALID_ID) {
2018  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
2019  ctx->va_context = VA_INVALID_ID;
2020  }
2021 
2022  if (ctx->va_config != VA_INVALID_ID) {
2023  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
2024  ctx->va_config = VA_INVALID_ID;
2025  }
2026 
2029 
2032  av_buffer_unref(&ctx->device_ref);
2033 
2034  return 0;
2035 }
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:3087
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:2498
VAAPI-specific data associated with a frame pool.
This structure describes decoded (raw) audio or video data.
Definition: frame.h:268
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:1604
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:1814
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:2456
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1467
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:2883
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:1677
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:361
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1655
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:1466
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:1498
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:326
#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
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
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:2399
#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:1634
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:118
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:1472
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:2413
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:351
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:844
unsigned int value
int width
picture width / height.
Definition: avcodec.h:1727
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:3244
const VAAPIEncodeProfile * profile
Definition: vaapi_encode.h:140
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2884
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:1626
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:1554
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:2392
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:1656
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:282
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:893
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:1749
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:784
int slices
Number of slices.
Definition: avcodec.h:2201
void * priv_data
Definition: avcodec.h:1581
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:1465
unsigned int desired_packed_headers
Definition: vaapi_encode.h:124
int height
Definition: frame.h:326
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:2414
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:1443
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1459
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:2428
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