mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
v4l2: add support for DMABUF
Export dmafd on buffers and use those directly to send to the client. Do some v4l2 cleanup.
This commit is contained in:
parent
17ef36c9c1
commit
16d2a3a69c
3 changed files with 61 additions and 18 deletions
|
|
@ -58,6 +58,7 @@ struct _V4l2Buffer {
|
|||
bool outstanding;
|
||||
struct v4l2_buffer v4l2_buffer;
|
||||
V4l2Buffer *next;
|
||||
int dmafd;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -79,6 +80,7 @@ typedef struct {
|
|||
SpaPortInfo info;
|
||||
SpaAllocParam *params[1];
|
||||
SpaAllocParamBuffers param_buffers;
|
||||
bool export_buf;
|
||||
SpaPortStatus status;
|
||||
} SpaV4l2State;
|
||||
|
||||
|
|
@ -598,6 +600,8 @@ v4l2_source_init (const SpaHandleFactory *factory,
|
|||
this->state[0].info.flags = SPA_PORT_INFO_FLAG_NONE;
|
||||
this->state[0].status.flags = SPA_PORT_STATUS_FLAG_NONE;
|
||||
|
||||
this->state[0].export_buf = true;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -346,7 +346,6 @@ spa_v4l2_close (SpaV4l2Source *this)
|
|||
|
||||
state->fd = -1;
|
||||
state->opened = false;
|
||||
state->have_buffers = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -530,22 +529,40 @@ mmap_init (SpaV4l2Source *this)
|
|||
b->metas[0].data = &b->header;
|
||||
b->metas[0].size = sizeof (b->header);
|
||||
|
||||
b->datas[0].type = SPA_DATA_TYPE_MEMPTR;
|
||||
b->datas[0].data = mmap (NULL,
|
||||
buf.length,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
state->fd,
|
||||
buf.m.offset);
|
||||
b->datas[0].offset = 0;
|
||||
b->datas[0].size = buf.length;
|
||||
b->datas[0].stride = state->fmt.fmt.pix.bytesperline;
|
||||
b->outstanding = true;
|
||||
if (state->export_buf) {
|
||||
struct v4l2_exportbuffer expbuf;
|
||||
|
||||
if (b->datas[0].data == MAP_FAILED) {
|
||||
perror ("mmap");
|
||||
continue;
|
||||
CLEAR (expbuf);
|
||||
expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
expbuf.index = i;
|
||||
if (xioctl (state->fd, VIDIOC_EXPBUF, &expbuf) < 0) {
|
||||
perror("VIDIOC_EXPBUF");
|
||||
continue;
|
||||
}
|
||||
|
||||
b->dmafd = expbuf.fd;
|
||||
b->datas[0].type = SPA_DATA_TYPE_FD;
|
||||
b->datas[0].data = &b->dmafd;
|
||||
b->datas[0].offset = 0;
|
||||
b->datas[0].size = buf.length;
|
||||
b->datas[0].stride = state->fmt.fmt.pix.bytesperline;
|
||||
} else {
|
||||
b->datas[0].type = SPA_DATA_TYPE_MEMPTR;
|
||||
b->datas[0].data = mmap (NULL,
|
||||
buf.length,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
state->fd,
|
||||
buf.m.offset);
|
||||
b->datas[0].offset = 0;
|
||||
b->datas[0].size = buf.length;
|
||||
b->datas[0].stride = state->fmt.fmt.pix.bytesperline;
|
||||
if (b->datas[0].data == MAP_FAILED) {
|
||||
perror ("mmap");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
b->outstanding = true;
|
||||
|
||||
CLEAR (b->v4l2_buffer);
|
||||
b->v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
|
@ -626,6 +643,7 @@ spa_v4l2_stop (SpaV4l2Source *this)
|
|||
SpaV4l2State *state = &this->state[0];
|
||||
enum v4l2_buf_type type;
|
||||
SpaEvent event;
|
||||
int i;
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (xioctl (state->fd, VIDIOC_STREAMOFF, &type) < 0) {
|
||||
|
|
@ -633,6 +651,22 @@ spa_v4l2_stop (SpaV4l2Source *this)
|
|||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < state->reqbuf.count; i++) {
|
||||
V4l2Buffer *b;
|
||||
|
||||
b = &state->buffers[i];
|
||||
if (b->outstanding) {
|
||||
fprintf (stderr, "queueing outstanding buffer %p\n", b);
|
||||
v4l2_buffer_free (b);
|
||||
}
|
||||
if (state->export_buf) {
|
||||
close (b->dmafd);
|
||||
} else {
|
||||
munmap (b->datas[0].data, b->datas[0].size);
|
||||
}
|
||||
}
|
||||
state->have_buffers = false;
|
||||
|
||||
event.refcount = 1;
|
||||
event.notify = NULL;
|
||||
event.type = SPA_EVENT_TYPE_REMOVE_POLL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue