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 
297  for (i = 0; i < pic->nb_slices; i++) {
298  slice = av_mallocz(sizeof(*slice));
299  if (!slice) {
300  err = AVERROR(ENOMEM);
301  goto fail;
302  }
303  pic->slices[i] = slice;
304 
305  if (ctx->codec->slice_params_size > 0) {
307  if (!slice->codec_slice_params) {
308  err = AVERROR(ENOMEM);
309  goto fail;
310  }
311  }
312 
313  if (ctx->codec->init_slice_params) {
314  err = ctx->codec->init_slice_params(avctx, pic, slice);
315  if (err < 0) {
316  av_log(avctx, AV_LOG_ERROR, "Failed to initalise slice "
317  "parameters: %d.\n", err);
318  goto fail;
319  }
320  }
321 
322  if (ctx->codec->write_slice_header) {
323  bit_len = 8 * sizeof(data);
324  err = ctx->codec->write_slice_header(avctx, pic, slice,
325  data, &bit_len);
326  if (err < 0) {
327  av_log(avctx, AV_LOG_ERROR, "Failed to write per-slice "
328  "header: %d.\n", err);
329  goto fail;
330  }
331  err = vaapi_encode_make_packed_header(avctx, pic,
332  ctx->codec->slice_header_type,
333  data, bit_len);
334  if (err < 0)
335  goto fail;
336  }
337 
338  if (ctx->codec->init_slice_params) {
339  err = vaapi_encode_make_param_buffer(avctx, pic,
340  VAEncSliceParameterBufferType,
341  slice->codec_slice_params,
342  ctx->codec->slice_params_size);
343  if (err < 0)
344  goto fail;
345  }
346  }
347 
348  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
349  pic->input_surface);
350  if (vas != VA_STATUS_SUCCESS) {
351  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
352  "%d (%s).\n", vas, vaErrorStr(vas));
353  err = AVERROR(EIO);
354  goto fail_with_picture;
355  }
356 
357  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
358  pic->param_buffers, pic->nb_param_buffers);
359  if (vas != VA_STATUS_SUCCESS) {
360  av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
361  "%d (%s).\n", vas, vaErrorStr(vas));
362  err = AVERROR(EIO);
363  goto fail_with_picture;
364  }
365 
366  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
367  if (vas != VA_STATUS_SUCCESS) {
368  av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
369  "%d (%s).\n", vas, vaErrorStr(vas));
370  err = AVERROR(EIO);
371  goto fail_at_end;
372  }
373 
374  pic->encode_issued = 1;
375 
377  return vaapi_encode_wait(avctx, pic);
378  else
379  return 0;
380 
381 fail_with_picture:
382  vaEndPicture(ctx->hwctx->display, ctx->va_context);
383 fail:
384  for(i = 0; i < pic->nb_param_buffers; i++)
385  vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
386 fail_at_end:
388  av_frame_free(&pic->recon_image);
389  return err;
390 }
391 
394 {
395  VAAPIEncodeContext *ctx = avctx->priv_data;
396  VACodedBufferSegment *buf_list, *buf;
397  VAStatus vas;
398  int err;
399 
400  err = vaapi_encode_wait(avctx, pic);
401  if (err < 0)
402  return err;
403 
404  buf_list = NULL;
405  vas = vaMapBuffer(ctx->hwctx->display, pic->output_buffer,
406  (void**)&buf_list);
407  if (vas != VA_STATUS_SUCCESS) {
408  av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
409  "%d (%s).\n", vas, vaErrorStr(vas));
410  err = AVERROR(EIO);
411  goto fail;
412  }
413 
414  for (buf = buf_list; buf; buf = buf->next) {
415  av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
416  "(status %08x).\n", buf->size, buf->status);
417 
418  err = av_new_packet(pkt, buf->size);
419  if (err < 0)
420  goto fail;
421 
422  memcpy(pkt->data, buf->buf, buf->size);
423  }
424 
425  if (pic->type == PICTURE_TYPE_IDR)
426  pkt->flags |= AV_PKT_FLAG_KEY;
427 
428  pkt->pts = pic->pts;
429 
430  vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
431  if (vas != VA_STATUS_SUCCESS) {
432  av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
433  "%d (%s).\n", vas, vaErrorStr(vas));
434  err = AVERROR(EIO);
435  goto fail;
436  }
437 
438  vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
439  pic->output_buffer = VA_INVALID_ID;
440 
441  av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
442  pic->display_order, pic->encode_order);
443  return 0;
444 
445 fail:
446  if (pic->output_buffer != VA_INVALID_ID) {
447  vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
448  vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
449  pic->output_buffer = VA_INVALID_ID;
450  }
451  return err;
452 }
453 
455  VAAPIEncodePicture *pic)
456 {
457  VAAPIEncodeContext *ctx = avctx->priv_data;
458 
459  vaapi_encode_wait(avctx, pic);
460 
461  if (pic->output_buffer != VA_INVALID_ID) {
462  av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
463  "%"PRId64"/%"PRId64".\n",
464  pic->display_order, pic->encode_order);
465 
466  vaDestroyBuffer(ctx->hwctx->display, pic->output_buffer);
467  pic->output_buffer = VA_INVALID_ID;
468  }
469 
470  return 0;
471 }
472 
474 {
475  VAAPIEncodePicture *pic;
476 
477  pic = av_mallocz(sizeof(*pic));
478  if (!pic)
479  return NULL;
480 
481  pic->input_surface = VA_INVALID_ID;
482  pic->recon_surface = VA_INVALID_ID;
483  pic->output_buffer = VA_INVALID_ID;
484 
485  return pic;
486 }
487 
489  VAAPIEncodePicture *pic)
490 {
491  int i;
492 
493  if (pic->encode_issued)
494  vaapi_encode_discard(avctx, pic);
495 
496  for (i = 0; i < pic->nb_slices; i++) {
497  av_freep(&pic->slices[i]->priv_data);
499  av_freep(&pic->slices[i]);
500  }
502 
503  av_frame_free(&pic->input_image);
504  av_frame_free(&pic->recon_image);
505 
506  // Output buffer should already be destroyed.
507  av_assert0(pic->output_buffer == VA_INVALID_ID);
508 
509  av_freep(&pic->priv_data);
511 
512  av_free(pic);
513 
514  return 0;
515 }
516 
518  VAAPIEncodePicture *target)
519 {
520  VAAPIEncodeContext *ctx = avctx->priv_data;
521  VAAPIEncodePicture *pic;
522  int i, err;
523 
526  // These two modes are equivalent, except that we wait for
527  // immediate completion on each operation if serialised.
528 
529  if (!target) {
530  // No target, nothing to do yet.
531  return 0;
532  }
533 
534  if (target->encode_complete) {
535  // Already done.
536  return 0;
537  }
538 
539  pic = target;
540  for (i = 0; i < pic->nb_refs; i++) {
541  if (!pic->refs[i]->encode_complete) {
542  err = vaapi_encode_step(avctx, pic->refs[i]);
543  if (err < 0)
544  return err;
545  }
546  }
547 
548  err = vaapi_encode_issue(avctx, pic);
549  if (err < 0)
550  return err;
551 
552  } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
553  int activity;
554 
555  do {
556  activity = 0;
557  for (pic = ctx->pic_start; pic; pic = pic->next) {
558  if (!pic->input_available || pic->encode_issued)
559  continue;
560  for (i = 0; i < pic->nb_refs; i++) {
561  if (!pic->refs[i]->encode_issued)
562  break;
563  }
564  if (i < pic->nb_refs)
565  continue;
566  err = vaapi_encode_issue(avctx, pic);
567  if (err < 0)
568  return err;
569  activity = 1;
570  }
571  } while(activity);
572 
573  if (target) {
574  av_assert0(target->encode_issued && "broken dependencies?");
575  }
576 
577  } else {
578  av_assert0(0);
579  }
580 
581  return 0;
582 }
583 
585  VAAPIEncodePicture **pic_out)
586 {
587  VAAPIEncodeContext *ctx = avctx->priv_data;
588  VAAPIEncodePicture *start, *end, *pic;
589  int i;
590 
591  for (pic = ctx->pic_start; pic; pic = pic->next) {
592  if (pic->next)
593  av_assert0(pic->display_order + 1 == pic->next->display_order);
594  if (pic->display_order == ctx->input_order) {
595  *pic_out = pic;
596  return 0;
597  }
598  }
599 
600  if (ctx->input_order == 0) {
601  // First frame is always an IDR frame.
602  av_assert0(!ctx->pic_start && !ctx->pic_end);
603 
604  pic = vaapi_encode_alloc();
605  if (!pic)
606  return AVERROR(ENOMEM);
607 
608  pic->type = PICTURE_TYPE_IDR;
609  pic->display_order = 0;
610  pic->encode_order = 0;
611 
612  ctx->pic_start = ctx->pic_end = pic;
613 
614  *pic_out = pic;
615  return 0;
616  }
617 
618  pic = vaapi_encode_alloc();
619  if (!pic)
620  return AVERROR(ENOMEM);
621 
622  if (ctx->p_per_i == 0 || ctx->p_counter == ctx->p_per_i) {
623  if (ctx->i_per_idr == 0 || ctx->i_counter == ctx->i_per_idr) {
624  pic->type = PICTURE_TYPE_IDR;
625  ctx->i_counter = 0;
626  } else {
627  pic->type = PICTURE_TYPE_I;
628  ++ctx->i_counter;
629  }
630  ctx->p_counter = 0;
631  } else {
632  pic->type = PICTURE_TYPE_P;
633  pic->refs[0] = ctx->pic_end;
634  pic->nb_refs = 1;
635  ++ctx->p_counter;
636  }
637  start = end = pic;
638 
639  if (pic->type != PICTURE_TYPE_IDR) {
640  // If that was not an IDR frame, add B-frames display-before and
641  // encode-after it.
642 
643  for (i = 0; i < ctx->b_per_p; i++) {
644  pic = vaapi_encode_alloc();
645  if (!pic)
646  goto fail;
647 
648  pic->type = PICTURE_TYPE_B;
649  pic->refs[0] = ctx->pic_end;
650  pic->refs[1] = end;
651  pic->nb_refs = 2;
652 
653  pic->next = start;
654  pic->display_order = ctx->input_order + ctx->b_per_p - i - 1;
655  pic->encode_order = pic->display_order + 1;
656  start = pic;
657  }
658  }
659 
660  for (i = 0, pic = start; pic; i++, pic = pic->next) {
661  pic->display_order = ctx->input_order + i;
662  if (end->type == PICTURE_TYPE_IDR)
663  pic->encode_order = ctx->input_order + i;
664  else if (pic == end)
665  pic->encode_order = ctx->input_order;
666  else
667  pic->encode_order = ctx->input_order + i + 1;
668  }
669 
670  av_assert0(ctx->pic_end);
671  ctx->pic_end->next = start;
672  ctx->pic_end = end;
673 
674  *pic_out = start;
675 
676  av_log(avctx, AV_LOG_DEBUG, "Pictures:");
677  for (pic = ctx->pic_start; pic; pic = pic->next) {
678  av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
679  picture_type_name[pic->type],
680  pic->display_order, pic->encode_order);
681  }
682  av_log(avctx, AV_LOG_DEBUG, "\n");
683 
684  return 0;
685 
686 fail:
687  while (start) {
688  pic = start->next;
689  vaapi_encode_free(avctx, start);
690  start = pic;
691  }
692  return AVERROR(ENOMEM);
693 }
694 
696 {
697  VAAPIEncodeContext *ctx = avctx->priv_data;
698  VAAPIEncodePicture *pic, *last_pic, *next;
699 
700  // Find the last picture we actually have input for.
701  for (pic = ctx->pic_start; pic; pic = pic->next) {
702  if (!pic->input_available)
703  break;
704  last_pic = pic;
705  }
706 
707  if (pic) {
708  av_assert0(last_pic);
709 
710  if (last_pic->type == PICTURE_TYPE_B) {
711  // Some fixing up is required. Change the type of this
712  // picture to P, then modify preceding B references which
713  // point beyond it to point at it instead.
714 
715  last_pic->type = PICTURE_TYPE_P;
716  last_pic->encode_order = last_pic->refs[1]->encode_order;
717 
718  for (pic = ctx->pic_start; pic != last_pic; pic = pic->next) {
719  if (pic->type == PICTURE_TYPE_B &&
720  pic->refs[1] == last_pic->refs[1])
721  pic->refs[1] = last_pic;
722  }
723 
724  last_pic->nb_refs = 1;
725  last_pic->refs[1] = NULL;
726  } else {
727  // We can use the current structure (no references point
728  // beyond the end), but there are unused pics to discard.
729  }
730 
731  // Discard all following pics, they will never be used.
732  for (pic = last_pic->next; pic; pic = next) {
733  next = pic->next;
734  vaapi_encode_free(avctx, pic);
735  }
736 
737  last_pic->next = NULL;
738  ctx->pic_end = last_pic;
739 
740  } else {
741  // Input is available for all pictures, so we don't need to
742  // mangle anything.
743  }
744 
745  av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:");
746  for (pic = ctx->pic_start; pic; pic = pic->next) {
747  av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
748  picture_type_name[pic->type],
749  pic->display_order, pic->encode_order);
750  }
751  av_log(avctx, AV_LOG_DEBUG, "\n");
752 
753  return 0;
754 }
755 
757 {
758  VAAPIEncodeContext *ctx = avctx->priv_data;
759  VAAPIEncodePicture *pic, *old;
760  int i;
761 
762  while (ctx->pic_start != ctx->pic_end) {
763  old = ctx->pic_start;
764  if (old->encode_order > ctx->output_order)
765  break;
766 
767  for (pic = old->next; pic; pic = pic->next) {
768  if (pic->encode_complete)
769  continue;
770  for (i = 0; i < pic->nb_refs; i++) {
771  if (pic->refs[i] == old) {
772  // We still need this picture because it's referred to
773  // directly by a later one, so it and all following
774  // pictures have to stay.
775  return 0;
776  }
777  }
778  }
779 
780  pic = ctx->pic_start;
781  ctx->pic_start = pic->next;
782  vaapi_encode_free(avctx, pic);
783  }
784 
785  return 0;
786 }
787 
789  const AVFrame *input_image, int *got_packet)
790 {
791  VAAPIEncodeContext *ctx = avctx->priv_data;
792  VAAPIEncodePicture *pic;
793  int err;
794 
795  if (input_image) {
796  av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
797  input_image->width, input_image->height, input_image->pts);
798 
799  err = vaapi_encode_get_next(avctx, &pic);
800  if (err) {
801  av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
802  return err;
803  }
804 
805  pic->input_image = av_frame_alloc();
806  if (!pic->input_image) {
807  err = AVERROR(ENOMEM);
808  goto fail;
809  }
810  err = av_frame_ref(pic->input_image, input_image);
811  if (err < 0)
812  goto fail;
813  pic->input_surface = (VASurfaceID)(uintptr_t)input_image->data[3];
814  pic->pts = input_image->pts;
815 
816  if (ctx->input_order == 0)
817  ctx->first_pts = pic->pts;
818  if (ctx->input_order == ctx->decode_delay)
819  ctx->dts_pts_diff = pic->pts - ctx->first_pts;
820  if (ctx->output_delay > 0)
821  ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;
822 
823  pic->input_available = 1;
824 
825  } else {
826  if (!ctx->end_of_stream) {
827  err = vaapi_encode_mangle_end(avctx);
828  if (err < 0)
829  goto fail;
830  ctx->end_of_stream = 1;
831  }
832  }
833 
834  ++ctx->input_order;
835  ++ctx->output_order;
836  av_assert0(ctx->output_order + ctx->output_delay + 1 == ctx->input_order);
837 
838  for (pic = ctx->pic_start; pic; pic = pic->next)
839  if (pic->encode_order == ctx->output_order)
840  break;
841 
842  // pic can be null here if we don't have a specific target in this
843  // iteration. We might still issue encodes if things can be overlapped,
844  // even though we don't intend to output anything.
845 
846  err = vaapi_encode_step(avctx, pic);
847  if (err < 0) {
848  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
849  goto fail;
850  }
851 
852  if (!pic) {
853  *got_packet = 0;
854  } else {
855  err = vaapi_encode_output(avctx, pic, pkt);
856  if (err < 0) {
857  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
858  goto fail;
859  }
860 
861  if (ctx->output_delay == 0) {
862  pkt->dts = pkt->pts;
863  } else if (ctx->output_order < ctx->decode_delay) {
864  if (ctx->ts_ring[ctx->output_order] < INT64_MIN + ctx->dts_pts_diff)
865  pkt->dts = INT64_MIN;
866  else
867  pkt->dts = ctx->ts_ring[ctx->output_order] - ctx->dts_pts_diff;
868  } else {
869  pkt->dts = ctx->ts_ring[(ctx->output_order - ctx->decode_delay) %
870  (3 * ctx->output_delay)];
871  }
872 
873  *got_packet = 1;
874  }
875 
876  err = vaapi_encode_clear_old(avctx);
877  if (err < 0) {
878  av_log(avctx, AV_LOG_ERROR, "List clearing failed: %d.\n", err);
879  goto fail;
880  }
881 
882  return 0;
883 
884 fail:
885  // Unclear what to clean up on failure. There are probably some things we
886  // could do usefully clean up here, but for now just leave them for uninit()
887  // to do instead.
888  return err;
889 }
890 
892 {
893  VAAPIEncodeContext *ctx = avctx->priv_data;
894  VAStatus vas;
895  int i, n, err;
896  VAProfile *profiles = NULL;
897  VAEntrypoint *entrypoints = NULL;
898  VAConfigAttrib attr[] = {
899  { VAConfigAttribRateControl },
900  { VAConfigAttribEncMaxRefFrames },
901  };
902 
903  n = vaMaxNumProfiles(ctx->hwctx->display);
904  profiles = av_malloc_array(n, sizeof(VAProfile));
905  if (!profiles) {
906  err = AVERROR(ENOMEM);
907  goto fail;
908  }
909  vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n);
910  if (vas != VA_STATUS_SUCCESS) {
911  av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
912  vas, vaErrorStr(vas));
913  err = AVERROR(ENOSYS);
914  goto fail;
915  }
916  for (i = 0; i < n; i++) {
917  if (profiles[i] == ctx->va_profile)
918  break;
919  }
920  if (i >= n) {
921  av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n",
922  ctx->va_profile);
923  err = AVERROR(ENOSYS);
924  goto fail;
925  }
926 
927  n = vaMaxNumEntrypoints(ctx->hwctx->display);
928  entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
929  if (!entrypoints) {
930  err = AVERROR(ENOMEM);
931  goto fail;
932  }
933  vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
934  entrypoints, &n);
935  if (vas != VA_STATUS_SUCCESS) {
936  av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for "
937  "profile %u: %d (%s).\n", ctx->va_profile,
938  vas, vaErrorStr(vas));
939  err = AVERROR(ENOSYS);
940  goto fail;
941  }
942  for (i = 0; i < n; i++) {
943  if (entrypoints[i] == ctx->va_entrypoint)
944  break;
945  }
946  if (i >= n) {
947  av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found "
948  "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint);
949  err = AVERROR(ENOSYS);
950  goto fail;
951  }
952 
953  vas = vaGetConfigAttributes(ctx->hwctx->display,
954  ctx->va_profile, ctx->va_entrypoint,
955  attr, FF_ARRAY_ELEMS(attr));
956  if (vas != VA_STATUS_SUCCESS) {
957  av_log(avctx, AV_LOG_ERROR, "Failed to fetch config "
958  "attributes: %d (%s).\n", vas, vaErrorStr(vas));
959  return AVERROR(EINVAL);
960  }
961 
962  for (i = 0; i < FF_ARRAY_ELEMS(attr); i++) {
963  if (attr[i].value == VA_ATTRIB_NOT_SUPPORTED) {
964  // Unfortunately we have to treat this as "don't know" and hope
965  // for the best, because the Intel MJPEG encoder returns this
966  // for all the interesting attributes.
967  continue;
968  }
969  switch (attr[i].type) {
970  case VAConfigAttribRateControl:
971  if (!(ctx->va_rc_mode & attr[i].value)) {
972  av_log(avctx, AV_LOG_ERROR, "Rate control mode is not "
973  "supported: %x\n", attr[i].value);
974  err = AVERROR(EINVAL);
975  goto fail;
976  }
977  break;
978  case VAConfigAttribEncMaxRefFrames:
979  {
980  unsigned int ref_l0 = attr[i].value & 0xffff;
981  unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff;
982 
983  if (avctx->gop_size > 1 && ref_l0 < 1) {
984  av_log(avctx, AV_LOG_ERROR, "P frames are not "
985  "supported (%x).\n", attr[i].value);
986  err = AVERROR(EINVAL);
987  goto fail;
988  }
989  if (avctx->max_b_frames > 0 && ref_l1 < 1) {
990  av_log(avctx, AV_LOG_ERROR, "B frames are not "
991  "supported (%x).\n", attr[i].value);
992  err = AVERROR(EINVAL);
993  goto fail;
994  }
995  }
996  break;
997  }
998  }
999 
1000  err = 0;
1001 fail:
1002  av_freep(&profiles);
1003  av_freep(&entrypoints);
1004  return err;
1005 }
1006 
1008  const VAAPIEncodeType *type)
1009 {
1010  VAAPIEncodeContext *ctx = avctx->priv_data;
1011  AVVAAPIFramesContext *recon_hwctx = NULL;
1012  AVVAAPIHWConfig *hwconfig = NULL;
1013  AVHWFramesConstraints *constraints = NULL;
1014  enum AVPixelFormat recon_format;
1015  VAStatus vas;
1016  int err, i;
1017 
1018  if (!avctx->hw_frames_ctx) {
1019  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
1020  "required to associate the encoding device.\n");
1021  return AVERROR(EINVAL);
1022  }
1023 
1024  ctx->codec = type;
1025  ctx->codec_options = ctx->codec_options_data;
1026 
1027  ctx->va_config = VA_INVALID_ID;
1028  ctx->va_context = VA_INVALID_ID;
1029 
1030  ctx->priv_data = av_mallocz(type->priv_data_size);
1031  if (!ctx->priv_data) {
1032  err = AVERROR(ENOMEM);
1033  goto fail;
1034  }
1035 
1037  if (!ctx->input_frames_ref) {
1038  err = AVERROR(ENOMEM);
1039  goto fail;
1040  }
1042 
1044  if (!ctx->device_ref) {
1045  err = AVERROR(ENOMEM);
1046  goto fail;
1047  }
1048  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
1049  ctx->hwctx = ctx->device->hwctx;
1050 
1051  err = ctx->codec->init(avctx);
1052  if (err < 0)
1053  goto fail;
1054 
1055  err = vaapi_encode_check_config(avctx);
1056  if (err < 0)
1057  goto fail;
1058 
1059  vas = vaCreateConfig(ctx->hwctx->display,
1060  ctx->va_profile, ctx->va_entrypoint,
1062  &ctx->va_config);
1063  if (vas != VA_STATUS_SUCCESS) {
1064  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1065  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1066  err = AVERROR(EIO);
1067  goto fail;
1068  }
1069 
1070  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
1071  if (!hwconfig) {
1072  err = AVERROR(ENOMEM);
1073  goto fail;
1074  }
1075  hwconfig->config_id = ctx->va_config;
1076 
1078  hwconfig);
1079  if (!constraints) {
1080  err = AVERROR(ENOMEM);
1081  goto fail;
1082  }
1083 
1084  // Probably we can use the input surface format as the surface format
1085  // of the reconstructed frames. If not, we just pick the first (only?)
1086  // format in the valid list and hope that it all works.
1087  recon_format = AV_PIX_FMT_NONE;
1088  if (constraints->valid_sw_formats) {
1089  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
1090  if (ctx->input_frames->sw_format ==
1091  constraints->valid_sw_formats[i]) {
1092  recon_format = ctx->input_frames->sw_format;
1093  break;
1094  }
1095  }
1096  if (recon_format == AV_PIX_FMT_NONE)
1097  recon_format = constraints->valid_sw_formats[i];
1098  } else {
1099  // No idea what to use; copy input format.
1100  recon_format = ctx->input_frames->sw_format;
1101  }
1102  av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
1103  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
1104 
1105  if (ctx->aligned_width < constraints->min_width ||
1106  ctx->aligned_height < constraints->min_height ||
1107  ctx->aligned_width > constraints->max_width ||
1108  ctx->aligned_height > constraints->max_height) {
1109  av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
1110  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
1111  ctx->aligned_width, ctx->aligned_height,
1112  constraints->min_width, constraints->max_width,
1113  constraints->min_height, constraints->max_height);
1114  err = AVERROR(EINVAL);
1115  goto fail;
1116  }
1117 
1118  av_freep(&hwconfig);
1119  av_hwframe_constraints_free(&constraints);
1120 
1122  if (!ctx->recon_frames_ref) {
1123  err = AVERROR(ENOMEM);
1124  goto fail;
1125  }
1127 
1129  ctx->recon_frames->sw_format = recon_format;
1130  ctx->recon_frames->width = ctx->aligned_width;
1131  ctx->recon_frames->height = ctx->aligned_height;
1133 
1135  if (err < 0) {
1136  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
1137  "frame context: %d.\n", err);
1138  goto fail;
1139  }
1140  recon_hwctx = ctx->recon_frames->hwctx;
1141 
1142  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
1143  ctx->aligned_width, ctx->aligned_height,
1144  VA_PROGRESSIVE,
1145  recon_hwctx->surface_ids,
1146  recon_hwctx->nb_surfaces,
1147  &ctx->va_context);
1148  if (vas != VA_STATUS_SUCCESS) {
1149  av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
1150  "context: %d (%s).\n", vas, vaErrorStr(vas));
1151  err = AVERROR(EIO);
1152  goto fail;
1153  }
1154 
1155  ctx->input_order = 0;
1156  ctx->output_delay = avctx->max_b_frames;
1157  ctx->decode_delay = 1;
1158  ctx->output_order = - ctx->output_delay - 1;
1159 
1160  if (ctx->codec->sequence_params_size > 0) {
1161  ctx->codec_sequence_params =
1163  if (!ctx->codec_sequence_params) {
1164  err = AVERROR(ENOMEM);
1165  goto fail;
1166  }
1167  }
1168  if (ctx->codec->picture_params_size > 0) {
1169  ctx->codec_picture_params =
1171  if (!ctx->codec_picture_params) {
1172  err = AVERROR(ENOMEM);
1173  goto fail;
1174  }
1175  }
1176 
1177  if (ctx->codec->init_sequence_params) {
1178  err = ctx->codec->init_sequence_params(avctx);
1179  if (err < 0) {
1180  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
1181  "failed: %d.\n", err);
1182  goto fail;
1183  }
1184  }
1185 
1186  // All I are IDR for now.
1187  ctx->i_per_idr = 0;
1188  ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /
1189  (avctx->max_b_frames + 1));
1190  ctx->b_per_p = avctx->max_b_frames;
1191 
1192  // This should be configurable somehow. (Needs testing on a machine
1193  // where it actually overlaps properly, though.)
1195 
1196  return 0;
1197 
1198 fail:
1199  av_freep(&hwconfig);
1200  av_hwframe_constraints_free(&constraints);
1201  ff_vaapi_encode_close(avctx);
1202  return err;
1203 }
1204 
1206 {
1207  VAAPIEncodeContext *ctx = avctx->priv_data;
1208  VAAPIEncodePicture *pic, *next;
1209 
1210  for (pic = ctx->pic_start; pic; pic = next) {
1211  next = pic->next;
1212  vaapi_encode_free(avctx, pic);
1213  }
1214 
1215  if (ctx->va_context != VA_INVALID_ID) {
1216  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
1217  ctx->va_context = VA_INVALID_ID;
1218  }
1219 
1220  if (ctx->va_config != VA_INVALID_ID) {
1221  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
1222  ctx->va_config = VA_INVALID_ID;
1223  }
1224 
1225  if (ctx->codec->close)
1226  ctx->codec->close(avctx);
1227 
1230 
1233  av_buffer_unref(&ctx->device_ref);
1234 
1235  av_freep(&ctx->priv_data);
1236 
1237  return 0;
1238 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:53
#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:488
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:1935
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
int size
Definition: avcodec.h:1581
size_t priv_data_size
Definition: vaapi_encode.h:184
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:221
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:411
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:201
int(* write_slice_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice, char *data, size_t *data_len)
Definition: vaapi_encode.h:209
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:390
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:447
static int vaapi_encode_mangle_end(AVCodecContext *avctx)
Definition: vaapi_encode.c:695
#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:140
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:374
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:84
uint8_t * data
Definition: avcodec.h:1580
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:1612
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:517
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:153
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet)
Definition: vaapi_encode.c:788
#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:260
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:387
#define fail()
Definition: checkasm.h:81
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:1586
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:191
static int vaapi_encode_get_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
Definition: vaapi_encode.c:584
AVBufferRef * hw_frames_ctx
Encoding only.
Definition: avcodec.h:3495
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:454
AVFrame * input_image
Definition: vaapi_encode.h:78
void * codec_picture_params
Definition: vaapi_encode.h:145
int n
Definition: avisynth_c.h:547
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:383
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:365
VAAPIEncodePicture * pic_start
Definition: vaapi_encode.h:148
main external API structure.
Definition: avcodec.h:1649
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:422
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:473
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:154
size_t slice_params_size
Definition: vaapi_encode.h:191
void * buf
Definition: avisynth_c.h:553
GLint GLenum type
Definition: opengl_enc.c:105
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
AVBufferRef * recon_frames_ref
Definition: vaapi_encode.h:130
static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
Definition: vaapi_encode.c:891
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:133
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:1862
size_t sequence_params_size
Definition: vaapi_encode.h:189
static const AVProfile profiles[]
Definition: libfaac.c:216
static int vaapi_encode_clear_old(AVCodecContext *avctx)
Definition: vaapi_encode.c:756
common internal and external API header
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
Definition: vaapi_encode.c:392
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:174
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:92
void * priv_data
Definition: avcodec.h:1691
#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:377
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:1579
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:553
#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:2138
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:214
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1557
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1573
int(* init)(AVCodecContext *avctx)
Definition: vaapi_encode.h:186
GLuint buffer
Definition: opengl_enc.c:102
AVVAAPIDeviceContext * hwctx
Definition: vaapi_encode.h:117