This improves performance and helps a little when given FDs without any synchronization fences.
Unified · Split
| @@ -19,6 +19,8 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <fcntl.h> |
| 20 | 20 | #include <sys/mman.h> |
| 21 | 21 | #include <unistd.h> |
| 22 | +#include <linux/dma-buf.h> | |
| 23 | +#include <sys/ioctl.h> | |
| 22 | 24 | |
| 23 | 25 | #include <drm.h> |
| 24 | 26 | #include <xf86drm.h> |
| @@ -85,6 +87,8 @@ static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) · 60 unmodified lines | ||
| 85 | 87 | typedef struct DRMMapping { |
| 86 | 88 | // Address and length of each mmap()ed region. |
| 87 | 89 | int nb_regions; |
| 90 | + int sync_flags; | |
| 91 | + int object[AV_DRM_MAX_PLANES]; | |
| 88 | 92 | void *address[AV_DRM_MAX_PLANES]; |
| 89 | 93 | size_t length[AV_DRM_MAX_PLANES]; |
| 90 | 94 | } DRMMapping; |
| @@ -93,10 +97,16 @@ static void drm_unmap_frame(AVHWFramesContext *hwfc, · 2 unmodified lines | ||
| 93 | 97 | HWMapDescriptor *hwmap) |
| 94 | 98 | { |
| 95 | 99 | DRMMapping *map = hwmap->priv; |
| 96 | − int i; | |
| 97 | − | |
| 98 | − for (i = 0; i < map->nb_regions; i++) | |
| 100 | + struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END | map->sync_flags }; | |
| 101 | + int i, ret; | |
| 102 | + | |
| 103 | + for (i = 0; i < map->nb_regions; i++) { | |
| 104 | + ret = ioctl(map->object[i], DMA_BUF_IOCTL_SYNC, &sync); | |
| 105 | + if (ret) | |
| 106 | + av_log(hwfc, AV_LOG_ERROR, "Failed to issue ioctl sync to DRM object " | |
| 107 | + "%d: %d.\n", map->object[i], errno); | |
| 99 | 108 | munmap(map->address[i], map->length[i]); |
| 109 | + } | |
| 100 | 110 | |
| 101 | 111 | av_free(map); |
| 102 | 112 | } |
| @@ -105,6 +115,7 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 2 unmodified lines | ||
| 105 | 115 | AVFrame *dst, const AVFrame *src, int flags) |
| 106 | 116 | { |
| 107 | 117 | const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0]; |
| 118 | + struct dma_buf_sync sync_start = { 0 }; | |
| 108 | 119 | DRMMapping *map; |
| 109 | 120 | int err, i, p, plane; |
| 110 | 121 | int mmap_prot; |
| @@ -115,10 +126,16 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 4 unmodified lines | ||
| 115 | 126 | return AVERROR(ENOMEM); |
| 116 | 127 | |
| 117 | 128 | mmap_prot = 0; |
| 118 | − if (flags & AV_HWFRAME_MAP_READ) | |
| 129 | + if (flags & AV_HWFRAME_MAP_READ) { | |
| 119 | 130 | mmap_prot |= PROT_READ; |
| 120 | − if (flags & AV_HWFRAME_MAP_WRITE) | |
| 131 | + map->sync_flags |= DMA_BUF_SYNC_READ; | |
| 132 | + } | |
| 133 | + if (flags & AV_HWFRAME_MAP_WRITE) { | |
| 121 | 134 | mmap_prot |= PROT_WRITE; |
| 135 | + map->sync_flags |= DMA_BUF_SYNC_WRITE; | |
| 136 | + } | |
| 137 | + | |
| 138 | + sync_start.flags = DMA_BUF_SYNC_START | map->sync_flags; | |
| 122 | 139 | |
| 123 | 140 | av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES); |
| 124 | 141 | for (i = 0; i < desc->nb_objects; i++) { |
| @@ -133,6 +150,15 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 8 unmodified lines | ||
| 133 | 150 | |
| 134 | 151 | map->address[i] = addr; |
| 135 | 152 | map->length[i] = desc->objects[i].size; |
| 153 | + map->object[i] = desc->objects[i].fd; | |
| 154 | + | |
| 155 | + err = ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start); | |
| 156 | + if (err) { | |
| 157 | + err = AVERROR(errno); | |
| 158 | + av_log(hwfc, AV_LOG_ERROR, "Failed to issue ioctl sync to DRM object " | |
| 159 | + "%d: %d.\n", desc->objects[i].fd, errno); | |
| 160 | + goto fail; | |
| 161 | + } | |
| 136 | 162 | } |
| 137 | 163 | map->nb_regions = i; |
| 138 | 164 | |