]> code.delx.au - pulseaudio/commitdiff
native: rework handling of seeks that depend on variables the client does not know...
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Jan 2010 00:33:04 +0000 (01:33 +0100)
committerColin Guthrie <cguthrie@mandriva.org>
Tue, 9 Feb 2010 22:45:59 +0000 (22:45 +0000)
All seeks/flushes that depend on the playback buffer read pointer cannot
be accounted for properly in the client since it does not know the
actual read pointer. Due to that the clients do not account for it at
all. We need do the same on the server side. And we did, but a little
bit too extreme. While we properly have not applied the changes to the
"request" counter we still do have to apply it to the "missing" counter.
This patch fixes that.

src/modules/module-combine.c
src/modules/module-loopback.c
src/pulse/stream.c
src/pulsecore/memblockq.c
src/pulsecore/memblockq.h
src/pulsecore/protocol-native.c
src/pulsecore/sink-input.c

index 62e626791745a535ac31eaa4ccceacac9657584b..cffb901b6e8b6c9043ba2e4bff746f83c443ee21 100644 (file)
@@ -562,7 +562,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_write(o->memblockq);
+                pa_memblockq_flush_write(o->memblockq, TRUE);
 
             return 0;
     }
@@ -982,7 +982,7 @@ static void output_disable(struct output *o) {
     o->sink_input = NULL;
 
     /* Finally, drop all queued data */
-    pa_memblockq_flush_write(o->memblockq);
+    pa_memblockq_flush_write(o->memblockq, TRUE);
     pa_asyncmsgq_flush(o->inq, FALSE);
     pa_asyncmsgq_flush(o->outq, FALSE);
 }
index bb0182b00d9478c7b0b1a84227fb6a426d7a11a6..15ef96efefd9bd15b4b85e0adcc1db4ae3142f17 100644 (file)
@@ -430,7 +430,7 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
             if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
                 pa_memblockq_push_align(u->memblockq, chunk);
             else
-                pa_memblockq_flush_write(u->memblockq);
+                pa_memblockq_flush_write(u->memblockq, TRUE);
 
             update_min_memblockq_length(u);
 
@@ -457,7 +457,7 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
             if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
                 pa_memblockq_seek(u->memblockq, -offset, PA_SEEK_RELATIVE, TRUE);
             else
-                pa_memblockq_flush_write(u->memblockq);
+                pa_memblockq_flush_write(u->memblockq, TRUE);
 
             u->recv_counter -= offset;
 
index 5e42ab28c7d0177bd7947f88dad42f47408d8b30..36514e0e8f5750f4bf66ef0c9cae4c4916f37775 100644 (file)
@@ -2154,6 +2154,11 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use
          * index, but the read index might jump. */
         invalidate_indexes(s, TRUE, FALSE);
 
+    /* Note that we do not update requested_bytes here. This is
+     * because we cannot really know how data actually was dropped
+     * from the write index due to this. This 'error' will be applied
+     * by both client and server and hence we should be fine. */
+
     return o;
 }
 
index 4641801d43124415708f26542c33dd2a7274a21a..2b063fac5e89c679e378c43dcdd6b19cc7b1a282 100644 (file)
@@ -254,6 +254,8 @@ static void write_index_changed(pa_memblockq *bq, int64_t old_write_index, pa_bo
 
     if (account)
         bq->requested -= delta;
+    else
+        bq->missing -= delta;
 
     /* pa_log("pushed/seeked %lli: requested counter at %lli, account=%i", (long long) delta, (long long) bq->requested, account); */
 }
@@ -642,7 +644,7 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek, pa
     write_index_changed(bq, old, account);
 }
 
-void pa_memblockq_flush_write(pa_memblockq *bq) {
+void pa_memblockq_flush_write(pa_memblockq *bq, pa_bool_t account) {
     int64_t old;
     pa_assert(bq);
 
@@ -652,7 +654,7 @@ void pa_memblockq_flush_write(pa_memblockq *bq) {
     bq->write_index = bq->read_index;
 
     pa_memblockq_prebuf_force(bq);
-    write_index_changed(bq, old, TRUE);
+    write_index_changed(bq, old, account);
 }
 
 void pa_memblockq_flush_read(pa_memblockq *bq) {
index b756549affff698d244a819b946f7f413c0ca675..402c6cdb22d9bf71cad1e1a89556c65e1dcd678d 100644 (file)
@@ -118,7 +118,7 @@ size_t pa_memblockq_pop_missing(pa_memblockq *bq);
 int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source);
 
 /* Set the queue to silence, set write index to read index */
-void pa_memblockq_flush_write(pa_memblockq *bq);
+void pa_memblockq_flush_write(pa_memblockq *bq, pa_bool_t account);
 
 /* Set the queue to silence, set write read index to write index*/
 void pa_memblockq_flush_read(pa_memblockq *bq);
index 89f33d087d2e843d5b653f5cf5e5f85eac220b5b..ff246120bd8986962d8fb670d21ae3ac1da26ce4 100644 (file)
@@ -1326,6 +1326,10 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
     playback_stream_request_bytes(s);
 }
 
+static void flush_write_no_account(pa_memblockq *q) {
+    pa_memblockq_flush_write(q, FALSE);
+}
+
 /* Called from thread context */
 static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
     pa_sink_input *i = PA_SINK_INPUT(o);
@@ -1387,7 +1391,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_write;
+                    func = flush_write_no_account;
                     break;
 
                 case SINK_INPUT_MESSAGE_PREBUF_FORCE:
index e73999d9d06541287d2933b16aac8849ec1cc2e1..395110b7fe412656dc35c52f622ab8ec4cfd833c 100644 (file)
@@ -842,7 +842,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_write(i->thread_info.render_memblockq);
+        pa_memblockq_flush_write(i->thread_info.render_memblockq, TRUE);
 
     } else if (i->thread_info.rewrite_nbytes > 0) {
         size_t max_rewrite, amount;