History

hwcontext_drm: issue DMA_BUF_IOCTL_SYNC when mapping FDs

This improves performance and helps a little when given FDs without any synchronization fences.

Lynne committed 5 years ago

Commit 993d8d91 parent dd348611 file · +31 −5Browse files

Unified · Split

libavutil/hwcontext_drm.c+31−5
@@ -19,6 +19,8 @@ · 18 unmodified lines
19#include <fcntl.h>19#include <fcntl.h>
20#include <sys/mman.h>20#include <sys/mman.h>
21#include <unistd.h>21#include <unistd.h>
22#include <linux/dma-buf.h>
23#include <sys/ioctl.h>
22 24
23#include <drm.h>25#include <drm.h>
24#include <xf86drm.h>26#include <xf86drm.h>
@@ -85,6 +87,8 @@ static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) · 60 unmodified lines
85typedef struct DRMMapping {87typedef struct DRMMapping {
86 // Address and length of each mmap()ed region.88 // Address and length of each mmap()ed region.
87 int nb_regions;89 int nb_regions;
90 int sync_flags;
91 int object[AV_DRM_MAX_PLANES];
88 void *address[AV_DRM_MAX_PLANES];92 void *address[AV_DRM_MAX_PLANES];
89 size_t length[AV_DRM_MAX_PLANES];93 size_t length[AV_DRM_MAX_PLANES];
90} DRMMapping;94} DRMMapping;
@@ -93,10 +97,16 @@ static void drm_unmap_frame(AVHWFramesContext *hwfc, · 2 unmodified lines
93 HWMapDescriptor *hwmap)97 HWMapDescriptor *hwmap)
94{98{
95 DRMMapping *map = hwmap->priv;99 DRMMapping *map = hwmap->priv;
96 int i;100 struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END | map->sync_flags };
97 101 int i, ret;
98 for (i = 0; i < map->nb_regions; i++)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 munmap(map->address[i], map->length[i]);108 munmap(map->address[i], map->length[i]);
109 }
100 110
101 av_free(map);111 av_free(map);
102}112}
@@ -105,6 +115,7 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 2 unmodified lines
105 AVFrame *dst, const AVFrame *src, int flags)115 AVFrame *dst, const AVFrame *src, int flags)
106{116{
107 const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0];117 const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0];
118 struct dma_buf_sync sync_start = { 0 };
108 DRMMapping *map;119 DRMMapping *map;
109 int err, i, p, plane;120 int err, i, p, plane;
110 int mmap_prot;121 int mmap_prot;
@@ -115,10 +126,16 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 4 unmodified lines
115 return AVERROR(ENOMEM);126 return AVERROR(ENOMEM);
116 127
117 mmap_prot = 0;128 mmap_prot = 0;
118 if (flags & AV_HWFRAME_MAP_READ)129 if (flags & AV_HWFRAME_MAP_READ) {
119 mmap_prot |= PROT_READ;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 mmap_prot |= PROT_WRITE;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 av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES);140 av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES);
124 for (i = 0; i < desc->nb_objects; i++) {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 map->address[i] = addr;151 map->address[i] = addr;
135 map->length[i] = desc->objects[i].size;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 map->nb_regions = i;163 map->nb_regions = i;
138 164

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t