]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/protocol-esound.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / protocol-esound.c
index f64552aa49fff48eb7c09e04eb287f27ab8d3fe5..7c1b7a21067506ee4dcf09c3401a951cc74e2dbb 100644 (file)
@@ -28,7 +28,6 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <limits.h>
 
 #include <pulse/rtclock.h>
 #include <pulse/sample.h>
@@ -46,7 +45,6 @@
 #include <pulsecore/source.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/sample-util.h>
-#include <pulsecore/authkey.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
@@ -55,8 +53,7 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/shared.h>
-
-#include "endianmacros.h"
+#include <pulsecore/endianmacros.h>
 
 #include "protocol-esound.h"
 
@@ -85,12 +82,12 @@ typedef struct connection {
     pa_msgobject parent;
 
     uint32_t index;
-    pa_bool_t dead;
+    bool dead;
     pa_esound_protocol *protocol;
     pa_esound_options *options;
     pa_iochannel *io;
     pa_client *client;
-    pa_bool_t authorized, swap_byte_order;
+    bool authorized, swap_byte_order;
     void *write_data;
     size_t write_data_alloc, write_data_index, write_data_length;
     void *read_data;
@@ -108,7 +105,7 @@ typedef struct connection {
         pa_memblock *current_memblock;
         size_t memblock_index;
         pa_atomic_t missing;
-        pa_bool_t underrun;
+        bool underrun;
     } playback;
 
     struct {
@@ -120,9 +117,8 @@ typedef struct connection {
     pa_time_event *auth_timeout_event;
 } 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_esound_protocol {
     PA_REFCNT_DECLARE;
@@ -310,7 +306,7 @@ static void connection_write(connection *c, const void *data, size_t length) {
     memcpy((uint8_t*) c->write_data + i, data, length);
 }
 
-static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) {
+static void format_esd2native(int format, bool swap_bytes, pa_sample_spec *ss) {
     pa_assert(ss);
 
     ss->channels = (uint8_t) (((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1);
@@ -329,12 +325,12 @@ static int format_native2esd(pa_sample_spec *ss) {
     return format;
 }
 
-#define CHECK_VALIDITY(expression, ...) do { \
-    if (!(expression)) { \
-        pa_log_warn(__FILE__ ": " __VA_ARGS__); \
-        return -1; \
-    } \
-} while(0);
+#define CHECK_VALIDITY(expression, ...) do {            \
+        if (PA_UNLIKELY(!(expression))) {               \
+            pa_log_warn(__FILE__ ": " __VA_ARGS__);     \
+            return -1;                                  \
+        }                                               \
+    } while(0);
 
 /*** esound commands ***/
 
@@ -351,7 +347,7 @@ static int esd_proto_connect(connection *c, esd_proto_t request, const void *dat
 
         if ((key = pa_auth_cookie_read(c->options->auth_cookie, ESD_KEY_LEN)))
             if (memcmp(data, key, ESD_KEY_LEN) == 0)
-                c->authorized = TRUE;
+                c->authorized = true;
     }
 
     if (!c->authorized) {
@@ -368,9 +364,9 @@ static int esd_proto_connect(connection *c, esd_proto_t request, const void *dat
 
     memcpy(&ekey, data, sizeof(uint32_t));
     if (ekey == ESD_ENDIAN_KEY)
-        c->swap_byte_order = FALSE;
+        c->swap_byte_order = false;
     else if (ekey == ESD_SWAP_ENDIAN_KEY)
-        c->swap_byte_order = TRUE;
+        c->swap_byte_order = true;
     else {
         pa_log_warn("Client sent invalid endian key");
         return -1;
@@ -390,6 +386,7 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
     size_t l;
     pa_sink *sink = NULL;
     pa_sink_input_new_data sdata;
+    pa_memchunk silence;
 
     connection_assert_ref(c);
     pa_assert(data);
@@ -427,24 +424,28 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
     sdata.driver = __FILE__;
     sdata.module = c->options->module;
     sdata.client = c->client;
-    sdata.sink = sink;
+    if (sink)
+        pa_sink_input_new_data_set_sink(&sdata, sink, false);
     pa_sink_input_new_data_set_sample_spec(&sdata, &ss);
 
-    pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata, 0);
+    pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata);
     pa_sink_input_new_data_done(&sdata);
 
     CHECK_VALIDITY(c->sink_input, "Failed to create sink input.");
 
     l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
+    pa_sink_input_get_silence(c->sink_input, &silence);
     c->input_memblockq = pa_memblockq_new(
+            "esound protocol connection input_memblockq",
             0,
             l,
             l,
-            pa_frame_size(&ss),
+            &ss,
             (size_t) -1,
             l/PLAYBACK_BUFFER_FRAGMENTS,
             0,
-            NULL);
+            &silence);
+    pa_memblock_unref(silence.memblock);
     pa_iochannel_socket_set_rcvbuf(c->io, l);
 
     c->sink_input->parent.process_msg = sink_input_process_msg;
@@ -460,7 +461,7 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
 
     c->protocol->n_player++;
 
-    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);
 
@@ -523,20 +524,22 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi
     sdata.driver = __FILE__;
     sdata.module = c->options->module;
     sdata.client = c->client;
-    sdata.source = source;
+    if (source)
+        pa_source_output_new_data_set_source(&sdata, source, false);
     pa_source_output_new_data_set_sample_spec(&sdata, &ss);
 
-    pa_source_output_new(&c->source_output, c->protocol->core, &sdata, 0);
+    pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
     pa_source_output_new_data_done(&sdata);
 
     CHECK_VALIDITY(c->source_output, "Failed to create source output.");
 
     l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
     c->output_memblockq = pa_memblockq_new(
+            "esound protocol connection output_memblockq",
             0,
             l,
             l,
-            pa_frame_size(&ss),
+            &ss,
             1,
             0,
             0,
@@ -629,7 +632,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
 
     memset(terminator, 0, sizeof(terminator));
 
-    for (conn = pa_idxset_first(c->protocol->connections, &idx); conn; conn = pa_idxset_next(c->protocol->connections, &idx)) {
+    PA_IDXSET_FOREACH(conn, c->protocol->connections, idx) {
         int32_t id, format = ESD_BITS16 | ESD_STEREO, rate = 44100, lvolume = ESD_VOLUME_BASE, rvolume = ESD_VOLUME_BASE;
         char name[ESD_NAME_MAX];
 
@@ -640,7 +643,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
 
         if (conn->sink_input) {
             pa_cvolume volume;
-            pa_sink_input_get_volume(conn->sink_input, &volume, TRUE);
+            pa_sink_input_get_volume(conn->sink_input, &volume, true);
             rate = (int32_t) conn->sink_input->sample_spec.rate;
             lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
             rvolume = (int32_t) ((volume.values[volume.channels == 2 ? 1 : 0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
@@ -687,7 +690,8 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
         pa_scache_entry *ce;
 
         idx = PA_IDXSET_INVALID;
-        for (ce = pa_idxset_first(c->protocol->core->scache, &idx); ce; ce = pa_idxset_next(c->protocol->core->scache, &idx)) {
+
+        PA_IDXSET_FOREACH(ce, c->protocol->core->scache, idx) {
             int32_t id, rate, lvolume, rvolume, format, len;
             char name[ESD_NAME_MAX];
             pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
@@ -772,7 +776,6 @@ static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *
 
     memcpy(&rvolume, data, sizeof(uint32_t));
     rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
-    data = (const char*)data + sizeof(uint32_t);
 
     if ((conn = pa_idxset_get_by_index(c->protocol->connections, idx)) && conn->sink_input) {
         pa_cvolume volume;
@@ -780,7 +783,7 @@ static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *
         volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
         volume.channels = conn->sink_input->sample_spec.channels;
 
-        pa_sink_input_set_volume(conn->sink_input, &volume, TRUE, TRUE);
+        pa_sink_input_set_volume(conn->sink_input, &volume, true, true);
         ok = 1;
     } else
         ok = 0;
@@ -810,7 +813,6 @@ static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *
 
     memcpy(&rvolume, data, sizeof(uint32_t));
     rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
-    data = (const char*)data + sizeof(uint32_t);
 
     volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
     volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
@@ -821,7 +823,7 @@ static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *
 
         pa_cvolume_remap(&volume, &stereo, &ce->channel_map);
         ce->volume = volume;
-        ce->volume_is_set = TRUE;
+        ce->volume_is_set = true;
         ok = 1;
     }
 
@@ -947,11 +949,16 @@ static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const
     connection_write_prepare(c, sizeof(int32_t) * 2);
     connection_write(c, &ok, sizeof(int32_t));
 
-    if (request == ESD_PROTO_STANDBY)
-        ok = pa_sink_suspend_all(c->protocol->core, TRUE, PA_SUSPEND_USER) >= 0;
-    else {
+    pa_log_debug("%s of all sinks and sources requested by client %" PRIu32 ".",
+                 request == ESD_PROTO_STANDBY ? "Suspending" : "Resuming", c->client->index);
+
+    if (request == ESD_PROTO_STANDBY) {
+        ok = pa_sink_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
+        ok &= pa_source_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
+    } else {
         pa_assert(request == ESD_PROTO_RESUME);
-        ok = pa_sink_suspend_all(c->protocol->core, FALSE, PA_SUSPEND_USER) >= 0;
+        ok = pa_sink_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
+        ok &= pa_source_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
     }
 
     connection_write(c, &ok, sizeof(int32_t));
@@ -1019,7 +1026,7 @@ static int do_read(connection *c) {
             c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request);
 
             if (c->request < ESD_PROTO_CONNECT || c->request >= ESD_PROTO_MAX) {
-                pa_log("recieved invalid request.");
+                pa_log("received invalid request.");
                 return -1;
             }
 
@@ -1028,7 +1035,7 @@ static int do_read(connection *c) {
 /*             pa_log("executing request #%u", c->request); */
 
             if (!handler->proc) {
-                pa_log("recieved unimplemented request #%u.", c->request);
+                pa_log("received unimplemented request #%u.", c->request);
                 return -1;
             }
 
@@ -1124,13 +1131,13 @@ static int do_read(connection *c) {
         ssize_t r;
         size_t l;
         void *p;
-        size_t space;
+        size_t space = 0;
 
         pa_assert(c->input_memblockq);
 
 /*         pa_log("STREAMING_DATA"); */
 
-        if (!(l = (size_t) pa_atomic_load(&c->playback.missing)))
+        if ((l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0)
             return 0;
 
         if (c->playback.current_memblock) {
@@ -1172,8 +1179,8 @@ static int do_read(connection *c) {
 
         c->playback.memblock_index += (size_t) r;
 
-        pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
         pa_atomic_sub(&c->playback.missing, (int) r);
+        pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
     }
 
     return 0;
@@ -1189,10 +1196,6 @@ static int do_write(connection *c) {
 
         pa_assert(c->write_data_index < c->write_data_length);
         if ((r = pa_iochannel_write(c->io, (uint8_t*) c->write_data+c->write_data_index, c->write_data_length-c->write_data_index)) < 0) {
-
-            if (r < 0 && (errno == EINTR || errno == EAGAIN))
-                return 0;
-
             pa_log("write(): %s", pa_cstrerror(errno));
             return -1;
         }
@@ -1201,6 +1204,8 @@ static int do_write(connection *c) {
         if (c->write_data_index >= c->write_data_length)
             c->write_data_length = c->write_data_index = 0;
 
+        return 1;
+
     } else if (c->state == ESD_STREAMING_DATA && c->source_output) {
         pa_memchunk chunk;
         ssize_t r;
@@ -1219,15 +1224,12 @@ static int do_write(connection *c) {
         pa_memblock_unref(chunk.memblock);
 
         if (r < 0) {
-
-            if (r < 0 && (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 1;
     }
 
     return 0;
@@ -1251,16 +1253,20 @@ static void do_work(connection *c) {
          * here, instead of simply waiting for read() to return 0. */
         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;
 
 fail:
 
     if (c->state == ESD_STREAMING_DATA && c->sink_input) {
-        c->dead = TRUE;
+        c->dead = true;
 
         pa_iochannel_free(c->io);
         c->io = NULL;
@@ -1335,7 +1341,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)); */
@@ -1372,7 +1378,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);
@@ -1381,10 +1387,9 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
     } else {
         size_t m;
 
-        chunk->length = PA_MIN(length, chunk->length);
-
-        c->playback.underrun = FALSE;
+        c->playback.underrun = false;
 
+        chunk->length = PA_MIN(length, chunk->length);
         pa_memblockq_drop(c->input_memblockq, chunk->length);
         m = pa_memblockq_pop_missing(c->input_memblockq);
 
@@ -1511,9 +1516,9 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou
     c->client->userdata = c;
 
     c->options = pa_esound_options_ref(o);
-    c->authorized = FALSE;
-    c->swap_byte_order = FALSE;
-    c->dead = FALSE;
+    c->authorized = false;
+    c->swap_byte_order = false;
+    c->dead = false;
 
     c->read_data_length = 0;
     c->read_data = pa_xmalloc(c->read_data_alloc = proto_map[ESD_PROTO_CONNECT].data_length);
@@ -1532,7 +1537,7 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou
 
     c->playback.current_memblock = NULL;
     c->playback.memblock_index = 0;
-    c->playback.underrun = TRUE;
+    c->playback.underrun = true;
     pa_atomic_store(&c->playback.missing, 0);
 
     pa_memchunk_reset(&c->scache.memchunk);
@@ -1542,7 +1547,7 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou
 
     if (o->auth_anonymous) {
         pa_log_info("Client authenticated anonymously.");
-        c->authorized = TRUE;
+        c->authorized = true;
     }
 
     if (!c->authorized &&
@@ -1550,7 +1555,7 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou
         pa_ip_acl_check(o->auth_ip_acl, pa_iochannel_get_recv_fd(io)) > 0) {
 
         pa_log_info("Client authenticated by IP ACL.");
-        c->authorized = TRUE;
+        c->authorized = true;
     }
 
     if (!c->authorized)
@@ -1621,7 +1626,7 @@ void pa_esound_protocol_unref(pa_esound_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, "esound-protocol") >= 0);
 
@@ -1666,7 +1671,7 @@ void pa_esound_options_unref(pa_esound_options *o) {
 }
 
 int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
-    pa_bool_t enabled;
+    bool enabled;
     const char *acl;
 
     pa_assert(o);
@@ -1692,7 +1697,7 @@ int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
         o->auth_ip_acl = ipa;
     }
 
-    enabled = TRUE;
+    enabled = true;
     if (pa_modargs_get_value_boolean(ma, "auth-cookie-enabled", &enabled) < 0) {
         pa_log("auth-cookie-enabled= expects a boolean argument.");
         return -1;
@@ -1710,7 +1715,7 @@ int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
             if (!(cn = pa_modargs_get_value(ma, "cookie", NULL)))
                 cn = DEFAULT_COOKIE_FILE;
 
-        if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, ESD_KEY_LEN)))
+        if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, true, ESD_KEY_LEN)))
             return -1;
 
     } else