From 75119e91cdb4f29b0567689d07d00ddc17a98b5c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 15 Jan 2009 00:40:06 +0100 Subject: add new dont_rewind_render flag to allow quick starts of newly created streams --- src/pulsecore/play-memblockq.c | 2 +- src/pulsecore/protocol-esound.c | 2 +- src/pulsecore/protocol-native.c | 4 ++-- src/pulsecore/protocol-simple.c | 2 +- src/pulsecore/sink-input.c | 23 ++++++++++++++++------- src/pulsecore/sink-input.h | 5 +++-- src/pulsecore/sound-file-stream.c | 2 +- 7 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src/pulsecore') diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 86edfe98..758c0dee 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -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) { diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 460119a9..2f014827 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -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)); */ diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 3c1e5761..7cce3db0 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -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); } } diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 743bf2ee..9c4a5386 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -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)); */ diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 33490cc6..f5a1cb80 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -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 */ diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 8cfe32bc..3d2a8c0d 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -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); diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index c30c16eb..b78afca8 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -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 */ -- cgit