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