mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
Plug some leaks
Add maxsize to bufferdata in case the memory size can be variable such as with encoded formats. Copy new size in the proxy.
This commit is contained in:
parent
9d4048e73a
commit
b208e8b690
15 changed files with 117 additions and 57 deletions
|
|
@ -389,12 +389,12 @@ on_add_buffer (GObject *gobject,
|
||||||
gint fd = *(int*)d->data;
|
gint fd = *(int*)d->data;
|
||||||
|
|
||||||
fdmem = gst_fd_allocator_alloc (pinossink->allocator, dup (fd),
|
fdmem = gst_fd_allocator_alloc (pinossink->allocator, dup (fd),
|
||||||
d->offset + d->size, GST_FD_MEMORY_FLAG_NONE);
|
d->offset + d->maxsize, GST_FD_MEMORY_FLAG_NONE);
|
||||||
gst_memory_resize (fdmem, d->offset, d->size);
|
gst_memory_resize (fdmem, d->offset, d->size);
|
||||||
gst_buffer_append_memory (buf, fdmem);
|
gst_buffer_append_memory (buf, fdmem);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_append_memory (buf,
|
gst_buffer_append_memory (buf,
|
||||||
gst_memory_new_wrapped (0, d->data, d->offset + d->size, d->offset,
|
gst_memory_new_wrapped (0, d->data, d->offset + d->maxsize, d->offset,
|
||||||
d->size, NULL, NULL));
|
d->size, NULL, NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -404,10 +404,10 @@ on_add_buffer (GObject *gobject,
|
||||||
gint fd = SPA_PTR_TO_INT (d->data);
|
gint fd = SPA_PTR_TO_INT (d->data);
|
||||||
|
|
||||||
gmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, dup (fd),
|
gmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, dup (fd),
|
||||||
d->offset + d->size, GST_FD_MEMORY_FLAG_NONE);
|
d->offset + d->maxsize, GST_FD_MEMORY_FLAG_NONE);
|
||||||
gst_memory_resize (gmem, d->offset, d->size);
|
gst_memory_resize (gmem, d->offset, d->size);
|
||||||
} else {
|
} else {
|
||||||
gmem = gst_memory_new_wrapped (0, d->data, d->offset + d->size, d->offset,
|
gmem = gst_memory_new_wrapped (0, d->data, d->offset + d->maxsize, d->offset,
|
||||||
d->size, NULL, NULL);
|
d->size, NULL, NULL);
|
||||||
}
|
}
|
||||||
gst_buffer_append_memory (buf, gmem);
|
gst_buffer_append_memory (buf, gmem);
|
||||||
|
|
|
||||||
|
|
@ -491,6 +491,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||||
this->input->buffers = priv->buffers;
|
this->input->buffers = priv->buffers;
|
||||||
this->input->n_buffers = priv->n_buffers;
|
this->input->n_buffers = priv->n_buffers;
|
||||||
this->input->allocated = TRUE;
|
this->input->allocated = TRUE;
|
||||||
|
this->input->buffer_mem = priv->buffer_mem;
|
||||||
priv->allocated = FALSE;
|
priv->allocated = FALSE;
|
||||||
g_debug ("allocated %d buffers %p from input port", priv->n_buffers, priv->buffers);
|
g_debug ("allocated %d buffers %p from input port", priv->n_buffers, priv->buffers);
|
||||||
}
|
}
|
||||||
|
|
@ -507,6 +508,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||||
this->output->buffers = priv->buffers;
|
this->output->buffers = priv->buffers;
|
||||||
this->output->n_buffers = priv->n_buffers;
|
this->output->n_buffers = priv->n_buffers;
|
||||||
this->output->allocated = TRUE;
|
this->output->allocated = TRUE;
|
||||||
|
this->output->buffer_mem = priv->buffer_mem;
|
||||||
priv->allocated = FALSE;
|
priv->allocated = FALSE;
|
||||||
g_debug ("allocated %d buffers %p from output port", priv->n_buffers, priv->buffers);
|
g_debug ("allocated %d buffers %p from output port", priv->n_buffers, priv->buffers);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ typedef struct _PinosLinkClass PinosLinkClass;
|
||||||
typedef struct _PinosLinkPrivate PinosLinkPrivate;
|
typedef struct _PinosLinkPrivate PinosLinkPrivate;
|
||||||
|
|
||||||
#include <pinos/server/daemon.h>
|
#include <pinos/server/daemon.h>
|
||||||
|
#include <pinos/server/utils.h>
|
||||||
#include <spa/include/spa/ringbuffer.h>
|
#include <spa/include/spa/ringbuffer.h>
|
||||||
|
|
||||||
#define PINOS_TYPE_LINK (pinos_link_get_type ())
|
#define PINOS_TYPE_LINK (pinos_link_get_type ())
|
||||||
|
|
@ -41,11 +42,12 @@ typedef struct _PinosLinkPrivate PinosLinkPrivate;
|
||||||
#define PINOS_LINK_CLASS_CAST(klass)((PinosLinkClass*)(klass))
|
#define PINOS_LINK_CLASS_CAST(klass)((PinosLinkClass*)(klass))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PinosNode *node;
|
PinosNode *node;
|
||||||
uint32_t port;
|
uint32_t port;
|
||||||
gboolean allocated;
|
gboolean allocated;
|
||||||
SpaBuffer **buffers;
|
PinosMemblock buffer_mem;
|
||||||
guint n_buffers;
|
SpaBuffer **buffers;
|
||||||
|
guint n_buffers;
|
||||||
} PinosPort;
|
} PinosPort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,8 @@ suspend_node (PinosNode *this)
|
||||||
g_warning ("error unset format output: %d", res);
|
g_warning ("error unset format output: %d", res);
|
||||||
p->port.buffers = NULL;
|
p->port.buffers = NULL;
|
||||||
p->port.n_buffers = 0;
|
p->port.n_buffers = 0;
|
||||||
|
if (p->port.allocated)
|
||||||
|
pinos_memblock_free (&p->port.buffer_mem);
|
||||||
p->port.allocated = FALSE;
|
p->port.allocated = FALSE;
|
||||||
}
|
}
|
||||||
for (walk = priv->output_ports; walk; walk = g_list_next (walk)) {
|
for (walk = priv->output_ports; walk; walk = g_list_next (walk)) {
|
||||||
|
|
@ -293,6 +295,8 @@ suspend_node (PinosNode *this)
|
||||||
g_warning ("error unset format output: %d", res);
|
g_warning ("error unset format output: %d", res);
|
||||||
p->port.buffers = NULL;
|
p->port.buffers = NULL;
|
||||||
p->port.n_buffers = 0;
|
p->port.n_buffers = 0;
|
||||||
|
if (p->port.allocated)
|
||||||
|
pinos_memblock_free (&p->port.buffer_mem);
|
||||||
p->port.allocated = FALSE;
|
p->port.allocated = FALSE;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,14 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "memfd-wrappers.h"
|
#include "memfd-wrappers.h"
|
||||||
|
|
||||||
#include <pinos/server/utils.h>
|
#include <pinos/server/utils.h>
|
||||||
|
|
||||||
|
#undef USE_MEMFD
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
pinos_memblock_alloc (PinosMemblockFlags flags,
|
pinos_memblock_alloc (PinosMemblockFlags flags,
|
||||||
gsize size,
|
gsize size,
|
||||||
|
|
@ -41,19 +44,35 @@ pinos_memblock_alloc (PinosMemblockFlags flags,
|
||||||
mem->size = size;
|
mem->size = size;
|
||||||
|
|
||||||
if (flags & PINOS_MEMBLOCK_FLAG_WITH_FD) {
|
if (flags & PINOS_MEMBLOCK_FLAG_WITH_FD) {
|
||||||
|
#ifdef USE_MEMFD
|
||||||
mem->fd = memfd_create ("pinos-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
mem->fd = memfd_create ("pinos-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||||
|
if (mem->fd == -1) {
|
||||||
|
fprintf (stderr, "Failed to create memfd: %s\n", strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
char filename[] = "/dev/shm/spa-tmpfile.XXXXXX";
|
||||||
|
mem->fd = mkostemp (filename, O_CLOEXEC);
|
||||||
|
if (mem->fd == -1) {
|
||||||
|
fprintf (stderr, "Failed to create temporary file: %s\n", strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
unlink (filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ftruncate (mem->fd, size) < 0) {
|
if (ftruncate (mem->fd, size) < 0) {
|
||||||
g_warning ("Failed to truncate temporary file: %s", strerror (errno));
|
g_warning ("Failed to truncate temporary file: %s", strerror (errno));
|
||||||
close (mem->fd);
|
close (mem->fd);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_MEMFD
|
||||||
if (flags & PINOS_MEMBLOCK_FLAG_SEAL) {
|
if (flags & PINOS_MEMBLOCK_FLAG_SEAL) {
|
||||||
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
|
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
|
||||||
if (fcntl (mem->fd, F_ADD_SEALS, seals) == -1) {
|
if (fcntl (mem->fd, F_ADD_SEALS, seals) == -1) {
|
||||||
g_warning ("Failed to add seals: %s", strerror (errno));
|
g_warning ("Failed to add seals: %s", strerror (errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (flags & PINOS_MEMBLOCK_FLAG_MAP_READWRITE) {
|
if (flags & PINOS_MEMBLOCK_FLAG_MAP_READWRITE) {
|
||||||
int prot = 0;
|
int prot = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,6 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _PinosMemblock PinosMemblock;
|
typedef struct _PinosMemblock PinosMemblock;
|
||||||
|
|
||||||
#include <pinos/server/daemon.h>
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PINOS_MEMBLOCK_FLAG_NONE = 0,
|
PINOS_MEMBLOCK_FLAG_NONE = 0,
|
||||||
PINOS_MEMBLOCK_FLAG_WITH_FD = (1 << 0),
|
PINOS_MEMBLOCK_FLAG_WITH_FD = (1 << 0),
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,8 @@ typedef enum {
|
||||||
* @type: memory type
|
* @type: memory type
|
||||||
* @data: pointer to memory
|
* @data: pointer to memory
|
||||||
* @offset: offset in @data
|
* @offset: offset in @data
|
||||||
* @size: size of @data
|
* @size: valid size of @data
|
||||||
|
* @maxsize: size of @data
|
||||||
* @stride: stride of data if applicable
|
* @stride: stride of data if applicable
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -140,6 +141,7 @@ typedef struct {
|
||||||
void *data;
|
void *data;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
size_t maxsize;
|
||||||
ssize_t stride;
|
ssize_t stride;
|
||||||
} SpaData;
|
} SpaData;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ spa_prop_info_fill_audio (SpaPropInfo *info,
|
||||||
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
||||||
|
|
||||||
memcpy (info, &format_prop_info[i], sizeof (SpaPropInfo));
|
memcpy (info, &format_prop_info[i], sizeof (SpaPropInfo));
|
||||||
info->offset = offset;
|
info->offset = offset - sizeof (SpaFormat) + sizeof (SpaProps);
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,11 +122,12 @@ spa_debug_buffer (const SpaBuffer *buffer)
|
||||||
fprintf (stderr, " n_datas: \t%u (at %p)\n", buffer->n_datas, buffer->datas);
|
fprintf (stderr, " n_datas: \t%u (at %p)\n", buffer->n_datas, buffer->datas);
|
||||||
for (i = 0; i < buffer->n_datas; i++) {
|
for (i = 0; i < buffer->n_datas; i++) {
|
||||||
SpaData *d = &buffer->datas[i];
|
SpaData *d = &buffer->datas[i];
|
||||||
fprintf (stderr, " type: %d\n", d->type);
|
fprintf (stderr, " type: %d\n", d->type);
|
||||||
fprintf (stderr, " data: %p\n", d->data);
|
fprintf (stderr, " data: %p\n", d->data);
|
||||||
fprintf (stderr, " offset: %zd\n", d->offset);
|
fprintf (stderr, " offset: %zd\n", d->offset);
|
||||||
fprintf (stderr, " size: %zd\n", d->size);
|
fprintf (stderr, " size: %zd\n", d->size);
|
||||||
fprintf (stderr, " stride: %zd\n", d->stride);
|
fprintf (stderr, " maxsize: %zd\n", d->maxsize);
|
||||||
|
fprintf (stderr, " stride: %zd\n", d->stride);
|
||||||
}
|
}
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ struct _SpaAudioMixer {
|
||||||
|
|
||||||
int port_count;
|
int port_count;
|
||||||
int port_queued;
|
int port_queued;
|
||||||
SpaAudioMixerPort ports[MAX_PORTS];
|
SpaAudioMixerPort ports[MAX_PORTS + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -224,13 +224,13 @@ spa_audiomixer_node_get_port_ids (SpaNode *node,
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (input_ids) {
|
if (input_ids) {
|
||||||
for (i = 1, idx = 0; i < MAX_PORTS && idx < n_input_ports; i++) {
|
for (i = 0, idx = 0; i < MAX_PORTS && idx < n_input_ports; i++) {
|
||||||
if (this->ports[i].valid)
|
if (this->ports[i].valid)
|
||||||
input_ids[idx++] = i;
|
input_ids[idx++] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n_output_ports > 0 && output_ids)
|
if (n_output_ports > 0 && output_ids)
|
||||||
output_ids[0] = 0;
|
output_ids[0] = MAX_PORTS;
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +261,7 @@ spa_audiomixer_node_add_port (SpaNode *node,
|
||||||
SPA_PORT_INFO_FLAG_IN_PLACE;
|
SPA_PORT_INFO_FLAG_IN_PLACE;
|
||||||
this->ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
this->ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
||||||
|
|
||||||
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
this->ports[MAX_PORTS].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -277,7 +277,7 @@ spa_audiomixer_node_remove_port (SpaNode *node,
|
||||||
|
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (port_id == 0 || port_id >= MAX_PORTS || !this->ports[port_id].valid)
|
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
this->ports[port_id].valid = false;
|
this->ports[port_id].valid = false;
|
||||||
|
|
@ -287,7 +287,7 @@ spa_audiomixer_node_remove_port (SpaNode *node,
|
||||||
this->port_queued--;
|
this->port_queued--;
|
||||||
}
|
}
|
||||||
if (this->port_count == this->port_queued)
|
if (this->port_count == this->port_queued)
|
||||||
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
this->ports[MAX_PORTS].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -377,7 +377,7 @@ spa_audiomixer_node_port_get_format (SpaNode *node,
|
||||||
|
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
|
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
@ -403,7 +403,7 @@ spa_audiomixer_node_port_get_info (SpaNode *node,
|
||||||
|
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
|
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
@ -469,7 +469,7 @@ spa_audiomixer_node_port_get_status (SpaNode *node,
|
||||||
|
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
|
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
@ -495,7 +495,7 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
|
||||||
|
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (this->ports[0].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
|
if (this->ports[MAX_PORTS].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
|
||||||
return SPA_RESULT_HAVE_ENOUGH_INPUT;
|
return SPA_RESULT_HAVE_ENOUGH_INPUT;
|
||||||
|
|
||||||
for (i = 0; i < n_info; i++) {
|
for (i = 0; i < n_info; i++) {
|
||||||
|
|
@ -673,7 +673,7 @@ spa_audiomixer_node_port_pull_output (SpaNode *node,
|
||||||
|
|
||||||
this = (SpaAudioMixer *) node->handle;
|
this = (SpaAudioMixer *) node->handle;
|
||||||
|
|
||||||
if (info->port_id != 0)
|
if (info->port_id != MAX_PORTS)
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
port = &this->ports[info->port_id];
|
port = &this->ports[info->port_id];
|
||||||
|
|
@ -781,10 +781,10 @@ spa_audiomixer_init (const SpaHandleFactory *factory,
|
||||||
this->props[1].props.prop_info = prop_info;
|
this->props[1].props.prop_info = prop_info;
|
||||||
reset_audiomixer_props (&this->props[1]);
|
reset_audiomixer_props (&this->props[1]);
|
||||||
|
|
||||||
this->ports[0].valid = true;
|
this->ports[MAX_PORTS].valid = true;
|
||||||
this->ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
|
this->ports[MAX_PORTS].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
|
||||||
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
||||||
SPA_PORT_INFO_FLAG_NO_REF;
|
SPA_PORT_INFO_FLAG_NO_REF;
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -418,6 +418,27 @@ do_update_port (SpaProxy *this,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_port (SpaProxy *this,
|
||||||
|
SpaProxyPort *port,
|
||||||
|
uint32_t port_id)
|
||||||
|
{
|
||||||
|
SpaControlCmdPortUpdate pu;
|
||||||
|
|
||||||
|
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||||
|
SPA_CONTROL_CMD_PORT_UPDATE_FORMAT |
|
||||||
|
SPA_CONTROL_CMD_PORT_UPDATE_PROPS |
|
||||||
|
SPA_CONTROL_CMD_PORT_UPDATE_INFO;
|
||||||
|
pu.port_id = port_id;
|
||||||
|
pu.n_possible_formats = 0;
|
||||||
|
pu.possible_formats = NULL;
|
||||||
|
pu.format = NULL;
|
||||||
|
pu.props = NULL;
|
||||||
|
pu.info = NULL;
|
||||||
|
do_update_port (this, &pu);
|
||||||
|
clear_buffers (this, port);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_uninit_port (SpaProxy *this,
|
do_uninit_port (SpaProxy *this,
|
||||||
uint32_t port_id)
|
uint32_t port_id)
|
||||||
|
|
@ -432,10 +453,8 @@ do_uninit_port (SpaProxy *this,
|
||||||
else
|
else
|
||||||
this->n_outputs--;
|
this->n_outputs--;
|
||||||
|
|
||||||
|
clear_port (this, port, port_id);
|
||||||
port->valid = false;
|
port->valid = false;
|
||||||
if (port->format)
|
|
||||||
free (port->format);
|
|
||||||
port->format = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
|
|
@ -443,7 +462,7 @@ spa_proxy_node_add_port (SpaNode *node,
|
||||||
uint32_t port_id)
|
uint32_t port_id)
|
||||||
{
|
{
|
||||||
SpaProxy *this;
|
SpaProxy *this;
|
||||||
SpaControlCmdPortUpdate pu;
|
SpaProxyPort *port;
|
||||||
|
|
||||||
if (node == NULL || node->handle == NULL)
|
if (node == NULL || node->handle == NULL)
|
||||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||||
|
|
@ -453,17 +472,8 @@ spa_proxy_node_add_port (SpaNode *node,
|
||||||
if (!CHECK_FREE_PORT_ID (this, port_id))
|
if (!CHECK_FREE_PORT_ID (this, port_id))
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
|
port = &this->ports[port_id];
|
||||||
SPA_CONTROL_CMD_PORT_UPDATE_FORMAT |
|
clear_port (this, port, port_id);
|
||||||
SPA_CONTROL_CMD_PORT_UPDATE_PROPS |
|
|
||||||
SPA_CONTROL_CMD_PORT_UPDATE_INFO;
|
|
||||||
pu.port_id = port_id;
|
|
||||||
pu.n_possible_formats = 0;
|
|
||||||
pu.possible_formats = NULL;
|
|
||||||
pu.format = NULL;
|
|
||||||
pu.props = NULL;
|
|
||||||
pu.info = NULL;
|
|
||||||
do_update_port (this, &pu);
|
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -714,7 +724,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
||||||
am.fd_index = spa_control_builder_add_fd (&builder, SPA_PTR_TO_INT (d->data), false);
|
am.fd_index = spa_control_builder_add_fd (&builder, SPA_PTR_TO_INT (d->data), false);
|
||||||
am.flags = 0;
|
am.flags = 0;
|
||||||
am.offset = d->offset;
|
am.offset = d->offset;
|
||||||
am.size = d->size;
|
am.size = d->maxsize;
|
||||||
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
|
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
|
||||||
|
|
||||||
b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
|
b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
|
||||||
|
|
@ -732,12 +742,14 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
||||||
close (port->buffer_mem_fd);
|
close (port->buffer_mem_fd);
|
||||||
return SPA_RESULT_ERROR;
|
return SPA_RESULT_ERROR;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
|
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
|
||||||
if (fcntl (port->buffer_mem_fd, F_ADD_SEALS, seals) == -1) {
|
if (fcntl (port->buffer_mem_fd, F_ADD_SEALS, seals) == -1) {
|
||||||
fprintf (stderr, "Failed to add seals: %s\n", strerror (errno));
|
fprintf (stderr, "Failed to add seals: %s\n", strerror (errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
p = port->buffer_mem_ptr = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, port->buffer_mem_fd, 0);
|
p = port->buffer_mem_ptr = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, port->buffer_mem_fd, 0);
|
||||||
|
|
||||||
for (i = 0; i < n_buffers; i++) {
|
for (i = 0; i < n_buffers; i++) {
|
||||||
|
|
@ -749,6 +761,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
||||||
len = spa_buffer_serialize (p, &b->buffer);
|
len = spa_buffer_serialize (p, &b->buffer);
|
||||||
|
|
||||||
sb = p;
|
sb = p;
|
||||||
|
b->buffer.datas = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData);
|
||||||
sbm = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->metas), SpaMeta);
|
sbm = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->metas), SpaMeta);
|
||||||
|
|
||||||
for (j = 0; j < b->buffer.n_metas; j++)
|
for (j = 0; j < b->buffer.n_metas; j++)
|
||||||
|
|
@ -869,6 +882,9 @@ copy_meta (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
|
||||||
SpaMeta *dm = &b->buffer.metas[i];
|
SpaMeta *dm = &b->buffer.metas[i];
|
||||||
memcpy (dm->data, sm->data, dm->size);
|
memcpy (dm->data, sm->data, dm->size);
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < b->outbuf->n_datas; i++) {
|
||||||
|
b->buffer.datas[i].size = b->outbuf->datas[i].size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
|
|
@ -1223,6 +1239,19 @@ spa_proxy_get_interface (SpaHandle *handle,
|
||||||
static SpaResult
|
static SpaResult
|
||||||
proxy_clear (SpaHandle *handle)
|
proxy_clear (SpaHandle *handle)
|
||||||
{
|
{
|
||||||
|
SpaProxy *this;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (handle == NULL)
|
||||||
|
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
this = (SpaProxy *) handle;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_PORTS; i++) {
|
||||||
|
if (this->ports[i].valid)
|
||||||
|
clear_port (this, &this->ports[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -948,7 +948,7 @@ spa_v4l2_use_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_buffe
|
||||||
b->v4l2_buffer.memory = state->memtype;
|
b->v4l2_buffer.memory = state->memtype;
|
||||||
b->v4l2_buffer.index = i;
|
b->v4l2_buffer.index = i;
|
||||||
b->v4l2_buffer.m.userptr = (unsigned long) SPA_MEMBER (d[0].data, d[0].offset, void *);
|
b->v4l2_buffer.m.userptr = (unsigned long) SPA_MEMBER (d[0].data, d[0].offset, void *);
|
||||||
b->v4l2_buffer.length = d[0].size;
|
b->v4l2_buffer.length = d[0].maxsize;
|
||||||
|
|
||||||
spa_v4l2_buffer_recycle (this, buffers[i]->id);
|
spa_v4l2_buffer_recycle (this, buffers[i]->id);
|
||||||
}
|
}
|
||||||
|
|
@ -1017,6 +1017,7 @@ mmap_init (SpaV4l2Source *this,
|
||||||
d = buffers[i]->datas;
|
d = buffers[i]->datas;
|
||||||
d[0].offset = 0;
|
d[0].offset = 0;
|
||||||
d[0].size = b->v4l2_buffer.length;
|
d[0].size = b->v4l2_buffer.length;
|
||||||
|
d[0].maxsize = b->v4l2_buffer.length;
|
||||||
d[0].stride = state->fmt.fmt.pix.bytesperline;
|
d[0].stride = state->fmt.fmt.pix.bytesperline;
|
||||||
|
|
||||||
if (state->export_buf) {
|
if (state->export_buf) {
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ make_nodes (AppData *data)
|
||||||
SpaProps *props;
|
SpaProps *props;
|
||||||
SpaPropValue value;
|
SpaPropValue value;
|
||||||
|
|
||||||
if ((res = make_node (&data->sink, "plugins/alsa/libspa-alsa.so", "alsa-sink")) < 0) {
|
if ((res = make_node (&data->sink, "spa/plugins/alsa/libspa-alsa.so", "alsa-sink")) < 0) {
|
||||||
printf ("can't create alsa-sink: %d\n", res);
|
printf ("can't create alsa-sink: %d\n", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +188,7 @@ make_nodes (AppData *data)
|
||||||
if ((res = spa_node_get_props (data->sink, &props)) < 0)
|
if ((res = spa_node_get_props (data->sink, &props)) < 0)
|
||||||
printf ("got get_props error %d\n", res);
|
printf ("got get_props error %d\n", res);
|
||||||
|
|
||||||
value.value = "hw:0";
|
value.value = "hw:1";
|
||||||
value.size = strlen (value.value)+1;
|
value.size = strlen (value.value)+1;
|
||||||
spa_props_set_value (props, spa_props_index_for_name (props, "device"), &value);
|
spa_props_set_value (props, spa_props_index_for_name (props, "device"), &value);
|
||||||
|
|
||||||
|
|
@ -196,17 +196,17 @@ make_nodes (AppData *data)
|
||||||
printf ("got set_props error %d\n", res);
|
printf ("got set_props error %d\n", res);
|
||||||
|
|
||||||
|
|
||||||
if ((res = make_node (&data->mix, "plugins/audiomixer/libspa-audiomixer.so", "audiomixer")) < 0) {
|
if ((res = make_node (&data->mix, "spa/plugins/audiomixer/libspa-audiomixer.so", "audiomixer")) < 0) {
|
||||||
printf ("can't create audiomixer: %d\n", res);
|
printf ("can't create audiomixer: %d\n", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
spa_node_set_event_callback (data->mix, on_mix_event, data);
|
spa_node_set_event_callback (data->mix, on_mix_event, data);
|
||||||
|
|
||||||
if ((res = make_node (&data->source1, "plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
|
if ((res = make_node (&data->source1, "spa/plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
|
||||||
printf ("can't create audiotestsrc: %d\n", res);
|
printf ("can't create audiotestsrc: %d\n", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if ((res = make_node (&data->source2, "plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
|
if ((res = make_node (&data->source2, "spa/plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
|
||||||
printf ("can't create audiotestsrc: %d\n", res);
|
printf ("can't create audiotestsrc: %d\n", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +247,7 @@ negotiate_formats (AppData *data)
|
||||||
if ((res = spa_node_port_set_format (data->sink, 0, false, format)) < 0)
|
if ((res = spa_node_port_set_format (data->sink, 0, false, format)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if ((res = spa_node_port_set_format (data->mix, 0, false, format)) < 0)
|
if ((res = spa_node_port_set_format (data->mix, 128, false, format)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
data->mix_ports[0] = 0;
|
data->mix_ports[0] = 0;
|
||||||
|
|
@ -260,7 +260,7 @@ negotiate_formats (AppData *data)
|
||||||
if ((res = spa_node_port_set_format (data->source1, 0, false, format)) < 0)
|
if ((res = spa_node_port_set_format (data->source1, 0, false, format)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
data->mix_ports[1] = 0;
|
data->mix_ports[1] = 1;
|
||||||
if ((res = spa_node_add_port (data->mix, 1)) < 0)
|
if ((res = spa_node_add_port (data->mix, 1)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ on_source_event (SpaNode *node, SpaNodeEvent *event, void *user_data)
|
||||||
datas[0].data = sdata;
|
datas[0].data = sdata;
|
||||||
datas[0].offset = 0;
|
datas[0].offset = 0;
|
||||||
datas[0].size = sstride * 240;
|
datas[0].size = sstride * 240;
|
||||||
|
datas[0].maxsize = sstride * 240;
|
||||||
datas[0].stride = sstride;
|
datas[0].stride = sstride;
|
||||||
} else {
|
} else {
|
||||||
if (SDL_LockTexture (data->texture, NULL, &ddata, &dstride) < 0) {
|
if (SDL_LockTexture (data->texture, NULL, &ddata, &dstride) < 0) {
|
||||||
|
|
@ -267,6 +268,7 @@ alloc_buffers (AppData *data)
|
||||||
b->datas[0].data = ptr;
|
b->datas[0].data = ptr;
|
||||||
b->datas[0].offset = 0;
|
b->datas[0].offset = 0;
|
||||||
b->datas[0].size = stride * 240;
|
b->datas[0].size = stride * 240;
|
||||||
|
b->datas[0].maxsize = stride * 240;
|
||||||
b->datas[0].stride = stride;
|
b->datas[0].stride = stride;
|
||||||
}
|
}
|
||||||
data->n_buffers = MAX_BUFFERS;
|
data->n_buffers = MAX_BUFFERS;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue