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 MAP(ABGR, RGB32, ABGR),
119 MAP(XBGR, RGB32, 0BGR),
120 MAP(ARGB, RGB32, ARGB),
121 MAP(XRGB, RGB32, 0RGB),
136 VAImageFormat **image_format)
151 const void *hwconfig,
157 VASurfaceAttrib *attr_list =
NULL;
161 int err, i, j, attr_count, pix_fmt_count;
171 vas = vaCreateConfig(hwctx->
display,
172 VAProfileNone, VAEntrypointVideoProc,
174 if (vas != VA_STATUS_SUCCESS) {
178 vas = vaCreateConfig(hwctx->
display,
179 VAProfileH264ConstrainedBaseline,
180 VAEntrypointVLD,
NULL, 0,
182 if (vas != VA_STATUS_SUCCESS) {
194 if (vas != VA_STATUS_SUCCESS) {
196 "%d (%s).\n", vas, vaErrorStr(vas));
201 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
208 attr_list, &attr_count);
209 if (vas != VA_STATUS_SUCCESS) {
211 "%d (%s).\n", vas, vaErrorStr(vas));
217 for (i = 0; i < attr_count; i++) {
218 switch (attr_list[i].
type) {
219 case VASurfaceAttribPixelFormat:
220 fourcc = attr_list[i].value.value.i;
228 case VASurfaceAttribMinWidth:
229 constraints->
min_width = attr_list[i].value.value.i;
231 case VASurfaceAttribMinHeight:
232 constraints->
min_height = attr_list[i].value.value.i;
234 case VASurfaceAttribMaxWidth:
235 constraints->
max_width = attr_list[i].value.value.i;
237 case VASurfaceAttribMaxHeight:
238 constraints->
max_height = attr_list[i].value.value.i;
242 if (pix_fmt_count == 0) {
254 for (i = j = 0; i < attr_count; i++) {
255 if (attr_list[i].
type != VASurfaceAttribPixelFormat)
257 fourcc = attr_list[i].value.value.i;
289 VAImageFormat *image_list =
NULL;
291 int err, i, j, image_count;
295 constraints =
av_mallocz(
sizeof(*constraints));
303 image_count = vaMaxNumImageFormats(hwctx->
display);
304 if (image_count <= 0) {
308 image_list =
av_malloc(image_count *
sizeof(*image_list));
313 vas = vaQueryImageFormats(hwctx->
display, image_list, &image_count);
314 if (vas != VA_STATUS_SUCCESS) {
325 for (i = 0; i < image_count; i++) {
326 fourcc = image_list[i].fourcc;
364 VASurfaceID surface_id;
367 surface_id = (VASurfaceID)(uintptr_t)
data;
369 vas = vaDestroySurfaces(hwctx->
display, &surface_id, 1);
370 if (vas != VA_STATUS_SUCCESS) {
372 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
382 VASurfaceID surface_id;
390 if (vas != VA_STATUS_SUCCESS) {
392 "%d (%s).\n", vas, vaErrorStr(vas));
401 vaDestroySurfaces(hwctx->
display, &surface_id, 1);
421 VAImageFormat *expected_format;
423 VASurfaceID test_surface_id;
443 int need_memory_type = 1, need_pixel_format = 1;
445 if (ctx->
attributes[i].type == VASurfaceAttribMemoryType)
446 need_memory_type = 0;
447 if (ctx->
attributes[i].type == VASurfaceAttribPixelFormat)
448 need_pixel_format = 0;
462 if (need_memory_type) {
464 .type = VASurfaceAttribMemoryType,
465 .flags = VA_SURFACE_ATTRIB_SETTABLE,
466 .value.type = VAGenericValueTypeInteger,
467 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
470 if (need_pixel_format) {
472 .type = VASurfaceAttribPixelFormat,
473 .flags = VA_SURFACE_ATTRIB_SETTABLE,
474 .value.type = VAGenericValueTypeInteger,
516 "user-configured buffer pool.\n");
524 "internal buffer pool.\n");
529 test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
536 vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
537 if (vas == VA_STATUS_SUCCESS) {
538 if (expected_format->fourcc == test_image.format.fourcc) {
543 "derived image format %08x does not match "
544 "expected format %08x.\n",
545 expected_format->fourcc, test_image.format.fourcc);
547 vaDestroyImage(hwctx->
display, test_image.image_id);
550 "deriving image does not work: "
551 "%d (%s).\n", vas, vaErrorStr(vas));
555 "image format is not supported.\n");
605 pix_fmts[0] = preferred_format;
626 VASurfaceID surface_id;
630 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
634 if (vas != VA_STATUS_SUCCESS) {
636 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
641 vas = vaPutImage(hwctx->
display, surface_id, map->
image.image_id,
644 if (vas != VA_STATUS_SUCCESS) {
646 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
650 vas = vaDestroyImage(hwctx->
display, map->
image.image_id);
651 if (vas != VA_STATUS_SUCCESS) {
653 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
664 VASurfaceID surface_id;
665 VAImageFormat *image_format;
668 void *address =
NULL;
671 surface_id = (VASurfaceID)(uintptr_t)src->
data[3];
697 map->
image.image_id = VA_INVALID_ID;
699 vas = vaSyncSurface(hwctx->
display, surface_id);
700 if (vas != VA_STATUS_SUCCESS) {
702 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
716 vas = vaDeriveImage(hwctx->
display, surface_id, &map->
image);
717 if (vas != VA_STATUS_SUCCESS) {
719 "surface %#x: %d (%s).\n",
720 surface_id, vas, vaErrorStr(vas));
724 if (map->
image.format.fourcc != image_format->fourcc) {
726 "is in wrong format: expected %#08x, got %#08x.\n",
727 surface_id, image_format->fourcc, map->
image.format.fourcc);
733 vas = vaCreateImage(hwctx->
display, image_format,
735 if (vas != VA_STATUS_SUCCESS) {
737 "surface %#x: %d (%s).\n",
738 surface_id, vas, vaErrorStr(vas));
742 if (flags & VAAPI_MAP_READ) {
743 vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
745 if (vas != VA_STATUS_SUCCESS) {
747 "surface %#x: %d (%s).\n",
748 surface_id, vas, vaErrorStr(vas));
755 vas = vaMapBuffer(hwctx->
display, map->
image.buf, &address);
756 if (vas != VA_STATUS_SUCCESS) {
758 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
766 for (i = 0; i < map->
image.num_planes; i++) {
771 #ifdef VA_FOURCC_YV16
772 map->
image.format.fourcc == VA_FOURCC_YV16 ||
774 map->
image.format.fourcc == VA_FOURCC_YV12) {
792 if (map->
image.image_id != VA_INVALID_ID)
858 if (priv->x11_display)
859 XCloseDisplay(priv->x11_display);
873 VADisplay display = 0;
887 if (!display && !(device && device[0] ==
'/')) {
889 priv->x11_display = XOpenDisplay(device);
890 if (!priv->x11_display) {
892 "%s.\n", XDisplayName(device));
894 display = vaGetDisplay(priv->x11_display);
897 "from X11 display %s.\n", XDisplayName(device));
902 "X11 display %s.\n", XDisplayName(device));
908 if (!display && device) {
910 priv->
drm_fd = open(device, O_RDWR);
915 display = vaGetDisplayDRM(priv->
drm_fd);
918 "from DRM device %s.\n", device);
923 "DRM device %s.\n", device);
930 "device: %s.\n", device ? device :
"");
936 vas = vaInitialize(display, &major, &minor);
937 if (vas != VA_STATUS_SUCCESS) {
939 "connection: %d (%s).\n", vas, vaErrorStr(vas));
943 "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)
int max_width
The maximum size of frames in this hw_frames_ctx.
API-specific header for AV_HWDEVICE_TYPE_VAAPI.
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
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().
static struct @219 vaapi_format_map[]
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.
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.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...