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) 
  108 } VAAPIFormatDescriptor;
 
  110 #define MAP(va, rt, av, swap_uv) { \ 
  112         VA_RT_FORMAT_ ## rt, \ 
  119     MAP(NV12, YUV420,  NV12,    0),
 
  120 #ifdef VA_FOURCC_I420 
  121     MAP(I420, YUV420,  YUV420P, 0),
 
  123     MAP(YV12, YUV420,  YUV420P, 1),
 
  124     MAP(IYUV, YUV420,  YUV420P, 0),
 
  125     MAP(422
H, YUV422,  YUV422P, 0),
 
  126 #ifdef VA_FOURCC_YV16 
  127     MAP(YV16, YUV422,  YUV422P, 1),
 
  129     MAP(UYVY, YUV422,  UYVY422, 0),
 
  130     MAP(YUY2, YUV422,  YUYV422, 0),
 
  131 #ifdef VA_FOURCC_Y210 
  132     MAP(Y210, YUV422_10,  Y210, 0),
 
  134 #ifdef VA_FOURCC_Y212 
  135     MAP(Y212, YUV422_12,  Y212, 0),
 
  137     MAP(411
P, YUV411,  YUV411P, 0),
 
  138     MAP(422
V, YUV422,  YUV440P, 0),
 
  139     MAP(444
P, YUV444,  YUV444P, 0),
 
  140 #ifdef VA_FOURCC_XYUV 
  141     MAP(XYUV, YUV444,  VUYX,    0),
 
  143     MAP(Y800, YUV400,  GRAY8,   0),
 
  144 #ifdef VA_FOURCC_P010 
  145     MAP(P010, YUV420_10BPP, P010, 0),
 
  147 #ifdef VA_FOURCC_P012 
  148     MAP(P012, YUV420_12, P012, 0),
 
  150     MAP(BGRA, RGB32,   BGRA, 0),
 
  151     MAP(BGRX, RGB32,   BGR0, 0),
 
  153     MAP(RGBX, RGB32,   RGB0, 0),
 
  154 #ifdef VA_FOURCC_ABGR 
  155     MAP(ABGR, RGB32,   ABGR, 0),
 
  156     MAP(XBGR, RGB32,   0BGR, 0),
 
  158     MAP(ARGB, RGB32,   ARGB, 0),
 
  159     MAP(XRGB, RGB32,   0RGB, 0),
 
  160 #ifdef VA_FOURCC_X2R10G10B10 
  161     MAP(X2R10G10B10, RGB32_10, X2RGB10, 0),
 
  163 #ifdef VA_FOURCC_Y410 
  166     MAP(Y410, YUV444_10,  XV30, 0),
 
  168 #ifdef VA_FOURCC_Y412 
  171     MAP(Y412, YUV444_12,  XV36, 0),
 
  176 static const VAAPIFormatDescriptor *
 
  186 static const VAAPIFormatDescriptor *
 
  198     const VAAPIFormatDescriptor *
desc;
 
  201         return desc->pix_fmt;
 
  208                                   VAImageFormat **image_format)
 
  213     for (
i = 0; 
i < 
ctx->nb_formats; 
i++) {
 
  216                 *image_format = &
ctx->formats[
i].image_format;
 
  224                                         const void *hwconfig,
 
  230     VASurfaceAttrib *attr_list = 
NULL;
 
  234     int err, 
i, j, attr_count, pix_fmt_count;
 
  239         vas = vaQuerySurfaceAttributes(hwctx->
display, 
config->config_id,
 
  241         if (vas != VA_STATUS_SUCCESS) {
 
  243                    "%d (%s).\n", vas, vaErrorStr(vas));
 
  248         attr_list = 
av_malloc(attr_count * 
sizeof(*attr_list));
 
  254         vas = vaQuerySurfaceAttributes(hwctx->
display, 
config->config_id,
 
  255                                        attr_list, &attr_count);
 
  256         if (vas != VA_STATUS_SUCCESS) {
 
  258                    "%d (%s).\n", vas, vaErrorStr(vas));
 
  264         for (
i = 0; 
i < attr_count; 
i++) {
 
  265             switch (attr_list[
i].
type) {
 
  266             case VASurfaceAttribPixelFormat:
 
  267                 fourcc = attr_list[
i].value.value.i;
 
  275             case VASurfaceAttribMinWidth:
 
  276                 constraints->
min_width  = attr_list[
i].value.value.i;
 
  278             case VASurfaceAttribMinHeight:
 
  279                 constraints->
min_height = attr_list[
i].value.value.i;
 
  281             case VASurfaceAttribMaxWidth:
 
  282                 constraints->
max_width  = attr_list[
i].value.value.i;
 
  284             case VASurfaceAttribMaxHeight:
 
  285                 constraints->
max_height = attr_list[
i].value.value.i;
 
  289         if (pix_fmt_count == 0) {
 
  301             for (
i = j = 0; 
i < attr_count; 
i++) {
 
  304                 if (attr_list[
i].
type != VASurfaceAttribPixelFormat)
 
  306                 fourcc = attr_list[
i].value.value.i;
 
  312                 for (k = 0; k < j; k++) {
 
  331         for (
i = j = 0; 
i < 
ctx->nb_formats; 
i++) {
 
  334             for (k = 0; k < j; k++) {
 
  360 static const struct {
 
  365 #if !VA_CHECK_VERSION(1, 0, 0) 
  368         "Intel i965 (Quick Sync)",
 
  380         "Splitted-Desktop Systems VDPAU backend for VA-API",
 
  389     VAImageFormat *image_list = 
NULL;
 
  391     const char *vendor_string;
 
  392     int err, 
i, image_count;
 
  396     image_count = vaMaxNumImageFormats(hwctx->
display);
 
  397     if (image_count <= 0) {
 
  401     image_list = 
av_malloc(image_count * 
sizeof(*image_list));
 
  406     vas = vaQueryImageFormats(hwctx->
display, image_list, &image_count);
 
  407     if (vas != VA_STATUS_SUCCESS) {
 
  418     for (
i = 0; 
i < image_count; 
i++) {
 
  428             ctx->formats[
ctx->nb_formats].image_format = image_list[
i];
 
  433     vendor_string = vaQueryVendorString(hwctx->
display);
 
  445                 if (strstr(vendor_string,
 
  448                            "as known nonstandard driver \"%s\", setting " 
  459                        "nonstandard list, using standard behaviour.\n");
 
  463                    "assuming standard behaviour.\n");
 
  486     VASurfaceID surface_id;
 
  489     surface_id = (VASurfaceID)(uintptr_t)
data;
 
  491     vas = vaDestroySurfaces(hwctx->
display, &surface_id, 1);
 
  492     if (vas != VA_STATUS_SUCCESS) {
 
  494                "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
  504     VASurfaceID surface_id;
 
  512     vas = vaCreateSurfaces(hwctx->
display, 
ctx->rt_format,
 
  515                            ctx->attributes, 
ctx->nb_attributes);
 
  516     if (vas != VA_STATUS_SUCCESS) {
 
  518                "%d (%s).\n", vas, vaErrorStr(vas));
 
  527         vaDestroySurfaces(hwctx->
display, &surface_id, 1);
 
  547     const VAAPIFormatDescriptor *
desc;
 
  548     VAImageFormat *expected_format;
 
  550     VASurfaceID test_surface_id;
 
  565             int need_pixel_format = 1;
 
  567                 if (avfc->
attributes[
i].type == VASurfaceAttribMemoryType)
 
  568                     need_memory_type  = 0;
 
  569                 if (avfc->
attributes[
i].type == VASurfaceAttribPixelFormat)
 
  570                     need_pixel_format = 0;
 
  576                                         sizeof(*
ctx->attributes));
 
  577             if (!
ctx->attributes) {
 
  584             if (need_memory_type) {
 
  585                 ctx->attributes[
i++] = (VASurfaceAttrib) {
 
  586                     .type          = VASurfaceAttribMemoryType,
 
  587                     .
flags         = VA_SURFACE_ATTRIB_SETTABLE,
 
  588                     .value.type    = VAGenericValueTypeInteger,
 
  589                     .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
 
  592             if (need_pixel_format) {
 
  593                 ctx->attributes[
i++] = (VASurfaceAttrib) {
 
  594                     .type          = VASurfaceAttribPixelFormat,
 
  595                     .
flags         = VA_SURFACE_ATTRIB_SETTABLE,
 
  596                     .value.type    = VAGenericValueTypeInteger,
 
  597                     .value.value.i = 
desc->fourcc,
 
  603             ctx->nb_attributes = 0;
 
  606         ctx->rt_format = 
desc->rt_format;
 
  642                    "user-configured buffer pool.\n");
 
  650                    "internal buffer pool.\n");
 
  655     test_surface_id = (VASurfaceID)(uintptr_t)test_surface->
data;
 
  657     ctx->derive_works = 0;
 
  662         vas = vaDeriveImage(hwctx->
display, test_surface_id, &test_image);
 
  663         if (vas == VA_STATUS_SUCCESS) {
 
  664             if (expected_format->fourcc == test_image.format.fourcc) {
 
  666                 ctx->derive_works = 1;
 
  669                        "derived image format %08x does not match " 
  670                        "expected format %08x.\n",
 
  671                        expected_format->fourcc, test_image.format.fourcc);
 
  673             vaDestroyImage(hwctx->
display, test_image.image_id);
 
  676                    "deriving image does not work: " 
  677                    "%d (%s).\n", vas, vaErrorStr(vas));
 
  681                "image format is not supported.\n");
 
  723     int i, k, sw_format_available;
 
  725     sw_format_available = 0;
 
  726     for (
i = 0; 
i < 
ctx->nb_formats; 
i++) {
 
  728             sw_format_available = 1;
 
  735     if (sw_format_available) {
 
  741     for (
i = 0; 
i < 
ctx->nb_formats; 
i++) {
 
  758     VASurfaceID surface_id;
 
  761     surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
 
  764     vas = vaUnmapBuffer(hwctx->
display, 
map->image.buf);
 
  765     if (vas != VA_STATUS_SUCCESS) {
 
  767                "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
  772         vas = vaPutImage(hwctx->
display, surface_id, 
map->image.image_id,
 
  775         if (vas != VA_STATUS_SUCCESS) {
 
  777                    "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
  781     vas = vaDestroyImage(hwctx->
display, 
map->image.image_id);
 
  782     if (vas != VA_STATUS_SUCCESS) {
 
  784                "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
  795     VASurfaceID surface_id;
 
  796     const VAAPIFormatDescriptor *
desc;
 
  797     VAImageFormat *image_format;
 
  800     void *address = 
NULL;
 
  803     surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
 
  827     map->image.image_id = VA_INVALID_ID;
 
  829     vas = vaSyncSurface(hwctx->
display, surface_id);
 
  830     if (vas != VA_STATUS_SUCCESS) {
 
  832                "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
  846         vas = vaDeriveImage(hwctx->
display, surface_id, &
map->image);
 
  847         if (vas != VA_STATUS_SUCCESS) {
 
  849                    "surface %#x: %d (%s).\n",
 
  850                    surface_id, vas, vaErrorStr(vas));
 
  854         if (
map->image.format.fourcc != image_format->fourcc) {
 
  856                    "is in wrong format: expected %#08x, got %#08x.\n",
 
  857                    surface_id, image_format->fourcc, 
map->image.format.fourcc);
 
  863         vas = vaCreateImage(hwctx->
display, image_format,
 
  865         if (vas != VA_STATUS_SUCCESS) {
 
  867                    "surface %#x: %d (%s).\n",
 
  868                    surface_id, vas, vaErrorStr(vas));
 
  873             vas = vaGetImage(hwctx->
display, surface_id, 0, 0,
 
  875             if (vas != VA_STATUS_SUCCESS) {
 
  877                        "surface %#x: %d (%s).\n",
 
  878                        surface_id, vas, vaErrorStr(vas));
 
  885     vas = vaMapBuffer(hwctx->
display, 
map->image.buf, &address);
 
  886     if (vas != VA_STATUS_SUCCESS) {
 
  888                "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
  901     for (
i = 0; 
i < 
map->image.num_planes; 
i++) {
 
  902         dst->
data[
i] = (uint8_t*)address + 
map->image.offsets[
i];
 
  907     if (
desc && 
desc->chroma_planes_swapped) {
 
  917             vaUnmapBuffer(hwctx->
display, 
map->image.buf);
 
  918         if (
map->image.image_id != VA_INVALID_ID)
 
  919             vaDestroyImage(hwctx->
display, 
map->image.image_id);
 
  968     map->format = 
src->format;
 
  975     map->height = 
src->height;
 
 1011 #define DRM_MAP(va, layers, ...) { \ 
 1016 static const struct {
 
 1018     int   nb_layer_formats;
 
 1020 } vaapi_drm_format_map[] = {
 
 1021 #ifdef DRM_FORMAT_R8 
 1022     DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
 
 1023     DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 
 1025     DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 
 1026 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16) 
 1027     DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616),
 
 1029 #if defined(VA_FOURCC_P012) && defined(DRM_FORMAT_R16) 
 1030     DRM_MAP(P012, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616),
 
 1032     DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888),
 
 1033     DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888),
 
 1034     DRM_MAP(
RGBA, 1, DRM_FORMAT_ABGR8888),
 
 1035     DRM_MAP(RGBX, 1, DRM_FORMAT_XBGR8888),
 
 1036 #ifdef VA_FOURCC_ABGR 
 1037     DRM_MAP(ABGR, 1, DRM_FORMAT_RGBA8888),
 
 1038     DRM_MAP(XBGR, 1, DRM_FORMAT_RGBX8888),
 
 1040     DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888),
 
 1041     DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888),
 
 1042 #if defined(VA_FOURCC_XYUV) && defined(DRM_FORMAT_XYUV8888) 
 1043     DRM_MAP(XYUV, 1, DRM_FORMAT_XYUV8888),
 
 1045 #if defined(VA_FOURCC_Y412) && defined(DRM_FORMAT_XVYU2101010) 
 1046     DRM_MAP(Y410, 1, DRM_FORMAT_XVYU2101010),
 
 1048 #if defined(VA_FOURCC_Y412) && defined(DRM_FORMAT_XVYU12_16161616) 
 1049     DRM_MAP(Y412, 1, DRM_FORMAT_XVYU12_16161616),
 
 1051 #if defined(VA_FOURCC_X2R10G10B10) && defined(DRM_FORMAT_XRGB2101010) 
 1052     DRM_MAP(X2R10G10B10, 1, DRM_FORMAT_XRGB2101010),
 
 1062     VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->
priv;
 
 1066     vaDestroySurfaces(dst_dev->
display, &surface_id, 1);
 
 1072 #if VA_CHECK_VERSION(1, 1, 0) 
 1082     const VAAPIFormatDescriptor *format_desc;
 
 1083     VASurfaceID surface_id;
 
 1084     VAStatus vas = VA_STATUS_SUCCESS;
 
 1088 #
if !VA_CHECK_VERSION(1, 1, 0)
 
 1089     unsigned long buffer_handle;
 
 1090     VASurfaceAttribExternalBuffers buffer_desc;
 
 1091     VASurfaceAttrib attrs[2] = {
 
 1093             .type  = VASurfaceAttribMemoryType,
 
 1094             .flags = VA_SURFACE_ATTRIB_SETTABLE,
 
 1095             .value.type    = VAGenericValueTypeInteger,
 
 1096             .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
 
 1099             .type  = VASurfaceAttribExternalBufferDescriptor,
 
 1100             .flags = VA_SURFACE_ATTRIB_SETTABLE,
 
 1101             .value.type    = VAGenericValueTypePointer,
 
 1102             .value.value.p = &buffer_desc,
 
 1109     if (
desc->nb_objects != 1) {
 
 1111                "made from a single DRM object.\n");
 
 1117         if (
desc->nb_layers != vaapi_drm_format_map[
i].nb_layer_formats)
 
 1119         for (j = 0; j < 
desc->nb_layers; j++) {
 
 1120             if (
desc->layers[j].format !=
 
 1121                 vaapi_drm_format_map[
i].layer_formats[j])
 
 1124         if (j != 
desc->nb_layers)
 
 1126         va_fourcc = vaapi_drm_format_map[
i].va_fourcc;
 
 1136            "%08x.\n", 
desc->objects[0].fd, va_fourcc);
 
 1141 #if VA_CHECK_VERSION(1, 1, 0) 
 1145         VADRMPRIMESurfaceDescriptor prime_desc;
 
 1146         VASurfaceAttrib prime_attrs[2] = {
 
 1148                 .type  = VASurfaceAttribMemoryType,
 
 1149                 .flags = VA_SURFACE_ATTRIB_SETTABLE,
 
 1150                 .value.type    = VAGenericValueTypeInteger,
 
 1151                 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
 
 1154                 .type  = VASurfaceAttribExternalBufferDescriptor,
 
 1155                 .flags = VA_SURFACE_ATTRIB_SETTABLE,
 
 1156                 .value.type    = VAGenericValueTypePointer,
 
 1157                 .value.value.p = &prime_desc,
 
 1160         prime_desc.fourcc = va_fourcc;
 
 1161         prime_desc.width = src_fc->
width;
 
 1162         prime_desc.height = src_fc->
height;
 
 1163         prime_desc.num_objects = 
desc->nb_objects;
 
 1164         for (
i = 0; 
i < 
desc->nb_objects; ++
i) {
 
 1165             prime_desc.objects[
i].fd = 
desc->objects[
i].fd;
 
 1166             prime_desc.objects[
i].size = 
desc->objects[
i].size;
 
 1167             prime_desc.objects[
i].drm_format_modifier =
 
 1168                     desc->objects[
i].format_modifier;
 
 1171         prime_desc.num_layers = 
desc->nb_layers;
 
 1172         for (
i = 0; 
i < 
desc->nb_layers; ++
i) {
 
 1173             prime_desc.layers[
i].drm_format = 
desc->layers[
i].format;
 
 1174             prime_desc.layers[
i].num_planes = 
desc->layers[
i].nb_planes;
 
 1175             for (j = 0; j < 
desc->layers[
i].nb_planes; ++j) {
 
 1176                 prime_desc.layers[
i].object_index[j] =
 
 1177                         desc->layers[
i].planes[j].object_index;
 
 1178                 prime_desc.layers[
i].offset[j] = 
desc->layers[
i].planes[j].offset;
 
 1179                 prime_desc.layers[
i].pitch[j] = 
desc->layers[
i].planes[j].pitch;
 
 1182             if (format_desc->chroma_planes_swapped &&
 
 1183                 desc->layers[
i].nb_planes == 3) {
 
 1184                 FFSWAP(uint32_t, prime_desc.layers[
i].pitch[1],
 
 1185                     prime_desc.layers[
i].pitch[2]);
 
 1186                 FFSWAP(uint32_t, prime_desc.layers[
i].offset[1],
 
 1187                     prime_desc.layers[
i].offset[2]);
 
 1197         vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
 
 1198                                src->width, 
src->height, &surface_id, 1,
 
 1200         if (vas != VA_STATUS_SUCCESS)
 
 1204     if (!use_prime2 || vas != VA_STATUS_SUCCESS) {
 
 1206         unsigned long buffer_handle;
 
 1207         VASurfaceAttribExternalBuffers buffer_desc;
 
 1208         VASurfaceAttrib buffer_attrs[2] = {
 
 1210                 .type  = VASurfaceAttribMemoryType,
 
 1211                 .flags = VA_SURFACE_ATTRIB_SETTABLE,
 
 1212                 .value.type    = VAGenericValueTypeInteger,
 
 1213                 .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
 
 1216                 .type  = VASurfaceAttribExternalBufferDescriptor,
 
 1217                 .flags = VA_SURFACE_ATTRIB_SETTABLE,
 
 1218                 .value.type    = VAGenericValueTypePointer,
 
 1219                 .value.value.p = &buffer_desc,
 
 1223         buffer_handle = 
desc->objects[0].fd;
 
 1224         buffer_desc.pixel_format = va_fourcc;
 
 1225         buffer_desc.width        = src_fc->
width;
 
 1226         buffer_desc.height       = src_fc->
height;
 
 1227         buffer_desc.data_size    = 
desc->objects[0].size;
 
 1228         buffer_desc.buffers      = &buffer_handle;
 
 1229         buffer_desc.num_buffers  = 1;
 
 1230         buffer_desc.flags        = 0;
 
 1233         for (
i = 0; 
i < 
desc->nb_layers; 
i++) {
 
 1234             for (j = 0; j < 
desc->layers[
i].nb_planes; j++) {
 
 1235                 buffer_desc.pitches[k] = 
desc->layers[
i].planes[j].pitch;
 
 1236                 buffer_desc.offsets[k] = 
desc->layers[
i].planes[j].offset;
 
 1240         buffer_desc.num_planes = k;
 
 1242         if (format_desc->chroma_planes_swapped &&
 
 1243             buffer_desc.num_planes == 3) {
 
 1244             FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]);
 
 1245             FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
 
 1248         vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
 
 1254     buffer_handle = 
desc->objects[0].fd;
 
 1255     buffer_desc.pixel_format = va_fourcc;
 
 1256     buffer_desc.width        = src_fc->
width;
 
 1257     buffer_desc.height       = src_fc->
height;
 
 1258     buffer_desc.data_size    = 
desc->objects[0].size;
 
 1259     buffer_desc.buffers      = &buffer_handle;
 
 1260     buffer_desc.num_buffers  = 1;
 
 1261     buffer_desc.flags        = 0;
 
 1264     for (
i = 0; 
i < 
desc->nb_layers; 
i++) {
 
 1265         for (j = 0; j < 
desc->layers[
i].nb_planes; j++) {
 
 1266             buffer_desc.pitches[k] = 
desc->layers[
i].planes[j].pitch;
 
 1267             buffer_desc.offsets[k] = 
desc->layers[
i].planes[j].offset;
 
 1271     buffer_desc.num_planes = k;
 
 1273     if (format_desc->chroma_planes_swapped &&
 
 1274         buffer_desc.num_planes == 3) {
 
 1275         FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]);
 
 1276         FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
 
 1279     vas = vaCreateSurfaces(dst_dev->
display, format_desc->rt_format,
 
 1284     if (vas != VA_STATUS_SUCCESS) {
 
 1286                "object: %d (%s).\n", vas, vaErrorStr(vas));
 
 1292                                 &vaapi_unmap_from_drm,
 
 1293                                 (
void*)(uintptr_t)surface_id);
 
 1299     dst->
data[3] = (uint8_t*)(uintptr_t)surface_id;
 
 1302            "surface %#x.\n", 
desc->objects[0].fd, surface_id);
 
 1307 #if VA_CHECK_VERSION(1, 1, 0) 
 1324     VASurfaceID surface_id;
 
 1326     VADRMPRIMESurfaceDescriptor va_desc;
 
 1328     uint32_t export_flags;
 
 1331     surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
 
 1333     export_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS;
 
 1335         export_flags |= VA_EXPORT_SURFACE_READ_ONLY;
 
 1337         vas = vaSyncSurface(hwctx->
display, surface_id);
 
 1338         if (vas != VA_STATUS_SUCCESS) {
 
 1340                    "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
 1346         export_flags |= VA_EXPORT_SURFACE_WRITE_ONLY;
 
 1348     vas = vaExportSurfaceHandle(hwctx->
display, surface_id,
 
 1349                                 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
 
 1350                                 export_flags, &va_desc);
 
 1351     if (vas != VA_STATUS_SUCCESS) {
 
 1352         if (vas == VA_STATUS_ERROR_UNIMPLEMENTED)
 
 1355                "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
 
 1367     for (
i = 0; 
i < va_desc.num_objects; 
i++) {
 
 1371             va_desc.objects[
i].drm_format_modifier;
 
 1373     drm_desc->
nb_layers = va_desc.num_layers;
 
 1374     for (
i = 0; 
i < va_desc.num_layers; 
i++) {
 
 1377         for (j = 0; j < va_desc.layers[
i].num_planes; j++) {
 
 1379                 va_desc.layers[
i].object_index[j];
 
 1381                 va_desc.layers[
i].offset[j];
 
 1383                 va_desc.layers[
i].pitch[j];
 
 1388                                 &vaapi_unmap_to_drm_esh, drm_desc);
 
 1394     dst->
data[0] = (uint8_t*)drm_desc;
 
 1399     for (
i = 0; 
i < va_desc.num_objects; 
i++)
 
 1400         close(va_desc.objects[
i].fd);
 
 1406 #if VA_CHECK_VERSION(0, 36, 0) 
 1407 typedef struct VAAPIDRMImageBufferMapping {
 
 1409     VABufferInfo buffer_info;
 
 1412 } VAAPIDRMImageBufferMapping;
 
 1418     VAAPIDRMImageBufferMapping *mapping = hwmap->
priv;
 
 1419     VASurfaceID surface_id;
 
 1422     surface_id = (VASurfaceID)(uintptr_t)hwmap->
source->
data[3];
 
 1429     vas = vaReleaseBufferHandle(hwctx->
display, mapping->image.buf);
 
 1430     if (vas != VA_STATUS_SUCCESS) {
 
 1432                "handle of image %#x (derived from surface %#x): " 
 1433                "%d (%s).\n", mapping->image.buf, surface_id,
 
 1434                vas, vaErrorStr(vas));
 
 1437     vas = vaDestroyImage(hwctx->
display, mapping->image.image_id);
 
 1438     if (vas != VA_STATUS_SUCCESS) {
 
 1440                "derived from surface %#x: %d (%s).\n",
 
 1441                surface_id, vas, vaErrorStr(vas));
 
 1451     VAAPIDRMImageBufferMapping *mapping = 
NULL;
 
 1452     VASurfaceID surface_id;
 
 1456     surface_id = (VASurfaceID)(uintptr_t)
src->data[3];
 
 1464     vas = vaDeriveImage(hwctx->
display, surface_id,
 
 1466     if (vas != VA_STATUS_SUCCESS) {
 
 1468                "surface %#x: %d (%s).\n",
 
 1469                surface_id, vas, vaErrorStr(vas));
 
 1475         if (vaapi_drm_format_map[
i].va_fourcc ==
 
 1476             mapping->image.format.fourcc)
 
 1481                "VAAPI format %#x.\n", mapping->image.format.fourcc);
 
 1486     mapping->buffer_info.mem_type =
 
 1487         VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
 
 1489     mapping->drm_desc.nb_layers =
 
 1490         vaapi_drm_format_map[
i].nb_layer_formats;
 
 1491     if (mapping->drm_desc.nb_layers > 1) {
 
 1492         if (mapping->drm_desc.nb_layers != mapping->image.num_planes) {
 
 1494                    "expected format: got %d planes, but expected %d.\n",
 
 1495                    mapping->image.num_planes, mapping->drm_desc.nb_layers);
 
 1500         for(p = 0; p < mapping->drm_desc.nb_layers; p++) {
 
 1502                 .format    = vaapi_drm_format_map[
i].layer_formats[p],
 
 1506                     .offset       = mapping->image.offsets[p],
 
 1507                     .pitch        = mapping->image.pitches[p],
 
 1512         mapping->drm_desc.layers[0].format =
 
 1513             vaapi_drm_format_map[
i].layer_formats[0];
 
 1514         mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes;
 
 1515         for (p = 0; p < mapping->image.num_planes; p++) {
 
 1518                 .offset       = mapping->image.offsets[p],
 
 1519                 .pitch        = mapping->image.pitches[p],
 
 1524     vas = vaAcquireBufferHandle(hwctx->
display, mapping->image.buf,
 
 1525                                 &mapping->buffer_info);
 
 1526     if (vas != VA_STATUS_SUCCESS) {
 
 1528                "handle from image %#x (derived from surface %#x): " 
 1529                "%d (%s).\n", mapping->image.buf, surface_id,
 
 1530                vas, vaErrorStr(vas));
 
 1536            mapping->buffer_info.handle);
 
 1538     mapping->drm_desc.nb_objects = 1;
 
 1540         .fd   = mapping->buffer_info.handle,
 
 1541         .size = mapping->image.data_size,
 
 1547                                 dst, 
src, &vaapi_unmap_to_drm_abh,
 
 1552     dst->
data[0] = (uint8_t*)&mapping->drm_desc;
 
 1559     vaReleaseBufferHandle(hwctx->
display, mapping->image.buf);
 
 1561     vaDestroyImage(hwctx->
display, mapping->image.image_id);
 
 1571 #if VA_CHECK_VERSION(1, 1, 0) 
 1573     err = vaapi_map_to_drm_esh(hwfc, dst, 
src, 
flags);
 
 1577 #if VA_CHECK_VERSION(0, 36, 0) 
 1578     return vaapi_map_to_drm_abh(hwfc, dst, 
src, 
flags);
 
 1588     switch (
src->format) {
 
 1591         return vaapi_map_from_drm(hwfc, dst, 
src, 
flags);
 
 1604         return vaapi_map_to_drm(hwfc, dst, 
src, 
flags);
 
 1620     if (priv->x11_display)
 
 1621         XCloseDisplay(priv->x11_display);
 
 1631 static void vaapi_device_log_error(
void *
context, 
const char *
message)
 
 1638 static void vaapi_device_log_info(
void *
context, 
const char *
message)
 
 1654     vaSetErrorCallback(display, &vaapi_device_log_error, 
ctx);
 
 1655     vaSetInfoCallback (display, &vaapi_device_log_info,  
ctx);
 
 1660     vas = vaInitialize(display, &major, &minor);
 
 1661     if (vas != VA_STATUS_SUCCESS) {
 
 1663                "connection: %d (%s).\n", vas, vaErrorStr(vas));
 
 1667            "version %d.%d\n", major, minor);
 
 1676     VADisplay display = 
NULL;
 
 1678     int try_drm, try_x11, try_win32, try_all;
 
 1686     ctx->user_opaque = priv;
 
 1691         try_all = try_drm = try_x11 = try_win32 = 0;
 
 1692         if (!strcmp(ent->
value, 
"drm")) {
 
 1694         } 
else if (!strcmp(ent->
value, 
"x11")) {
 
 1696         } 
else if (!strcmp(ent->
value, 
"win32")) {
 
 1705         try_drm = HAVE_VAAPI_DRM;
 
 1706         try_x11 = HAVE_VAAPI_X11;
 
 1707         try_win32 = HAVE_VAAPI_WIN32;
 
 1711     while (!display && try_drm) {
 
 1717             priv->
drm_fd = open(device, O_RDWR);
 
 1719                 av_log(
ctx, loglevel, 
"Failed to open %s as " 
 1720                        "DRM device node.\n", device);
 
 1725             int n, max_devices = 8;
 
 1731             for (n = 0; n < max_devices; n++) {
 
 1733                          "/dev/dri/renderD%d", 128 + n);
 
 1734                 priv->
drm_fd = open(path, O_RDWR);
 
 1737                            "DRM render node for device %d.\n", n);
 
 1744                            "Failed to get DRM version for device %d.\n", n);
 
 1749                 if (kernel_driver) {
 
 1750                     if (strcmp(kernel_driver->
value, 
info->name)) {
 
 1752                                "with non-matching kernel driver (%s).\n",
 
 1754                         drmFreeVersion(
info);
 
 1760                            "DRM render node for device %d, " 
 1761                            "with matching kernel driver (%s).\n",
 
 1763                     drmFreeVersion(
info);
 
 1766                 } 
else if (!strcmp(
info->name, 
"vgem")) {
 
 1768                            "Skipping vgem node for device %d.\n", n);
 
 1769                     drmFreeVersion(
info);
 
 1774                 drmFreeVersion(
info);
 
 1777                        "DRM render node for device %d.\n", n);
 
 1780             if (n >= max_devices)
 
 1784         display = vaGetDisplayDRM(priv->
drm_fd);
 
 1787                    "from DRM device %s.\n", device);
 
 1795     if (!display && try_x11) {
 
 1797         priv->x11_display = XOpenDisplay(device);
 
 1798         if (!priv->x11_display) {
 
 1800                    "%s.\n", XDisplayName(device));
 
 1802             display = vaGetDisplay(priv->x11_display);
 
 1805                        "from X11 display %s.\n", XDisplayName(device));
 
 1810                    "X11 display %s.\n", XDisplayName(device));
 
 1815 #if HAVE_VAAPI_WIN32 
 1816     if (!display && try_win32) {
 
 1819             display = vaGetDisplayWin32(
NULL);
 
 1821             IDXGIFactory2 *pDXGIFactory = 
NULL;
 
 1822             IDXGIAdapter *pAdapter = 
NULL;
 
 1824             HANDLE dxgi = dlopen(
"dxgi.dll", 0);
 
 1831             if (!pfnCreateDXGIFactory) {
 
 1842             if (SUCCEEDED(pfnCreateDXGIFactory(&IID_IDXGIFactory2,
 
 1843                                               (
void **)&pDXGIFactory))) {
 
 1844                 int adapter = atoi(device);
 
 1845                 if (SUCCEEDED(IDXGIFactory2_EnumAdapters(pDXGIFactory,
 
 1848                     DXGI_ADAPTER_DESC 
desc;
 
 1849                     if (SUCCEEDED(IDXGIAdapter2_GetDesc(pAdapter, &
desc))) {
 
 1851                               "Using device %04x:%04x (%ls) - LUID %lu %ld.\n",
 
 1853                               desc.AdapterLuid.LowPart,
 
 1854                               desc.AdapterLuid.HighPart);
 
 1855                         display = vaGetDisplayWin32(&
desc.AdapterLuid);
 
 1857                     IDXGIAdapter_Release(pAdapter);
 
 1859                 IDXGIFactory2_Release(pDXGIFactory);
 
 1868                     "from Win32 display.\n");
 
 1873                 "Win32 display.\n");
 
 1880                    "device %s.\n", device);
 
 1883                    "any default device.\n");
 
 1889 #if VA_CHECK_VERSION(0, 38, 0) 
 1891         vas = vaSetDriverName(display, ent->
value);
 
 1892         if (vas != VA_STATUS_SUCCESS) {
 
 1894                    "%s: %d (%s).\n", ent->
value, vas, vaErrorStr(vas));
 
 1895             vaTerminate(display);
 
 1900                "supported with this VAAPI version.\n");
 
 1918         if (src_hwctx->
fd < 0) {
 
 1920                    "device to derive a VA display from.\n");
 
 1926             int node_type = drmGetNodeTypeFromFd(src_hwctx->
fd);
 
 1928             if (node_type < 0) {
 
 1930                        "to refer to a DRM device.\n");
 
 1933             if (node_type == DRM_NODE_RENDER) {
 
 1936                 render_node = drmGetRenderDeviceNameFromFd(src_hwctx->
fd);
 
 1939                            "because the device does not have an " 
 1940                            "associated render node.\n");
 
 1943                     fd = open(render_node, O_RDWR);
 
 1946                                "because the associated render node " 
 1947                                "could not be opened.\n");
 
 1951                                "in place of non-render DRM device.\n",
 
 1964             if (fd != src_hwctx->
fd) {
 
 1971         if (fd == src_hwctx->
fd) {
 
 1979         ctx->user_opaque = priv;
 
 1982         display = vaGetDisplayDRM(fd);