22 # include <va/va_x11.h>
25 # include <va/va_drm.h>
29 # include <va/va_drmcommon.h>
31 # include <drm_fourcc.h>
32 # ifndef DRM_FORMAT_MOD_INVALID
33 # define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
99 } VAAPIFormatDescriptor;
101 #define MAP(va, rt, av, swap_uv) { \
103 VA_RT_FORMAT_ ## rt, \
110 MAP(NV12, YUV420, NV12, 0),
111 #ifdef VA_FOURCC_I420
112 MAP(I420, YUV420, YUV420P, 0),
114 MAP(YV12, YUV420, YUV420P, 1),
115 MAP(IYUV, YUV420, YUV420P, 0),
116 MAP(422
H, YUV422, YUV422P, 0),
117 #ifdef VA_FOURCC_YV16
118 MAP(YV16, YUV422, YUV422P, 1),
120 MAP(UYVY, YUV422, UYVY422, 0),
121 MAP(YUY2, YUV422, YUYV422, 0),
122 #ifdef VA_FOURCC_Y210
123 MAP(Y210, YUV422_10, Y210, 0),
125 MAP(411
P, YUV411, YUV411P, 0),
126 MAP(422
V, YUV422, YUV440P, 0),
127 MAP(444
P, YUV444, YUV444P, 0),
128 MAP(AYUV, YUV444, VUYA, 0),
129 MAP(Y800, YUV400, GRAY8, 0),
130 #ifdef VA_FOURCC_P010
131 MAP(P010, YUV420_10BPP, P010, 0),
133 MAP(BGRA, RGB32, BGRA, 0),
134 MAP(BGRX, RGB32, BGR0, 0),
136 MAP(RGBX, RGB32, RGB0, 0),
137 #ifdef VA_FOURCC_ABGR
138 MAP(ABGR, RGB32, ABGR, 0),
139 MAP(XBGR, RGB32, 0BGR, 0),
141 MAP(ARGB, RGB32, ARGB, 0),
142 MAP(XRGB, RGB32, 0RGB, 0),
143 #ifdef VA_FOURCC_X2R10G10B10
144 MAP(X2R10G10B10, RGB32_10, X2RGB10, 0),
149 static const VAAPIFormatDescriptor *
159 static const VAAPIFormatDescriptor *
171 const VAAPIFormatDescriptor *
desc;
174 return desc->pix_fmt;
181 VAImageFormat **image_format)
186 for (
i = 0;
i <
ctx->nb_formats;
i++) {
189 *image_format = &
ctx->formats[
i].image_format;
197 const void *hwconfig,
203 VASurfaceAttrib *attr_list =
NULL;
207 int err,
i, j, attr_count, pix_fmt_count;
212 vas = vaQuerySurfaceAttributes(hwctx->
display,
config->config_id,
214 if (vas != VA_STATUS_SUCCESS) {
216 "%d (%s).\n", vas, vaErrorStr(vas));
221 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
227 vas = vaQuerySurfaceAttributes(hwctx->
display,
config->config_id,
228 attr_list, &attr_count);
229 if (vas != VA_STATUS_SUCCESS) {
231 "%d (%s).\n", vas, vaErrorStr(vas));
237 for (
i = 0;
i < attr_count;
i++) {
238 switch (attr_list[
i].
type) {
239 case VASurfaceAttribPixelFormat:
240 fourcc = attr_list[
i].value.value.i;
248 case VASurfaceAttribMinWidth:
249 constraints->
min_width = attr_list[
i].value.value.i;
251 case VASurfaceAttribMinHeight:
252 constraints->
min_height = attr_list[
i].value.value.i;
254 case VASurfaceAttribMaxWidth:
255 constraints->
max_width = attr_list[
i].value.value.i;
257 case VASurfaceAttribMaxHeight:
258 constraints->
max_height = attr_list[
i].value.value.i;
262 if (pix_fmt_count == 0) {
274 for (
i = j = 0;
i < attr_count;
i++) {
277 if (attr_list[
i].
type != VASurfaceAttribPixelFormat)
279 fourcc = attr_list[
i].value.value.i;
285 for (k = 0; k < j; k++) {
304 for (
i = j = 0;
i <
ctx->nb_formats;
i++) {
307 for (k = 0; k < j; k++) {
333 static const struct {
338 #if !VA_CHECK_VERSION(1, 0, 0)
341 "Intel i965 (Quick Sync)",
353 "Splitted-Desktop Systems VDPAU backend for VA-API",
362 VAImageFormat *image_list =
NULL;
364 const char *vendor_string;
365 int err,
i, image_count;
369 image_count = vaMaxNumImageFormats(hwctx->
display);
370 if (image_count <= 0) {
374 image_list =
av_malloc(image_count *
sizeof(*image_list));
379 vas = vaQueryImageFormats(hwctx->
display, image_list, &image_count);
380 if (vas != VA_STATUS_SUCCESS) {
391 for (
i = 0;
i < image_count;
i++) {
401 ctx->formats[
ctx->nb_formats].image_format = image_list[
i];
406 vendor_string = vaQueryVendorString(hwctx->
display);
418 if (strstr(vendor_string,
421 "as known nonstandard driver \"%s\", setting "
432 "nonstandard list, using standard behaviour.\n");
436 "assuming standard behaviour.\n");
459 VASurfaceID surface_id;
462 surface_id = (VASurfaceID)(uintptr_t)
data;
464 vas = vaDestroySurfaces(hwctx->
display, &surface_id, 1);
465 if (vas != VA_STATUS_SUCCESS) {
467 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
477 VASurfaceID surface_id;
485 vas = vaCreateSurfaces(hwctx->
display,
ctx->rt_format,
488 ctx->attributes,
ctx->nb_attributes);
489 if (vas != VA_STATUS_SUCCESS) {
491 "%d (%s).\n", vas, vaErrorStr(vas));
500 vaDestroySurfaces(hwctx->
display, &surface_id, 1);
520 const VAAPIFormatDescriptor *
desc;
521 VAImageFormat *expected_format;
523 VASurfaceID test_surface_id;
538 int need_pixel_format = 1;
540 if (avfc->
attributes[
i].type == VASurfaceAttribMemoryType)
541 need_memory_type = 0;
542 if (avfc->
attributes[
i].type == VASurfaceAttribPixelFormat)
543 need_pixel_format = 0;
549 sizeof(*
ctx->attributes));
550 if (!
ctx->attributes) {
557 if (need_memory_type) {
558 ctx->attributes[
i++] = (VASurfaceAttrib) {
559 .type = VASurfaceAttribMemoryType,
560 .
flags = VA_SURFACE_ATTRIB_SETTABLE,
561 .value.type = VAGenericValueTypeInteger,
562 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
565 if (need_pixel_format) {
566 ctx->attributes[
i++] = (VASurfaceAttrib) {
567 .type = VASurfaceAttribPixelFormat,
568 .
flags = VA_SURFACE_ATTRIB_SETTABLE,
569 .value.type = VAGenericValueTypeInteger,
570 .value.value.i =
desc->fourcc,
576 ctx->nb_attributes = 0;
579 ctx->rt_format =
desc->rt_format;
615 "user-configured buffer pool.\n");
623 "internal buffer pool.\n");
628 test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
630 ctx->derive_works = 0;
635 vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
636 if (vas == VA_STATUS_SUCCESS) {
637 if (expected_format->fourcc == test_image.format.fourcc) {
639 ctx->derive_works = 1;
642 "derived image format %08x does not match "
643 "expected format %08x.\n",
644 expected_format->fourcc, test_image.format.fourcc);
646 vaDestroyImage(hwctx->
display, test_image.image_id);
649 "deriving image does not work: "
650 "%d (%s).\n", vas, vaErrorStr(vas));
654 "image format is not supported.\n");
696 int i, k, sw_format_available;
698 sw_format_available = 0;
699 for (
i = 0;
i <
ctx->nb_formats;
i++) {
701 sw_format_available = 1;
708 if (sw_format_available) {
714 for (
i = 0;
i <
ctx->nb_formats;
i++) {
731 VASurfaceID surface_id;
734 surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
737 vas = vaUnmapBuffer(hwctx->
display,
map->image.buf);
738 if (vas != VA_STATUS_SUCCESS) {
740 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
745 vas = vaPutImage(hwctx->
display, surface_id,
map->image.image_id,
748 if (vas != VA_STATUS_SUCCESS) {
750 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
754 vas = vaDestroyImage(hwctx->
display,
map->image.image_id);
755 if (vas != VA_STATUS_SUCCESS) {
757 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
768 VASurfaceID surface_id;
769 const VAAPIFormatDescriptor *
desc;
770 VAImageFormat *image_format;
773 void *address =
NULL;
776 surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
800 map->image.image_id = VA_INVALID_ID;
802 vas = vaSyncSurface(hwctx->
display, surface_id);
803 if (vas != VA_STATUS_SUCCESS) {
805 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
819 vas = vaDeriveImage(hwctx->
display, surface_id, &
map->image);
820 if (vas != VA_STATUS_SUCCESS) {
822 "surface %#x: %d (%s).\n",
823 surface_id, vas, vaErrorStr(vas));
827 if (
map->image.format.fourcc != image_format->fourcc) {
829 "is in wrong format: expected %#08x, got %#08x.\n",
830 surface_id, image_format->fourcc,
map->image.format.fourcc);
836 vas = vaCreateImage(hwctx->
display, image_format,
838 if (vas != VA_STATUS_SUCCESS) {
840 "surface %#x: %d (%s).\n",
841 surface_id, vas, vaErrorStr(vas));
846 vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
848 if (vas != VA_STATUS_SUCCESS) {
850 "surface %#x: %d (%s).\n",
851 surface_id, vas, vaErrorStr(vas));
858 vas = vaMapBuffer(hwctx->
display,
map->image.buf, &address);
859 if (vas != VA_STATUS_SUCCESS) {
861 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
874 for (
i = 0;
i <
map->image.num_planes;
i++) {
875 dst->
data[
i] = (uint8_t*)address +
map->image.offsets[
i];
880 if (
desc &&
desc->chroma_planes_swapped) {
890 vaUnmapBuffer(hwctx->
display,
map->image.buf);
891 if (
map->image.image_id != VA_INVALID_ID)
892 vaDestroyImage(hwctx->
display,
map->image.image_id);
941 map->format =
src->format;
948 map->height =
src->height;
984 #define DRM_MAP(va, layers, ...) { \
989 static const struct {
991 int nb_layer_formats;
993 } vaapi_drm_format_map[] = {
995 DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88),
996 DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_GR88),
998 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
999 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
1000 DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616),
1002 DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888),
1003 DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888),
1004 DRM_MAP(
RGBA, 1, DRM_FORMAT_ABGR8888),
1005 DRM_MAP(RGBX, 1, DRM_FORMAT_XBGR8888),
1006 #ifdef VA_FOURCC_ABGR
1007 DRM_MAP(ABGR, 1, DRM_FORMAT_RGBA8888),
1008 DRM_MAP(XBGR, 1, DRM_FORMAT_RGBX8888),
1010 DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888),
1011 DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888),
1020 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->
priv;
1024 vaDestroySurfaces(dst_dev->
display, &surface_id, 1);
1030 #if VA_CHECK_VERSION(1, 1, 0)
1040 const VAAPIFormatDescriptor *format_desc;
1041 VASurfaceID surface_id;
1042 VAStatus vas = VA_STATUS_SUCCESS;
1046 #
if !VA_CHECK_VERSION(1, 1, 0)
1047 unsigned long buffer_handle;
1048 VASurfaceAttribExternalBuffers buffer_desc;
1049 VASurfaceAttrib attrs[2] = {
1051 .type = VASurfaceAttribMemoryType,
1052 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1053 .value.type = VAGenericValueTypeInteger,
1054 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
1057 .type = VASurfaceAttribExternalBufferDescriptor,
1058 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1059 .value.type = VAGenericValueTypePointer,
1060 .value.value.p = &buffer_desc,
1067 if (
desc->nb_objects != 1) {
1069 "made from a single DRM object.\n");
1075 if (
desc->nb_layers != vaapi_drm_format_map[
i].nb_layer_formats)
1077 for (j = 0; j <
desc->nb_layers; j++) {
1078 if (
desc->layers[j].format !=
1079 vaapi_drm_format_map[
i].layer_formats[j])
1082 if (j !=
desc->nb_layers)
1084 va_fourcc = vaapi_drm_format_map[
i].va_fourcc;
1094 "%08x.\n",
desc->objects[0].fd, va_fourcc);
1099 #if VA_CHECK_VERSION(1, 1, 0)
1103 VADRMPRIMESurfaceDescriptor prime_desc;
1104 VASurfaceAttrib prime_attrs[2] = {
1106 .type = VASurfaceAttribMemoryType,
1107 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1108 .value.type = VAGenericValueTypeInteger,
1109 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
1112 .type = VASurfaceAttribExternalBufferDescriptor,
1113 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1114 .value.type = VAGenericValueTypePointer,
1115 .value.value.p = &prime_desc,
1118 prime_desc.fourcc = va_fourcc;
1119 prime_desc.width = src_fc->
width;
1120 prime_desc.height = src_fc->
height;
1121 prime_desc.num_objects =
desc->nb_objects;
1122 for (
i = 0;
i <
desc->nb_objects; ++
i) {
1123 prime_desc.objects[
i].fd =
desc->objects[
i].fd;
1124 prime_desc.objects[
i].size =
desc->objects[
i].size;
1125 prime_desc.objects[
i].drm_format_modifier =
1126 desc->objects[
i].format_modifier;
1129 prime_desc.num_layers =
desc->nb_layers;
1130 for (
i = 0;
i <
desc->nb_layers; ++
i) {
1131 prime_desc.layers[
i].drm_format =
desc->layers[
i].format;
1132 prime_desc.layers[
i].num_planes =
desc->layers[
i].nb_planes;
1133 for (j = 0; j <
desc->layers[
i].nb_planes; ++j) {
1134 prime_desc.layers[
i].object_index[j] =
1135 desc->layers[
i].planes[j].object_index;
1136 prime_desc.layers[
i].offset[j] =
desc->layers[
i].planes[j].offset;
1137 prime_desc.layers[
i].pitch[j] =
desc->layers[
i].planes[j].pitch;
1140 if (format_desc->chroma_planes_swapped &&
1141 desc->layers[
i].nb_planes == 3) {
1142 FFSWAP(uint32_t, prime_desc.layers[
i].pitch[1],
1143 prime_desc.layers[
i].pitch[2]);
1144 FFSWAP(uint32_t, prime_desc.layers[
i].offset[1],
1145 prime_desc.layers[
i].offset[2]);
1155 vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
1156 src->width,
src->height, &surface_id, 1,
1158 if (vas != VA_STATUS_SUCCESS)
1162 if (!use_prime2 || vas != VA_STATUS_SUCCESS) {
1164 unsigned long buffer_handle;
1165 VASurfaceAttribExternalBuffers buffer_desc;
1166 VASurfaceAttrib buffer_attrs[2] = {
1168 .type = VASurfaceAttribMemoryType,
1169 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1170 .value.type = VAGenericValueTypeInteger,
1171 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
1174 .type = VASurfaceAttribExternalBufferDescriptor,
1175 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1176 .value.type = VAGenericValueTypePointer,
1177 .value.value.p = &buffer_desc,
1181 buffer_handle =
desc->objects[0].fd;
1182 buffer_desc.pixel_format = va_fourcc;
1183 buffer_desc.width = src_fc->
width;
1184 buffer_desc.height = src_fc->
height;
1185 buffer_desc.data_size =
desc->objects[0].size;
1186 buffer_desc.buffers = &buffer_handle;
1187 buffer_desc.num_buffers = 1;
1188 buffer_desc.flags = 0;
1191 for (
i = 0;
i <
desc->nb_layers;
i++) {
1192 for (j = 0; j <
desc->layers[
i].nb_planes; j++) {
1193 buffer_desc.pitches[k] =
desc->layers[
i].planes[j].pitch;
1194 buffer_desc.offsets[k] =
desc->layers[
i].planes[j].offset;
1198 buffer_desc.num_planes = k;
1200 if (format_desc->chroma_planes_swapped &&
1201 buffer_desc.num_planes == 3) {
1202 FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]);
1203 FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
1206 vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
1212 buffer_handle =
desc->objects[0].fd;
1213 buffer_desc.pixel_format = va_fourcc;
1214 buffer_desc.width = src_fc->
width;
1215 buffer_desc.height = src_fc->
height;
1216 buffer_desc.data_size =
desc->objects[0].size;
1217 buffer_desc.buffers = &buffer_handle;
1218 buffer_desc.num_buffers = 1;
1219 buffer_desc.flags = 0;
1222 for (
i = 0;
i <
desc->nb_layers;
i++) {
1223 for (j = 0; j <
desc->layers[
i].nb_planes; j++) {
1224 buffer_desc.pitches[k] =
desc->layers[
i].planes[j].pitch;
1225 buffer_desc.offsets[k] =
desc->layers[
i].planes[j].offset;
1229 buffer_desc.num_planes = k;
1231 if (format_desc->chroma_planes_swapped &&
1232 buffer_desc.num_planes == 3) {
1233 FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]);
1234 FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
1237 vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
1242 if (vas != VA_STATUS_SUCCESS) {
1244 "object: %d (%s).\n", vas, vaErrorStr(vas));
1250 &vaapi_unmap_from_drm,
1251 (
void*)(uintptr_t)surface_id);
1257 dst->
data[3] = (uint8_t*)(uintptr_t)surface_id;
1260 "surface %#x.\n",
desc->objects[0].fd, surface_id);
1265 #if VA_CHECK_VERSION(1, 1, 0)
1282 VASurfaceID surface_id;
1284 VADRMPRIMESurfaceDescriptor va_desc;
1286 uint32_t export_flags;
1289 surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
1291 export_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS;
1293 export_flags |= VA_EXPORT_SURFACE_READ_ONLY;
1295 export_flags |= VA_EXPORT_SURFACE_WRITE_ONLY;
1297 vas = vaExportSurfaceHandle(hwctx->
display, surface_id,
1298 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
1299 export_flags, &va_desc);
1300 if (vas != VA_STATUS_SUCCESS) {
1301 if (vas == VA_STATUS_ERROR_UNIMPLEMENTED)
1304 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
1316 for (
i = 0;
i < va_desc.num_objects;
i++) {
1320 va_desc.objects[
i].drm_format_modifier;
1322 drm_desc->
nb_layers = va_desc.num_layers;
1323 for (
i = 0;
i < va_desc.num_layers;
i++) {
1326 for (j = 0; j < va_desc.layers[
i].num_planes; j++) {
1328 va_desc.layers[
i].object_index[j];
1330 va_desc.layers[
i].offset[j];
1332 va_desc.layers[
i].pitch[j];
1337 &vaapi_unmap_to_drm_esh, drm_desc);
1343 dst->
data[0] = (uint8_t*)drm_desc;
1348 for (
i = 0;
i < va_desc.num_objects;
i++)
1349 close(va_desc.objects[
i].fd);
1355 #if VA_CHECK_VERSION(0, 36, 0)
1356 typedef struct VAAPIDRMImageBufferMapping {
1358 VABufferInfo buffer_info;
1361 } VAAPIDRMImageBufferMapping;
1367 VAAPIDRMImageBufferMapping *mapping = hwmap->
priv;
1368 VASurfaceID surface_id;
1371 surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
1378 vas = vaReleaseBufferHandle(hwctx->
display, mapping->image.buf);
1379 if (vas != VA_STATUS_SUCCESS) {
1381 "handle of image %#x (derived from surface %#x): "
1382 "%d (%s).\n", mapping->image.buf, surface_id,
1383 vas, vaErrorStr(vas));
1386 vas = vaDestroyImage(hwctx->
display, mapping->image.image_id);
1387 if (vas != VA_STATUS_SUCCESS) {
1389 "derived from surface %#x: %d (%s).\n",
1390 surface_id, vas, vaErrorStr(vas));
1400 VAAPIDRMImageBufferMapping *mapping =
NULL;
1401 VASurfaceID surface_id;
1405 surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
1413 vas = vaDeriveImage(hwctx->
display, surface_id,
1415 if (vas != VA_STATUS_SUCCESS) {
1417 "surface %#x: %d (%s).\n",
1418 surface_id, vas, vaErrorStr(vas));
1424 if (vaapi_drm_format_map[
i].va_fourcc ==
1425 mapping->image.format.fourcc)
1430 "VAAPI format %#x.\n", mapping->image.format.fourcc);
1435 mapping->buffer_info.mem_type =
1436 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
1438 mapping->drm_desc.nb_layers =
1439 vaapi_drm_format_map[
i].nb_layer_formats;
1440 if (mapping->drm_desc.nb_layers > 1) {
1441 if (mapping->drm_desc.nb_layers != mapping->image.num_planes) {
1443 "expected format: got %d planes, but expected %d.\n",
1444 mapping->image.num_planes, mapping->drm_desc.nb_layers);
1449 for(p = 0; p < mapping->drm_desc.nb_layers; p++) {
1451 .format = vaapi_drm_format_map[
i].layer_formats[p],
1455 .offset = mapping->image.offsets[p],
1456 .pitch = mapping->image.pitches[p],
1461 mapping->drm_desc.layers[0].format =
1462 vaapi_drm_format_map[
i].layer_formats[0];
1463 mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes;
1464 for (p = 0; p < mapping->image.num_planes; p++) {
1467 .offset = mapping->image.offsets[p],
1468 .pitch = mapping->image.pitches[p],
1473 vas = vaAcquireBufferHandle(hwctx->
display, mapping->image.buf,
1474 &mapping->buffer_info);
1475 if (vas != VA_STATUS_SUCCESS) {
1477 "handle from image %#x (derived from surface %#x): "
1478 "%d (%s).\n", mapping->image.buf, surface_id,
1479 vas, vaErrorStr(vas));
1485 mapping->buffer_info.handle);
1487 mapping->drm_desc.nb_objects = 1;
1489 .fd = mapping->buffer_info.handle,
1490 .size = mapping->image.data_size,
1496 dst,
src, &vaapi_unmap_to_drm_abh,
1501 dst->
data[0] = (uint8_t*)&mapping->drm_desc;
1508 vaReleaseBufferHandle(hwctx->
display, mapping->image.buf);
1510 vaDestroyImage(hwctx->
display, mapping->image.image_id);
1520 #if VA_CHECK_VERSION(1, 1, 0)
1522 err = vaapi_map_to_drm_esh(hwfc, dst,
src,
flags);
1526 #if VA_CHECK_VERSION(0, 36, 0)
1527 return vaapi_map_to_drm_abh(hwfc, dst,
src,
flags);
1537 switch (
src->format) {
1540 return vaapi_map_from_drm(hwfc, dst,
src,
flags);
1553 return vaapi_map_to_drm(hwfc, dst,
src,
flags);
1569 if (priv->x11_display)
1570 XCloseDisplay(priv->x11_display);
1580 static void vaapi_device_log_error(
void *
context,
const char *
message)
1587 static void vaapi_device_log_info(
void *
context,
const char *
message)
1603 vaSetErrorCallback(display, &vaapi_device_log_error,
ctx);
1604 vaSetInfoCallback (display, &vaapi_device_log_info,
ctx);
1610 if (vas != VA_STATUS_SUCCESS) {
1612 "connection: %d (%s).\n", vas, vaErrorStr(vas));
1625 VADisplay display =
NULL;
1627 int try_drm, try_x11, try_all;
1635 ctx->user_opaque = priv;
1640 try_all = try_drm = try_x11 = 0;
1641 if (!strcmp(ent->
value,
"drm")) {
1643 }
else if (!strcmp(ent->
value,
"x11")) {
1652 try_drm = HAVE_VAAPI_DRM;
1653 try_x11 = HAVE_VAAPI_X11;
1657 while (!display && try_drm) {
1663 priv->
drm_fd = open(device, O_RDWR);
1665 av_log(
ctx, loglevel,
"Failed to open %s as "
1666 "DRM device node.\n", device);
1671 int n, max_devices = 8;
1676 for (n = 0; n < max_devices; n++) {
1678 "/dev/dri/renderD%d", 128 + n);
1679 priv->
drm_fd = open(path, O_RDWR);
1682 "DRM render node for device %d.\n", n);
1686 if (kernel_driver) {
1689 if (strcmp(kernel_driver->
value,
info->name)) {
1691 "with non-matching kernel driver (%s).\n",
1693 drmFreeVersion(
info);
1699 "DRM render node for device %d, "
1700 "with matching kernel driver (%s).\n",
1702 drmFreeVersion(
info);
1707 "DRM render node for device %d.\n", n);
1711 if (n >= max_devices)
1715 display = vaGetDisplayDRM(priv->
drm_fd);
1718 "from DRM device %s.\n", device);
1726 if (!display && try_x11) {
1728 priv->x11_display = XOpenDisplay(device);
1729 if (!priv->x11_display) {
1731 "%s.\n", XDisplayName(device));
1733 display = vaGetDisplay(priv->x11_display);
1736 "from X11 display %s.\n", XDisplayName(device));
1741 "X11 display %s.\n", XDisplayName(device));
1749 "device %s.\n", device);
1752 "any default device.\n");
1758 #if VA_CHECK_VERSION(0, 38, 0)
1760 vas = vaSetDriverName(display, ent->
value);
1761 if (vas != VA_STATUS_SUCCESS) {
1763 "%s: %d (%s).\n", ent->
value, vas, vaErrorStr(vas));
1764 vaTerminate(display);
1769 "supported with this VAAPI version.\n");
1787 if (src_hwctx->
fd < 0) {
1789 "device to derive a VA display from.\n");
1795 int node_type = drmGetNodeTypeFromFd(src_hwctx->
fd);
1797 if (node_type < 0) {
1799 "to refer to a DRM device.\n");
1802 if (node_type == DRM_NODE_RENDER) {
1805 render_node = drmGetRenderDeviceNameFromFd(src_hwctx->
fd);
1808 "because the device does not have an "
1809 "associated render node.\n");
1812 fd = open(render_node, O_RDWR);
1815 "because the associated render node "
1816 "could not be opened.\n");
1820 "in place of non-render DRM device.\n",
1833 if (fd != src_hwctx->
fd) {
1840 if (fd == src_hwctx->
fd) {
1848 ctx->user_opaque = priv;
1851 display = vaGetDisplayDRM(fd);