1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <inttypes.h>
20 #include <string.h>
21
26
29
31
34 int type,
char *
data,
size_t bit_len)
35 {
37 VAStatus vas;
38 VABufferID param_buffer, data_buffer;
39 VAEncPackedHeaderParameterBuffer
params = {
41 .bit_length = bit_len,
42 .has_emulation_bytes = 1,
43 };
44
46
48 VAEncPackedHeaderParameterBufferType,
49 sizeof(params), 1, ¶ms, ¶m_buffer);
50 if (vas != VA_STATUS_SUCCESS) {
52 "for packed header (type %d): %d (%s).\n",
53 type, vas, vaErrorStr(vas));
55 }
57
59 VAEncPackedHeaderDataBufferType,
60 (bit_len + 7) / 8, 1, data, &data_buffer);
61 if (vas != VA_STATUS_SUCCESS) {
63 "for packed header (type %d): %d (%s).\n",
64 type, vas, vaErrorStr(vas));
66 }
68
70 "(%zu bits).\n", type, param_buffer, data_buffer, bit_len);
71 return 0;
72 }
73
77 {
79 VAStatus vas;
81
83
85 type, len, 1, data, &buffer);
86 if (vas != VA_STATUS_SUCCESS) {
88 "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
90 }
92
94 type, buffer);
95 return 0;
96 }
97
100 {
102 VAStatus vas;
103
105
107 // Already waited for this picture.
108 return 0;
109 }
110
114
116 if (vas != VA_STATUS_SUCCESS) {
118 "%d (%s).\n", vas, vaErrorStr(vas));
120 }
121
122 // Input is definitely finished with now.
124
126 return 0;
127 }
128
131 {
134 VAStatus vas;
135 int err, i;
137 size_t bit_len;
138
144 } else {
146 for (i = 0; i < pic->
nb_refs; i++) {
149 }
151 }
152
154 for (i = 0; i < pic->
nb_refs; i++) {
156 // If we are serialised then the references must have already
157 // completed. If not, they must have been issued but need not
158 // have completed yet.
161 else
163 }
164
166
171 }
172
174 if (err < 0) {
177 }
180
182 VAEncCodedBufferType,
185 if (vas != VA_STATUS_SUCCESS) {
187 "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
190 }
193
200 } else {
202 }
203
205
207 // Global parameter buffers are set on the first picture only.
208
211 VAEncMiscParameterBufferType,
214 if (err < 0)
216 }
217 }
218
221 VAEncSequenceParameterBufferType,
224 if (err < 0)
226 }
227
230 if (err < 0) {
232 "parameters: %d.\n", err);
234 }
236 VAEncPictureParameterBufferType,
239 if (err < 0)
241 }
242
245 bit_len = 8 *
sizeof(
data);
247 if (err < 0) {
249 "header: %d.\n", err);
251 }
254 data, bit_len);
255 if (err < 0)
257 }
258 }
259
261 bit_len = 8 *
sizeof(
data);
263 if (err < 0) {
265 "header: %d.\n", err);
267 }
270 data, bit_len);
271 if (err < 0)
273 }
274
276 for (i = 0;; i++) {
280 data, &len);
282 break;
283 if (err < 0) {
285 "buffer %d: %d.\n", i, err);
287 }
288
290 data, len);
291 if (err < 0)
293 }
294 }
295
297 for (i = 0;; i++) {
299 bit_len = 8 *
sizeof(
data);
301 data, &bit_len);
303 break;
304 if (err < 0) {
306 "header %d: %d.\n", i, err);
308 }
309
311 data, bit_len);
312 if (err < 0)
314 }
315 }
316
320 if (!slice) {
323 }
325
331 }
332 }
333
336 if (err < 0) {
338 "parameters: %d.\n", err);
340 }
341 }
342
344 bit_len = 8 *
sizeof(
data);
346 data, &bit_len);
347 if (err < 0) {
349 "header: %d.\n", err);
351 }
354 data, bit_len);
355 if (err < 0)
357 }
358
361 VAEncSliceParameterBufferType,
364 if (err < 0)
366 }
367 }
368
371 if (vas != VA_STATUS_SUCCESS) {
373 "%d (%s).\n", vas, vaErrorStr(vas));
375 goto fail_with_picture;
376 }
377
380 if (vas != VA_STATUS_SUCCESS) {
382 "%d (%s).\n", vas, vaErrorStr(vas));
384 goto fail_with_picture;
385 }
386
388 if (vas != VA_STATUS_SUCCESS) {
390 "%d (%s).\n", vas, vaErrorStr(vas));
392 goto fail_at_end;
393 }
394
396
399 else
400 return 0;
401
402 fail_with_picture:
407 fail_at_end:
410 return err;
411 }
412
415 {
417 VACodedBufferSegment *buf_list, *
buf;
418 VAStatus vas;
419 int err;
420
422 if (err < 0)
423 return err;
424
427 (void**)&buf_list);
428 if (vas != VA_STATUS_SUCCESS) {
430 "%d (%s).\n", vas, vaErrorStr(vas));
433 }
434
435 for (buf = buf_list;
buf; buf = buf->next) {
437 "(status %08x).\n", buf->size, buf->status);
438
440 if (err < 0)
442
443 memcpy(pkt->
data, buf->buf, buf->size);
444 }
445
448
450
452 if (vas != VA_STATUS_SUCCESS) {
454 "%d (%s).\n", vas, vaErrorStr(vas));
457 }
458
461
464 return 0;
465
471 }
472 return err;
473 }
474
477 {
479
481
484 "%"PRId64"/%"PRId64".\n",
486
489 }
490
491 return 0;
492 }
493
495 {
497
499 if (!pic)
501
505
506 return pic;
507 }
508
511 {
512 int i;
513
516
521 }
523
526
527 // Output buffer should already be destroyed.
529
532
534
535 return 0;
536 }
537
540 {
543 int i, err;
544
547 // These two modes are equivalent, except that we wait for
548 // immediate completion on each operation if serialised.
549
550 if (!target) {
551 // No target, nothing to do yet.
552 return 0;
553 }
554
556 // Already done.
557 return 0;
558 }
559
560 pic = target;
561 for (i = 0; i < pic->
nb_refs; i++) {
564 if (err < 0)
565 return err;
566 }
567 }
568
570 if (err < 0)
571 return err;
572
574 int activity;
575
576 do {
577 activity = 0;
580 continue;
581 for (i = 0; i < pic->
nb_refs; i++) {
583 break;
584 }
585 if (i < pic->nb_refs)
586 continue;
588 if (err < 0)
589 return err;
590 activity = 1;
591 }
592 } while(activity);
593
594 if (target) {
596 }
597
598 } else {
600 }
601
602 return 0;
603 }
604
607 {
610 int i;
611
616 *pic_out = pic;
617 return 0;
618 }
619 }
620
622 // First frame is always an IDR frame.
624
626 if (!pic)
628
632
634
635 *pic_out = pic;
636 return 0;
637 }
638
640 if (!pic)
642
647 } else {
650 }
652 } else {
657 }
658 start = end = pic;
659
661 // If that was not an IDR frame, add B-frames display-before and
662 // encode-after it.
663
664 for (i = 0; i < ctx->
b_per_p; i++) {
666 if (!pic)
668
673
677 start = pic;
678 }
679 }
680
681 for (i = 0, pic = start; pic; i++, pic = pic->
next) {
685 else if (pic == end)
687 else
689 }
690
694
696
701 pic->display_order, pic->encode_order);
702 }
704
705 return 0;
706
708 while (start) {
711 start = pic;
712 }
714 }
715
717 {
720
721 // Find the last picture we actually have input for.
724 break;
725 last_pic = pic;
726 }
727
728 if (pic) {
730
732 // Some fixing up is required. Change the type of this
733 // picture to P, then modify preceding B references which
734 // point beyond it to point at it instead.
735
738
739 for (pic = ctx->
pic_start; pic != last_pic; pic = pic->
next) {
742 pic->
refs[1] = last_pic;
743 }
744
747 } else {
748 // We can use the current structure (no references point
749 // beyond the end), but there are unused pics to discard.
750 }
751
752 // Discard all following pics, they will never be used.
753 for (pic = last_pic->
next; pic; pic = next) {
756 }
757
760
761 } else {
762 // Input is available for all pictures, so we don't need to
763 // mangle anything.
764 }
765
771 }
773
774 return 0;
775 }
776
778 {
781 int i;
782
786 break;
787
788 for (pic = old->
next; pic; pic = pic->
next) {
790 continue;
791 for (i = 0; i < pic->
nb_refs; i++) {
792 if (pic->
refs[i] == old) {
793 // We still need this picture because it's referred to
794 // directly by a later one, so it and all following
795 // pictures have to stay.
796 return 0;
797 }
798 }
799 }
800
804 }
805
806 return 0;
807 }
808
810 const AVFrame *input_image,
int *got_packet)
811 {
814 int err;
815
816 if (input_image) {
819
821 if (err) {
823 return err;
824 }
825
830 }
832 if (err < 0)
835 pic->
pts = input_image->
pts;
836
843
845
846 } else {
849 if (err < 0)
852 }
853 }
854
858
861 break;
862
863 // pic can be null here if we don't have a specific target in this
864 // iteration. We might still issue encodes if things can be overlapped,
865 // even though we don't intend to output anything.
866
868 if (err < 0) {
871 }
872
873 if (!pic) {
874 *got_packet = 0;
875 } else {
877 if (err < 0) {
880 }
881
886 pkt->
dts = INT64_MIN;
887 else
889 } else {
892 }
893
894 *got_packet = 1;
895 }
896
898 if (err < 0) {
901 }
902
903 return 0;
904
906 // Unclear what to clean up on failure. There are probably some things we
907 // could do usefully clean up here, but for now just leave them for uninit()
908 // to do instead.
909 return err;
910 }
911
913 {
915 VAStatus vas;
918 VAEntrypoint *entrypoints =
NULL;
919 VAConfigAttrib attr[] = {
920 { VAConfigAttribRateControl },
921 { VAConfigAttribEncMaxRefFrames },
922 };
923
926 if (!profiles) {
929 }
930 vas = vaQueryConfigProfiles(ctx->
hwctx->
display, profiles, &n);
931 if (vas != VA_STATUS_SUCCESS) {
933 vas, vaErrorStr(vas));
936 }
937 for (i = 0; i <
n; i++) {
939 break;
940 }
941 if (i >= n) {
946 }
947
950 if (!entrypoints) {
953 }
955 entrypoints, &n);
956 if (vas != VA_STATUS_SUCCESS) {
959 vas, vaErrorStr(vas));
962 }
963 for (i = 0; i <
n; i++) {
965 break;
966 }
967 if (i >= n) {
972 }
973
977 if (vas != VA_STATUS_SUCCESS) {
979 "attributes: %d (%s).\n", vas, vaErrorStr(vas));
981 }
982
984 if (attr[i].
value == VA_ATTRIB_NOT_SUPPORTED) {
985 // Unfortunately we have to treat this as "don't know" and hope
986 // for the best, because the Intel MJPEG encoder returns this
987 // for all the interesting attributes.
988 continue;
989 }
990 switch (attr[i].
type) {
991 case VAConfigAttribRateControl:
994 "supported: %x\n", attr[i].
value);
997 }
998 break;
999 case VAConfigAttribEncMaxRefFrames:
1000 {
1001 unsigned int ref_l0 = attr[i].value & 0xffff;
1002 unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff;
1003
1004 if (avctx->
gop_size > 1 && ref_l0 < 1) {
1006 "supported (%x).\n", attr[i].
value);
1009 }
1012 "supported (%x).\n", attr[i].
value);
1015 }
1016 }
1017 break;
1018 }
1019 }
1020
1021 err = 0;
1025 return err;
1026 }
1027
1030 {
1036 VAStatus vas;
1037 int err, i;
1038
1041 "required to associate the encoding device.\n");
1043 }
1044
1047
1050
1055 }
1056
1061 }
1063
1068 }
1071
1073 if (err < 0)
1075
1077 if (err < 0)
1079
1084 if (vas != VA_STATUS_SUCCESS) {
1086 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1089 }
1090
1092 if (!hwconfig) {
1095 }
1097
1099 hwconfig);
1100 if (!constraints) {
1103 }
1104
1105 // Probably we can use the input surface format as the surface format
1106 // of the reconstructed frames. If not, we just pick the first (only?)
1107 // format in the valid list and hope that it all works.
1114 break;
1115 }
1116 }
1118 // No match. Just use the first in the supported list and
1119 // hope for the best.
1121 }
1122 } else {
1123 // No idea what to use; copy input format.
1125 }
1128
1134 "size %dx%d (constraints: width %d-%d height %d-%d).\n",
1140 }
1141
1144
1149 }
1151
1157
1159 if (err < 0) {
1161 "frame context: %d.\n", err);
1163 }
1165
1168 VA_PROGRESSIVE,
1172 if (vas != VA_STATUS_SUCCESS) {
1174 "context: %d (%s).\n", vas, vaErrorStr(vas));
1177 }
1178
1183
1190 }
1191 }
1198 }
1199 }
1200
1203 if (err < 0) {
1205 "failed: %d.\n", err);
1207 }
1208 }
1209
1210 // All I are IDR for now.
1215
1216 // This should be configurable somehow. (Needs testing on a machine
1217 // where it actually overlaps properly, though.)
1219
1220 return 0;
1221
1226 return err;
1227 }
1228
1230 {
1233
1234 for (pic = ctx->
pic_start; pic; pic = next) {
1237 }
1238
1242 }
1243
1247 }
1248
1251
1254
1258
1260
1261 return 0;
1262 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
VASurfaceID input_surface
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
VAAPI-specific data associated with a frame pool.
This structure describes decoded (raw) audio or video data.
VAAPIEncodeSlice * slices[MAX_PICTURE_SLICES]
VAEntrypoint va_entrypoint
ptrdiff_t const GLvoid * data
static const char * picture_type_name[]
static int vaapi_encode_free(AVCodecContext *avctx, VAAPIEncodePicture *pic)
char codec_options_data[0]
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
int width
The allocated dimensions of the frames in this pool.
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
int(* write_slice_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice, char *data, size_t *data_len)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
void * codec_sequence_params
AVBufferRef * input_frames_ref
size_t picture_params_size
AVHWDeviceContext * device
int max_width
The maximum size of frames in this hw_frames_ctx.
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
static int vaapi_encode_mangle_end(AVCodecContext *avctx)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static av_cold int end(AVCodecContext *avctx)
int(* write_picture_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, char *data, size_t *data_len)
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, const VAAPIEncodeType *type)
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
#define AVERROR_EOF
End of file.
VASurfaceID recon_surface
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]
AVHWFramesContext * input_frames
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
VAAPI hardware pipeline configuration details.
static int vaapi_encode_step(AVCodecContext *avctx, VAAPIEncodePicture *target)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
VAEncMiscParameterBuffer * global_params[MAX_GLOBAL_PARAMS]
simple assert() macros that are a bit more flexible than ISO C assert().
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
int(* init_picture_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic)
void * codec_picture_params
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
int(* write_extra_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
AVHWFramesContext * recon_frames
int flags
A combination of AV_PKT_FLAG values.
int initial_pool_size
Initial size of the frame pool.
static int vaapi_encode_get_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
static int vaapi_encode_make_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t len)
GLsizei GLboolean const GLfloat * value
int(* close)(AVCodecContext *avctx)
struct VAAPIEncodePicture * next
static int vaapi_encode_discard(AVCodecContext *avctx, VAAPIEncodePicture *pic)
void * codec_picture_params
int64_t ts_ring[MAX_REORDER_DELAY *3]
#define FF_ARRAY_ELEMS(a)
VADisplay display
The VADisplay handle, to be filled by the user.
int(* write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len)
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
int min_width
The minimum size of frames in this hw_frames_ctx.
const struct VAAPIEncodeType * codec
Libavcodec external API header.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
VAAPIEncodePicture * pic_start
main external API structure.
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
uint8_t * data
The data buffer.
int(* write_extra_buffer)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len)
static VAAPIEncodePicture * vaapi_encode_alloc(void)
VABufferID param_buffers[MAX_PARAM_BUFFERS]
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
static const AVProfile profiles[]
This struct describes a set or pool of "hardware" frames (i.e.
AVBufferRef * recon_frames_ref
static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
VAAPIEncodePicture * pic_end
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
size_t global_params_size[MAX_GLOBAL_PARAMS]
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
size_t sequence_params_size
static int vaapi_encode_clear_old(AVCodecContext *avctx)
common internal and external API header
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
void * codec_slice_params
int(* init_slice_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice)
static int vaapi_encode_wait(AVCodecContext *avctx, VAAPIEncodePicture *pic)
VAConfigID config_id
ID of a VAAPI pipeline configuration.
int(* init_sequence_params)(AVCodecContext *avctx)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t bit_len)
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
#define av_malloc_array(a, b)
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
AVPixelFormat
Pixel format.
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
int(* init)(AVCodecContext *avctx)
AVVAAPIDeviceContext * hwctx