mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
pinossrc: handle latency and liveness
Use NULL filter when the port format enumeration returns nothing. Send clock update even when there is no clock. Don't send data to a port when the node is not streaming Add latency support to the clock update Copy the unset_mask when copying the formats
This commit is contained in:
parent
021eccb8ad
commit
b75d9786d4
13 changed files with 147 additions and 77 deletions
|
|
@ -61,6 +61,7 @@ typedef struct {
|
|||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_TIME (1 << 0)
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_SCALE (1 << 1)
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_STATE (1 << 2)
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_LATENCY (1 << 3)
|
||||
uint32_t change_mask;
|
||||
int32_t rate;
|
||||
int64_t ticks;
|
||||
|
|
@ -68,6 +69,9 @@ typedef struct {
|
|||
int64_t offset;
|
||||
int32_t scale;
|
||||
SpaClockState state;
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_FLAG_LIVE (1 << 0)
|
||||
uint32_t flags;
|
||||
int64_t latency;
|
||||
} SpaNodeCommandClockUpdate;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -25,15 +25,6 @@
|
|||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
static const SpaAudioInfoRaw default_raw_info = {
|
||||
SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FLAG_NONE,
|
||||
SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
44100,
|
||||
2,
|
||||
0
|
||||
};
|
||||
|
||||
static const uint32_t format_values[] = {
|
||||
SPA_AUDIO_FORMAT_S8,
|
||||
SPA_AUDIO_FORMAT_U8,
|
||||
|
|
@ -228,6 +219,14 @@ spa_format_audio_init (SpaMediaType type,
|
|||
{ SPA_PROP_ID_AUDIO_CHANNELS, offsetof (SpaFormatAudio, info.raw.channels), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, offsetof (SpaFormatAudio, info.raw.channel_mask), },
|
||||
};
|
||||
static const SpaAudioInfoRaw default_raw_info = {
|
||||
SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FLAG_NONE,
|
||||
SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
44100,
|
||||
2,
|
||||
0
|
||||
};
|
||||
prop_info = raw_format_prop_info;
|
||||
n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
|
||||
format->format.props.unset_mask = (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5);
|
||||
|
|
@ -295,7 +294,8 @@ spa_format_audio_parse (const SpaFormat *format,
|
|||
if (props->prop_info[idx].type != SPA_PROP_TYPE_POINTER)
|
||||
goto fallback;
|
||||
|
||||
memcpy (&aformat->info, value.value, SPA_MIN (value.size, sizeof (SpaAudioInfoRaw)));
|
||||
memcpy (&aformat->info, value.value, SPA_MIN (value.size, sizeof (aformat->info)));
|
||||
aformat->format.props.unset_mask = props->unset_mask;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
|
|
|
|||
|
|
@ -1366,7 +1366,7 @@ spa_control_read (SpaControl *control,
|
|||
break;
|
||||
}
|
||||
if (len != hdr->length)
|
||||
return SPA_RESULT_ERROR;
|
||||
goto wrong_length;
|
||||
}
|
||||
|
||||
/* handle control messages */
|
||||
|
|
@ -1389,6 +1389,11 @@ recv_error:
|
|||
fprintf (stderr, "could not recvmsg: %s\n", strerror (errno));
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
wrong_length:
|
||||
{
|
||||
fprintf (stderr, "wrong header length %zd != %u\n", len, hdr->length);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@
|
|||
#include "spa/memory.h"
|
||||
#include "memfd-wrappers.h"
|
||||
|
||||
#undef USE_MEMFD
|
||||
|
||||
#if 0
|
||||
#define SPA_DEBUG_MEMORY(format,args...) fprintf(stderr,format,##args)
|
||||
#else
|
||||
#define SPA_DEBUG_MEMORY(format,args...)
|
||||
#endif
|
||||
|
||||
#define MAX_POOLS 16
|
||||
#define MAX_MEMORIES 1024
|
||||
|
||||
|
|
@ -121,6 +129,8 @@ spa_memory_alloc (uint32_t pool_id)
|
|||
mem->mem.pool_id = pool_id;
|
||||
mem->mem.id = id;
|
||||
|
||||
SPA_DEBUG_MEMORY ("mem %p: alloc\n", mem);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +159,9 @@ spa_memory_alloc_with_fd (uint32_t pool_id, void *data, size_t size)
|
|||
if (!(mem = spa_memory_alloc (pool_id)))
|
||||
return NULL;
|
||||
|
||||
#if 1
|
||||
#ifdef USE_MEMFD
|
||||
mem->fd = memfd_create ("spa-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
#else
|
||||
{
|
||||
char filename[] = "/dev/shm/spa-tmpfile.XXXXXX";
|
||||
mem->fd = mkostemp (filename, O_CLOEXEC);
|
||||
|
|
@ -159,8 +171,6 @@ spa_memory_alloc_with_fd (uint32_t pool_id, void *data, size_t size)
|
|||
}
|
||||
unlink (filename);
|
||||
}
|
||||
#else
|
||||
mem->fd = memfd_create ("spa-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
|
|
@ -176,7 +186,7 @@ spa_memory_alloc_with_fd (uint32_t pool_id, void *data, size_t size)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
#ifdef USE_MEMFD
|
||||
{
|
||||
unsigned int seals;
|
||||
|
||||
|
|
@ -231,6 +241,7 @@ spa_memory_import (SpaMemoryRef *ref)
|
|||
} else {
|
||||
mem->refcount++;
|
||||
}
|
||||
SPA_DEBUG_MEMORY ("mem %p: import %u:%u\n", mem, pool_id, id);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
|
@ -253,6 +264,8 @@ spa_memory_free (SpaMemory *mem)
|
|||
{
|
||||
SpaMemoryPool *pool;
|
||||
|
||||
SPA_DEBUG_MEMORY ("mem %p: free\n", mem);
|
||||
|
||||
if (mem->fd != -1) {
|
||||
if (mem->ptr)
|
||||
munmap (mem->ptr, mem->size);
|
||||
|
|
|
|||
|
|
@ -625,7 +625,8 @@ spa_format_video_parse (const SpaFormat *format,
|
|||
if (props->prop_info[idx].type != SPA_PROP_TYPE_POINTER)
|
||||
goto fallback;
|
||||
|
||||
memcpy (&vformat->info, value.value, SPA_MIN (value.size, sizeof (SpaVideoInfoRaw)));
|
||||
memcpy (&vformat->info, value.value, SPA_MIN (value.size, sizeof (vformat->info)));
|
||||
vformat->format.props.unset_mask = props->unset_mask;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,11 +67,9 @@ struct _SpaAudioTestSrc {
|
|||
SpaFormatAudio query_format;
|
||||
SpaFormatAudio current_format;
|
||||
|
||||
bool have_buffers;
|
||||
SpaMemory *alloc_mem;
|
||||
ATSBuffer *alloc_buffers;
|
||||
|
||||
bool have_buffers;
|
||||
SpaBuffer **buffers;
|
||||
unsigned int n_buffers;
|
||||
|
||||
ATSBuffer *empty;
|
||||
|
|
@ -406,6 +404,20 @@ spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
clear_buffers (SpaAudioTestSrc *this)
|
||||
{
|
||||
if (this->have_buffers) {
|
||||
fprintf (stderr, "clear buffers");
|
||||
if (this->alloc_mem)
|
||||
spa_memory_unref (&this->alloc_mem->mem);
|
||||
this->alloc_mem = NULL;
|
||||
this->n_buffers = 0;
|
||||
this->have_buffers = false;
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiotestsrc_node_port_set_format (SpaNode *node,
|
||||
uint32_t port_id,
|
||||
|
|
@ -425,7 +437,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
|
|||
|
||||
if (format == NULL) {
|
||||
this->have_format = false;
|
||||
this->have_buffers = false;
|
||||
clear_buffers (this);
|
||||
} else {
|
||||
if ((res = spa_format_audio_parse (format, &this->current_format)) < 0)
|
||||
return res;
|
||||
|
|
@ -535,14 +547,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
|
|||
if (!this->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
if (this->have_buffers) {
|
||||
if (this->alloc_mem)
|
||||
spa_memory_unref (&this->alloc_mem->mem);
|
||||
this->alloc_mem = NULL;
|
||||
this->buffers = NULL;
|
||||
this->n_buffers = 0;
|
||||
this->have_buffers = false;
|
||||
}
|
||||
clear_buffers (this);
|
||||
if (buffers != NULL && n_buffers != 0) {
|
||||
unsigned int i;
|
||||
|
||||
|
|
@ -578,16 +583,16 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
|
|||
b->ptr = SPA_MEMBER (spa_memory_ensure_ptr (mem), d[0].mem.offset, void);
|
||||
b->size = d[0].mem.size;
|
||||
}
|
||||
this->buffers = buffers;
|
||||
this->n_buffers = n_buffers;
|
||||
this->have_buffers = true;
|
||||
this->empty = this->alloc_buffers;
|
||||
}
|
||||
|
||||
if (this->have_buffers)
|
||||
if (this->have_buffers) {
|
||||
update_state (this, SPA_NODE_STATE_PAUSED);
|
||||
else
|
||||
} else {
|
||||
update_state (this, SPA_NODE_STATE_READY);
|
||||
}
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -600,6 +605,22 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
|
|||
SpaBuffer **buffers,
|
||||
uint32_t *n_buffers)
|
||||
{
|
||||
SpaAudioTestSrc *this;
|
||||
|
||||
if (node == NULL || node->handle == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this = (SpaAudioTestSrc *) node->handle;
|
||||
|
||||
if (port_id != 0)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
if (!this->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
if (!this->have_buffers)
|
||||
return SPA_RESULT_NO_BUFFERS;
|
||||
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -862,12 +862,8 @@ v4l2_on_fd_events (SpaPollNotifyData *data)
|
|||
SpaNodeEvent event;
|
||||
SpaNodeEventHaveOutput ho;
|
||||
|
||||
if (data->fds[0].revents & POLLERR) {
|
||||
|
||||
if (data->fds[0].revents & POLLERR)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (mmap_read (this) < 0)
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue