22 # include <va/va_x11.h>
25 # include <va/va_drm.h>
80 #define MAP(va, rt, av) { \
82 VA_RT_FORMAT_ ## rt, \
92 MAP(NV12, YUV420, NV12),
93 MAP(YV12, YUV420, YUV420P),
94 MAP(IYUV, YUV420, YUV420P),
97 MAP(YV16, YUV422, YUV422P),
99 MAP(422
H, YUV422, YUV422P),
100 MAP(UYVY, YUV422, UYVY422),
101 MAP(YUY2, YUV422, YUYV422),
102 MAP(Y800, YUV400, GRAY8),
103 #ifdef VA_FOURCC_P010
104 MAP(P010, YUV420_10BPP, P010),
106 MAP(BGRA, RGB32, BGRA),
107 MAP(BGRX, RGB32, BGR0),
109 MAP(RGBX, RGB32, RGB0),
110 #ifdef VA_FOURCC_ABGR
111 MAP(ABGR, RGB32, ABGR),
112 MAP(XBGR, RGB32, 0BGR),
114 MAP(ARGB, RGB32, ARGB),
115 MAP(XRGB, RGB32, 0RGB),
130 VAImageFormat **image_format)
146 const void *hwconfig,
152 VASurfaceAttrib *attr_list =
NULL;
156 int err, i, j, attr_count, pix_fmt_count;
162 if (vas != VA_STATUS_SUCCESS) {
164 "%d (%s).\n", vas, vaErrorStr(vas));
169 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
176 attr_list, &attr_count);
177 if (vas != VA_STATUS_SUCCESS) {
179 "%d (%s).\n", vas, vaErrorStr(vas));
185 for (i = 0; i < attr_count; i++) {
186 switch (attr_list[i].
type) {
187 case VASurfaceAttribPixelFormat:
188 fourcc = attr_list[i].value.value.i;
196 case VASurfaceAttribMinWidth:
197 constraints->
min_width = attr_list[i].value.value.i;
199 case VASurfaceAttribMinHeight:
200 constraints->
min_height = attr_list[i].value.value.i;
202 case VASurfaceAttribMaxWidth:
203 constraints->
max_width = attr_list[i].value.value.i;
205 case VASurfaceAttribMaxHeight:
206 constraints->
max_height = attr_list[i].value.value.i;
210 if (pix_fmt_count == 0) {
222 for (i = j = 0; i < attr_count; i++) {
223 if (attr_list[i].
type != VASurfaceAttribPixelFormat)
225 fourcc = attr_list[i].value.value.i;
261 static const struct {
267 "Intel i965 (Quick Sync)",
282 VAImageFormat *image_list =
NULL;
284 const char *vendor_string;
285 int err, i, image_count;
289 image_count = vaMaxNumImageFormats(hwctx->
display);
290 if (image_count <= 0) {
294 image_list =
av_malloc(image_count *
sizeof(*image_list));
299 vas = vaQueryImageFormats(hwctx->
display, image_list, &image_count);
300 if (vas != VA_STATUS_SUCCESS) {
311 for (i = 0; i < image_count; i++) {
312 fourcc = image_list[i].fourcc;
328 "quirks set by user.\n");
331 vendor_string = vaQueryVendorString(hwctx->
display);
335 if (strstr(vendor_string,
338 "driver \"%s\".\n", vendor_string,
347 "assuming standard behaviour.\n", vendor_string);
371 VASurfaceID surface_id;
374 surface_id = (VASurfaceID)(uintptr_t)
data;
376 vas = vaDestroySurfaces(hwctx->
display, &surface_id, 1);
377 if (vas != VA_STATUS_SUCCESS) {
379 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
389 VASurfaceID surface_id;
401 if (vas != VA_STATUS_SUCCESS) {
403 "%d (%s).\n", vas, vaErrorStr(vas));
412 vaDestroySurfaces(hwctx->
display, &surface_id, 1);
432 VAImageFormat *expected_format;
434 VASurfaceID test_surface_id;
455 int need_pixel_format = 1;
457 if (ctx->
attributes[i].type == VASurfaceAttribMemoryType)
458 need_memory_type = 0;
459 if (ctx->
attributes[i].type == VASurfaceAttribPixelFormat)
460 need_pixel_format = 0;
474 if (need_memory_type) {
476 .type = VASurfaceAttribMemoryType,
477 .flags = VA_SURFACE_ATTRIB_SETTABLE,
478 .value.type = VAGenericValueTypeInteger,
479 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
482 if (need_pixel_format) {
484 .type = VASurfaceAttribPixelFormat,
485 .flags = VA_SURFACE_ATTRIB_SETTABLE,
486 .value.type = VAGenericValueTypeInteger,
528 "user-configured buffer pool.\n");
536 "internal buffer pool.\n");
541 test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
548 vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
549 if (vas == VA_STATUS_SUCCESS) {
550 if (expected_format->fourcc == test_image.format.fourcc) {
555 "derived image format %08x does not match "
556 "expected format %08x.\n",
557 expected_format->fourcc, test_image.format.fourcc);
559 vaDestroyImage(hwctx->
display, test_image.image_id);
562 "deriving image does not work: "
563 "%d (%s).\n", vas, vaErrorStr(vas));
567 "image format is not supported.\n");
617 pix_fmts[0] = preferred_format;
637 VASurfaceID surface_id;
640 surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
644 if (vas != VA_STATUS_SUCCESS) {
646 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
651 vas = vaPutImage(hwctx->
display, surface_id, map->
image.image_id,
654 if (vas != VA_STATUS_SUCCESS) {
656 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
660 vas = vaDestroyImage(hwctx->
display, map->
image.image_id);
661 if (vas != VA_STATUS_SUCCESS) {
663 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
674 VASurfaceID surface_id;
675 VAImageFormat *image_format;
678 void *address =
NULL;
681 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
690 if (dst->
format != hwfc->
sw_format && (flags & AV_HWFRAME_MAP_DIRECT)) {
705 map->
image.image_id = VA_INVALID_ID;
707 vas = vaSyncSurface(hwctx->
display, surface_id);
708 if (vas != VA_STATUS_SUCCESS) {
710 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
724 vas = vaDeriveImage(hwctx->
display, surface_id, &map->
image);
725 if (vas != VA_STATUS_SUCCESS) {
727 "surface %#x: %d (%s).\n",
728 surface_id, vas, vaErrorStr(vas));
732 if (map->
image.format.fourcc != image_format->fourcc) {
734 "is in wrong format: expected %#08x, got %#08x.\n",
735 surface_id, image_format->fourcc, map->
image.format.fourcc);
741 vas = vaCreateImage(hwctx->
display, image_format,
743 if (vas != VA_STATUS_SUCCESS) {
745 "surface %#x: %d (%s).\n",
746 surface_id, vas, vaErrorStr(vas));
751 vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
753 if (vas != VA_STATUS_SUCCESS) {
755 "surface %#x: %d (%s).\n",
756 surface_id, vas, vaErrorStr(vas));
763 vas = vaMapBuffer(hwctx->
display, map->
image.buf, &address);
764 if (vas != VA_STATUS_SUCCESS) {
766 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
779 for (i = 0; i < map->
image.num_planes; i++) {
784 #ifdef VA_FOURCC_YV16
785 map->
image.format.fourcc == VA_FOURCC_YV16 ||
787 map->
image.format.fourcc == VA_FOURCC_YV12) {
798 if (map->
image.image_id != VA_INVALID_ID)
898 if (priv->x11_display)
899 XCloseDisplay(priv->x11_display);
913 VADisplay display = 0;
927 if (!display && !(device && device[0] ==
'/')) {
929 priv->x11_display = XOpenDisplay(device);
930 if (!priv->x11_display) {
932 "%s.\n", XDisplayName(device));
934 display = vaGetDisplay(priv->x11_display);
937 "from X11 display %s.\n", XDisplayName(device));
942 "X11 display %s.\n", XDisplayName(device));
952 const char *path = device ? device :
"/dev/dri/renderD128";
953 priv->
drm_fd = open(path, O_RDWR);
958 display = vaGetDisplayDRM(priv->
drm_fd);
961 "from DRM device %s.\n", path);
966 "DRM device %s.\n", path);
973 "device: %s.\n", device ? device :
"");
979 vas = vaInitialize(display, &major, &minor);
980 if (vas != VA_STATUS_SUCCESS) {
982 "connection: %d (%s).\n", vas, vaErrorStr(vas));
986 "version %d.%d\n", major, minor);
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
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.
static enum AVPixelFormat vaapi_pix_fmt_from_fourcc(unsigned int fourcc)
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
static void vaapi_device_free(AVHWDeviceContext *ctx)
The mapped frame will be overwritten completely in subsequent operations, so the current frame data n...
The mapping must be writeable.
static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pixelformat)
Memory handling functions.
VASurfaceAttrib * attributes
Set by the user to apply surface attributes to all surfaces in the frame pool.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
static FFServerConfig config
int width
The allocated dimensions of the frames in this pool.
static int vaapi_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
int max_width
The maximum size of frames in this hw_frames_ctx.
API-specific header for AV_HWDEVICE_TYPE_VAAPI.
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
static int vaapi_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src)
static int vaapi_device_init(AVHWDeviceContext *hwdev)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVBufferPool * pool_internal
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static void vaapi_buffer_free(void *opaque, uint8_t *data)
static void vaapi_frames_uninit(AVHWFramesContext *hwfc)
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
static int vaapi_map_frame(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags)
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
The driver does not support the VASurfaceAttribMemoryType attribute, so the surface allocation code w...
VAAPI hardware pipeline configuration details.
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
The quirks field has been set by the user and should not be detected automatically by av_hwdevice_ctx...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
simple assert() macros that are a bit more flexible than ISO C assert().
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
VASurfaceAttrib * attributes
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
const char * match_string
int initial_pool_size
Initial size of the frame pool.
AVFrame * source
A reference to the original source of the mapping.
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
enum AVPixelFormat pix_fmt
static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
static const struct @242 vaapi_driver_quirks_table[]
AVBufferPool * av_buffer_pool_init2(int size, void *opaque, AVBufferRef *(*alloc)(void *opaque, int size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
static int vaapi_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src)
static void vaapi_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
#define FF_ARRAY_ELEMS(a)
VADisplay display
The VADisplay handle, to be filled by the user.
VAAPISurfaceFormat * formats
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
int min_width
The minimum size of frames in this hw_frames_ctx.
void * priv
Hardware-specific private data associated with the mapping.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
const char * friendly_name
uint8_t * data
The data buffer.
static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags)
static int vaapi_frames_init(AVHWFramesContext *hwfc)
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
unsigned int driver_quirks
Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), with reference to a table of known...
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void(*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv)
This struct describes a set or pool of "hardware" frames (i.e.
refcounted data buffer API
enum AVPixelFormat * valid_hw_formats
A list of possible values for format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
const VDPAUPixFmtMap * map
static int vaapi_get_image_format(AVHWDeviceContext *hwdev, enum AVPixelFormat pix_fmt, VAImageFormat **image_format)
AVHWFramesInternal * internal
Private data used internally by libavutil.
static enum AVPixelFormat pix_fmts[]
The mapping must be readable.
static void vaapi_device_uninit(AVHWDeviceContext *hwdev)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
void * user_opaque
Arbitrary user data, to be used e.g.
static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
A reference to a data buffer.
common internal and external API header
static int ref[MAX_W *MAX_W]
static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, const void *hwconfig, AVHWFramesConstraints *constraints)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
AVHWFrameTransferDirection
static AVBufferRef * vaapi_pool_alloc(void *opaque, int size)
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
The mapping must be direct.
VAAPI connection details.
VAConfigID config_id
ID of a VAAPI pipeline configuration.
static struct @241 vaapi_format_map[]
const HWContextType ff_hwcontext_type_vaapi
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
#define av_malloc_array(a, b)
#define FFSWAP(type, a, b)
AVHWDeviceInternal * internal
Private data used internally by libavutil.
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.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.