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
165OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o165OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
166OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o166OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o
167OBJS-$(CONFIG_TPELDSP) += tpeldsp.o167OBJS-$(CONFIG_TPELDSP) += tpeldsp.o
168OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o168OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o hw_base_encode.o
169OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o169OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o
170OBJS-$(CONFIG_VC1DSP) += vc1dsp.o170OBJS-$(CONFIG_VC1DSP) += vc1dsp.o
171OBJS-$(CONFIG_VIDEODSP) += videodsp.o171OBJS-$(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
30static 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
63static 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
97static 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
161static 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
194static 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
346static 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
384static 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
410static 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
486fail:
487 ctx->op->free(avctx, pic);
488 return err;
489}
490
491int 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
501start:
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
588end:
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
19#ifndef AVCODEC_HW_BASE_ENCODE_H19#ifndef AVCODEC_HW_BASE_ENCODE_H
20#define AVCODEC_HW_BASE_ENCODE_H20#define AVCODEC_HW_BASE_ENCODE_H
21 21
22#include "libavutil/fifo.h"
23
22#define MAX_DPB_SIZE 1624#define MAX_DPB_SIZE 16
23#define MAX_PICTURE_REFERENCES 225#define MAX_PICTURE_REFERENCES 2
24#define MAX_REORDER_DELAY 1626#define MAX_REORDER_DELAY 16
@@ -54,13 +56,135 @@ enum { · 29 unmodified lines
54 FF_HW_FLAG_NON_IDR_KEY_PICTURES = 1 << 5,56 FF_HW_FLAG_NON_IDR_KEY_PICTURES = 1 << 5,
55};57};
56 58
59typedef 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
104typedef 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
57typedef struct FFHWBaseEncodeContext {116typedef struct FFHWBaseEncodeContext {
58 const AVClass *class;117 const AVClass *class;
59 118
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;
60 // Max number of frame buffered in encoder.179 // Max number of frame buffered in encoder.
61 int async_depth;180 int async_depth;
181
182 /** Tail data of a pic, now only used for av1 repeat frame header. */
183 AVPacket *tail_pkt;
62} FFHWBaseEncodeContext;184} FFHWBaseEncodeContext;
63 185
186int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
187
64#define HW_BASE_ENCODE_COMMON_OPTIONS \188#define HW_BASE_ENCODE_COMMON_OPTIONS \
65 { "async_depth", "Maximum processing parallelism. " \189 { "async_depth", "Maximum processing parallelism. " \
66 "Increase this to improve single channel performance.", \190 "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
138static int vaapi_encode_wait(AVCodecContext *avctx,138static int vaapi_encode_wait(AVCodecContext *avctx,
139 VAAPIEncodePicture *pic)139 VAAPIEncodePicture *pic)
140{140{
141#if VA_CHECK_VERSION(1, 9, 0)
142 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
143#endif
141 VAAPIEncodeContext *ctx = avctx->priv_data;144 VAAPIEncodeContext *ctx = avctx->priv_data;
145 FFHWBaseEncodePicture *base_pic = &pic->base;
142 VAStatus vas;146 VAStatus vas;
143 147
144 av_assert0(pic->encode_issued);148 av_assert0(base_pic->encode_issued);
145 149
146 if (pic->encode_complete) {150 if (base_pic->encode_complete) {
147 // Already waited for this picture.151 // Already waited for this picture.
148 return 0;152 return 0;
149 }153 }
150 154
151 av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "155 av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
152 "(input surface %#x).\n", pic->display_order,156 "(input surface %#x).\n", base_pic->display_order,
153 pic->encode_order, pic->input_surface);157 base_pic->encode_order, pic->input_surface);
154 158
155#if VA_CHECK_VERSION(1, 9, 0)159#if VA_CHECK_VERSION(1, 9, 0)
156 if (ctx->has_sync_buffer_func) {160 if (base_ctx->async_encode) {
157 vas = vaSyncBuffer(ctx->hwctx->display,161 vas = vaSyncBuffer(ctx->hwctx->display,
158 pic->output_buffer,162 pic->output_buffer,
159 VA_TIMEOUT_INFINITE);163 VA_TIMEOUT_INFINITE);
@@ -174,9 +178,9 @@ static int vaapi_encode_wait(AVCodecContext *avctx, · 14 unmodified lines
174 }178 }
175 179
176 // Input is definitely finished with now.180 // Input is definitely finished with now.
177 av_frame_free(&pic->input_image);181 av_frame_free(&base_pic->input_image);
178 182
179 pic->encode_complete = 1;183 base_pic->encode_complete = 1;
180 return 0;184 return 0;
181}185}
182 186
@@ -263,9 +267,11 @@ static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, · 80 unmodified lines
263}267}
264 268
265static int vaapi_encode_issue(AVCodecContext *avctx,269static int vaapi_encode_issue(AVCodecContext *avctx,
266 VAAPIEncodePicture *pic)270 const FFHWBaseEncodePicture *base_pic)
267{271{
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;
269 VAAPIEncodeSlice *slice;275 VAAPIEncodeSlice *slice;
270 VAStatus vas;276 VAStatus vas;
271 int err, i;277 int err, i;
@@ -274,52 +280,46 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 2 unmodified lines
274 av_unused AVFrameSideData *sd;280 av_unused AVFrameSideData *sd;
275 281
276 av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "282 av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
277 "as type %s.\n", pic->display_order, pic->encode_order,283 "as type %s.\n", base_pic->display_order, base_pic->encode_order,
278 ff_hw_base_encode_get_pictype_name(pic->type));284 ff_hw_base_encode_get_pictype_name(base_pic->type));
279 if (pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0) {285 if (base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0) {
280 av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");286 av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
281 } else {287 } else {
282 av_log(avctx, AV_LOG_DEBUG, "L0 refers to");288 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++) {
284 av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,290 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);
286 }292 }
287 av_log(avctx, AV_LOG_DEBUG, ".\n");293 av_log(avctx, AV_LOG_DEBUG, ".\n");
288 294
289 if (pic->nb_refs[1]) {295 if (base_pic->nb_refs[1]) {
290 av_log(avctx, AV_LOG_DEBUG, "L1 refers to");296 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++) {
292 av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,298 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);
294 }300 }
295 av_log(avctx, AV_LOG_DEBUG, ".\n");301 av_log(avctx, AV_LOG_DEBUG, ".\n");
296 }302 }
297 }303 }
298 304
299 av_assert0(!pic->encode_issued);305 av_assert0(!base_pic->encode_issued);
300 for (i = 0; i < pic->nb_refs[0]; i++) {306 for (i = 0; i < base_pic->nb_refs[0]; i++) {
301 av_assert0(pic->refs[0][i]);307 av_assert0(base_pic->refs[0][i]);
302 av_assert0(pic->refs[0][i]->encode_issued);308 av_assert0(base_pic->refs[0][i]->encode_issued);
303 }309 }
304 for (i = 0; i < pic->nb_refs[1]; i++) {310 for (i = 0; i < base_pic->nb_refs[1]; i++) {
305 av_assert0(pic->refs[1][i]);311 av_assert0(base_pic->refs[1][i]);
306 av_assert0(pic->refs[1][i]->encode_issued);312 av_assert0(base_pic->refs[1][i]->encode_issued);
307 }313 }
308 314
309 av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);315 av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
310 316
311 pic->recon_image = av_frame_alloc();317 err = av_hwframe_get_buffer(ctx->recon_frames_ref, base_pic->recon_image, 0);
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);
318 if (err < 0) {318 if (err < 0) {
319 err = AVERROR(ENOMEM);319 err = AVERROR(ENOMEM);
320 goto fail;320 goto fail;
321 }321 }
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];
323 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);323 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
324 324
325 pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool);325 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
343 343
344 pic->nb_param_buffers = 0;344 pic->nb_param_buffers = 0;
345 345
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) {
347 err = vaapi_encode_make_param_buffer(avctx, pic,347 err = vaapi_encode_make_param_buffer(avctx, pic,
348 VAEncSequenceParameterBufferType,348 VAEncSequenceParameterBufferType,
349 ctx->codec_sequence_params,349 ctx->codec_sequence_params,
@@ -352,7 +352,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 2 unmodified lines
352 goto fail;352 goto fail;
353 }353 }
354 354
355 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {355 if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
356 for (i = 0; i < ctx->nb_global_params; i++) {356 for (i = 0; i < ctx->nb_global_params; i++) {
357 err = vaapi_encode_make_misc_param_buffer(avctx, pic,357 err = vaapi_encode_make_misc_param_buffer(avctx, pic,
358 ctx->global_params_type[i],358 ctx->global_params_type[i],
@@ -389,7 +389,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 30 unmodified lines
389 }389 }
390#endif390#endif
391 391
392 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {392 if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
393 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&393 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
394 ctx->codec->write_sequence_header) {394 ctx->codec->write_sequence_header) {
395 bit_len = 8 * sizeof(data);395 bit_len = 8 * sizeof(data);
@@ -529,9 +529,9 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 133 unmodified lines
529 }529 }
530 530
531#if VA_CHECK_VERSION(1, 0, 0)531#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,
533 AV_FRAME_DATA_REGIONS_OF_INTEREST);533 AV_FRAME_DATA_REGIONS_OF_INTEREST);
534 if (sd && ctx->roi_allowed) {534 if (sd && base_ctx->roi_allowed) {
535 const AVRegionOfInterest *roi;535 const AVRegionOfInterest *roi;
536 uint32_t roi_size;536 uint32_t roi_size;
537 VAEncMiscParameterBufferROI param_roi;537 VAEncMiscParameterBufferROI param_roi;
@@ -542,11 +542,11 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 4 unmodified lines
542 av_assert0(roi_size && sd->size % roi_size == 0);542 av_assert0(roi_size && sd->size % roi_size == 0);
543 nb_roi = sd->size / roi_size;543 nb_roi = sd->size / roi_size;
544 if (nb_roi > ctx->roi_max_regions) {544 if (nb_roi > ctx->roi_max_regions) {
545 if (!ctx->roi_warned) {545 if (!base_ctx->roi_warned) {
546 av_log(avctx, AV_LOG_WARNING, "More ROIs set than "546 av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
547 "supported by driver (%d > %d).\n",547 "supported by driver (%d > %d).\n",
548 nb_roi, ctx->roi_max_regions);548 nb_roi, ctx->roi_max_regions);
549 ctx->roi_warned = 1;549 base_ctx->roi_warned = 1;
550 }550 }
551 nb_roi = ctx->roi_max_regions;551 nb_roi = ctx->roi_max_regions;
552 }552 }
@@ -639,8 +639,6 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 86 unmodified lines
639 }639 }
640 }640 }
641 641
642 pic->encode_issued = 1;
643
644 return 0;642 return 0;
645 643
646fail_with_picture:644fail_with_picture:
@@ -657,14 +655,13 @@ fail_at_end: · 10 unmodified lines
657 av_freep(&pic->param_buffers);655 av_freep(&pic->param_buffers);
658 av_freep(&pic->slices);656 av_freep(&pic->slices);
659 av_freep(&pic->roi);657 av_freep(&pic->roi);
660 av_frame_free(&pic->recon_image);
661 ff_refstruct_unref(&pic->output_buffer_ref);658 ff_refstruct_unref(&pic->output_buffer_ref);
662 pic->output_buffer = VA_INVALID_ID;659 pic->output_buffer = VA_INVALID_ID;
663 return err;660 return err;
664}661}
665 662
666static int vaapi_encode_set_output_property(AVCodecContext *avctx,663static int vaapi_encode_set_output_property(AVCodecContext *avctx,
667 VAAPIEncodePicture *pic,664 FFHWBaseEncodePicture *pic,
668 AVPacket *pkt)665 AVPacket *pkt)
669{666{
670 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;667 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
@@ -689,16 +686,16 @@ static int vaapi_encode_set_output_property(AVCodecContext *avctx, · 18 unmodified lines
689 return 0;686 return 0;
690 }687 }
691 688
692 if (ctx->output_delay == 0) {689 if (base_ctx->output_delay == 0) {
693 pkt->dts = pkt->pts;690 pkt->dts = pkt->pts;
694 } else if (pic->encode_order < ctx->decode_delay) {691 } else if (pic->encode_order < base_ctx->decode_delay) {
695 if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)692 if (base_ctx->ts_ring[pic->encode_order] < INT64_MIN + base_ctx->dts_pts_diff)
696 pkt->dts = INT64_MIN;693 pkt->dts = INT64_MIN;
697 else694 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;
699 } else {696 } else {
700 pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %697 pkt->dts = base_ctx->ts_ring[(pic->encode_order - base_ctx->decode_delay) %
701 (3 * ctx->output_delay + base_ctx->async_depth)];698 (3 * base_ctx->output_delay + base_ctx->async_depth)];
702 }699 }
703 700
704 return 0;701 return 0;
@@ -817,9 +814,11 @@ end: · 112 unmodified lines
817}814}
818 815
819static int vaapi_encode_output(AVCodecContext *avctx,816static int vaapi_encode_output(AVCodecContext *avctx,
820 VAAPIEncodePicture *pic, AVPacket *pkt)817 const FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
821{818{
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;
823 AVPacket *pkt_ptr = pkt;822 AVPacket *pkt_ptr = pkt;
824 int err;823 int err;
825 824
@@ -832,17 +831,17 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 6 unmodified lines
832 ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref);831 ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref);
833 832
834 if (pic->tail_size) {833 if (pic->tail_size) {
835 if (ctx->tail_pkt->size) {834 if (base_ctx->tail_pkt->size) {
836 err = AVERROR_BUG;835 err = AVERROR_BUG;
837 goto end;836 goto end;
838 }837 }
839 838
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);
841 if (err < 0)840 if (err < 0)
842 goto end;841 goto end;
843 842
844 memcpy(ctx->tail_pkt->data, pic->tail_data, pic->tail_size);843 memcpy(base_ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
845 pkt_ptr = ctx->tail_pkt;844 pkt_ptr = base_ctx->tail_pkt;
846 }845 }
847 } else {846 } else {
848 err = vaapi_encode_get_coded_data(avctx, pic, pkt);847 err = vaapi_encode_get_coded_data(avctx, pic, pkt);
@@ -851,9 +850,9 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 2 unmodified lines
851 }850 }
852 851
853 av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",852 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);
855 854
856 vaapi_encode_set_output_property(avctx, pic, pkt_ptr);855 vaapi_encode_set_output_property(avctx, (FFHWBaseEncodePicture*)pic, pkt_ptr);
857 856
858end:857end:
859 ff_refstruct_unref(&pic->output_buffer_ref);858 ff_refstruct_unref(&pic->output_buffer_ref);
@@ -864,12 +863,14 @@ end: · 4 unmodified lines
864static int vaapi_encode_discard(AVCodecContext *avctx,863static int vaapi_encode_discard(AVCodecContext *avctx,
865 VAAPIEncodePicture *pic)864 VAAPIEncodePicture *pic)
866{865{
866 FFHWBaseEncodePicture *base_pic = &pic->base;
867
867 vaapi_encode_wait(avctx, pic);868 vaapi_encode_wait(avctx, pic);
868 869
869 if (pic->output_buffer_ref) {870 if (pic->output_buffer_ref) {
870 av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "871 av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
871 "%"PRId64"/%"PRId64".\n",872 "%"PRId64"/%"PRId64".\n",
872 pic->display_order, pic->encode_order);873 base_pic->display_order, base_pic->encode_order);
873 874
874 ff_refstruct_unref(&pic->output_buffer_ref);875 ff_refstruct_unref(&pic->output_buffer_ref);
875 pic->output_buffer = VA_INVALID_ID;876 pic->output_buffer = VA_INVALID_ID;
@@ -878,8 +879,8 @@ static int vaapi_encode_discard(AVCodecContext *avctx, · 2 unmodified lines
878 return 0;879 return 0;
879}880}
880 881
881static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx,882static FFHWBaseEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx,
882 const AVFrame *frame)883 const AVFrame *frame)
883{884{
884 VAAPIEncodeContext *ctx = avctx->priv_data;885 VAAPIEncodeContext *ctx = avctx->priv_data;
885 VAAPIEncodePicture *pic;886 VAAPIEncodePicture *pic;
@@ -889,8 +890,8 @@ static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, · 3 unmodified lines
889 return NULL;890 return NULL;
890 891
891 if (ctx->codec->picture_priv_data_size > 0) {892 if (ctx->codec->picture_priv_data_size > 0) {
892 pic->priv_data = av_mallocz(ctx->codec->picture_priv_data_size);893 pic->base.priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
893 if (!pic->priv_data) {894 if (!pic->base.priv_data) {
894 av_freep(&pic);895 av_freep(&pic);
895 return NULL;896 return NULL;
896 }897 }
@@ -900,15 +901,16 @@ static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, · 3 unmodified lines
900 pic->recon_surface = VA_INVALID_ID;901 pic->recon_surface = VA_INVALID_ID;
901 pic->output_buffer = VA_INVALID_ID;902 pic->output_buffer = VA_INVALID_ID;
902 903
903 return pic;904 return &pic->base;
904}905}
905 906
906static int vaapi_encode_free(AVCodecContext *avctx,907static int vaapi_encode_free(AVCodecContext *avctx,
907 VAAPIEncodePicture *pic)908 FFHWBaseEncodePicture *base_pic)
908{909{
910 VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
909 int i;911 int i;
910 912
911 if (pic->encode_issued)913 if (base_pic->encode_issued)
912 vaapi_encode_discard(avctx, pic);914 vaapi_encode_discard(avctx, pic);
913 915
914 if (pic->slices) {916 if (pic->slices) {
@@ -916,17 +918,17 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 1 unmodified line
916 av_freep(&pic->slices[i].codec_slice_params);918 av_freep(&pic->slices[i].codec_slice_params);
917 }919 }
918 920
919 av_frame_free(&pic->input_image);921 av_frame_free(&base_pic->input_image);
920 av_frame_free(&pic->recon_image);922 av_frame_free(&base_pic->recon_image);
921 923
922 av_buffer_unref(&pic->opaque_ref);924 av_buffer_unref(&base_pic->opaque_ref);
923 925
924 av_freep(&pic->param_buffers);926 av_freep(&pic->param_buffers);
925 av_freep(&pic->slices);927 av_freep(&pic->slices);
926 // Output buffer should already be destroyed.928 // Output buffer should already be destroyed.
927 av_assert0(pic->output_buffer == VA_INVALID_ID);929 av_assert0(pic->output_buffer == VA_INVALID_ID);
928 930
929 av_freep(&pic->priv_data);931 av_freep(&base_pic->priv_data);
930 av_freep(&pic->codec_picture_params);932 av_freep(&pic->codec_picture_params);
931 av_freep(&pic->roi);933 av_freep(&pic->roi);
932 934
@@ -935,564 +937,6 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 2 unmodified lines
935 return 0;937 return 0;
936}938}
937 939
938static 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
972static 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
1008static 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
1072static 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
1105static 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
1257static 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
1295static 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
1321static 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
1392fail:
1393 vaapi_encode_free(avctx, pic);
1394 return err;
1395}
1396
1397int 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
1404start:
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
1488end:
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
1496static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type,940static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type,
1497 void *buffer, size_t size)941 void *buffer, size_t size)
1498{942{
@@ -2188,7 +1632,8 @@ static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx) · 689 unmodified lines
2188 1632
2189static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)1633static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
2190{1634{
2191 VAAPIEncodeContext *ctx = avctx->priv_data;1635 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1636 VAAPIEncodeContext *ctx = avctx->priv_data;
2192 VAStatus vas;1637 VAStatus vas;
2193 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };1638 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
2194 uint32_t ref_l0, ref_l1;1639 uint32_t ref_l0, ref_l1;
@@ -2211,7 +1656,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 16 unmodified lines
2211 ref_l1 = attr.value >> 16 & 0xffff;1656 ref_l1 = attr.value >> 16 & 0xffff;
2212 }1657 }
2213 1658
2214 ctx->p_to_gpb = 0;1659 base_ctx->p_to_gpb = 0;
2215 prediction_pre_only = 0;1660 prediction_pre_only = 0;
2216 1661
2217#if VA_CHECK_VERSION(1, 9, 0)1662#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
2247 1692
2248 if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {1693 if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
2249 if (ref_l0 > 0 && ref_l1 > 0) {1694 if (ref_l0 > 0 && ref_l1 > 0) {
2250 ctx->p_to_gpb = 1;1695 base_ctx->p_to_gpb = 1;
2251 av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "1696 av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
2252 "replacing them with B-frames.\n");1697 "replacing them with B-frames.\n");
2253 }1698 }
@@ -2259,7 +1704,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 5 unmodified lines
2259 if (ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||1704 if (ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||
2260 avctx->gop_size <= 1) {1705 avctx->gop_size <= 1) {
2261 av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");1706 av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
2262 ctx->gop_size = 1;1707 base_ctx->gop_size = 1;
2263 } else if (ref_l0 < 1) {1708 } else if (ref_l0 < 1) {
2264 av_log(avctx, AV_LOG_ERROR, "Driver does not support any "1709 av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
2265 "reference frames.\n");1710 "reference frames.\n");
@@ -2267,41 +1712,41 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 1 unmodified line
2267 } else if (!(ctx->codec->flags & FF_HW_FLAG_B_PICTURES) ||1712 } else if (!(ctx->codec->flags & FF_HW_FLAG_B_PICTURES) ||
2268 ref_l1 < 1 || avctx->max_b_frames < 1 ||1713 ref_l1 < 1 || avctx->max_b_frames < 1 ||
2269 prediction_pre_only) {1714 prediction_pre_only) {
2270 if (ctx->p_to_gpb)1715 if (base_ctx->p_to_gpb)
2271 av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "1716 av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2272 "(supported references: %d / %d).\n",1717 "(supported references: %d / %d).\n",
2273 ref_l0, ref_l1);1718 ref_l0, ref_l1);
2274 else1719 else
2275 av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "1720 av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
2276 "(supported references: %d / %d).\n", ref_l0, ref_l1);1721 "(supported references: %d / %d).\n", ref_l0, ref_l1);
2277 ctx->gop_size = avctx->gop_size;1722 base_ctx->gop_size = avctx->gop_size;
2278 ctx->p_per_i = INT_MAX;1723 base_ctx->p_per_i = INT_MAX;
2279 ctx->b_per_p = 0;1724 base_ctx->b_per_p = 0;
2280 } else {1725 } else {
2281 if (ctx->p_to_gpb)1726 if (base_ctx->p_to_gpb)
2282 av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "1727 av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
2283 "(supported references: %d / %d).\n",1728 "(supported references: %d / %d).\n",
2284 ref_l0, ref_l1);1729 ref_l0, ref_l1);
2285 else1730 else
2286 av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "1731 av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
2287 "(supported references: %d / %d).\n", ref_l0, ref_l1);1732 "(supported references: %d / %d).\n", ref_l0, ref_l1);
2288 ctx->gop_size = avctx->gop_size;1733 base_ctx->gop_size = avctx->gop_size;
2289 ctx->p_per_i = INT_MAX;1734 base_ctx->p_per_i = INT_MAX;
2290 ctx->b_per_p = avctx->max_b_frames;1735 base_ctx->b_per_p = avctx->max_b_frames;
2291 if (ctx->codec->flags & FF_HW_FLAG_B_PICTURE_REFERENCES) {1736 if (ctx->codec->flags & FF_HW_FLAG_B_PICTURE_REFERENCES) {
2292 ctx->max_b_depth = FFMIN(ctx->desired_b_depth,1737 base_ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
2293 av_log2(ctx->b_per_p) + 1);1738 av_log2(base_ctx->b_per_p) + 1);
2294 } else {1739 } else {
2295 ctx->max_b_depth = 1;1740 base_ctx->max_b_depth = 1;
2296 }1741 }
2297 }1742 }
2298 1743
2299 if (ctx->codec->flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) {1744 if (ctx->codec->flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) {
2300 ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);1745 base_ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
2301 ctx->gop_per_idr = ctx->idr_interval + 1;1746 base_ctx->gop_per_idr = ctx->idr_interval + 1;
2302 } else {1747 } else {
2303 ctx->closed_gop = 1;1748 base_ctx->closed_gop = 1;
2304 ctx->gop_per_idr = 1;1749 base_ctx->gop_per_idr = 1;
2305 }1750 }
2306 1751
2307 return 0;1752 return 0;
@@ -2614,7 +2059,8 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) · 306 unmodified lines
2614static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)2059static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
2615{2060{
2616#if VA_CHECK_VERSION(1, 0, 0)2061#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;
2618 VAStatus vas;2064 VAStatus vas;
2619 VAConfigAttrib attr = { VAConfigAttribEncROI };2065 VAConfigAttrib attr = { VAConfigAttribEncROI };
2620 2066
@@ -2629,14 +2075,14 @@ static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx) · 8 unmodified lines
2629 }2075 }
2630 2076
2631 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {2077 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2632 ctx->roi_allowed = 0;2078 base_ctx->roi_allowed = 0;
2633 } else {2079 } else {
2634 VAConfigAttribValEncROI roi = {2080 VAConfigAttribValEncROI roi = {
2635 .value = attr.value,2081 .value = attr.value,
2636 };2082 };
2637 2083
2638 ctx->roi_max_regions = roi.bits.num_roi_regions;2084 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 &&
2640 (ctx->va_rc_mode == VA_RC_CQP ||2086 (ctx->va_rc_mode == VA_RC_CQP ||
2641 roi.bits.roi_rc_qp_delta_support);2087 roi.bits.roi_rc_qp_delta_support);
2642 }2088 }
@@ -2771,6 +2217,16 @@ static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx) · 128 unmodified lines
2771 return err;2217 return err;
2772}2218}
2773 2219
2220static 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
2774av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)2230av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
2775{2231{
2776 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;2232 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
@@ -2782,10 +2238,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 5 unmodified lines
2782 ctx->va_config = VA_INVALID_ID;2238 ctx->va_config = VA_INVALID_ID;
2783 ctx->va_context = VA_INVALID_ID;2239 ctx->va_context = VA_INVALID_ID;
2784 2240
2241 base_ctx->op = &vaapi_op;
2242
2785 /* If you add something that can fail above this av_frame_alloc(),2243 /* If you add something that can fail above this av_frame_alloc(),
2786 * modify ff_vaapi_encode_close() accordingly. */2244 * modify ff_vaapi_encode_close() accordingly. */
2787 ctx->frame = av_frame_alloc();2245 base_ctx->frame = av_frame_alloc();
2788 if (!ctx->frame) {2246 if (!base_ctx->frame) {
2789 return AVERROR(ENOMEM);2247 return AVERROR(ENOMEM);
2790 }2248 }
2791 2249
@@ -2810,8 +2268,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 18 unmodified lines
2810 ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;2268 ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
2811 ctx->hwctx = ctx->device->hwctx;2269 ctx->hwctx = ctx->device->hwctx;
2812 2270
2813 ctx->tail_pkt = av_packet_alloc();2271 base_ctx->tail_pkt = av_packet_alloc();
2814 if (!ctx->tail_pkt) {2272 if (!base_ctx->tail_pkt) {
2815 err = AVERROR(ENOMEM);2273 err = AVERROR(ENOMEM);
2816 goto fail;2274 goto fail;
2817 }2275 }
@@ -2910,8 +2368,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 92 unmodified lines
2910 goto fail;2368 goto fail;
2911 }2369 }
2912 2370
2913 ctx->output_delay = ctx->b_per_p;2371 base_ctx->output_delay = base_ctx->b_per_p;
2914 ctx->decode_delay = ctx->max_b_depth;2372 base_ctx->decode_delay = base_ctx->max_b_depth;
2915 2373
2916 if (ctx->codec->sequence_params_size > 0) {2374 if (ctx->codec->sequence_params_size > 0) {
2917 ctx->codec_sequence_params =2375 ctx->codec_sequence_params =
@@ -2966,11 +2424,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 48 unmodified lines
2966 // check vaSyncBuffer function2424 // check vaSyncBuffer function
2967 vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);2425 vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
2968 if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {2426 if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2969 ctx->has_sync_buffer_func = 1;2427 base_ctx->async_encode = 1;
2970 ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,2428 base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
2971 sizeof(VAAPIEncodePicture *),2429 sizeof(VAAPIEncodePicture*),
2972 0);2430 0);
2973 if (!ctx->encode_fifo)2431 if (!base_ctx->encode_fifo)
2974 return AVERROR(ENOMEM);2432 return AVERROR(ENOMEM);
2975 }2433 }
2976#endif2434#endif
@@ -2983,15 +2441,16 @@ fail: · 6 unmodified lines
2983 2441
2984av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)2442av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
2985{2443{
2986 VAAPIEncodeContext *ctx = avctx->priv_data;2444 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
2987 VAAPIEncodePicture *pic, *next;2445 VAAPIEncodeContext *ctx = avctx->priv_data;
2446 FFHWBaseEncodePicture *pic, *next;
2988 2447
2989 /* We check ctx->frame to know whether ff_vaapi_encode_init()2448 /* We check ctx->frame to know whether ff_vaapi_encode_init()
2990 * has been called and va_config/va_context initialized. */2449 * has been called and va_config/va_context initialized. */
2991 if (!ctx->frame)2450 if (!base_ctx->frame)
2992 return 0;2451 return 0;
2993 2452
2994 for (pic = ctx->pic_start; pic; pic = next) {2453 for (pic = base_ctx->pic_start; pic; pic = next) {
2995 next = pic->next;2454 next = pic->next;
2996 vaapi_encode_free(avctx, pic);2455 vaapi_encode_free(avctx, pic);
2997 }2456 }
@@ -3008,12 +2467,12 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) · 10 unmodified lines
3008 ctx->va_config = VA_INVALID_ID;2467 ctx->va_config = VA_INVALID_ID;
3009 }2468 }
3010 2469
3011 av_frame_free(&ctx->frame);2470 av_frame_free(&base_ctx->frame);
3012 av_packet_free(&ctx->tail_pkt);2471 av_packet_free(&base_ctx->tail_pkt);
3013 2472
3014 av_freep(&ctx->codec_sequence_params);2473 av_freep(&ctx->codec_sequence_params);
3015 av_freep(&ctx->codec_picture_params);2474 av_freep(&ctx->codec_picture_params);
3016 av_fifo_freep2(&ctx->encode_fifo);2475 av_fifo_freep2(&base_ctx->encode_fifo);
3017 2476
3018 av_buffer_unref(&ctx->recon_frames_ref);2477 av_buffer_unref(&ctx->recon_frames_ref);
3019 av_buffer_unref(&ctx->input_frames_ref);2478 av_buffer_unref(&ctx->input_frames_ref);
libavcodec/vaapi_encode.h+1−101
@@ -29,7 +29,6 @@ · 28 unmodified lines
29 29
30#include "libavutil/hwcontext.h"30#include "libavutil/hwcontext.h"
31#include "libavutil/hwcontext_vaapi.h"31#include "libavutil/hwcontext_vaapi.h"
32#include "libavutil/fifo.h"
33 32
34#include "avcodec.h"33#include "avcodec.h"
35#include "hwconfig.h"34#include "hwconfig.h"
@@ -64,16 +63,7 @@ typedef struct VAAPIEncodeSlice { · 28 unmodified lines
64} VAAPIEncodeSlice;63} VAAPIEncodeSlice;
65 64
66typedef struct VAAPIEncodePicture {65typedef struct VAAPIEncodePicture {
67 struct VAAPIEncodePicture *next;66 FFHWBaseEncodePicture base;
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;
77 67
78#if VA_CHECK_VERSION(1, 0, 0)68#if VA_CHECK_VERSION(1, 0, 0)
79 // ROI regions.69 // ROI regions.
@@ -82,15 +72,7 @@ typedef struct VAAPIEncodePicture { · 2 unmodified lines
82 void *roi;72 void *roi;
83#endif73#endif
84 74
85 int type;
86 int b_depth;
87 int encode_issued;
88 int encode_complete;
89
90 AVFrame *input_image;
91 VASurfaceID input_surface;75 VASurfaceID input_surface;
92
93 AVFrame *recon_image;
94 VASurfaceID recon_surface;76 VASurfaceID recon_surface;
95 77
96 int nb_param_buffers;78 int nb_param_buffers;
@@ -100,31 +82,8 @@ typedef struct VAAPIEncodePicture { · 3 unmodified lines
100 VABufferID *output_buffer_ref;82 VABufferID *output_buffer_ref;
101 VABufferID output_buffer;83 VABufferID output_buffer;
102 84
103 void *priv_data;
104 void *codec_picture_params;85 void *codec_picture_params;
105 86
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
128 int nb_slices;87 int nb_slices;
129 VAAPIEncodeSlice *slices;88 VAAPIEncodeSlice *slices;
130 89
@@ -298,30 +257,6 @@ typedef struct VAAPIEncodeContext { · 167 unmodified lines
298 // structure (VAEncPictureParameterBuffer*).257 // structure (VAEncPictureParameterBuffer*).
299 void *codec_picture_params;258 void *codec_picture_params;
300 259
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
325 // Slice structure.260 // Slice structure.
326 int slice_block_rows;261 int slice_block_rows;
327 int slice_block_cols;262 int slice_block_cols;
@@ -340,41 +275,12 @@ typedef struct VAAPIEncodeContext { · 12 unmodified lines
340 // Location of the i-th tile row boundary.275 // Location of the i-th tile row boundary.
341 int row_bd[MAX_TILE_ROWS + 1];276 int row_bd[MAX_TILE_ROWS + 1];
342 277
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;
358 // Maximum number of regions supported by the driver.278 // Maximum number of regions supported by the driver.
359 int roi_max_regions;279 int roi_max_regions;
360 // Quantisation range for offset calculations. Set by codec-specific280 // Quantisation range for offset calculations. Set by codec-specific
361 // code, as it may change based on parameters.281 // code, as it may change based on parameters.
362 int roi_quant_range;282 int roi_quant_range;
363 283
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
378 /** Head data for current output pkt, used only for AV1. */284 /** Head data for current output pkt, used only for AV1. */
379 //void *header_data;285 //void *header_data;
380 //size_t header_data_size;286 //size_t header_data_size;
@@ -384,9 +290,6 @@ typedef struct VAAPIEncodeContext { · 3 unmodified lines
384 * This is a RefStruct reference.290 * This is a RefStruct reference.
385 */291 */
386 VABufferID *coded_buffer_ref;292 VABufferID *coded_buffer_ref;
387
388 /** Tail data of a pic, now only used for av1 repeat frame header. */
389 AVPacket *tail_pkt;
390} VAAPIEncodeContext;293} VAAPIEncodeContext;
391 294
392typedef struct VAAPIEncodeType {295typedef struct VAAPIEncodeType {
@@ -468,9 +371,6 @@ typedef struct VAAPIEncodeType { · 75 unmodified lines
468 char *data, size_t *data_len);371 char *data, size_t *data_len);
469} VAAPIEncodeType;372} VAAPIEncodeType;
470 373
471
472int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
473
474int ff_vaapi_encode_init(AVCodecContext *avctx);374int ff_vaapi_encode_init(AVCodecContext *avctx);
475int ff_vaapi_encode_close(AVCodecContext *avctx);375int ff_vaapi_encode_close(AVCodecContext *avctx);
476 376
libavcodec/vaapi_encode_av1.c+19−16
@@ -360,6 +360,7 @@ static int vaapi_encode_av1_write_sequence_header(AVCodecContext *avctx, · 359 unmodified lines
360 360
361static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)361static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)
362{362{
363 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
363 VAAPIEncodeContext *ctx = avctx->priv_data;364 VAAPIEncodeContext *ctx = avctx->priv_data;
364 VAAPIEncodeAV1Context *priv = avctx->priv_data;365 VAAPIEncodeAV1Context *priv = avctx->priv_data;
365 AV1RawOBU *sh_obu = &priv->sh;366 AV1RawOBU *sh_obu = &priv->sh;
@@ -441,8 +442,8 @@ static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines
441 vseq->seq_level_idx = sh->seq_level_idx[0];442 vseq->seq_level_idx = sh->seq_level_idx[0];
442 vseq->seq_tier = sh->seq_tier[0];443 vseq->seq_tier = sh->seq_tier[0];
443 vseq->order_hint_bits_minus_1 = sh->order_hint_bits_minus_1;444 vseq->order_hint_bits_minus_1 = sh->order_hint_bits_minus_1;
444 vseq->intra_period = ctx->gop_size;445 vseq->intra_period = base_ctx->gop_size;
445 vseq->ip_period = ctx->b_per_p + 1;446 vseq->ip_period = base_ctx->b_per_p + 1;
446 447
447 vseq->seq_fields.bits.enable_order_hint = sh->enable_order_hint;448 vseq->seq_fields.bits.enable_order_hint = sh->enable_order_hint;
448 449
@@ -465,16 +466,17 @@ end: · 16 unmodified lines
465}466}
466 467
467static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,468static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
468 VAAPIEncodePicture *pic)469 VAAPIEncodePicture *vaapi_pic)
469{470{
470 VAAPIEncodeContext *ctx = avctx->priv_data;471 VAAPIEncodeContext *ctx = avctx->priv_data;
471 VAAPIEncodeAV1Context *priv = avctx->priv_data;472 VAAPIEncodeAV1Context *priv = avctx->priv_data;
473 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
472 VAAPIEncodeAV1Picture *hpic = pic->priv_data;474 VAAPIEncodeAV1Picture *hpic = pic->priv_data;
473 AV1RawOBU *fh_obu = &priv->fh;475 AV1RawOBU *fh_obu = &priv->fh;
474 AV1RawFrameHeader *fh = &fh_obu->obu.frame.header;476 AV1RawFrameHeader *fh = &fh_obu->obu.frame.header;
475 VAEncPictureParameterBufferAV1 *vpic = pic->codec_picture_params;477 VAEncPictureParameterBufferAV1 *vpic = vaapi_pic->codec_picture_params;
476 CodedBitstreamFragment *obu = &priv->current_obu;478 CodedBitstreamFragment *obu = &priv->current_obu;
477 VAAPIEncodePicture *ref;479 FFHWBaseEncodePicture *ref;
478 VAAPIEncodeAV1Picture *href;480 VAAPIEncodeAV1Picture *href;
479 int slot, i;481 int slot, i;
480 int ret;482 int ret;
@@ -482,8 +484,8 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 1 unmodified line
482 { 1, 0, 0, 0, -1, 0, -1, -1 };484 { 1, 0, 0, 0, -1, 0, -1, -1 };
483 485
484 memset(fh_obu, 0, sizeof(*fh_obu));486 memset(fh_obu, 0, sizeof(*fh_obu));
485 pic->nb_slices = priv->tile_groups;487 vaapi_pic->nb_slices = priv->tile_groups;
486 pic->non_independent_frame = pic->encode_order < pic->display_order;488 vaapi_pic->non_independent_frame = pic->encode_order < pic->display_order;
487 fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER;489 fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER;
488 fh_obu->header.obu_has_size_field = 1;490 fh_obu->header.obu_has_size_field = 1;
489 491
@@ -601,8 +603,8 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 111 unmodified lines
601 vpic->frame_width_minus_1 = fh->frame_width_minus_1;603 vpic->frame_width_minus_1 = fh->frame_width_minus_1;
602 vpic->frame_height_minus_1 = fh->frame_height_minus_1;604 vpic->frame_height_minus_1 = fh->frame_height_minus_1;
603 vpic->primary_ref_frame = fh->primary_ref_frame;605 vpic->primary_ref_frame = fh->primary_ref_frame;
604 vpic->reconstructed_frame = pic->recon_surface;606 vpic->reconstructed_frame = vaapi_pic->recon_surface;
605 vpic->coded_buf = pic->output_buffer;607 vpic->coded_buf = vaapi_pic->output_buffer;
606 vpic->tile_cols = fh->tile_cols;608 vpic->tile_cols = fh->tile_cols;
607 vpic->tile_rows = fh->tile_rows;609 vpic->tile_rows = fh->tile_rows;
608 vpic->order_hint = fh->order_hint;610 vpic->order_hint = fh->order_hint;
@@ -630,12 +632,12 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 21 unmodified lines
630 632
631 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {633 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
632 for (int j = 0; j < pic->nb_refs[i]; j++) {634 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];
634 636
635 slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot;637 slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot;
636 av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);638 av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);
637 639
638 vpic->reference_frames[slot] = ref_pic->recon_surface;640 vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)->recon_surface;
639 }641 }
640 }642 }
641 643
@@ -752,7 +754,7 @@ static int vaapi_encode_av1_init_slice_params(AVCodecContext *avctx, · 110 unmodified lines
752}754}
753 755
754static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx,756static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx,
755 VAAPIEncodePicture *pic,757 VAAPIEncodePicture *vaapi_pic,
756 char *data, size_t *data_len)758 char *data, size_t *data_len)
757{759{
758 VAAPIEncodeAV1Context *priv = avctx->priv_data;760 VAAPIEncodeAV1Context *priv = avctx->priv_data;
@@ -760,10 +762,11 @@ static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, · 1 unmodified line
760 CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data;762 CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data;
761 AV1RawOBU *fh_obu = &priv->fh;763 AV1RawOBU *fh_obu = &priv->fh;
762 AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header;764 AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header;
765 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
763 VAAPIEncodeAV1Picture *href;766 VAAPIEncodeAV1Picture *href;
764 int ret = 0;767 int ret = 0;
765 768
766 pic->tail_size = 0;769 vaapi_pic->tail_size = 0;
767 /** Pack repeat frame header. */770 /** Pack repeat frame header. */
768 if (pic->display_order > pic->encode_order) {771 if (pic->display_order > pic->encode_order) {
769 memset(fh_obu, 0, sizeof(*fh_obu));772 memset(fh_obu, 0, sizeof(*fh_obu));
@@ -785,11 +788,11 @@ static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, · 15 unmodified lines
785 if (ret < 0)788 if (ret < 0)
786 goto end;789 goto end;
787 790
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);
789 if (ret < 0)792 if (ret < 0)
790 goto end;793 goto end;
791 794
792 pic->tail_size /= 8;795 vaapi_pic->tail_size /= 8;
793 }796 }
794 797
795 memcpy(data, &priv->fh_data, MAX_PARAM_BUFFER_SIZE * sizeof(char));798 memcpy(data, &priv->fh_data, MAX_PARAM_BUFFER_SIZE * sizeof(char));
@@ -1038,7 +1041,7 @@ const FFCodec ff_av1_vaapi_encoder = { · 242 unmodified lines
1038 .p.id = AV_CODEC_ID_AV1,1041 .p.id = AV_CODEC_ID_AV1,
1039 .priv_data_size = sizeof(VAAPIEncodeAV1Context),1042 .priv_data_size = sizeof(VAAPIEncodeAV1Context),
1040 .init = &vaapi_encode_av1_init,1043 .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),
1042 .close = &vaapi_encode_av1_close,1045 .close = &vaapi_encode_av1_close,
1043 .p.priv_class = &vaapi_encode_av1_class,1046 .p.priv_class = &vaapi_encode_av1_class,
1044 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |1047 .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
233 goto fail;233 goto fail;
234 }234 }
235 if (priv->sei_needed & SEI_TIMING) {235 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) {
237 err = ff_cbs_sei_add_message(priv->cbc, au, 1,237 err = ff_cbs_sei_add_message(priv->cbc, au, 1,
238 SEI_TYPE_BUFFERING_PERIOD,238 SEI_TYPE_BUFFERING_PERIOD,
239 &priv->sei_buffering_period, NULL);239 &priv->sei_buffering_period, NULL);
@@ -295,6 +295,7 @@ fail: · 55 unmodified lines
295 295
296static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)296static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
297{297{
298 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
298 VAAPIEncodeContext *ctx = avctx->priv_data;299 VAAPIEncodeContext *ctx = avctx->priv_data;
299 VAAPIEncodeH264Context *priv = avctx->priv_data;300 VAAPIEncodeH264Context *priv = avctx->priv_data;
300 H264RawSPS *sps = &priv->raw_sps;301 H264RawSPS *sps = &priv->raw_sps;
@@ -326,18 +327,18 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 25 unmodified lines
326 sps->constraint_set1_flag = 1;327 sps->constraint_set1_flag = 1;
327 328
328 if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10)329 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;
330 331
331 if (avctx->profile == AV_PROFILE_H264_MAIN ||332 if (avctx->profile == AV_PROFILE_H264_MAIN ||
332 avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) {333 avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) {
333 sps->constraint_set4_flag = 1;334 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;
335 }336 }
336 337
337 if (ctx->gop_size == 1)338 if (base_ctx->gop_size == 1)
338 priv->dpb_frames = 0;339 priv->dpb_frames = 0;
339 else340 else
340 priv->dpb_frames = 1 + ctx->max_b_depth;341 priv->dpb_frames = 1 + base_ctx->max_b_depth;
341 342
342 if (avctx->level != AV_LEVEL_UNKNOWN) {343 if (avctx->level != AV_LEVEL_UNKNOWN) {
343 sps->level_idc = avctx->level;344 sps->level_idc = avctx->level;
@@ -374,7 +375,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 30 unmodified lines
374 sps->bit_depth_chroma_minus8 = bit_depth - 8;375 sps->bit_depth_chroma_minus8 = bit_depth - 8;
375 376
376 sps->log2_max_frame_num_minus4 = 4;377 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;
378 if (sps->pic_order_cnt_type == 0) {379 if (sps->pic_order_cnt_type == 0) {
379 sps->log2_max_pic_order_cnt_lsb_minus4 = 4;380 sps->log2_max_pic_order_cnt_lsb_minus4 = 4;
380 }381 }
@@ -501,8 +502,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 120 unmodified lines
501 sps->vui.motion_vectors_over_pic_boundaries_flag = 1;502 sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
502 sps->vui.log2_max_mv_length_horizontal = 15;503 sps->vui.log2_max_mv_length_horizontal = 15;
503 sps->vui.log2_max_mv_length_vertical = 15;504 sps->vui.log2_max_mv_length_vertical = 15;
504 sps->vui.max_num_reorder_frames = ctx->max_b_depth;505 sps->vui.max_num_reorder_frames = base_ctx->max_b_depth;
505 sps->vui.max_dec_frame_buffering = ctx->max_b_depth + 1;506 sps->vui.max_dec_frame_buffering = base_ctx->max_b_depth + 1;
506 507
507 pps->nal_unit_header.nal_ref_idc = 3;508 pps->nal_unit_header.nal_ref_idc = 3;
508 pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;509 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
535 *vseq = (VAEncSequenceParameterBufferH264) {536 *vseq = (VAEncSequenceParameterBufferH264) {
536 .seq_parameter_set_id = sps->seq_parameter_set_id,537 .seq_parameter_set_id = sps->seq_parameter_set_id,
537 .level_idc = sps->level_idc,538 .level_idc = sps->level_idc,
538 .intra_period = ctx->gop_size,539 .intra_period = base_ctx->gop_size,
539 .intra_idr_period = ctx->gop_size,540 .intra_idr_period = base_ctx->gop_size,
540 .ip_period = ctx->b_per_p + 1,541 .ip_period = base_ctx->b_per_p + 1,
541 542
542 .bits_per_second = ctx->va_bit_rate,543 .bits_per_second = ctx->va_bit_rate,
543 .max_num_ref_frames = sps->max_num_ref_frames,544 .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
619}620}
620 621
621static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,622static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
622 VAAPIEncodePicture *pic)623 VAAPIEncodePicture *vaapi_pic)
623{624{
624 VAAPIEncodeContext *ctx = avctx->priv_data;625 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
625 VAAPIEncodeH264Context *priv = avctx->priv_data;626 VAAPIEncodeH264Context *priv = avctx->priv_data;
627 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
626 VAAPIEncodeH264Picture *hpic = pic->priv_data;628 VAAPIEncodeH264Picture *hpic = pic->priv_data;
627 VAAPIEncodePicture *prev = pic->prev;629 FFHWBaseEncodePicture *prev = pic->prev;
628 VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL;630 VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL;
629 VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;631 VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params;
630 int i, j = 0;632 int i, j = 0;
631 633
632 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {634 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
662 hpic->pic_order_cnt *= 2;664 hpic->pic_order_cnt *= 2;
663 }665 }
664 666
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;
666 hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame;668 hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame;
667 669
668 if (priv->aud) {670 if (priv->aud) {
@@ -699,7 +701,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 30 unmodified lines
699 priv->sei_recovery_point = (H264RawSEIRecoveryPoint) {701 priv->sei_recovery_point = (H264RawSEIRecoveryPoint) {
700 .recovery_frame_cnt = 0,702 .recovery_frame_cnt = 0,
701 .exact_match_flag = 1,703 .exact_match_flag = 1,
702 .broken_link_flag = ctx->b_per_p > 0,704 .broken_link_flag = base_ctx->b_per_p > 0,
703 };705 };
704 706
705 priv->sei_needed |= SEI_RECOVERY_POINT;707 priv->sei_needed |= SEI_RECOVERY_POINT;
@@ -722,7 +724,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 16 unmodified lines
722 }724 }
723 725
724 vpic->CurrPic = (VAPictureH264) {726 vpic->CurrPic = (VAPictureH264) {
725 .picture_id = pic->recon_surface,727 .picture_id = vaapi_pic->recon_surface,
726 .frame_idx = hpic->frame_num,728 .frame_idx = hpic->frame_num,
727 .flags = 0,729 .flags = 0,
728 .TopFieldOrderCnt = hpic->pic_order_cnt,730 .TopFieldOrderCnt = hpic->pic_order_cnt,
@@ -730,14 +732,14 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 1 unmodified line
730 };732 };
731 for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {733 for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {
732 for (i = 0; i < pic->nb_refs[k]; i++) {734 for (i = 0; i < pic->nb_refs[k]; i++) {
733 VAAPIEncodePicture *ref = pic->refs[k][i];735 FFHWBaseEncodePicture *ref = pic->refs[k][i];
734 VAAPIEncodeH264Picture *href;736 VAAPIEncodeH264Picture *href;
735 737
736 av_assert0(ref && ref->encode_order < pic->encode_order);738 av_assert0(ref && ref->encode_order < pic->encode_order);
737 href = ref->priv_data;739 href = ref->priv_data;
738 740
739 vpic->ReferenceFrames[j++] = (VAPictureH264) {741 vpic->ReferenceFrames[j++] = (VAPictureH264) {
740 .picture_id = ref->recon_surface,742 .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface,
741 .frame_idx = href->frame_num,743 .frame_idx = href->frame_num,
742 .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE,744 .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE,
743 .TopFieldOrderCnt = href->pic_order_cnt,745 .TopFieldOrderCnt = href->pic_order_cnt,
@@ -753,7 +755,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 9 unmodified lines
753 };755 };
754 }756 }
755 757
756 vpic->coded_buf = pic->output_buffer;758 vpic->coded_buf = vaapi_pic->output_buffer;
757 759
758 vpic->frame_num = hpic->frame_num;760 vpic->frame_num = hpic->frame_num;
759 761
@@ -764,12 +766,13 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 4 unmodified lines
764}766}
765 767
766static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,768static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,
767 VAAPIEncodePicture *pic,769 VAAPIEncodePicture *vaapi_pic,
768 VAAPIEncodePicture **rpl0,770 VAAPIEncodePicture **rpl0,
769 VAAPIEncodePicture **rpl1,771 VAAPIEncodePicture **rpl1,
770 int *rpl_size)772 int *rpl_size)
771{773{
772 VAAPIEncodePicture *prev;774 FFHWBaseEncodePicture *pic = &vaapi_pic->base;
775 FFHWBaseEncodePicture *prev;
773 VAAPIEncodeH264Picture *hp, *hn, *hc;776 VAAPIEncodeH264Picture *hp, *hn, *hc;
774 int i, j, n = 0;777 int i, j, n = 0;
775 778
@@ -783,17 +786,17 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 7 unmodified lines
783 786
784 if (pic->type == FF_HW_PICTURE_TYPE_P) {787 if (pic->type == FF_HW_PICTURE_TYPE_P) {
785 for (j = n; j > 0; j--) {788 for (j = n; j > 0; j--) {
786 hc = rpl0[j - 1]->priv_data;789 hc = rpl0[j - 1]->base.priv_data;
787 av_assert0(hc->frame_num != hn->frame_num);790 av_assert0(hc->frame_num != hn->frame_num);
788 if (hc->frame_num > hn->frame_num)791 if (hc->frame_num > hn->frame_num)
789 break;792 break;
790 rpl0[j] = rpl0[j - 1];793 rpl0[j] = rpl0[j - 1];
791 }794 }
792 rpl0[j] = prev->dpb[i];795 rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i];
793 796
794 } else if (pic->type == FF_HW_PICTURE_TYPE_B) {797 } else if (pic->type == FF_HW_PICTURE_TYPE_B) {
795 for (j = n; j > 0; j--) {798 for (j = n; j > 0; j--) {
796 hc = rpl0[j - 1]->priv_data;799 hc = rpl0[j - 1]->base.priv_data;
797 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);800 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);
798 if (hc->pic_order_cnt < hp->pic_order_cnt) {801 if (hc->pic_order_cnt < hp->pic_order_cnt) {
799 if (hn->pic_order_cnt > hp->pic_order_cnt ||802 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
805 }808 }
806 rpl0[j] = rpl0[j - 1];809 rpl0[j] = rpl0[j - 1];
807 }810 }
808 rpl0[j] = prev->dpb[i];811 rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i];
809 812
810 for (j = n; j > 0; j--) {813 for (j = n; j > 0; j--) {
811 hc = rpl1[j - 1]->priv_data;814 hc = rpl1[j - 1]->base.priv_data;
812 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);815 av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);
813 if (hc->pic_order_cnt > hp->pic_order_cnt) {816 if (hc->pic_order_cnt > hp->pic_order_cnt) {
814 if (hn->pic_order_cnt < hp->pic_order_cnt ||817 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
820 }823 }
821 rpl1[j] = rpl1[j - 1];824 rpl1[j] = rpl1[j - 1];
822 }825 }
823 rpl1[j] = prev->dpb[i];826 rpl1[j] = (VAAPIEncodePicture *)prev->dpb[i];
824 }827 }
825 828
826 ++n;829 ++n;
@@ -840,7 +843,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 13 unmodified lines
840 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:",843 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:",
841 hp->frame_num, hp->pic_order_cnt);844 hp->frame_num, hp->pic_order_cnt);
842 for (i = 0; i < n; i++) {845 for (i = 0; i < n; i++) {
843 hn = rpl0[i]->priv_data;846 hn = rpl0[i]->base.priv_data;
844 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",847 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",
845 hn->frame_num, hn->pic_order_cnt);848 hn->frame_num, hn->pic_order_cnt);
846 }849 }
@@ -850,7 +853,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 3 unmodified lines
850 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:",853 av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:",
851 hp->frame_num, hp->pic_order_cnt);854 hp->frame_num, hp->pic_order_cnt);
852 for (i = 0; i < n; i++) {855 for (i = 0; i < n; i++) {
853 hn = rpl1[i]->priv_data;856 hn = rpl1[i]->base.priv_data;
854 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",857 av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",
855 hn->frame_num, hn->pic_order_cnt);858 hn->frame_num, hn->pic_order_cnt);
856 }859 }
@@ -861,16 +864,17 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 4 unmodified lines
861}864}
862 865
863static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,866static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
864 VAAPIEncodePicture *pic,867 VAAPIEncodePicture *vaapi_pic,
865 VAAPIEncodeSlice *slice)868 VAAPIEncodeSlice *slice)
866{869{
867 VAAPIEncodeH264Context *priv = avctx->priv_data;870 VAAPIEncodeH264Context *priv = avctx->priv_data;
871 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
868 VAAPIEncodeH264Picture *hpic = pic->priv_data;872 VAAPIEncodeH264Picture *hpic = pic->priv_data;
869 VAAPIEncodePicture *prev = pic->prev;873 FFHWBaseEncodePicture *prev = pic->prev;
870 H264RawSPS *sps = &priv->raw_sps;874 H264RawSPS *sps = &priv->raw_sps;
871 H264RawPPS *pps = &priv->raw_pps;875 H264RawPPS *pps = &priv->raw_pps;
872 H264RawSliceHeader *sh = &priv->raw_slice.header;876 H264RawSliceHeader *sh = &priv->raw_slice.header;
873 VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;877 VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params;
874 VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;878 VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;
875 int i, j;879 int i, j;
876 880
@@ -903,7 +907,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 26 unmodified lines
903 sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);907 sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);
904 908
905 if (pic->is_reference && pic->type != FF_HW_PICTURE_TYPE_IDR) {909 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];
907 int discard = 0, keep = 0;911 int discard = 0, keep = 0;
908 912
909 // Discard everything which is in the DPB of the previous frame but913 // 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
944 VAAPIEncodeH264Picture *href;948 VAAPIEncodeH264Picture *href;
945 int n;949 int n;
946 950
947 vaapi_encode_h264_default_ref_pic_list(avctx, pic,951 vaapi_encode_h264_default_ref_pic_list(avctx, vaapi_pic,
948 def_l0, def_l1, &n);952 def_l0, def_l1, &n);
949 953
950 if (pic->type == FF_HW_PICTURE_TYPE_P) {954 if (pic->type == FF_HW_PICTURE_TYPE_P) {
951 int need_rplm = 0;955 int need_rplm = 0;
952 for (i = 0; i < pic->nb_refs[0]; i++) {956 for (i = 0; i < pic->nb_refs[0]; i++) {
953 av_assert0(pic->refs[0][i]);957 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])
955 need_rplm = 1;959 need_rplm = 1;
956 }960 }
957 961
@@ -982,7 +986,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 24 unmodified lines
982 av_assert0(pic->refs[0][i]);986 av_assert0(pic->refs[0][i]);
983 href = pic->refs[0][i]->priv_data;987 href = pic->refs[0][i]->priv_data;
984 av_assert0(href->pic_order_cnt < hpic->pic_order_cnt);988 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])
986 need_rplm_l0 = 1;990 need_rplm_l0 = 1;
987 ++n0;991 ++n0;
988 }992 }
@@ -991,7 +995,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 2 unmodified lines
991 av_assert0(pic->refs[1][i]);995 av_assert0(pic->refs[1][i]);
992 href = pic->refs[1][i]->priv_data;996 href = pic->refs[1][i]->priv_data;
993 av_assert0(href->pic_order_cnt > hpic->pic_order_cnt);997 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])
995 need_rplm_l1 = 1;999 need_rplm_l1 = 1;
996 ++n1;1000 ++n1;
997 }1001 }
@@ -1380,7 +1384,7 @@ const FFCodec ff_h264_vaapi_encoder = { · 382 unmodified lines
1380 .p.id = AV_CODEC_ID_H264,1384 .p.id = AV_CODEC_ID_H264,
1381 .priv_data_size = sizeof(VAAPIEncodeH264Context),1385 .priv_data_size = sizeof(VAAPIEncodeH264Context),
1382 .init = &vaapi_encode_h264_init,1386 .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),
1384 .close = &vaapi_encode_h264_close,1388 .close = &vaapi_encode_h264_close,
1385 .p.priv_class = &vaapi_encode_h264_class,1389 .p.priv_class = &vaapi_encode_h264_class,
1386 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |1390 .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
260 260
261static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)261static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
262{262{
263 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
263 VAAPIEncodeContext *ctx = avctx->priv_data;264 VAAPIEncodeContext *ctx = avctx->priv_data;
264 VAAPIEncodeH265Context *priv = avctx->priv_data;265 VAAPIEncodeH265Context *priv = avctx->priv_data;
265 H265RawVPS *vps = &priv->raw_vps;266 H265RawVPS *vps = &priv->raw_vps;
@@ -341,7 +342,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines
341 ptl->general_max_420chroma_constraint_flag = chroma_format <= 1;342 ptl->general_max_420chroma_constraint_flag = chroma_format <= 1;
342 ptl->general_max_monochrome_constraint_flag = chroma_format == 0;343 ptl->general_max_monochrome_constraint_flag = chroma_format == 0;
343 344
344 ptl->general_intra_constraint_flag = ctx->gop_size == 1;345 ptl->general_intra_constraint_flag = base_ctx->gop_size == 1;
345 ptl->general_one_picture_only_constraint_flag = 0;346 ptl->general_one_picture_only_constraint_flag = 0;
346 347
347 ptl->general_lower_bit_rate_constraint_flag = 1;348 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
354 level = ff_h265_guess_level(ptl, avctx->bit_rate,355 level = ff_h265_guess_level(ptl, avctx->bit_rate,
355 ctx->surface_width, ctx->surface_height,356 ctx->surface_width, ctx->surface_height,
356 ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,357 ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,
357 (ctx->b_per_p > 0) + 1);358 (base_ctx->b_per_p > 0) + 1);
358 if (level) {359 if (level) {
359 av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);360 av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
360 ptl->general_level_idc = level->level_idc;361 ptl->general_level_idc = level->level_idc;
@@ -368,8 +369,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 7 unmodified lines
368 }369 }
369 370
370 vps->vps_sub_layer_ordering_info_present_flag = 0;371 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_dec_pic_buffering_minus1[0] = base_ctx->max_b_depth + 1;
372 vps->vps_max_num_reorder_pics[0] = ctx->max_b_depth;373 vps->vps_max_num_reorder_pics[0] = base_ctx->max_b_depth;
373 vps->vps_max_latency_increase_plus1[0] = 0;374 vps->vps_max_latency_increase_plus1[0] = 0;
374 375
375 vps->vps_max_layer_id = 0;376 vps->vps_max_layer_id = 0;
@@ -643,9 +644,9 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 267 unmodified lines
643 .general_level_idc = vps->profile_tier_level.general_level_idc,644 .general_level_idc = vps->profile_tier_level.general_level_idc,
644 .general_tier_flag = vps->profile_tier_level.general_tier_flag,645 .general_tier_flag = vps->profile_tier_level.general_tier_flag,
645 646
646 .intra_period = ctx->gop_size,647 .intra_period = base_ctx->gop_size,
647 .intra_idr_period = ctx->gop_size,648 .intra_idr_period = base_ctx->gop_size,
648 .ip_period = ctx->b_per_p + 1,649 .ip_period = base_ctx->b_per_p + 1,
649 .bits_per_second = ctx->va_bit_rate,650 .bits_per_second = ctx->va_bit_rate,
650 651
651 .pic_width_in_luma_samples = sps->pic_width_in_luma_samples,652 .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
756}757}
757 758
758static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,759static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
759 VAAPIEncodePicture *pic)760 VAAPIEncodePicture *vaapi_pic)
760{761{
761 VAAPIEncodeContext *ctx = avctx->priv_data;762 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
762 VAAPIEncodeH265Context *priv = avctx->priv_data;763 VAAPIEncodeH265Context *priv = avctx->priv_data;
764 FFHWBaseEncodePicture *pic = &vaapi_pic->base;
763 VAAPIEncodeH265Picture *hpic = pic->priv_data;765 VAAPIEncodeH265Picture *hpic = pic->priv_data;
764 VAAPIEncodePicture *prev = pic->prev;766 FFHWBaseEncodePicture *prev = pic->prev;
765 VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL;767 VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL;
766 VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;768 VAEncPictureParameterBufferHEVC *vpic = vaapi_pic->codec_picture_params;
767 int i, j = 0;769 int i, j = 0;
768 770
769 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {771 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
788 hpic->slice_type = HEVC_SLICE_P;790 hpic->slice_type = HEVC_SLICE_P;
789 hpic->pic_type = 1;791 hpic->pic_type = 1;
790 } else {792 } else {
791 VAAPIEncodePicture *irap_ref;793 FFHWBaseEncodePicture *irap_ref;
792 av_assert0(pic->refs[0][0] && pic->refs[1][0]);794 av_assert0(pic->refs[0][0] && pic->refs[1][0]);
793 for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) {795 for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) {
794 if (irap_ref->type == FF_HW_PICTURE_TYPE_I)796 if (irap_ref->type == FF_HW_PICTURE_TYPE_I)
795 break;797 break;
796 }798 }
797 if (pic->b_depth == ctx->max_b_depth) {799 if (pic->b_depth == base_ctx->max_b_depth) {
798 hpic->slice_nal_unit = irap_ref ? HEVC_NAL_RASL_N800 hpic->slice_nal_unit = irap_ref ? HEVC_NAL_RASL_N
799 : HEVC_NAL_TRAIL_N;801 : HEVC_NAL_TRAIL_N;
800 } else {802 } else {
@@ -910,21 +912,21 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 109 unmodified lines
910 }912 }
911 913
912 vpic->decoded_curr_pic = (VAPictureHEVC) {914 vpic->decoded_curr_pic = (VAPictureHEVC) {
913 .picture_id = pic->recon_surface,915 .picture_id = vaapi_pic->recon_surface,
914 .pic_order_cnt = hpic->pic_order_cnt,916 .pic_order_cnt = hpic->pic_order_cnt,
915 .flags = 0,917 .flags = 0,
916 };918 };
917 919
918 for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {920 for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {
919 for (i = 0; i < pic->nb_refs[k]; i++) {921 for (i = 0; i < pic->nb_refs[k]; i++) {
920 VAAPIEncodePicture *ref = pic->refs[k][i];922 FFHWBaseEncodePicture *ref = pic->refs[k][i];
921 VAAPIEncodeH265Picture *href;923 VAAPIEncodeH265Picture *href;
922 924
923 av_assert0(ref && ref->encode_order < pic->encode_order);925 av_assert0(ref && ref->encode_order < pic->encode_order);
924 href = ref->priv_data;926 href = ref->priv_data;
925 927
926 vpic->reference_frames[j++] = (VAPictureHEVC) {928 vpic->reference_frames[j++] = (VAPictureHEVC) {
927 .picture_id = ref->recon_surface,929 .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface,
928 .pic_order_cnt = href->pic_order_cnt,930 .pic_order_cnt = href->pic_order_cnt,
929 .flags = (ref->display_order < pic->display_order ?931 .flags = (ref->display_order < pic->display_order ?
930 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) |932 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
941 };943 };
942 }944 }
943 945
944 vpic->coded_buf = pic->output_buffer;946 vpic->coded_buf = vaapi_pic->output_buffer;
945 947
946 vpic->nal_unit_type = hpic->slice_nal_unit;948 vpic->nal_unit_type = hpic->slice_nal_unit;
947 949
@@ -971,16 +973,17 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 23 unmodified lines
971}973}
972 974
973static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,975static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
974 VAAPIEncodePicture *pic,976 VAAPIEncodePicture *vaapi_pic,
975 VAAPIEncodeSlice *slice)977 VAAPIEncodeSlice *slice)
976{978{
977 VAAPIEncodeContext *ctx = avctx->priv_data;979 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
978 VAAPIEncodeH265Context *priv = avctx->priv_data;980 VAAPIEncodeH265Context *priv = avctx->priv_data;
981 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
979 VAAPIEncodeH265Picture *hpic = pic->priv_data;982 VAAPIEncodeH265Picture *hpic = pic->priv_data;
980 const H265RawSPS *sps = &priv->raw_sps;983 const H265RawSPS *sps = &priv->raw_sps;
981 const H265RawPPS *pps = &priv->raw_pps;984 const H265RawPPS *pps = &priv->raw_pps;
982 H265RawSliceHeader *sh = &priv->raw_slice.header;985 H265RawSliceHeader *sh = &priv->raw_slice.header;
983 VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;986 VAEncPictureParameterBufferHEVC *vpic = vaapi_pic->codec_picture_params;
984 VAEncSliceParameterBufferHEVC *vslice = slice->codec_slice_params;987 VAEncSliceParameterBufferHEVC *vslice = slice->codec_slice_params;
985 int i;988 int i;
986 989
@@ -997,7 +1000,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 10 unmodified lines
997 1000
998 sh->slice_type = hpic->slice_type;1001 sh->slice_type = hpic->slice_type;
999 1002
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)
1001 sh->slice_type = HEVC_SLICE_B;1004 sh->slice_type = HEVC_SLICE_B;
1002 1005
1003 sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt &1006 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
1141 .slice_tc_offset_div2 = sh->slice_tc_offset_div2,1144 .slice_tc_offset_div2 = sh->slice_tc_offset_div2,
1142 1145
1143 .slice_fields.bits = {1146 .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,
1145 .dependent_slice_segment_flag = sh->dependent_slice_segment_flag,1148 .dependent_slice_segment_flag = sh->dependent_slice_segment_flag,
1146 .colour_plane_id = sh->colour_plane_id,1149 .colour_plane_id = sh->colour_plane_id,
1147 .slice_temporal_mvp_enabled_flag =1150 .slice_temporal_mvp_enabled_flag =
@@ -1172,7 +1175,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 24 unmodified lines
1172 av_assert0(pic->type == FF_HW_PICTURE_TYPE_P ||1175 av_assert0(pic->type == FF_HW_PICTURE_TYPE_P ||
1173 pic->type == FF_HW_PICTURE_TYPE_B);1176 pic->type == FF_HW_PICTURE_TYPE_B);
1174 vslice->ref_pic_list0[0] = vpic->reference_frames[0];1177 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)
1176 // Reference for GPB B-frame, L0 == L11179 // Reference for GPB B-frame, L0 == L1
1177 vslice->ref_pic_list1[0] = vpic->reference_frames[0];1180 vslice->ref_pic_list1[0] = vpic->reference_frames[0];
1178 }1181 }
@@ -1182,7 +1185,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 3 unmodified lines
1182 vslice->ref_pic_list1[0] = vpic->reference_frames[1];1185 vslice->ref_pic_list1[0] = vpic->reference_frames[1];
1183 }1186 }
1184 1187
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) {
1186 vslice->slice_type = HEVC_SLICE_B;1189 vslice->slice_type = HEVC_SLICE_B;
1187 for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {1190 for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
1188 vslice->ref_pic_list1[i].picture_id = vslice->ref_pic_list0[i].picture_id;1191 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
1495 .p.id = AV_CODEC_ID_HEVC,1498 .p.id = AV_CODEC_ID_HEVC,
1496 .priv_data_size = sizeof(VAAPIEncodeH265Context),1499 .priv_data_size = sizeof(VAAPIEncodeH265Context),
1497 .init = &vaapi_encode_h265_init,1500 .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),
1499 .close = &vaapi_encode_h265_close,1502 .close = &vaapi_encode_h265_close,
1500 .p.priv_class = &vaapi_encode_h265_class,1503 .p.priv_class = &vaapi_encode_h265_class,
1501 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |1504 .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
220}220}
221 221
222static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,222static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
223 VAAPIEncodePicture *pic)223 VAAPIEncodePicture *vaapi_pic)
224{224{
225 VAAPIEncodeMJPEGContext *priv = avctx->priv_data;225 VAAPIEncodeMJPEGContext *priv = avctx->priv_data;
226 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
226 JPEGRawFrameHeader *fh = &priv->frame_header;227 JPEGRawFrameHeader *fh = &priv->frame_header;
227 JPEGRawScanHeader *sh = &priv->scan.header;228 JPEGRawScanHeader *sh = &priv->scan.header;
228 VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;229 VAEncPictureParameterBufferJPEG *vpic = vaapi_pic->codec_picture_params;
229 const AVPixFmtDescriptor *desc;230 const AVPixFmtDescriptor *desc;
230 const uint8_t components_rgb[3] = { 'R', 'G', 'B' };231 const uint8_t components_rgb[3] = { 'R', 'G', 'B' };
231 const uint8_t components_yuv[3] = { 1, 2, 3 };232 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
377 378
378 379
379 *vpic = (VAEncPictureParameterBufferJPEG) {380 *vpic = (VAEncPictureParameterBufferJPEG) {
380 .reconstructed_picture = pic->recon_surface,381 .reconstructed_picture = vaapi_pic->recon_surface,
381 .coded_buf = pic->output_buffer,382 .coded_buf = vaapi_pic->output_buffer,
382 383
383 .picture_width = fh->X,384 .picture_width = fh->X,
384 .picture_height = fh->Y,385 .picture_height = fh->Y,
@@ -406,7 +407,7 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, · 21 unmodified lines
406 vpic->quantiser_table_selector[i] = fh->Tq[i];407 vpic->quantiser_table_selector[i] = fh->Tq[i];
407 }408 }
408 409
409 pic->nb_slices = 1;410 vaapi_pic->nb_slices = 1;
410 411
411 return 0;412 return 0;
412}413}
@@ -572,7 +573,7 @@ const FFCodec ff_mjpeg_vaapi_encoder = { · 159 unmodified lines
572 .p.id = AV_CODEC_ID_MJPEG,573 .p.id = AV_CODEC_ID_MJPEG,
573 .priv_data_size = sizeof(VAAPIEncodeMJPEGContext),574 .priv_data_size = sizeof(VAAPIEncodeMJPEGContext),
574 .init = &vaapi_encode_mjpeg_init,575 .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),
576 .close = &vaapi_encode_mjpeg_close,577 .close = &vaapi_encode_mjpeg_close,
577 .p.priv_class = &vaapi_encode_mjpeg_class,578 .p.priv_class = &vaapi_encode_mjpeg_class,
578 .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1 |579 .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
166 166
167static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)167static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
168{168{
169 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
169 VAAPIEncodeContext *ctx = avctx->priv_data;170 VAAPIEncodeContext *ctx = avctx->priv_data;
170 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;171 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
171 MPEG2RawSequenceHeader *sh = &priv->sequence_header;172 MPEG2RawSequenceHeader *sh = &priv->sequence_header;
@@ -281,7 +282,7 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 109 unmodified lines
281 282
282 se->bit_rate_extension = priv->bit_rate >> 18;283 se->bit_rate_extension = priv->bit_rate >> 18;
283 se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10;284 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;
285 286
286 se->frame_rate_extension_n = ext_n;287 se->frame_rate_extension_n = ext_n;
287 se->frame_rate_extension_d = ext_d;288 se->frame_rate_extension_d = ext_d;
@@ -353,8 +354,8 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 65 unmodified lines
353 354
354 355
355 *vseq = (VAEncSequenceParameterBufferMPEG2) {356 *vseq = (VAEncSequenceParameterBufferMPEG2) {
356 .intra_period = ctx->gop_size,357 .intra_period = base_ctx->gop_size,
357 .ip_period = ctx->b_per_p + 1,358 .ip_period = base_ctx->b_per_p + 1,
358 359
359 .picture_width = avctx->width,360 .picture_width = avctx->width,
360 .picture_height = avctx->height,361 .picture_height = avctx->height,
@@ -417,12 +418,13 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 56 unmodified lines
417}418}
418 419
419static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,420static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
420 VAAPIEncodePicture *pic)421 VAAPIEncodePicture *vaapi_pic)
421{422{
422 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;423 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
424 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
423 MPEG2RawPictureHeader *ph = &priv->picture_header;425 MPEG2RawPictureHeader *ph = &priv->picture_header;
424 MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding;426 MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding;
425 VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;427 VAEncPictureParameterBufferMPEG2 *vpic = vaapi_pic->codec_picture_params;
426 428
427 if (pic->type == FF_HW_PICTURE_TYPE_IDR || pic->type == FF_HW_PICTURE_TYPE_I) {429 if (pic->type == FF_HW_PICTURE_TYPE_IDR || pic->type == FF_HW_PICTURE_TYPE_I) {
428 ph->temporal_reference = 0;430 ph->temporal_reference = 0;
@@ -448,8 +450,8 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 19 unmodified lines
448 pce->f_code[1][1] = 15;450 pce->f_code[1][1] = 15;
449 }451 }
450 452
451 vpic->reconstructed_picture = pic->recon_surface;453 vpic->reconstructed_picture = vaapi_pic->recon_surface;
452 vpic->coded_buf = pic->output_buffer;454 vpic->coded_buf = vaapi_pic->output_buffer;
453 455
454 switch (pic->type) {456 switch (pic->type) {
455 case FF_HW_PICTURE_TYPE_IDR:457 case FF_HW_PICTURE_TYPE_IDR:
@@ -458,12 +460,12 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 2 unmodified lines
458 break;460 break;
459 case FF_HW_PICTURE_TYPE_P:461 case FF_HW_PICTURE_TYPE_P:
460 vpic->picture_type = VAEncPictureTypePredictive;462 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;
462 break;464 break;
463 case FF_HW_PICTURE_TYPE_B:465 case FF_HW_PICTURE_TYPE_B:
464 vpic->picture_type = VAEncPictureTypeBidirectional;466 vpic->picture_type = VAEncPictureTypeBidirectional;
465 vpic->forward_reference_picture = pic->refs[0][0]->recon_surface;467 vpic->forward_reference_picture = ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface;
466 vpic->backward_reference_picture = pic->refs[1][0]->recon_surface;468 vpic->backward_reference_picture = ((VAAPIEncodePicture *)pic->refs[1][0])->recon_surface;
467 break;469 break;
468 default:470 default:
469 av_assert0(0 && "invalid picture type");471 av_assert0(0 && "invalid picture type");
@@ -479,11 +481,12 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 9 unmodified lines
479}481}
480 482
481static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,483static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,
482 VAAPIEncodePicture *pic,484 VAAPIEncodePicture *vaapi_pic,
483 VAAPIEncodeSlice *slice)485 VAAPIEncodeSlice *slice)
484{486{
485 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;487 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
486 VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;488 VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
489 VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;
487 int qp;490 int qp;
488 491
489 vslice->macroblock_address = slice->block_start;492 vslice->macroblock_address = slice->block_start;
@@ -695,7 +698,7 @@ const FFCodec ff_mpeg2_vaapi_encoder = { · 205 unmodified lines
695 .p.id = AV_CODEC_ID_MPEG2VIDEO,698 .p.id = AV_CODEC_ID_MPEG2VIDEO,
696 .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),699 .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),
697 .init = &vaapi_encode_mpeg2_init,700 .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),
699 .close = &vaapi_encode_mpeg2_close,702 .close = &vaapi_encode_mpeg2_close,
700 .p.priv_class = &vaapi_encode_mpeg2_class,703 .p.priv_class = &vaapi_encode_mpeg2_class,
701 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |704 .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
52 52
53static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)53static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
54{54{
55 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
55 VAAPIEncodeContext *ctx = avctx->priv_data;56 VAAPIEncodeContext *ctx = avctx->priv_data;
56 VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params;57 VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params;
57 58
@@ -66,22 +67,23 @@ static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) · 8 unmodified lines
66 67
67 if (!(ctx->va_rc_mode & VA_RC_CQP)) {68 if (!(ctx->va_rc_mode & VA_RC_CQP)) {
68 vseq->bits_per_second = ctx->va_bit_rate;69 vseq->bits_per_second = ctx->va_bit_rate;
69 vseq->intra_period = ctx->gop_size;70 vseq->intra_period = base_ctx->gop_size;
70 }71 }
71 72
72 return 0;73 return 0;
73}74}
74 75
75static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx,76static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx,
76 VAAPIEncodePicture *pic)77 VAAPIEncodePicture *vaapi_pic)
77{78{
79 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
78 VAAPIEncodeVP8Context *priv = avctx->priv_data;80 VAAPIEncodeVP8Context *priv = avctx->priv_data;
79 VAEncPictureParameterBufferVP8 *vpic = pic->codec_picture_params;81 VAEncPictureParameterBufferVP8 *vpic = vaapi_pic->codec_picture_params;
80 int i;82 int i;
81 83
82 vpic->reconstructed_frame = pic->recon_surface;84 vpic->reconstructed_frame = vaapi_pic->recon_surface;
83 85
84 vpic->coded_buf = pic->output_buffer;86 vpic->coded_buf = vaapi_pic->output_buffer;
85 87
86 switch (pic->type) {88 switch (pic->type) {
87 case FF_HW_PICTURE_TYPE_IDR:89 case FF_HW_PICTURE_TYPE_IDR:
@@ -101,7 +103,7 @@ static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, · 13 unmodified lines
101 vpic->ref_last_frame =103 vpic->ref_last_frame =
102 vpic->ref_gf_frame =104 vpic->ref_gf_frame =
103 vpic->ref_arf_frame =105 vpic->ref_arf_frame =
104 pic->refs[0][0]->recon_surface;106 ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface;
105 break;107 break;
106 default:108 default:
107 av_assert0(0 && "invalid picture type");109 av_assert0(0 && "invalid picture type");
@@ -145,7 +147,7 @@ static int vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx, · 37 unmodified lines
145 147
146 memset(&quant, 0, sizeof(quant));148 memset(&quant, 0, sizeof(quant));
147 149
148 if (pic->type == FF_HW_PICTURE_TYPE_P)150 if (pic->base.type == FF_HW_PICTURE_TYPE_P)
149 q = priv->q_index_p;151 q = priv->q_index_p;
150 else152 else
151 q = priv->q_index_i;153 q = priv->q_index_i;
@@ -250,7 +252,7 @@ const FFCodec ff_vp8_vaapi_encoder = { · 98 unmodified lines
250 .p.id = AV_CODEC_ID_VP8,252 .p.id = AV_CODEC_ID_VP8,
251 .priv_data_size = sizeof(VAAPIEncodeVP8Context),253 .priv_data_size = sizeof(VAAPIEncodeVP8Context),
252 .init = &vaapi_encode_vp8_init,254 .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),
254 .close = &ff_vaapi_encode_close,256 .close = &ff_vaapi_encode_close,
255 .p.priv_class = &vaapi_encode_vp8_class,257 .p.priv_class = &vaapi_encode_vp8_class,
256 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |258 .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
53 53
54static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)54static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)
55{55{
56 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
56 VAAPIEncodeContext *ctx = avctx->priv_data;57 VAAPIEncodeContext *ctx = avctx->priv_data;
57 VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params;58 VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params;
58 VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params;59 VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params;
@@ -64,7 +65,7 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) · 5 unmodified lines
64 65
65 if (!(ctx->va_rc_mode & VA_RC_CQP)) {66 if (!(ctx->va_rc_mode & VA_RC_CQP)) {
66 vseq->bits_per_second = ctx->va_bit_rate;67 vseq->bits_per_second = ctx->va_bit_rate;
67 vseq->intra_period = ctx->gop_size;68 vseq->intra_period = base_ctx->gop_size;
68 }69 }
69 70
70 vpic->frame_width_src = avctx->width;71 vpic->frame_width_src = avctx->width;
@@ -76,17 +77,18 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) · 5 unmodified lines
76}77}
77 78
78static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,79static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
79 VAAPIEncodePicture *pic)80 VAAPIEncodePicture *vaapi_pic)
80{81{
81 VAAPIEncodeContext *ctx = avctx->priv_data;82 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
82 VAAPIEncodeVP9Context *priv = avctx->priv_data;83 VAAPIEncodeVP9Context *priv = avctx->priv_data;
84 const FFHWBaseEncodePicture *pic = &vaapi_pic->base;
83 VAAPIEncodeVP9Picture *hpic = pic->priv_data;85 VAAPIEncodeVP9Picture *hpic = pic->priv_data;
84 VAEncPictureParameterBufferVP9 *vpic = pic->codec_picture_params;86 VAEncPictureParameterBufferVP9 *vpic = vaapi_pic->codec_picture_params;
85 int i;87 int i;
86 int num_tile_columns;88 int num_tile_columns;
87 89
88 vpic->reconstructed_frame = pic->recon_surface;90 vpic->reconstructed_frame = vaapi_pic->recon_surface;
89 vpic->coded_buf = pic->output_buffer;91 vpic->coded_buf = vaapi_pic->output_buffer;
90 92
91 // Maximum width of a tile in units of superblocks is MAX_TILE_WIDTH_B64(64)93 // Maximum width of a tile in units of superblocks is MAX_TILE_WIDTH_B64(64)
92 // So the number of tile columns is related to the width of the picture.94 // 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
107 VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data;109 VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data;
108 av_assert0(href->slot == 0 || href->slot == 1);110 av_assert0(href->slot == 0 || href->slot == 1);
109 111
110 if (ctx->max_b_depth > 0) {112 if (base_ctx->max_b_depth > 0) {
111 hpic->slot = !href->slot;113 hpic->slot = !href->slot;
112 vpic->refresh_frame_flags = 1 << hpic->slot | 0xfc;114 vpic->refresh_frame_flags = 1 << hpic->slot | 0xfc;
113 } else {115 } else {
@@ -127,7 +129,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 13 unmodified lines
127 av_assert0(href0->slot < pic->b_depth + 1 &&129 av_assert0(href0->slot < pic->b_depth + 1 &&
128 href1->slot < pic->b_depth + 1);130 href1->slot < pic->b_depth + 1);
129 131
130 if (pic->b_depth == ctx->max_b_depth) {132 if (pic->b_depth == base_ctx->max_b_depth) {
131 // Unreferenced frame.133 // Unreferenced frame.
132 vpic->refresh_frame_flags = 0x00;134 vpic->refresh_frame_flags = 0x00;
133 hpic->slot = 8;135 hpic->slot = 8;
@@ -159,11 +161,11 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 25 unmodified lines
159 161
160 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {162 for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
161 for (int j = 0; j < pic->nb_refs[i]; j++) {163 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];
163 int slot;165 int slot;
164 slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot;166 slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot;
165 av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);167 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;
167 }169 }
168 }170 }
169 171
@@ -307,7 +309,7 @@ const FFCodec ff_vp9_vaapi_encoder = { · 137 unmodified lines
307 .p.id = AV_CODEC_ID_VP9,309 .p.id = AV_CODEC_ID_VP9,
308 .priv_data_size = sizeof(VAAPIEncodeVP9Context),310 .priv_data_size = sizeof(VAAPIEncodeVP9Context),
309 .init = &vaapi_encode_vp9_init,311 .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),
311 .close = &ff_vaapi_encode_close,313 .close = &ff_vaapi_encode_close,
312 .p.priv_class = &vaapi_encode_vp9_class,314 .p.priv_class = &vaapi_encode_vp9_class,
313 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |315 .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