FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vaapi_encode.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <inttypes.h>
20 #include <string.h>
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/common.h"
24 #include "libavutil/log.h"
25 #include "libavutil/pixdesc.h"
26 
27 #include "vaapi_encode.h"
28 #include "avcodec.h"
29 
30 static const char *picture_type_name[] = { "IDR", "I", "P", "B" };
31 
33  VAAPIEncodePicture *pic,
34  int type, char *data, size_t bit_len)
35 {
37  VAStatus vas;
38  VABufferID param_buffer, data_buffer;
39  VAEncPackedHeaderParameterBuffer params = {
40  .type = type,
41  .bit_length = bit_len,
42  .has_emulation_bytes = 1,
43  };
44 
46 
47  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
48  VAEncPackedHeaderParameterBufferType,
49  sizeof(params), 1, &params, &param_buffer);
50  if (vas != VA_STATUS_SUCCESS) {
51  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
52  "for packed header (type %d): %d (%s).\n",
53  type, vas, vaErrorStr(vas));
54  return AVERROR(EIO);
55  }
56  pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
57 
58  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
59  VAEncPackedHeaderDataBufferType,
60  (bit_len + 7) / 8, 1, data, &data_buffer);
61  if (vas != VA_STATUS_SUCCESS) {
62  av_log(avctx, AV_LOG_ERROR, "Failed to create data 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++] = data_buffer;
68 
69  av_log(avctx, AV_LOG_DEBUG, "Packed header buffer (%d) is %#x/%#x "
70  "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
71  return 0;
72 }
73 
75  VAAPIEncodePicture *pic,
76  int type, char *data, size_t len)
77 {
79  VAStatus vas;
80  VABufferID buffer;
81 
83 
84  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
85  type, len, 1, data, &buffer);
86  if (vas != VA_STATUS_SUCCESS) {
87  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
88  "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
89  return AVERROR(EIO);
90  }
91  pic->param_buffers[pic->nb_param_buffers++] = buffer;
92 
93  av_log(avctx, AV_LOG_DEBUG, "Param buffer (%d) is %#x.\n",
94  type, buffer);
95  return 0;
96 }
97 
99  VAAPIEncodePicture *pic)
100 {
101  VAAPIEncodeContext *ctx = avctx->priv_data;
102  VAStatus vas;
103 
105 
106  if (pic->encode_complete) {
107  // Already waited for this picture.
108  return 0;
109  }
110 
111  av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
112  "(recon surface %#x).\n", pic->display_order,
113  pic->encode_order, pic->recon_surface);
114 
115  vas = vaSyncSurface(ctx->hwctx->display, pic->recon_surface);
116  if (vas != VA_STATUS_SUCCESS) {
117  av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
118  "%d (%s).\n", vas, vaErrorStr(vas));
119  return AVERROR(EIO);
120  }
121 
122  // Input is definitely finished with now.
123  av_frame_free(&pic->input_image);
124 
125  pic->encode_complete = 1;
126  return 0;
127 }
128 
130  VAAPIEncodePicture *pic)
131 {
132  VAAPIEncodeContext *ctx = avctx->priv_data;
133  VAAPIEncodeSlice *slice;
134  VAStatus vas;
135  int err, i;
137  size_t bit_len;
138 
139  av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
140  "as type %s.\n", pic->display_order, pic->encode_order,
141  picture_type_name[pic->type]);
142  if (pic->nb_refs == 0) {
143  av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
144  } else {
145  av_log(avctx, AV_LOG_DEBUG, "Refers to:");
146  for (i = 0; i < pic->nb_refs; i++) {
147  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
148  pic->refs[i]->display_order, pic->refs[i]->encode_order);
149  }
150  av_log(avctx, AV_LOG_DEBUG, ".\n");
151  }
152 
154  for (i = 0; i < pic->nb_refs; i++) {
155  av_assert0(pic->refs[i]);
156  // If we are serialised then the references must have already
157  // completed. If not, they must have been issued but need not
158  // have completed yet.
160  av_assert0(pic->refs[i]->encode_complete);
161  else
162  av_assert0(pic->refs[i]->encode_issued);
163  }
164 
165  av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
166 
167  pic->recon_image = av_frame_alloc();
168  if (!pic->recon_image) {
169  err = AVERROR(ENOMEM);
170  goto fail;
171  }
172 
174  if (err < 0) {
175  err = AVERROR(ENOMEM);
176  goto fail;
177  }
178  pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
179  av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
180 
181  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
182  VAEncCodedBufferType,
184  &pic->output_buffer);
185  if (vas != VA_STATUS_SUCCESS) {
186  av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
187  "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
188  err = AVERROR(ENOMEM);
189  goto fail;
190  }
191  av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
192  pic->output_buffer);
193 
194  if (ctx->codec->picture_params_size > 0) {
196  if (!pic->codec_picture_params)
197  goto fail;
198  memcpy(pic->codec_picture_params, ctx->codec_picture_params,
199  ctx->codec->picture_params_size);
200  } else {
202  }
203 
204  pic->nb_param_buffers = 0;
205 
206  if (pic->encode_order == 0) {
207  // Global parameter buffers are set on the first picture only.
208 
209  for (i = 0; i < ctx->nb_global_params; i++) {
210  err = vaapi_encode_make_param_buffer(avctx, pic,
211  VAEncMiscParameterBufferType,
212  (char*)ctx->global_params[i],
213  ctx->global_params_size[i]);
214  if (err < 0)
215  goto fail;
216  }
217  }
218 
219  if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
220  err = vaapi_encode_make_param_buffer(avctx, pic,
221  VAEncSequenceParameterBufferType,
224  if (err < 0)
225  goto fail;
226  }
227 
228  if (ctx->codec->init_picture_params) {
229  err = ctx->codec->init_picture_params(avctx, pic);
230  if (err < 0) {
231  av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
232  "parameters: %d.\n", err);
233  goto fail;
234  }
235  err = vaapi_encode_make_param_buffer(avctx, pic,
236  VAEncPictureParameterBufferType,
238  ctx->codec->picture_params_size);
239  if (err < 0)
240  goto fail;
241  }
242 
243  if (pic->type == PICTURE_TYPE_IDR) {
244  if (ctx->codec->write_sequence_header) {
245  bit_len = 8 * sizeof(data);
246  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
247  if (err < 0) {
248  av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
249  "header: %d.\n", err);
250  goto fail;
251  }
252  err = vaapi_encode_make_packed_header(avctx, pic,
254  data, bit_len);
255  if (err < 0)
256  goto fail;
257  }
258  }
259 
260  if (ctx->codec->write_picture_header) {
261  bit_len = 8 * sizeof(data);
262  err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len);
263  if (err < 0) {
264  av_log(avctx, AV_LOG_ERROR, "Failed to write per-picture "
265  "header: %d.\n", err);
266  goto fail;
267  }
268  err = vaapi_encode_make_packed_header(avctx, pic,
270  data, bit_len);
271  if (err < 0)
272  goto fail;
273  }
274 
275  if (ctx->codec->write_extra_buffer) {
276  for (i = 0;; i++) {
277  size_t len = sizeof(data);
278  int type;
279  err = ctx->codec->write_extra_buffer(avctx, pic, i, &type,
280  data, &len);
281  if (err == AVERROR_EOF)
282  break;
283  if (err < 0) {
284  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
285  "buffer %d: %d.\n", i, err);
286  goto fail;
287  }
288 
289  err = vaapi_encode_make_param_buffer(avctx, pic, type,
290  data, len);
291  if (err < 0)
292  goto fail;
293  }
294  }
295 
296  if (ctx->codec->write_extra_header) {
297  for (i = 0;; i++) {
298  int type;
299  bit_len = 8 * sizeof(data);
300  err = ctx->codec->write_extra_header(avctx, pic, i, &type,
301  data, &bit_len);
302  if (err == AVERROR_EOF)
303  break;
304  if (err < 0) {
305  av_log(avctx, AV_LOG_ERROR, "Failed to write extra "
306  "header %d: %d.\n", i, err);
307  goto fail;
308  }
309 
310  err = vaapi_encode_make_packed_header(avctx, pic, type,
311  data, bit_len);
312  if (err < 0)
313  goto fail;
314  }
315  }
316 
318  for (i = 0; i < pic->nb_slices; i++) {
319  slice = av_mallocz(sizeof(*slice));
320  if (!slice) {
321  err = AVERROR(ENOMEM);
322  goto fail;
323  }
324  pic->slices[i] = slice;
325 
326  if (ctx->codec->slice_params_size > 0) {
328  if (!slice->codec_slice_params) {
329  err = AVERROR(ENOMEM);
330  goto fail;
331  }
332  }
333 
334  if (ctx->codec->init_slice_params) {
335  err = ctx->codec->init_slice_params(avctx, pic, slice);
336  if (err < 0) {
337  av_log(avctx, AV_LOG_ERROR, "Failed to initialise slice "
338  "parameters: %d.\n", err);
339  goto fail;
340  }
341  }
342 
343  if (ctx->codec->write_slice_header) {
344  bit_len = 8 * sizeof(data);
345  err = ctx->codec->write_slice_header(avctx, pic, slice,
346  data, &bit_len);
347  if (err < 0) {
348  av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
349  "header: %d.\n", err);
350  goto fail;
351  }
352  err = vaapi_encode_make_packed_header(avctx, pic,
353  ctx->codec->slice_header_type,
354  data, bit_len);
355  if (err < 0)
356  goto fail;
357  }
358 
359  if (ctx->codec->init_slice_params) {
360  err = vaapi_encode_make_param_buffer(avctx, pic,
361  VAEncSliceParameterBufferType,
362  slice->codec_slice_params,
363  ctx->codec->slice_params_size);
364  if (err < 0)
365  goto fail;
366  }
367  }
368 
369  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
370  pic->input_surface);
371  if (vas != VA_STATUS_SUCCESS) {
372  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
373  "%d (%s).\n", vas, vaErrorStr(vas));
374  err = AVERROR(EIO);
375  goto fail_with_picture;
376  }
377 
378  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
379  pic->param_buffers, pic->nb_param_buffers);
380  if (vas != VA_STATUS_SUCCESS) {
381  av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
382  "%d (%s).\n", vas, vaErrorStr(vas));
383  err = AVERROR(EIO);
384  goto fail_with_picture;
385  }
386 
387  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
388  if (vas != VA_STATUS_SUCCESS) {
389  av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
390  "%d (%s).\n", vas, vaErrorStr(vas));
391  err = AVERROR(EIO);
392  goto fail_at_end;
393  }
394 
395  pic->encode_issued = 1;
396 
398  return vaapi_encode_wait(avctx, pic);
399  else
400  return 0;
401 
402 fail_with_picture:
403  vaEndPicture(ctx->hwctx->display, ctx->va_context);
404 fail:
405  for(i = 0; i < pic->nb_param_buffers; i++)
406  vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
407 fail_at_end:
409  av_frame_free(&pic->recon_image);
410  return err;
411 }
412 
415 {
416  VAAPIEncodeContext *ctx = avctx->priv_data;
417  VACodedBufferSegment *buf_list, *buf;
418  VAStatus vas;
419  int err;
420 
421  err = vaapi_encode_wait(avctx, pic);
422  if (err < 0)
423  return err;
424 
425  buf_list = NULL;
426  vas = vaMapBuffer(ctx->hwctx->display, pic->output_buffer,
427  (void**)&buf_list);
428  if (vas != VA_STATUS_SUCCESS) {
429  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
430  "%d (%s).\n", vas, vaErrorStr(vas));
431  err = AVERROR(EIO);
432  goto fail;
433  }
434 
435  for (buf = buf_list; buf; buf = buf->next) {
436  av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
437  "(status %08x).\n", buf->size, buf->status);
438 
439  err = av_new_packet(pkt, buf->size);
440  if (err < 0)
441  goto fail;
442 
443  memcpy(pkt->data, buf->buf, buf->size);
444  }
445 
446  if (pic->type == PICTURE_TYPE_IDR)
447  pkt->flags |= AV_PKT_FLAG_KEY;
448 
449  pkt->pts = pic->pts;
450 
451  vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
452  if (vas != VA_STATUS_SUCCESS) {
453  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
454  "%d (%s).\n", vas, vaErrorStr(vas));
455  err = AVERROR(EIO);
456  goto fail;
457  }
458 
459  vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
460  pic->output_buffer = VA_INVALID_ID;
461 
462  av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
463  pic->display_order, pic->encode_order);
464  return 0;
465 
466 fail:
467  if (pic->output_buffer != VA_INVALID_ID) {
468  vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
469  vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
470  pic->output_buffer = VA_INVALID_ID;
471  }
472  return err;
473 }
474 
476  VAAPIEncodePicture *pic)
477 {
478  VAAPIEncodeContext *ctx = avctx->priv_data;
479 
480  vaapi_encode_wait(avctx, pic);
481 
482  if (pic->output_buffer != VA_INVALID_ID) {
483  av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
484  "%"PRId64"/%"PRId64".\n",
485  pic->display_order, pic->encode_order);
486 
487  vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
488  pic->output_buffer = VA_INVALID_ID;
489  }
490 
491  return 0;
492 }
493 
495 {
496  VAAPIEncodePicture *pic;
497 
498  pic = av_mallocz(sizeof(*pic));
499  if (!pic)
500  return NULL;
501 
502  pic->input_surface = VA_INVALID_ID;
503  pic->recon_surface = VA_INVALID_ID;
504  pic->output_buffer = VA_INVALID_ID;
505 
506  return pic;
507 }
508 
510  VAAPIEncodePicture *pic)
511 {
512  int i;
513 
514  if (pic->encode_issued)
515  vaapi_encode_discard(avctx, pic);
516 
517  for (i = 0; i < pic->nb_slices; i++) {
518  av_freep(&pic->slices[i]->priv_data);
520  av_freep(&pic->slices[i]);
521  }
523 
524  av_frame_free(&pic->input_image);
525  av_frame_free(&pic->recon_image);
526 
527  // Output buffer should already be destroyed.
528  av_assert0(pic->output_buffer == VA_INVALID_ID);
529 
530  av_freep(&pic->priv_data);
532 
533  av_free(pic);
534 
535  return 0;
536 }
537 
539  VAAPIEncodePicture *target)
540 {
541  VAAPIEncodeContext *ctx = avctx->priv_data;
542  VAAPIEncodePicture *pic;
543  int i, err;
544 
547  // These two modes are equivalent, except that we wait for
548  // immediate completion on each operation if serialised.
549 
550  if (!target) {
551  // No target, nothing to do yet.
552  return 0;
553  }
554 
555  if (target->encode_complete) {
556  // Already done.
557  return 0;
558  }
559 
560  pic = target;
561  for (i = 0; i < pic->nb_refs; i++) {
562  if (!pic->refs[i]->encode_complete) {
563  err = vaapi_encode_step(avctx, pic->refs[i]);
564  if (err < 0)
565  return err;
566  }
567  }
568 
569  err = vaapi_encode_issue(avctx, pic);
570  if (err < 0)
571  return err;
572 
573  } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
574  int activity;
575 
576  do {
577  activity = 0;
578  for (pic = ctx->pic_start; pic; pic = pic->next) {
579  if (!pic->input_available || pic->encode_issued)
580  continue;
581  for (i = 0; i < pic->nb_refs; i++) {
582  if (!pic->refs[i]->encode_issued)
583  break;
584  }
585  if (i < pic->nb_refs)
586  continue;
587  err = vaapi_encode_issue(avctx, pic);
588  if (err < 0)
589  return err;
590  activity = 1;
591  }
592  } while(activity);
593 
594  if (target) {
595  av_assert0(target->encode_issued && "broken dependencies?");
596  }
597 
598  } else {
599  av_assert0(0);
600  }
601 
602  return 0;
603 }
604 
606  VAAPIEncodePicture **pic_out)
607 {
608  VAAPIEncodeContext *ctx = avctx->priv_data;
609  VAAPIEncodePicture *start, *end, *pic;
610  int i;
611 
612  for (pic = ctx->pic_start; pic; pic = pic->next) {
613  if (pic->next)
614  av_assert0(pic->display_order + 1 == pic->next->display_order);
615  if (pic->display_order == ctx->input_order) {
616  *pic_out = pic;
617  return 0;
618  }
619  }
620 
621  if (ctx->input_order == 0) {
622  // First frame is always an IDR frame.
623  av_assert0(!ctx->pic_start && !ctx->pic_end);
624 
625  pic = vaapi_encode_alloc();
626  if (!pic)
627  return AVERROR(ENOMEM);
628 
629  pic->type = PICTURE_TYPE_IDR;
630  pic->display_order = 0;
631  pic->encode_order = 0;
632 
633  ctx->pic_start = ctx->pic_end = pic;
634 
635  *pic_out = pic;
636  return 0;
637  }
638 
639  pic = vaapi_encode_alloc();
640  if (!pic)
641  return AVERROR(ENOMEM);
642 
643  if (ctx->p_per_i == 0 || ctx->p_counter == ctx->p_per_i) {
644  if (ctx->i_per_idr == 0 || ctx->i_counter == ctx->i_per_idr) {
645  pic->type = PICTURE_TYPE_IDR;
646  ctx->i_counter = 0;
647  } else {
648  pic->type = PICTURE_TYPE_I;
649  ++ctx->i_counter;
650  }
651  ctx->p_counter = 0;
652  } else {
653  pic->type = PICTURE_TYPE_P;
654  pic->refs[0] = ctx->pic_end;
655  pic->nb_refs = 1;
656  ++ctx->p_counter;
657  }
658  start = end = pic;
659 
660  if (pic->type != PICTURE_TYPE_IDR) {
661  // If that was not an IDR frame, add B-frames display-before and
662  // encode-after it.
663 
664  for (i = 0; i < ctx->b_per_p; i++) {
665  pic = vaapi_encode_alloc();
666  if (!pic)
667  goto fail;
668 
669  pic->type = PICTURE_TYPE_B;
670  pic->refs[0] = ctx->pic_end;
671  pic->refs[1] = end;
672  pic->nb_refs = 2;
673 
674  pic->next = start;
675  pic->display_order = ctx->input_order + ctx->b_per_p - i - 1;
676  pic->encode_order = pic->display_order + 1;
677  start = pic;
678  }
679  }
680 
681  for (i = 0, pic = start; pic; i++, pic = pic->next) {
682  pic->display_order = ctx->input_order + i;
683  if (end->type == PICTURE_TYPE_IDR)
684  pic->encode_order = ctx->input_order + i;
685  else if (pic == end)
686  pic->encode_order = ctx->input_order;
687  else
688  pic->encode_order = ctx->input_order + i + 1;
689  }
690 
691  av_assert0(ctx->pic_end);
692  ctx->pic_end->next = start;
693  ctx->pic_end = end;
694 
695  *pic_out = start;
696 
697  av_log(avctx, AV_LOG_DEBUG, "Pictures:");
698  for (pic = ctx->pic_start; pic; pic = pic->next) {
699  av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
700  picture_type_name[pic->type],
701  pic->display_order, pic->encode_order);
702  }
703  av_log(avctx, AV_LOG_DEBUG, "\n");
704 
705  return 0;
706 
707 fail:
708  while (start) {
709  pic = start->next;
710  vaapi_encode_free(avctx, start);
711  start = pic;
712  }
713  return AVERROR(ENOMEM);
714 }
715 
717 {
718  VAAPIEncodeContext *ctx = avctx->priv_data;
719  VAAPIEncodePicture *pic, *last_pic, *next;
720 
721  // Find the last picture we actually have input for.
722  for (pic = ctx->pic_start; pic; pic = pic->next) {
723  if (!pic->input_available)
724  break;
725  last_pic = pic;
726  }
727 
728  if (pic) {
729  av_assert0(last_pic);
730 
731  if (last_pic->type == PICTURE_TYPE_B) {
732  // Some fixing up is required. Change the type of this
733  // picture to P, then modify preceding B references which
734  // point beyond it to point at it instead.
735 
736  last_pic->type = PICTURE_TYPE_P;
737  last_pic->encode_order = last_pic->refs[1]->encode_order;
738 
739  for (pic = ctx->pic_start; pic != last_pic; pic = pic->next) {
740  if (pic->type == PICTURE_TYPE_B &&
741  pic->refs[1] == last_pic->refs[1])
742  pic->refs[1] = last_pic;
743  }
744 
745  last_pic->nb_refs = 1;
746  last_pic->refs[1] = NULL;
747  } else {
748  // We can use the current structure (no references point
749  // beyond the end), but there are unused pics to discard.
750  }
751 
752  // Discard all following pics, they will never be used.
753  for (pic = last_pic->next; pic; pic = next) {
754  next = pic->next;
755  vaapi_encode_free(avctx, pic);
756  }
757 
758  last_pic->next = NULL;
759  ctx->pic_end = last_pic;
760 
761  } else {
762  // Input is available for all pictures, so we don't need to
763  // mangle anything.
764  }
765 
766  av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:");
767  for (pic = ctx->pic_start; pic; pic = pic->next) {
768  av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
769  picture_type_name[pic->type],
770  pic->display_order, pic->encode_order);
771  }
772  av_log(avctx, AV_LOG_DEBUG, "\n");
773 
774  return 0;
775 }
776 
778 {
779  VAAPIEncodeContext *ctx = avctx->priv_data;
780  VAAPIEncodePicture *pic, *old;
781  int i;
782 
783  while (ctx->pic_start != ctx->pic_end) {
784  old = ctx->pic_start;
785  if (old->encode_order > ctx->output_order)
786  break;
787 
788  for (pic = old->next; pic; pic = pic->next) {
789  if (pic->encode_complete)
790  continue;
791  for (i = 0; i < pic->nb_refs; i++) {
792  if (pic->refs[i] == old) {
793  // We still need this picture because it's referred to
794  // directly by a later one, so it and all following
795  // pictures have to stay.
796  return 0;
797  }
798  }
799  }
800 
801  pic = ctx->pic_start;
802  ctx->pic_start = pic->next;
803  vaapi_encode_free(avctx, pic);
804  }
805 
806  return 0;
807 }
808 
810  const AVFrame *input_image, int *got_packet)
811 {
812  VAAPIEncodeContext *ctx = avctx->priv_data;
813  VAAPIEncodePicture *pic;
814  int err;
815 
816  if (input_image) {
817  av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
818  input_image->width, input_image->height, input_image->pts);
819 
820  err = vaapi_encode_get_next(avctx, &pic);
821  if (err) {
822  av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
823  return err;
824  }
825 
826  pic->input_image = av_frame_alloc();
827  if (!pic->input_image) {
828  err = AVERROR(ENOMEM);
829  goto fail;
830  }
831  err = av_frame_ref(pic->input_image, input_image);
832  if (err < 0)
833  goto fail;
834  pic->input_surface = (VASurfaceID)(uintptr_t)input_image->data[3];
835  pic->pts = input_image->pts;
836 
837  if (ctx->input_order == 0)
838  ctx->first_pts = pic->pts;
839  if (ctx->input_order == ctx->decode_delay)
840  ctx->dts_pts_diff = pic->pts - ctx->first_pts;
841  if (ctx->output_delay > 0)
842  ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;
843 
844  pic->input_available = 1;
845 
846  } else {
847  if (!ctx->end_of_stream) {
848  err = vaapi_encode_mangle_end(avctx);
849  if (err < 0)
850  goto fail;
851  ctx->end_of_stream = 1;
852  }
853  }
854 
855  ++ctx->input_order;
856  ++ctx->output_order;
857  av_assert0(ctx->output_order + ctx->output_delay + 1 == ctx->input_order);
858 
859  for (pic = ctx->pic_start; pic; pic = pic->next)
860  if (pic->encode_order == ctx->output_order)
861  break;
862 
863  // pic can be null here if we don't have a specific target in this
864  // iteration. We might still issue encodes if things can be overlapped,
865  // even though we don't intend to output anything.
866 
867  err = vaapi_encode_step(avctx, pic);
868  if (err < 0) {
869  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
870  goto fail;
871  }
872 
873  if (!pic) {
874  *got_packet = 0;
875  } else {
876  err = vaapi_encode_output(avctx, pic, pkt);
877  if (err < 0) {
878  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
879  goto fail;
880  }
881 
882  if (ctx->output_delay == 0) {
883  pkt->dts = pkt->pts;
884  } else if (ctx->output_order < ctx->decode_delay) {
885  if (ctx->ts_ring[ctx->output_order] < INT64_MIN + ctx->dts_pts_diff)
886  pkt->dts = INT64_MIN;
887  else
888  pkt->dts = ctx->ts_ring[ctx->output_order] - ctx->dts_pts_diff;
889  } else {
890  pkt->dts = ctx->ts_ring[(ctx->output_order - ctx->decode_delay) %
891  (3 * ctx->output_delay)];
892  }
893 
894  *got_packet = 1;
895  }
896 
897  err = vaapi_encode_clear_old(avctx);
898  if (err < 0) {
899  av_log(avctx, AV_LOG_ERROR, "List clearing failed: %d.\n", err);
900  goto fail;
901  }
902 
903  return 0;
904 
905 fail:
906  // Unclear what to clean up on failure. There are probably some things we
907  // could do usefully clean up here, but for now just leave them for uninit()
908  // to do instead.
909  return err;
910 }
911 
913 {
914  VAAPIEncodeContext *ctx = avctx->priv_data;
915  VAStatus vas;
916  int i, n, err;
917  VAProfile *profiles = NULL;
918  VAEntrypoint *entrypoints = NULL;
919  VAConfigAttrib attr[] = {
920  { VAConfigAttribRateControl },
921  { VAConfigAttribEncMaxRefFrames },
922  };
923 
924  n = vaMaxNumProfiles(ctx->hwctx->display);
925  profiles = av_malloc_array(n, sizeof(VAProfile));
926  if (!profiles) {
927  err = AVERROR(ENOMEM);
928  goto fail;
929  }
930  vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n);
931  if (vas != VA_STATUS_SUCCESS) {
932  av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
933  vas, vaErrorStr(vas));
934  err = AVERROR(ENOSYS);
935  goto fail;
936  }
937  for (i = 0; i < n; i++) {
938  if (profiles[i] == ctx->va_profile)
939  break;
940  }
941  if (i >= n) {
942  av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n",
943  ctx->va_profile);
944  err = AVERROR(ENOSYS);
945  goto fail;
946  }
947 
948  n = vaMaxNumEntrypoints(ctx->hwctx->display);
949  entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
950  if (!entrypoints) {
951  err = AVERROR(ENOMEM);
952  goto fail;
953  }
954  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
955  entrypoints, &n);
956  if (vas != VA_STATUS_SUCCESS) {
957  av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for "
958  "profile %u: %d (%s).\n", ctx->va_profile,
959  vas, vaErrorStr(vas));
960  err = AVERROR(ENOSYS);
961  goto fail;
962  }
963  for (i = 0; i < n; i++) {
964  if (entrypoints[i] == ctx->va_entrypoint)
965  break;
966  }
967  if (i >= n) {
968  av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found "
969  "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint);
970  err = AVERROR(ENOSYS);
971  goto fail;
972  }
973 
974  vas = vaGetConfigAttributes(ctx->hwctx->display,
975  ctx->va_profile, ctx->va_entrypoint,
976  attr, FF_ARRAY_ELEMS(attr));
977  if (vas != VA_STATUS_SUCCESS) {
978  av_log(avctx, AV_LOG_ERROR, "Failed to fetch config "
979  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
980  return AVERROR(EINVAL);
981  }
982 
983  for (i = 0; i < FF_ARRAY_ELEMS(attr); i++) {
984  if (attr[i].value == VA_ATTRIB_NOT_SUPPORTED) {
985  // Unfortunately we have to treat this as "don't know" and hope
986  // for the best, because the Intel MJPEG encoder returns this
987  // for all the interesting attributes.
988  continue;
989  }
990  switch (attr[i].type) {
991  case VAConfigAttribRateControl:
992  if (!(ctx->va_rc_mode & attr[i].value)) {
993  av_log(avctx, AV_LOG_ERROR, "Rate control mode is not "
994  "supported: %x\n", attr[i].value);
995  err = AVERROR(EINVAL);
996  goto fail;
997  }
998  break;
999  case VAConfigAttribEncMaxRefFrames:
1000  {
1001  unsigned int ref_l0 = attr[i].value & 0xffff;
1002  unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff;
1003 
1004  if (avctx->gop_size > 1 && ref_l0 < 1) {
1005  av_log(avctx, AV_LOG_ERROR, "P frames are not "
1006  "supported (%x).\n", attr[i].value);
1007  err = AVERROR(EINVAL);
1008  goto fail;
1009  }
1010  if (avctx->max_b_frames > 0 && ref_l1 < 1) {
1011  av_log(avctx, AV_LOG_ERROR, "B frames are not "
1012  "supported (%x).\n", attr[i].value);
1013  err = AVERROR(EINVAL);
1014  goto fail;
1015  }
1016  }
1017  break;
1018  }
1019  }
1020 
1021  err = 0;
1022 fail:
1023  av_freep(&profiles);
1024  av_freep(&entrypoints);
1025  return err;
1026 }
1027 
1029  const VAAPIEncodeType *type)
1030 {
1031  VAAPIEncodeContext *ctx = avctx->priv_data;
1032  AVVAAPIFramesContext *recon_hwctx = NULL;
1033  AVVAAPIHWConfig *hwconfig = NULL;
1034  AVHWFramesConstraints *constraints = NULL;
1035  enum AVPixelFormat recon_format;
1036  VAStatus vas;
1037  int err, i;
1038 
1039  if (!avctx->hw_frames_ctx) {
1040  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
1041  "required to associate the encoding device.\n");
1042  return AVERROR(EINVAL);
1043  }
1044 
1045  ctx->codec = type;
1046  ctx->codec_options = ctx->codec_options_data;
1047 
1048  ctx->va_config = VA_INVALID_ID;
1049  ctx->va_context = VA_INVALID_ID;
1050 
1051  ctx->priv_data = av_mallocz(type->priv_data_size);
1052  if (!ctx->priv_data) {
1053  err = AVERROR(ENOMEM);
1054  goto fail;
1055  }
1056 
1058  if (!ctx->input_frames_ref) {
1059  err = AVERROR(ENOMEM);
1060  goto fail;
1061  }
1063 
1065  if (!ctx->device_ref) {
1066  err = AVERROR(ENOMEM);
1067  goto fail;
1068  }
1069  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
1070  ctx->hwctx = ctx->device->hwctx;
1071 
1072  err = ctx->codec->init(avctx);
1073  if (err < 0)
1074  goto fail;
1075 
1076  err = vaapi_encode_check_config(avctx);
1077  if (err < 0)
1078  goto fail;
1079 
1080  vas = vaCreateConfig(ctx->hwctx->display,
1081  ctx->va_profile, ctx->va_entrypoint,
1083  &ctx->va_config);
1084  if (vas != VA_STATUS_SUCCESS) {
1085  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1086  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1087  err = AVERROR(EIO);
1088  goto fail;
1089  }
1090 
1091  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
1092  if (!hwconfig) {
1093  err = AVERROR(ENOMEM);
1094  goto fail;
1095  }
1096  hwconfig->config_id = ctx->va_config;
1097 
1099  hwconfig);
1100  if (!constraints) {
1101  err = AVERROR(ENOMEM);
1102  goto fail;
1103  }
1104 
1105  // Probably we can use the input surface format as the surface format
1106  // of the reconstructed frames. If not, we just pick the first (only?)
1107  // format in the valid list and hope that it all works.
1108  recon_format = AV_PIX_FMT_NONE;
1109  if (constraints->valid_sw_formats) {
1110  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
1111  if (ctx->input_frames->sw_format ==
1112  constraints->valid_sw_formats[i]) {
1113  recon_format = ctx->input_frames->sw_format;
1114  break;
1115  }
1116  }
1117  if (recon_format == AV_PIX_FMT_NONE) {
1118  // No match. Just use the first in the supported list and
1119  // hope for the best.
1120  recon_format = constraints->valid_sw_formats[0];
1121  }
1122  } else {
1123  // No idea what to use; copy input format.
1124  recon_format = ctx->input_frames->sw_format;
1125  }
1126  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
1127  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
1128 
1129  if (ctx->aligned_width < constraints->min_width ||
1130  ctx->aligned_height < constraints->min_height ||
1131  ctx->aligned_width > constraints->max_width ||
1132  ctx->aligned_height > constraints->max_height) {
1133  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
1134  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
1135  ctx->aligned_width, ctx->aligned_height,
1136  constraints->min_width, constraints->max_width,
1137  constraints->min_height, constraints->max_height);
1138  err = AVERROR(EINVAL);
1139  goto fail;
1140  }
1141 
1142  av_freep(&hwconfig);
1143  av_hwframe_constraints_free(&constraints);
1144 
1146  if (!ctx->recon_frames_ref) {
1147  err = AVERROR(ENOMEM);
1148  goto fail;
1149  }
1151 
1153  ctx->recon_frames->sw_format = recon_format;
1154  ctx->recon_frames->width = ctx->aligned_width;
1155  ctx->recon_frames->height = ctx->aligned_height;
1157 
1159  if (err < 0) {
1160  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
1161  "frame context: %d.\n", err);
1162  goto fail;
1163  }
1164  recon_hwctx = ctx->recon_frames->hwctx;
1165 
1166  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
1167  ctx->aligned_width, ctx->aligned_height,
1168  VA_PROGRESSIVE,
1169  recon_hwctx->surface_ids,
1170  recon_hwctx->nb_surfaces,
1171  &ctx->va_context);
1172  if (vas != VA_STATUS_SUCCESS) {
1173  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1174  "context: %d (%s).\n", vas, vaErrorStr(vas));
1175  err = AVERROR(EIO);
1176  goto fail;
1177  }
1178 
1179  ctx->input_order = 0;
1180  ctx->output_delay = avctx->max_b_frames;
1181  ctx->decode_delay = 1;
1182  ctx->output_order = - ctx->output_delay - 1;
1183 
1184  if (ctx->codec->sequence_params_size > 0) {
1185  ctx->codec_sequence_params =
1187  if (!ctx->codec_sequence_params) {
1188  err = AVERROR(ENOMEM);
1189  goto fail;
1190  }
1191  }
1192  if (ctx->codec->picture_params_size > 0) {
1193  ctx->codec_picture_params =
1195  if (!ctx->codec_picture_params) {
1196  err = AVERROR(ENOMEM);
1197  goto fail;
1198  }
1199  }
1200 
1201  if (ctx->codec->init_sequence_params) {
1202  err = ctx->codec->init_sequence_params(avctx);
1203  if (err < 0) {
1204  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
1205  "failed: %d.\n", err);
1206  goto fail;
1207  }
1208  }
1209 
1210  // All I are IDR for now.
1211  ctx->i_per_idr = 0;
1212  ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /
1213  (avctx->max_b_frames + 1));
1214  ctx->b_per_p = avctx->max_b_frames;
1215 
1216  // This should be configurable somehow. (Needs testing on a machine
1217  // where it actually overlaps properly, though.)
1219 
1220  return 0;
1221 
1222 fail:
1223  av_freep(&hwconfig);
1224  av_hwframe_constraints_free(&constraints);
1225  ff_vaapi_encode_close(avctx);
1226  return err;
1227 }
1228 
1230 {
1231  VAAPIEncodeContext *ctx = avctx->priv_data;
1232  VAAPIEncodePicture *pic, *next;
1233 
1234  for (pic = ctx->pic_start; pic; pic = next) {
1235  next = pic->next;
1236  vaapi_encode_free(avctx, pic);
1237  }
1238 
1239  if (ctx->va_context != VA_INVALID_ID) {
1240  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
1241  ctx->va_context = VA_INVALID_ID;
1242  }
1243 
1244  if (ctx->va_config != VA_INVALID_ID) {
1245  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
1246  ctx->va_config = VA_INVALID_ID;
1247  }
1248 
1249  if (ctx->codec->close)
1250  ctx->codec->close(avctx);
1251 
1254 
1257  av_buffer_unref(&ctx->device_ref);
1258 
1259  av_freep(&ctx->priv_data);
1260 
1261  return 0;
1262 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:54
#define NULL
Definition: coverity.c:32
VASurfaceID input_surface
Definition: vaapi_encode.h:79
VAProfile va_profile
Definition: vaapi_encode.h:108
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:124
VAAPI-specific data associated with a frame pool.
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
VAAPIEncodeSlice * slices[MAX_PICTURE_SLICES]
Definition: vaapi_encode.h:96
VAEntrypoint va_entrypoint
Definition: vaapi_encode.h:109
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static const char * picture_type_name[]
Definition: vaapi_encode.c:30
static int vaapi_encode_free(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:509
char codec_options_data[0]
Definition: vaapi_encode.h:179
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:1962
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
int size
Definition: avcodec.h:1602
size_t priv_data_size
Definition: vaapi_encode.h:184
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:222
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:414
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:202
int(* write_slice_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice, char *data, size_t *data_len)
Definition: vaapi_encode.h:209
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:252
void * codec_sequence_params
Definition: vaapi_encode.h:141
AVBufferRef * input_frames_ref
Definition: vaapi_encode.h:119
static AVPacket pkt
size_t picture_params_size
Definition: vaapi_encode.h:190
AVHWDeviceContext * device
Definition: vaapi_encode.h:116
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:391
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:450
static int vaapi_encode_mangle_end(AVCodecContext *avctx)
Definition: vaapi_encode.c:716
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:145
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int(* write_picture_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, char *data, size_t *data_len)
Definition: vaapi_encode.h:206
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:383
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:268
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, const VAAPIEncodeType *type)
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
uint8_t * data
Definition: avcodec.h:1601
VAContextID va_context
Definition: vaapi_encode.h:111
#define AVERROR_EOF
End of file.
Definition: error.h:55
VASurfaceID recon_surface
Definition: vaapi_encode.h:82
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1633
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]
Definition: vaapi_encode.h:133
AVHWFramesContext * input_frames
Definition: vaapi_encode.h:120
int width
width and height of the video frame
Definition: frame.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
VAAPI hardware pipeline configuration details.
#define AVERROR(e)
Definition: error.h:43
static int vaapi_encode_step(AVCodecContext *avctx, VAAPIEncodePicture *target)
Definition: vaapi_encode.c:538
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:158
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet)
Definition: vaapi_encode.c:809
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
VAEncMiscParameterBuffer * global_params[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:136
GLenum GLint * params
Definition: opengl_enc.c:114
simple assert() macros that are a bit more flexible than ISO C assert().
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:263
int(* init_picture_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.h:194
void * codec_picture_params
Definition: vaapi_encode.h:90
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:390
#define fail()
Definition: checkasm.h:83
int(* write_extra_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode.h:218
VAConfigID va_config
Definition: vaapi_encode.h:110
AVHWFramesContext * recon_frames
Definition: vaapi_encode.h:131
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1607
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:192
static int vaapi_encode_get_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
Definition: vaapi_encode.c:605
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:3542
static int vaapi_encode_make_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t len)
Definition: vaapi_encode.c:74
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
int(* close)(AVCodecContext *avctx)
Definition: vaapi_encode.h:187
AVFormatContext * ctx
Definition: movenc.c:48
struct VAAPIEncodePicture * next
Definition: vaapi_encode.h:67
static int vaapi_encode_discard(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:475
AVFrame * input_image
Definition: vaapi_encode.h:78
void * codec_picture_params
Definition: vaapi_encode.h:145
int n
Definition: avisynth_c.h:684
int64_t ts_ring[MAX_REORDER_DELAY *3]
Definition: vaapi_encode.h:164
#define FF_ARRAY_ELEMS(a)
VADisplay display
The VADisplay handle, to be filled by the user.
int(* write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len)
Definition: vaapi_encode.h:204
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
Definition: vaapi_encode.h:93
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:384
const struct VAAPIEncodeType * codec
Definition: vaapi_encode.h:103
Libavcodec external API header.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:366
VAAPIEncodePicture * pic_start
Definition: vaapi_encode.h:148
main external API structure.
Definition: avcodec.h:1676
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:425
uint8_t * data
The data buffer.
Definition: buffer.h:89
int(* write_extra_buffer)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
Definition: vaapi_encode.h:214
static VAAPIEncodePicture * vaapi_encode_alloc(void)
Definition: vaapi_encode.c:494
VABufferID param_buffers[MAX_PARAM_BUFFERS]
Definition: vaapi_encode.h:85
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:155
size_t slice_params_size
Definition: vaapi_encode.h:191
void * buf
Definition: avisynth_c.h:690
GLint GLenum type
Definition: opengl_enc.c:105
static const AVProfile profiles[]
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:117
AVBufferRef * recon_frames_ref
Definition: vaapi_encode.h:130
static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
Definition: vaapi_encode.c:912
AVBufferRef * device_ref
Definition: vaapi_encode.h:115
VAAPIEncodePicture * pic_end
Definition: vaapi_encode.h:148
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:134
size_t global_params_size[MAX_GLOBAL_PARAMS]
Definition: vaapi_encode.h:137
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:129
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1889
size_t sequence_params_size
Definition: vaapi_encode.h:189
static int vaapi_encode_clear_old(AVCodecContext *avctx)
Definition: vaapi_encode.c:777
common internal and external API header
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:413
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:177
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:92
void * priv_data
Definition: avcodec.h:1718
#define av_free(p)
int len
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:378
void * codec_slice_params
Definition: vaapi_encode.h:63
AVFrame * recon_image
Definition: vaapi_encode.h:81
int(* init_slice_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice)
Definition: vaapi_encode.h:196
static int vaapi_encode_wait(AVCodecContext *avctx, VAAPIEncodePicture *pic)
Definition: vaapi_encode.c:98
VAConfigID config_id
ID of a VAAPI pipeline configuration.
int(* init_sequence_params)(AVCodecContext *avctx)
Definition: vaapi_encode.h:193
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1600
static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t bit_len)
Definition: vaapi_encode.c:32
int height
Definition: frame.h:236
#define av_freep(p)
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
void INT64 start
Definition: avisynth_c.h:690
#define av_malloc_array(a, b)
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:2182
VABufferID output_buffer
Definition: vaapi_encode.h:87
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:215
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1578
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1594
int(* init)(AVCodecContext *avctx)
Definition: vaapi_encode.h:186
GLuint buffer
Definition: opengl_enc.c:102
AVVAAPIDeviceContext * hwctx
Definition: vaapi_encode.h:117