mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
Improve ringbuffer support
Fix ringbuffer mixing in audiomixer Add ringbuffer support in audiotestsrc params Don't recycle buffers before signaling have_output, the app is supposed to recycle explicitly or with a process_output call. Add some trace to graph functions in tests Add ringbuffer support in export-source
This commit is contained in:
parent
e11e19f3e7
commit
8c77332f25
8 changed files with 110 additions and 61 deletions
|
|
@ -26,6 +26,16 @@ extern "C" {
|
|||
|
||||
#include <spa/graph.h>
|
||||
|
||||
struct spa_graph_data {
|
||||
struct spa_graph *graph;
|
||||
};
|
||||
|
||||
static inline void spa_graph_data_init(struct spa_graph_data *data,
|
||||
struct spa_graph *graph)
|
||||
{
|
||||
data->graph = graph;
|
||||
}
|
||||
|
||||
static inline int spa_graph_impl_need_input(void *data, struct spa_graph_node *node)
|
||||
{
|
||||
struct spa_graph_port *p;
|
||||
|
|
|
|||
|
|
@ -372,7 +372,6 @@ pull_frames(struct state *state,
|
|||
|
||||
spa_ringbuffer_read_data(ringbuffer, d[0].data, index % ringbuffer->size, dst, n_bytes);
|
||||
|
||||
|
||||
spa_ringbuffer_read_update(ringbuffer, index + n_bytes);
|
||||
|
||||
reuse = avail == n_frames || state->n_buffers == 1;
|
||||
|
|
|
|||
|
|
@ -679,11 +679,11 @@ impl_node_port_send_command(struct spa_node *node,
|
|||
static inline void
|
||||
add_port_data(struct impl *this, void *out, size_t outsize, size_t next, struct port *port, int layer)
|
||||
{
|
||||
void *in;
|
||||
size_t insize;
|
||||
struct buffer *b;
|
||||
struct spa_data *id;
|
||||
uint32_t index = 0, offset, len1, len2;
|
||||
mix_func_t mix = layer == 0 ? this->copy : this->add;
|
||||
|
||||
b = spa_list_first(&port->queue, struct buffer, link);
|
||||
|
||||
|
|
@ -704,21 +704,11 @@ add_port_data(struct impl *this, void *out, size_t outsize, size_t next, struct
|
|||
outsize = SPA_MIN(outsize, insize);
|
||||
len1 = outsize;
|
||||
}
|
||||
in = SPA_MEMBER(id[0].data, offset, void);
|
||||
len2 = outsize - len1;
|
||||
|
||||
if (layer == 0) {
|
||||
this->copy(out, in, len1);
|
||||
if (len2 > 0)
|
||||
this->copy(out + len1, in + len1, len2);
|
||||
}
|
||||
else {
|
||||
this->add(out, in, len1);
|
||||
if (len2 > 0)
|
||||
this->add(out + len1, in + len1, len2);
|
||||
}
|
||||
|
||||
spa_log_trace(this->log, NAME " %p: %d %d %d %zd", this, index, len1, len2, outsize);
|
||||
mix(out, SPA_MEMBER(id[0].data, offset, void), len1);
|
||||
if (len2 > 0)
|
||||
mix(out + len1, id[0].data, len2);
|
||||
|
||||
if (b->rb)
|
||||
spa_ringbuffer_read_update(&b->rb->ringbuffer, index + outsize);
|
||||
|
|
@ -774,8 +764,6 @@ static int mix_output(struct impl *this, size_t n_bytes)
|
|||
else
|
||||
len1 = n_bytes;
|
||||
len2 = n_bytes - len1;
|
||||
|
||||
spa_log_trace(this->log, NAME " %p: %d %d %d %ld %d %d", this, index, offset, avail, n_bytes, len1, len2);
|
||||
} else {
|
||||
n_bytes = SPA_MIN(n_bytes, od[0].maxsize);
|
||||
offset = 0;
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ static int make_buffer(struct impl *this)
|
|||
|
||||
if (b->rb) {
|
||||
int32_t filled, avail;
|
||||
uint32_t index, offset;
|
||||
uint32_t index, offset, l0, l1;
|
||||
|
||||
filled = spa_ringbuffer_get_write_index(&b->rb->ringbuffer, &index);
|
||||
avail = b->rb->ringbuffer.size - filled;
|
||||
|
|
@ -296,15 +296,18 @@ static int make_buffer(struct impl *this)
|
|||
offset = index & b->rb->ringbuffer.mask;
|
||||
|
||||
if (offset + n_bytes > b->rb->ringbuffer.size) {
|
||||
uint32_t l0 = b->rb->ringbuffer.size - offset;
|
||||
this->render_func(this, SPA_MEMBER(b->outbuf->datas[0].data, offset, void),
|
||||
l0 / this->bpf);
|
||||
this->render_func(this, b->outbuf->datas[0].data,
|
||||
(n_bytes - l0) / this->bpf);
|
||||
} else {
|
||||
this->render_func(this, SPA_MEMBER(b->outbuf->datas[0].data, offset, void),
|
||||
n_samples);
|
||||
l0 = (b->rb->ringbuffer.size - offset) / this->bpf;
|
||||
l1 = n_samples - l0;
|
||||
}
|
||||
else {
|
||||
l0 = n_samples;
|
||||
l1 = 0;
|
||||
}
|
||||
|
||||
this->render_func(this, SPA_MEMBER(b->outbuf->datas[0].data, offset, void), l0);
|
||||
if (l1)
|
||||
this->render_func(this, b->outbuf->datas[0].data, l1);
|
||||
|
||||
spa_ringbuffer_write_update(&b->rb->ringbuffer, index + n_bytes);
|
||||
} else {
|
||||
n_samples = n_bytes / this->bpf;
|
||||
|
|
@ -674,8 +677,20 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*param = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
|
||||
":", t->param_alloc_meta_enable.ringbufferSize, "ir", 5512 * this->bpf,
|
||||
2, 16 * this->bpf, INT32_MAX / this->bpf,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
|
||||
":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
|
||||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
break;
|
||||
|
||||
default:
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
|
|
|||
|
|
@ -930,9 +930,6 @@ static int mmap_read(struct impl *this)
|
|||
d[0].chunk->size = buf.bytesused;
|
||||
d[0].chunk->stride = port->fmt.fmt.pix.bytesperline;
|
||||
|
||||
if (io->buffer_id != SPA_ID_INVALID)
|
||||
spa_v4l2_buffer_recycle(this, io->buffer_id);
|
||||
|
||||
b->outstanding = true;
|
||||
io->buffer_id = b->outbuf->id;
|
||||
io->status = SPA_RESULT_HAVE_BUFFER;
|
||||
|
|
|
|||
|
|
@ -35,14 +35,17 @@
|
|||
#include <spa/audio/format-utils.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/graph.h>
|
||||
#include <spa/graph-scheduler1.h>
|
||||
|
||||
#include <lib/debug.h>
|
||||
|
||||
static SPA_TYPE_MAP_IMPL(default_map, 4096);
|
||||
static SPA_LOG_IMPL(default_log);
|
||||
|
||||
#define spa_debug(f,...) spa_log_trace(&default_log.log, f, __VA_ARGS__)
|
||||
|
||||
#include <spa/graph.h>
|
||||
#include <spa/graph-scheduler6.h>
|
||||
|
||||
#include <lib/debug.h>
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t props;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
#include <spa/log.h>
|
||||
#include <spa/log-impl.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/graph.h>
|
||||
#include <spa/graph-scheduler1.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/type-map-impl.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
|
|
@ -43,6 +41,11 @@
|
|||
static SPA_TYPE_MAP_IMPL(default_map, 4096);
|
||||
static SPA_LOG_IMPL(default_log);
|
||||
|
||||
#define spa_debug(...) spa_log_trace(&default_log.log,__VA_ARGS__)
|
||||
|
||||
#include <spa/graph.h>
|
||||
#include <spa/graph-scheduler1.h>
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t props;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue