mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
pulse-server: implement stream_buffer_attr
This commit is contained in:
parent
ce03fc7c15
commit
6543899fe6
1 changed files with 80 additions and 52 deletions
|
|
@ -444,55 +444,66 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
|
||||||
return latency / frame_size;
|
return latency / frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reply_create_playback_stream(struct stream *stream, struct pw_manager_object *peer)
|
static uint64_t set_playback_buffer_attr(struct stream *s, struct buffer_attr *attr)
|
||||||
{
|
{
|
||||||
struct client *client = stream->client;
|
struct spa_fraction lat;
|
||||||
struct pw_manager *manager = client->manager;
|
uint64_t lat_usec;
|
||||||
struct message *reply;
|
|
||||||
uint32_t missing, peer_index;
|
|
||||||
struct spa_dict_item items[5];
|
struct spa_dict_item items[5];
|
||||||
char latency[32];
|
char latency[32];
|
||||||
char attr_maxlength[32];
|
char attr_maxlength[32];
|
||||||
char attr_tlength[32];
|
char attr_tlength[32];
|
||||||
char attr_prebuf[32];
|
char attr_prebuf[32];
|
||||||
char attr_minreq[32];
|
char attr_minreq[32];
|
||||||
const char *peer_name;
|
|
||||||
struct spa_fraction lat;
|
|
||||||
uint64_t lat_usec;
|
|
||||||
|
|
||||||
lat.denom = stream->ss.rate;
|
lat.denom = s->ss.rate;
|
||||||
lat.num = fix_playback_buffer_attr(stream, &stream->attr);
|
lat.num = fix_playback_buffer_attr(s, attr);
|
||||||
|
|
||||||
stream->buffer = calloc(1, MAXLENGTH);
|
s->attr = *attr;
|
||||||
if (stream->buffer == NULL)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
if (lat.num * stream->min_quantum.denom / lat.denom < stream->min_quantum.num)
|
if (lat.num * s->min_quantum.denom / lat.denom < s->min_quantum.num)
|
||||||
lat.num = (stream->min_quantum.num * lat.denom +
|
lat.num = (s->min_quantum.num * lat.denom +
|
||||||
(stream->min_quantum.denom -1)) / stream->min_quantum.denom;
|
(s->min_quantum.denom -1)) / s->min_quantum.denom;
|
||||||
lat_usec = lat.num * SPA_USEC_PER_SEC / lat.denom;
|
lat_usec = lat.num * SPA_USEC_PER_SEC / lat.denom;
|
||||||
|
|
||||||
snprintf(latency, sizeof(latency), "%u/%u", lat.num, lat.denom);
|
snprintf(latency, sizeof(latency), "%u/%u", lat.num, lat.denom);
|
||||||
snprintf(attr_maxlength, sizeof(attr_maxlength), "%u", stream->attr.maxlength);
|
snprintf(attr_maxlength, sizeof(attr_maxlength), "%u", s->attr.maxlength);
|
||||||
snprintf(attr_tlength, sizeof(attr_tlength), "%u", stream->attr.tlength);
|
snprintf(attr_tlength, sizeof(attr_tlength), "%u", s->attr.tlength);
|
||||||
snprintf(attr_prebuf, sizeof(attr_prebuf), "%u", stream->attr.prebuf);
|
snprintf(attr_prebuf, sizeof(attr_prebuf), "%u", s->attr.prebuf);
|
||||||
snprintf(attr_minreq, sizeof(attr_minreq), "%u", stream->attr.minreq);
|
snprintf(attr_minreq, sizeof(attr_minreq), "%u", s->attr.minreq);
|
||||||
|
|
||||||
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
|
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
|
||||||
items[1] = SPA_DICT_ITEM_INIT("pulse.attr.maxlength", attr_maxlength);
|
items[1] = SPA_DICT_ITEM_INIT("pulse.attr.maxlength", attr_maxlength);
|
||||||
items[2] = SPA_DICT_ITEM_INIT("pulse.attr.tlength", attr_tlength);
|
items[2] = SPA_DICT_ITEM_INIT("pulse.attr.tlength", attr_tlength);
|
||||||
items[3] = SPA_DICT_ITEM_INIT("pulse.attr.prebuf", attr_prebuf);
|
items[3] = SPA_DICT_ITEM_INIT("pulse.attr.prebuf", attr_prebuf);
|
||||||
items[4] = SPA_DICT_ITEM_INIT("pulse.attr.minreq", attr_minreq);
|
items[4] = SPA_DICT_ITEM_INIT("pulse.attr.minreq", attr_minreq);
|
||||||
pw_stream_update_properties(stream->stream, &SPA_DICT_INIT(items, 5));
|
pw_stream_update_properties(s->stream, &SPA_DICT_INIT(items, 5));
|
||||||
|
|
||||||
if (stream->attr.prebuf > 0)
|
if (s->attr.prebuf > 0)
|
||||||
stream->in_prebuf = true;
|
s->in_prebuf = true;
|
||||||
|
|
||||||
|
return lat_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int reply_create_playback_stream(struct stream *stream, struct pw_manager_object *peer)
|
||||||
|
{
|
||||||
|
struct client *client = stream->client;
|
||||||
|
struct pw_manager *manager = client->manager;
|
||||||
|
struct message *reply;
|
||||||
|
uint32_t missing, peer_index;
|
||||||
|
const char *peer_name;
|
||||||
|
uint64_t lat_usec;
|
||||||
|
|
||||||
|
stream->buffer = calloc(1, MAXLENGTH);
|
||||||
|
if (stream->buffer == NULL)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
lat_usec = set_playback_buffer_attr(stream, &stream->attr);
|
||||||
|
|
||||||
missing = stream_pop_missing(stream);
|
missing = stream_pop_missing(stream);
|
||||||
stream->index = id_to_index(manager, stream->id);
|
stream->index = id_to_index(manager, stream->id);
|
||||||
|
|
||||||
pw_log_info("[%s] reply CREATE_PLAYBACK_STREAM tag:%u index:%u missing:%u latency:%s",
|
pw_log_info("[%s] reply CREATE_PLAYBACK_STREAM tag:%u index:%u missing:%u lat:%"PRIu64,
|
||||||
client->name, stream->create_tag, stream->index, missing, latency);
|
client->name, stream->create_tag, stream->index, missing, lat_usec);
|
||||||
|
|
||||||
reply = reply_new(client, stream->create_tag);
|
reply = reply_new(client, stream->create_tag);
|
||||||
message_put(reply,
|
message_put(reply,
|
||||||
|
|
@ -584,47 +595,56 @@ static uint32_t fix_record_buffer_attr(struct stream *s, struct buffer_attr *att
|
||||||
return latency / frame_size;
|
return latency / frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t set_record_buffer_attr(struct stream *s, struct buffer_attr *attr)
|
||||||
|
{
|
||||||
|
struct spa_dict_item items[3];
|
||||||
|
char latency[32];
|
||||||
|
char attr_maxlength[32];
|
||||||
|
char attr_fragsize[32];
|
||||||
|
struct spa_fraction lat;
|
||||||
|
uint64_t lat_usec;
|
||||||
|
|
||||||
|
lat.denom = s->ss.rate;
|
||||||
|
lat.num = fix_record_buffer_attr(s, &s->attr);
|
||||||
|
|
||||||
|
if (lat.num * s->min_quantum.denom / lat.denom < s->min_quantum.num)
|
||||||
|
lat.num = (s->min_quantum.num * lat.denom +
|
||||||
|
(s->min_quantum.denom -1)) / s->min_quantum.denom;
|
||||||
|
lat_usec = lat.num * SPA_USEC_PER_SEC / lat.denom;
|
||||||
|
|
||||||
|
snprintf(latency, sizeof(latency), "%u/%u", lat.num, lat.denom);
|
||||||
|
|
||||||
|
snprintf(attr_maxlength, sizeof(attr_maxlength), "%u", s->attr.maxlength);
|
||||||
|
snprintf(attr_fragsize, sizeof(attr_fragsize), "%u", s->attr.fragsize);
|
||||||
|
|
||||||
|
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
|
||||||
|
items[1] = SPA_DICT_ITEM_INIT("pulse.attr.maxlength", attr_maxlength);
|
||||||
|
items[2] = SPA_DICT_ITEM_INIT("pulse.attr.fragsize", attr_fragsize);
|
||||||
|
pw_stream_update_properties(s->stream, &SPA_DICT_INIT(items, 3));
|
||||||
|
|
||||||
|
return lat_usec;
|
||||||
|
}
|
||||||
|
|
||||||
static int reply_create_record_stream(struct stream *stream, struct pw_manager_object *peer)
|
static int reply_create_record_stream(struct stream *stream, struct pw_manager_object *peer)
|
||||||
{
|
{
|
||||||
struct client *client = stream->client;
|
struct client *client = stream->client;
|
||||||
struct pw_manager *manager = client->manager;
|
struct pw_manager *manager = client->manager;
|
||||||
|
char *tmp;
|
||||||
struct message *reply;
|
struct message *reply;
|
||||||
struct spa_dict_item items[3];
|
|
||||||
char latency[32], *tmp;
|
|
||||||
char attr_maxlength[32];
|
|
||||||
char attr_fragsize[32];
|
|
||||||
const char *peer_name, *name;
|
const char *peer_name, *name;
|
||||||
uint32_t peer_index;
|
uint32_t peer_index;
|
||||||
struct spa_fraction lat;
|
|
||||||
uint64_t lat_usec;
|
uint64_t lat_usec;
|
||||||
|
|
||||||
lat.denom = stream->ss.rate;
|
|
||||||
lat.num = fix_record_buffer_attr(stream, &stream->attr);
|
|
||||||
|
|
||||||
stream->buffer = calloc(1, MAXLENGTH);
|
stream->buffer = calloc(1, MAXLENGTH);
|
||||||
if (stream->buffer == NULL)
|
if (stream->buffer == NULL)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (lat.num * stream->min_quantum.denom / lat.denom < stream->min_quantum.num)
|
lat_usec = set_record_buffer_attr(stream, &stream->attr);
|
||||||
lat.num = (stream->min_quantum.num * lat.denom +
|
|
||||||
(stream->min_quantum.denom -1)) / stream->min_quantum.denom;
|
|
||||||
lat_usec = lat.num * SPA_USEC_PER_SEC / lat.denom;
|
|
||||||
|
|
||||||
snprintf(latency, sizeof(latency), "%u/%u", lat.num, lat.denom);
|
|
||||||
|
|
||||||
snprintf(attr_maxlength, sizeof(attr_maxlength), "%u", stream->attr.maxlength);
|
|
||||||
snprintf(attr_fragsize, sizeof(attr_fragsize), "%u", stream->attr.fragsize);
|
|
||||||
|
|
||||||
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
|
|
||||||
items[1] = SPA_DICT_ITEM_INIT("pulse.attr.maxlength", attr_maxlength);
|
|
||||||
items[2] = SPA_DICT_ITEM_INIT("pulse.attr.fragsize", attr_fragsize);
|
|
||||||
pw_stream_update_properties(stream->stream,
|
|
||||||
&SPA_DICT_INIT(items, 3));
|
|
||||||
|
|
||||||
stream->index = id_to_index(manager, stream->id);
|
stream->index = id_to_index(manager, stream->id);
|
||||||
|
|
||||||
pw_log_info("[%s] reply CREATE_RECORD_STREAM tag:%u index:%u latency:%s",
|
pw_log_info("[%s] reply CREATE_RECORD_STREAM tag:%u index:%u latency:%"PRIu64,
|
||||||
client->name, stream->create_tag, stream->index, latency);
|
client->name, stream->create_tag, stream->index, lat_usec);
|
||||||
|
|
||||||
reply = reply_new(client, stream->create_tag);
|
reply = reply_new(client, stream->create_tag);
|
||||||
message_put(reply,
|
message_put(reply,
|
||||||
|
|
@ -4299,6 +4319,7 @@ static int do_set_stream_buffer_attr(struct client *client, uint32_t command, ui
|
||||||
struct message *reply;
|
struct message *reply;
|
||||||
struct buffer_attr attr;
|
struct buffer_attr attr;
|
||||||
bool adjust_latency = false, early_requests = false;
|
bool adjust_latency = false, early_requests = false;
|
||||||
|
uint64_t lat_usec;
|
||||||
|
|
||||||
if (message_get(m,
|
if (message_get(m,
|
||||||
TAG_U32, &channel,
|
TAG_U32, &channel,
|
||||||
|
|
@ -4348,7 +4369,12 @@ static int do_set_stream_buffer_attr(struct client *client, uint32_t command, ui
|
||||||
|
|
||||||
reply = reply_new(client, tag);
|
reply = reply_new(client, tag);
|
||||||
|
|
||||||
|
stream->adjust_latency = adjust_latency;
|
||||||
|
stream->early_requests = early_requests;
|
||||||
|
|
||||||
if (command == COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR) {
|
if (command == COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR) {
|
||||||
|
lat_usec = set_playback_buffer_attr(stream, &attr);
|
||||||
|
|
||||||
message_put(reply,
|
message_put(reply,
|
||||||
TAG_U32, stream->attr.maxlength,
|
TAG_U32, stream->attr.maxlength,
|
||||||
TAG_U32, stream->attr.tlength,
|
TAG_U32, stream->attr.tlength,
|
||||||
|
|
@ -4357,17 +4383,19 @@ static int do_set_stream_buffer_attr(struct client *client, uint32_t command, ui
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
if (client->version >= 13) {
|
if (client->version >= 13) {
|
||||||
message_put(reply,
|
message_put(reply,
|
||||||
TAG_USEC, 0LL, /* configured_sink_latency */
|
TAG_USEC, lat_usec, /* configured_sink_latency */
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
lat_usec = set_record_buffer_attr(stream, &attr);
|
||||||
|
|
||||||
message_put(reply,
|
message_put(reply,
|
||||||
TAG_U32, stream->attr.maxlength,
|
TAG_U32, stream->attr.maxlength,
|
||||||
TAG_U32, stream->attr.fragsize,
|
TAG_U32, stream->attr.fragsize,
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
if (client->version >= 13) {
|
if (client->version >= 13) {
|
||||||
message_put(reply,
|
message_put(reply,
|
||||||
TAG_USEC, 0LL, /* configured_source_latency */
|
TAG_USEC, lat_usec, /* configured_source_latency */
|
||||||
TAG_INVALID);
|
TAG_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue