mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
add new dont_rewind_render flag to allow quick starts of newly created streams
This commit is contained in:
parent
06de6393d1
commit
75119e91cd
12 changed files with 32 additions and 22 deletions
|
|
@ -504,7 +504,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
|
|||
* we are heard right-away. */
|
||||
if (PA_SINK_INPUT_IS_LINKED(state) &&
|
||||
i->thread_info.state == PA_SINK_INPUT_INIT)
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/* Called from thread context */
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ static void sink_request_rewind(pa_sink *s) {
|
|||
pa_assert_se(u = s->userdata);
|
||||
|
||||
/* Just hand this one over to the master sink */
|
||||
pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes + pa_memblockq_get_length(u->memblockq), TRUE, FALSE);
|
||||
pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes + pa_memblockq_get_length(u->memblockq), TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Called from I/O thread context */
|
||||
|
|
@ -355,7 +355,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
|
|||
if (PA_SINK_INPUT_IS_LINKED(state) &&
|
||||
i->thread_info.state == PA_SINK_INPUT_INIT) {
|
||||
pa_log_debug("Requesting rewind due to state change.");
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ static void sink_request_rewind(pa_sink *s) {
|
|||
pa_sink_assert_ref(s);
|
||||
pa_assert_se(u = s->userdata);
|
||||
|
||||
pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes, TRUE, FALSE);
|
||||
pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes, TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Called from I/O thread context */
|
||||
|
|
@ -270,7 +270,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
|
|||
if (PA_SINK_INPUT_IS_LINKED(state) &&
|
||||
i->thread_info.state == PA_SINK_INPUT_INIT) {
|
||||
pa_log_debug("Requesting rewind due to state change.");
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
|
|||
* we are heard right-away. */
|
||||
if (PA_SINK_INPUT_IS_LINKED(state) &&
|
||||
i->thread_info.state == PA_SINK_INPUT_INIT)
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
int pa__init(pa_module*m) {
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
|
|||
if (pa_memblockq_is_readable(s->memblockq) &&
|
||||
s->sink_input->thread_info.underrun_for > 0) {
|
||||
pa_log_debug("Requesting rewind due to end of underrun");
|
||||
pa_sink_input_request_rewind(s->sink_input, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(s->sink_input, 0, FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
|
|||
* we are heard right-away. */
|
||||
if (PA_SINK_INPUT_IS_LINKED(state) &&
|
||||
i->thread_info.state == PA_SINK_INPUT_INIT)
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
|
||||
|
|
|
|||
|
|
@ -1238,7 +1238,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
|||
|
||||
if (pa_memblockq_is_readable(c->input_memblockq) && c->playback.underrun) {
|
||||
pa_log_debug("Requesting rewind due to end of underrun.");
|
||||
pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
|
||||
|
|
|
|||
|
|
@ -1240,7 +1240,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
|
|||
pa_log_debug("Requesting rewind due to end of underrun.");
|
||||
pa_sink_input_request_rewind(s->sink_input,
|
||||
(size_t) (s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for),
|
||||
FALSE, TRUE);
|
||||
FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -1253,7 +1253,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
|
|||
* let's have it usk us again */
|
||||
|
||||
pa_log_debug("Requesting rewind due to rewrite.");
|
||||
pa_sink_input_request_rewind(s->sink_input, (size_t) (indexr - indexw), TRUE, FALSE);
|
||||
pa_sink_input_request_rewind(s->sink_input, (size_t) (indexr - indexw), TRUE, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
|||
|
||||
if (pa_memblockq_is_readable(c->input_memblockq) && c->playback.underrun) {
|
||||
pa_log_debug("Requesting rewind due to end of underrun.");
|
||||
pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
|
||||
|
|
|
|||
|
|
@ -265,6 +265,7 @@ pa_sink_input* pa_sink_input_new(
|
|||
i->thread_info.requested_sink_latency = (pa_usec_t) -1;
|
||||
i->thread_info.rewrite_nbytes = 0;
|
||||
i->thread_info.rewrite_flush = FALSE;
|
||||
i->thread_info.dont_rewind_render = FALSE;
|
||||
i->thread_info.underrun_for = (uint64_t) -1;
|
||||
i->thread_info.playing_for = 0;
|
||||
i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
|
||||
|
|
@ -658,7 +659,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
|
|||
|
||||
lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
|
||||
|
||||
if (nbytes > 0) {
|
||||
if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
|
||||
pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
|
||||
pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
|
||||
}
|
||||
|
|
@ -714,6 +715,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
|
|||
|
||||
i->thread_info.rewrite_nbytes = 0;
|
||||
i->thread_info.rewrite_flush = FALSE;
|
||||
i->thread_info.dont_rewind_render = FALSE;
|
||||
}
|
||||
|
||||
/* Called from thread context */
|
||||
|
|
@ -1091,7 +1093,7 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
|
|||
|
||||
/* This will tell the implementing sink input driver to rewind
|
||||
* so that the unplayed already mixed data is not lost */
|
||||
pa_sink_input_request_rewind(i, 0, TRUE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
|
||||
|
||||
} else if (uncorking) {
|
||||
|
||||
|
|
@ -1102,7 +1104,7 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
|
|||
|
||||
/* OK, we're being uncorked. Make sure we're not rewound when
|
||||
* the hw buffer is remixed and request a remix. */
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1115,12 +1117,12 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t
|
|||
|
||||
case PA_SINK_INPUT_MESSAGE_SET_VOLUME:
|
||||
i->thread_info.volume = *((pa_cvolume*) userdata);
|
||||
pa_sink_input_request_rewind(i, 0, TRUE, FALSE);
|
||||
pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
|
||||
return 0;
|
||||
|
||||
case PA_SINK_INPUT_MESSAGE_SET_MUTE:
|
||||
i->thread_info.muted = PA_PTR_TO_UINT(userdata);
|
||||
pa_sink_input_request_rewind(i, 0, TRUE, FALSE);
|
||||
pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
|
||||
return 0;
|
||||
|
||||
case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
|
||||
|
|
@ -1195,7 +1197,7 @@ pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
|
|||
}
|
||||
|
||||
/* Called from IO context */
|
||||
void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sample spec */, pa_bool_t rewrite, pa_bool_t flush) {
|
||||
void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sample spec */, pa_bool_t rewrite, pa_bool_t flush, pa_bool_t dont_rewind_render) {
|
||||
size_t lbq;
|
||||
|
||||
/* If 'rewrite' is TRUE the sink is rewound as far as requested
|
||||
|
|
@ -1206,7 +1208,9 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
|
|||
* If 'rewrite' is FALSE the sink is rewound as far as requested
|
||||
* and possible and the already rendered data is dropped so that
|
||||
* in the next iteration we read new data from the
|
||||
* implementor. This implies 'flush' is TRUE. */
|
||||
* implementor. This implies 'flush' is TRUE. If
|
||||
* dont_rewind_render is TRUE then the render memblockq is not
|
||||
* rewound. */
|
||||
|
||||
pa_sink_input_assert_ref(i);
|
||||
|
||||
|
|
@ -1219,6 +1223,7 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
|
|||
return;
|
||||
|
||||
pa_assert(rewrite || flush);
|
||||
pa_assert(!dont_rewind_render || !rewrite);
|
||||
|
||||
/* Calculate how much we can rewind locally without having to
|
||||
* touch the sink */
|
||||
|
|
@ -1253,6 +1258,10 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
|
|||
i->thread_info.rewrite_flush ||
|
||||
(flush && i->thread_info.rewrite_nbytes != 0);
|
||||
|
||||
i->thread_info.dont_rewind_render =
|
||||
i->thread_info.dont_rewind_render ||
|
||||
dont_rewind_render;
|
||||
|
||||
if (nbytes != (size_t) -1) {
|
||||
|
||||
/* Transform to sink domain */
|
||||
|
|
|
|||
|
|
@ -179,8 +179,9 @@ struct pa_sink_input {
|
|||
/* We maintain a history of resampled audio data here. */
|
||||
pa_memblockq *render_memblockq;
|
||||
|
||||
/* 0: rewrite nothing, (size_t) -1: rewrite everything, otherwise how many bytes to rewrite */
|
||||
size_t rewrite_nbytes;
|
||||
pa_bool_t rewrite_flush;
|
||||
pa_bool_t rewrite_flush, dont_rewind_render;
|
||||
uint64_t underrun_for, playing_for;
|
||||
|
||||
pa_sink_input *sync_prev, *sync_next;
|
||||
|
|
@ -277,7 +278,7 @@ fully -- or at all. If the request for a rewrite was successful, the
|
|||
sink driver will call ->rewind() and pass the number of bytes that
|
||||
could be rewound in the HW device. This functionality is required for
|
||||
implementing the "zero latency" write-through functionality. */
|
||||
void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes, pa_bool_t rewrite, pa_bool_t flush);
|
||||
void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes, pa_bool_t rewrite, pa_bool_t flush, pa_bool_t dont_rewind_render);
|
||||
|
||||
void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b);
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
|
|||
* we are heard right-away. */
|
||||
if (PA_SINK_INPUT_IS_LINKED(state) &&
|
||||
i->thread_info.state == PA_SINK_INPUT_INIT)
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
|
||||
pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/* Called from IO thread context */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue