History

avcodec/vaapi_encode: move the dpb logic from VAAPI to base layer

Move receive_packet function to base. This requires adding *alloc, *issue, *output, *free as hardware callbacks. HWBaseEncodePicture is introduced as the base layer structure. The related parameters in VAAPIEncodeContext are also extracted to HWBaseEncodeContext. Then DPB management logic can be fully extracted to base layer as-is.

Tong Wu committed 2 years ago

Commit aa823401 parent f303c2612 files · +985 −890Browse files

Showing the changes to libavcodec (12 of 12 files). Show all

Unified · Split

12 files
  1. libavcodec/Makefile +1 −1
  2. libavcodec/hw_base_encode.c +594 −0
  3. libavcodec/hw_base_encode.h +124 −0
  4. libavcodec/vaapi_encode.c +126 −667
  5. libavcodec/vaapi_encode.h +1 −101
  6. libavcodec/vaapi_encode_av1.c +19 −16
  7. libavcodec/vaapi_encode_h264.c +44 −40
  8. libavcodec/vaapi_encode_h265.c +28 −25
  9. libavcodec/vaapi_encode_mjpeg.c +7 −6
  10. libavcodec/vaapi_encode_mpeg2.c +18 −15
  11. libavcodec/vaapi_encode_vp8.c +10 −8
  12. libavcodec/vaapi_encode_vp9.c +13 −11
libavcodec/Makefile+1−1
@@ -165,7 +165,7 @@ OBJS-$(CONFIG_STARTCODE) += startcode.o · 164 unmodified lines
165165 OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
166166 OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o
167167 OBJS-$(CONFIG_TPELDSP) += tpeldsp.o
168−OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o
168+OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o hw_base_encode.o
169169 OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o
170170 OBJS-$(CONFIG_VC1DSP) += vc1dsp.o
171171 OBJS-$(CONFIG_VIDEODSP) += videodsp.o
libavcodec/hw_base_encode.c+594−0
@@ -0,0 +1,594 @@
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+
30+static void hw_base_encode_add_ref(FFHWBaseEncodePicture *pic,
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);
38+ av_assert0(pic->nb_refs[0] < MAX_PICTURE_REFERENCES &&
39+ pic->nb_refs[1] < MAX_PICTURE_REFERENCES);
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) {
48+ av_assert0(pic->nb_dpb_pics < MAX_DPB_SIZE);
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+
63+static void hw_base_encode_remove_refs(FFHWBaseEncodePicture *pic, int level)
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+
97+static void hw_base_encode_set_b_pictures(AVCodecContext *avctx,
98+ FFHWBaseEncodePicture *start,
99+ FFHWBaseEncodePicture *end,
100+ FFHWBaseEncodePicture *prev,
101+ int current_depth,
102+ FFHWBaseEncodePicture **last)
103+{
104+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
105+ FFHWBaseEncodePicture *pic, *next, *ref;
106+ int i, len;
107+
108+ av_assert0(start && end && start != end && start->next != end);
109+
110+ // If we are at the maximum depth then encode all pictures as
111+ // non-referenced B-pictures. Also do this if there is exactly one
112+ // picture left, since there will be nothing to reference it.
113+ if (current_depth == ctx->max_b_depth || start->next->next == end) {
114+ for (pic = start->next; pic; pic = pic->next) {
115+ if (pic == end)
116+ break;
117+ pic->type = FF_HW_PICTURE_TYPE_B;
118+ pic->b_depth = current_depth;
119+
120+ hw_base_encode_add_ref(pic, start, 1, 1, 0);
121+ hw_base_encode_add_ref(pic, end, 1, 1, 0);
122+ hw_base_encode_add_ref(pic, prev, 0, 0, 1);
123+
124+ for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
125+ hw_base_encode_add_ref(pic, ref, 0, 1, 0);
126+ }
127+ *last = prev;
128+
129+ } else {
130+ // Split the current list at the midpoint with a referenced
131+ // B-picture, then descend into each side separately.
132+ len = 0;
133+ for (pic = start->next; pic != end; pic = pic->next)
134+ ++len;
135+ for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
136+
137+ pic->type = FF_HW_PICTURE_TYPE_B;
138+ pic->b_depth = current_depth;
139+
140+ pic->is_reference = 1;
141+
142+ hw_base_encode_add_ref(pic, pic, 0, 1, 0);
143+ hw_base_encode_add_ref(pic, start, 1, 1, 0);
144+ hw_base_encode_add_ref(pic, end, 1, 1, 0);
145+ hw_base_encode_add_ref(pic, prev, 0, 0, 1);
146+
147+ for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
148+ hw_base_encode_add_ref(pic, ref, 0, 1, 0);
149+
150+ if (i > 1)
151+ hw_base_encode_set_b_pictures(avctx, start, pic, pic,
152+ current_depth + 1, &next);
153+ else
154+ next = pic;
155+
156+ hw_base_encode_set_b_pictures(avctx, pic, end, next,
157+ current_depth + 1, last);
158+ }
159+}
160+
161+static void hw_base_encode_add_next_prev(AVCodecContext *avctx,
162+ FFHWBaseEncodePicture *pic)
163+{
164+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
165+ int i;
166+
167+ if (!pic)
168+ return;
169+
170+ if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
171+ for (i = 0; i < ctx->nb_next_prev; i++) {
172+ --ctx->next_prev[i]->ref_count[0];
173+ ctx->next_prev[i] = NULL;
174+ }
175+ ctx->next_prev[0] = pic;
176+ ++pic->ref_count[0];
177+ ctx->nb_next_prev = 1;
178+
179+ return;
180+ }
181+
182+ if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) {
183+ ctx->next_prev[ctx->nb_next_prev++] = pic;
184+ ++pic->ref_count[0];
185+ } else {
186+ --ctx->next_prev[0]->ref_count[0];
187+ for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++)
188+ ctx->next_prev[i] = ctx->next_prev[i + 1];
189+ ctx->next_prev[i] = pic;
190+ ++pic->ref_count[0];
191+ }
192+}
193+
194+static int hw_base_encode_pick_next(AVCodecContext *avctx,
195+ FFHWBaseEncodePicture **pic_out)
196+{
197+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
198+ FFHWBaseEncodePicture *pic = NULL, *prev = NULL, *next, *start;
199+ int i, b_counter, closed_gop_end;
200+
201+ // If there are any B-frames already queued, the next one to encode
202+ // is the earliest not-yet-issued frame for which all references are
203+ // available.
204+ for (pic = ctx->pic_start; pic; pic = pic->next) {
205+ if (pic->encode_issued)
206+ continue;
207+ if (pic->type != FF_HW_PICTURE_TYPE_B)
208+ continue;
209+ for (i = 0; i < pic->nb_refs[0]; i++) {
210+ if (!pic->refs[0][i]->encode_issued)
211+ break;
212+ }
213+ if (i != pic->nb_refs[0])
214+ continue;
215+
216+ for (i = 0; i < pic->nb_refs[1]; i++) {
217+ if (!pic->refs[1][i]->encode_issued)
218+ break;
219+ }
220+ if (i == pic->nb_refs[1])
221+ break;
222+ }
223+
224+ if (pic) {
225+ av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
226+ "encode next.\n", pic->b_depth);
227+ *pic_out = pic;
228+ return 0;
229+ }
230+
231+ // Find the B-per-Pth available picture to become the next picture
232+ // on the top layer.
233+ start = NULL;
234+ b_counter = 0;
235+ closed_gop_end = ctx->closed_gop ||
236+ ctx->idr_counter == ctx->gop_per_idr;
237+ for (pic = ctx->pic_start; pic; pic = next) {
238+ next = pic->next;
239+ if (pic->encode_issued) {
240+ start = pic;
241+ continue;
242+ }
243+ // If the next available picture is force-IDR, encode it to start
244+ // a new GOP immediately.
245+ if (pic->force_idr)
246+ break;
247+ if (b_counter == ctx->b_per_p)
248+ break;
249+ // If this picture ends a closed GOP or starts a new GOP then it
250+ // needs to be in the top layer.
251+ if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
252+ break;
253+ // If the picture after this one is force-IDR, we need to encode
254+ // this one in the top layer.
255+ if (next && next->force_idr)
256+ break;
257+ ++b_counter;
258+ }
259+
260+ // At the end of the stream the last picture must be in the top layer.
261+ if (!pic && ctx->end_of_stream) {
262+ --b_counter;
263+ pic = ctx->pic_end;
264+ if (pic->encode_complete)
265+ return AVERROR_EOF;
266+ else if (pic->encode_issued)
267+ return AVERROR(EAGAIN);
268+ }
269+
270+ if (!pic) {
271+ av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
272+ "need more input for reference pictures.\n");
273+ return AVERROR(EAGAIN);
274+ }
275+ if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
276+ av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
277+ "need more input for timestamps.\n");
278+ return AVERROR(EAGAIN);
279+ }
280+
281+ if (pic->force_idr) {
282+ av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
283+ "encode next.\n");
284+ pic->type = FF_HW_PICTURE_TYPE_IDR;
285+ ctx->idr_counter = 1;
286+ ctx->gop_counter = 1;
287+
288+ } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
289+ if (ctx->idr_counter == ctx->gop_per_idr) {
290+ av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
291+ "encode next.\n");
292+ pic->type = FF_HW_PICTURE_TYPE_IDR;
293+ ctx->idr_counter = 1;
294+ } else {
295+ av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
296+ "encode next.\n");
297+ pic->type = FF_HW_PICTURE_TYPE_I;
298+ ++ctx->idr_counter;
299+ }
300+ ctx->gop_counter = 1;
301+
302+ } else {
303+ if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
304+ av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
305+ "encode next.\n");
306+ } else {
307+ av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
308+ "encode next.\n");
309+ }
310+ pic->type = FF_HW_PICTURE_TYPE_P;
311+ av_assert0(start);
312+ ctx->gop_counter += 1 + b_counter;
313+ }
314+ pic->is_reference = 1;
315+ *pic_out = pic;
316+
317+ hw_base_encode_add_ref(pic, pic, 0, 1, 0);
318+ if (pic->type != FF_HW_PICTURE_TYPE_IDR) {
319+ // TODO: apply both previous and forward multi reference for all vaapi encoders.
320+ // And L0/L1 reference frame number can be set dynamically through query
321+ // VAConfigAttribEncMaxRefFrames attribute.
322+ if (avctx->codec_id == AV_CODEC_ID_AV1) {
323+ for (i = 0; i < ctx->nb_next_prev; i++)
324+ hw_base_encode_add_ref(pic, ctx->next_prev[i],
325+ pic->type == FF_HW_PICTURE_TYPE_P,
326+ b_counter > 0, 0);
327+ } else
328+ hw_base_encode_add_ref(pic, start,
329+ pic->type == FF_HW_PICTURE_TYPE_P,
330+ b_counter > 0, 0);
331+
332+ hw_base_encode_add_ref(pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1);
333+ }
334+
335+ if (b_counter > 0) {
336+ hw_base_encode_set_b_pictures(avctx, start, pic, pic, 1,
337+ &prev);
338+ } else {
339+ prev = pic;
340+ }
341+ hw_base_encode_add_next_prev(avctx, prev);
342+
343+ return 0;
344+}
345+
346+static int hw_base_encode_clear_old(AVCodecContext *avctx)
347+{
348+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
349+ FFHWBaseEncodePicture *pic, *prev, *next;
350+
351+ av_assert0(ctx->pic_start);
352+
353+ // Remove direct references once each picture is complete.
354+ for (pic = ctx->pic_start; pic; pic = pic->next) {
355+ if (pic->encode_complete && pic->next)
356+ hw_base_encode_remove_refs(pic, 0);
357+ }
358+
359+ // Remove indirect references once a picture has no direct references.
360+ for (pic = ctx->pic_start; pic; pic = pic->next) {
361+ if (pic->encode_complete && pic->ref_count[0] == 0)
362+ hw_base_encode_remove_refs(pic, 1);
363+ }
364+
365+ // Clear out all complete pictures with no remaining references.
366+ prev = NULL;
367+ for (pic = ctx->pic_start; pic; pic = next) {
368+ next = pic->next;
369+ if (pic->encode_complete && pic->ref_count[1] == 0) {
370+ av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
371+ if (prev)
372+ prev->next = next;
373+ else
374+ ctx->pic_start = next;
375+ ctx->op->free(avctx, pic);
376+ } else {
377+ prev = pic;
378+ }
379+ }
380+
381+ return 0;
382+}
383+
384+static int hw_base_encode_check_frame(AVCodecContext *avctx,
385+ const AVFrame *frame)
386+{
387+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
388+
389+ if ((frame->crop_top || frame->crop_bottom ||
390+ frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
391+ av_log(avctx, AV_LOG_WARNING, "Cropping information on input "
392+ "frames ignored due to lack of API support.\n");
393+ ctx->crop_warned = 1;
394+ }
395+
396+ if (!ctx->roi_allowed) {
397+ AVFrameSideData *sd =
398+ av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
399+
400+ if (sd && !ctx->roi_warned) {
401+ av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
402+ "frames ignored due to lack of driver support.\n");
403+ ctx->roi_warned = 1;
404+ }
405+ }
406+
407+ return 0;
408+}
409+
410+static int hw_base_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
411+{
412+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
413+ FFHWBaseEncodePicture *pic;
414+ int err;
415+
416+ if (frame) {
417+ av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
418+ frame->width, frame->height, frame->pts);
419+
420+ err = hw_base_encode_check_frame(avctx, frame);
421+ if (err < 0)
422+ return err;
423+
424+ pic = ctx->op->alloc(avctx, frame);
425+ if (!pic)
426+ return AVERROR(ENOMEM);
427+
428+ pic->input_image = av_frame_alloc();
429+ if (!pic->input_image) {
430+ err = AVERROR(ENOMEM);
431+ goto fail;
432+ }
433+
434+ pic->recon_image = av_frame_alloc();
435+ if (!pic->recon_image) {
436+ err = AVERROR(ENOMEM);
437+ goto fail;
438+ }
439+
440+ if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I)
441+ pic->force_idr = 1;
442+
443+ pic->pts = frame->pts;
444+ pic->duration = frame->duration;
445+
446+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
447+ err = av_buffer_replace(&pic->opaque_ref, frame->opaque_ref);
448+ if (err < 0)
449+ goto fail;
450+
451+ pic->opaque = frame->opaque;
452+ }
453+
454+ av_frame_move_ref(pic->input_image, frame);
455+
456+ if (ctx->input_order == 0)
457+ ctx->first_pts = pic->pts;
458+ if (ctx->input_order == ctx->decode_delay)
459+ ctx->dts_pts_diff = pic->pts - ctx->first_pts;
460+ if (ctx->output_delay > 0)
461+ ctx->ts_ring[ctx->input_order %
462+ (3 * ctx->output_delay + ctx->async_depth)] = pic->pts;
463+
464+ pic->display_order = ctx->input_order;
465+ ++ctx->input_order;
466+
467+ if (ctx->pic_start) {
468+ ctx->pic_end->next = pic;
469+ ctx->pic_end = pic;
470+ } else {
471+ ctx->pic_start = pic;
472+ ctx->pic_end = pic;
473+ }
474+
475+ } else {
476+ ctx->end_of_stream = 1;
477+
478+ // Fix timestamps if we hit end-of-stream before the initial decode
479+ // delay has elapsed.
480+ if (ctx->input_order < ctx->decode_delay)
481+ ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
482+ }
483+
484+ return 0;
485+
486+fail:
487+ ctx->op->free(avctx, pic);
488+ return err;
489+}
490+
491+int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
492+{
493+ FFHWBaseEncodeContext *ctx = avctx->priv_data;
494+ FFHWBaseEncodePicture *pic = NULL;
495+ AVFrame *frame = ctx->frame;
496+ int err;
497+
498+ av_assert0(ctx->op && ctx->op->alloc && ctx->op->issue &&
499+ ctx->op->output && ctx->op->free);
500+
501+start:
502+ /** if no B frame before repeat P frame, sent repeat P frame out. */
503+ if (ctx->tail_pkt->size) {
504+ for (FFHWBaseEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) {
505+ if (tmp->type == FF_HW_PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts)
506+ break;
507+ else if (!tmp->next) {
508+ av_packet_move_ref(pkt, ctx->tail_pkt);
509+ goto end;
510+ }
511+ }
512+ }
513+
514+ err = ff_encode_get_frame(avctx, frame);
515+ if (err < 0 && err != AVERROR_EOF)
516+ return err;
517+
518+ if (err == AVERROR_EOF)
519+ frame = NULL;
520+
521+ err = hw_base_encode_send_frame(avctx, frame);
522+ if (err < 0)
523+ return err;
524+
525+ if (!ctx->pic_start) {
526+ if (ctx->end_of_stream)
527+ return AVERROR_EOF;
528+ else
529+ return AVERROR(EAGAIN);
530+ }
531+
532+ if (ctx->async_encode) {
533+ if (av_fifo_can_write(ctx->encode_fifo)) {
534+ err = hw_base_encode_pick_next(avctx, &pic);
535+ if (!err) {
536+ av_assert0(pic);
537+ pic->encode_order = ctx->encode_order +
538+ av_fifo_can_read(ctx->encode_fifo);
539+ err = ctx->op->issue(avctx, pic);
540+ if (err < 0) {
541+ av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
542+ return err;
543+ }
544+ pic->encode_issued = 1;
545+ av_fifo_write(ctx->encode_fifo, &pic, 1);
546+ }
547+ }
548+
549+ if (!av_fifo_can_read(ctx->encode_fifo))
550+ return err;
551+
552+ // More frames can be buffered
553+ if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream)
554+ return AVERROR(EAGAIN);
555+
556+ av_fifo_read(ctx->encode_fifo, &pic, 1);
557+ ctx->encode_order = pic->encode_order + 1;
558+ } else {
559+ err = hw_base_encode_pick_next(avctx, &pic);
560+ if (err < 0)
561+ return err;
562+ av_assert0(pic);
563+
564+ pic->encode_order = ctx->encode_order++;
565+
566+ err = ctx->op->issue(avctx, pic);
567+ if (err < 0) {
568+ av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
569+ return err;
570+ }
571+
572+ pic->encode_issued = 1;
573+ }
574+
575+ err = ctx->op->output(avctx, pic, pkt);
576+ if (err < 0) {
577+ av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
578+ return err;
579+ }
580+
581+ ctx->output_order = pic->encode_order;
582+ hw_base_encode_clear_old(avctx);
583+
584+ /** loop to get an available pkt in encoder flushing. */
585+ if (ctx->end_of_stream && !pkt->size)
586+ goto start;
587+
588+end:
589+ if (pkt->size)
590+ av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", "
591+ "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size);
592+
593+ return 0;
594+}
libavcodec/hw_base_encode.h+124−0
@@ -19,6 +19,8 @@ · 18 unmodified lines
1919 #ifndef AVCODEC_HW_BASE_ENCODE_H
2020 #define AVCODEC_HW_BASE_ENCODE_H
2121
22+#include "libavutil/fifo.h"
23+
2224 #define MAX_DPB_SIZE 16
2325 #define MAX_PICTURE_REFERENCES 2
2426 #define MAX_REORDER_DELAY 16
@@ -54,13 +56,135 @@ enum { · 29 unmodified lines
5456 FF_HW_FLAG_NON_IDR_KEY_PICTURES = 1 << 5,
5557 };
5658
59+typedef struct FFHWBaseEncodePicture {
60+ struct FFHWBaseEncodePicture *next;
61+
62+ int64_t display_order;
63+ int64_t encode_order;
64+ int64_t pts;
65+ int64_t duration;
66+ int force_idr;
67+
68+ void *opaque;
69+ AVBufferRef *opaque_ref;
70+
71+ int type;
72+ int b_depth;
73+ int encode_issued;
74+ int encode_complete;
75+
76+ AVFrame *input_image;
77+ AVFrame *recon_image;
78+
79+ void *priv_data;
80+
81+ // Whether this picture is a reference picture.
82+ int is_reference;
83+
84+ // The contents of the DPB after this picture has been decoded.
85+ // This will contain the picture itself if it is a reference picture,
86+ // but not if it isn't.
87+ int nb_dpb_pics;
88+ struct FFHWBaseEncodePicture *dpb[MAX_DPB_SIZE];
89+ // The reference pictures used in decoding this picture. If they are
90+ // used by later pictures they will also appear in the DPB. ref[0][] for
91+ // previous reference frames. ref[1][] for future reference frames.
92+ int nb_refs[MAX_REFERENCE_LIST_NUM];
93+ struct FFHWBaseEncodePicture *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES];
94+ // The previous reference picture in encode order. Must be in at least
95+ // one of the reference list and DPB list.
96+ struct FFHWBaseEncodePicture *prev;
97+ // Reference count for other pictures referring to this one through
98+ // the above pointers, directly from incomplete pictures and indirectly
99+ // through completed pictures.
100+ int ref_count[2];
101+ int ref_removed[2];
102+} FFHWBaseEncodePicture;
103+
104+typedef struct FFHWEncodePictureOperation {
105+ // Alloc memory for the picture structure and initialize the API-specific internals
106+ // based of the given frame.
107+ FFHWBaseEncodePicture * (*alloc)(AVCodecContext *avctx, const AVFrame *frame);
108+ // Issue the picture structure, which will send the frame surface to HW Encode API.
109+ int (*issue)(AVCodecContext *avctx, const FFHWBaseEncodePicture *base_pic);
110+ // Get the output AVPacket.
111+ int (*output)(AVCodecContext *avctx, const FFHWBaseEncodePicture *base_pic, AVPacket *pkt);
112+ // Free the picture structure.
113+ int (*free)(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic);
114+} FFHWEncodePictureOperation;
115+
57116 typedef struct FFHWBaseEncodeContext {
58117 const AVClass *class;
59118
119+ // Hardware-specific hooks.
120+ const struct FFHWEncodePictureOperation *op;
121+
122+ // Current encoding window, in display (input) order.
123+ FFHWBaseEncodePicture *pic_start, *pic_end;
124+ // The next picture to use as the previous reference picture in
125+ // encoding order. Order from small to large in encoding order.
126+ FFHWBaseEncodePicture *next_prev[MAX_PICTURE_REFERENCES];
127+ int nb_next_prev;
128+
129+ // Next input order index (display order).
130+ int64_t input_order;
131+ // Number of frames that output is behind input.
132+ int64_t output_delay;
133+ // Next encode order index.
134+ int64_t encode_order;
135+ // Number of frames decode output will need to be delayed.
136+ int64_t decode_delay;
137+ // Next output order index (in encode order).
138+ int64_t output_order;
139+
140+ // Timestamp handling.
141+ int64_t first_pts;
142+ int64_t dts_pts_diff;
143+ int64_t ts_ring[MAX_REORDER_DELAY * 3 +
144+ MAX_ASYNC_DEPTH];
145+
146+ // Frame type decision.
147+ int gop_size;
148+ int closed_gop;
149+ int gop_per_idr;
150+ int p_per_i;
151+ int max_b_depth;
152+ int b_per_p;
153+ int force_idr;
154+ int idr_counter;
155+ int gop_counter;
156+ int end_of_stream;
157+ int p_to_gpb;
158+
159+ // Whether the driver supports ROI at all.
160+ int roi_allowed;
161+
162+ // The encoder does not support cropping information, so warn about
163+ // it the first time we encounter any nonzero crop fields.
164+ int crop_warned;
165+ // If the driver does not support ROI then warn the first time we
166+ // encounter a frame with ROI side data.
167+ int roi_warned;
168+
169+ // The frame to be filled with data.
170+ AVFrame *frame;
171+
172+ // Whether the HW supports sync buffer function.
173+ // If supported, encode_fifo/async_depth will be used together.
174+ // Used for output buffer synchronization.
175+ int async_encode;
176+
177+ // Store buffered pic.
178+ AVFifo *encode_fifo;
60179 // Max number of frame buffered in encoder.
61180 int async_depth;
181+
182+ /** Tail data of a pic, now only used for av1 repeat frame header. */
183+ AVPacket *tail_pkt;
62184 } FFHWBaseEncodeContext;
63185
186+int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
187+
64188 #define HW_BASE_ENCODE_COMMON_OPTIONS \
65189 { "async_depth", "Maximum processing parallelism. " \
66190 "Increase this to improve single channel performance.", \
libavcodec/vaapi_encode.c+126−667
@@ -138,22 +138,26 @@ static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, · 137 unmodified lines
138138 static int vaapi_encode_wait(AVCodecContext *avctx,
139139 VAAPIEncodePicture *pic)
140140 {
141+#if VA_CHECK_VERSION(1, 9, 0)
142+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
143+#endif
141144 VAAPIEncodeContext *ctx = avctx->priv_data;
145+ FFHWBaseEncodePicture *base_pic = &pic->base;
142146 VAStatus vas;
143147
144− av_assert0(pic->encode_issued);
148+ av_assert0(base_pic->encode_issued);
145149
146− if (pic->encode_complete) {
150+ if (base_pic->encode_complete) {
147151 // Already waited for this picture.
148152 return 0;
149153 }
150154
151155 av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
152− "(input surface %#x).\n", pic->display_order,
153− pic->encode_order, pic->input_surface);
156+ "(input surface %#x).\n", base_pic->display_order,
157+ base_pic->encode_order, pic->input_surface);
154158
155159 #if VA_CHECK_VERSION(1, 9, 0)
156− if (ctx->has_sync_buffer_func) {
160+ if (base_ctx->async_encode) {
157161 vas = vaSyncBuffer(ctx->hwctx->display,
158162 pic->output_buffer,
159163 VA_TIMEOUT_INFINITE);
@@ -174,9 +178,9 @@ static int vaapi_encode_wait(AVCodecContext *avctx, · 14 unmodified lines
174178 }
175179
176180 // Input is definitely finished with now.
177− av_frame_free(&pic->input_image);
181+ av_frame_free(&base_pic->input_image);
178182
179− pic->encode_complete = 1;
183+ base_pic->encode_complete = 1;
180184 return 0;
181185 }
182186
@@ -263,9 +267,11 @@ static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, · 80 unmodified lines
263267 }
264268
265269 static int vaapi_encode_issue(AVCodecContext *avctx,
266− VAAPIEncodePicture *pic)
270+ const FFHWBaseEncodePicture *base_pic)
267271 {
268− VAAPIEncodeContext *ctx = avctx->priv_data;
272+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
273+ VAAPIEncodeContext *ctx = avctx->priv_data;
274+ VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
269275 VAAPIEncodeSlice *slice;
270276 VAStatus vas;
271277 int err, i;
@@ -274,52 +280,46 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 2 unmodified lines
274280 av_unused AVFrameSideData *sd;
275281
276282 av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
277− "as type %s.\n", pic->display_order, pic->encode_order,
278− ff_hw_base_encode_get_pictype_name(pic->type));
279− if (pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0) {
283+ "as type %s.\n", base_pic->display_order, base_pic->encode_order,
284+ ff_hw_base_encode_get_pictype_name(base_pic->type));
285+ if (base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0) {
280286 av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
281287 } else {
282288 av_log(avctx, AV_LOG_DEBUG, "L0 refers to");
283− for (i = 0; i < pic->nb_refs[0]; i++) {
289+ for (i = 0; i < base_pic->nb_refs[0]; i++) {
284290 av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
285− pic->refs[0][i]->display_order, pic->refs[0][i]->encode_order);
291+ base_pic->refs[0][i]->display_order, base_pic->refs[0][i]->encode_order);
286292 }
287293 av_log(avctx, AV_LOG_DEBUG, ".\n");
288294
289− if (pic->nb_refs[1]) {
295+ if (base_pic->nb_refs[1]) {
290296 av_log(avctx, AV_LOG_DEBUG, "L1 refers to");
291− for (i = 0; i < pic->nb_refs[1]; i++) {
297+ for (i = 0; i < base_pic->nb_refs[1]; i++) {
292298 av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
293− pic->refs[1][i]->display_order, pic->refs[1][i]->encode_order);
299+ base_pic->refs[1][i]->display_order, base_pic->refs[1][i]->encode_order);
294300 }
295301 av_log(avctx, AV_LOG_DEBUG, ".\n");
296302 }
297303 }
298304
299− av_assert0(!pic->encode_issued);
300− for (i = 0; i < pic->nb_refs[0]; i++) {
301− av_assert0(pic->refs[0][i]);
302− av_assert0(pic->refs[0][i]->encode_issued);
305+ av_assert0(!base_pic->encode_issued);
306+ for (i = 0; i < base_pic->nb_refs[0]; i++) {
307+ av_assert0(base_pic->refs[0][i]);
308+ av_assert0(base_pic->refs[0][i]->encode_issued);
303309 }
304− for (i = 0; i < pic->nb_refs[1]; i++) {
305− av_assert0(pic->refs[1][i]);
306− av_assert0(pic->refs[1][i]->encode_issued);
310+ for (i = 0; i < base_pic->nb_refs[1]; i++) {
311+ av_assert0(base_pic->refs[1][i]);
312+ av_assert0(base_pic->refs[1][i]->encode_issued);
307313 }
308314
309315 av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
310316
311− pic->recon_image = av_frame_alloc();
312− if (!pic->recon_image) {
313− err = AVERROR(ENOMEM);
314− goto fail;
315− }
316−
317− err = av_hwframe_get_buffer(ctx->recon_frames_ref, pic->recon_image, 0);
317+ err = av_hwframe_get_buffer(ctx->recon_frames_ref, base_pic->recon_image, 0);
318318 if (err < 0) {
319319 err = AVERROR(ENOMEM);
320320 goto fail;
321321 }
322− pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
322+ pic->recon_surface = (VASurfaceID)(uintptr_t)base_pic->recon_image->data[3];
323323 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
324324
325325 pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool);
@@ -343,7 +343,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 17 unmodified lines
343343
344344 pic->nb_param_buffers = 0;
345345
346− if (pic->type == FF_HW_PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
346+ if (base_pic->type == FF_HW_PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
347347 err = vaapi_encode_make_param_buffer(avctx, pic,
348348 VAEncSequenceParameterBufferType,
349349 ctx->codec_sequence_params,
@@ -352,7 +352,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 2 unmodified lines
352352 goto fail;
353353 }
354354
355− if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
355+ if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
356356 for (i = 0; i < ctx->nb_global_params; i++) {
357357 err = vaapi_encode_make_misc_param_buffer(avctx, pic,
358358 ctx->global_params_type[i],
@@ -389,7 +389,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 30 unmodified lines
389389 }
390390 #endif
391391
392− if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
392+ if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
393393 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
394394 ctx->codec->write_sequence_header) {
395395 bit_len = 8 * sizeof(data);
@@ -529,9 +529,9 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 133 unmodified lines
529529 }
530530
531531 #if VA_CHECK_VERSION(1, 0, 0)
532− sd = av_frame_get_side_data(pic->input_image,
532+ sd = av_frame_get_side_data(base_pic->input_image,
533533 AV_FRAME_DATA_REGIONS_OF_INTEREST);
534− if (sd && ctx->roi_allowed) {
534+ if (sd && base_ctx->roi_allowed) {
535535 const AVRegionOfInterest *roi;
536536 uint32_t roi_size;
537537 VAEncMiscParameterBufferROI param_roi;
@@ -542,11 +542,11 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 4 unmodified lines
542542 av_assert0(roi_size && sd->size % roi_size == 0);
543543 nb_roi = sd->size / roi_size;
544544 if (nb_roi > ctx->roi_max_regions) {
545− if (!ctx->roi_warned) {
545+ if (!base_ctx->roi_warned) {
546546 av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
547547 "supported by driver (%d > %d).\n",
548548 nb_roi, ctx->roi_max_regions);
549− ctx->roi_warned = 1;
549+ base_ctx->roi_warned = 1;
550550 }
551551 nb_roi = ctx->roi_max_regions;
552552 }
@@ -639,8 +639,6 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 86 unmodified lines
639639 }
640640 }
641641
642− pic->encode_issued = 1;
643−
644642 return 0;
645643
646644 fail_with_picture:
@@ -657,14 +655,13 @@ fail_at_end: · 10 unmodified lines
657655 av_freep(&pic->param_buffers);
658656 av_freep(&pic->slices);
659657 av_freep(&pic->roi);
660− av_frame_free(&pic->recon_image);
661658 ff_refstruct_unref(&pic->output_buffer_ref);
662659 pic->output_buffer = VA_INVALID_ID;
663660 return err;
664661 }
665662
666663 static int vaapi_encode_set_output_property(AVCodecContext *avctx,
667− VAAPIEncodePicture *pic,
664+ FFHWBaseEncodePicture *pic,
668665 AVPacket *pkt)
669666 {
670667 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
@@ -689,16 +686,16 @@ static int vaapi_encode_set_output_property(AVCodecContext *avctx, · 18 unmodified lines
689686 return 0;
690687 }
691688
692− if (ctx->output_delay == 0) {
689+ if (base_ctx->output_delay == 0) {
693690 pkt->dts = pkt->pts;
694− } else if (pic->encode_order < ctx->decode_delay) {
695− if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
691+ } else if (pic->encode_order < base_ctx->decode_delay) {
692+ if (base_ctx->ts_ring[pic->encode_order] < INT64_MIN + base_ctx->dts_pts_diff)
696693 pkt->dts = INT64_MIN;
697694 else
698− pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
695+ pkt->dts = base_ctx->ts_ring[pic->encode_order] - base_ctx->dts_pts_diff;
699696 } else {
700− pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
701− (3 * ctx->output_delay + base_ctx->async_depth)];
697+ pkt->dts = base_ctx->ts_ring[(pic->encode_order - base_ctx->decode_delay) %
698+ (3 * base_ctx->output_delay + base_ctx->async_depth)];
702699 }
703700
704701 return 0;
@@ -817,9 +814,11 @@ end: · 112 unmodified lines
817814 }
818815
819816 static int vaapi_encode_output(AVCodecContext *avctx,
820− VAAPIEncodePicture *pic, AVPacket *pkt)
817+ const FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
821818 {
822− VAAPIEncodeContext *ctx = avctx->priv_data;
819+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
820+ VAAPIEncodeContext *ctx = avctx->priv_data;
821+ VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
823822 AVPacket *pkt_ptr = pkt;
824823 int err;
825824
@@ -832,17 +831,17 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 6 unmodified lines
832831 ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref);
833832
834833 if (pic->tail_size) {
835− if (ctx->tail_pkt->size) {
834+ if (base_ctx->tail_pkt->size) {
836835 err = AVERROR_BUG;
837836 goto end;
838837 }
839838
840− err = ff_get_encode_buffer(avctx, ctx->tail_pkt, pic->tail_size, 0);
839+ err = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, pic->tail_size, 0);
841840 if (err < 0)
842841 goto end;
843842
844− memcpy(ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
845− pkt_ptr = ctx->tail_pkt;
843+ memcpy(base_ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
844+ pkt_ptr = base_ctx->tail_pkt;
846845 }
847846 } else {
848847 err = vaapi_encode_get_coded_data(avctx, pic, pkt);
@@ -851,9 +850,9 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 2 unmodified lines
851850 }
852851
853852 av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
854− pic->display_order, pic->encode_order);
853+ base_pic->display_order, base_pic->encode_order);
855854
856− vaapi_encode_set_output_property(avctx, pic, pkt_ptr);
855+ vaapi_encode_set_output_property(avctx, (FFHWBaseEncodePicture*)pic, pkt_ptr);
857856
858857 end:
859858 ff_refstruct_unref(&pic->output_buffer_ref);
@@ -864,12 +863,14 @@ end: · 4 unmodified lines
864863 static int vaapi_encode_discard(AVCodecContext *avctx,
865864 VAAPIEncodePicture *pic)
866865 {
866+ FFHWBaseEncodePicture *base_pic = &pic->base;
867+
867868 vaapi_encode_wait(avctx, pic);
868869
869870 if (pic->output_buffer_ref) {
870871 av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
871872 "%"PRId64"/%"PRId64".\n",
872− pic->display_order, pic->encode_order);
873+ base_pic->display_order, base_pic->encode_order);
873874
874875 ff_refstruct_unref(&pic->output_buffer_ref);
875876 pic->output_buffer = VA_INVALID_ID;
@@ -878,8 +879,8 @@ static int vaapi_encode_discard(AVCodecContext *avctx, · 2 unmodified lines
878879 return 0;
879880 }
880881
881−static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx,
882− const AVFrame *frame)
882+static FFHWBaseEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx,
883+ const AVFrame *frame)
883884 {
884885 VAAPIEncodeContext *ctx = avctx->priv_data;
885886 VAAPIEncodePicture *pic;
@@ -889,8 +890,8 @@ static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, · 3 unmodified lines
889890 return NULL;
890891
891892 if (ctx->codec->picture_priv_data_size > 0) {
892− pic->priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
893− if (!pic->priv_data) {
893+ pic->base.priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
894+ if (!pic->base.priv_data) {
894895 av_freep(&pic);
895896 return NULL;
896897 }
@@ -900,15 +901,16 @@ static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, · 3 unmodified lines
900901 pic->recon_surface = VA_INVALID_ID;
901902 pic->output_buffer = VA_INVALID_ID;
902903
903− return pic;
904+ return &pic->base;
904905 }
905906
906907 static int vaapi_encode_free(AVCodecContext *avctx,
907− VAAPIEncodePicture *pic)
908+ FFHWBaseEncodePicture *base_pic)
908909 {
910+ VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
909911 int i;
910912
911− if (pic->encode_issued)
913+ if (base_pic->encode_issued)
912914 vaapi_encode_discard(avctx, pic);
913915
914916 if (pic->slices) {
@@ -916,17 +918,17 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 1 unmodified line
916918 av_freep(&pic->slices[i].codec_slice_params);
917919 }
918920
919− av_frame_free(&pic->input_image);
920− av_frame_free(&pic->recon_image);
921+ av_frame_free(&base_pic->input_image);
922+ av_frame_free(&base_pic->recon_image);
921923
922− av_buffer_unref(&pic->opaque_ref);
924+ av_buffer_unref(&base_pic->opaque_ref);
923925
924926 av_freep(&pic->param_buffers);
925927 av_freep(&pic->slices);
926928 // Output buffer should already be destroyed.
927929 av_assert0(pic->output_buffer == VA_INVALID_ID);
928930
929− av_freep(&pic->priv_data);
931+ av_freep(&base_pic->priv_data);
930932 av_freep(&pic->codec_picture_params);
931933 av_freep(&pic->roi);
932934
@@ -935,564 +937,6 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 2 unmodified lines
935937 return 0;
936938 }
937939
938−static void vaapi_encode_add_ref(AVCodecContext *avctx,
939− VAAPIEncodePicture *pic,
940− VAAPIEncodePicture *target,
941− int is_ref, int in_dpb, int prev)
942−{
943− int refs = 0;
944−
945− if (is_ref) {
946− av_assert0(pic != target);
947− av_assert0(pic->nb_refs[0] < MAX_PICTURE_REFERENCES &&
948− pic->nb_refs[1] < MAX_PICTURE_REFERENCES);
949− if (target->display_order < pic->display_order)
950− pic->refs[0][pic->nb_refs[0]++] = target;
951− else
952− pic->refs[1][pic->nb_refs[1]++] = target;
953− ++refs;
954− }
955−
956− if (in_dpb) {
957− av_assert0(pic->nb_dpb_pics < MAX_DPB_SIZE);
958− pic->dpb[pic->nb_dpb_pics++] = target;
959− ++refs;
960− }
961−
962− if (prev) {
963− av_assert0(!pic->prev);
964− pic->prev = target;
965− ++refs;
966− }
967−
968− target->ref_count[0] += refs;
969− target->ref_count[1] += refs;
970−}
971−
972−static void vaapi_encode_remove_refs(AVCodecContext *avctx,
973− VAAPIEncodePicture *pic,
974− int level)
975−{
976− int i;
977−
978− if (pic->ref_removed[level])
979− return;
980−
981− for (i = 0; i < pic->nb_refs[0]; i++) {
982− av_assert0(pic->refs[0][i]);
983− --pic->refs[0][i]->ref_count[level];
984− av_assert0(pic->refs[0][i]->ref_count[level] >= 0);
985− }
986−
987− for (i = 0; i < pic->nb_refs[1]; i++) {
988− av_assert0(pic->refs[1][i]);
989− --pic->refs[1][i]->ref_count[level];
990− av_assert0(pic->refs[1][i]->ref_count[level] >= 0);
991− }
992−
993− for (i = 0; i < pic->nb_dpb_pics; i++) {
994− av_assert0(pic->dpb[i]);
995− --pic->dpb[i]->ref_count[level];
996− av_assert0(pic->dpb[i]->ref_count[level] >= 0);
997− }
998−
999− av_assert0(pic->prev || pic->type == FF_HW_PICTURE_TYPE_IDR);
1000− if (pic->prev) {
1001− --pic->prev->ref_count[level];
1002− av_assert0(pic->prev->ref_count[level] >= 0);
1003− }
1004−
1005− pic->ref_removed[level] = 1;
1006−}
1007−
1008−static void vaapi_encode_set_b_pictures(AVCodecContext *avctx,
1009− VAAPIEncodePicture *start,
1010− VAAPIEncodePicture *end,
1011− VAAPIEncodePicture *prev,
1012− int current_depth,
1013− VAAPIEncodePicture **last)
1014−{
1015− VAAPIEncodeContext *ctx = avctx->priv_data;
1016− VAAPIEncodePicture *pic, *next, *ref;
1017− int i, len;
1018−
1019− av_assert0(start && end && start != end && start->next != end);
1020−
1021− // If we are at the maximum depth then encode all pictures as
1022− // non-referenced B-pictures. Also do this if there is exactly one
1023− // picture left, since there will be nothing to reference it.
1024− if (current_depth == ctx->max_b_depth || start->next->next == end) {
1025− for (pic = start->next; pic; pic = pic->next) {
1026− if (pic == end)
1027− break;
1028− pic->type = FF_HW_PICTURE_TYPE_B;
1029− pic->b_depth = current_depth;
1030−
1031− vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
1032− vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
1033− vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
1034−
1035− for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
1036− vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
1037− }
1038− *last = prev;
1039−
1040− } else {
1041− // Split the current list at the midpoint with a referenced
1042− // B-picture, then descend into each side separately.
1043− len = 0;
1044− for (pic = start->next; pic != end; pic = pic->next)
1045− ++len;
1046− for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
1047−
1048− pic->type = FF_HW_PICTURE_TYPE_B;
1049− pic->b_depth = current_depth;
1050−
1051− pic->is_reference = 1;
1052−
1053− vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
1054− vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
1055− vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
1056− vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
1057−
1058− for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0])
1059− vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
1060−
1061− if (i > 1)
1062− vaapi_encode_set_b_pictures(avctx, start, pic, pic,
1063− current_depth + 1, &next);
1064− else
1065− next = pic;
1066−
1067− vaapi_encode_set_b_pictures(avctx, pic, end, next,
1068− current_depth + 1, last);
1069− }
1070−}
1071−
1072−static void vaapi_encode_add_next_prev(AVCodecContext *avctx,
1073− VAAPIEncodePicture *pic)
1074−{
1075− VAAPIEncodeContext *ctx = avctx->priv_data;
1076− int i;
1077−
1078− if (!pic)
1079− return;
1080−
1081− if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
1082− for (i = 0; i < ctx->nb_next_prev; i++) {
1083− --ctx->next_prev[i]->ref_count[0];
1084− ctx->next_prev[i] = NULL;
1085− }
1086− ctx->next_prev[0] = pic;
1087− ++pic->ref_count[0];
1088− ctx->nb_next_prev = 1;
1089−
1090− return;
1091− }
1092−
1093− if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) {
1094− ctx->next_prev[ctx->nb_next_prev++] = pic;
1095− ++pic->ref_count[0];
1096− } else {
1097− --ctx->next_prev[0]->ref_count[0];
1098− for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++)
1099− ctx->next_prev[i] = ctx->next_prev[i + 1];
1100− ctx->next_prev[i] = pic;
1101− ++pic->ref_count[0];
1102− }
1103−}
1104−
1105−static int vaapi_encode_pick_next(AVCodecContext *avctx,
1106− VAAPIEncodePicture **pic_out)
1107−{
1108− VAAPIEncodeContext *ctx = avctx->priv_data;
1109− VAAPIEncodePicture *pic = NULL, *prev = NULL, *next, *start;
1110− int i, b_counter, closed_gop_end;
1111−
1112− // If there are any B-frames already queued, the next one to encode
1113− // is the earliest not-yet-issued frame for which all references are
1114− // available.
1115− for (pic = ctx->pic_start; pic; pic = pic->next) {
1116− if (pic->encode_issued)
1117− continue;
1118− if (pic->type != FF_HW_PICTURE_TYPE_B)
1119− continue;
1120− for (i = 0; i < pic->nb_refs[0]; i++) {
1121− if (!pic->refs[0][i]->encode_issued)
1122− break;
1123− }
1124− if (i != pic->nb_refs[0])
1125− continue;
1126−
1127− for (i = 0; i < pic->nb_refs[1]; i++) {
1128− if (!pic->refs[1][i]->encode_issued)
1129− break;
1130− }
1131− if (i == pic->nb_refs[1])
1132− break;
1133− }
1134−
1135− if (pic) {
1136− av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
1137− "encode next.\n", pic->b_depth);
1138− *pic_out = pic;
1139− return 0;
1140− }
1141−
1142− // Find the B-per-Pth available picture to become the next picture
1143− // on the top layer.
1144− start = NULL;
1145− b_counter = 0;
1146− closed_gop_end = ctx->closed_gop ||
1147− ctx->idr_counter == ctx->gop_per_idr;
1148− for (pic = ctx->pic_start; pic; pic = next) {
1149− next = pic->next;
1150− if (pic->encode_issued) {
1151− start = pic;
1152− continue;
1153− }
1154− // If the next available picture is force-IDR, encode it to start
1155− // a new GOP immediately.
1156− if (pic->force_idr)
1157− break;
1158− if (b_counter == ctx->b_per_p)
1159− break;
1160− // If this picture ends a closed GOP or starts a new GOP then it
1161− // needs to be in the top layer.
1162− if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
1163− break;
1164− // If the picture after this one is force-IDR, we need to encode
1165− // this one in the top layer.
1166− if (next && next->force_idr)
1167− break;
1168− ++b_counter;
1169− }
1170−
1171− // At the end of the stream the last picture must be in the top layer.
1172− if (!pic && ctx->end_of_stream) {
1173− --b_counter;
1174− pic = ctx->pic_end;
1175− if (pic->encode_complete)
1176− return AVERROR_EOF;
1177− else if (pic->encode_issued)
1178− return AVERROR(EAGAIN);
1179− }
1180−
1181− if (!pic) {
1182− av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
1183− "need more input for reference pictures.\n");
1184− return AVERROR(EAGAIN);
1185− }
1186− if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
1187− av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
1188− "need more input for timestamps.\n");
1189− return AVERROR(EAGAIN);
1190− }
1191−
1192− if (pic->force_idr) {
1193− av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
1194− "encode next.\n");
1195− pic->type = FF_HW_PICTURE_TYPE_IDR;
1196− ctx->idr_counter = 1;
1197− ctx->gop_counter = 1;
1198−
1199− } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
1200− if (ctx->idr_counter == ctx->gop_per_idr) {
1201− av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
1202− "encode next.\n");
1203− pic->type = FF_HW_PICTURE_TYPE_IDR;
1204− ctx->idr_counter = 1;
1205− } else {
1206− av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
1207− "encode next.\n");
1208− pic->type = FF_HW_PICTURE_TYPE_I;
1209− ++ctx->idr_counter;
1210− }
1211− ctx->gop_counter = 1;
1212−
1213− } else {
1214− if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
1215− av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
1216− "encode next.\n");
1217− } else {
1218− av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
1219− "encode next.\n");
1220− }
1221− pic->type = FF_HW_PICTURE_TYPE_P;
1222− av_assert0(start);
1223− ctx->gop_counter += 1 + b_counter;
1224− }
1225− pic->is_reference = 1;
1226− *pic_out = pic;
1227−
1228− vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
1229− if (pic->type != FF_HW_PICTURE_TYPE_IDR) {
1230− // TODO: apply both previous and forward multi reference for all vaapi encoders.
1231− // And L0/L1 reference frame number can be set dynamically through query
1232− // VAConfigAttribEncMaxRefFrames attribute.
1233− if (avctx->codec_id == AV_CODEC_ID_AV1) {
1234− for (i = 0; i < ctx->nb_next_prev; i++)
1235− vaapi_encode_add_ref(avctx, pic, ctx->next_prev[i],
1236− pic->type == FF_HW_PICTURE_TYPE_P,
1237− b_counter > 0, 0);
1238− } else
1239− vaapi_encode_add_ref(avctx, pic, start,
1240− pic->type == FF_HW_PICTURE_TYPE_P,
1241− b_counter > 0, 0);
1242−
1243− vaapi_encode_add_ref(avctx, pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1);
1244− }
1245−
1246− if (b_counter > 0) {
1247− vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1,
1248− &prev);
1249− } else {
1250− prev = pic;
1251− }
1252− vaapi_encode_add_next_prev(avctx, prev);
1253−
1254− return 0;
1255−}
1256−
1257−static int vaapi_encode_clear_old(AVCodecContext *avctx)
1258−{
1259− VAAPIEncodeContext *ctx = avctx->priv_data;
1260− VAAPIEncodePicture *pic, *prev, *next;
1261−
1262− av_assert0(ctx->pic_start);
1263−
1264− // Remove direct references once each picture is complete.
1265− for (pic = ctx->pic_start; pic; pic = pic->next) {
1266− if (pic->encode_complete && pic->next)
1267− vaapi_encode_remove_refs(avctx, pic, 0);
1268− }
1269−
1270− // Remove indirect references once a picture has no direct references.
1271− for (pic = ctx->pic_start; pic; pic = pic->next) {
1272− if (pic->encode_complete && pic->ref_count[0] == 0)
1273− vaapi_encode_remove_refs(avctx, pic, 1);
1274− }
1275−
1276− // Clear out all complete pictures with no remaining references.
1277− prev = NULL;
1278− for (pic = ctx->pic_start; pic; pic = next) {
1279− next = pic->next;
1280− if (pic->encode_complete && pic->ref_count[1] == 0) {
1281− av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
1282− if (prev)
1283− prev->next = next;
1284− else
1285− ctx->pic_start = next;
1286− vaapi_encode_free(avctx, pic);
1287− } else {
1288− prev = pic;
1289− }
1290− }
1291−
1292− return 0;
1293−}
1294−
1295−static int vaapi_encode_check_frame(AVCodecContext *avctx,
1296− const AVFrame *frame)
1297−{
1298− VAAPIEncodeContext *ctx = avctx->priv_data;
1299−
1300− if ((frame->crop_top || frame->crop_bottom ||
1301− frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
1302− av_log(avctx, AV_LOG_WARNING, "Cropping information on input "
1303− "frames ignored due to lack of API support.\n");
1304− ctx->crop_warned = 1;
1305− }
1306−
1307− if (!ctx->roi_allowed) {
1308− AVFrameSideData *sd =
1309− av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
1310−
1311− if (sd && !ctx->roi_warned) {
1312− av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
1313− "frames ignored due to lack of driver support.\n");
1314− ctx->roi_warned = 1;
1315− }
1316− }
1317−
1318− return 0;
1319−}
1320−
1321−static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
1322−{
1323− FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1324− VAAPIEncodeContext *ctx = avctx->priv_data;
1325− VAAPIEncodePicture *pic;
1326− int err;
1327−
1328− if (frame) {
1329− av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
1330− frame->width, frame->height, frame->pts);
1331−
1332− err = vaapi_encode_check_frame(avctx, frame);
1333− if (err < 0)
1334− return err;
1335−
1336− pic = vaapi_encode_alloc(avctx, frame);
1337− if (!pic)
1338− return AVERROR(ENOMEM);
1339−
1340− pic->input_image = av_frame_alloc();
1341− if (!pic->input_image) {
1342− err = AVERROR(ENOMEM);
1343− goto fail;
1344− }
1345−
1346− if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I)
1347− pic->force_idr = 1;
1348−
1349− pic->pts = frame->pts;
1350− pic->duration = frame->duration;
1351−
1352− if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
1353− err = av_buffer_replace(&pic->opaque_ref, frame->opaque_ref);
1354− if (err < 0)
1355− goto fail;
1356−
1357− pic->opaque = frame->opaque;
1358− }
1359−
1360− av_frame_move_ref(pic->input_image, frame);
1361−
1362− if (ctx->input_order == 0)
1363− ctx->first_pts = pic->pts;
1364− if (ctx->input_order == ctx->decode_delay)
1365− ctx->dts_pts_diff = pic->pts - ctx->first_pts;
1366− if (ctx->output_delay > 0)
1367− ctx->ts_ring[ctx->input_order %
1368− (3 * ctx->output_delay + base_ctx->async_depth)] = pic->pts;
1369−
1370− pic->display_order = ctx->input_order;
1371− ++ctx->input_order;
1372−
1373− if (ctx->pic_start) {
1374− ctx->pic_end->next = pic;
1375− ctx->pic_end = pic;
1376− } else {
1377− ctx->pic_start = pic;
1378− ctx->pic_end = pic;
1379− }
1380−
1381− } else {
1382− ctx->end_of_stream = 1;
1383−
1384− // Fix timestamps if we hit end-of-stream before the initial decode
1385− // delay has elapsed.
1386− if (ctx->input_order < ctx->decode_delay)
1387− ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
1388− }
1389−
1390− return 0;
1391−
1392−fail:
1393− vaapi_encode_free(avctx, pic);
1394− return err;
1395−}
1396−
1397−int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
1398−{
1399− VAAPIEncodeContext *ctx = avctx->priv_data;
1400− VAAPIEncodePicture *pic = NULL;
1401− AVFrame *frame = ctx->frame;
1402− int err;
1403−
1404−start:
1405− /** if no B frame before repeat P frame, sent repeat P frame out. */
1406− if (ctx->tail_pkt->size) {
1407− for (VAAPIEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) {
1408− if (tmp->type == FF_HW_PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts)
1409− break;
1410− else if (!tmp->next) {
1411− av_packet_move_ref(pkt, ctx->tail_pkt);
1412− goto end;
1413− }
1414− }
1415− }
1416−
1417− err = ff_encode_get_frame(avctx, frame);
1418− if (err < 0 && err != AVERROR_EOF)
1419− return err;
1420−
1421− if (err == AVERROR_EOF)
1422− frame = NULL;
1423−
1424− err = vaapi_encode_send_frame(avctx, frame);
1425− if (err < 0)
1426− return err;
1427−
1428− if (!ctx->pic_start) {
1429− if (ctx->end_of_stream)
1430− return AVERROR_EOF;
1431− else
1432− return AVERROR(EAGAIN);
1433− }
1434−
1435− if (ctx->has_sync_buffer_func) {
1436− if (av_fifo_can_write(ctx->encode_fifo)) {
1437− err = vaapi_encode_pick_next(avctx, &pic);
1438− if (!err) {
1439− av_assert0(pic);
1440− pic->encode_order = ctx->encode_order +
1441− av_fifo_can_read(ctx->encode_fifo);
1442− err = vaapi_encode_issue(avctx, pic);
1443− if (err < 0) {
1444− av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1445− return err;
1446− }
1447− av_fifo_write(ctx->encode_fifo, &pic, 1);
1448− }
1449− }
1450−
1451− if (!av_fifo_can_read(ctx->encode_fifo))
1452− return err;
1453−
1454− // More frames can be buffered
1455− if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream)
1456− return AVERROR(EAGAIN);
1457−
1458− av_fifo_read(ctx->encode_fifo, &pic, 1);
1459− ctx->encode_order = pic->encode_order + 1;
1460− } else {
1461− err = vaapi_encode_pick_next(avctx, &pic);
1462− if (err < 0)
1463− return err;
1464− av_assert0(pic);
1465−
1466− pic->encode_order = ctx->encode_order++;
1467−
1468− err = vaapi_encode_issue(avctx, pic);
1469− if (err < 0) {
1470− av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1471− return err;
1472− }
1473− }
1474−
1475− err = vaapi_encode_output(avctx, pic, pkt);
1476− if (err < 0) {
1477− av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
1478− return err;
1479− }
1480−
1481− ctx->output_order = pic->encode_order;
1482− vaapi_encode_clear_old(avctx);
1483−
1484− /** loop to get an available pkt in encoder flushing. */
1485− if (ctx->end_of_stream && !pkt->size)
1486− goto start;
1487−
1488−end:
1489− if (pkt->size)
1490− av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", "
1491− "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size);
1492−
1493− return 0;
1494−}
1495−
1496940 static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type,
1497941 void *buffer, size_t size)
1498942 {
@@ -2188,7 +1632,8 @@ static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx) · 689 unmodified lines
21881632
21891633 static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
21901634 {
2191− VAAPIEncodeContext *ctx = avctx->priv_data;
1635+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1636+ VAAPIEncodeContext *ctx = avctx->priv_data;
21921637 VAStatus vas;
21931638 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
21941639 uint32_t ref_l0, ref_l1;
@@ -2211,7 +1656,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 16 unmodified lines
22111656 ref_l1 = attr.value >> 16 & 0xffff;
22121657 }
22131658
2214− ctx->p_to_gpb = 0;
1659+ base_ctx->p_to_gpb = 0;
22151660 prediction_pre_only = 0;
22161661
22171662 #if VA_CHECK_VERSION(1, 9, 0)
@@ -2247,7 +1692,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 29 unmodified lines
22471692
22481693 if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
22491694 if (ref_l0 > 0 && ref_l1 > 0) {
2250− ctx->p_to_gpb = 1;
1695+ base_ctx->p_to_gpb = 1;
22511696 av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
22521697 "replacing them with B-frames.\n");
22531698 }
@@ -2259,7 +1704,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 5 unmodified lines
22591704 if (ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||
22601705 avctx->gop_size <= 1) {
22611706 av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
2262− ctx->gop_size = 1;
1707+ base_ctx->gop_size = 1;
22631708 } else if (ref_l0 < 1) {
22641709 av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
22651710 "reference frames.\n");
@@ -2267,41 +1712,41 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 1 unmodified line
22671712 } else if (!(ctx->codec->flags & FF_HW_FLAG_B_PICTURES) ||
22681713 ref_l1 < 1 || avctx->max_b_frames < 1 ||
22691714 prediction_pre_only) {
2270− if (ctx->p_to_gpb)
1715+ if (base_ctx->p_to_gpb)
22711716 av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
22721717 "(supported references: %d / %d).\n",
22731718 ref_l0, ref_l1);
22741719 else
22751720 av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
22761721 "(supported references: %d / %d).\n", ref_l0, ref_l1);
2277− ctx->gop_size = avctx->gop_size;
2278− ctx->p_per_i = INT_MAX;
2279− ctx->b_per_p = 0;
1722+ base_ctx->gop_size = avctx->gop_size;
1723+ base_ctx->p_per_i = INT_MAX;
1724+ base_ctx->b_per_p = 0;
22801725 } else {
2281− if (ctx->p_to_gpb)
1726+ if (base_ctx->p_to_gpb)
22821727 av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
22831728 "(supported references: %d / %d).\n",
22841729 ref_l0, ref_l1);
22851730 else
22861731 av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
22871732 "(supported references: %d / %d).\n", ref_l0, ref_l1);
2288− ctx->gop_size = avctx->gop_size;
2289− ctx->p_per_i = INT_MAX;
2290− ctx->b_per_p = avctx->max_b_frames;
1733+ base_ctx->gop_size = avctx->gop_size;
1734+ base_ctx->p_per_i = INT_MAX;
1735+ base_ctx->b_per_p = avctx->max_b_frames;
22911736 if (ctx->codec->flags & FF_HW_FLAG_B_PICTURE_REFERENCES) {
2292− ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
2293− av_log2(ctx->b_per_p) + 1);
1737+ base_ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
1738+ av_log2(base_ctx->b_per_p) + 1);
22941739 } else {
2295− ctx->max_b_depth = 1;
1740+ base_ctx->max_b_depth = 1;
22961741 }
22971742 }
22981743
22991744 if (ctx->codec->flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) {
2300− ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
2301− ctx->gop_per_idr = ctx->idr_interval + 1;
1745+ base_ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
1746+ base_ctx->gop_per_idr = ctx->idr_interval + 1;
23021747 } else {
2303− ctx->closed_gop = 1;
2304− ctx->gop_per_idr = 1;
1748+ base_ctx->closed_gop = 1;
1749+ base_ctx->gop_per_idr = 1;
23051750 }
23061751
23071752 return 0;
@@ -2614,7 +2059,8 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) · 306 unmodified lines
26142059 static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
26152060 {
26162061 #if VA_CHECK_VERSION(1, 0, 0)
2617− VAAPIEncodeContext *ctx = avctx->priv_data;
2062+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2063+ VAAPIEncodeContext *ctx = avctx->priv_data;
26182064 VAStatus vas;
26192065 VAConfigAttrib attr = { VAConfigAttribEncROI };
26202066
@@ -2629,14 +2075,14 @@ static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx) · 8 unmodified lines
26292075 }
26302076
26312077 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2632− ctx->roi_allowed = 0;
2078+ base_ctx->roi_allowed = 0;
26332079 } else {
26342080 VAConfigAttribValEncROI roi = {
26352081 .value = attr.value,
26362082 };
26372083
26382084 ctx->roi_max_regions = roi.bits.num_roi_regions;
2639− ctx->roi_allowed = ctx->roi_max_regions > 0 &&
2085+ base_ctx->roi_allowed = ctx->roi_max_regions > 0 &&
26402086 (ctx->va_rc_mode == VA_RC_CQP ||
26412087 roi.bits.roi_rc_qp_delta_support);
26422088 }
@@ -2771,6 +2217,16 @@ static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx) · 128 unmodified lines
27712217 return err;
27722218 }
27732219
2220+static const FFHWEncodePictureOperation vaapi_op = {
2221+ .alloc = &vaapi_encode_alloc,
2222+
2223+ .issue = &vaapi_encode_issue,
2224+
2225+ .output = &vaapi_encode_output,
2226+
2227+ .free = &vaapi_encode_free,
2228+};
2229+
27742230 av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
27752231 {
27762232 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
@@ -2782,10 +2238,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 5 unmodified lines
27822238 ctx->va_config = VA_INVALID_ID;
27832239 ctx->va_context = VA_INVALID_ID;
27842240
2241+ base_ctx->op = &vaapi_op;
2242+
27852243 /* If you add something that can fail above this av_frame_alloc(),
27862244 * modify ff_vaapi_encode_close() accordingly. */
2787− ctx->frame = av_frame_alloc();
2788− if (!ctx->frame) {
2245+ base_ctx->frame = av_frame_alloc();
2246+ if (!base_ctx->frame) {
27892247 return AVERROR(ENOMEM);
27902248 }
27912249
@@ -2810,8 +2268,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 18 unmodified lines
28102268 ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
28112269 ctx->hwctx = ctx->device->hwctx;
28122270
2813− ctx->tail_pkt = av_packet_alloc();
2814− if (!ctx->tail_pkt) {
2271+ base_ctx->tail_pkt = av_packet_alloc();
2272+ if (!base_ctx->tail_pkt) {
28152273 err = AVERROR(ENOMEM);
28162274 goto fail;
28172275 }
@@ -2910,8 +2368,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 92 unmodified lines
29102368 goto fail;
29112369 }
29122370
2913− ctx->output_delay = ctx->b_per_p;
2914− ctx->decode_delay = ctx->max_b_depth;
2371+ base_ctx->output_delay = base_ctx->b_per_p;
2372+ base_ctx->decode_delay = base_ctx->max_b_depth;
29152373
29162374 if (ctx->codec->sequence_params_size > 0) {
29172375 ctx->codec_sequence_params =
@@ -2966,11 +2424,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 48 unmodified lines
29662424 // check vaSyncBuffer function
29672425 vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
29682426 if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2969− ctx->has_sync_buffer_func = 1;
2970− ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
2971− sizeof(VAAPIEncodePicture *),
2972− 0);
2973− if (!ctx->encode_fifo)
2427+ base_ctx->async_encode = 1;
2428+ base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
2429+ sizeof(VAAPIEncodePicture*),
2430+ 0);
2431+ if (!base_ctx->encode_fifo)
29742432 return AVERROR(ENOMEM);
29752433 }
29762434 #endif
@@ -2983,15 +2441,16 @@ fail: · 6 unmodified lines
29832441
29842442 av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
29852443 {
2986− VAAPIEncodeContext *ctx = avctx->priv_data;
2987− VAAPIEncodePicture *pic, *next;
2444+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2445+ VAAPIEncodeContext *ctx = avctx->priv_data;
2446+ FFHWBaseEncodePicture *pic, *next;
29882447
29892448 /* We check ctx->frame to know whether ff_vaapi_encode_init()
29902449 * has been called and va_config/va_context initialized. */
2991− if (!ctx->frame)
2450+ if (!base_ctx->frame)
29922451 return 0;
29932452
2994− for (pic = ctx->pic_start; pic; pic = next) {
2453+ for (pic = base_ctx->pic_start; pic; pic = next) {
29952454 next = pic->next;
29962455 vaapi_encode_free(avctx, pic);
29972456 }
@@ -3008,12 +2467,12 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) · 10 unmodified lines
30082467 ctx->va_config = VA_INVALID_ID;
30092468 }
30102469
3011− av_frame_free(&ctx->frame);
3012− av_packet_free(&ctx->tail_pkt);
2470+ av_frame_free(&base_ctx->frame);
2471+ av_packet_free(&base_ctx->tail_pkt);
30132472
30142473 av_freep(&ctx->codec_sequence_params);
30152474 av_freep(&ctx->codec_picture_params);
3016− av_fifo_freep2(&ctx->encode_fifo);
2475+ av_fifo_freep2(&base_ctx->encode_fifo);
30172476
30182477 av_buffer_unref(&ctx->recon_frames_ref);
30192478 av_buffer_unref(&ctx->input_frames_ref);
libavcodec/vaapi_encode.h+1−101
@@ -29,7 +29,6 @@ · 28 unmodified lines
2929
3030 #include "libavutil/hwcontext.h"
3131 #include "libavutil/hwcontext_vaapi.h"
32−#include "libavutil/fifo.h"
3332
3433 #include "avcodec.h"
3534 #include "hwconfig.h"
@@ -64,16 +63,7 @@ typedef struct VAAPIEncodeSlice { · 28 unmodified lines
6463 } VAAPIEncodeSlice;
6564
6665 typedef struct VAAPIEncodePicture {
67− struct VAAPIEncodePicture *next;
68−
69− int64_t display_order;
70− int64_t encode_order;
71− int64_t pts;
72− int64_t duration;
73− int force_idr;
74−
75− void *opaque;
76− AVBufferRef *opaque_ref;
66+ FFHWBaseEncodePicture base;
7767
7868 #if VA_CHECK_VERSION(1, 0, 0)
7969 // ROI regions.
@@ -82,15 +72,7 @@ typedef struct VAAPIEncodePicture { · 2 unmodified lines
8272 void *roi;
8373 #endif
8474
85− int type;
86− int b_depth;
87− int encode_issued;
88− int encode_complete;
89−
90− AVFrame *input_image;
9175 VASurfaceID input_surface;
92−
93− AVFrame *recon_image;
9476 VASurfaceID recon_surface;
9577
9678 int nb_param_buffers;
@@ -100,31 +82,8 @@ typedef struct VAAPIEncodePicture { · 3 unmodified lines
10082 VABufferID *output_buffer_ref;
10183 VABufferID output_buffer;
10284
103− void *priv_data;
10485 void *codec_picture_params;
10586
106− // Whether this picture is a reference picture.
107− int is_reference;
108−
109− // The contents of the DPB after this picture has been decoded.
110− // This will contain the picture itself if it is a reference picture,
111− // but not if it isn't.
112− int nb_dpb_pics;
113− struct VAAPIEncodePicture *dpb[MAX_DPB_SIZE];
114− // The reference pictures used in decoding this picture. If they are
115− // used by later pictures they will also appear in the DPB. ref[0][] for
116− // previous reference frames. ref[1][] for future reference frames.
117− int nb_refs[MAX_REFERENCE_LIST_NUM];
118− struct VAAPIEncodePicture *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES];
119− // The previous reference picture in encode order. Must be in at least
120− // one of the reference list and DPB list.
121− struct VAAPIEncodePicture *prev;
122− // Reference count for other pictures referring to this one through
123− // the above pointers, directly from incomplete pictures and indirectly
124− // through completed pictures.
125− int ref_count[2];
126− int ref_removed[2];
127−
12887 int nb_slices;
12988 VAAPIEncodeSlice *slices;
13089
@@ -298,30 +257,6 @@ typedef struct VAAPIEncodeContext { · 167 unmodified lines
298257 // structure (VAEncPictureParameterBuffer*).
299258 void *codec_picture_params;
300259
301− // Current encoding window, in display (input) order.
302− VAAPIEncodePicture *pic_start, *pic_end;
303− // The next picture to use as the previous reference picture in
304− // encoding order. Order from small to large in encoding order.
305− VAAPIEncodePicture *next_prev[MAX_PICTURE_REFERENCES];
306− int nb_next_prev;
307−
308− // Next input order index (display order).
309− int64_t input_order;
310− // Number of frames that output is behind input.
311− int64_t output_delay;
312− // Next encode order index.
313− int64_t encode_order;
314− // Number of frames decode output will need to be delayed.
315− int64_t decode_delay;
316− // Next output order index (in encode order).
317− int64_t output_order;
318−
319− // Timestamp handling.
320− int64_t first_pts;
321− int64_t dts_pts_diff;
322− int64_t ts_ring[MAX_REORDER_DELAY * 3 +
323− MAX_ASYNC_DEPTH];
324−
325260 // Slice structure.
326261 int slice_block_rows;
327262 int slice_block_cols;
@@ -340,41 +275,12 @@ typedef struct VAAPIEncodeContext { · 12 unmodified lines
340275 // Location of the i-th tile row boundary.
341276 int row_bd[MAX_TILE_ROWS + 1];
342277
343− // Frame type decision.
344− int gop_size;
345− int closed_gop;
346− int gop_per_idr;
347− int p_per_i;
348− int max_b_depth;
349− int b_per_p;
350− int force_idr;
351− int idr_counter;
352− int gop_counter;
353− int end_of_stream;
354− int p_to_gpb;
355−
356− // Whether the driver supports ROI at all.
357− int roi_allowed;
358278 // Maximum number of regions supported by the driver.
359279 int roi_max_regions;
360280 // Quantisation range for offset calculations. Set by codec-specific
361281 // code, as it may change based on parameters.
362282 int roi_quant_range;
363283
364− // The encoder does not support cropping information, so warn about
365− // it the first time we encounter any nonzero crop fields.
366− int crop_warned;
367− // If the driver does not support ROI then warn the first time we
368− // encounter a frame with ROI side data.
369− int roi_warned;
370−
371− AVFrame *frame;
372−
373− // Whether the driver support vaSyncBuffer
374− int has_sync_buffer_func;
375− // Store buffered pic
376− AVFifo *encode_fifo;
377−
378284 /** Head data for current output pkt, used only for AV1. */
379285 //void *header_data;
380286 //size_t header_data_size;
@@ -384,9 +290,6 @@ typedef struct VAAPIEncodeContext { · 3 unmodified lines
384290 * This is a RefStruct reference.
385291 */
386292 VABufferID *coded_buffer_ref;
387−
388− /** Tail data of a pic, now only used for av1 repeat frame header. */
389− AVPacket *tail_pkt;
390293 } VAAPIEncodeContext;
391294
392295 typedef struct VAAPIEncodeType {
@@ -468,9 +371,6 @@ typedef struct VAAPIEncodeType { · 75 unmodified lines
468371 char *data, size_t *data_len);
469372 } VAAPIEncodeType;
470373
471−
472−int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
473−
474374 int ff_vaapi_encode_init(AVCodecContext *avctx);
475375 int ff_vaapi_encode_close(AVCodecContext *avctx);
476376
libavcodec/vaapi_encode_av1.c+19−16
@@ -360,6 +360,7 @@ static int vaapi_encode_av1_write_sequence_header(AVCodecContext *avctx, · 359 unmodified lines
360360
361361 static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)
362362 {
363+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
363364 VAAPIEncodeContext *ctx = avctx->priv_data;
364365 VAAPIEncodeAV1Context *priv = avctx->priv_data;
365366 AV1RawOBU *sh_obu = &priv->sh;
@@ -441,8 +442,8 @@ static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines
441442 vseq->seq_level_idx = sh->seq_level_idx[0];
442443 vseq->seq_tier = sh->seq_tier[0];
443444 vseq->order_hint_bits_minus_1 = sh->order_hint_bits_minus_1;
444− vseq->intra_period = ctx->gop_size;
445− vseq->ip_period = ctx->b_per_p + 1;
445+ vseq->intra_period = base_ctx->gop_size;
446+ vseq->ip_period = base_ctx->b_per_p + 1;
446447
447448 vseq->seq_fields.bits.enable_order_hint = sh->enable_order_hint;
448449
@@ -465,16 +466,17 @@ end: · 16 unmodified lines
465466 }
466467
467468 static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
468− VAAPIEncodePicture *pic)
469+ VAAPIEncodePicture *vaapi_pic)
469470 {
470471 VAAPIEncodeContext *ctx = avctx->priv_data;
471472 VAAPIEncodeAV1Context *priv = avctx->priv_data;
473+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
472474 VAAPIEncodeAV1Picture *hpic = pic->priv_data;
473475 AV1RawOBU *fh_obu = &priv->fh;
474476 AV1RawFrameHeader *fh = &fh_obu->obu.frame.header;
475− VAEncPictureParameterBufferAV1 *vpic = pic->codec_picture_params;
477+ VAEncPictureParameterBufferAV1 *vpic = vaapi_pic->codec_picture_params;
476478 CodedBitstreamFragment *obu = &priv->current_obu;
477− VAAPIEncodePicture *ref;
479+ FFHWBaseEncodePicture *ref;
478480 VAAPIEncodeAV1Picture *href;
479481 int slot, i;
480482 int ret;
@@ -482,8 +484,8 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 1 unmodified line
482484 { 1, 0, 0, 0, -1, 0, -1, -1 };
483485
484486 memset(fh_obu, 0, sizeof(*fh_obu));
485− pic->nb_slices = priv->tile_groups;
486− pic->non_independent_frame = pic->encode_order < pic->display_order;
487+ vaapi_pic->nb_slices = priv->tile_groups;
488+ vaapi_pic->non_independent_frame = pic->encode_order < pic->display_order;
487489 fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER;
488490 fh_obu->header.obu_has_size_field = 1;
489491
@@ -601,8 +603,8 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 111 unmodified lines
601603 vpic->frame_width_minus_1 = fh->frame_width_minus_1;
602604 vpic->frame_height_minus_1 = fh->frame_height_minus_1;
603605 vpic->primary_ref_frame = fh->primary_ref_frame;
604− vpic->reconstructed_frame = pic->recon_surface;
605− vpic->coded_buf = pic->output_buffer;
606+ vpic->reconstructed_frame = vaapi_pic->recon_surface;
607+ vpic->coded_buf = vaapi_pic->output_buffer;
606608 vpic->tile_cols = fh->tile_cols;
607609 vpic->tile_rows = fh->tile_rows;
608610 vpic->order_hint = fh->order_hint;
@@ -630,12 +632,12 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 21 unmodified lines
630632
631633 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
632634 for (int j = 0; j < pic->nb_refs[i]; j++) {
633− VAAPIEncodePicture *ref_pic = pic->refs[i][j];
635+ FFHWBaseEncodePicture *ref_pic = pic->refs[i][j];
634636
635637 slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot;
636638 av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);
637639
638− vpic->reference_frames[slot] = ref_pic->recon_surface;
640+ vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)->recon_surface;
639641 }
640642 }
641643
@@ -752,7 +754,7 @@ static int vaapi_encode_av1_init_slice_params(AVCodecContext *avctx, · 110 unmodified lines
752754 }
753755
754756 static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx,
755− VAAPIEncodePicture *pic,
757+ VAAPIEncodePicture *vaapi_pic,
756758 char *data, size_t *data_len)
757759 {
758760 VAAPIEncodeAV1Context *priv = avctx->priv_data;
@@ -760,10 +762,11 @@ static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, · 1 unmodified line
760762 CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data;
761763 AV1RawOBU *fh_obu = &priv->fh;
762764 AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header;
765+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
763766 VAAPIEncodeAV1Picture *href;
764767 int ret = 0;
765768
766− pic->tail_size = 0;
769+ vaapi_pic->tail_size = 0;
767770 /** Pack repeat frame header. */
768771 if (pic->display_order > pic->encode_order) {
769772 memset(fh_obu, 0, sizeof(*fh_obu));
@@ -785,11 +788,11 @@ static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, · 15 unmodified lines
785788 if (ret < 0)
786789 goto end;
787790
788− ret = vaapi_encode_av1_write_obu(avctx, pic->tail_data, &pic->tail_size, obu);
791+ ret = vaapi_encode_av1_write_obu(avctx, vaapi_pic->tail_data, &vaapi_pic->tail_size, obu);
789792 if (ret < 0)
790793 goto end;
791794
792− pic->tail_size /= 8;
795+ vaapi_pic->tail_size /= 8;
793796 }
794797
795798 memcpy(data, &priv->fh_data, MAX_PARAM_BUFFER_SIZE * sizeof(char));
@@ -1038,7 +1041,7 @@ const FFCodec ff_av1_vaapi_encoder = { · 242 unmodified lines
10381041 .p.id = AV_CODEC_ID_AV1,
10391042 .priv_data_size = sizeof(VAAPIEncodeAV1Context),
10401043 .init = &vaapi_encode_av1_init,
1041− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
1044+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
10421045 .close = &vaapi_encode_av1_close,
10431046 .p.priv_class = &vaapi_encode_av1_class,
10441047 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
libavcodec/vaapi_encode_h264.c+44−40
@@ -233,7 +233,7 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, · 232 unmodified lines
233233 goto fail;
234234 }
235235 if (priv->sei_needed & SEI_TIMING) {
236− if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
236+ if (pic->base.type == FF_HW_PICTURE_TYPE_IDR) {
237237 err = ff_cbs_sei_add_message(priv->cbc, au, 1,
238238 SEI_TYPE_BUFFERING_PERIOD,
239239 &priv->sei_buffering_period, NULL);
@@ -295,6 +295,7 @@ fail: · 55 unmodified lines
295295
296296 static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
297297 {
298+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
298299 VAAPIEncodeContext *ctx = avctx->priv_data;
299300 VAAPIEncodeH264Context *priv = avctx->priv_data;
300301 H264RawSPS *sps = &priv->raw_sps;
@@ -326,18 +327,18 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 25 unmodified lines
326327 sps->constraint_set1_flag = 1;
327328
328329 if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10)
329− sps->constraint_set3_flag = ctx->gop_size == 1;
330+ sps->constraint_set3_flag = base_ctx->gop_size == 1;
330331
331332 if (avctx->profile == AV_PROFILE_H264_MAIN ||
332333 avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) {
333334 sps->constraint_set4_flag = 1;
334− sps->constraint_set5_flag = ctx->b_per_p == 0;
335+ sps->constraint_set5_flag = base_ctx->b_per_p == 0;
335336 }
336337
337− if (ctx->gop_size == 1)
338+ if (base_ctx->gop_size == 1)
338339 priv->dpb_frames = 0;
339340 else
340− priv->dpb_frames = 1 + ctx->max_b_depth;
341+ priv->dpb_frames = 1 + base_ctx->max_b_depth;
341342
342343 if (avctx->level != AV_LEVEL_UNKNOWN) {
343344 sps->level_idc = avctx->level;
@@ -374,7 +375,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 30 unmodified lines
374375 sps->bit_depth_chroma_minus8 = bit_depth - 8;
375376
376377 sps->log2_max_frame_num_minus4 = 4;
377− sps->pic_order_cnt_type = ctx->max_b_depth ? 0 : 2;
378+ sps->pic_order_cnt_type = base_ctx->max_b_depth ? 0 : 2;
378379 if (sps->pic_order_cnt_type == 0) {
379380 sps->log2_max_pic_order_cnt_lsb_minus4 = 4;
380381 }
@@ -501,8 +502,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 120 unmodified lines
501502 sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
502503 sps->vui.log2_max_mv_length_horizontal = 15;
503504 sps->vui.log2_max_mv_length_vertical = 15;
504− sps->vui.max_num_reorder_frames = ctx->max_b_depth;
505− sps->vui.max_dec_frame_buffering = ctx->max_b_depth + 1;
505+ sps->vui.max_num_reorder_frames = base_ctx->max_b_depth;
506+ sps->vui.max_dec_frame_buffering = base_ctx->max_b_depth + 1;
506507
507508 pps->nal_unit_header.nal_ref_idc = 3;
508509 pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;
@@ -535,9 +536,9 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 26 unmodified lines
535536 *vseq = (VAEncSequenceParameterBufferH264) {
536537 .seq_parameter_set_id = sps->seq_parameter_set_id,
537538 .level_idc = sps->level_idc,
538− .intra_period = ctx->gop_size,
539− .intra_idr_period = ctx->gop_size,
540− .ip_period = ctx->b_per_p + 1,
539+ .intra_period = base_ctx->gop_size,
540+ .intra_idr_period = base_ctx->gop_size,
541+ .ip_period = base_ctx->b_per_p + 1,
541542
542543 .bits_per_second = ctx->va_bit_rate,
543544 .max_num_ref_frames = sps->max_num_ref_frames,
@@ -619,14 +620,15 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines
619620 }
620621
621622 static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
622− VAAPIEncodePicture *pic)
623+ VAAPIEncodePicture *vaapi_pic)
623624 {
624− VAAPIEncodeContext *ctx = avctx->priv_data;
625+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
625626 VAAPIEncodeH264Context *priv = avctx->priv_data;
627+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
626628 VAAPIEncodeH264Picture *hpic = pic->priv_data;
627− VAAPIEncodePicture *prev = pic->prev;
629+ FFHWBaseEncodePicture *prev = pic->prev;
628630 VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL;
629− VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
631+ VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params;
630632 int i, j = 0;
631633
632634 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
@@ -662,7 +664,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 29 unmodified lines
662664 hpic->pic_order_cnt *= 2;
663665 }
664666
665− hpic->dpb_delay = pic->display_order - pic->encode_order + ctx->max_b_depth;
667+ hpic->dpb_delay = pic->display_order - pic->encode_order + base_ctx->max_b_depth;
666668 hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame;
667669
668670 if (priv->aud) {
@@ -699,7 +701,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 30 unmodified lines
699701 priv->sei_recovery_point = (H264RawSEIRecoveryPoint) {
700702 .recovery_frame_cnt = 0,
701703 .exact_match_flag = 1,
702− .broken_link_flag = ctx->b_per_p > 0,
704+ .broken_link_flag = base_ctx->b_per_p > 0,
703705 };
704706
705707 priv->sei_needed |= SEI_RECOVERY_POINT;
@@ -722,7 +724,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 16 unmodified lines
722724 }
723725
724726 vpic->CurrPic = (VAPictureH264) {
725− .picture_id = pic->recon_surface,
727+ .picture_id = vaapi_pic->recon_surface,
726728 .frame_idx = hpic->frame_num,
727729 .flags = 0,
728730 .TopFieldOrderCnt = hpic->pic_order_cnt,
@@ -730,14 +732,14 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 1 unmodified line
730732 };
731733 for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {
732734 for (i = 0; i < pic->nb_refs[k]; i++) {
733− VAAPIEncodePicture *ref = pic->refs[k][i];
735+ FFHWBaseEncodePicture *ref = pic->refs[k][i];
734736 VAAPIEncodeH264Picture *href;
735737
736738 av_assert0(ref && ref->encode_order < pic->encode_order);
737739 href = ref->priv_data;
738740
739741 vpic->ReferenceFrames[j++] = (VAPictureH264) {
740− .picture_id = ref->recon_surface,
742+ .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface,
741743 .frame_idx = href->frame_num,
742744 .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE,
743745 .TopFieldOrderCnt = href->pic_order_cnt,
@@ -753,7 +755,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 9 unmodified lines
753755 };
754756 }
755757
756− vpic->coded_buf = pic->output_buffer;
758+ vpic->coded_buf = vaapi_pic->output_buffer;
757759
758760 vpic->frame_num = hpic->frame_num;
759761
@@ -764,12 +766,13 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 4 unmodified lines
764766 }
765767
766768 static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,
767− VAAPIEncodePicture *pic,
769+ VAAPIEncodePicture *vaapi_pic,
768770 VAAPIEncodePicture **rpl0,
769771 VAAPIEncodePicture **rpl1,
770772 int *rpl_size)
771773 {
772− VAAPIEncodePicture *prev;
774+ FFHWBaseEncodePicture *pic = &vaapi_pic->base;
775+ FFHWBaseEncodePicture *prev;
773776 VAAPIEncodeH264Picture *hp, *hn, *hc;
774777 int i, j, n = 0;
775778
@@ -783,17 +786,17 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 7 unmodified lines
783786
784787 if (pic->type == FF_HW_PICTURE_TYPE_P) {
785788 for (j = n; j > 0; j--) {
786− hc = rpl0[j - 1]->priv_data;
789+ hc = rpl0[j - 1]->base.priv_data;
787790 av_assert0(hc->frame_num != hn->frame_num);
788791 if (hc->frame_num > hn->frame_num)
789792 break;
790793 rpl0[j] = rpl0[j - 1];
791794 }
792− rpl0[j] = prev->dpb[i];
795+ rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i];
793796
794797 } else if (pic->type == FF_HW_PICTURE_TYPE_B) {
795798 for (j = n; j > 0; j--) {
796− hc = rpl0[j - 1]->priv_data;
799+ hc = rpl0[j - 1]->base.priv_data;
797800 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);
798801 if (hc->pic_order_cnt < hp->pic_order_cnt) {
799802 if (hn->pic_order_cnt > hp->pic_order_cnt ||
@@ -805,10 +808,10 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 5 unmodified lines
805808 }
806809 rpl0[j] = rpl0[j - 1];
807810 }
808− rpl0[j] = prev->dpb[i];
811+ rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i];
809812
810813 for (j = n; j > 0; j--) {
811− hc = rpl1[j - 1]->priv_data;
814+ hc = rpl1[j - 1]->base.priv_data;
812815 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);
813816 if (hc->pic_order_cnt > hp->pic_order_cnt) {
814817 if (hn->pic_order_cnt < hp->pic_order_cnt ||
@@ -820,7 +823,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 5 unmodified lines
820823 }
821824 rpl1[j] = rpl1[j - 1];
822825 }
823− rpl1[j] = prev->dpb[i];
826+ rpl1[j] = (VAAPIEncodePicture *)prev->dpb[i];
824827 }
825828
826829 ++n;
@@ -840,7 +843,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 13 unmodified lines
840843 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:",
841844 hp->frame_num, hp->pic_order_cnt);
842845 for (i = 0; i < n; i++) {
843− hn = rpl0[i]->priv_data;
846+ hn = rpl0[i]->base.priv_data;
844847 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",
845848 hn->frame_num, hn->pic_order_cnt);
846849 }
@@ -850,7 +853,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 3 unmodified lines
850853 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:",
851854 hp->frame_num, hp->pic_order_cnt);
852855 for (i = 0; i < n; i++) {
853− hn = rpl1[i]->priv_data;
856+ hn = rpl1[i]->base.priv_data;
854857 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",
855858 hn->frame_num, hn->pic_order_cnt);
856859 }
@@ -861,16 +864,17 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 4 unmodified lines
861864 }
862865
863866 static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
864− VAAPIEncodePicture *pic,
867+ VAAPIEncodePicture *vaapi_pic,
865868 VAAPIEncodeSlice *slice)
866869 {
867870 VAAPIEncodeH264Context *priv = avctx->priv_data;
871+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
868872 VAAPIEncodeH264Picture *hpic = pic->priv_data;
869− VAAPIEncodePicture *prev = pic->prev;
873+ FFHWBaseEncodePicture *prev = pic->prev;
870874 H264RawSPS *sps = &priv->raw_sps;
871875 H264RawPPS *pps = &priv->raw_pps;
872876 H264RawSliceHeader *sh = &priv->raw_slice.header;
873− VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
877+ VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params;
874878 VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;
875879 int i, j;
876880
@@ -903,7 +907,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 26 unmodified lines
903907 sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);
904908
905909 if (pic->is_reference && pic->type != FF_HW_PICTURE_TYPE_IDR) {
906− VAAPIEncodePicture *discard_list[MAX_DPB_SIZE];
910+ FFHWBaseEncodePicture *discard_list[MAX_DPB_SIZE];
907911 int discard = 0, keep = 0;
908912
909913 // Discard everything which is in the DPB of the previous frame but
@@ -944,14 +948,14 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 34 unmodified lines
944948 VAAPIEncodeH264Picture *href;
945949 int n;
946950
947− vaapi_encode_h264_default_ref_pic_list(avctx, pic,
951+ vaapi_encode_h264_default_ref_pic_list(avctx, vaapi_pic,
948952 def_l0, def_l1, &n);
949953
950954 if (pic->type == FF_HW_PICTURE_TYPE_P) {
951955 int need_rplm = 0;
952956 for (i = 0; i < pic->nb_refs[0]; i++) {
953957 av_assert0(pic->refs[0][i]);
954− if (pic->refs[0][i] != def_l0[i])
958+ if (pic->refs[0][i] != (FFHWBaseEncodePicture *)def_l0[i])
955959 need_rplm = 1;
956960 }
957961
@@ -982,7 +986,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 24 unmodified lines
982986 av_assert0(pic->refs[0][i]);
983987 href = pic->refs[0][i]->priv_data;
984988 av_assert0(href->pic_order_cnt < hpic->pic_order_cnt);
985− if (pic->refs[0][i] != def_l0[n0])
989+ if (pic->refs[0][i] != (FFHWBaseEncodePicture *)def_l0[n0])
986990 need_rplm_l0 = 1;
987991 ++n0;
988992 }
@@ -991,7 +995,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 2 unmodified lines
991995 av_assert0(pic->refs[1][i]);
992996 href = pic->refs[1][i]->priv_data;
993997 av_assert0(href->pic_order_cnt > hpic->pic_order_cnt);
994− if (pic->refs[1][i] != def_l1[n1])
998+ if (pic->refs[1][i] != (FFHWBaseEncodePicture *)def_l1[n1])
995999 need_rplm_l1 = 1;
9961000 ++n1;
9971001 }
@@ -1380,7 +1384,7 @@ const FFCodec ff_h264_vaapi_encoder = { · 382 unmodified lines
13801384 .p.id = AV_CODEC_ID_H264,
13811385 .priv_data_size = sizeof(VAAPIEncodeH264Context),
13821386 .init = &vaapi_encode_h264_init,
1383− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
1387+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
13841388 .close = &vaapi_encode_h264_close,
13851389 .p.priv_class = &vaapi_encode_h264_class,
13861390 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
libavcodec/vaapi_encode_h265.c+28−25
@@ -260,6 +260,7 @@ fail: · 259 unmodified lines
260260
261261 static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
262262 {
263+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
263264 VAAPIEncodeContext *ctx = avctx->priv_data;
264265 VAAPIEncodeH265Context *priv = avctx->priv_data;
265266 H265RawVPS *vps = &priv->raw_vps;
@@ -341,7 +342,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines
341342 ptl->general_max_420chroma_constraint_flag = chroma_format <= 1;
342343 ptl->general_max_monochrome_constraint_flag = chroma_format == 0;
343344
344− ptl->general_intra_constraint_flag = ctx->gop_size == 1;
345+ ptl->general_intra_constraint_flag = base_ctx->gop_size == 1;
345346 ptl->general_one_picture_only_constraint_flag = 0;
346347
347348 ptl->general_lower_bit_rate_constraint_flag = 1;
@@ -354,7 +355,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 6 unmodified lines
354355 level = ff_h265_guess_level(ptl, avctx->bit_rate,
355356 ctx->surface_width, ctx->surface_height,
356357 ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,
357− (ctx->b_per_p > 0) + 1);
358+ (base_ctx->b_per_p > 0) + 1);
358359 if (level) {
359360 av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
360361 ptl->general_level_idc = level->level_idc;
@@ -368,8 +369,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 7 unmodified lines
368369 }
369370
370371 vps->vps_sub_layer_ordering_info_present_flag = 0;
371− vps->vps_max_dec_pic_buffering_minus1[0] = ctx->max_b_depth + 1;
372− vps->vps_max_num_reorder_pics[0] = ctx->max_b_depth;
372+ vps->vps_max_dec_pic_buffering_minus1[0] = base_ctx->max_b_depth + 1;
373+ vps->vps_max_num_reorder_pics[0] = base_ctx->max_b_depth;
373374 vps->vps_max_latency_increase_plus1[0] = 0;
374375
375376 vps->vps_max_layer_id = 0;
@@ -643,9 +644,9 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 267 unmodified lines
643644 .general_level_idc = vps->profile_tier_level.general_level_idc,
644645 .general_tier_flag = vps->profile_tier_level.general_tier_flag,
645646
646− .intra_period = ctx->gop_size,
647− .intra_idr_period = ctx->gop_size,
648− .ip_period = ctx->b_per_p + 1,
647+ .intra_period = base_ctx->gop_size,
648+ .intra_idr_period = base_ctx->gop_size,
649+ .ip_period = base_ctx->b_per_p + 1,
649650 .bits_per_second = ctx->va_bit_rate,
650651
651652 .pic_width_in_luma_samples = sps->pic_width_in_luma_samples,
@@ -756,14 +757,15 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 104 unmodified lines
756757 }
757758
758759 static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
759− VAAPIEncodePicture *pic)
760+ VAAPIEncodePicture *vaapi_pic)
760761 {
761− VAAPIEncodeContext *ctx = avctx->priv_data;
762+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
762763 VAAPIEncodeH265Context *priv = avctx->priv_data;
764+ FFHWBaseEncodePicture *pic = &vaapi_pic->base;
763765 VAAPIEncodeH265Picture *hpic = pic->priv_data;
764− VAAPIEncodePicture *prev = pic->prev;
766+ FFHWBaseEncodePicture *prev = pic->prev;
765767 VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL;
766− VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;
768+ VAEncPictureParameterBufferHEVC *vpic = vaapi_pic->codec_picture_params;
767769 int i, j = 0;
768770
769771 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
@@ -788,13 +790,13 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 18 unmodified lines
788790 hpic->slice_type = HEVC_SLICE_P;
789791 hpic->pic_type = 1;
790792 } else {
791− VAAPIEncodePicture *irap_ref;
793+ FFHWBaseEncodePicture *irap_ref;
792794 av_assert0(pic->refs[0][0] && pic->refs[1][0]);
793795 for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) {
794796 if (irap_ref->type == FF_HW_PICTURE_TYPE_I)
795797 break;
796798 }
797− if (pic->b_depth == ctx->max_b_depth) {
799+ if (pic->b_depth == base_ctx->max_b_depth) {
798800 hpic->slice_nal_unit = irap_ref ? HEVC_NAL_RASL_N
799801 : HEVC_NAL_TRAIL_N;
800802 } else {
@@ -910,21 +912,21 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 109 unmodified lines
910912 }
911913
912914 vpic->decoded_curr_pic = (VAPictureHEVC) {
913− .picture_id = pic->recon_surface,
915+ .picture_id = vaapi_pic->recon_surface,
914916 .pic_order_cnt = hpic->pic_order_cnt,
915917 .flags = 0,
916918 };
917919
918920 for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {
919921 for (i = 0; i < pic->nb_refs[k]; i++) {
920− VAAPIEncodePicture *ref = pic->refs[k][i];
922+ FFHWBaseEncodePicture *ref = pic->refs[k][i];
921923 VAAPIEncodeH265Picture *href;
922924
923925 av_assert0(ref && ref->encode_order < pic->encode_order);
924926 href = ref->priv_data;
925927
926928 vpic->reference_frames[j++] = (VAPictureHEVC) {
927− .picture_id = ref->recon_surface,
929+ .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface,
928930 .pic_order_cnt = href->pic_order_cnt,
929931 .flags = (ref->display_order < pic->display_order ?
930932 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) |
@@ -941,7 +943,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 10 unmodified lines
941943 };
942944 }
943945
944− vpic->coded_buf = pic->output_buffer;
946+ vpic->coded_buf = vaapi_pic->output_buffer;
945947
946948 vpic->nal_unit_type = hpic->slice_nal_unit;
947949
@@ -971,16 +973,17 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 23 unmodified lines
971973 }
972974
973975 static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
974− VAAPIEncodePicture *pic,
976+ VAAPIEncodePicture *vaapi_pic,
975977 VAAPIEncodeSlice *slice)
976978 {
977− VAAPIEncodeContext *ctx = avctx->priv_data;
979+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
978980 VAAPIEncodeH265Context *priv = avctx->priv_data;
981+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
979982 VAAPIEncodeH265Picture *hpic = pic->priv_data;
980983 const H265RawSPS *sps = &priv->raw_sps;
981984 const H265RawPPS *pps = &priv->raw_pps;
982985 H265RawSliceHeader *sh = &priv->raw_slice.header;
983− VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;
986+ VAEncPictureParameterBufferHEVC *vpic = vaapi_pic->codec_picture_params;
984987 VAEncSliceParameterBufferHEVC *vslice = slice->codec_slice_params;
985988 int i;
986989
@@ -997,7 +1000,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 10 unmodified lines
9971000
9981001 sh->slice_type = hpic->slice_type;
9991002
1000− if (sh->slice_type == HEVC_SLICE_P && ctx->p_to_gpb)
1003+ if (sh->slice_type == HEVC_SLICE_P && base_ctx->p_to_gpb)
10011004 sh->slice_type = HEVC_SLICE_B;
10021005
10031006 sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt &
@@ -1141,7 +1144,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 137 unmodified lines
11411144 .slice_tc_offset_div2 = sh->slice_tc_offset_div2,
11421145
11431146 .slice_fields.bits = {
1144− .last_slice_of_pic_flag = slice->index == pic->nb_slices - 1,
1147+ .last_slice_of_pic_flag = slice->index == vaapi_pic->nb_slices - 1,
11451148 .dependent_slice_segment_flag = sh->dependent_slice_segment_flag,
11461149 .colour_plane_id = sh->colour_plane_id,
11471150 .slice_temporal_mvp_enabled_flag =
@@ -1172,7 +1175,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 24 unmodified lines
11721175 av_assert0(pic->type == FF_HW_PICTURE_TYPE_P ||
11731176 pic->type == FF_HW_PICTURE_TYPE_B);
11741177 vslice->ref_pic_list0[0] = vpic->reference_frames[0];
1175− if (ctx->p_to_gpb && pic->type == FF_HW_PICTURE_TYPE_P)
1178+ if (base_ctx->p_to_gpb && pic->type == FF_HW_PICTURE_TYPE_P)
11761179 // Reference for GPB B-frame, L0 == L1
11771180 vslice->ref_pic_list1[0] = vpic->reference_frames[0];
11781181 }
@@ -1182,7 +1185,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 3 unmodified lines
11821185 vslice->ref_pic_list1[0] = vpic->reference_frames[1];
11831186 }
11841187
1185− if (pic->type == FF_HW_PICTURE_TYPE_P && ctx->p_to_gpb) {
1188+ if (pic->type == FF_HW_PICTURE_TYPE_P && base_ctx->p_to_gpb) {
11861189 vslice->slice_type = HEVC_SLICE_B;
11871190 for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
11881191 vslice->ref_pic_list1[i].picture_id = vslice->ref_pic_list0[i].picture_id;
@@ -1495,7 +1498,7 @@ const FFCodec ff_hevc_vaapi_encoder = { · 306 unmodified lines
14951498 .p.id = AV_CODEC_ID_HEVC,
14961499 .priv_data_size = sizeof(VAAPIEncodeH265Context),
14971500 .init = &vaapi_encode_h265_init,
1498− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
1501+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
14991502 .close = &vaapi_encode_h265_close,
15001503 .p.priv_class = &vaapi_encode_h265_class,
15011504 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
libavcodec/vaapi_encode_mjpeg.c+7−6
@@ -220,12 +220,13 @@ static int vaapi_encode_mjpeg_write_extra_buffer(AVCodecContext *avctx, · 219 unmodified lines
220220 }
221221
222222 static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
223− VAAPIEncodePicture *pic)
223+ VAAPIEncodePicture *vaapi_pic)
224224 {
225225 VAAPIEncodeMJPEGContext *priv = avctx->priv_data;
226+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
226227 JPEGRawFrameHeader *fh = &priv->frame_header;
227228 JPEGRawScanHeader *sh = &priv->scan.header;
228− VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
229+ VAEncPictureParameterBufferJPEG *vpic = vaapi_pic->codec_picture_params;
229230 const AVPixFmtDescriptor *desc;
230231 const uint8_t components_rgb[3] = { 'R', 'G', 'B' };
231232 const uint8_t components_yuv[3] = { 1, 2, 3 };
@@ -377,8 +378,8 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, · 145 unmodified lines
377378
378379
379380 *vpic = (VAEncPictureParameterBufferJPEG) {
380− .reconstructed_picture = pic->recon_surface,
381− .coded_buf = pic->output_buffer,
381+ .reconstructed_picture = vaapi_pic->recon_surface,
382+ .coded_buf = vaapi_pic->output_buffer,
382383
383384 .picture_width = fh->X,
384385 .picture_height = fh->Y,
@@ -406,7 +407,7 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, · 21 unmodified lines
406407 vpic->quantiser_table_selector[i] = fh->Tq[i];
407408 }
408409
409− pic->nb_slices = 1;
410+ vaapi_pic->nb_slices = 1;
410411
411412 return 0;
412413 }
@@ -572,7 +573,7 @@ const FFCodec ff_mjpeg_vaapi_encoder = { · 159 unmodified lines
572573 .p.id = AV_CODEC_ID_MJPEG,
573574 .priv_data_size = sizeof(VAAPIEncodeMJPEGContext),
574575 .init = &vaapi_encode_mjpeg_init,
575− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
576+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
576577 .close = &vaapi_encode_mjpeg_close,
577578 .p.priv_class = &vaapi_encode_mjpeg_class,
578579 .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1 |
libavcodec/vaapi_encode_mpeg2.c+18−15
@@ -166,6 +166,7 @@ fail: · 165 unmodified lines
166166
167167 static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
168168 {
169+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
169170 VAAPIEncodeContext *ctx = avctx->priv_data;
170171 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
171172 MPEG2RawSequenceHeader *sh = &priv->sequence_header;
@@ -281,7 +282,7 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 109 unmodified lines
281282
282283 se->bit_rate_extension = priv->bit_rate >> 18;
283284 se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10;
284− se->low_delay = ctx->b_per_p == 0;
285+ se->low_delay = base_ctx->b_per_p == 0;
285286
286287 se->frame_rate_extension_n = ext_n;
287288 se->frame_rate_extension_d = ext_d;
@@ -353,8 +354,8 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 65 unmodified lines
353354
354355
355356 *vseq = (VAEncSequenceParameterBufferMPEG2) {
356− .intra_period = ctx->gop_size,
357− .ip_period = ctx->b_per_p + 1,
357+ .intra_period = base_ctx->gop_size,
358+ .ip_period = base_ctx->b_per_p + 1,
358359
359360 .picture_width = avctx->width,
360361 .picture_height = avctx->height,
@@ -417,12 +418,13 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 56 unmodified lines
417418 }
418419
419420 static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
420− VAAPIEncodePicture *pic)
421+ VAAPIEncodePicture *vaapi_pic)
421422 {
422423 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
424+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
423425 MPEG2RawPictureHeader *ph = &priv->picture_header;
424426 MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding;
425− VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
427+ VAEncPictureParameterBufferMPEG2 *vpic = vaapi_pic->codec_picture_params;
426428
427429 if (pic->type == FF_HW_PICTURE_TYPE_IDR || pic->type == FF_HW_PICTURE_TYPE_I) {
428430 ph->temporal_reference = 0;
@@ -448,8 +450,8 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 19 unmodified lines
448450 pce->f_code[1][1] = 15;
449451 }
450452
451− vpic->reconstructed_picture = pic->recon_surface;
452− vpic->coded_buf = pic->output_buffer;
453+ vpic->reconstructed_picture = vaapi_pic->recon_surface;
454+ vpic->coded_buf = vaapi_pic->output_buffer;
453455
454456 switch (pic->type) {
455457 case FF_HW_PICTURE_TYPE_IDR:
@@ -458,12 +460,12 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 2 unmodified lines
458460 break;
459461 case FF_HW_PICTURE_TYPE_P:
460462 vpic->picture_type = VAEncPictureTypePredictive;
461− vpic->forward_reference_picture = pic->refs[0][0]->recon_surface;
463+ vpic->forward_reference_picture = ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface;
462464 break;
463465 case FF_HW_PICTURE_TYPE_B:
464466 vpic->picture_type = VAEncPictureTypeBidirectional;
465− vpic->forward_reference_picture = pic->refs[0][0]->recon_surface;
466− vpic->backward_reference_picture = pic->refs[1][0]->recon_surface;
467+ vpic->forward_reference_picture = ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface;
468+ vpic->backward_reference_picture = ((VAAPIEncodePicture *)pic->refs[1][0])->recon_surface;
467469 break;
468470 default:
469471 av_assert0(0 && "invalid picture type");
@@ -479,11 +481,12 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 9 unmodified lines
479481 }
480482
481483 static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,
482− VAAPIEncodePicture *pic,
483− VAAPIEncodeSlice *slice)
484+ VAAPIEncodePicture *vaapi_pic,
485+ VAAPIEncodeSlice *slice)
484486 {
485− VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
486− VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;
487+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
488+ VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
489+ VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;
487490 int qp;
488491
489492 vslice->macroblock_address = slice->block_start;
@@ -695,7 +698,7 @@ const FFCodec ff_mpeg2_vaapi_encoder = { · 205 unmodified lines
695698 .p.id = AV_CODEC_ID_MPEG2VIDEO,
696699 .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),
697700 .init = &vaapi_encode_mpeg2_init,
698− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
701+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
699702 .close = &vaapi_encode_mpeg2_close,
700703 .p.priv_class = &vaapi_encode_mpeg2_class,
701704 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
libavcodec/vaapi_encode_vp8.c+10−8
@@ -52,6 +52,7 @@ typedef struct VAAPIEncodeVP8Context { · 51 unmodified lines
5252
5353 static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
5454 {
55+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
5556 VAAPIEncodeContext *ctx = avctx->priv_data;
5657 VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params;
5758
@@ -66,22 +67,23 @@ static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) · 8 unmodified lines
6667
6768 if (!(ctx->va_rc_mode & VA_RC_CQP)) {
6869 vseq->bits_per_second = ctx->va_bit_rate;
69− vseq->intra_period = ctx->gop_size;
70+ vseq->intra_period = base_ctx->gop_size;
7071 }
7172
7273 return 0;
7374 }
7475
7576 static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx,
76− VAAPIEncodePicture *pic)
77+ VAAPIEncodePicture *vaapi_pic)
7778 {
79+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
7880 VAAPIEncodeVP8Context *priv = avctx->priv_data;
79− VAEncPictureParameterBufferVP8 *vpic = pic->codec_picture_params;
81+ VAEncPictureParameterBufferVP8 *vpic = vaapi_pic->codec_picture_params;
8082 int i;
8183
82− vpic->reconstructed_frame = pic->recon_surface;
84+ vpic->reconstructed_frame = vaapi_pic->recon_surface;
8385
84− vpic->coded_buf = pic->output_buffer;
86+ vpic->coded_buf = vaapi_pic->output_buffer;
8587
8688 switch (pic->type) {
8789 case FF_HW_PICTURE_TYPE_IDR:
@@ -101,7 +103,7 @@ static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, · 13 unmodified lines
101103 vpic->ref_last_frame =
102104 vpic->ref_gf_frame =
103105 vpic->ref_arf_frame =
104− pic->refs[0][0]->recon_surface;
106+ ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface;
105107 break;
106108 default:
107109 av_assert0(0 && "invalid picture type");
@@ -145,7 +147,7 @@ static int vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx, · 37 unmodified lines
145147
146148 memset(&quant, 0, sizeof(quant));
147149
148− if (pic->type == FF_HW_PICTURE_TYPE_P)
150+ if (pic->base.type == FF_HW_PICTURE_TYPE_P)
149151 q = priv->q_index_p;
150152 else
151153 q = priv->q_index_i;
@@ -250,7 +252,7 @@ const FFCodec ff_vp8_vaapi_encoder = { · 98 unmodified lines
250252 .p.id = AV_CODEC_ID_VP8,
251253 .priv_data_size = sizeof(VAAPIEncodeVP8Context),
252254 .init = &vaapi_encode_vp8_init,
253− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
255+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
254256 .close = &ff_vaapi_encode_close,
255257 .p.priv_class = &vaapi_encode_vp8_class,
256258 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
libavcodec/vaapi_encode_vp9.c+13−11
@@ -53,6 +53,7 @@ typedef struct VAAPIEncodeVP9Context { · 52 unmodified lines
5353
5454 static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)
5555 {
56+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
5657 VAAPIEncodeContext *ctx = avctx->priv_data;
5758 VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params;
5859 VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params;
@@ -64,7 +65,7 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) · 5 unmodified lines
6465
6566 if (!(ctx->va_rc_mode & VA_RC_CQP)) {
6667 vseq->bits_per_second = ctx->va_bit_rate;
67− vseq->intra_period = ctx->gop_size;
68+ vseq->intra_period = base_ctx->gop_size;
6869 }
6970
7071 vpic->frame_width_src = avctx->width;
@@ -76,17 +77,18 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) · 5 unmodified lines
7677 }
7778
7879 static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
79− VAAPIEncodePicture *pic)
80+ VAAPIEncodePicture *vaapi_pic)
8081 {
81− VAAPIEncodeContext *ctx = avctx->priv_data;
82+ FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
8283 VAAPIEncodeVP9Context *priv = avctx->priv_data;
84+ const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
8385 VAAPIEncodeVP9Picture *hpic = pic->priv_data;
84− VAEncPictureParameterBufferVP9 *vpic = pic->codec_picture_params;
86+ VAEncPictureParameterBufferVP9 *vpic = vaapi_pic->codec_picture_params;
8587 int i;
8688 int num_tile_columns;
8789
88− vpic->reconstructed_frame = pic->recon_surface;
89− vpic->coded_buf = pic->output_buffer;
90+ vpic->reconstructed_frame = vaapi_pic->recon_surface;
91+ vpic->coded_buf = vaapi_pic->output_buffer;
9092
9193 // Maximum width of a tile in units of superblocks is MAX_TILE_WIDTH_B64(64)
9294 // So the number of tile columns is related to the width of the picture.
@@ -107,7 +109,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 14 unmodified lines
107109 VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data;
108110 av_assert0(href->slot == 0 || href->slot == 1);
109111
110− if (ctx->max_b_depth > 0) {
112+ if (base_ctx->max_b_depth > 0) {
111113 hpic->slot = !href->slot;
112114 vpic->refresh_frame_flags = 1 << hpic->slot | 0xfc;
113115 } else {
@@ -127,7 +129,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 13 unmodified lines
127129 av_assert0(href0->slot < pic->b_depth + 1 &&
128130 href1->slot < pic->b_depth + 1);
129131
130− if (pic->b_depth == ctx->max_b_depth) {
132+ if (pic->b_depth == base_ctx->max_b_depth) {
131133 // Unreferenced frame.
132134 vpic->refresh_frame_flags = 0x00;
133135 hpic->slot = 8;
@@ -159,11 +161,11 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 25 unmodified lines
159161
160162 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
161163 for (int j = 0; j < pic->nb_refs[i]; j++) {
162− VAAPIEncodePicture *ref_pic = pic->refs[i][j];
164+ FFHWBaseEncodePicture *ref_pic = pic->refs[i][j];
163165 int slot;
164166 slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot;
165167 av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);
166− vpic->reference_frames[slot] = ref_pic->recon_surface;
168+ vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)->recon_surface;
167169 }
168170 }
169171
@@ -307,7 +309,7 @@ const FFCodec ff_vp9_vaapi_encoder = { · 137 unmodified lines
307309 .p.id = AV_CODEC_ID_VP9,
308310 .priv_data_size = sizeof(VAAPIEncodeVP9Context),
309311 .init = &vaapi_encode_vp9_init,
310− FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
312+ FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet),
311313 .close = &ff_vaapi_encode_close,
312314 .p.priv_class = &vaapi_encode_vp9_class,
313315 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t