mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
unify code that fixes up buffering metrics
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/glitch-free@2302 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
af03dd4e4f
commit
ed0af46e69
1 changed files with 188 additions and 157 deletions
|
|
@ -470,11 +470,65 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latency, uint32_t *maxlength, uint32_t *fragsize) {
|
||||
pa_assert(s);
|
||||
pa_assert(maxlength);
|
||||
pa_assert(fragsize);
|
||||
|
||||
if (*maxlength <= 0 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
|
||||
*maxlength = MAX_MEMBLOCKQ_LENGTH;
|
||||
|
||||
if (*fragsize <= 0)
|
||||
*fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec);
|
||||
|
||||
if (adjust_latency) {
|
||||
pa_usec_t fragsize_usec;
|
||||
|
||||
/* So, the user asked us to adjust the latency according to
|
||||
* the what the source can provide. Half the latency will be
|
||||
* spent on the hw buffer, half of it in the async buffer
|
||||
* queue we maintain for each client. */
|
||||
|
||||
fragsize_usec = pa_bytes_to_usec(*fragsize, &s->source_output->sample_spec);
|
||||
|
||||
s->source_latency = pa_source_output_set_requested_latency(s->source_output, fragsize_usec/2);
|
||||
|
||||
if (fragsize_usec >= s->source_latency*2)
|
||||
fragsize_usec -= s->source_latency;
|
||||
else
|
||||
fragsize_usec = s->source_latency;
|
||||
|
||||
*fragsize = pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec);
|
||||
}
|
||||
}
|
||||
|
||||
static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, uint32_t *fragsize) {
|
||||
size_t base;
|
||||
|
||||
pa_assert(s);
|
||||
pa_assert(maxlength);
|
||||
pa_assert(fragsize);
|
||||
|
||||
*maxlength = pa_memblockq_get_maxlength(s->memblockq);
|
||||
|
||||
base = pa_frame_size(&s->source_output->sample_spec);
|
||||
|
||||
s->fragment_size = (*fragsize/base)*base;
|
||||
if (s->fragment_size <= 0)
|
||||
s->fragment_size = base;
|
||||
|
||||
if (s->fragment_size > *maxlength)
|
||||
s->fragment_size = *maxlength;
|
||||
|
||||
*fragsize = s->fragment_size;
|
||||
}
|
||||
|
||||
static record_stream* record_stream_new(
|
||||
connection *c,
|
||||
pa_source *source,
|
||||
pa_sample_spec *ss,
|
||||
pa_channel_map *map,
|
||||
pa_bool_t peak_detect,
|
||||
uint32_t *maxlength,
|
||||
uint32_t *fragsize,
|
||||
pa_source_output_flags_t flags,
|
||||
|
|
@ -501,6 +555,8 @@ static record_stream* record_stream_new(
|
|||
data.source = source;
|
||||
pa_source_output_new_data_set_sample_spec(&data, ss);
|
||||
pa_source_output_new_data_set_channel_map(&data, map);
|
||||
if (peak_detect)
|
||||
data.resample_method = PA_RESAMPLER_PEAKS;
|
||||
|
||||
source_output = pa_source_output_new(c->protocol->core, &data, flags);
|
||||
|
||||
|
|
@ -522,30 +578,7 @@ static record_stream* record_stream_new(
|
|||
s->source_output->suspend = source_output_suspend_cb;
|
||||
s->source_output->userdata = s;
|
||||
|
||||
if (*maxlength <= 0 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
|
||||
*maxlength = MAX_MEMBLOCKQ_LENGTH;
|
||||
if (*fragsize <= 0)
|
||||
*fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &source_output->sample_spec);
|
||||
|
||||
if (adjust_latency) {
|
||||
pa_usec_t fragsize_usec;
|
||||
|
||||
/* So, the user asked us to adjust the latency according to
|
||||
* the what the source can provide. Half the latency will be
|
||||
* spent on the hw buffer, half of it in the async buffer
|
||||
* queue we maintain for each client. */
|
||||
|
||||
fragsize_usec = pa_bytes_to_usec(*fragsize, &source_output->sample_spec);
|
||||
|
||||
s->source_latency = pa_source_output_set_requested_latency(source_output, fragsize_usec/2);
|
||||
|
||||
if (fragsize_usec >= s->source_latency*2)
|
||||
fragsize_usec -= s->source_latency;
|
||||
else
|
||||
fragsize_usec = s->source_latency;
|
||||
|
||||
*fragsize = pa_usec_to_bytes(fragsize_usec, &source_output->sample_spec);
|
||||
}
|
||||
fix_record_buffer_attr_pre(s, adjust_latency, maxlength, fragsize);
|
||||
|
||||
s->memblockq = pa_memblockq_new(
|
||||
0,
|
||||
|
|
@ -557,16 +590,7 @@ static record_stream* record_stream_new(
|
|||
0,
|
||||
NULL);
|
||||
|
||||
*maxlength = pa_memblockq_get_maxlength(s->memblockq);
|
||||
|
||||
s->fragment_size = (*fragsize/base)*base;
|
||||
if (s->fragment_size <= 0)
|
||||
s->fragment_size = base;
|
||||
|
||||
if (s->fragment_size > *maxlength)
|
||||
s->fragment_size = *maxlength;
|
||||
|
||||
*fragsize = s->fragment_size;
|
||||
fix_record_buffer_attr_post(s, maxlength, fragsize);
|
||||
|
||||
*ss = s->source_output->sample_spec;
|
||||
*map = s->source_output->channel_map;
|
||||
|
|
@ -674,6 +698,114 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_latency, uint32_t *maxlength, uint32_t *tlength, uint32_t* prebuf, uint32_t* minreq) {
|
||||
size_t frame_size;
|
||||
pa_usec_t tlength_usec, minreq_usec, sink_usec;
|
||||
|
||||
pa_assert(s);
|
||||
pa_assert(maxlength);
|
||||
pa_assert(tlength);
|
||||
pa_assert(prebuf);
|
||||
pa_assert(minreq);
|
||||
|
||||
if (*maxlength <= 0 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
|
||||
*maxlength = MAX_MEMBLOCKQ_LENGTH;
|
||||
if (*tlength <= 0)
|
||||
*tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
|
||||
if (*minreq <= 0)
|
||||
*minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
|
||||
|
||||
frame_size = pa_frame_size(&s->sink_input->sample_spec);
|
||||
if (*minreq <= 0)
|
||||
*minreq = frame_size;
|
||||
if (*tlength < *minreq+frame_size)
|
||||
*tlength = *minreq+frame_size;
|
||||
|
||||
tlength_usec = pa_bytes_to_usec(*tlength, &s->sink_input->sample_spec);
|
||||
minreq_usec = pa_bytes_to_usec(*minreq, &s->sink_input->sample_spec);
|
||||
|
||||
pa_log_info("Requested tlength=%0.2f ms, minreq=%0.2f ms",
|
||||
(double) tlength_usec / PA_USEC_PER_MSEC,
|
||||
(double) minreq_usec / PA_USEC_PER_MSEC);
|
||||
|
||||
if (adjust_latency) {
|
||||
|
||||
/* So, the user asked us to adjust the latency of the stream
|
||||
* buffer according to the what the sink can provide. The
|
||||
* tlength passed in shall be the overall latency. Roughly
|
||||
* half the latency will be spent on the hw buffer, the other
|
||||
* half of it in the async buffer queue we maintain for each
|
||||
* client. In between we'll have a safety space of size
|
||||
* 2*minreq. Why the 2*minreq? When the hw buffer is completey
|
||||
* empty and needs to be filled, then our buffer must have
|
||||
* enough data to fulfill this request immediatly and thus
|
||||
* have at least the same tlength as the size of the hw
|
||||
* buffer. It additionally needs space for 2 times minreq
|
||||
* because if the buffer ran empty and a partial fillup
|
||||
* happens immediately on the next iteration we need to be
|
||||
* able to fulfill it and give the application also minreq
|
||||
* time to fill it up again for the next request Makes 2 times
|
||||
* minreq in plus.. */
|
||||
|
||||
if (tlength_usec > minreq_usec*2)
|
||||
sink_usec = (tlength_usec - minreq_usec*2)/2;
|
||||
else
|
||||
sink_usec = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Ok, the user didn't ask us to adjust the latency, but we
|
||||
* still need to make sure that the parameters from the user
|
||||
* do make sense. */
|
||||
|
||||
if (tlength_usec > minreq_usec*2)
|
||||
sink_usec = (tlength_usec - minreq_usec*2);
|
||||
else
|
||||
sink_usec = 0;
|
||||
}
|
||||
|
||||
s->sink_latency = pa_sink_input_set_requested_latency(s->sink_input, sink_usec);
|
||||
|
||||
if (adjust_latency) {
|
||||
/* Ok, we didn't necessarily get what we were asking for, so
|
||||
* let's subtract from what we asked for for the remaining
|
||||
* buffer space */
|
||||
|
||||
if (tlength_usec >= s->sink_latency)
|
||||
tlength_usec -= s->sink_latency;
|
||||
}
|
||||
|
||||
if (tlength_usec < s->sink_latency + 2*minreq_usec)
|
||||
tlength_usec = s->sink_latency + 2*minreq_usec;
|
||||
|
||||
*tlength = pa_usec_to_bytes(tlength_usec, &s->sink_input->sample_spec);
|
||||
*minreq = pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec);
|
||||
|
||||
if (*minreq <= 0) {
|
||||
*minreq += frame_size;
|
||||
*tlength += frame_size*2;
|
||||
}
|
||||
|
||||
if (*tlength <= *minreq)
|
||||
*tlength = *minreq*2 + frame_size;
|
||||
|
||||
if (*prebuf <= 0)
|
||||
*prebuf = *tlength;
|
||||
}
|
||||
|
||||
static void fix_playback_buffer_attr_post(playback_stream *s, uint32_t *maxlength, uint32_t *tlength, uint32_t* prebuf, uint32_t* minreq) {
|
||||
pa_assert(s);
|
||||
pa_assert(maxlength);
|
||||
pa_assert(tlength);
|
||||
pa_assert(prebuf);
|
||||
pa_assert(minreq);
|
||||
|
||||
*maxlength = (uint32_t) pa_memblockq_get_maxlength(s->memblockq);
|
||||
*tlength = (uint32_t) pa_memblockq_get_tlength(s->memblockq);
|
||||
*prebuf = (uint32_t) pa_memblockq_get_prebuf(s->memblockq);
|
||||
*minreq = (uint32_t) pa_memblockq_get_minreq(s->memblockq);
|
||||
}
|
||||
|
||||
static playback_stream* playback_stream_new(
|
||||
connection *c,
|
||||
pa_sink *sink,
|
||||
|
|
@ -697,8 +829,6 @@ static playback_stream* playback_stream_new(
|
|||
uint32_t idx;
|
||||
int64_t start_index;
|
||||
pa_sink_input_new_data data;
|
||||
pa_usec_t tlength_usec, minreq_usec, sink_usec;
|
||||
size_t frame_size;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(ss);
|
||||
|
|
@ -769,90 +899,7 @@ static playback_stream* playback_stream_new(
|
|||
|
||||
start_index = ssync ? pa_memblockq_get_read_index(ssync->memblockq) : 0;
|
||||
|
||||
if (*maxlength <= 0 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
|
||||
*maxlength = MAX_MEMBLOCKQ_LENGTH;
|
||||
if (*tlength <= 0)
|
||||
*tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &sink_input->sample_spec);
|
||||
if (*minreq <= 0)
|
||||
*minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &sink_input->sample_spec);
|
||||
|
||||
frame_size = pa_frame_size(&sink_input->sample_spec);
|
||||
if (*minreq <= 0)
|
||||
*minreq = frame_size;
|
||||
if (*tlength < *minreq+frame_size)
|
||||
*tlength = *minreq+frame_size;
|
||||
|
||||
tlength_usec = pa_bytes_to_usec(*tlength, &sink_input->sample_spec);
|
||||
minreq_usec = pa_bytes_to_usec(*minreq, &sink_input->sample_spec);
|
||||
|
||||
pa_log_info("Requested tlength=%0.2f ms, minreq=%0.2f ms",
|
||||
(double) tlength_usec / PA_USEC_PER_MSEC,
|
||||
(double) minreq_usec / PA_USEC_PER_MSEC);
|
||||
|
||||
if (adjust_latency) {
|
||||
|
||||
/* So, the user asked us to adjust the latency of the stream
|
||||
* buffer according to the what the sink can provide. The
|
||||
* tlength passed in shall be the overall latency. Roughly
|
||||
* half the latency will be spent on the hw buffer, the other
|
||||
* half of it in the async buffer queue we maintain for each
|
||||
* client. In between we'll have a safety space of size
|
||||
* 2*minreq. Why the 2*minreq? When the hw buffer is completey
|
||||
* empty and needs to be filled, then our buffer must have
|
||||
* enough data to fulfill this request immediatly and thus
|
||||
* have at least the same tlength as the size of the hw
|
||||
* buffer. It additionally needs space for 2 times minreq
|
||||
* because if the buffer ran empty and a partial fillup
|
||||
* happens immediately on the next iteration we need to be
|
||||
* able to fulfill it and give the application also minreq
|
||||
* time to fill it up again for the next request Makes 2 times
|
||||
* minreq in plus.. */
|
||||
|
||||
if (tlength_usec > minreq_usec*2)
|
||||
sink_usec = (tlength_usec - minreq_usec*2)/2;
|
||||
else
|
||||
sink_usec = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Ok, the user didn't ask us to adjust the latency, but we
|
||||
* still need to make sure that the parameters from the user
|
||||
* do make sense. */
|
||||
|
||||
if (tlength_usec > minreq_usec*2)
|
||||
sink_usec = (tlength_usec - minreq_usec*2);
|
||||
else
|
||||
sink_usec = 0;
|
||||
}
|
||||
|
||||
s->sink_latency = pa_sink_input_set_requested_latency(sink_input, sink_usec);
|
||||
|
||||
if (adjust_latency) {
|
||||
/* Ok, we didn't necessarily get what we were asking for, so
|
||||
* let's subtract from what we asked for for the remaining
|
||||
* buffer space */
|
||||
|
||||
if (tlength_usec >= s->sink_latency)
|
||||
tlength_usec -= s->sink_latency;
|
||||
}
|
||||
|
||||
if (tlength_usec < s->sink_latency + 2*minreq_usec)
|
||||
tlength_usec = s->sink_latency + 2*minreq_usec;
|
||||
|
||||
*tlength = pa_usec_to_bytes(tlength_usec, &sink_input->sample_spec);
|
||||
*minreq = pa_usec_to_bytes(minreq_usec, &sink_input->sample_spec);
|
||||
|
||||
if (*minreq <= 0) {
|
||||
*minreq += frame_size;
|
||||
*tlength += frame_size*2;
|
||||
}
|
||||
|
||||
if (*tlength <= *minreq)
|
||||
*tlength = *minreq*2 + frame_size;
|
||||
|
||||
if (*prebuf <= 0)
|
||||
*prebuf = *tlength;
|
||||
|
||||
fix_playback_buffer_attr_pre(s, adjust_latency, maxlength, tlength, prebuf, minreq);
|
||||
pa_sink_input_get_silence(sink_input, &silence);
|
||||
|
||||
s->memblockq = pa_memblockq_new(
|
||||
|
|
@ -866,17 +913,14 @@ static playback_stream* playback_stream_new(
|
|||
&silence);
|
||||
|
||||
pa_memblock_unref(silence.memblock);
|
||||
fix_playback_buffer_attr_post(s, maxlength, tlength, prebuf, minreq);
|
||||
|
||||
*maxlength = (uint32_t) pa_memblockq_get_maxlength(s->memblockq);
|
||||
*tlength = (uint32_t) pa_memblockq_get_tlength(s->memblockq);
|
||||
*prebuf = (uint32_t) pa_memblockq_get_prebuf(s->memblockq);
|
||||
*minreq = (uint32_t) pa_memblockq_get_minreq(s->memblockq);
|
||||
*missing = (uint32_t) pa_memblockq_pop_missing(s->memblockq);
|
||||
|
||||
*ss = s->sink_input->sample_spec;
|
||||
*map = s->sink_input->channel_map;
|
||||
|
||||
s->minreq = pa_memblockq_get_minreq(s->memblockq);
|
||||
s->minreq = *minreq;
|
||||
pa_atomic_store(&s->missing, 0);
|
||||
s->drain_request = FALSE;
|
||||
|
||||
|
|
@ -1671,7 +1715,8 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
|
|||
fix_channels = FALSE,
|
||||
no_move = FALSE,
|
||||
variable_rate = FALSE,
|
||||
adjust_latency = FALSE;
|
||||
adjust_latency = FALSE,
|
||||
peak_detect = FALSE;
|
||||
pa_source_output_flags_t flags = 0;
|
||||
pa_proplist *p;
|
||||
|
||||
|
|
@ -1720,7 +1765,8 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
|
|||
|
||||
if (c->version >= 13) {
|
||||
|
||||
if (pa_tagstruct_get_boolean(t, &adjust_latency) < 0 ||
|
||||
if (pa_tagstruct_get_boolean(t, &peak_detect) < 0 ||
|
||||
pa_tagstruct_get_boolean(t, &adjust_latency) < 0 ||
|
||||
pa_tagstruct_get_proplist(t, p) < 0) {
|
||||
protocol_error(c);
|
||||
pa_proplist_free(p);
|
||||
|
|
@ -1761,7 +1807,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
|
|||
(no_move ? PA_SOURCE_OUTPUT_DONT_MOVE : 0) |
|
||||
(variable_rate ? PA_SOURCE_OUTPUT_VARIABLE_RATE : 0);
|
||||
|
||||
s = record_stream_new(c, source, &ss, &map, &maxlength, &fragment_size, flags, p, adjust_latency);
|
||||
s = record_stream_new(c, source, &ss, &map, peak_detect, &maxlength, &fragment_size, flags, p, adjust_latency);
|
||||
pa_proplist_free(p);
|
||||
|
||||
CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID);
|
||||
|
|
@ -2940,6 +2986,7 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
|
|||
|
||||
if (command == PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR) {
|
||||
playback_stream *s;
|
||||
pa_bool_t adjust_latency = FALSE;
|
||||
|
||||
s = pa_idxset_get_by_index(c->output_streams, idx);
|
||||
CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
|
||||
|
|
@ -2952,34 +2999,28 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
|
|||
PA_TAG_U32, &prebuf,
|
||||
PA_TAG_U32, &minreq,
|
||||
PA_TAG_INVALID) < 0 ||
|
||||
(c->version >= 13 && pa_tagstruct_get_boolean(t, &adjust_latency) < 0) ||
|
||||
!pa_tagstruct_eof(t)) {
|
||||
protocol_error(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxlength <= 0 || maxlength > MAX_MEMBLOCKQ_LENGTH)
|
||||
maxlength = MAX_MEMBLOCKQ_LENGTH;
|
||||
if (tlength <= 0)
|
||||
tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*1000, &s->sink_input->sample_spec);
|
||||
if (minreq <= 0)
|
||||
minreq = (tlength*9)/10;
|
||||
if (prebuf <= 0)
|
||||
prebuf = tlength;
|
||||
|
||||
fix_playback_buffer_attr_pre(s, adjust_latency, &maxlength, &tlength, &prebuf, &minreq);
|
||||
pa_memblockq_set_maxlength(s->memblockq, maxlength);
|
||||
pa_memblockq_set_tlength(s->memblockq, tlength);
|
||||
pa_memblockq_set_prebuf(s->memblockq, prebuf);
|
||||
pa_memblockq_set_minreq(s->memblockq, minreq);
|
||||
fix_playback_buffer_attr_post(s, &maxlength, &tlength, &prebuf, &minreq);
|
||||
|
||||
reply = reply_new(tag);
|
||||
pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq));
|
||||
pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_tlength(s->memblockq));
|
||||
pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_prebuf(s->memblockq));
|
||||
pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_minreq(s->memblockq));
|
||||
pa_tagstruct_putu32(reply, maxlength);
|
||||
pa_tagstruct_putu32(reply, tlength);
|
||||
pa_tagstruct_putu32(reply, prebuf);
|
||||
pa_tagstruct_putu32(reply, minreq);
|
||||
|
||||
} else {
|
||||
record_stream *s;
|
||||
size_t base;
|
||||
pa_bool_t adjust_latency = FALSE;
|
||||
pa_assert(command == PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR);
|
||||
|
||||
s = pa_idxset_get_by_index(c->record_streams, idx);
|
||||
|
|
@ -2990,29 +3031,19 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
|
|||
PA_TAG_U32, &maxlength,
|
||||
PA_TAG_U32, &fragsize,
|
||||
PA_TAG_INVALID) < 0 ||
|
||||
(c->version >= 13 && pa_tagstruct_get_boolean(t, &adjust_latency) < 0) ||
|
||||
!pa_tagstruct_eof(t)) {
|
||||
protocol_error(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxlength <= 0 || maxlength > MAX_MEMBLOCKQ_LENGTH)
|
||||
maxlength = MAX_MEMBLOCKQ_LENGTH;
|
||||
if (fragsize <= 0)
|
||||
fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &s->source_output->sample_spec);
|
||||
|
||||
fix_record_buffer_attr_pre(s, adjust_latency, &maxlength, &fragsize);
|
||||
pa_memblockq_set_maxlength(s->memblockq, maxlength);
|
||||
|
||||
base = pa_frame_size(&s->source_output->sample_spec);
|
||||
s->fragment_size = (fragsize/base)*base;
|
||||
if (s->fragment_size <= 0)
|
||||
s->fragment_size = base;
|
||||
|
||||
if (s->fragment_size > pa_memblockq_get_maxlength(s->memblockq))
|
||||
s->fragment_size = pa_memblockq_get_maxlength(s->memblockq);
|
||||
fix_record_buffer_attr_post(s, &maxlength, &fragsize);
|
||||
|
||||
reply = reply_new(tag);
|
||||
pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq));
|
||||
pa_tagstruct_putu32(reply, s->fragment_size);
|
||||
pa_tagstruct_putu32(reply, maxlength);
|
||||
pa_tagstruct_putu32(reply, fragsize);
|
||||
}
|
||||
|
||||
pa_pstream_send_tagstruct(c->pstream, reply);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue