2 * This file is part of Libav.
4 * Libav 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.
9 * Libav 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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/avassert.h"
23 #include "libavutil/common.h"
24 #include "libavutil/log.h"
25 #include "libavutil/pixdesc.h"
27 #include "vaapi_encode.h"
30 static const char * const picture_type_name
[] = { "IDR", "I", "P", "B" };
32 static int vaapi_encode_make_packed_header(AVCodecContext
*avctx
,
33 VAAPIEncodePicture
*pic
,
34 int type
, char *data
, size_t bit_len
)
36 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
38 VABufferID param_buffer
, data_buffer
;
40 VAEncPackedHeaderParameterBuffer params
= {
42 .bit_length
= bit_len
,
43 .has_emulation_bytes
= 1,
46 tmp
= av_realloc_array(pic
->param_buffers
, sizeof(*tmp
), pic
->nb_param_buffers
+ 2);
48 return AVERROR(ENOMEM
);
49 pic
->param_buffers
= tmp
;
51 vas
= vaCreateBuffer(ctx
->hwctx
->display
, ctx
->va_context
,
52 VAEncPackedHeaderParameterBufferType
,
53 sizeof(params
), 1, ¶ms
, ¶m_buffer
);
54 if (vas
!= VA_STATUS_SUCCESS
) {
55 av_log(avctx
, AV_LOG_ERROR
, "Failed to create parameter buffer "
56 "for packed header (type %d): %d (%s).\n",
57 type
, vas
, vaErrorStr(vas
));
60 pic
->param_buffers
[pic
->nb_param_buffers
++] = param_buffer
;
62 vas
= vaCreateBuffer(ctx
->hwctx
->display
, ctx
->va_context
,
63 VAEncPackedHeaderDataBufferType
,
64 (bit_len
+ 7) / 8, 1, data
, &data_buffer
);
65 if (vas
!= VA_STATUS_SUCCESS
) {
66 av_log(avctx
, AV_LOG_ERROR
, "Failed to create data buffer "
67 "for packed header (type %d): %d (%s).\n",
68 type
, vas
, vaErrorStr(vas
));
71 pic
->param_buffers
[pic
->nb_param_buffers
++] = data_buffer
;
73 av_log(avctx
, AV_LOG_DEBUG
, "Packed header buffer (%d) is %#x/%#x "
74 "(%zu bits).\n", type
, param_buffer
, data_buffer
, bit_len
);
78 static int vaapi_encode_make_param_buffer(AVCodecContext
*avctx
,
79 VAAPIEncodePicture
*pic
,
80 int type
, char *data
, size_t len
)
82 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
87 tmp
= av_realloc_array(pic
->param_buffers
, sizeof(*tmp
), pic
->nb_param_buffers
+ 1);
89 return AVERROR(ENOMEM
);
90 pic
->param_buffers
= tmp
;
92 vas
= vaCreateBuffer(ctx
->hwctx
->display
, ctx
->va_context
,
93 type
, len
, 1, data
, &buffer
);
94 if (vas
!= VA_STATUS_SUCCESS
) {
95 av_log(avctx
, AV_LOG_ERROR
, "Failed to create parameter buffer "
96 "(type %d): %d (%s).\n", type
, vas
, vaErrorStr(vas
));
99 pic
->param_buffers
[pic
->nb_param_buffers
++] = buffer
;
101 av_log(avctx
, AV_LOG_DEBUG
, "Param buffer (%d) is %#x.\n",
106 static int vaapi_encode_wait(AVCodecContext
*avctx
,
107 VAAPIEncodePicture
*pic
)
109 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
112 av_assert0(pic
->encode_issued
);
114 if (pic
->encode_complete
) {
115 // Already waited for this picture.
119 av_log(avctx
, AV_LOG_DEBUG
, "Sync to pic %"PRId64
"/%"PRId64
" "
120 "(input surface %#x).\n", pic
->display_order
,
121 pic
->encode_order
, pic
->input_surface
);
123 vas
= vaSyncSurface(ctx
->hwctx
->display
, pic
->input_surface
);
124 if (vas
!= VA_STATUS_SUCCESS
) {
125 av_log(avctx
, AV_LOG_ERROR
, "Failed to sync to picture completion: "
126 "%d (%s).\n", vas
, vaErrorStr(vas
));
130 // Input is definitely finished with now.
131 av_frame_free(&pic
->input_image
);
133 pic
->encode_complete
= 1;
137 static int vaapi_encode_issue(AVCodecContext
*avctx
,
138 VAAPIEncodePicture
*pic
)
140 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
141 VAAPIEncodeSlice
*slice
;
144 char data
[MAX_PARAM_BUFFER_SIZE
];
147 av_log(avctx
, AV_LOG_DEBUG
, "Issuing encode for pic %"PRId64
"/%"PRId64
" "
148 "as type %s.\n", pic
->display_order
, pic
->encode_order
,
149 picture_type_name
[pic
->type
]);
150 if (pic
->nb_refs
== 0) {
151 av_log(avctx
, AV_LOG_DEBUG
, "No reference pictures.\n");
153 av_log(avctx
, AV_LOG_DEBUG
, "Refers to:");
154 for (i
= 0; i
< pic
->nb_refs
; i
++) {
155 av_log(avctx
, AV_LOG_DEBUG
, " %"PRId64
"/%"PRId64
,
156 pic
->refs
[i
]->display_order
, pic
->refs
[i
]->encode_order
);
158 av_log(avctx
, AV_LOG_DEBUG
, ".\n");
161 av_assert0(pic
->input_available
&& !pic
->encode_issued
);
162 for (i
= 0; i
< pic
->nb_refs
; i
++) {
163 av_assert0(pic
->refs
[i
]);
164 // If we are serialised then the references must have already
165 // completed. If not, they must have been issued but need not
166 // have completed yet.
167 if (ctx
->issue_mode
== ISSUE_MODE_SERIALISE_EVERYTHING
)
168 av_assert0(pic
->refs
[i
]->encode_complete
);
170 av_assert0(pic
->refs
[i
]->encode_issued
);
173 av_log(avctx
, AV_LOG_DEBUG
, "Input surface is %#x.\n", pic
->input_surface
);
175 pic
->recon_image
= av_frame_alloc();
176 if (!pic
->recon_image
) {
177 err
= AVERROR(ENOMEM
);
181 err
= av_hwframe_get_buffer(ctx
->recon_frames_ref
, pic
->recon_image
, 0);
183 err
= AVERROR(ENOMEM
);
186 pic
->recon_surface
= (VASurfaceID
)(uintptr_t)pic
->recon_image
->data
[3];
187 av_log(avctx
, AV_LOG_DEBUG
, "Recon surface is %#x.\n", pic
->recon_surface
);
189 pic
->output_buffer_ref
= av_buffer_pool_get(ctx
->output_buffer_pool
);
190 if (!pic
->output_buffer_ref
) {
191 err
= AVERROR(ENOMEM
);
194 pic
->output_buffer
= (VABufferID
)(uintptr_t)pic
->output_buffer_ref
->data
;
195 av_log(avctx
, AV_LOG_DEBUG
, "Output buffer is %#x.\n",
198 if (ctx
->codec
->picture_params_size
> 0) {
199 pic
->codec_picture_params
= av_malloc(ctx
->codec
->picture_params_size
);
200 if (!pic
->codec_picture_params
)
202 memcpy(pic
->codec_picture_params
, ctx
->codec_picture_params
,
203 ctx
->codec
->picture_params_size
);
205 av_assert0(!ctx
->codec_picture_params
);
208 pic
->nb_param_buffers
= 0;
210 if (pic
->encode_order
== 0) {
211 // Global parameter buffers are set on the first picture only.
213 for (i
= 0; i
< ctx
->nb_global_params
; i
++) {
214 err
= vaapi_encode_make_param_buffer(avctx
, pic
,
215 VAEncMiscParameterBufferType
,
216 (char*)ctx
->global_params
[i
],
217 ctx
->global_params_size
[i
]);
223 if (pic
->type
== PICTURE_TYPE_IDR
&& ctx
->codec
->init_sequence_params
) {
224 err
= vaapi_encode_make_param_buffer(avctx
, pic
,
225 VAEncSequenceParameterBufferType
,
226 ctx
->codec_sequence_params
,
227 ctx
->codec
->sequence_params_size
);
232 if (ctx
->codec
->init_picture_params
) {
233 err
= ctx
->codec
->init_picture_params(avctx
, pic
);
235 av_log(avctx
, AV_LOG_ERROR
, "Failed to initialise picture "
236 "parameters: %d.\n", err
);
239 err
= vaapi_encode_make_param_buffer(avctx
, pic
,
240 VAEncPictureParameterBufferType
,
241 pic
->codec_picture_params
,
242 ctx
->codec
->picture_params_size
);
247 if (pic
->type
== PICTURE_TYPE_IDR
) {
248 if (ctx
->va_packed_headers
& VA_ENC_PACKED_HEADER_SEQUENCE
&&
249 ctx
->codec
->write_sequence_header
) {
250 bit_len
= 8 * sizeof(data
);
251 err
= ctx
->codec
->write_sequence_header(avctx
, data
, &bit_len
);
253 av_log(avctx
, AV_LOG_ERROR
, "Failed to write per-sequence "
254 "header: %d.\n", err
);
257 err
= vaapi_encode_make_packed_header(avctx
, pic
,
258 ctx
->codec
->sequence_header_type
,
265 if (ctx
->va_packed_headers
& VA_ENC_PACKED_HEADER_PICTURE
&&
266 ctx
->codec
->write_picture_header
) {
267 bit_len
= 8 * sizeof(data
);
268 err
= ctx
->codec
->write_picture_header(avctx
, pic
, data
, &bit_len
);
270 av_log(avctx
, AV_LOG_ERROR
, "Failed to write per-picture "
271 "header: %d.\n", err
);
274 err
= vaapi_encode_make_packed_header(avctx
, pic
,
275 ctx
->codec
->picture_header_type
,
281 if (ctx
->codec
->write_extra_buffer
) {
283 size_t len
= sizeof(data
);
285 err
= ctx
->codec
->write_extra_buffer(avctx
, pic
, i
, &type
,
287 if (err
== AVERROR_EOF
)
290 av_log(avctx
, AV_LOG_ERROR
, "Failed to write extra "
291 "buffer %d: %d.\n", i
, err
);
295 err
= vaapi_encode_make_param_buffer(avctx
, pic
, type
,
302 if (ctx
->va_packed_headers
& VA_ENC_PACKED_HEADER_MISC
&&
303 ctx
->codec
->write_extra_header
) {
306 bit_len
= 8 * sizeof(data
);
307 err
= ctx
->codec
->write_extra_header(avctx
, pic
, i
, &type
,
309 if (err
== AVERROR_EOF
)
312 av_log(avctx
, AV_LOG_ERROR
, "Failed to write extra "
313 "header %d: %d.\n", i
, err
);
317 err
= vaapi_encode_make_packed_header(avctx
, pic
, type
,
324 if (pic
->nb_slices
> 0) {
325 pic
->slices
= av_mallocz_array(pic
->nb_slices
, sizeof(*pic
->slices
));
327 err
= AVERROR(ENOMEM
);
331 for (i
= 0; i
< pic
->nb_slices
; i
++) {
332 slice
= &pic
->slices
[i
];
335 if (ctx
->codec
->slice_params_size
> 0) {
336 slice
->codec_slice_params
= av_mallocz(ctx
->codec
->slice_params_size
);
337 if (!slice
->codec_slice_params
) {
338 err
= AVERROR(ENOMEM
);
343 if (ctx
->codec
->init_slice_params
) {
344 err
= ctx
->codec
->init_slice_params(avctx
, pic
, slice
);
346 av_log(avctx
, AV_LOG_ERROR
, "Failed to initalise slice "
347 "parameters: %d.\n", err
);
352 if (ctx
->va_packed_headers
& VA_ENC_PACKED_HEADER_SLICE
&&
353 ctx
->codec
->write_slice_header
) {
354 bit_len
= 8 * sizeof(data
);
355 err
= ctx
->codec
->write_slice_header(avctx
, pic
, slice
,
358 av_log(avctx
, AV_LOG_ERROR
, "Failed to write per-slice "
359 "header: %d.\n", err
);
362 err
= vaapi_encode_make_packed_header(avctx
, pic
,
363 ctx
->codec
->slice_header_type
,
369 if (ctx
->codec
->init_slice_params
) {
370 err
= vaapi_encode_make_param_buffer(avctx
, pic
,
371 VAEncSliceParameterBufferType
,
372 slice
->codec_slice_params
,
373 ctx
->codec
->slice_params_size
);
379 vas
= vaBeginPicture(ctx
->hwctx
->display
, ctx
->va_context
,
381 if (vas
!= VA_STATUS_SUCCESS
) {
382 av_log(avctx
, AV_LOG_ERROR
, "Failed to begin picture encode issue: "
383 "%d (%s).\n", vas
, vaErrorStr(vas
));
385 goto fail_with_picture
;
388 vas
= vaRenderPicture(ctx
->hwctx
->display
, ctx
->va_context
,
389 pic
->param_buffers
, pic
->nb_param_buffers
);
390 if (vas
!= VA_STATUS_SUCCESS
) {
391 av_log(avctx
, AV_LOG_ERROR
, "Failed to upload encode parameters: "
392 "%d (%s).\n", vas
, vaErrorStr(vas
));
394 goto fail_with_picture
;
397 vas
= vaEndPicture(ctx
->hwctx
->display
, ctx
->va_context
);
398 if (vas
!= VA_STATUS_SUCCESS
) {
399 av_log(avctx
, AV_LOG_ERROR
, "Failed to end picture encode issue: "
400 "%d (%s).\n", vas
, vaErrorStr(vas
));
402 // vaRenderPicture() has been called here, so we should not destroy
403 // the parameter buffers unless separate destruction is required.
404 if (HAVE_VAAPI_1
|| ctx
->hwctx
->driver_quirks
&
405 AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
)
411 if (HAVE_VAAPI_1
|| ctx
->hwctx
->driver_quirks
&
412 AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
) {
413 for (i
= 0; i
< pic
->nb_param_buffers
; i
++) {
414 vas
= vaDestroyBuffer(ctx
->hwctx
->display
,
415 pic
->param_buffers
[i
]);
416 if (vas
!= VA_STATUS_SUCCESS
) {
417 av_log(avctx
, AV_LOG_ERROR
, "Failed to destroy "
418 "param buffer %#x: %d (%s).\n",
419 pic
->param_buffers
[i
], vas
, vaErrorStr(vas
));
425 pic
->encode_issued
= 1;
427 if (ctx
->issue_mode
== ISSUE_MODE_SERIALISE_EVERYTHING
)
428 return vaapi_encode_wait(avctx
, pic
);
433 vaEndPicture(ctx
->hwctx
->display
, ctx
->va_context
);
435 for(i
= 0; i
< pic
->nb_param_buffers
; i
++)
436 vaDestroyBuffer(ctx
->hwctx
->display
, pic
->param_buffers
[i
]);
437 for (i
= 0; i
< pic
->nb_slices
; i
++) {
439 av_freep(&pic
->slices
[i
].priv_data
);
440 av_freep(&pic
->slices
[i
].codec_slice_params
);
444 av_freep(&pic
->codec_picture_params
);
445 av_freep(&pic
->param_buffers
);
446 av_freep(&pic
->slices
);
447 av_frame_free(&pic
->recon_image
);
448 av_buffer_unref(&pic
->output_buffer_ref
);
449 pic
->output_buffer
= VA_INVALID_ID
;
453 static int vaapi_encode_output(AVCodecContext
*avctx
,
454 VAAPIEncodePicture
*pic
, AVPacket
*pkt
)
456 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
457 VACodedBufferSegment
*buf_list
, *buf
;
461 err
= vaapi_encode_wait(avctx
, pic
);
466 vas
= vaMapBuffer(ctx
->hwctx
->display
, pic
->output_buffer
,
468 if (vas
!= VA_STATUS_SUCCESS
) {
469 av_log(avctx
, AV_LOG_ERROR
, "Failed to map output buffers: "
470 "%d (%s).\n", vas
, vaErrorStr(vas
));
475 for (buf
= buf_list
; buf
; buf
= buf
->next
) {
476 av_log(avctx
, AV_LOG_DEBUG
, "Output buffer: %u bytes "
477 "(status %08x).\n", buf
->size
, buf
->status
);
479 err
= av_new_packet(pkt
, buf
->size
);
483 memcpy(pkt
->data
, buf
->buf
, buf
->size
);
486 if (pic
->type
== PICTURE_TYPE_IDR
)
487 pkt
->flags
|= AV_PKT_FLAG_KEY
;
491 vas
= vaUnmapBuffer(ctx
->hwctx
->display
, pic
->output_buffer
);
492 if (vas
!= VA_STATUS_SUCCESS
) {
493 av_log(avctx
, AV_LOG_ERROR
, "Failed to unmap output buffers: "
494 "%d (%s).\n", vas
, vaErrorStr(vas
));
499 av_buffer_unref(&pic
->output_buffer_ref
);
500 pic
->output_buffer
= VA_INVALID_ID
;
502 av_log(avctx
, AV_LOG_DEBUG
, "Output read for pic %"PRId64
"/%"PRId64
".\n",
503 pic
->display_order
, pic
->encode_order
);
507 vaUnmapBuffer(ctx
->hwctx
->display
, pic
->output_buffer
);
509 av_buffer_unref(&pic
->output_buffer_ref
);
510 pic
->output_buffer
= VA_INVALID_ID
;
514 static int vaapi_encode_discard(AVCodecContext
*avctx
,
515 VAAPIEncodePicture
*pic
)
517 vaapi_encode_wait(avctx
, pic
);
519 if (pic
->output_buffer_ref
) {
520 av_log(avctx
, AV_LOG_DEBUG
, "Discard output for pic "
521 "%"PRId64
"/%"PRId64
".\n",
522 pic
->display_order
, pic
->encode_order
);
524 av_buffer_unref(&pic
->output_buffer_ref
);
525 pic
->output_buffer
= VA_INVALID_ID
;
531 static VAAPIEncodePicture
*vaapi_encode_alloc(void)
533 VAAPIEncodePicture
*pic
;
535 pic
= av_mallocz(sizeof(*pic
));
539 pic
->input_surface
= VA_INVALID_ID
;
540 pic
->recon_surface
= VA_INVALID_ID
;
541 pic
->output_buffer
= VA_INVALID_ID
;
546 static int vaapi_encode_free(AVCodecContext
*avctx
,
547 VAAPIEncodePicture
*pic
)
551 if (pic
->encode_issued
)
552 vaapi_encode_discard(avctx
, pic
);
554 for (i
= 0; i
< pic
->nb_slices
; i
++) {
556 av_freep(&pic
->slices
[i
].priv_data
);
557 av_freep(&pic
->slices
[i
].codec_slice_params
);
560 av_freep(&pic
->codec_picture_params
);
562 av_frame_free(&pic
->input_image
);
563 av_frame_free(&pic
->recon_image
);
565 av_freep(&pic
->param_buffers
);
566 av_freep(&pic
->slices
);
567 // Output buffer should already be destroyed.
568 av_assert0(pic
->output_buffer
== VA_INVALID_ID
);
570 av_freep(&pic
->priv_data
);
571 av_freep(&pic
->codec_picture_params
);
578 static int vaapi_encode_step(AVCodecContext
*avctx
,
579 VAAPIEncodePicture
*target
)
581 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
582 VAAPIEncodePicture
*pic
;
585 if (ctx
->issue_mode
== ISSUE_MODE_SERIALISE_EVERYTHING
||
586 ctx
->issue_mode
== ISSUE_MODE_MINIMISE_LATENCY
) {
587 // These two modes are equivalent, except that we wait for
588 // immediate completion on each operation if serialised.
591 // No target, nothing to do yet.
595 if (target
->encode_complete
) {
601 for (i
= 0; i
< pic
->nb_refs
; i
++) {
602 if (!pic
->refs
[i
]->encode_complete
) {
603 err
= vaapi_encode_step(avctx
, pic
->refs
[i
]);
609 err
= vaapi_encode_issue(avctx
, pic
);
613 } else if (ctx
->issue_mode
== ISSUE_MODE_MAXIMISE_THROUGHPUT
) {
616 // Run through the list of all available pictures repeatedly
617 // and issue the first one found which has all dependencies
618 // available (including previously-issued but not necessarily
619 // completed pictures).
622 for (pic
= ctx
->pic_start
; pic
; pic
= pic
->next
) {
623 if (!pic
->input_available
|| pic
->encode_issued
)
625 for (i
= 0; i
< pic
->nb_refs
; i
++) {
626 if (!pic
->refs
[i
]->encode_issued
)
629 if (i
< pic
->nb_refs
)
631 err
= vaapi_encode_issue(avctx
, pic
);
635 // Start again from the beginning of the list,
636 // because issuing this picture may have satisfied
637 // forward dependencies of earlier ones.
642 // If we had a defined target for this step then it will
643 // always have been issued by now.
645 av_assert0(target
->encode_issued
&& "broken dependencies?");
655 static int vaapi_encode_get_next(AVCodecContext
*avctx
,
656 VAAPIEncodePicture
**pic_out
)
658 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
659 VAAPIEncodePicture
*start
, *end
, *pic
;
662 for (pic
= ctx
->pic_start
; pic
; pic
= pic
->next
) {
664 av_assert0(pic
->display_order
+ 1 == pic
->next
->display_order
);
665 if (pic
->display_order
== ctx
->input_order
) {
671 pic
= vaapi_encode_alloc();
673 return AVERROR(ENOMEM
);
675 if (ctx
->input_order
== 0 || ctx
->force_idr
||
676 ctx
->gop_counter
>= avctx
->gop_size
) {
677 pic
->type
= PICTURE_TYPE_IDR
;
679 ctx
->gop_counter
= 1;
681 } else if (ctx
->p_counter
>= ctx
->p_per_i
) {
682 pic
->type
= PICTURE_TYPE_I
;
686 pic
->type
= PICTURE_TYPE_P
;
687 pic
->refs
[0] = ctx
->pic_end
;
694 if (pic
->type
!= PICTURE_TYPE_IDR
) {
695 // If that was not an IDR frame, add B-frames display-before and
696 // encode-after it, but not exceeding the GOP size.
698 for (i
= 0; i
< ctx
->b_per_p
&&
699 ctx
->gop_counter
< avctx
->gop_size
; i
++) {
700 pic
= vaapi_encode_alloc();
704 pic
->type
= PICTURE_TYPE_B
;
705 pic
->refs
[0] = ctx
->pic_end
;
710 pic
->display_order
= ctx
->input_order
+ ctx
->b_per_p
- i
- 1;
711 pic
->encode_order
= pic
->display_order
+ 1;
718 if (ctx
->input_order
== 0) {
719 pic
->display_order
= 0;
720 pic
->encode_order
= 0;
722 ctx
->pic_start
= ctx
->pic_end
= pic
;
725 for (i
= 0, pic
= start
; pic
; i
++, pic
= pic
->next
) {
726 pic
->display_order
= ctx
->input_order
+ i
;
727 if (end
->type
== PICTURE_TYPE_IDR
)
728 pic
->encode_order
= ctx
->input_order
+ i
;
730 pic
->encode_order
= ctx
->input_order
;
732 pic
->encode_order
= ctx
->input_order
+ i
+ 1;
735 av_assert0(ctx
->pic_end
);
736 ctx
->pic_end
->next
= start
;
741 av_log(avctx
, AV_LOG_DEBUG
, "Pictures:");
742 for (pic
= ctx
->pic_start
; pic
; pic
= pic
->next
) {
743 av_log(avctx
, AV_LOG_DEBUG
, " %s (%"PRId64
"/%"PRId64
")",
744 picture_type_name
[pic
->type
],
745 pic
->display_order
, pic
->encode_order
);
747 av_log(avctx
, AV_LOG_DEBUG
, "\n");
754 vaapi_encode_free(avctx
, start
);
757 return AVERROR(ENOMEM
);
760 static int vaapi_encode_truncate_gop(AVCodecContext
*avctx
)
762 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
763 VAAPIEncodePicture
*pic
, *last_pic
, *next
;
765 // Find the last picture we actually have input for.
766 for (pic
= ctx
->pic_start
; pic
; pic
= pic
->next
) {
767 if (!pic
->input_available
)
773 av_assert0(last_pic
);
775 if (last_pic
->type
== PICTURE_TYPE_B
) {
776 // Some fixing up is required. Change the type of this
777 // picture to P, then modify preceding B references which
778 // point beyond it to point at it instead.
780 last_pic
->type
= PICTURE_TYPE_P
;
781 last_pic
->encode_order
= last_pic
->refs
[1]->encode_order
;
783 for (pic
= ctx
->pic_start
; pic
!= last_pic
; pic
= pic
->next
) {
784 if (pic
->type
== PICTURE_TYPE_B
&&
785 pic
->refs
[1] == last_pic
->refs
[1])
786 pic
->refs
[1] = last_pic
;
789 last_pic
->nb_refs
= 1;
790 last_pic
->refs
[1] = NULL
;
792 // We can use the current structure (no references point
793 // beyond the end), but there are unused pics to discard.
796 // Discard all following pics, they will never be used.
797 for (pic
= last_pic
->next
; pic
; pic
= next
) {
799 vaapi_encode_free(avctx
, pic
);
802 last_pic
->next
= NULL
;
803 ctx
->pic_end
= last_pic
;
806 // Input is available for all pictures, so we don't need to
810 av_log(avctx
, AV_LOG_DEBUG
, "Pictures ending truncated GOP:");
811 for (pic
= ctx
->pic_start
; pic
; pic
= pic
->next
) {
812 av_log(avctx
, AV_LOG_DEBUG
, " %s (%"PRId64
"/%"PRId64
")",
813 picture_type_name
[pic
->type
],
814 pic
->display_order
, pic
->encode_order
);
816 av_log(avctx
, AV_LOG_DEBUG
, "\n");
821 static int vaapi_encode_clear_old(AVCodecContext
*avctx
)
823 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
824 VAAPIEncodePicture
*pic
, *old
;
827 while (ctx
->pic_start
!= ctx
->pic_end
) {
828 old
= ctx
->pic_start
;
829 if (old
->encode_order
> ctx
->output_order
)
832 for (pic
= old
->next
; pic
; pic
= pic
->next
) {
833 if (pic
->encode_complete
)
835 for (i
= 0; i
< pic
->nb_refs
; i
++) {
836 if (pic
->refs
[i
] == old
) {
837 // We still need this picture because it's referred to
838 // directly by a later one, so it and all following
839 // pictures have to stay.
845 pic
= ctx
->pic_start
;
846 ctx
->pic_start
= pic
->next
;
847 vaapi_encode_free(avctx
, pic
);
853 int ff_vaapi_encode2(AVCodecContext
*avctx
, AVPacket
*pkt
,
854 const AVFrame
*input_image
, int *got_packet
)
856 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
857 VAAPIEncodePicture
*pic
;
861 av_log(avctx
, AV_LOG_DEBUG
, "Encode frame: %ux%u (%"PRId64
").\n",
862 input_image
->width
, input_image
->height
, input_image
->pts
);
864 if (input_image
->pict_type
== AV_PICTURE_TYPE_I
) {
865 err
= vaapi_encode_truncate_gop(avctx
);
871 err
= vaapi_encode_get_next(avctx
, &pic
);
873 av_log(avctx
, AV_LOG_ERROR
, "Input setup failed: %d.\n", err
);
877 pic
->input_image
= av_frame_alloc();
878 if (!pic
->input_image
) {
879 err
= AVERROR(ENOMEM
);
882 err
= av_frame_ref(pic
->input_image
, input_image
);
885 pic
->input_surface
= (VASurfaceID
)(uintptr_t)input_image
->data
[3];
886 pic
->pts
= input_image
->pts
;
888 if (ctx
->input_order
== 0)
889 ctx
->first_pts
= pic
->pts
;
890 if (ctx
->input_order
== ctx
->decode_delay
)
891 ctx
->dts_pts_diff
= pic
->pts
- ctx
->first_pts
;
892 if (ctx
->output_delay
> 0)
893 ctx
->ts_ring
[ctx
->input_order
% (3 * ctx
->output_delay
)] = pic
->pts
;
895 pic
->input_available
= 1;
898 if (!ctx
->end_of_stream
) {
899 err
= vaapi_encode_truncate_gop(avctx
);
902 ctx
->end_of_stream
= 1;
908 av_assert0(ctx
->output_order
+ ctx
->output_delay
+ 1 == ctx
->input_order
);
910 for (pic
= ctx
->pic_start
; pic
; pic
= pic
->next
)
911 if (pic
->encode_order
== ctx
->output_order
)
914 // pic can be null here if we don't have a specific target in this
915 // iteration. We might still issue encodes if things can be overlapped,
916 // even though we don't intend to output anything.
918 err
= vaapi_encode_step(avctx
, pic
);
920 av_log(avctx
, AV_LOG_ERROR
, "Encode failed: %d.\n", err
);
927 err
= vaapi_encode_output(avctx
, pic
, pkt
);
929 av_log(avctx
, AV_LOG_ERROR
, "Output failed: %d.\n", err
);
933 if (ctx
->output_delay
== 0) {
935 } else if (ctx
->output_order
< ctx
->decode_delay
) {
936 if (ctx
->ts_ring
[ctx
->output_order
] < INT64_MIN
+ ctx
->dts_pts_diff
)
937 pkt
->dts
= INT64_MIN
;
939 pkt
->dts
= ctx
->ts_ring
[ctx
->output_order
] - ctx
->dts_pts_diff
;
941 pkt
->dts
= ctx
->ts_ring
[(ctx
->output_order
- ctx
->decode_delay
) %
942 (3 * ctx
->output_delay
)];
948 err
= vaapi_encode_clear_old(avctx
);
950 av_log(avctx
, AV_LOG_ERROR
, "List clearing failed: %d.\n", err
);
957 // Unclear what to clean up on failure. There are probably some things we
958 // could do usefully clean up here, but for now just leave them for uninit()
963 static av_cold
int vaapi_encode_config_attributes(AVCodecContext
*avctx
)
965 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
968 VAProfile
*profiles
= NULL
;
969 VAEntrypoint
*entrypoints
= NULL
;
970 VAConfigAttrib attr
[] = {
971 { VAConfigAttribRTFormat
},
972 { VAConfigAttribRateControl
},
973 { VAConfigAttribEncMaxRefFrames
},
974 { VAConfigAttribEncPackedHeaders
},
977 n
= vaMaxNumProfiles(ctx
->hwctx
->display
);
978 profiles
= av_malloc_array(n
, sizeof(VAProfile
));
980 err
= AVERROR(ENOMEM
);
983 vas
= vaQueryConfigProfiles(ctx
->hwctx
->display
, profiles
, &n
);
984 if (vas
!= VA_STATUS_SUCCESS
) {
985 av_log(ctx
, AV_LOG_ERROR
, "Failed to query profiles: %d (%s).\n",
986 vas
, vaErrorStr(vas
));
987 err
= AVERROR(ENOSYS
);
990 for (i
= 0; i
< n
; i
++) {
991 if (profiles
[i
] == ctx
->va_profile
)
995 av_log(ctx
, AV_LOG_ERROR
, "Encoding profile not found (%d).\n",
997 err
= AVERROR(ENOSYS
);
1001 n
= vaMaxNumEntrypoints(ctx
->hwctx
->display
);
1002 entrypoints
= av_malloc_array(n
, sizeof(VAEntrypoint
));
1004 err
= AVERROR(ENOMEM
);
1007 vas
= vaQueryConfigEntrypoints(ctx
->hwctx
->display
, ctx
->va_profile
,
1009 if (vas
!= VA_STATUS_SUCCESS
) {
1010 av_log(ctx
, AV_LOG_ERROR
, "Failed to query entrypoints for "
1011 "profile %u: %d (%s).\n", ctx
->va_profile
,
1012 vas
, vaErrorStr(vas
));
1013 err
= AVERROR(ENOSYS
);
1016 for (i
= 0; i
< n
; i
++) {
1017 if (entrypoints
[i
] == ctx
->va_entrypoint
)
1021 av_log(ctx
, AV_LOG_ERROR
, "Encoding entrypoint not found "
1022 "(%d / %d).\n", ctx
->va_profile
, ctx
->va_entrypoint
);
1023 err
= AVERROR(ENOSYS
);
1027 vas
= vaGetConfigAttributes(ctx
->hwctx
->display
,
1028 ctx
->va_profile
, ctx
->va_entrypoint
,
1029 attr
, FF_ARRAY_ELEMS(attr
));
1030 if (vas
!= VA_STATUS_SUCCESS
) {
1031 av_log(avctx
, AV_LOG_ERROR
, "Failed to fetch config "
1032 "attributes: %d (%s).\n", vas
, vaErrorStr(vas
));
1033 return AVERROR(EINVAL
);
1036 for (i
= 0; i
< FF_ARRAY_ELEMS(attr
); i
++) {
1037 if (attr
[i
].value
== VA_ATTRIB_NOT_SUPPORTED
) {
1038 // Unfortunately we have to treat this as "don't know" and hope
1039 // for the best, because the Intel MJPEG encoder returns this
1040 // for all the interesting attributes.
1043 switch (attr
[i
].type
) {
1044 case VAConfigAttribRTFormat
:
1045 if (!(ctx
->va_rt_format
& attr
[i
].value
)) {
1046 av_log(avctx
, AV_LOG_ERROR
, "Surface RT format %#x "
1047 "is not supported (mask %#x).\n",
1048 ctx
->va_rt_format
, attr
[i
].value
);
1049 err
= AVERROR(EINVAL
);
1052 ctx
->config_attributes
[ctx
->nb_config_attributes
++] =
1054 .type
= VAConfigAttribRTFormat
,
1055 .value
= ctx
->va_rt_format
,
1058 case VAConfigAttribRateControl
:
1059 // Hack for backward compatibility: CBR was the only
1060 // usable RC mode for a long time, so old drivers will
1061 // only have it. Normal default options may now choose
1062 // VBR and then fail, however, so override it here with
1063 // CBR if that is the only supported mode.
1064 if (ctx
->va_rc_mode
== VA_RC_VBR
&&
1065 !(attr
[i
].value
& VA_RC_VBR
) &&
1066 (attr
[i
].value
& VA_RC_CBR
)) {
1067 av_log(avctx
, AV_LOG_WARNING
, "VBR rate control is "
1068 "not supported with this driver version; "
1069 "using CBR instead.\n");
1070 ctx
->va_rc_mode
= VA_RC_CBR
;
1072 if (!(ctx
->va_rc_mode
& attr
[i
].value
)) {
1073 av_log(avctx
, AV_LOG_ERROR
, "Rate control mode %#x "
1074 "is not supported (mask: %#x).\n",
1075 ctx
->va_rc_mode
, attr
[i
].value
);
1076 err
= AVERROR(EINVAL
);
1079 ctx
->config_attributes
[ctx
->nb_config_attributes
++] =
1081 .type
= VAConfigAttribRateControl
,
1082 .value
= ctx
->va_rc_mode
,
1085 case VAConfigAttribEncMaxRefFrames
:
1087 unsigned int ref_l0
= attr
[i
].value
& 0xffff;
1088 unsigned int ref_l1
= (attr
[i
].value
>> 16) & 0xffff;
1090 if (avctx
->gop_size
> 1 && ref_l0
< 1) {
1091 av_log(avctx
, AV_LOG_ERROR
, "P frames are not "
1092 "supported (%#x).\n", attr
[i
].value
);
1093 err
= AVERROR(EINVAL
);
1096 if (avctx
->max_b_frames
> 0 && ref_l1
< 1) {
1097 av_log(avctx
, AV_LOG_ERROR
, "B frames are not "
1098 "supported (%#x).\n", attr
[i
].value
);
1099 err
= AVERROR(EINVAL
);
1104 case VAConfigAttribEncPackedHeaders
:
1105 if (ctx
->va_packed_headers
& ~attr
[i
].value
) {
1106 // This isn't fatal, but packed headers are always
1107 // preferable because they are under our control.
1108 // When absent, the driver is generating them and some
1109 // features may not work (e.g. VUI or SEI in H.264).
1110 av_log(avctx
, AV_LOG_WARNING
, "Warning: some packed "
1111 "headers are not supported (want %#x, got %#x).\n",
1112 ctx
->va_packed_headers
, attr
[i
].value
);
1113 ctx
->va_packed_headers
&= attr
[i
].value
;
1115 ctx
->config_attributes
[ctx
->nb_config_attributes
++] =
1117 .type
= VAConfigAttribEncPackedHeaders
,
1118 .value
= ctx
->va_packed_headers
,
1122 av_assert0(0 && "Unexpected config attribute.");
1128 av_freep(&profiles
);
1129 av_freep(&entrypoints
);
1133 static av_cold
int vaapi_encode_init_rate_control(AVCodecContext
*avctx
)
1135 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1136 int rc_bits_per_second
;
1137 int rc_target_percentage
;
1139 int hrd_buffer_size
;
1140 int hrd_initial_buffer_fullness
;
1143 if (avctx
->rc_buffer_size
)
1144 hrd_buffer_size
= avctx
->rc_buffer_size
;
1146 hrd_buffer_size
= avctx
->bit_rate
;
1147 if (avctx
->rc_initial_buffer_occupancy
)
1148 hrd_initial_buffer_fullness
= avctx
->rc_initial_buffer_occupancy
;
1150 hrd_initial_buffer_fullness
= hrd_buffer_size
* 3 / 4;
1152 if (ctx
->va_rc_mode
== VA_RC_CBR
) {
1153 rc_bits_per_second
= avctx
->bit_rate
;
1154 rc_target_percentage
= 100;
1155 rc_window_size
= 1000;
1157 if (avctx
->rc_max_rate
< avctx
->bit_rate
) {
1158 // Max rate is unset or invalid, just use the normal bitrate.
1159 rc_bits_per_second
= avctx
->bit_rate
;
1160 rc_target_percentage
= 100;
1162 rc_bits_per_second
= avctx
->rc_max_rate
;
1163 rc_target_percentage
= (avctx
->bit_rate
* 100) / rc_bits_per_second
;
1165 rc_window_size
= (hrd_buffer_size
* 1000) / avctx
->bit_rate
;
1168 ctx
->rc_params
.misc
.type
= VAEncMiscParameterTypeRateControl
;
1169 ctx
->rc_params
.rc
= (VAEncMiscParameterRateControl
) {
1170 .bits_per_second
= rc_bits_per_second
,
1171 .target_percentage
= rc_target_percentage
,
1172 .window_size
= rc_window_size
,
1174 .min_qp
= (avctx
->qmin
> 0 ? avctx
->qmin
: 0),
1175 .basic_unit_size
= 0,
1177 ctx
->global_params
[ctx
->nb_global_params
] =
1178 &ctx
->rc_params
.misc
;
1179 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1180 sizeof(ctx
->rc_params
);
1182 ctx
->hrd_params
.misc
.type
= VAEncMiscParameterTypeHRD
;
1183 ctx
->hrd_params
.hrd
= (VAEncMiscParameterHRD
) {
1184 .initial_buffer_fullness
= hrd_initial_buffer_fullness
,
1185 .buffer_size
= hrd_buffer_size
,
1187 ctx
->global_params
[ctx
->nb_global_params
] =
1188 &ctx
->hrd_params
.misc
;
1189 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1190 sizeof(ctx
->hrd_params
);
1192 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0)
1193 av_reduce(&fr_num
, &fr_den
,
1194 avctx
->framerate
.num
, avctx
->framerate
.den
, 65535);
1196 av_reduce(&fr_num
, &fr_den
,
1197 avctx
->time_base
.den
, avctx
->time_base
.num
, 65535);
1199 ctx
->fr_params
.misc
.type
= VAEncMiscParameterTypeFrameRate
;
1200 ctx
->fr_params
.fr
.framerate
= (unsigned int)fr_den
<< 16 | fr_num
;
1202 #if VA_CHECK_VERSION(0, 40, 0)
1203 ctx
->global_params
[ctx
->nb_global_params
] =
1204 &ctx
->fr_params
.misc
;
1205 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1206 sizeof(ctx
->fr_params
);
1212 static void vaapi_encode_free_output_buffer(void *opaque
,
1215 AVCodecContext
*avctx
= opaque
;
1216 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1217 VABufferID buffer_id
;
1219 buffer_id
= (VABufferID
)(uintptr_t)data
;
1221 vaDestroyBuffer(ctx
->hwctx
->display
, buffer_id
);
1223 av_log(avctx
, AV_LOG_DEBUG
, "Freed output buffer %#x\n", buffer_id
);
1226 static AVBufferRef
*vaapi_encode_alloc_output_buffer(void *opaque
,
1229 AVCodecContext
*avctx
= opaque
;
1230 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1231 VABufferID buffer_id
;
1235 // The output buffer size is fixed, so it needs to be large enough
1236 // to hold the largest possible compressed frame. We assume here
1237 // that the uncompressed frame plus some header data is an upper
1239 vas
= vaCreateBuffer(ctx
->hwctx
->display
, ctx
->va_context
,
1240 VAEncCodedBufferType
,
1241 3 * ctx
->surface_width
* ctx
->surface_height
+
1242 (1 << 16), 1, 0, &buffer_id
);
1243 if (vas
!= VA_STATUS_SUCCESS
) {
1244 av_log(avctx
, AV_LOG_ERROR
, "Failed to create bitstream "
1245 "output buffer: %d (%s).\n", vas
, vaErrorStr(vas
));
1249 av_log(avctx
, AV_LOG_DEBUG
, "Allocated output buffer %#x\n", buffer_id
);
1251 ref
= av_buffer_create((uint8_t*)(uintptr_t)buffer_id
,
1253 &vaapi_encode_free_output_buffer
,
1254 avctx
, AV_BUFFER_FLAG_READONLY
);
1256 vaDestroyBuffer(ctx
->hwctx
->display
, buffer_id
);
1263 static av_cold
int vaapi_encode_create_recon_frames(AVCodecContext
*avctx
)
1265 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1266 AVVAAPIHWConfig
*hwconfig
= NULL
;
1267 AVHWFramesConstraints
*constraints
= NULL
;
1268 enum AVPixelFormat recon_format
;
1271 hwconfig
= av_hwdevice_hwconfig_alloc(ctx
->device_ref
);
1273 err
= AVERROR(ENOMEM
);
1276 hwconfig
->config_id
= ctx
->va_config
;
1278 constraints
= av_hwdevice_get_hwframe_constraints(ctx
->device_ref
,
1281 err
= AVERROR(ENOMEM
);
1285 // Probably we can use the input surface format as the surface format
1286 // of the reconstructed frames. If not, we just pick the first (only?)
1287 // format in the valid list and hope that it all works.
1288 recon_format
= AV_PIX_FMT_NONE
;
1289 if (constraints
->valid_sw_formats
) {
1290 for (i
= 0; constraints
->valid_sw_formats
[i
] != AV_PIX_FMT_NONE
; i
++) {
1291 if (ctx
->input_frames
->sw_format
==
1292 constraints
->valid_sw_formats
[i
]) {
1293 recon_format
= ctx
->input_frames
->sw_format
;
1297 if (recon_format
== AV_PIX_FMT_NONE
) {
1298 // No match. Just use the first in the supported list and
1299 // hope for the best.
1300 recon_format
= constraints
->valid_sw_formats
[0];
1303 // No idea what to use; copy input format.
1304 recon_format
= ctx
->input_frames
->sw_format
;
1306 av_log(avctx
, AV_LOG_DEBUG
, "Using %s as format of "
1307 "reconstructed frames.\n", av_get_pix_fmt_name(recon_format
));
1309 if (ctx
->surface_width
< constraints
->min_width
||
1310 ctx
->surface_height
< constraints
->min_height
||
1311 ctx
->surface_width
> constraints
->max_width
||
1312 ctx
->surface_height
> constraints
->max_height
) {
1313 av_log(avctx
, AV_LOG_ERROR
, "Hardware does not support encoding at "
1314 "size %dx%d (constraints: width %d-%d height %d-%d).\n",
1315 ctx
->surface_width
, ctx
->surface_height
,
1316 constraints
->min_width
, constraints
->max_width
,
1317 constraints
->min_height
, constraints
->max_height
);
1318 err
= AVERROR(EINVAL
);
1322 av_freep(&hwconfig
);
1323 av_hwframe_constraints_free(&constraints
);
1325 ctx
->recon_frames_ref
= av_hwframe_ctx_alloc(ctx
->device_ref
);
1326 if (!ctx
->recon_frames_ref
) {
1327 err
= AVERROR(ENOMEM
);
1330 ctx
->recon_frames
= (AVHWFramesContext
*)ctx
->recon_frames_ref
->data
;
1332 ctx
->recon_frames
->format
= AV_PIX_FMT_VAAPI
;
1333 ctx
->recon_frames
->sw_format
= recon_format
;
1334 ctx
->recon_frames
->width
= ctx
->surface_width
;
1335 ctx
->recon_frames
->height
= ctx
->surface_height
;
1336 // At most three IDR/I/P frames and two runs of B frames can be in
1337 // flight at any one time.
1338 ctx
->recon_frames
->initial_pool_size
= 3 + 2 * avctx
->max_b_frames
;
1340 err
= av_hwframe_ctx_init(ctx
->recon_frames_ref
);
1342 av_log(avctx
, AV_LOG_ERROR
, "Failed to initialise reconstructed "
1343 "frame context: %d.\n", err
);
1349 av_freep(&hwconfig
);
1350 av_hwframe_constraints_free(&constraints
);
1354 av_cold
int ff_vaapi_encode_init(AVCodecContext
*avctx
)
1356 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1357 AVVAAPIFramesContext
*recon_hwctx
= NULL
;
1361 if (!avctx
->hw_frames_ctx
) {
1362 av_log(avctx
, AV_LOG_ERROR
, "A hardware frames reference is "
1363 "required to associate the encoding device.\n");
1364 return AVERROR(EINVAL
);
1367 ctx
->codec_options
= ctx
->codec_options_data
;
1369 ctx
->va_config
= VA_INVALID_ID
;
1370 ctx
->va_context
= VA_INVALID_ID
;
1372 ctx
->priv_data
= av_mallocz(ctx
->codec
->priv_data_size
);
1373 if (!ctx
->priv_data
) {
1374 err
= AVERROR(ENOMEM
);
1378 ctx
->input_frames_ref
= av_buffer_ref(avctx
->hw_frames_ctx
);
1379 if (!ctx
->input_frames_ref
) {
1380 err
= AVERROR(ENOMEM
);
1383 ctx
->input_frames
= (AVHWFramesContext
*)ctx
->input_frames_ref
->data
;
1385 ctx
->device_ref
= av_buffer_ref(ctx
->input_frames
->device_ref
);
1386 if (!ctx
->device_ref
) {
1387 err
= AVERROR(ENOMEM
);
1390 ctx
->device
= (AVHWDeviceContext
*)ctx
->device_ref
->data
;
1391 ctx
->hwctx
= ctx
->device
->hwctx
;
1393 err
= vaapi_encode_config_attributes(avctx
);
1397 vas
= vaCreateConfig(ctx
->hwctx
->display
,
1398 ctx
->va_profile
, ctx
->va_entrypoint
,
1399 ctx
->config_attributes
, ctx
->nb_config_attributes
,
1401 if (vas
!= VA_STATUS_SUCCESS
) {
1402 av_log(avctx
, AV_LOG_ERROR
, "Failed to create encode pipeline "
1403 "configuration: %d (%s).\n", vas
, vaErrorStr(vas
));
1408 err
= vaapi_encode_create_recon_frames(avctx
);
1412 recon_hwctx
= ctx
->recon_frames
->hwctx
;
1413 vas
= vaCreateContext(ctx
->hwctx
->display
, ctx
->va_config
,
1414 ctx
->surface_width
, ctx
->surface_height
,
1416 recon_hwctx
->surface_ids
,
1417 recon_hwctx
->nb_surfaces
,
1419 if (vas
!= VA_STATUS_SUCCESS
) {
1420 av_log(avctx
, AV_LOG_ERROR
, "Failed to create encode pipeline "
1421 "context: %d (%s).\n", vas
, vaErrorStr(vas
));
1426 ctx
->output_buffer_pool
=
1427 av_buffer_pool_init2(sizeof(VABufferID
), avctx
,
1428 &vaapi_encode_alloc_output_buffer
, NULL
);
1429 if (!ctx
->output_buffer_pool
) {
1430 err
= AVERROR(ENOMEM
);
1434 if (ctx
->va_rc_mode
& ~VA_RC_CQP
) {
1435 err
= vaapi_encode_init_rate_control(avctx
);
1440 if (ctx
->codec
->configure
) {
1441 err
= ctx
->codec
->configure(avctx
);
1446 if (avctx
->compression_level
>= 0) {
1447 #if VA_CHECK_VERSION(0, 36, 0)
1448 VAConfigAttrib attr
= { VAConfigAttribEncQualityRange
};
1450 vas
= vaGetConfigAttributes(ctx
->hwctx
->display
,
1454 if (vas
!= VA_STATUS_SUCCESS
) {
1455 av_log(avctx
, AV_LOG_WARNING
, "Failed to query quality "
1456 "attribute: will use default compression level.\n");
1458 if (avctx
->compression_level
> attr
.value
) {
1459 av_log(avctx
, AV_LOG_WARNING
, "Invalid compression "
1460 "level: valid range is 0-%d, using %d.\n",
1461 attr
.value
, attr
.value
);
1462 avctx
->compression_level
= attr
.value
;
1465 ctx
->quality_params
.misc
.type
=
1466 VAEncMiscParameterTypeQualityLevel
;
1467 ctx
->quality_params
.quality
.quality_level
=
1468 avctx
->compression_level
;
1470 ctx
->global_params
[ctx
->nb_global_params
] =
1471 &ctx
->quality_params
.misc
;
1472 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1473 sizeof(ctx
->quality_params
);
1476 av_log(avctx
, AV_LOG_WARNING
, "The encode compression level "
1477 "option is not supported with this VAAPI version.\n");
1481 ctx
->input_order
= 0;
1482 ctx
->output_delay
= avctx
->max_b_frames
;
1483 ctx
->decode_delay
= 1;
1484 ctx
->output_order
= - ctx
->output_delay
- 1;
1486 // Currently we never generate I frames, only IDR.
1487 ctx
->p_per_i
= INT_MAX
;
1488 ctx
->b_per_p
= avctx
->max_b_frames
;
1490 if (ctx
->codec
->sequence_params_size
> 0) {
1491 ctx
->codec_sequence_params
=
1492 av_mallocz(ctx
->codec
->sequence_params_size
);
1493 if (!ctx
->codec_sequence_params
) {
1494 err
= AVERROR(ENOMEM
);
1498 if (ctx
->codec
->picture_params_size
> 0) {
1499 ctx
->codec_picture_params
=
1500 av_mallocz(ctx
->codec
->picture_params_size
);
1501 if (!ctx
->codec_picture_params
) {
1502 err
= AVERROR(ENOMEM
);
1507 if (ctx
->codec
->init_sequence_params
) {
1508 err
= ctx
->codec
->init_sequence_params(avctx
);
1510 av_log(avctx
, AV_LOG_ERROR
, "Codec sequence initialisation "
1511 "failed: %d.\n", err
);
1516 // This should be configurable somehow. (Needs testing on a machine
1517 // where it actually overlaps properly, though.)
1518 ctx
->issue_mode
= ISSUE_MODE_MAXIMISE_THROUGHPUT
;
1520 if (ctx
->va_packed_headers
& VA_ENC_PACKED_HEADER_SEQUENCE
&&
1521 ctx
->codec
->write_sequence_header
) {
1522 char data
[MAX_PARAM_BUFFER_SIZE
];
1523 size_t bit_len
= 8 * sizeof(data
);
1525 err
= ctx
->codec
->write_sequence_header(avctx
, data
, &bit_len
);
1527 av_log(avctx
, AV_LOG_ERROR
, "Failed to write sequence header "
1528 "for extradata: %d.\n", err
);
1531 avctx
->extradata_size
= (bit_len
+ 7) / 8;
1532 avctx
->extradata
= av_mallocz(avctx
->extradata_size
+
1533 AV_INPUT_BUFFER_PADDING_SIZE
);
1534 if (!avctx
->extradata
) {
1535 err
= AVERROR(ENOMEM
);
1538 memcpy(avctx
->extradata
, data
, avctx
->extradata_size
);
1545 ff_vaapi_encode_close(avctx
);
1549 av_cold
int ff_vaapi_encode_close(AVCodecContext
*avctx
)
1551 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1552 VAAPIEncodePicture
*pic
, *next
;
1554 for (pic
= ctx
->pic_start
; pic
; pic
= next
) {
1556 vaapi_encode_free(avctx
, pic
);
1559 av_buffer_pool_uninit(&ctx
->output_buffer_pool
);
1561 if (ctx
->va_context
!= VA_INVALID_ID
) {
1562 vaDestroyContext(ctx
->hwctx
->display
, ctx
->va_context
);
1563 ctx
->va_context
= VA_INVALID_ID
;
1566 if (ctx
->va_config
!= VA_INVALID_ID
) {
1567 vaDestroyConfig(ctx
->hwctx
->display
, ctx
->va_config
);
1568 ctx
->va_config
= VA_INVALID_ID
;
1571 av_freep(&ctx
->codec_sequence_params
);
1572 av_freep(&ctx
->codec_picture_params
);
1574 av_buffer_unref(&ctx
->recon_frames_ref
);
1575 av_buffer_unref(&ctx
->input_frames_ref
);
1576 av_buffer_unref(&ctx
->device_ref
);
1578 av_freep(&ctx
->priv_data
);