FFmpeg
hw_base_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 "libavutil/avassert.h"
20 #include "libavutil/common.h"
21 #include "libavutil/internal.h"
22 #include "libavutil/log.h"
23 #include "libavutil/mem.h"
24 #include "libavutil/pixdesc.h"
25 
26 #include "encode.h"
27 #include "avcodec.h"
28 #include "hw_base_encode.h"
29 
31  FFHWBaseEncodePicture *target,
32  int is_ref, int in_dpb, int prev)
33 {
34  int refs = 0;
35 
36  if (is_ref) {
37  av_assert0(pic != target);
40  if (target->display_order < pic->display_order)
41  pic->refs[0][pic->nb_refs[0]++] = target;
42  else
43  pic->refs[1][pic->nb_refs[1]++] = target;
44  ++refs;
45  }
46 
47  if (in_dpb) {
49  pic->dpb[pic->nb_dpb_pics++] = target;
50  ++refs;
51  }
52 
53  if (prev) {
54  av_assert0(!pic->prev);
55  pic->prev = target;
56  ++refs;
57  }
58 
59  target->ref_count[0] += refs;
60  target->ref_count[1] += refs;
61 }
62 
64 {
65  int i;
66 
67  if (pic->ref_removed[level])
68  return;
69 
70  for (i = 0; i < pic->nb_refs[0]; i++) {
71  av_assert0(pic->refs[0][i]);
72  --pic->refs[0][i]->ref_count[level];
73  av_assert0(pic->refs[0][i]->ref_count[level] >= 0);
74  }
75 
76  for (i = 0; i < pic->nb_refs[1]; i++) {
77  av_assert0(pic->refs[1][i]);
78  --pic->refs[1][i]->ref_count[level];
79  av_assert0(pic->refs[1][i]->ref_count[level] >= 0);
80  }
81 
82  for (i = 0; i < pic->nb_dpb_pics; i++) {
83  av_assert0(pic->dpb[i]);
84  --pic->dpb[i]->ref_count[level];
85  av_assert0(pic->dpb[i]->ref_count[level] >= 0);
86  }
87 
88  av_assert0(pic->prev || pic->type == FF_HW_PICTURE_TYPE_IDR);
89  if (pic->prev) {
90  --pic->prev->ref_count[level];
91  av_assert0(pic->prev->ref_count[level] >= 0);
92  }
93 
94  pic->ref_removed[level] = 1;
95 }
96 
98  FFHWBaseEncodePicture *start,
100  FFHWBaseEncodePicture *prev,
101  int current_depth,
102  FFHWBaseEncodePicture **last)
103 {
104  FFHWBaseEncodePicture *pic, *next, *ref;
105  int i, len;
106 
107  av_assert0(start && end && start != end && start->next != end);
108 
109  // If we are at the maximum depth then encode all pictures as
110  // non-referenced B-pictures. Also do this if there is exactly one
111  // picture left, since there will be nothing to reference it.
112  if (current_depth == ctx->max_b_depth || start->next->next == end) {
113  for (pic = start->next; pic; pic = pic->next) {
114  if (pic == end)
115  break;
116  pic->type = FF_HW_PICTURE_TYPE_B;
117  pic->b_depth = current_depth;
118 
119  hw_base_encode_add_ref(pic, start, 1, 1, 0);
120  hw_base_encode_add_ref(pic, end, 1, 1, 0);
121  hw_base_encode_add_ref(pic, prev, 0, 0, 1);
122 
123  for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
124  hw_base_encode_add_ref(pic, ref, 0, 1, 0);
125  }
126  *last = prev;
127 
128  } else {
129  // Split the current list at the midpoint with a referenced
130  // B-picture, then descend into each side separately.
131  len = 0;
132  for (pic = start->next; pic != end; pic = pic->next)
133  ++len;
134  for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
135 
136  pic->type = FF_HW_PICTURE_TYPE_B;
137  pic->b_depth = current_depth;
138 
139  pic->is_reference = 1;
140 
141  hw_base_encode_add_ref(pic, pic, 0, 1, 0);
142  hw_base_encode_add_ref(pic, start, 1, 1, 0);
143  hw_base_encode_add_ref(pic, end, 1, 1, 0);
144  hw_base_encode_add_ref(pic, prev, 0, 0, 1);
145 
146  for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
147  hw_base_encode_add_ref(pic, ref, 0, 1, 0);
148 
149  if (i > 1)
150  hw_base_encode_set_b_pictures(ctx, start, pic, pic,
151  current_depth + 1, &next);
152  else
153  next = pic;
154 
155  hw_base_encode_set_b_pictures(ctx, pic, end, next,
156  current_depth + 1, last);
157  }
158 }
159 
162 {
163  int i;
164 
165  if (!pic)
166  return;
167 
168  if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
169  for (i = 0; i < ctx->nb_next_prev; i++) {
170  --ctx->next_prev[i]->ref_count[0];
171  ctx->next_prev[i] = NULL;
172  }
173  ctx->next_prev[0] = pic;
174  ++pic->ref_count[0];
175  ctx->nb_next_prev = 1;
176 
177  return;
178  }
179 
180  if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) {
181  ctx->next_prev[ctx->nb_next_prev++] = pic;
182  ++pic->ref_count[0];
183  } else {
184  --ctx->next_prev[0]->ref_count[0];
185  for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++)
186  ctx->next_prev[i] = ctx->next_prev[i + 1];
187  ctx->next_prev[i] = pic;
188  ++pic->ref_count[0];
189  }
190 }
191 
194  FFHWBaseEncodePicture **pic_out)
195 {
196  FFHWBaseEncodePicture *pic = NULL, *prev = NULL, *next, *start;
197  int i, b_counter, closed_gop_end;
198 
199  // If there are any B-frames already queued, the next one to encode
200  // is the earliest not-yet-issued frame for which all references are
201  // available.
202  for (pic = ctx->pic_start; pic; pic = pic->next) {
203  if (pic->encode_issued)
204  continue;
205  if (pic->type != FF_HW_PICTURE_TYPE_B)
206  continue;
207  for (i = 0; i < pic->nb_refs[0]; i++) {
208  if (!pic->refs[0][i]->encode_issued)
209  break;
210  }
211  if (i != pic->nb_refs[0])
212  continue;
213 
214  for (i = 0; i < pic->nb_refs[1]; i++) {
215  if (!pic->refs[1][i]->encode_issued)
216  break;
217  }
218  if (i == pic->nb_refs[1])
219  break;
220  }
221 
222  if (pic) {
223  av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
224  "encode next.\n", pic->b_depth);
225  *pic_out = pic;
226  return 0;
227  }
228 
229  // Find the B-per-Pth available picture to become the next picture
230  // on the top layer.
231  start = NULL;
232  b_counter = 0;
233  closed_gop_end = ctx->closed_gop ||
234  ctx->idr_counter == ctx->gop_per_idr;
235  for (pic = ctx->pic_start; pic; pic = next) {
236  next = pic->next;
237  if (pic->encode_issued) {
238  start = pic;
239  continue;
240  }
241  // If the next available picture is force-IDR, encode it to start
242  // a new GOP immediately.
243  if (pic->force_idr)
244  break;
245  if (b_counter == ctx->b_per_p)
246  break;
247  // If this picture ends a closed GOP or starts a new GOP then it
248  // needs to be in the top layer.
249  if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
250  break;
251  // If the picture after this one is force-IDR, we need to encode
252  // this one in the top layer.
253  if (next && next->force_idr)
254  break;
255  ++b_counter;
256  }
257 
258  // At the end of the stream the last picture must be in the top layer.
259  if (!pic && ctx->end_of_stream) {
260  --b_counter;
261  pic = ctx->pic_end;
262  if (pic->encode_complete)
263  return AVERROR_EOF;
264  else if (pic->encode_issued)
265  return AVERROR(EAGAIN);
266  }
267 
268  if (!pic) {
269  av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
270  "need more input for reference pictures.\n");
271  return AVERROR(EAGAIN);
272  }
273  if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
274  av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
275  "need more input for timestamps.\n");
276  return AVERROR(EAGAIN);
277  }
278 
279  if (pic->force_idr) {
280  av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
281  "encode next.\n");
283  ctx->idr_counter = 1;
284  ctx->gop_counter = 1;
285 
286  } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
287  if (ctx->idr_counter == ctx->gop_per_idr) {
288  av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
289  "encode next.\n");
291  ctx->idr_counter = 1;
292  } else {
293  av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
294  "encode next.\n");
295  pic->type = FF_HW_PICTURE_TYPE_I;
296  ++ctx->idr_counter;
297  }
298  ctx->gop_counter = 1;
299 
300  } else {
301  if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
302  av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
303  "encode next.\n");
304  } else {
305  av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
306  "encode next.\n");
307  }
308  pic->type = FF_HW_PICTURE_TYPE_P;
309  av_assert0(start);
310  ctx->gop_counter += 1 + b_counter;
311  }
312  pic->is_reference = 1;
313  *pic_out = pic;
314 
315  hw_base_encode_add_ref(pic, pic, 0, 1, 0);
316  if (pic->type != FF_HW_PICTURE_TYPE_IDR) {
317  // TODO: apply both previous and forward multi reference for all vaapi encoders.
318  // And L0/L1 reference frame number can be set dynamically through query
319  // VAConfigAttribEncMaxRefFrames attribute.
320  if (avctx->codec_id == AV_CODEC_ID_AV1) {
321  for (i = 0; i < ctx->nb_next_prev; i++)
322  hw_base_encode_add_ref(pic, ctx->next_prev[i],
323  pic->type == FF_HW_PICTURE_TYPE_P,
324  b_counter > 0, 0);
325  } else
326  hw_base_encode_add_ref(pic, start,
327  pic->type == FF_HW_PICTURE_TYPE_P,
328  b_counter > 0, 0);
329 
330  hw_base_encode_add_ref(pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1);
331  }
332 
333  if (b_counter > 0) {
334  hw_base_encode_set_b_pictures(ctx, start, pic, pic, 1,
335  &prev);
336  } else {
337  prev = pic;
338  }
340 
341  return 0;
342 }
343 
345 {
346  FFHWBaseEncodePicture *pic, *prev, *next;
347 
348  av_assert0(ctx->pic_start);
349 
350  // Remove direct references once each picture is complete.
351  for (pic = ctx->pic_start; pic; pic = pic->next) {
352  if (pic->encode_complete && pic->next)
354  }
355 
356  // Remove indirect references once a picture has no direct references.
357  for (pic = ctx->pic_start; pic; pic = pic->next) {
358  if (pic->encode_complete && pic->ref_count[0] == 0)
360  }
361 
362  // Clear out all complete pictures with no remaining references.
363  prev = NULL;
364  for (pic = ctx->pic_start; pic; pic = next) {
365  next = pic->next;
366  if (pic->encode_complete && pic->ref_count[1] == 0) {
367  av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
368  if (prev)
369  prev->next = next;
370  else
371  ctx->pic_start = next;
372  ctx->op->free(avctx, pic);
373  } else {
374  prev = pic;
375  }
376  }
377 
378  return 0;
379 }
380 
382  const AVFrame *frame)
383 {
384  if ((frame->crop_top || frame->crop_bottom ||
385  frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
386  av_log(ctx->log_ctx, AV_LOG_WARNING, "Cropping information on input "
387  "frames ignored due to lack of API support.\n");
388  ctx->crop_warned = 1;
389  }
390 
391  if (!ctx->roi_allowed) {
392  AVFrameSideData *sd =
394 
395  if (sd && !ctx->roi_warned) {
396  av_log(ctx->log_ctx, AV_LOG_WARNING, "ROI side data on input "
397  "frames ignored due to lack of driver support.\n");
398  ctx->roi_warned = 1;
399  }
400  }
401 
402  return 0;
403 }
404 
406  AVFrame *frame)
407 {
409  int err;
410 
411  if (frame) {
412  av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
413  frame->width, frame->height, frame->pts);
414 
416  if (err < 0)
417  return err;
418 
419  pic = ctx->op->alloc(avctx, frame);
420  if (!pic)
421  return AVERROR(ENOMEM);
422 
423  pic->input_image = av_frame_alloc();
424  if (!pic->input_image) {
425  err = AVERROR(ENOMEM);
426  goto fail;
427  }
428 
429  pic->recon_image = av_frame_alloc();
430  if (!pic->recon_image) {
431  err = AVERROR(ENOMEM);
432  goto fail;
433  }
434 
435  if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I)
436  pic->force_idr = 1;
437 
438  pic->pts = frame->pts;
439  pic->duration = frame->duration;
440 
441  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
442  err = av_buffer_replace(&pic->opaque_ref, frame->opaque_ref);
443  if (err < 0)
444  goto fail;
445 
446  pic->opaque = frame->opaque;
447  }
448 
450 
451  if (ctx->input_order == 0)
452  ctx->first_pts = pic->pts;
453  if (ctx->input_order == ctx->decode_delay)
454  ctx->dts_pts_diff = pic->pts - ctx->first_pts;
455  if (ctx->output_delay > 0)
456  ctx->ts_ring[ctx->input_order %
457  (3 * ctx->output_delay + ctx->async_depth)] = pic->pts;
458 
459  pic->display_order = ctx->input_order;
460  ++ctx->input_order;
461 
462  if (ctx->pic_start) {
463  ctx->pic_end->next = pic;
464  ctx->pic_end = pic;
465  } else {
466  ctx->pic_start = pic;
467  ctx->pic_end = pic;
468  }
469 
470  } else {
471  ctx->end_of_stream = 1;
472 
473  // Fix timestamps if we hit end-of-stream before the initial decode
474  // delay has elapsed.
475  if (ctx->input_order < ctx->decode_delay)
476  ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
477  }
478 
479  return 0;
480 
481 fail:
482  ctx->op->free(avctx, pic);
483  return err;
484 }
485 
487  AVCodecContext *avctx,
489  AVPacket *pkt, int flag_no_delay)
490 {
491  if (pic->type == FF_HW_PICTURE_TYPE_IDR)
493 
494  pkt->pts = pic->pts;
495  pkt->duration = pic->duration;
496 
497  // for no-delay encoders this is handled in generic codec
498  if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY &&
499  avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
500  pkt->opaque = pic->opaque;
501  pkt->opaque_ref = pic->opaque_ref;
502  pic->opaque_ref = NULL;
503  }
504 
505  if (flag_no_delay) {
506  pkt->dts = pkt->pts;
507  return 0;
508  }
509 
510  if (ctx->output_delay == 0) {
511  pkt->dts = pkt->pts;
512  } else if (pic->encode_order < ctx->decode_delay) {
513  if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
514  pkt->dts = INT64_MIN;
515  else
516  pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
517  } else {
518  pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
519  (3 * ctx->output_delay + ctx->async_depth)];
520  }
521 
522  return 0;
523 }
524 
526  AVCodecContext *avctx, AVPacket *pkt)
527 {
529  AVFrame *frame = ctx->frame;
530  int err;
531 
532  av_assert0(ctx->op && ctx->op->alloc && ctx->op->issue &&
533  ctx->op->output && ctx->op->free);
534 
535 start:
536  /** if no B frame before repeat P frame, sent repeat P frame out. */
537  if (ctx->tail_pkt->size) {
538  for (FFHWBaseEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) {
539  if (tmp->type == FF_HW_PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts)
540  break;
541  else if (!tmp->next) {
542  av_packet_move_ref(pkt, ctx->tail_pkt);
543  goto end;
544  }
545  }
546  }
547 
548  err = ff_encode_get_frame(avctx, frame);
549  if (err < 0 && err != AVERROR_EOF)
550  return err;
551 
552  if (err == AVERROR_EOF)
553  frame = NULL;
554 
555  err = hw_base_encode_send_frame(avctx, ctx, frame);
556  if (err < 0)
557  return err;
558 
559  if (!ctx->pic_start) {
560  if (ctx->end_of_stream)
561  return AVERROR_EOF;
562  else
563  return AVERROR(EAGAIN);
564  }
565 
566  if (ctx->async_encode) {
567  if (av_fifo_can_write(ctx->encode_fifo)) {
568  err = hw_base_encode_pick_next(avctx, ctx, &pic);
569  if (!err) {
570  av_assert0(pic);
571  pic->encode_order = ctx->encode_order +
572  av_fifo_can_read(ctx->encode_fifo);
573  err = ctx->op->issue(avctx, pic);
574  if (err < 0) {
575  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
576  return err;
577  }
578  pic->encode_issued = 1;
579  av_fifo_write(ctx->encode_fifo, &pic, 1);
580  }
581  }
582 
583  if (!av_fifo_can_read(ctx->encode_fifo))
584  return err;
585 
586  // More frames can be buffered
587  if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream)
588  return AVERROR(EAGAIN);
589 
590  av_fifo_read(ctx->encode_fifo, &pic, 1);
591  ctx->encode_order = pic->encode_order + 1;
592  } else {
593  err = hw_base_encode_pick_next(avctx, ctx, &pic);
594  if (err < 0)
595  return err;
596  av_assert0(pic);
597 
598  pic->encode_order = ctx->encode_order++;
599 
600  err = ctx->op->issue(avctx, pic);
601  if (err < 0) {
602  av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
603  return err;
604  }
605 
606  pic->encode_issued = 1;
607  }
608 
609  err = ctx->op->output(avctx, pic, pkt);
610  if (err < 0) {
611  av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
612  return err;
613  }
614 
615  ctx->output_order = pic->encode_order;
617 
618  /** loop to get an available pkt in encoder flushing. */
619  if (ctx->end_of_stream && !pkt->size)
620  goto start;
621 
622 end:
623  if (pkt->size)
624  av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", "
625  "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size);
626 
627  return 0;
628 }
629 
631  uint32_t ref_l0, uint32_t ref_l1,
632  int flags, int prediction_pre_only)
633 {
634  if (flags & FF_HW_FLAG_INTRA_ONLY || avctx->gop_size <= 1) {
635  av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
636  ctx->gop_size = 1;
637  } else if (ref_l0 < 1) {
638  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
639  "reference frames.\n");
640  return AVERROR(EINVAL);
641  } else if (!(flags & FF_HW_FLAG_B_PICTURES) || ref_l1 < 1 ||
642  avctx->max_b_frames < 1 || prediction_pre_only) {
643  if (ctx->p_to_gpb)
644  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
645  "(supported references: %d / %d).\n",
646  ref_l0, ref_l1);
647  else
648  av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
649  "(supported references: %d / %d).\n", ref_l0, ref_l1);
650  ctx->gop_size = avctx->gop_size;
651  ctx->p_per_i = INT_MAX;
652  ctx->b_per_p = 0;
653  } else {
654  if (ctx->p_to_gpb)
655  av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
656  "(supported references: %d / %d).\n",
657  ref_l0, ref_l1);
658  else
659  av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
660  "(supported references: %d / %d).\n", ref_l0, ref_l1);
661  ctx->gop_size = avctx->gop_size;
662  ctx->p_per_i = INT_MAX;
663  ctx->b_per_p = avctx->max_b_frames;
665  ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
666  av_log2(ctx->b_per_p) + 1);
667  } else {
668  ctx->max_b_depth = 1;
669  }
670  }
671 
673  ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
674  ctx->gop_per_idr = ctx->idr_interval + 1;
675  } else {
676  ctx->closed_gop = 1;
677  ctx->gop_per_idr = 1;
678  }
679 
680  return 0;
681 }
682 
684  enum AVPixelFormat *fmt)
685 {
686  AVHWFramesConstraints *constraints = NULL;
687  enum AVPixelFormat recon_format;
688  int err, i;
689 
690  constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
691  hwconfig);
692  if (!constraints) {
693  err = AVERROR(ENOMEM);
694  goto fail;
695  }
696 
697  // Probably we can use the input surface format as the surface format
698  // of the reconstructed frames. If not, we just pick the first (only?)
699  // format in the valid list and hope that it all works.
700  recon_format = AV_PIX_FMT_NONE;
701  if (constraints->valid_sw_formats) {
702  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
703  if (ctx->input_frames->sw_format ==
704  constraints->valid_sw_formats[i]) {
705  recon_format = ctx->input_frames->sw_format;
706  break;
707  }
708  }
709  if (recon_format == AV_PIX_FMT_NONE) {
710  // No match. Just use the first in the supported list and
711  // hope for the best.
712  recon_format = constraints->valid_sw_formats[0];
713  }
714  } else {
715  // No idea what to use; copy input format.
716  recon_format = ctx->input_frames->sw_format;
717  }
718  av_log(ctx->log_ctx, AV_LOG_DEBUG, "Using %s as format of "
719  "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
720 
721  if (ctx->surface_width < constraints->min_width ||
722  ctx->surface_height < constraints->min_height ||
723  ctx->surface_width > constraints->max_width ||
724  ctx->surface_height > constraints->max_height) {
725  av_log(ctx->log_ctx, AV_LOG_ERROR, "Hardware does not support encoding at "
726  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
727  ctx->surface_width, ctx->surface_height,
728  constraints->min_width, constraints->max_width,
729  constraints->min_height, constraints->max_height);
730  err = AVERROR(EINVAL);
731  goto fail;
732  }
733 
734  *fmt = recon_format;
735  err = 0;
736 fail:
737  av_hwframe_constraints_free(&constraints);
738  return err;
739 }
740 
742 {
743  av_frame_free(&pic->input_image);
744  av_frame_free(&pic->recon_image);
745 
747  av_freep(&pic->priv_data);
748 
749  return 0;
750 }
751 
753 {
754  ctx->log_ctx = (void *)avctx;
755 
756  ctx->frame = av_frame_alloc();
757  if (!ctx->frame)
758  return AVERROR(ENOMEM);
759 
760  if (!avctx->hw_frames_ctx) {
761  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
762  "required to associate the encoding device.\n");
763  return AVERROR(EINVAL);
764  }
765 
766  ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
767  if (!ctx->input_frames_ref)
768  return AVERROR(ENOMEM);
769 
770  ctx->input_frames = (AVHWFramesContext *)ctx->input_frames_ref->data;
771 
772  ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
773  if (!ctx->device_ref)
774  return AVERROR(ENOMEM);
775 
776  ctx->device = (AVHWDeviceContext *)ctx->device_ref->data;
777 
778  ctx->tail_pkt = av_packet_alloc();
779  if (!ctx->tail_pkt)
780  return AVERROR(ENOMEM);
781 
782  return 0;
783 }
784 
786 {
787  av_fifo_freep2(&ctx->encode_fifo);
788 
789  av_frame_free(&ctx->frame);
790  av_packet_free(&ctx->tail_pkt);
791 
792  av_buffer_unref(&ctx->device_ref);
793  av_buffer_unref(&ctx->input_frames_ref);
794  av_buffer_unref(&ctx->recon_frames_ref);
795 
796  return 0;
797 }
FFHWBaseEncodePicture::b_depth
int b_depth
Definition: hw_base_encode.h:73
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
level
uint8_t level
Definition: svq3.c:205
FFHWBaseEncodePicture::next
struct FFHWBaseEncodePicture * next
Definition: hw_base_encode.h:61
FF_HW_PICTURE_TYPE_I
@ FF_HW_PICTURE_TYPE_I
Definition: hw_base_encode.h:39
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
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:947
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:206
ff_hw_base_encode_init
int ff_hw_base_encode_init(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:752
encode.h
FFHWBaseEncodePicture::recon_image
AVFrame * recon_image
Definition: hw_base_encode.h:78
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:538
hw_base_encode_add_ref
static void hw_base_encode_add_ref(FFHWBaseEncodePicture *pic, FFHWBaseEncodePicture *target, int is_ref, int in_dpb, int prev)
Definition: hw_base_encode.c:30
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
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:566
FF_HW_FLAG_B_PICTURE_REFERENCES
@ FF_HW_FLAG_B_PICTURE_REFERENCES
Definition: hw_base_encode.h:54
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:575
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:441
FFHWBaseEncodeContext
Definition: hw_base_encode.h:117
AV_CODEC_FLAG_COPY_OPAQUE
#define AV_CODEC_FLAG_COPY_OPAQUE
Definition: avcodec.h:299
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:454
FFHWBaseEncodePicture::type
int type
Definition: hw_base_encode.h:72
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:556
ff_hw_base_encode_close
int ff_hw_base_encode_close(FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:785
FFHWBaseEncodePicture::is_reference
int is_reference
Definition: hw_base_encode.h:83
fail
#define fail()
Definition: checkasm.h:186
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
FF_HW_PICTURE_TYPE_B
@ FF_HW_PICTURE_TYPE_B
Definition: hw_base_encode.h:41
FFHWBaseEncodePicture::ref_removed
int ref_removed[2]
Definition: hw_base_encode.h:102
AVHWFramesConstraints::min_width
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:459
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:502
FFHWBaseEncodePicture::input_image
AVFrame * input_image
Definition: hw_base_encode.h:77
ff_hw_base_init_gop_structure
int ff_hw_base_init_gop_structure(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, uint32_t ref_l0, uint32_t ref_l1, int flags, int prediction_pre_only)
Definition: hw_base_encode.c:630
FF_HW_FLAG_B_PICTURES
@ FF_HW_FLAG_B_PICTURES
Definition: hw_base_encode.h:52
FFHWBaseEncodePicture::prev
struct FFHWBaseEncodePicture * prev
Definition: hw_base_encode.h:97
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:148
avassert.h
ff_hw_base_get_recon_format
int ff_hw_base_get_recon_format(FFHWBaseEncodeContext *ctx, const void *hwconfig, enum AVPixelFormat *fmt)
Definition: hw_base_encode.c:683
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FFHWBaseEncodePicture::opaque
void * opaque
Definition: hw_base_encode.h:69
hw_base_encode_clear_old
static int hw_base_encode_clear_old(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:344
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
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:453
av_hwframe_constraints_free
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:591
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
FFHWBaseEncodePicture::priv_data
void * priv_data
Definition: hw_base_encode.h:80
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:49
hw_base_encode_set_b_pictures
static void hw_base_encode_set_b_pictures(FFHWBaseEncodeContext *ctx, FFHWBaseEncodePicture *start, FFHWBaseEncodePicture *end, FFHWBaseEncodePicture *prev, int current_depth, FFHWBaseEncodePicture **last)
Definition: hw_base_encode.c:97
hw_base_encode.h
FF_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:38
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:545
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:455
if
if(ret)
Definition: filter_design.txt:179
FFHWBaseEncodePicture::dpb
struct FFHWBaseEncodePicture * dpb[MAX_DPB_SIZE]
Definition: hw_base_encode.h:89
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
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: packet.c:484
FFHWBaseEncodePicture::force_idr
int force_idr
Definition: hw_base_encode.h:67
ff_hw_base_encode_set_output_property
int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, FFHWBaseEncodePicture *pic, AVPacket *pkt, int flag_no_delay)
Definition: hw_base_encode.c:486
hw_base_encode_check_frame
static int hw_base_encode_check_frame(FFHWBaseEncodeContext *ctx, const AVFrame *frame)
Definition: hw_base_encode.c:381
AVPacket::size
int size
Definition: packet.h:521
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1031
FFHWBaseEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: hw_base_encode.h:93
MAX_DPB_SIZE
#define MAX_DPB_SIZE
Definition: hw_base_encode.h:25
ff_hw_base_encode_receive_packet
int ff_hw_base_encode_receive_packet(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, AVPacket *pkt)
Definition: hw_base_encode.c:525
FFHWBaseEncodePicture::encode_order
int64_t encode_order
Definition: hw_base_encode.h:64
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:519
AVHWFramesConstraints::max_width
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:466
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:526
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
FFHWBaseEncodePicture::opaque_ref
AVBufferRef * opaque_ref
Definition: hw_base_encode.h:70
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:513
internal.h
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:633
FFHWBaseEncodePicture::refs
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: hw_base_encode.h:94
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:233
len
int len
Definition: vorbis_enc_data.h:426
ff_hw_base_encode_free
int ff_hw_base_encode_free(FFHWBaseEncodePicture *pic)
Definition: hw_base_encode.c:741
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:1475
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
hw_base_encode_add_next_prev
static void hw_base_encode_add_next_prev(FFHWBaseEncodeContext *ctx, FFHWBaseEncodePicture *pic)
Definition: hw_base_encode.c:160
AV_CODEC_FLAG_CLOSED_GOP
#define AV_CODEC_FLAG_CLOSED_GOP
Definition: avcodec.h:352
FFHWBaseEncodePicture
Definition: hw_base_encode.h:60
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:467
FF_HW_PICTURE_TYPE_P
@ FF_HW_PICTURE_TYPE_P
Definition: hw_base_encode.h:40
AVCodecContext
main external API structure.
Definition: avcodec.h:445
hw_base_encode_pick_next
static int hw_base_encode_pick_next(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx, FFHWBaseEncodePicture **pic_out)
Definition: hw_base_encode.c:192
hw_base_encode_remove_refs
static void hw_base_encode_remove_refs(FFHWBaseEncodePicture *pic, int level)
Definition: hw_base_encode.c:63
AVHWFramesConstraints::min_height
int min_height
Definition: hwcontext.h:460
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
FF_HW_FLAG_INTRA_ONLY
@ FF_HW_FLAG_INTRA_ONLY
Definition: hw_base_encode.h:50
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
hw_base_encode_send_frame
static int hw_base_encode_send_frame(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx, AVFrame *frame)
Definition: hw_base_encode.c:405
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:76
FF_HW_FLAG_NON_IDR_KEY_PICTURES
@ FF_HW_FLAG_NON_IDR_KEY_PICTURES
Definition: hw_base_encode.h:57
FFHWBaseEncodePicture::encode_complete
int encode_complete
Definition: hw_base_encode.h:75
mem.h
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:795
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:205
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:250
FFHWBaseEncodePicture::pts
int64_t pts
Definition: hw_base_encode.h:65
AVPacket
This structure stores compressed data.
Definition: packet.h:497
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:165
FFHWBaseEncodePicture::duration
int64_t duration
Definition: hw_base_encode.h:66
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
FFHWBaseEncodePicture::encode_issued
int encode_issued
Definition: hw_base_encode.h:74
FFHWBaseEncodePicture::display_order
int64_t display_order
Definition: hw_base_encode.h:63
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
FFHWBaseEncodePicture::ref_count
int ref_count[2]
Definition: hw_base_encode.h:101
FFHWBaseEncodePicture::nb_dpb_pics
int nb_dpb_pics
Definition: hw_base_encode.h:88
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:2885
MAX_PICTURE_REFERENCES
#define MAX_PICTURE_REFERENCES
Definition: hw_base_encode.h:26