]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/protocol-simple.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / protocol-simple.c
index dd8002a3967ab604c0b1372fd93993ad313d9c21..fc36880e1ef8de07f78203c2e270855da1b3e545 100644 (file)
@@ -5,7 +5,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 #endif
 
 #include <stdlib.h>
-#include <limits.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
 
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
@@ -59,19 +57,18 @@ typedef struct connection {
     pa_client *client;
     pa_memblockq *input_memblockq, *output_memblockq;
 
-    pa_bool_t dead;
+    bool dead;
 
     struct {
         pa_memblock *current_memblock;
         size_t memblock_index;
         pa_atomic_t missing;
-        pa_bool_t underrun;
+        bool underrun;
     } playback;
 } connection;
 
-PA_DECLARE_CLASS(connection);
+PA_DEFINE_PRIVATE_CLASS(connection, pa_msgobject);
 #define CONNECTION(o) (connection_cast(o))
-static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject);
 
 struct pa_simple_protocol {
     PA_REFCNT_DECLARE;
@@ -88,7 +85,7 @@ enum {
 enum {
     CONNECTION_MESSAGE_REQUEST_DATA,      /* data requested from sink input from the main loop */
     CONNECTION_MESSAGE_POST_DATA,         /* data from source output to main loop */
-    CONNECTION_MESSAGE_UNLINK_CONNECTION    /* Please drop a aconnection now */
+    CONNECTION_MESSAGE_UNLINK_CONNECTION  /* Please drop the connection now */
 };
 
 #define PLAYBACK_BUFFER_SECONDS (.5)
@@ -130,7 +127,7 @@ static void connection_unlink(connection *c) {
         c->io = NULL;
     }
 
-    pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c);
+    pa_idxset_remove_by_data(c->protocol->connections, c, NULL);
     c->protocol = NULL;
     connection_unref(c);
 }
@@ -155,7 +152,7 @@ static int do_read(connection *c) {
     ssize_t r;
     size_t l;
     void *p;
-    size_t space;
+    size_t space = 0;
 
     connection_assert_ref(c);
 
@@ -232,17 +229,13 @@ static int do_write(connection *c) {
     pa_memblock_unref(chunk.memblock);
 
     if (r < 0) {
-
-        if (errno == EINTR || errno == EAGAIN)
-            return 0;
-
         pa_log("write(): %s", pa_cstrerror(errno));
         return -1;
     }
 
     pa_memblockq_drop(c->output_memblockq, (size_t) r);
 
-    return 0;
+    return 1;
 }
 
 static void do_work(connection *c) {
@@ -258,9 +251,13 @@ static void do_work(connection *c) {
     if (!c->sink_input && pa_iochannel_is_hungup(c->io))
         goto fail;
 
-    if (pa_iochannel_is_writable(c->io))
-        if (do_write(c) < 0)
+    while (pa_iochannel_is_writable(c->io)) {
+        int r = do_write(c);
+        if (r < 0)
             goto fail;
+        if (r == 0)
+            break;
+    }
 
     return;
 
@@ -269,7 +266,7 @@ fail:
     if (c->sink_input) {
 
         /* If there is a sink input, we first drain what we already have read before shutting down the connection */
-        c->dead = TRUE;
+        c->dead = true;
 
         pa_iochannel_free(c->io);
         c->io = NULL;
@@ -283,6 +280,9 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6
     connection *c = CONNECTION(o);
     connection_assert_ref(c);
 
+    if (!c->protocol)
+        return -1;
+
     switch (code) {
         case CONNECTION_MESSAGE_REQUEST_DATA:
             do_work(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, FALSE);
+                pa_sink_input_request_rewind(c->sink_input, 0, false, true, false);
             }
 
 /*             pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
@@ -360,7 +360,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
 
     if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) {
 
-        c->playback.underrun = TRUE;
+        c->playback.underrun = true;
 
         if (c->dead && pa_sink_input_safe_to_remove(i))
             pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL);
@@ -371,7 +371,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
 
         chunk->length = PA_MIN(length, chunk->length);
 
-        c->playback.underrun = FALSE;
+        c->playback.underrun = false;
 
         pa_memblockq_drop(c->input_memblockq, chunk->length);
         m = pa_memblockq_pop_missing(c->input_memblockq);
@@ -502,8 +502,8 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
     c->options = pa_simple_options_ref(o);
     c->playback.current_memblock = NULL;
     c->playback.memblock_index = 0;
-    c->dead = FALSE;
-    c->playback.underrun = TRUE;
+    c->dead = false;
+    c->playback.underrun = true;
     pa_atomic_store(&c->playback.missing, 0);
 
     pa_client_new_data_init(&client_data);
@@ -523,6 +523,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
 
     if (o->playback) {
         pa_sink_input_new_data data;
+        pa_memchunk silence;
         size_t l;
         pa_sink *sink;
 
@@ -535,11 +536,11 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         data.driver = __FILE__;
         data.module = o->module;
         data.client = c->client;
-        data.sink = sink;
+        pa_sink_input_new_data_set_sink(&data, sink, false);
         pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
         pa_sink_input_new_data_set_sample_spec(&data, &o->sample_spec);
 
-        c->sink_input = pa_sink_input_new(p->core, &data, 0);
+        pa_sink_input_new(&c->sink_input, p->core, &data);
         pa_sink_input_new_data_done(&data);
 
         if (!c->sink_input) {
@@ -557,18 +558,22 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY);
 
         l = (size_t) ((double) pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS);
+        pa_sink_input_get_silence(c->sink_input, &silence);
         c->input_memblockq = pa_memblockq_new(
+                "simple protocol connection input_memblockq",
                 0,
                 l,
                 l,
-                pa_frame_size(&o->sample_spec),
+                &o->sample_spec,
                 (size_t) -1,
                 l/PLAYBACK_BUFFER_FRAGMENTS,
                 0,
-                NULL);
+                &silence);
+        pa_memblock_unref(silence.memblock);
+
         pa_iochannel_socket_set_rcvbuf(io, l);
 
-        pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));
+        pa_atomic_store(&c->playback.missing, (int) pa_memblockq_pop_missing(c->input_memblockq));
 
         pa_sink_input_put(c->sink_input);
     }
@@ -587,11 +592,11 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         data.driver = __FILE__;
         data.module = o->module;
         data.client = c->client;
-        data.source = source;
+        pa_source_output_new_data_set_source(&data, source, false);
         pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
         pa_source_output_new_data_set_sample_spec(&data, &o->sample_spec);
 
-        c->source_output = pa_source_output_new(p->core, &data, 0);
+        pa_source_output_new(&c->source_output, p->core, &data);
         pa_source_output_new_data_done(&data);
 
         if (!c->source_output) {
@@ -607,10 +612,11 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
 
         l = (size_t) (pa_bytes_per_second(&o->sample_spec)*RECORD_BUFFER_SECONDS);
         c->output_memblockq = pa_memblockq_new(
+                "simple protocol connection output_memblockq",
                 0,
                 l,
                 0,
-                pa_frame_size(&o->sample_spec),
+                &o->sample_spec,
                 1,
                 0,
                 0,
@@ -625,8 +631,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
     return;
 
 fail:
-    if (c)
-        connection_unlink(c);
+    connection_unlink(c);
 }
 
 void pa_simple_protocol_disconnect(pa_simple_protocol *p, pa_module *m) {
@@ -685,7 +690,7 @@ void pa_simple_protocol_unref(pa_simple_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "simple-protocol") >= 0);
 
@@ -698,8 +703,8 @@ pa_simple_options* pa_simple_options_new(void) {
     o = pa_xnew0(pa_simple_options, 1);
     PA_REFCNT_INIT(o);
 
-    o->record = FALSE;
-    o->playback = TRUE;
+    o->record = false;
+    o->playback = true;
 
     return o;
 }
@@ -727,7 +732,7 @@ void pa_simple_options_unref(pa_simple_options *o) {
 }
 
 int pa_simple_options_parse(pa_simple_options *o, pa_core *c, pa_modargs *ma) {
-    pa_bool_t enabled;
+    bool enabled;
 
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);