22 # include <va/va_x11.h> 25 # include <va/va_drm.h> 88 #define MAP(va, rt, av) { \ 90 VA_RT_FORMAT_ ## rt, \ 100 MAP(NV12, YUV420, NV12),
101 MAP(YV12, YUV420, YUV420P),
102 MAP(IYUV, YUV420, YUV420P),
104 #ifdef VA_FOURCC_YV16 105 MAP(YV16, YUV422, YUV422P),
107 MAP(422
H, YUV422, YUV422P),
108 MAP(UYVY, YUV422, UYVY422),
109 MAP(YUY2, YUV422, YUYV422),
110 MAP(Y800, YUV400, GRAY8),
111 #ifdef VA_FOURCC_P010 114 MAP(BGRA, RGB32, BGRA),
118 MAP(ABGR, RGB32, ABGR),
120 MAP(ARGB, RGB32, ARGB),
136 VAImageFormat **image_format)
151 const void *hwconfig,
157 VASurfaceAttrib *attr_list =
NULL;
161 int err, i, j, attr_count, pix_fmt_count;
167 if (vas != VA_STATUS_SUCCESS) {
169 "%d (%s).\n", vas, vaErrorStr(vas));
174 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
181 attr_list, &attr_count);
182 if (vas != VA_STATUS_SUCCESS) {
184 "%d (%s).\n", vas, vaErrorStr(vas));
190 for (i = 0; i < attr_count; i++) {
191 switch (attr_list[i].type) {
192 case VASurfaceAttribPixelFormat:
193 fourcc = attr_list[i].value.value.i;
201 case VASurfaceAttribMinWidth:
202 constraints->
min_width = attr_list[i].value.value.i;
204 case VASurfaceAttribMinHeight:
205 constraints->
min_height = attr_list[i].value.value.i;
207 case VASurfaceAttribMaxWidth:
208 constraints->
max_width = attr_list[i].value.value.i;
210 case VASurfaceAttribMaxHeight:
211 constraints->
max_height = attr_list[i].value.value.i;
215 if (pix_fmt_count == 0) {
227 for (i = j = 0; i < attr_count; i++) {
228 if (attr_list[i].type != VASurfaceAttribPixelFormat)
230 fourcc = attr_list[i].value.value.i;
266 static const struct {
272 "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;
454 int need_memory_type = 1, need_pixel_format = 1;
456 if (ctx->
attributes[i].type == VASurfaceAttribMemoryType)
457 need_memory_type = 0;
458 if (ctx->
attributes[i].type == VASurfaceAttribPixelFormat)
459 need_pixel_format = 0;
473 if (need_memory_type) {
475 .type = VASurfaceAttribMemoryType,
476 .flags = VA_SURFACE_ATTRIB_SETTABLE,
477 .value.type = VAGenericValueTypeInteger,
478 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
481 if (need_pixel_format) {
483 .type = VASurfaceAttribPixelFormat,
484 .flags = VA_SURFACE_ATTRIB_SETTABLE,
485 .value.type = VAGenericValueTypeInteger,
527 "user-configured buffer pool.\n");
535 "internal buffer pool.\n");
540 test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
547 vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
548 if (vas == VA_STATUS_SUCCESS) {
549 if (expected_format->fourcc == test_image.format.fourcc) {
554 "derived image format %08x does not match " 555 "expected format %08x.\n",
556 expected_format->fourcc, test_image.format.fourcc);
558 vaDestroyImage(hwctx->
display, test_image.image_id);
561 "deriving image does not work: " 562 "%d (%s).\n", vas, vaErrorStr(vas));
566 "image format is not supported.\n");
616 pix_fmts[0] = preferred_format;
637 VASurfaceID surface_id;
641 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
645 if (vas != VA_STATUS_SUCCESS) {
647 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
652 vas = vaPutImage(hwctx->
display, surface_id, map->
image.image_id,
655 if (vas != VA_STATUS_SUCCESS) {
657 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
661 vas = vaDestroyImage(hwctx->
display, map->
image.image_id);
662 if (vas != VA_STATUS_SUCCESS) {
664 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
675 VASurfaceID surface_id;
676 VAImageFormat *image_format;
679 void *address =
NULL;
682 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
708 map->
image.image_id = VA_INVALID_ID;
710 vas = vaSyncSurface(hwctx->
display, surface_id);
711 if (vas != VA_STATUS_SUCCESS) {
713 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
727 vas = vaDeriveImage(hwctx->
display, surface_id, &map->
image);
728 if (vas != VA_STATUS_SUCCESS) {
730 "surface %#x: %d (%s).\n",
731 surface_id, vas, vaErrorStr(vas));
735 if (map->
image.format.fourcc != image_format->fourcc) {
737 "is in wrong format: expected %#08x, got %#08x.\n",
738 surface_id, image_format->fourcc, map->
image.format.fourcc);
744 vas = vaCreateImage(hwctx->
display, image_format,
746 if (vas != VA_STATUS_SUCCESS) {
748 "surface %#x: %d (%s).\n",
749 surface_id, vas, vaErrorStr(vas));
753 if (flags & VAAPI_MAP_READ) {
754 vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
756 if (vas != VA_STATUS_SUCCESS) {
758 "surface %#x: %d (%s).\n",
759 surface_id, vas, vaErrorStr(vas));
766 vas = vaMapBuffer(hwctx->
display, map->
image.buf, &address);
767 if (vas != VA_STATUS_SUCCESS) {
769 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
777 for (i = 0; i < map->
image.num_planes; i++) {
782 #ifdef VA_FOURCC_YV16
783 map->
image.format.fourcc == VA_FOURCC_YV16 ||
785 map->
image.format.fourcc == VA_FOURCC_YV12) {
802 vaUnmapBuffer(hwctx->
display, map->image.buf);
803 if (map->image.image_id != VA_INVALID_ID)
804 vaDestroyImage(hwctx->
display, map->image.image_id);
881 if (priv->x11_display)
882 XCloseDisplay(priv->x11_display);
896 VADisplay display = 0;
910 if (!display && !(device && device[0] ==
'/')) {
912 priv->x11_display = XOpenDisplay(device);
913 if (!priv->x11_display) {
915 "%s.\n", XDisplayName(device));
917 display = vaGetDisplay(priv->x11_display);
920 "from X11 display %s.\n", XDisplayName(device));
925 "X11 display %s.\n", XDisplayName(device));
935 const char *path = device ? device :
"/dev/dri/renderD128";
936 priv->
drm_fd = open(path, O_RDWR);
941 display = vaGetDisplayDRM(priv->
drm_fd);
944 "from DRM device %s.\n", path);
949 "DRM device %s.\n", path);
956 "device: %s.\n", device ? device :
"");
962 vas = vaInitialize(display, &major, &minor);
963 if (vas != VA_STATUS_SUCCESS) {
965 "connection: %d (%s).\n", vas, vaErrorStr(vas));
969 "version %d.%d\n", major, minor);
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static struct @166 vaapi_format_map[]
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.
static void vaapi_device_free(AVHWDeviceContext *ctx)
static const struct @167 vaapi_driver_quirks_table[]
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.
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
static enum AVSampleFormat formats[]
int width
The allocated dimensions of the frames in this pool.
static int vaapi_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame)
#define FF_ARRAY_ELEMS(a)
int max_width
The maximum size of frames in this hw_frames_ctx.
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
API-specific header for AV_HWDEVICE_TYPE_VAAPI.
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.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
VAAPI hardware pipeline configuration details.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#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.
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
enum AVPixelFormat pix_fmt
static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt)
static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
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)
if(ac->has_optimized_func)
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.
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_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...
The quirks field has been set by the user and should not be detected automatically by av_hwdevice_ctx...
static void vaapi_unmap_frame(void *opaque, uint8_t *data)
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[]
static void vaapi_device_uninit(AVHWDeviceContext *hwdev)
static void * av_malloc_array(size_t nmemb, size_t size)
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 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)
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.
VAAPI connection details.
VAConfigID config_id
ID of a VAAPI pipeline configuration.
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
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 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.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...