mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-06 13:30:01 -05:00
buffer: don't use ringbuffer in chunk
We can't use a ringbuffer on the chunk because it implies the consumer would write to it to update the read position, which we can't do because the chunk is read-only and might even be shared. Go back to offset/size pairs, which can sortof do the same thing if we want later when we keep a non-shared read pointer in the consumer. Keep alsa timestamp around and filled state for future. mmap the input port meta/data/chunk as read-only. Only do clock update requests when asked.
This commit is contained in:
parent
2ad722b579
commit
4288a634f4
25 changed files with 165 additions and 126 deletions
|
|
@ -364,8 +364,8 @@ static int impl_node_process_output(struct spa_node *node)
|
|||
int16_t *dst;
|
||||
struct spa_port_io *io = d->io;
|
||||
uint32_t maxsize, index = 0;
|
||||
struct spa_ringbuffer *rb;
|
||||
uint32_t filled, offset;
|
||||
struct spa_data *od;
|
||||
|
||||
if (io->buffer_id < d->n_buffers) {
|
||||
reuse_buffer(d, io->buffer_id);
|
||||
|
|
@ -378,10 +378,12 @@ static int impl_node_process_output(struct spa_node *node)
|
|||
b = spa_list_first(&d->empty, struct buffer, link);
|
||||
spa_list_remove(&b->link);
|
||||
|
||||
maxsize = b->buffer->datas[0].maxsize;
|
||||
rb = &b->buffer->datas[0].chunk->area;
|
||||
od = b->buffer->datas;
|
||||
|
||||
filled = spa_ringbuffer_get_write_index(rb, &index);
|
||||
maxsize = od[0].maxsize;
|
||||
|
||||
filled = 0;
|
||||
index = 0;
|
||||
avail = maxsize - filled;
|
||||
offset = index % maxsize;
|
||||
|
||||
|
|
@ -404,7 +406,9 @@ static int impl_node_process_output(struct spa_node *node)
|
|||
*dst++ = val;
|
||||
}
|
||||
|
||||
spa_ringbuffer_write_update(rb, index + avail);
|
||||
od[0].chunk->offset = 0;
|
||||
od[0].chunk->size = avail;
|
||||
od[0].chunk->stride = 0;
|
||||
|
||||
io->buffer_id = b->buffer->id;
|
||||
io->status = SPA_STATUS_HAVE_BUFFER;
|
||||
|
|
|
|||
|
|
@ -526,8 +526,8 @@ do_send_buffer (GstPipeWireSink *pwsink)
|
|||
for (i = 0; i < data->buf->n_datas; i++) {
|
||||
struct spa_data *d = &data->buf->datas[i];
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
d->chunk->area.readindex = mem->offset - data->offset;
|
||||
d->chunk->area.writeindex = d->chunk->area.readindex + mem->size;
|
||||
d->chunk->offset = mem->offset - data->offset;
|
||||
d->chunk->size = mem->size;
|
||||
}
|
||||
|
||||
if (!(res = pw_stream_send_buffer (pwsink->stream, data->id))) {
|
||||
|
|
|
|||
|
|
@ -464,11 +464,9 @@ on_new_buffer (void *_data,
|
|||
}
|
||||
for (i = 0; i < data->buf->n_datas; i++) {
|
||||
struct spa_data *d = &data->buf->datas[i];
|
||||
uint32_t index;
|
||||
GstMemory *mem = gst_buffer_peek_memory (buf, i);
|
||||
mem->size = spa_ringbuffer_get_read_index(&d->chunk->area, &index);
|
||||
mem->offset = index % d->maxsize;
|
||||
spa_ringbuffer_set_avail(&d->chunk->area, 0);
|
||||
mem->offset = SPA_MIN(d->chunk->offset, d->maxsize);
|
||||
mem->size = SPA_MIN(d->chunk->size, d->maxsize - mem->offset);
|
||||
}
|
||||
|
||||
if (pwsrc->always_copy)
|
||||
|
|
@ -663,7 +661,7 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
pw_stream_connect (pwsrc->stream,
|
||||
PW_DIRECTION_INPUT,
|
||||
pwsrc->path,
|
||||
PW_STREAM_FLAG_AUTOCONNECT,
|
||||
PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_CLOCK_UPDATE,
|
||||
(const struct spa_pod **)possible->pdata,
|
||||
possible->len);
|
||||
g_ptr_array_free (possible, TRUE);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
#include <pipewire/log.h>
|
||||
#include <extensions/client-node.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -305,7 +305,9 @@ static int driver_process_output(struct spa_node *node)
|
|||
in_io->status = SPA_STATUS_NEED_BUFFER;
|
||||
}
|
||||
|
||||
spa_ringbuffer_set_avail(&out->outbuf->datas[0].chunk->area, ctrl->buffer_size * sizeof(int16_t) * 2);
|
||||
out->outbuf->datas[0].chunk->offset = 0;
|
||||
out->outbuf->datas[0].chunk->size = ctrl->buffer_size * sizeof(int16_t) * 2;
|
||||
out->outbuf->datas[0].chunk->stride = 0;
|
||||
|
||||
spa_hook_list_call(&nd->listener_list, struct pw_jack_node_events, push);
|
||||
gn->ready[SPA_DIRECTION_INPUT] = gn->required[SPA_DIRECTION_OUTPUT] = 0;
|
||||
|
|
|
|||
|
|
@ -305,7 +305,8 @@ static struct spa_pod *find_param(struct spa_pod **params, int n_params, uint32_
|
|||
* || | ... <n_metas> |
|
||||
* || +------------------------------+
|
||||
* +->| struct spa_chunk | memory for n_datas chunks
|
||||
* | | struct spa_ringbuffer area |
|
||||
* | | uint32_t offset |
|
||||
* | | uint32_t size |
|
||||
* | | int32_t stride |
|
||||
* | | ... <n_datas> chunks |
|
||||
* | +------------------------------+
|
||||
|
|
@ -438,7 +439,8 @@ static struct spa_buffer **alloc_buffers(struct pw_link *this,
|
|||
d->mapoffset = SPA_PTRDIFF(ddp, mem->ptr);
|
||||
d->maxsize = data_sizes[j];
|
||||
d->data = SPA_MEMBER(mem->ptr, d->mapoffset, void);
|
||||
spa_ringbuffer_set_avail(&d->chunk->area, 0);
|
||||
d->chunk->offset = 0;
|
||||
d->chunk->size = 0;
|
||||
d->chunk->stride = data_strides[j];
|
||||
ddp += data_sizes[j];
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -955,8 +955,7 @@ client_node_port_use_buffers(void *object,
|
|||
|
||||
if (mid->ptr == NULL) {
|
||||
mid->ptr =
|
||||
mmap(NULL, mid->size + mid->offset, prot, MAP_SHARED,
|
||||
mid->fd, 0);
|
||||
mmap(NULL, mid->size + mid->offset, prot, MAP_SHARED, mid->fd, 0);
|
||||
if (mid->ptr == MAP_FAILED) {
|
||||
mid->ptr = NULL;
|
||||
pw_log_warn("Failed to mmap memory %d %p: %s", mid->size, mid,
|
||||
|
|
|
|||
|
|
@ -661,10 +661,12 @@ static void handle_socket(struct pw_stream *stream, int rtreadfd, int rtwritefd)
|
|||
SPA_IO_ERR | SPA_IO_HUP,
|
||||
true, on_rtsocket_condition, stream);
|
||||
|
||||
impl->timeout_source = pw_loop_add_timer(stream->remote->core->main_loop, on_timeout, stream);
|
||||
interval.tv_sec = 0;
|
||||
interval.tv_nsec = 100000000;
|
||||
pw_loop_update_timer(stream->remote->core->main_loop, impl->timeout_source, NULL, &interval, false);
|
||||
if (impl->flags & PW_STREAM_FLAG_CLOCK_UPDATE) {
|
||||
impl->timeout_source = pw_loop_add_timer(stream->remote->core->main_loop, on_timeout, stream);
|
||||
interval.tv_sec = 0;
|
||||
interval.tv_nsec = 100000000;
|
||||
pw_loop_update_timer(stream->remote->core->main_loop, impl->timeout_source, NULL, &interval, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -830,6 +832,9 @@ client_node_port_use_buffers(void *data,
|
|||
struct buffer_id *bid;
|
||||
uint32_t i, j, len;
|
||||
struct spa_buffer *b;
|
||||
int prot;
|
||||
|
||||
prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0);
|
||||
|
||||
/* clear previous buffers */
|
||||
clear_buffers(stream);
|
||||
|
|
@ -845,8 +850,7 @@ client_node_port_use_buffers(void *data,
|
|||
|
||||
if (mid->ptr == NULL) {
|
||||
mid->ptr =
|
||||
mmap(NULL, mid->size + mid->offset, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
mid->fd, 0);
|
||||
mmap(NULL, mid->size + mid->offset, prot, MAP_SHARED, mid->fd, 0);
|
||||
if (mid->ptr == MAP_FAILED) {
|
||||
mid->ptr = NULL;
|
||||
pw_log_warn("Failed to mmap memory %d %p: %s", mid->size, mid,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue