[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. ee79b05b31bc0e4ac331d2fbe869079c122e973b
Lennart Poettering
gitmailer-noreply at 0pointer.de
Thu Jun 26 10:04:41 PDT 2008
This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.
The master branch has been updated
from 517727ebdcd9d6dbc7eacdc843f886ed2e0f38f6 (commit)
- Log -----------------------------------------------------------------
ee79b05... rework logic to request automatic timing updates a bit
4b8c4ef... reorder a few things to get rid of an uneeded comparison
97084e8... add a FIXME
7d3d3fc... move initialization order of validity bools around a bit
36d6c71... unify smoother pause/resume handling in a single function check_smoother_status()
dcbb7f2... convert to double only once, and make sure we can deal with negative results of -y
eab1cb8... make sure to call process_rewind() under all circumstances before we do the next loop iteration
1e36b57... use the newer name for monotonic/monotonous
2c5a33d... remove redundant check
85b83e8... properly initialize pa_stream::corked based on the flags
1514d13... split pa_memblockq_flush() into two flush commands, one which fixes up the read ptr, and one which fixes up the write ptr
5fccac9... comment two functions in memblockq.c
ec10f5f... use the bight lighter _silence() instead of _flush() when destructing our little q
dd8b909... fix up if the smoother shall be resumed 'before' it was actually paused
b4302ca... fix up monotonicity of input to _get() instead of hitting an assert
63b68f4... call the enum PA_STREAM_NOT_MONOTONIC and make PA_STREAM_NOT_MONOTONOUS an alias for that
df2650e... fix return value of pa_namereg_make_valid_name()
c5cbeb5... choose more sensible default buffer sizes for old clients
-----------------------------------------------------------------------
Summary of changes:
src/modules/module-alsa-sink.c | 11 ++-
src/modules/module-combine.c | 5 +-
src/modules/module-esound-sink.c | 4 +
src/modules/module-jack-sink.c | 4 +
src/modules/module-null-sink.c | 8 +-
src/modules/module-pipe-sink.c | 8 +-
src/modules/module-tunnel.c | 6 +
src/pulse/def.h | 13 ++-
src/pulse/stream.c | 211 ++++++++++++++++++++-----------------
src/pulsecore/memblockq.c | 19 +++-
src/pulsecore/memblockq.h | 45 +++++----
src/pulsecore/namereg.c | 4 +-
src/pulsecore/namereg.h | 2 +-
src/pulsecore/protocol-native.c | 4 +-
src/pulsecore/sink-input.c | 25 ++---
src/pulsecore/sink.c | 42 +++++---
src/pulsecore/sink.h | 1 +
src/pulsecore/time-smoother.c | 22 +++--
18 files changed, 258 insertions(+), 176 deletions(-)
-----------------------------------------------------------------------
commit c5cbeb5ed294af7aaae8a8bb674526da2fecdd84
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jun 25 02:28:33 2008 +0200
choose more sensible default buffer sizes for old clients
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 3bee7a0..b3f9697 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -119,6 +119,11 @@ pa_stream *pa_stream_new_with_proplist(
s->requested_bytes = 0;
memset(&s->buffer_attr, 0, sizeof(s->buffer_attr));
+ /* We initialize der target length here, so that if the user
+ * passes no explicit buffering metrics the default is similar to
+ * what older PA versions provided. */
+ s->buffer_attr.tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+
s->device_index = PA_INVALID_INDEX;
s->device_name = NULL;
s->suspended = FALSE;
@@ -685,16 +690,19 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
return;
/* Version older than 0.9.10 didn't do server side buffer_attr
- * selection, hence we have to fake it on the client side */
+ * selection, hence we have to fake it on the client side. */
+
+ /* We choose fairly conservative values here, to not confuse
+ * old clients with extremely large playback buffers */
if (!attr->maxlength <= 0)
attr->maxlength = 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
if (!attr->tlength <= 0)
- attr->tlength = pa_bytes_per_second(ss)*2; /* 2s of buffering */
+ attr->tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
if (!attr->minreq <= 0)
- attr->minreq = (2*attr->tlength)/10; /* Ask for more data when there are only 200ms left in the playback buffer */
+ attr->minreq = (attr->tlength)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
if (!attr->prebuf)
attr->prebuf = attr->tlength; /* Start to play only when the playback is fully filled up once */
commit df2650e7a5167dbfc625727e0f189c21bc0e15e6
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:27:02 2008 +0200
fix return value of pa_namereg_make_valid_name()
diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
index 38d308c..3042054 100644
--- a/src/pulsecore/namereg.c
+++ b/src/pulsecore/namereg.c
@@ -70,7 +70,7 @@ pa_bool_t pa_namereg_is_valid_name(const char *name) {
return TRUE;
}
-const char* pa_namereg_make_valid_name(const char *name) {
+char* pa_namereg_make_valid_name(const char *name) {
const char *a;
char *b, *n;
@@ -109,7 +109,7 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t
return NULL;
if ((type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE) &&
- !pa_namereg_is_valid_name(name) ) {
+ !pa_namereg_is_valid_name(name)) {
if (fail)
return NULL;
diff --git a/src/pulsecore/namereg.h b/src/pulsecore/namereg.h
index b460382..3c1de8e 100644
--- a/src/pulsecore/namereg.h
+++ b/src/pulsecore/namereg.h
@@ -44,6 +44,6 @@ const char *pa_namereg_get_default_sink_name(pa_core *c);
const char *pa_namereg_get_default_source_name(pa_core *c);
pa_bool_t pa_namereg_is_valid_name(const char *name);
-const char* pa_namereg_make_valid_name(const char *name);
+char* pa_namereg_make_valid_name(const char *name);
#endif
commit 63b68f418e2bf905ebb6068aaa4fd05467d8e1ba
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:27:54 2008 +0200
call the enum PA_STREAM_NOT_MONOTONIC and make PA_STREAM_NOT_MONOTONOUS an alias for that
diff --git a/src/pulse/def.h b/src/pulse/def.h
index a91c103..8407dde 100644
--- a/src/pulse/def.h
+++ b/src/pulse/def.h
@@ -120,7 +120,7 @@ typedef enum pa_stream_flags {
* of sense to combine this
* option with
* PA_STREAM_AUTO_TIMING_UPDATE. */
- PA_STREAM_NOT_MONOTONOUS = 4, /**< Don't force the time to
+ PA_STREAM_NOT_MONOTONIC = 4, /**< Don't force the time to
* increase monotonically. If
* this option is enabled,
* pa_stream_get_time() will not
@@ -135,7 +135,12 @@ typedef enum pa_stream_flags {
* caused the time to to jump
* ahead can be corrected
* quickly, without the need to
- * wait. */
+ * wait. (Please note that this
+ * flag was named
+ * PA_STREAM_NOT_MONOTONOUS in
+ * releases prior to 0.9.11. The
+ * old name is still defined too,
+ * for compatibility reasons. */
PA_STREAM_AUTO_TIMING_UPDATE = 8, /**< If set timing update requests
* are issued periodically
* automatically. Combined with
@@ -237,8 +242,8 @@ typedef enum pa_stream_flags {
} pa_stream_flags_t;
-/** English is an evil language \since 0.9.11 */
-#define PA_STREAM_NOT_MONOTONIC PA_STREAM_NOT_MONOTONOUS
+/** English is an evil language */
+#define PA_STREAM_NOT_MONOTONOUS PA_STREAM_NOT_MONOTONIC
/** Playback and record buffer metrics */
typedef struct pa_buffer_attr {
commit b4302cacf94b0e720befc120ae9fe71be77a8973
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:29:59 2008 +0200
fix up monotonicity of input to _get() instead of hitting an assert
diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c
index fe5a4f1..013edfc 100644
--- a/src/pulsecore/time-smoother.c
+++ b/src/pulsecore/time-smoother.c
@@ -373,12 +373,15 @@ pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x) {
x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0;
+ if (s->monotonic)
+ if (x <= s->last_x)
+ x = s->last_x;
+
estimate(s, x, &y, NULL);
if (s->monotonic) {
/* Make sure the querier doesn't jump forth and back. */
- pa_assert(x >= s->last_x);
s->last_x = x;
if (y < s->last_y)
commit dd8b90953255db7529d6efa597c5996ac10d8849
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:31:39 2008 +0200
fix up if the smoother shall be resumed 'before' it was actually paused
diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c
index 013edfc..40220ad 100644
--- a/src/pulsecore/time-smoother.c
+++ b/src/pulsecore/time-smoother.c
@@ -421,7 +421,8 @@ void pa_smoother_resume(pa_smoother *s, pa_usec_t x) {
if (!s->paused)
return;
- pa_assert(x >= s->pause_time);
+ if (x < s->pause_time)
+ x = s->pause_time;
/* pa_log_debug("resume(%llu)", (unsigned long long) x); */
@@ -458,5 +459,4 @@ void pa_smoother_reset(pa_smoother *s) {
s->n_history = 0;
s->abc_valid = FALSE;
-
}
commit ec10f5fdd33065afad5abb0a3c3c7802fc9d32f6
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:33:07 2008 +0200
use the bight lighter _silence() instead of _flush() when destructing our little q
diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c
index a9f28a0..9ce3372 100644
--- a/src/pulsecore/memblockq.c
+++ b/src/pulsecore/memblockq.c
@@ -110,7 +110,7 @@ pa_memblockq* pa_memblockq_new(
void pa_memblockq_free(pa_memblockq* bq) {
pa_assert(bq);
- pa_memblockq_flush(bq);
+ pa_memblockq_silence(bq);
if (bq->silence.memblock)
pa_memblock_unref(bq->silence.memblock);
commit 5fccac94e737a760c12fb82e5cd4a82362c17a24
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:36:05 2008 +0200
comment two functions in memblockq.c
diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h
index 81f7cbb..ad3eea4 100644
--- a/src/pulsecore/memblockq.h
+++ b/src/pulsecore/memblockq.h
@@ -160,11 +160,13 @@ void pa_memblockq_willneed(pa_memblockq *bq);
* data for the future nor data in the backlog. */
pa_bool_t pa_memblockq_is_empty(pa_memblockq *bq);
+/* Drop everything in the queue, but don't modify the indexes */
void pa_memblockq_silence(pa_memblockq *bq);
/* Check whether we currently are in prebuf state */
pa_bool_t pa_memblockq_prebuf_active(pa_memblockq *bq);
+/* Return how many items are currently stored in the queue */
unsigned pa_memblockq_get_nblocks(pa_memblockq *bq);
size_t pa_memblockq_get_base(pa_memblockq *bq);
commit 1514d138353f04578d885d9cb18c528d9b562a83
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:39:31 2008 +0200
split pa_memblockq_flush() into two flush commands, one which fixes up the read ptr, and one which fixes up the write ptr
diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c
index cef7a99..8c155da 100644
--- a/src/modules/module-combine.c
+++ b/src/modules/module-combine.c
@@ -525,7 +525,7 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64
if (PA_SINK_IS_OPENED(o->sink_input->sink->thread_info.state))
pa_memblockq_push_align(o->memblockq, chunk);
else
- pa_memblockq_flush(o->memblockq);
+ pa_memblockq_flush_write(o->memblockq);
return 0;
}
@@ -555,7 +555,7 @@ static void enable_output(struct output *o) {
if (output_create_sink_input(o) >= 0) {
- pa_memblockq_flush(o->memblockq);
+ pa_memblockq_flush_write(o->memblockq);
pa_sink_input_put(o->sink_input);
diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c
index 9ce3372..841b907 100644
--- a/src/pulsecore/memblockq.c
+++ b/src/pulsecore/memblockq.c
@@ -638,7 +638,7 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) {
bq->missing -= delta;
}
-void pa_memblockq_flush(pa_memblockq *bq) {
+void pa_memblockq_flush_write(pa_memblockq *bq) {
int64_t old, delta;
pa_assert(bq);
@@ -662,6 +662,21 @@ void pa_memblockq_flush(pa_memblockq *bq) {
bq->missing -= delta;
}
+void pa_memblockq_flush_read(pa_memblockq *bq) {
+ int64_t old, delta;
+ pa_assert(bq);
+
+ pa_memblockq_silence(bq);
+
+ old = bq->read_index;
+ bq->read_index = bq->write_index;
+
+ pa_memblockq_prebuf_force(bq);
+
+ delta = bq->read_index - old;
+ bq->missing += delta;
+}
+
size_t pa_memblockq_get_tlength(pa_memblockq *bq) {
pa_assert(bq);
diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h
index ad3eea4..4b9450f 100644
--- a/src/pulsecore/memblockq.h
+++ b/src/pulsecore/memblockq.h
@@ -84,6 +84,9 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *chunk);
* you know what you do. */
int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk);
+/* Manipulate the write pointer */
+void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek);
+
/* Return a copy of the next memory chunk in the queue. It is not
* removed from the queue. There are two reasons this function might
* fail: 1. prebuffering is active, 2. queue is empty and no silence
@@ -95,6 +98,9 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk);
/* Drop the specified bytes from the queue. */
void pa_memblockq_drop(pa_memblockq *bq, size_t length);
+/* Rewind the read index. If the history is shorter than the specified length we'll point to silence afterwards. */
+void pa_memblockq_rewind(pa_memblockq *bq, size_t length);
+
/* Test if the pa_memblockq is currently readable, that is, more data than base */
pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq);
@@ -111,26 +117,11 @@ size_t pa_memblockq_pop_missing(pa_memblockq *bq);
/* Directly moves the data from the source memblockq into bq */
int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source);
-/* Returns the minimal request value */
-size_t pa_memblockq_get_minreq(pa_memblockq *bq);
-
-/* Manipulate the write pointer */
-void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek);
-
/* Set the queue to silence, set write index to read index */
-void pa_memblockq_flush(pa_memblockq *bq);
-
-/* Get Target length */
-size_t pa_memblockq_get_tlength(pa_memblockq *bq);
-
-/* Return the current read index */
-int64_t pa_memblockq_get_read_index(pa_memblockq *bq);
-
-/* Return the current write index */
-int64_t pa_memblockq_get_write_index(pa_memblockq *bq);
+void pa_memblockq_flush_write(pa_memblockq *bq);
-/* Rewind the read index. If the history is shorter than the specified length we'll point to silence afterwards. */
-void pa_memblockq_rewind(pa_memblockq *bq, size_t length);
+/* Set the queue to silence, set write read index to write index*/
+void pa_memblockq_flush_read(pa_memblockq *bq);
/* Ignore prebuf for now */
void pa_memblockq_prebuf_disable(pa_memblockq *bq);
@@ -141,9 +132,24 @@ void pa_memblockq_prebuf_force(pa_memblockq *bq);
/* Return the maximum length of the queue in bytes */
size_t pa_memblockq_get_maxlength(pa_memblockq *bq);
+/* Get Target length */
+size_t pa_memblockq_get_tlength(pa_memblockq *bq);
+
/* Return the prebuffer length in bytes */
size_t pa_memblockq_get_prebuf(pa_memblockq *bq);
+/* Returns the minimal request value */
+size_t pa_memblockq_get_minreq(pa_memblockq *bq);
+
+/* Return the base unit in bytes */
+size_t pa_memblockq_get_base(pa_memblockq *bq);
+
+/* Return the current read index */
+int64_t pa_memblockq_get_read_index(pa_memblockq *bq);
+
+/* Return the current write index */
+int64_t pa_memblockq_get_write_index(pa_memblockq *bq);
+
/* Change metrics. Always call in order. */
void pa_memblockq_set_maxlength(pa_memblockq *memblockq, size_t maxlength); /* might modify tlength, prebuf, minreq too */
void pa_memblockq_set_tlength(pa_memblockq *memblockq, size_t tlength); /* might modify minreq, too */
@@ -169,6 +175,5 @@ pa_bool_t pa_memblockq_prebuf_active(pa_memblockq *bq);
/* Return how many items are currently stored in the queue */
unsigned pa_memblockq_get_nblocks(pa_memblockq *bq);
-size_t pa_memblockq_get_base(pa_memblockq *bq);
#endif
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 923a566..862b062 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1196,7 +1196,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
switch (code) {
case SINK_INPUT_MESSAGE_FLUSH:
- func = pa_memblockq_flush;
+ func = pa_memblockq_flush_write;
break;
case SINK_INPUT_MESSAGE_PREBUF_FORCE:
@@ -3072,7 +3072,7 @@ static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_U
s = pa_idxset_get_by_index(c->record_streams, idx);
CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
- pa_memblockq_flush(s->memblockq);
+ pa_memblockq_flush_read(s->memblockq);
pa_pstream_send_simple_ack(c->pstream, tag);
}
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 43e7bb2..be16970 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -664,7 +664,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
/* We were asked to drop all buffered data, and rerequest new
* data from implementor the next time push() is called */
- pa_memblockq_flush(i->thread_info.render_memblockq);
+ pa_memblockq_flush_write(i->thread_info.render_memblockq);
} else if (i->thread_info.rewrite_nbytes > 0) {
size_t max_rewrite, amount;
commit 85b83e8e8cb7ddc154f6bf06b588ea93fe263186
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:42:09 2008 +0200
properly initialize pa_stream::corked based on the flags
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index b3f9697..33ab710 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -880,6 +880,7 @@ static int create_stream(
s->direction = direction;
s->flags = flags;
+ s->corked = !!(flags & PA_STREAM_START_CORKED);
if (sync_stream)
s->syncid = sync_stream->syncid;
@@ -919,7 +920,7 @@ static int create_stream(
PA_TAG_U32, PA_INVALID_INDEX,
PA_TAG_STRING, dev,
PA_TAG_U32, s->buffer_attr.maxlength,
- PA_TAG_BOOLEAN, !!(flags & PA_STREAM_START_CORKED),
+ PA_TAG_BOOLEAN, s->corked,
PA_TAG_INVALID);
if (s->direction == PA_STREAM_PLAYBACK) {
commit 2c5a33d9d8427c9add8085b05356c910a6f6ee94
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:43:30 2008 +0200
remove redundant check
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 33ab710..709f1b7 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -604,15 +604,12 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC
request_auto_timing_update(s, TRUE);
- if (s->state == PA_STREAM_READY) {
-
- if (command == PA_COMMAND_OVERFLOW) {
- if (s->overflow_callback)
- s->overflow_callback(s, s->overflow_userdata);
- } else if (command == PA_COMMAND_UNDERFLOW) {
- if (s->underflow_callback)
- s->underflow_callback(s, s->underflow_userdata);
- }
+ if (command == PA_COMMAND_OVERFLOW) {
+ if (s->overflow_callback)
+ s->overflow_callback(s, s->overflow_userdata);
+ } else if (command == PA_COMMAND_UNDERFLOW) {
+ if (s->underflow_callback)
+ s->underflow_callback(s, s->underflow_userdata);
}
finish:
commit 1e36b57b13d421dab20c436e0ae302acc34fbac9
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 00:44:19 2008 +0200
use the newer name for monotonic/monotonous
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 709f1b7..c75e38e 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -892,7 +892,7 @@ static int create_stream(
if (s->smoother)
pa_smoother_free(s->smoother);
- s->smoother = pa_smoother_new(SMOOTHER_ADJUST_TIME, SMOOTHER_HISTORY_TIME, !(flags & PA_STREAM_NOT_MONOTONOUS), SMOOTHER_MIN_HISTORY);
+ s->smoother = pa_smoother_new(SMOOTHER_ADJUST_TIME, SMOOTHER_HISTORY_TIME, !(flags & PA_STREAM_NOT_MONOTONIC), SMOOTHER_MIN_HISTORY);
x = pa_rtclock_usec();
pa_smoother_set_time_offset(s->smoother, x);
commit eab1cb8df952bc302d14efd1640d96f8bbdb148a
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 02:56:00 2008 +0200
make sure to call process_rewind() under all circumstances before we do the next loop iteration
diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c
index 6765775..5818dee 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -882,7 +882,7 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
if (u->hwbuf_unused_frames > before) {
pa_log_debug("Requesting rewind due to latency change.");
- pa_sink_request_rewind(s, 0);
+ pa_sink_request_rewind(s, (size_t) -1);
}
}
@@ -967,9 +967,12 @@ static void thread_func(void *userdata) {
int work_done;
pa_usec_t sleep_usec;
- if (u->sink->thread_info.rewind_nbytes > 0)
- if (process_rewind(u) < 0)
- goto fail;
+ if (u->sink->thread_info.rewind_requested) {
+ if (u->sink->thread_info.rewind_nbytes <= 0)
+ pa_sink_process_rewind(u->sink, 0);
+ else if (process_rewind(u) < 0)
+ goto fail;
+ }
if (u->use_mmap)
work_done = mmap_write(u, &sleep_usec);
diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c
index 8c155da..7d8e140 100644
--- a/src/modules/module-combine.c
+++ b/src/modules/module-combine.c
@@ -410,7 +410,6 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
struct output *o;
pa_sink_input_assert_ref(i);
- pa_assert(nbytes > 0);
pa_assert_se(o = i->userdata);
pa_memblockq_rewind(o->memblockq, nbytes);
diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c
index e189feb..6ca6497 100644
--- a/src/modules/module-esound-sink.c
+++ b/src/modules/module-esound-sink.c
@@ -204,6 +204,10 @@ static void thread_func(void *userdata) {
for (;;) {
int ret;
+ if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+ if (u->sink->thread_info.rewind_requested)
+ pa_sink_process_rewind(u->sink, 0);
+
if (u->rtpoll_item) {
struct pollfd *pollfd;
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c
index c4d47f8..edc543a 100644
--- a/src/modules/module-jack-sink.c
+++ b/src/modules/module-jack-sink.c
@@ -222,6 +222,10 @@ static void thread_func(void *userdata) {
for (;;) {
int ret;
+ if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+ if (u->sink->thread_info.rewind_requested)
+ pa_sink_process_rewind(u->sink, 0);
+
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;
diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c
index 604ab15..9162960 100644
--- a/src/modules/module-null-sink.c
+++ b/src/modules/module-null-sink.c
@@ -204,8 +204,12 @@ static void thread_func(void *userdata) {
now = pa_rtclock_usec();
- if (u->sink->thread_info.rewind_nbytes > 0)
- process_rewind(u, now);
+ if (u->sink->thread_info.rewind_requested) {
+ if (u->sink->thread_info.rewind_nbytes > 0)
+ process_rewind(u, now);
+ else
+ pa_sink_process_rewind(u->sink, 0);
+ }
if (u->timestamp <= now)
process_render(u, now);
diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c
index cd25b89..0999935 100644
--- a/src/modules/module-pipe-sink.c
+++ b/src/modules/module-pipe-sink.c
@@ -184,8 +184,12 @@ static void thread_func(void *userdata) {
/* Render some data and write it to the fifo */
if (u->sink->thread_info.state == PA_SINK_RUNNING) {
- if (u->sink->thread_info.rewind_nbytes > 0)
- process_rewind(u);
+ if (u->sink->thread_info.rewind_requested) {
+ if (u->sink->thread_info.rewind_nbytes > 0)
+ process_rewind(u);
+ else
+ pa_sink_process_rewind(u->sink, 0);
+ }
if (pollfd->revents) {
if (process_render(u) < 0)
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index 86f3081..1890646 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -605,6 +605,12 @@ static void thread_func(void *userdata) {
for (;;) {
int ret;
+#ifdef TUNNEL_SINK
+ if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+ if (u->sink->thread_info.rewind_requested)
+ pa_sink_process_rewind(u->sink, 0);
+#endif
+
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index be16970..4086b85 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -491,12 +491,6 @@ int pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa
i->thread_info.state == PA_SINK_INPUT_CORKED ||
i->thread_info.state == PA_SINK_INPUT_DRAINED);
- /* If there's still some rewrite request the handle, but the sink
- didn't do this for us, we do it here. However, since the sink
- apparently doesn't support rewinding, we pass 0 here. This still
- allows rewinding through the render buffer. */
- pa_sink_input_process_rewind(i, 0);
-
block_size_max_sink_input = i->thread_info.resampler ?
pa_resampler_max_block_size(i->thread_info.resampler) :
pa_frame_align(pa_mempool_block_size_max(i->sink->core->mempool), &i->sample_spec);
@@ -633,18 +627,13 @@ void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec *
/* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
- /* If there's still some rewrite request the handle, but the sink
- didn't do this for us, we do it here. However, since the sink
- apparently doesn't support rewinding, we pass 0 here. This still
- allows rewinding through the render buffer. */
- pa_sink_input_process_rewind(i, 0);
-
pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
}
/* Called from thread context */
void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
size_t lbq;
+ pa_bool_t called;
pa_sink_input_assert_ref(i);
pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
@@ -685,6 +674,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
/* Tell the implementor */
if (i->process_rewind)
i->process_rewind(i, amount);
+ called = TRUE;
/* Convert back to to sink domain */
if (i->thread_info.resampler)
@@ -703,6 +693,10 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
}
}
+ if (!called)
+ if (i->process_rewind)
+ i->process_rewind(i, 0);
+
i->thread_info.rewrite_nbytes = 0;
i->thread_info.rewrite_flush = FALSE;
}
@@ -1143,6 +1137,8 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
pa_sink_input_assert_ref(i);
pa_assert(i->thread_info.rewrite_nbytes == 0);
+/* pa_log_debug("request rewrite %lu", (unsigned long) nbytes); */
+
/* We don't take rewind requests while we are corked */
if (i->thread_info.state == PA_SINK_INPUT_CORKED)
return;
@@ -1184,6 +1180,9 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
if (nbytes > lbq)
pa_sink_request_rewind(i->sink, nbytes - lbq);
+ else
+ /* This call will make sure process_rewind() is called later */
+ pa_sink_request_rewind(i->sink, 0);
}
/* Called from main context */
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index edb023b..0866829 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -212,6 +212,7 @@ pa_sink* pa_sink_new(
s->thread_info.soft_muted = FALSE;
s->thread_info.state = s->state;
s->thread_info.rewind_nbytes = 0;
+ s->thread_info.rewind_requested = FALSE;
s->thread_info.max_rewind = 0;
s->thread_info.max_request = 0;
s->thread_info.requested_latency_valid = FALSE;
@@ -454,21 +455,20 @@ void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
pa_sink_assert_ref(s);
pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
- /* Make sure the sink code already reset the counter! */
- pa_assert(s->thread_info.rewind_nbytes <= 0);
-
- if (nbytes <= 0)
- return;
+ s->thread_info.rewind_nbytes = 0;
+ s->thread_info.rewind_requested = FALSE;
- pa_log_debug("Processing rewind...");
+ if (nbytes > 0)
+ pa_log_debug("Processing rewind...");
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
pa_sink_input_assert_ref(i);
pa_sink_input_process_rewind(i, nbytes);
}
- if (s->monitor_source && PA_SOURCE_IS_OPENED(s->monitor_source->thread_info.state))
- pa_source_process_rewind(s->monitor_source, nbytes);
+ if (nbytes > 0)
+ if (s->monitor_source && PA_SOURCE_IS_OPENED(s->monitor_source->thread_info.state))
+ pa_source_process_rewind(s->monitor_source, nbytes);
}
/* Called from IO thread context */
@@ -620,7 +620,8 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
pa_sink_ref(s);
- s->thread_info.rewind_nbytes = 0;
+ pa_assert(!s->thread_info.rewind_requested);
+ pa_assert(s->thread_info.rewind_nbytes == 0);
if (length <= 0)
length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
@@ -696,7 +697,8 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
pa_sink_ref(s);
- s->thread_info.rewind_nbytes = 0;
+ pa_assert(!s->thread_info.rewind_requested);
+ pa_assert(s->thread_info.rewind_nbytes == 0);
length = target->length;
block_size_max = pa_mempool_block_size_max(s->core->mempool);
@@ -774,7 +776,8 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
pa_sink_ref(s);
- s->thread_info.rewind_nbytes = 0;
+ pa_assert(!s->thread_info.rewind_requested);
+ pa_assert(s->thread_info.rewind_nbytes == 0);
l = target->length;
d = 0;
@@ -800,7 +803,8 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
pa_assert(pa_frame_aligned(length, &s->sample_spec));
pa_assert(result);
- s->thread_info.rewind_nbytes = 0;
+ pa_assert(!s->thread_info.rewind_requested);
+ pa_assert(s->thread_info.rewind_nbytes == 0);
/*** This needs optimization ***/
@@ -1067,7 +1071,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
pa_sink_input_unref(i);
pa_sink_invalidate_requested_latency(s);
- pa_sink_request_rewind(s, 0);
+ pa_sink_request_rewind(s, (size_t) -1);
return 0;
}
@@ -1112,7 +1116,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
pa_sink_invalidate_requested_latency(s);
pa_log_debug("Requesting rewind due to started move");
- pa_sink_request_rewind(s, 0);
+ pa_sink_request_rewind(s, (size_t) -1);
return 0;
}
@@ -1162,13 +1166,13 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
case PA_SINK_MESSAGE_SET_VOLUME:
s->thread_info.soft_volume = *((pa_cvolume*) userdata);
- pa_sink_request_rewind(s, 0);
+ pa_sink_request_rewind(s, (size_t) -1);
return 0;
case PA_SINK_MESSAGE_SET_MUTE:
s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata);
- pa_sink_request_rewind(s, 0);
+ pa_sink_request_rewind(s, (size_t) -1);
return 0;
case PA_SINK_MESSAGE_GET_VOLUME:
@@ -1309,15 +1313,17 @@ void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
pa_sink_assert_ref(s);
pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
- if (nbytes <= 0)
+ if (nbytes == (size_t) -1)
nbytes = s->thread_info.max_rewind;
nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
- if (nbytes <= s->thread_info.rewind_nbytes)
+ if (s->thread_info.rewind_requested &&
+ nbytes <= s->thread_info.rewind_nbytes)
return;
s->thread_info.rewind_nbytes = nbytes;
+ s->thread_info.rewind_requested = TRUE;
if (s->request_rewind)
s->request_rewind(s);
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index b73944e..604be26 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -145,6 +145,7 @@ struct pa_sink {
/* Maximum of what clients requested to rewind in this cycle */
size_t rewind_nbytes;
+ pa_bool_t rewind_requested;
pa_usec_t min_latency; /* we won't go below this latency */
pa_usec_t max_latency; /* An upper limit for the latencies */
commit dcbb7f2680a2b8a74691ec0ef1334fb655cf9bf6
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 18:49:02 2008 +0200
convert to double only once, and make sure we can deal with negative results of -y
diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c
index 40220ad..d023148 100644
--- a/src/pulsecore/time-smoother.c
+++ b/src/pulsecore/time-smoother.c
@@ -295,24 +295,29 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {
*deriv = s->dp;
} else {
+ double tx, ty;
/* Ok, we're not yet on track, thus let's interpolate, and
* make sure that the first derivative is smooth */
calc_abc(s);
+ tx = (double) x;
+
/* Move to origin */
- x -= s->ex;
+ tx -= (double) s->ex;
/* Horner scheme */
- *y = (pa_usec_t) ((double) x * (s->c + (double) x * (s->b + (double) x * s->a)));
+ ty = (tx * (s->c + tx * (s->b + tx * s->a)));
/* Move back from origin */
- *y += s->ey;
+ ty += (double) s->ey;
+
+ *y = ty >= 0 ? (pa_usec_t) ty : 0;
/* Horner scheme */
if (deriv)
- *deriv = s->c + ((double) x * (s->b*2 + (double) x * s->a*3));
+ *deriv = s->c + (tx * (s->b*2 + tx * s->a*3));
}
/* Guarantee monotonicity */
commit 36d6c712d8f06c7d96229c8543956cc7ffdf3c25
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 19:00:42 2008 +0200
unify smoother pause/resume handling in a single function check_smoother_status()
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index c75e38e..0c7df14 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -342,6 +342,41 @@ finish:
pa_context_unref(c);
}
+static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t force_start, pa_bool_t force_stop) {
+ pa_usec_t x;
+
+ pa_assert(s);
+ pa_assert(!force_start || !force_stop);
+
+ if (!s->smoother)
+ return;
+
+ x = pa_rtclock_usec();
+
+ if (s->timing_info_valid) {
+ if (aposteriori)
+ x -= s->timing_info.transport_usec;
+ else
+ x += s->timing_info.transport_usec;
+
+ if (s->direction == PA_STREAM_PLAYBACK)
+ /* it takes a while until the pause/resume is actually
+ * audible */
+ x += s->timing_info.sink_usec;
+ else
+ /* Data froma while back will be dropped */
+ x -= s->timing_info.source_usec;
+ }
+
+ if (s->suspended || s->corked || force_stop)
+ pa_smoother_pause(s->smoother, x);
+ else if (force_start || s->buffer_attr.prebuf == 0)
+ pa_smoother_resume(s->smoother, x);
+
+ /* Please note that we have no idea if playback actually started
+ * if prebuf is non-zero! */
+}
+
void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
@@ -429,6 +464,7 @@ void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED u
s->suspended = suspended;
+ check_smoother_status(s, TRUE, FALSE, FALSE);
request_auto_timing_update(s, TRUE);
if (s->moved_callback)
@@ -472,18 +508,7 @@ void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUS
s->suspended = suspended;
- if (s->smoother) {
- pa_usec_t x = pa_rtclock_usec();
-
- if (s->timing_info_valid)
- x -= s->timing_info.transport_usec;
-
- if (s->suspended || s->corked)
- pa_smoother_pause(s->smoother, x);
- else
- pa_smoother_resume(s->smoother, x);
- }
-
+ check_smoother_status(s, TRUE, FALSE, FALSE);
request_auto_timing_update(s, TRUE);
if (s->suspended_callback)
@@ -523,6 +548,7 @@ void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag,
if (s->state != PA_STREAM_READY)
goto finish;
+ check_smoother_status(s, TRUE, TRUE, FALSE);
request_auto_timing_update(s, TRUE);
if (s->started_callback)
@@ -592,15 +618,8 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC
if (s->state != PA_STREAM_READY)
goto finish;
- if (s->smoother)
- if (s->direction == PA_STREAM_PLAYBACK && s->buffer_attr.prebuf > 0) {
- pa_usec_t x = pa_rtclock_usec();
-
- if (s->timing_info_valid)
- x -= s->timing_info.transport_usec;
-
- pa_smoother_pause(s->smoother, x);
- }
+ if (s->buffer_attr.prebuf > 0)
+ check_smoother_status(s, TRUE, FALSE, TRUE);
request_auto_timing_update(s, TRUE);
@@ -676,6 +695,8 @@ static void create_stream_complete(pa_stream *s) {
request_auto_timing_update(s, TRUE);
}
+
+ check_smoother_status(s, TRUE, FALSE, FALSE);
}
static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_sample_spec *ss) {
@@ -1704,15 +1725,7 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi
pa_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_stream_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
- if (s->smoother) {
- pa_usec_t x = pa_rtclock_usec();
-
- if (s->timing_info_valid)
- x += s->timing_info.transport_usec;
-
- if (s->suspended || s->corked)
- pa_smoother_pause(s->smoother, x);
- }
+ check_smoother_status(s, FALSE, FALSE, FALSE);
if (s->direction == PA_STREAM_PLAYBACK)
invalidate_indexes(s, TRUE, FALSE);
commit 7d3d3fc15d43e61fbecf1746db88ca2edc1c51ff
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 19:01:51 2008 +0200
move initialization order of validity bools around a bit
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 0c7df14..43fc2fe 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -1292,13 +1292,9 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
i = &o->stream->timing_info;
-/* pa_log("pre corrupt w:%u r:%u\n", !o->stream->timing_info_valid || i->write_index_corrupt,!o->stream->timing_info_valid || i->read_index_corrupt); */
-
o->stream->timing_info_valid = FALSE;
- i->write_index_corrupt = FALSE;
- i->read_index_corrupt = FALSE;
-
-/* pa_log("timing update %u\n", tag); */
+ i->write_index_corrupt = TRUE;
+ i->read_index_corrupt = TRUE;
if (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
@@ -1332,8 +1328,10 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
pa_context_fail(o->context, PA_ERR_PROTOCOL);
goto finish;
}
-
o->stream->timing_info_valid = TRUE;
+ i->write_index_corrupt = FALSE;
+ i->read_index_corrupt = FALSE;
+
i->playing = (int) playing;
i->since_underrun = playing ? playing_for : underrun_for;
commit 97084e87c47071482ee9e2102bb480e67b0f5e8d
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 19:02:14 2008 +0200
add a FIXME
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 43fc2fe..adce7ad 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -1092,6 +1092,8 @@ int pa_stream_write(
else
s->requested_bytes = 0;
+ /* FIXME!!! ^^^ will break when offset is != 0 and mode is not RELATIVE*/
+
if (s->direction == PA_STREAM_PLAYBACK) {
/* Update latency request correction */
commit 4b8c4ef932e41404536e51d00b9bf010918151d6
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 19:03:16 2008 +0200
reorder a few things to get rid of an uneeded comparison
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index adce7ad..66964d3 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -1371,8 +1371,8 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
int n, j;
uint32_t ctag = tag;
- /* Go through the saved correction values and add up the total correction.*/
-
+ /* Go through the saved correction values and add up the
+ * total correction.*/
for (n = 0, j = o->stream->current_write_index_correction+1;
n < PA_MAX_WRITE_INDEX_CORRECTIONS;
n++, j = (j + 1) % PA_MAX_WRITE_INDEX_CORRECTIONS) {
@@ -1388,7 +1388,6 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
/* Now fix the write index */
if (o->stream->write_index_corrections[j].corrupt) {
/* A corrupting seek was made */
- i->write_index = 0;
i->write_index_corrupt = TRUE;
} else if (o->stream->write_index_corrections[j].absolute) {
/* An absolute seek was made */
@@ -1399,21 +1398,8 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
i->write_index += o->stream->write_index_corrections[j].value;
}
}
- }
-
- if (o->stream->direction == PA_STREAM_RECORD) {
- /* Read index correction */
-
- if (!i->read_index_corrupt)
- i->read_index -= pa_memblockq_get_length(o->stream->record_memblockq);
- }
-
-/* pa_log("post corrupt w:%u r:%u\n", i->write_index_corrupt || !o->stream->timing_info_valid, i->read_index_corrupt || !o->stream->timing_info_valid); */
-
- /* Clear old correction entries */
- if (o->stream->direction == PA_STREAM_PLAYBACK) {
- int n;
+ /* Clear old correction entries */
for (n = 0; n < PA_MAX_WRITE_INDEX_CORRECTIONS; n++) {
if (!o->stream->write_index_corrections[n].valid)
continue;
@@ -1423,6 +1409,13 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
}
}
+ if (o->stream->direction == PA_STREAM_RECORD) {
+ /* Read index correction */
+
+ if (!i->read_index_corrupt)
+ i->read_index -= pa_memblockq_get_length(o->stream->record_memblockq);
+ }
+
/* Update smoother */
if (o->stream->smoother) {
pa_usec_t u, x;
commit ee79b05b31bc0e4ac331d2fbe869079c122e973b
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jun 26 19:03:53 2008 +0200
rework logic to request automatic timing updates a bit
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 66964d3..89838c5 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -1422,8 +1422,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
u = x = pa_rtclock_usec() - i->transport_usec;
- if (o->stream->direction == PA_STREAM_PLAYBACK &&
- o->context->version >= 13) {
+ if (o->stream->direction == PA_STREAM_PLAYBACK && o->context->version >= 13) {
pa_usec_t su;
/* If we weren't playing then it will take some time
@@ -1720,8 +1719,9 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi
check_smoother_status(s, FALSE, FALSE, FALSE);
- if (s->direction == PA_STREAM_PLAYBACK)
- invalidate_indexes(s, TRUE, FALSE);
+ /* This might cause the indexes to hang/start again, hence
+ * let's request a timing update */
+ request_auto_timing_update(s, TRUE);
return o;
}
@@ -1755,32 +1755,25 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE);
- if ((o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata))) {
-
- if (s->direction == PA_STREAM_PLAYBACK) {
- if (s->write_index_corrections[s->current_write_index_correction].valid)
- s->write_index_corrections[s->current_write_index_correction].corrupt = TRUE;
-
- if (s->timing_info_valid)
- s->timing_info.write_index_corrupt = TRUE;
+ if (!(o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata)))
+ return NULL;
- if (s->buffer_attr.prebuf > 0)
- invalidate_indexes(s, TRUE, FALSE);
- else
- request_auto_timing_update(s, TRUE);
+ if (s->direction == PA_STREAM_PLAYBACK) {
- if (s->smoother && s->buffer_attr.prebuf > 0) {
- pa_usec_t x = pa_rtclock_usec();
+ if (s->write_index_corrections[s->current_write_index_correction].valid)
+ s->write_index_corrections[s->current_write_index_correction].corrupt = TRUE;
- if (s->timing_info_valid)
- x += s->timing_info.transport_usec;
+ if (s->buffer_attr.prebuf > 0)
+ check_smoother_status(s, FALSE, FALSE, TRUE);
- pa_smoother_pause(s->smoother, x);
- }
+ /* This will change the write index, but leave the
+ * read index untouched. */
+ invalidate_indexes(s, FALSE, TRUE);
- } else
- invalidate_indexes(s, FALSE, TRUE);
- }
+ } else
+ /* For record streams this has no influence on the write
+ * index, but the read index might jump. */
+ invalidate_indexes(s, TRUE, FALSE);
return o;
}
@@ -1795,8 +1788,12 @@ pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *us
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->buffer_attr.prebuf > 0, PA_ERR_BADSTATE);
- if ((o = stream_send_simple_command(s, PA_COMMAND_PREBUF_PLAYBACK_STREAM, cb, userdata)))
- invalidate_indexes(s, TRUE, FALSE);
+ if (!(o = stream_send_simple_command(s, PA_COMMAND_PREBUF_PLAYBACK_STREAM, cb, userdata)))
+ return NULL;
+
+ /* This might cause the read index to hang again, hence
+ * let's request a timing update */
+ request_auto_timing_update(s, TRUE);
return o;
}
@@ -1811,8 +1808,12 @@ pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *u
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->buffer_attr.prebuf > 0, PA_ERR_BADSTATE);
- if ((o = stream_send_simple_command(s, PA_COMMAND_TRIGGER_PLAYBACK_STREAM, cb, userdata)))
- invalidate_indexes(s, TRUE, FALSE);
+ if (!(o = stream_send_simple_command(s, PA_COMMAND_TRIGGER_PLAYBACK_STREAM, cb, userdata)))
+ return NULL;
+
+ /* This might cause the read index to start moving again, hence
+ * let's request a timing update */
+ request_auto_timing_update(s, TRUE);
return o;
}
@@ -2062,6 +2063,10 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
pa_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, stream_set_buffer_attr_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+ /* This might cause changes in the read/write indexex, hence let's
+ * request a timing update */
+ request_auto_timing_update(s, TRUE);
+
return o;
}
--
hooks/post-receive
PulseAudio Sound Server
More information about the pulseaudio-commits
mailing list