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
112 MAP(P010, YUV420_10BPP, P010),
114 MAP(BGRA, RGB32, BGRA),
115 MAP(BGRX, RGB32, BGR0),
117 MAP(RGBX, RGB32, RGB0),
118 #ifdef VA_FOURCC_ABGR
119 MAP(ABGR, RGB32, ABGR),
120 MAP(XBGR, RGB32, 0BGR),
122 MAP(ARGB, RGB32, ARGB),
123 MAP(XRGB, RGB32, 0RGB),
138 VAImageFormat **image_format)
153 const void *hwconfig,
159 VASurfaceAttrib *attr_list =
NULL;
163 int err, i, j, attr_count, pix_fmt_count;
169 if (vas != VA_STATUS_SUCCESS) {
171 "%d (%s).\n", vas, vaErrorStr(vas));
176 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
183 attr_list, &attr_count);
184 if (vas != VA_STATUS_SUCCESS) {
186 "%d (%s).\n", vas, vaErrorStr(vas));
192 for (i = 0; i < attr_count; i++) {
193 switch (attr_list[i].
type) {
194 case VASurfaceAttribPixelFormat:
195 fourcc = attr_list[i].value.value.i;
203 case VASurfaceAttribMinWidth:
204 constraints->
min_width = attr_list[i].value.value.i;
206 case VASurfaceAttribMinHeight:
207 constraints->
min_height = attr_list[i].value.value.i;
209 case VASurfaceAttribMaxWidth:
210 constraints->
max_width = attr_list[i].value.value.i;
212 case VASurfaceAttribMaxHeight:
213 constraints->
max_height = attr_list[i].value.value.i;
217 if (pix_fmt_count == 0) {
229 for (i = j = 0; i < attr_count; i++) {
230 if (attr_list[i].
type != VASurfaceAttribPixelFormat)
232 fourcc = attr_list[i].value.value.i;
272 VAImageFormat *image_list =
NULL;
274 int err, i, image_count;
278 image_count = vaMaxNumImageFormats(hwctx->
display);
279 if (image_count <= 0) {
283 image_list =
av_malloc(image_count *
sizeof(*image_list));
288 vas = vaQueryImageFormats(hwctx->
display, image_list, &image_count);
289 if (vas != VA_STATUS_SUCCESS) {
300 for (i = 0; i < image_count; i++) {
301 fourcc = image_list[i].fourcc;
334 VASurfaceID surface_id;
337 surface_id = (VASurfaceID)(uintptr_t)
data;
339 vas = vaDestroySurfaces(hwctx->
display, &surface_id, 1);
340 if (vas != VA_STATUS_SUCCESS) {
342 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
352 VASurfaceID surface_id;
360 if (vas != VA_STATUS_SUCCESS) {
362 "%d (%s).\n", vas, vaErrorStr(vas));
371 vaDestroySurfaces(hwctx->
display, &surface_id, 1);
391 VAImageFormat *expected_format;
393 VASurfaceID test_surface_id;
413 int need_memory_type = 1, need_pixel_format = 1;
415 if (ctx->
attributes[i].type == VASurfaceAttribMemoryType)
416 need_memory_type = 0;
417 if (ctx->
attributes[i].type == VASurfaceAttribPixelFormat)
418 need_pixel_format = 0;
432 if (need_memory_type) {
434 .type = VASurfaceAttribMemoryType,
435 .flags = VA_SURFACE_ATTRIB_SETTABLE,
436 .value.type = VAGenericValueTypeInteger,
437 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
440 if (need_pixel_format) {
442 .type = VASurfaceAttribPixelFormat,
443 .flags = VA_SURFACE_ATTRIB_SETTABLE,
444 .value.type = VAGenericValueTypeInteger,
486 "user-configured buffer pool.\n");
494 "internal buffer pool.\n");
499 test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
506 vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
507 if (vas == VA_STATUS_SUCCESS) {
508 if (expected_format->fourcc == test_image.format.fourcc) {
513 "derived image format %08x does not match "
514 "expected format %08x.\n",
515 expected_format->fourcc, test_image.format.fourcc);
517 vaDestroyImage(hwctx->
display, test_image.image_id);
520 "deriving image does not work: "
521 "%d (%s).\n", vas, vaErrorStr(vas));
525 "image format is not supported.\n");
575 pix_fmts[0] = preferred_format;
596 VASurfaceID surface_id;
600 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
604 if (vas != VA_STATUS_SUCCESS) {
606 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
611 vas = vaPutImage(hwctx->
display, surface_id, map->
image.image_id,
614 if (vas != VA_STATUS_SUCCESS) {
616 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
620 vas = vaDestroyImage(hwctx->
display, map->
image.image_id);
621 if (vas != VA_STATUS_SUCCESS) {
623 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
634 VASurfaceID surface_id;
635 VAImageFormat *image_format;
638 void *address =
NULL;
641 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
667 map->
image.image_id = VA_INVALID_ID;
669 vas = vaSyncSurface(hwctx->
display, surface_id);
670 if (vas != VA_STATUS_SUCCESS) {
672 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
686 vas = vaDeriveImage(hwctx->
display, surface_id, &map->
image);
687 if (vas != VA_STATUS_SUCCESS) {
689 "surface %#x: %d (%s).\n",
690 surface_id, vas, vaErrorStr(vas));
694 if (map->
image.format.fourcc != image_format->fourcc) {
696 "is in wrong format: expected %#08x, got %#08x.\n",
697 surface_id, image_format->fourcc, map->
image.format.fourcc);
703 vas = vaCreateImage(hwctx->
display, image_format,
705 if (vas != VA_STATUS_SUCCESS) {
707 "surface %#x: %d (%s).\n",
708 surface_id, vas, vaErrorStr(vas));
712 if (flags & VAAPI_MAP_READ) {
713 vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
715 if (vas != VA_STATUS_SUCCESS) {
717 "surface %#x: %d (%s).\n",
718 surface_id, vas, vaErrorStr(vas));
725 vas = vaMapBuffer(hwctx->
display, map->
image.buf, &address);
726 if (vas != VA_STATUS_SUCCESS) {
728 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
736 for (i = 0; i < map->
image.num_planes; i++) {
741 #ifdef VA_FOURCC_YV16
742 map->
image.format.fourcc == VA_FOURCC_YV16 ||
744 map->
image.format.fourcc == VA_FOURCC_YV12) {
762 if (map->
image.image_id != VA_INVALID_ID)
828 if (priv->x11_display)
829 XCloseDisplay(priv->x11_display);
843 VADisplay display = 0;
857 if (!display && !(device && device[0] ==
'/')) {
859 priv->x11_display = XOpenDisplay(device);
860 if (!priv->x11_display) {
862 "%s.\n", XDisplayName(device));
864 display = vaGetDisplay(priv->x11_display);
867 "from X11 display %s.\n", XDisplayName(device));
872 "X11 display %s.\n", XDisplayName(device));
878 if (!display && device) {
880 priv->
drm_fd = open(device, O_RDWR);
885 display = vaGetDisplayDRM(priv->
drm_fd);
888 "from DRM device %s.\n", device);
893 "DRM device %s.\n", device);
900 "device: %s.\n", device ? device :
"");
906 vas = vaInitialize(display, &major, &minor);
907 if (vas != VA_STATUS_SUCCESS) {
909 "connection: %d (%s).\n", vas, vaErrorStr(vas));
913 "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)
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
static enum AVSampleFormat formats[]
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.
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.
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.
#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.
int initial_pool_size
Initial size of the frame pool.
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
enum AVPixelFormat 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)
#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.
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.
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.
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)
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)
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.
const HWContextType ff_hwcontext_type_vaapi
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
static struct @237 vaapi_format_map[]
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.