]> code.delx.au - pulseaudio/blobdiff - src/modules/module-tunnel.c
introduce default channel map in addition to the default sample spec
[pulseaudio] / src / modules / module-tunnel.c
index af27ce7446b536f121ca442618ea114db1aa00af..63ae740aba6ebb92c83c0488a95dd72a030ee1b3 100644 (file)
@@ -159,7 +159,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = command_suspended,
     [PA_COMMAND_RECORD_STREAM_SUSPENDED] = command_suspended,
     [PA_COMMAND_PLAYBACK_STREAM_MOVED] = command_moved,
-    [PA_COMMAND_RECORD_STREAM_MOVED] = command_moved,
+    [PA_COMMAND_RECORD_STREAM_MOVED] = command_moved
 };
 
 struct userdata {
@@ -178,7 +178,7 @@ struct userdata {
 #ifdef TUNNEL_SINK
     char *sink_name;
     pa_sink *sink;
-    int32_t requested_bytes;
+    size_t requested_bytes;
 #else
     char *source_name;
     pa_source *source;
@@ -231,7 +231,7 @@ static void command_stream_killed(pa_pdispatch *pd,  uint32_t command,  uint32_t
     pa_assert(u->pdispatch == pd);
 
     pa_log_warn("Stream killed");
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 }
 
 /* Called from main context */
@@ -262,7 +262,7 @@ static void command_suspended(pa_pdispatch *pd,  uint32_t command,  uint32_t tag
         pa_tagstruct_get_boolean(t, &suspended) < 0 ||
         !pa_tagstruct_eof(t)) {
         pa_log("Invalid packet");
-        pa_module_unload_request(u->module);
+        pa_module_unload_request(u->module, TRUE);
         return;
     }
 
@@ -389,7 +389,7 @@ static void send_data(struct userdata *u) {
 
         u->requested_bytes -= memchunk.length;
 
-        u->counter += memchunk.length;
+        u->counter += (int64_t) memchunk.length;
     }
 }
 
@@ -417,7 +417,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
         case PA_SINK_MESSAGE_GET_LATENCY: {
             pa_usec_t yl, yr, *usec = data;
 
-            yl = pa_bytes_to_usec(u->counter, &u->sink->sample_spec);
+            yl = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec);
             yr = pa_smoother_get(u->smoother, pa_rtclock_usec());
 
             *usec = yl > yr ? yl - yr : 0;
@@ -444,10 +444,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
         case SINK_MESSAGE_UPDATE_LATENCY: {
             pa_usec_t y;
 
-            y = pa_bytes_to_usec(u->counter, &u->sink->sample_spec);
+            y = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec);
 
             if (y > (pa_usec_t) offset || offset < 0)
-                y -= offset;
+                y -= (pa_usec_t) offset;
             else
                 y = 0;
 
@@ -465,7 +465,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
             pa_pstream_send_memblock(u->pstream, u->channel, 0, PA_SEEK_RELATIVE, chunk);
 
-            u->counter_delta += chunk->length;
+            u->counter_delta += (int64_t) chunk->length;
 
             return 0;
     }
@@ -494,6 +494,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
 
         case PA_SINK_UNLINKED:
         case PA_SINK_INIT:
+        case PA_SINK_INVALID_STATE:
             ;
     }
 
@@ -508,7 +509,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
 
     switch (code) {
 
-        case PA_SINK_MESSAGE_SET_STATE: {
+        case PA_SOURCE_MESSAGE_SET_STATE: {
             int r;
 
             if ((r = pa_source_process_msg(o, code, data, offset, chunk)) >= 0)
@@ -520,7 +521,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
         case PA_SOURCE_MESSAGE_GET_LATENCY: {
             pa_usec_t yr, yl, *usec = data;
 
-            yl = pa_bytes_to_usec(u->counter, &PA_SINK(o)->sample_spec);
+            yl = pa_bytes_to_usec((uint64_t) u->counter, &PA_SOURCE(o)->sample_spec);
             yr = pa_smoother_get(u->smoother, pa_rtclock_usec());
 
             *usec = yr > yl ? yr - yl : 0;
@@ -532,7 +533,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
             if (PA_SOURCE_IS_OPENED(u->source->thread_info.state))
                 pa_source_post(u->source, chunk);
 
-            u->counter += chunk->length;
+            u->counter += (int64_t) chunk->length;
 
             return 0;
 
@@ -544,10 +545,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
         case SOURCE_MESSAGE_UPDATE_LATENCY: {
             pa_usec_t y;
 
-            y = pa_bytes_to_usec(u->counter, &u->source->sample_spec);
+            y = pa_bytes_to_usec((uint64_t) u->counter, &u->source->sample_spec);
 
             if (offset >= 0 || y > (pa_usec_t) -offset)
-                y += offset;
+                y += (pa_usec_t) offset;
             else
                 y = 0;
 
@@ -581,6 +582,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
 
         case PA_SOURCE_UNLINKED:
         case PA_SOURCE_INIT:
+        case PA_SINK_INVALID_STATE:
             ;
     }
 
@@ -652,7 +654,7 @@ static void command_request(pa_pdispatch *pd, uint32_t command,  uint32_t tag, p
     return;
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 }
 
 #endif
@@ -660,7 +662,7 @@ fail:
 /* Called from main context */
 static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     struct userdata *u = userdata;
-    pa_usec_t sink_usec, source_usec, transport_usec;
+    pa_usec_t sink_usec, source_usec, transport_usec = 0;
     pa_bool_t playing;
     int64_t write_index, read_index;
     struct timeval local, remote, now;
@@ -736,9 +738,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
 
     /* Add the length of our server-side buffer */
     if (write_index >= read_index)
-        delay += (int64_t) pa_bytes_to_usec(write_index-read_index, ss);
+        delay += (int64_t) pa_bytes_to_usec((uint64_t) (write_index-read_index), ss);
     else
-        delay -= (int64_t) pa_bytes_to_usec(read_index-write_index, ss);
+        delay -= (int64_t) pa_bytes_to_usec((uint64_t) (read_index-write_index), ss);
 
     /* Our measurements are already out of date, hence correct by the     *
      * transport latency */
@@ -750,9 +752,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
 
     /* Now correct by what we have have read/written since we requested the update */
 #ifdef TUNNEL_SINK
-    delay += (int64_t) pa_bytes_to_usec(u->counter_delta, ss);
+    delay += (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss);
 #else
-    delay -= (int64_t) pa_bytes_to_usec(u->counter_delta, ss);
+    delay -= (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss);
 #endif
 
 #ifdef TUNNEL_SINK
@@ -765,7 +767,7 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
 
 fail:
 
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 }
 
 /* Called from main context */
@@ -902,7 +904,7 @@ static void server_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
     return;
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 }
 
 #ifdef TUNNEL_SINK
@@ -979,7 +981,7 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa_t
     return;
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
     pa_proplist_free(pl);
 }
 
@@ -1054,10 +1056,10 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag
     pa_assert(u->sink);
 
     if ((u->version < 11 || !!mute == !!u->sink->muted) &&
-        pa_cvolume_equal(&volume, &u->sink->volume))
+        pa_cvolume_equal(&volume, &u->sink->virtual_volume))
         return;
 
-    memcpy(&u->sink->volume, &volume, sizeof(pa_cvolume));
+    memcpy(&u->sink->virtual_volume, &volume, sizeof(pa_cvolume));
 
     if (u->version >= 11)
         u->sink->muted = !!mute;
@@ -1066,7 +1068,7 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag
     return;
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
     pa_proplist_free(pl);
 }
 
@@ -1142,7 +1144,7 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
     return;
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
     pa_proplist_free(pl);
 }
 
@@ -1204,7 +1206,7 @@ static void command_subscribe_event(pa_pdispatch *pd,  uint32_t command,  uint32
     if (pa_tagstruct_getu32(t, &e) < 0 ||
         pa_tagstruct_getu32(t, &idx) < 0) {
         pa_log("Invalid protocol reply");
-        pa_module_unload_request(u->module);
+        pa_module_unload_request(u->module, TRUE);
         return;
     }
 
@@ -1344,7 +1346,7 @@ parse_error:
     pa_log("Invalid reply. (Create stream)");
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 
 }
 
@@ -1425,11 +1427,11 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
         u->maxlength = 4*1024*1024;
 
 #ifdef TUNNEL_SINK
-    u->tlength = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
-    u->minreq = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
+    u->tlength = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
+    u->minreq = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
     u->prebuf = u->tlength;
 #else
-    u->fragsize = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
+    u->fragsize = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
 #endif
 
 #ifdef TUNNEL_SINK
@@ -1494,6 +1496,13 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
 #endif
     }
 
+    if (u->version >= 14) {
+#ifdef TUNNEL_SINK
+        pa_tagstruct_put_boolean(reply, FALSE); /* volume_set */
+#endif
+        pa_tagstruct_put_boolean(reply, TRUE); /* early rquests */
+    }
+
     pa_pstream_send_tagstruct(u->pstream, reply);
     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL);
 
@@ -1502,7 +1511,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
     return;
 
 fail:
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 }
 
 /* Called from main context */
@@ -1513,7 +1522,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
     pa_assert(u);
 
     pa_log_warn("Stream died.");
-    pa_module_unload_request(u->module);
+    pa_module_unload_request(u->module, TRUE);
 }
 
 /* Called from main context */
@@ -1526,7 +1535,7 @@ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_c
 
     if (pa_pdispatch_run(u->pdispatch, packet, creds, u) < 0) {
         pa_log("Invalid packet");
-        pa_module_unload_request(u->module);
+        pa_module_unload_request(u->module, TRUE);
         return;
     }
 }
@@ -1542,13 +1551,13 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
 
     if (channel != u->channel) {
         pa_log("Recieved memory block on bad channel.");
-        pa_module_unload_request(u->module);
+        pa_module_unload_request(u->module, TRUE);
         return;
     }
 
     pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_POST, PA_UINT_TO_PTR(seek), offset, chunk);
 
-    u->counter_delta += chunk->length;
+    u->counter_delta += (int64_t) chunk->length;
 }
 
 #endif
@@ -1568,7 +1577,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
 
     if (!io) {
         pa_log("Connection failed: %s", pa_cstrerror(errno));
-        pa_module_unload_request(u->module);
+        pa_module_unload_request(u->module, TRUE);
         return;
     }
 
@@ -1612,7 +1621,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
 #ifdef TUNNEL_SINK
 
 /* Called from main context */
-static int sink_set_volume(pa_sink *sink) {
+static void sink_set_volume(pa_sink *sink) {
     struct userdata *u;
     pa_tagstruct *t;
     uint32_t tag;
@@ -1625,14 +1634,12 @@ static int sink_set_volume(pa_sink *sink) {
     pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME);
     pa_tagstruct_putu32(t, tag = u->ctag++);
     pa_tagstruct_putu32(t, u->device_index);
-    pa_tagstruct_put_cvolume(t, &sink->volume);
+    pa_tagstruct_put_cvolume(t, &sink->virtual_volume);
     pa_pstream_send_tagstruct(u->pstream, t);
-
-    return 0;
 }
 
 /* Called from main context */
-static int sink_set_mute(pa_sink *sink) {
+static void sink_set_mute(pa_sink *sink) {
     struct userdata *u;
     pa_tagstruct *t;
     uint32_t tag;
@@ -1642,7 +1649,7 @@ static int sink_set_mute(pa_sink *sink) {
     pa_assert(u);
 
     if (u->version < 11)
-        return -1;
+        return;
 
     t = pa_tagstruct_new(NULL, 0);
     pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_MUTE);
@@ -1650,8 +1657,6 @@ static int sink_set_mute(pa_sink *sink) {
     pa_tagstruct_putu32(t, u->device_index);
     pa_tagstruct_put_boolean(t, !!sink->muted);
     pa_pstream_send_tagstruct(u->pstream, t);
-
-    return 0;
 }
 
 #endif
@@ -1712,6 +1717,7 @@ int pa__init(pa_module*m) {
     }
 
     ss = m->core->default_sample_spec;
+    map = m->core->default_channel_map;
     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
         pa_log("Invalid sample format specification");
         goto fail;