24 # include <initguid.h>
27 # include <va/va_win32.h>
31 # include <va/va_x11.h>
34 # include <va/va_drm.h>
38 # include <va/va_drmcommon.h>
40 # include <drm_fourcc.h>
41 # ifndef DRM_FORMAT_MOD_INVALID
42 # define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
119 } VAAPIFormatDescriptor;
121 #define MAP(va, rt, av, swap_uv) { \
123 VA_RT_FORMAT_ ## rt, \
130 MAP(NV12, YUV420, NV12, 0),
131 #ifdef VA_FOURCC_I420
132 MAP(I420, YUV420, YUV420P, 0),
134 MAP(YV12, YUV420, YUV420P, 1),
135 MAP(IYUV, YUV420, YUV420P, 0),
136 MAP(422
H, YUV422, YUV422P, 0),
137 #ifdef VA_FOURCC_YV16
138 MAP(YV16, YUV422, YUV422P, 1),
140 MAP(UYVY, YUV422, UYVY422, 0),
141 MAP(YUY2, YUV422, YUYV422, 0),
142 #ifdef VA_FOURCC_Y210
143 MAP(Y210, YUV422_10, Y210, 0),
145 #ifdef VA_FOURCC_Y212
146 MAP(Y212, YUV422_12, Y212, 0),
148 MAP(411
P, YUV411, YUV411P, 0),
149 MAP(422
V, YUV422, YUV440P, 0),
150 MAP(444
P, YUV444, YUV444P, 0),
151 #ifdef VA_FOURCC_XYUV
152 MAP(XYUV, YUV444, VUYX, 0),
154 MAP(Y800, YUV400, GRAY8, 0),
155 #ifdef VA_FOURCC_P010
156 MAP(P010, YUV420_10BPP, P010, 0),
158 #ifdef VA_FOURCC_P012
159 MAP(P012, YUV420_12, P012, 0),
161 MAP(BGRA, RGB32, BGRA, 0),
162 MAP(BGRX, RGB32, BGR0, 0),
164 MAP(RGBX, RGB32, RGB0, 0),
165 #ifdef VA_FOURCC_ABGR
166 MAP(ABGR, RGB32, ABGR, 0),
167 MAP(XBGR, RGB32, 0BGR, 0),
169 MAP(ARGB, RGB32, ARGB, 0),
170 MAP(XRGB, RGB32, 0
RGB, 0),
171 #ifdef VA_FOURCC_X2R10G10B10
172 MAP(X2R10G10B10, RGB32_10, X2RGB10, 0),
174 #ifdef VA_FOURCC_Y410
177 MAP(Y410, YUV444_10, XV30, 0),
179 #ifdef VA_FOURCC_Y412
182 MAP(Y412, YUV444_12, XV36, 0),
187 static const VAAPIFormatDescriptor *
197 static const VAAPIFormatDescriptor *
206 for (; prev < end; prev++)
214 const VAAPIFormatDescriptor *
desc;
217 return desc->pix_fmt;
224 const VAAPIFormatDescriptor **_desc,
225 VAImageFormat **image_format)
228 const VAAPIFormatDescriptor *
desc =
NULL;
232 for (
i = 0;
i <
ctx->nb_formats;
i++) {
233 if (
ctx->formats[
i].fourcc ==
desc->fourcc) {
237 *image_format = &
ctx->formats[
i].image_format;
248 VAImageFormat **image_format)
256 const void *hwconfig,
262 VASurfaceAttrib *attr_list =
NULL;
266 int err,
i, j, attr_count, pix_fmt_count;
271 vas = vaQuerySurfaceAttributes(hwctx->
display,
config->config_id,
273 if (vas != VA_STATUS_SUCCESS) {
275 "%d (%s).\n", vas, vaErrorStr(vas));
280 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
286 vas = vaQuerySurfaceAttributes(hwctx->
display,
config->config_id,
287 attr_list, &attr_count);
288 if (vas != VA_STATUS_SUCCESS) {
290 "%d (%s).\n", vas, vaErrorStr(vas));
296 for (
i = 0;
i < attr_count;
i++) {
297 switch (attr_list[
i].
type) {
298 case VASurfaceAttribPixelFormat:
299 fourcc = attr_list[
i].value.value.i;
307 case VASurfaceAttribMinWidth:
308 constraints->
min_width = attr_list[
i].value.value.i;
310 case VASurfaceAttribMinHeight:
311 constraints->
min_height = attr_list[
i].value.value.i;
313 case VASurfaceAttribMaxWidth:
314 constraints->
max_width = attr_list[
i].value.value.i;
316 case VASurfaceAttribMaxHeight:
317 constraints->
max_height = attr_list[
i].value.value.i;
321 if (pix_fmt_count == 0) {
333 for (
i = j = 0;
i < attr_count;
i++) {
336 if (attr_list[
i].
type != VASurfaceAttribPixelFormat)
338 fourcc = attr_list[
i].value.value.i;
344 for (k = 0; k < j; k++) {
363 for (
i = j = 0;
i <
ctx->nb_formats;
i++) {
366 for (k = 0; k < j; k++) {
392 static const struct {
397 #if !VA_CHECK_VERSION(1, 0, 0)
400 "Intel i965 (Quick Sync)",
412 "Splitted-Desktop Systems VDPAU backend for VA-API",
421 VAImageFormat *image_list =
NULL;
423 const char *vendor_string;
424 int err,
i, image_count;
428 image_count = vaMaxNumImageFormats(hwctx->
display);
429 if (image_count <= 0) {
433 image_list =
av_malloc(image_count *
sizeof(*image_list));
438 vas = vaQueryImageFormats(hwctx->
display, image_list, &image_count);
439 if (vas != VA_STATUS_SUCCESS) {
450 for (
i = 0;
i < image_count;
i++) {
461 ctx->formats[
ctx->nb_formats].image_format = image_list[
i];
466 vendor_string = vaQueryVendorString(hwctx->
display);
478 if (strstr(vendor_string,
481 "as known nonstandard driver \"%s\", setting "
492 "nonstandard list, using standard behaviour.\n");
496 "assuming standard behaviour.\n");
519 VASurfaceID surface_id;
522 surface_id = (VASurfaceID)(uintptr_t)
data;
524 vas = vaDestroySurfaces(hwctx->
display, &surface_id, 1);
525 if (vas != VA_STATUS_SUCCESS) {
527 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
537 VASurfaceID surface_id;
545 vas = vaCreateSurfaces(hwctx->
display,
ctx->rt_format,
548 ctx->attributes,
ctx->nb_attributes);
549 if (vas != VA_STATUS_SUCCESS) {
551 "%d (%s).\n", vas, vaErrorStr(vas));
560 vaDestroySurfaces(hwctx->
display, &surface_id, 1);
580 const VAAPIFormatDescriptor *
desc =
NULL;
581 VAImageFormat *expected_format =
NULL;
583 VASurfaceID test_surface_id;
589 &
desc, &expected_format);
602 int need_pixel_format = 1;
604 if (avfc->
attributes[
i].type == VASurfaceAttribMemoryType)
605 need_memory_type = 0;
606 if (avfc->
attributes[
i].type == VASurfaceAttribPixelFormat)
607 need_pixel_format = 0;
613 sizeof(*
ctx->attributes));
614 if (!
ctx->attributes) {
621 if (need_memory_type) {
622 ctx->attributes[
i++] = (VASurfaceAttrib) {
623 .type = VASurfaceAttribMemoryType,
624 .
flags = VA_SURFACE_ATTRIB_SETTABLE,
625 .value.type = VAGenericValueTypeInteger,
626 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
629 if (need_pixel_format) {
630 ctx->attributes[
i++] = (VASurfaceAttrib) {
631 .type = VASurfaceAttribPixelFormat,
632 .
flags = VA_SURFACE_ATTRIB_SETTABLE,
633 .value.type = VAGenericValueTypeInteger,
634 .value.value.i =
desc->fourcc,
640 ctx->nb_attributes = 0;
643 ctx->rt_format =
desc->rt_format;
679 "user-configured buffer pool.\n");
687 "internal buffer pool.\n");
692 test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
694 ctx->derive_works = 0;
695 if (expected_format) {
696 vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
697 if (vas == VA_STATUS_SUCCESS) {
698 if (expected_format->fourcc == test_image.format.fourcc) {
700 ctx->derive_works = 1;
703 "derived image format %08x does not match "
704 "expected format %08x.\n",
705 expected_format->fourcc, test_image.format.fourcc);
707 vaDestroyImage(hwctx->
display, test_image.image_id);
710 "deriving image does not work: "
711 "%d (%s).\n", vas, vaErrorStr(vas));
715 "image format is not supported.\n");
757 int i, k, sw_format_available;
759 sw_format_available = 0;
760 for (
i = 0;
i <
ctx->nb_formats;
i++) {
762 sw_format_available = 1;
769 if (sw_format_available) {
775 for (
i = 0;
i <
ctx->nb_formats;
i++) {
792 VASurfaceID surface_id;
795 surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
798 vas = vaUnmapBuffer(hwctx->
display,
map->image.buf);
799 if (vas != VA_STATUS_SUCCESS) {
801 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
806 vas = vaPutImage(hwctx->
display, surface_id,
map->image.image_id,
809 if (vas != VA_STATUS_SUCCESS) {
811 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
815 vas = vaDestroyImage(hwctx->
display,
map->image.image_id);
816 if (vas != VA_STATUS_SUCCESS) {
818 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
829 VASurfaceID surface_id;
830 const VAAPIFormatDescriptor *
desc;
831 VAImageFormat *image_format;
834 void *address =
NULL;
836 #if VA_CHECK_VERSION(1, 21, 0)
837 uint32_t vaflags = 0;
840 surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
864 map->image.image_id = VA_INVALID_ID;
866 vas = vaSyncSurface(hwctx->
display, surface_id);
867 if (vas != VA_STATUS_SUCCESS) {
869 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
883 vas = vaDeriveImage(hwctx->
display, surface_id, &
map->image);
884 if (vas != VA_STATUS_SUCCESS) {
886 "surface %#x: %d (%s).\n",
887 surface_id, vas, vaErrorStr(vas));
891 if (
map->image.format.fourcc != image_format->fourcc) {
893 "is in wrong format: expected %#08x, got %#08x.\n",
894 surface_id, image_format->fourcc,
map->image.format.fourcc);
900 vas = vaCreateImage(hwctx->
display, image_format,
902 if (vas != VA_STATUS_SUCCESS) {
904 "surface %#x: %d (%s).\n",
905 surface_id, vas, vaErrorStr(vas));
910 vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
912 if (vas != VA_STATUS_SUCCESS) {
914 "surface %#x: %d (%s).\n",
915 surface_id, vas, vaErrorStr(vas));
922 #if VA_CHECK_VERSION(1, 21, 0)
924 vaflags |= VA_MAPBUFFER_FLAG_READ;
926 vaflags |= VA_MAPBUFFER_FLAG_WRITE;
928 vas = vaMapBuffer2(hwctx->
display,
map->image.buf, &address, vaflags);
930 vas = vaMapBuffer(hwctx->
display,
map->image.buf, &address);
932 if (vas != VA_STATUS_SUCCESS) {
934 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
945 dst->height =
src->height;
947 for (
i = 0;
i <
map->image.num_planes;
i++) {
948 dst->data[
i] = (uint8_t*)address +
map->image.offsets[
i];
949 dst->linesize[
i] =
map->image.pitches[
i];
953 if (
desc &&
desc->chroma_planes_swapped) {
963 vaUnmapBuffer(hwctx->
display,
map->image.buf);
964 if (
map->image.image_id != VA_INVALID_ID)
965 vaDestroyImage(hwctx->
display,
map->image.image_id);
983 map->format =
dst->format;
990 map->height =
dst->height;
1014 map->format =
src->format;
1021 map->height =
src->height;
1051 #define DRM_MAP(va, layers, ...) { \
1056 static const struct {
1058 int nb_layer_formats;
1060 } vaapi_drm_format_map[] = {
1061 #ifdef DRM_FORMAT_R8
1062 DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88),
1063 DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_GR88),
1065 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
1066 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
1067 DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616),
1069 #if defined(VA_FOURCC_P012) && defined(DRM_FORMAT_R16)
1070 DRM_MAP(P012, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616),
1072 DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888),
1073 DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888),
1074 DRM_MAP(
RGBA, 1, DRM_FORMAT_ABGR8888),
1075 DRM_MAP(RGBX, 1, DRM_FORMAT_XBGR8888),
1076 #ifdef VA_FOURCC_ABGR
1077 DRM_MAP(ABGR, 1, DRM_FORMAT_RGBA8888),
1078 DRM_MAP(XBGR, 1, DRM_FORMAT_RGBX8888),
1080 DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888),
1081 DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888),
1082 #if defined(VA_FOURCC_XYUV) && defined(DRM_FORMAT_XYUV8888)
1083 DRM_MAP(XYUV, 1, DRM_FORMAT_XYUV8888),
1085 #if defined(VA_FOURCC_Y412) && defined(DRM_FORMAT_XVYU2101010)
1086 DRM_MAP(Y410, 1, DRM_FORMAT_XVYU2101010),
1088 #if defined(VA_FOURCC_Y412) && defined(DRM_FORMAT_XVYU12_16161616)
1089 DRM_MAP(Y412, 1, DRM_FORMAT_XVYU12_16161616),
1091 #if defined(VA_FOURCC_X2R10G10B10) && defined(DRM_FORMAT_XRGB2101010)
1092 DRM_MAP(X2R10G10B10, 1, DRM_FORMAT_XRGB2101010),
1102 VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->
priv;
1106 vaDestroySurfaces(dst_dev->
display, &surface_id, 1);
1112 #if VA_CHECK_VERSION(1, 1, 0)
1122 const VAAPIFormatDescriptor *format_desc;
1123 VASurfaceID surface_id;
1124 VAStatus vas = VA_STATUS_SUCCESS;
1128 #
if !VA_CHECK_VERSION(1, 1, 0)
1129 unsigned long buffer_handle;
1130 VASurfaceAttribExternalBuffers buffer_desc;
1131 VASurfaceAttrib attrs[2] = {
1133 .type = VASurfaceAttribMemoryType,
1134 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1135 .value.type = VAGenericValueTypeInteger,
1136 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
1139 .type = VASurfaceAttribExternalBufferDescriptor,
1140 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1141 .value.type = VAGenericValueTypePointer,
1142 .value.value.p = &buffer_desc,
1149 if (
desc->nb_objects != 1) {
1151 "made from a single DRM object.\n");
1157 if (
desc->nb_layers != vaapi_drm_format_map[
i].nb_layer_formats)
1159 for (j = 0; j <
desc->nb_layers; j++) {
1160 if (
desc->layers[j].format !=
1161 vaapi_drm_format_map[
i].layer_formats[j])
1164 if (j !=
desc->nb_layers)
1166 va_fourcc = vaapi_drm_format_map[
i].va_fourcc;
1176 "%08x.\n",
desc->objects[0].fd, va_fourcc);
1181 #if VA_CHECK_VERSION(1, 1, 0)
1185 VADRMPRIMESurfaceDescriptor prime_desc;
1186 VASurfaceAttrib prime_attrs[2] = {
1188 .type = VASurfaceAttribMemoryType,
1189 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1190 .value.type = VAGenericValueTypeInteger,
1191 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
1194 .type = VASurfaceAttribExternalBufferDescriptor,
1195 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1196 .value.type = VAGenericValueTypePointer,
1197 .value.value.p = &prime_desc,
1200 prime_desc.fourcc = va_fourcc;
1201 prime_desc.width = src_fc->
width;
1202 prime_desc.height = src_fc->
height;
1203 prime_desc.num_objects =
desc->nb_objects;
1204 for (
i = 0;
i <
desc->nb_objects; ++
i) {
1205 prime_desc.objects[
i].fd =
desc->objects[
i].fd;
1206 prime_desc.objects[
i].size =
desc->objects[
i].size;
1207 prime_desc.objects[
i].drm_format_modifier =
1208 desc->objects[
i].format_modifier;
1211 prime_desc.num_layers =
desc->nb_layers;
1212 for (
i = 0;
i <
desc->nb_layers; ++
i) {
1213 prime_desc.layers[
i].drm_format =
desc->layers[
i].format;
1214 prime_desc.layers[
i].num_planes =
desc->layers[
i].nb_planes;
1215 for (j = 0; j <
desc->layers[
i].nb_planes; ++j) {
1216 prime_desc.layers[
i].object_index[j] =
1217 desc->layers[
i].planes[j].object_index;
1218 prime_desc.layers[
i].offset[j] =
desc->layers[
i].planes[j].offset;
1219 prime_desc.layers[
i].pitch[j] =
desc->layers[
i].planes[j].pitch;
1222 if (format_desc->chroma_planes_swapped &&
1223 desc->layers[
i].nb_planes == 3) {
1224 FFSWAP(uint32_t, prime_desc.layers[
i].pitch[1],
1225 prime_desc.layers[
i].pitch[2]);
1226 FFSWAP(uint32_t, prime_desc.layers[
i].offset[1],
1227 prime_desc.layers[
i].offset[2]);
1237 vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
1238 src->width,
src->height, &surface_id, 1,
1240 if (vas != VA_STATUS_SUCCESS)
1244 if (!use_prime2 || vas != VA_STATUS_SUCCESS) {
1246 uintptr_t buffer_handle;
1247 VASurfaceAttribExternalBuffers buffer_desc;
1248 VASurfaceAttrib buffer_attrs[2] = {
1250 .type = VASurfaceAttribMemoryType,
1251 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1252 .value.type = VAGenericValueTypeInteger,
1253 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
1256 .type = VASurfaceAttribExternalBufferDescriptor,
1257 .flags = VA_SURFACE_ATTRIB_SETTABLE,
1258 .value.type = VAGenericValueTypePointer,
1259 .value.value.p = &buffer_desc,
1263 buffer_handle =
desc->objects[0].fd;
1264 buffer_desc.pixel_format = va_fourcc;
1265 buffer_desc.width = src_fc->
width;
1266 buffer_desc.height = src_fc->
height;
1267 buffer_desc.data_size =
desc->objects[0].size;
1268 buffer_desc.buffers = &buffer_handle;
1269 buffer_desc.num_buffers = 1;
1270 buffer_desc.flags = 0;
1273 for (
i = 0;
i <
desc->nb_layers;
i++) {
1274 for (j = 0; j <
desc->layers[
i].nb_planes; j++) {
1275 buffer_desc.pitches[k] =
desc->layers[
i].planes[j].pitch;
1276 buffer_desc.offsets[k] =
desc->layers[
i].planes[j].offset;
1280 buffer_desc.num_planes = k;
1282 if (format_desc->chroma_planes_swapped &&
1283 buffer_desc.num_planes == 3) {
1284 FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]);
1285 FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
1288 vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
1294 buffer_handle =
desc->objects[0].fd;
1295 buffer_desc.pixel_format = va_fourcc;
1296 buffer_desc.width = src_fc->
width;
1297 buffer_desc.height = src_fc->
height;
1298 buffer_desc.data_size =
desc->objects[0].size;
1299 buffer_desc.buffers = &buffer_handle;
1300 buffer_desc.num_buffers = 1;
1301 buffer_desc.flags = 0;
1304 for (
i = 0;
i <
desc->nb_layers;
i++) {
1305 for (j = 0; j <
desc->layers[
i].nb_planes; j++) {
1306 buffer_desc.pitches[k] =
desc->layers[
i].planes[j].pitch;
1307 buffer_desc.offsets[k] =
desc->layers[
i].planes[j].offset;
1311 buffer_desc.num_planes = k;
1313 if (format_desc->chroma_planes_swapped &&
1314 buffer_desc.num_planes == 3) {
1315 FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]);
1316 FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
1319 vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
1324 if (vas != VA_STATUS_SUCCESS) {
1326 "object: %d (%s).\n", vas, vaErrorStr(vas));
1332 &vaapi_unmap_from_drm,
1333 (
void*)(uintptr_t)surface_id);
1338 dst->height =
src->height;
1339 dst->data[3] = (uint8_t*)(uintptr_t)surface_id;
1342 "surface %#x.\n",
desc->objects[0].fd, surface_id);
1347 #if VA_CHECK_VERSION(1, 1, 0)
1364 VASurfaceID surface_id;
1366 VADRMPRIMESurfaceDescriptor va_desc;
1368 uint32_t export_flags;
1371 surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
1373 export_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS;
1375 export_flags |= VA_EXPORT_SURFACE_READ_ONLY;
1377 vas = vaSyncSurface(hwctx->
display, surface_id);
1378 if (vas != VA_STATUS_SUCCESS) {
1380 "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
1386 export_flags |= VA_EXPORT_SURFACE_WRITE_ONLY;
1388 vas = vaExportSurfaceHandle(hwctx->
display, surface_id,
1389 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
1390 export_flags, &va_desc);
1391 if (vas != VA_STATUS_SUCCESS) {
1392 if (vas == VA_STATUS_ERROR_UNIMPLEMENTED)
1395 "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
1407 for (
i = 0;
i < va_desc.num_objects;
i++) {
1411 va_desc.objects[
i].drm_format_modifier;
1413 drm_desc->
nb_layers = va_desc.num_layers;
1414 for (
i = 0;
i < va_desc.num_layers;
i++) {
1417 for (j = 0; j < va_desc.layers[
i].num_planes; j++) {
1419 va_desc.layers[
i].object_index[j];
1421 va_desc.layers[
i].offset[j];
1423 va_desc.layers[
i].pitch[j];
1428 &vaapi_unmap_to_drm_esh, drm_desc);
1433 dst->height =
src->height;
1434 dst->data[0] = (uint8_t*)drm_desc;
1439 for (
i = 0;
i < va_desc.num_objects;
i++)
1440 close(va_desc.objects[
i].fd);
1446 #if VA_CHECK_VERSION(0, 36, 0)
1447 typedef struct VAAPIDRMImageBufferMapping {
1449 VABufferInfo buffer_info;
1452 } VAAPIDRMImageBufferMapping;
1458 VAAPIDRMImageBufferMapping *mapping = hwmap->
priv;
1459 VASurfaceID surface_id;
1462 surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
1469 vas = vaReleaseBufferHandle(hwctx->
display, mapping->image.buf);
1470 if (vas != VA_STATUS_SUCCESS) {
1472 "handle of image %#x (derived from surface %#x): "
1473 "%d (%s).\n", mapping->image.buf, surface_id,
1474 vas, vaErrorStr(vas));
1477 vas = vaDestroyImage(hwctx->
display, mapping->image.image_id);
1478 if (vas != VA_STATUS_SUCCESS) {
1480 "derived from surface %#x: %d (%s).\n",
1481 surface_id, vas, vaErrorStr(vas));
1491 VAAPIDRMImageBufferMapping *mapping =
NULL;
1492 VASurfaceID surface_id;
1496 surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
1504 vas = vaDeriveImage(hwctx->
display, surface_id,
1506 if (vas != VA_STATUS_SUCCESS) {
1508 "surface %#x: %d (%s).\n",
1509 surface_id, vas, vaErrorStr(vas));
1515 if (vaapi_drm_format_map[
i].va_fourcc ==
1516 mapping->image.format.fourcc)
1521 "VAAPI format %#x.\n", mapping->image.format.fourcc);
1526 mapping->buffer_info.mem_type =
1527 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
1529 mapping->drm_desc.nb_layers =
1530 vaapi_drm_format_map[
i].nb_layer_formats;
1531 if (mapping->drm_desc.nb_layers > 1) {
1532 if (mapping->drm_desc.nb_layers != mapping->image.num_planes) {
1534 "expected format: got %d planes, but expected %d.\n",
1535 mapping->image.num_planes, mapping->drm_desc.nb_layers);
1540 for(
p = 0;
p < mapping->drm_desc.nb_layers;
p++) {
1542 .format = vaapi_drm_format_map[
i].layer_formats[
p],
1546 .offset = mapping->image.offsets[
p],
1547 .pitch = mapping->image.pitches[
p],
1552 mapping->drm_desc.layers[0].format =
1553 vaapi_drm_format_map[
i].layer_formats[0];
1554 mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes;
1555 for (
p = 0;
p < mapping->image.num_planes;
p++) {
1558 .offset = mapping->image.offsets[
p],
1559 .pitch = mapping->image.pitches[
p],
1564 vas = vaAcquireBufferHandle(hwctx->
display, mapping->image.buf,
1565 &mapping->buffer_info);
1566 if (vas != VA_STATUS_SUCCESS) {
1568 "handle from image %#x (derived from surface %#x): "
1569 "%d (%s).\n", mapping->image.buf, surface_id,
1570 vas, vaErrorStr(vas));
1576 mapping->buffer_info.handle);
1578 mapping->drm_desc.nb_objects = 1;
1580 .fd = mapping->buffer_info.handle,
1581 .size = mapping->image.data_size,
1587 dst,
src, &vaapi_unmap_to_drm_abh,
1592 dst->data[0] = (uint8_t*)&mapping->drm_desc;
1594 dst->height =
src->height;
1599 vaReleaseBufferHandle(hwctx->
display, mapping->image.buf);
1601 vaDestroyImage(hwctx->
display, mapping->image.image_id);
1611 #if VA_CHECK_VERSION(1, 1, 0)
1613 err = vaapi_map_to_drm_esh(hwfc,
dst,
src,
flags);
1617 #if VA_CHECK_VERSION(0, 36, 0)
1618 return vaapi_map_to_drm_abh(hwfc,
dst,
src,
flags);
1628 switch (
src->format) {
1641 switch (
dst->format) {
1660 if (priv->x11_display)
1661 XCloseDisplay(priv->x11_display);
1671 static void vaapi_device_log_error(
void *
context,
const char *
message)
1678 static void vaapi_device_log_info(
void *
context,
const char *
message)
1694 vaSetErrorCallback(display, &vaapi_device_log_error,
ctx);
1695 vaSetInfoCallback (display, &vaapi_device_log_info,
ctx);
1700 vas = vaInitialize(display, &major, &minor);
1701 if (vas != VA_STATUS_SUCCESS) {
1703 "connection: %d (%s).\n", vas, vaErrorStr(vas));
1707 "version %d.%d\n", major, minor);
1716 VADisplay display =
NULL;
1718 int try_drm, try_x11, try_win32, try_all;
1726 ctx->user_opaque = priv;
1731 try_all = try_drm = try_x11 = try_win32 = 0;
1732 if (!strcmp(ent->
value,
"drm")) {
1734 }
else if (!strcmp(ent->
value,
"x11")) {
1736 }
else if (!strcmp(ent->
value,
"win32")) {
1745 try_drm = HAVE_VAAPI_DRM;
1746 try_x11 = HAVE_VAAPI_X11;
1747 try_win32 = HAVE_VAAPI_WIN32;
1751 while (!display && try_drm) {
1757 priv->
drm_fd = open(device, O_RDWR);
1759 av_log(
ctx, loglevel,
"Failed to open %s as "
1760 "DRM device node.\n", device);
1765 int n, max_devices = 8;
1773 for (n = 0; n < max_devices; n++) {
1775 "/dev/dri/renderD%d", 128 + n);
1776 priv->
drm_fd = open(path, O_RDWR);
1778 if (errno == ENOENT) {
1779 if (n != max_devices - 1) {
1781 "No render device %s, try next device for "
1782 "DRM render node.\n", path);
1787 "for DRM render node.\n");
1790 "DRM render node for device %d.\n", n);
1797 "Failed to get DRM version for device %d.\n", n);
1802 if (kernel_driver) {
1803 if (strcmp(kernel_driver->
value,
info->name)) {
1805 "with non-matching kernel driver (%s).\n",
1807 drmFreeVersion(
info);
1813 "DRM render node for device %d, "
1814 "with matching kernel driver (%s).\n",
1816 drmFreeVersion(
info);
1819 }
else if (!strcmp(
info->name,
"vgem")) {
1821 "Skipping vgem node for device %d.\n", n);
1822 drmFreeVersion(
info);
1826 }
else if (vendor_id) {
1827 drmDevicePtr device;
1829 if (drmGetDevice(priv->
drm_fd, &device)) {
1831 "Failed to get DRM device info for device %d.\n", n);
1834 drmFreeVersion(
info);
1838 snprintf(drm_vendor,
sizeof(drm_vendor),
"0x%x", device->deviceinfo.pci->vendor_id);
1839 if (strcmp(vendor_id->
value, drm_vendor)) {
1841 "with non-matching vendor id (%s).\n",
1842 n, vendor_id->
value);
1843 drmFreeDevice(&device);
1846 drmFreeVersion(
info);
1850 "DRM render node for device %d, "
1851 "with matching vendor id (%s).\n",
1852 n, vendor_id->
value);
1853 drmFreeDevice(&device);
1854 drmFreeVersion(
info);
1857 drmFreeVersion(
info);
1860 "DRM render node for device %d.\n", n);
1863 if (n >= max_devices)
1867 display = vaGetDisplayDRM(priv->
drm_fd);
1870 "from DRM device %s.\n", device);
1878 if (!display && try_x11) {
1880 priv->x11_display = XOpenDisplay(device);
1881 if (!priv->x11_display) {
1883 "%s.\n", XDisplayName(device));
1885 display = vaGetDisplay(priv->x11_display);
1888 "from X11 display %s.\n", XDisplayName(device));
1893 "X11 display %s.\n", XDisplayName(device));
1898 #if HAVE_VAAPI_WIN32
1899 if (!display && try_win32) {
1902 display = vaGetDisplayWin32(
NULL);
1904 IDXGIFactory2 *pDXGIFactory =
NULL;
1905 IDXGIAdapter *pAdapter =
NULL;
1907 HANDLE dxgi = dlopen(
"dxgi.dll", 0);
1914 if (!pfnCreateDXGIFactory) {
1925 if (SUCCEEDED(pfnCreateDXGIFactory(&IID_IDXGIFactory2,
1926 (
void **)&pDXGIFactory))) {
1927 int adapter = atoi(device);
1928 if (SUCCEEDED(IDXGIFactory2_EnumAdapters(pDXGIFactory,
1931 DXGI_ADAPTER_DESC
desc;
1932 if (SUCCEEDED(IDXGIAdapter2_GetDesc(pAdapter, &
desc))) {
1934 "Using device %04x:%04x (%ls) - LUID %lu %ld.\n",
1936 desc.AdapterLuid.LowPart,
1937 desc.AdapterLuid.HighPart);
1938 display = vaGetDisplayWin32(&
desc.AdapterLuid);
1940 IDXGIAdapter_Release(pAdapter);
1942 IDXGIFactory2_Release(pDXGIFactory);
1951 "from Win32 display.\n");
1956 "Win32 display.\n");
1963 "device %s.\n", device);
1966 "any default device.\n");
1972 #if VA_CHECK_VERSION(0, 38, 0)
1974 vas = vaSetDriverName(display, ent->
value);
1975 if (vas != VA_STATUS_SUCCESS) {
1977 "%s: %d (%s).\n", ent->
value, vas, vaErrorStr(vas));
1978 vaTerminate(display);
1983 "supported with this VAAPI version.\n");
2001 if (src_hwctx->
fd < 0) {
2003 "device to derive a VA display from.\n");
2009 int node_type = drmGetNodeTypeFromFd(src_hwctx->
fd);
2011 if (node_type < 0) {
2013 "to refer to a DRM device.\n");
2016 if (node_type == DRM_NODE_RENDER) {
2019 render_node = drmGetRenderDeviceNameFromFd(src_hwctx->
fd);
2022 "because the device does not have an "
2023 "associated render node.\n");
2026 fd = open(render_node, O_RDWR);
2029 "because the associated render node "
2030 "could not be opened.\n");
2034 "in place of non-render DRM device.\n",
2047 if (fd != src_hwctx->
fd) {
2054 if (fd == src_hwctx->
fd) {
2062 ctx->user_opaque = priv;
2065 display = vaGetDisplayDRM(fd);