]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/sink.c
protocol-native: Protect against clients trying to set a NULL port
[pulseaudio] / src / pulsecore / sink.c
index f3b78a5a86f35be0b7c54f422bffe9d90489bfdd..2d214cf0612fe5233fe9d7ea102d8cd06822ca26 100644 (file)
@@ -139,40 +139,13 @@ void pa_sink_new_data_done(pa_sink_new_data *data) {
 
     pa_proplist_free(data->proplist);
 
-    if (data->ports) {
-        pa_device_port *p;
-
-        while ((p = pa_hashmap_steal_first(data->ports)))
-            pa_device_port_free(p);
-
-        pa_hashmap_free(data->ports, NULL, NULL);
-    }
+    if (data->ports)
+        pa_device_port_hashmap_free(data->ports);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
 }
 
-pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra) {
-    pa_device_port *p;
-
-    pa_assert(name);
-
-    p = pa_xmalloc(PA_ALIGN(sizeof(pa_device_port)) + extra);
-    p->name = pa_xstrdup(name);
-    p->description = pa_xstrdup(description);
-
-    p->priority = 0;
-
-    return p;
-}
-
-void pa_device_port_free(pa_device_port *p) {
-    pa_assert(p);
-
-    pa_xfree(p->name);
-    pa_xfree(p->description);
-    pa_xfree(p);
-}
 
 /* Called from main context */
 static void reset_callbacks(pa_sink *s) {
@@ -285,11 +258,17 @@ pa_sink* pa_sink_new(
 
     s->sample_spec = data->sample_spec;
     s->channel_map = data->channel_map;
+    s->default_sample_rate = s->sample_spec.rate;
+
     if (data->alternate_sample_rate_is_set)
         s->alternate_sample_rate = data->alternate_sample_rate;
     else
         s->alternate_sample_rate = s->core->alternate_sample_rate;
-    s->default_sample_rate = s->sample_spec.rate;
+
+    if (s->sample_spec.rate == s->alternate_sample_rate) {
+        pa_log_warn("Default and alternate sample rates are the same.");
+        s->alternate_sample_rate = 0;
+    }
 
     s->inputs = pa_idxset_new(NULL, NULL);
     s->n_corked = 0;
@@ -756,14 +735,8 @@ static void sink_free(pa_object *o) {
     if (s->proplist)
         pa_proplist_free(s->proplist);
 
-    if (s->ports) {
-        pa_device_port *p;
-
-        while ((p = pa_hashmap_steal_first(s->ports)))
-            pa_device_port_free(p);
-
-        pa_hashmap_free(s->ports, NULL, NULL);
-    }
+    if (s->ports)
+        pa_device_port_hashmap_free(s->ports);
 
     pa_xfree(s);
 }
@@ -890,7 +863,7 @@ void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {
         pa_sink_input_unref(i);
     }
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
 }
 
 /* Called from main context */
@@ -905,7 +878,7 @@ void pa_sink_move_all_fail(pa_queue *q) {
         pa_sink_input_unref(i);
     }
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
 }
 
 /* Called from IO thread context */
@@ -1333,10 +1306,17 @@ pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough)
         uint32_t desired_rate = rate;
         uint32_t default_rate = s->default_sample_rate;
         uint32_t alternate_rate = s->alternate_sample_rate;
+        uint32_t idx;
+        pa_sink_input *i;
         pa_bool_t use_alternate = FALSE;
 
+        if (PA_UNLIKELY(default_rate == alternate_rate)) {
+            pa_log_warn("Default and alternate sample rates are the same.");
+            return FALSE;
+        }
+
         if (PA_SINK_IS_RUNNING(s->state)) {
-            pa_log_info("Cannot update rate, SINK_IS_RUNNING, will keep using %u kHz",
+            pa_log_info("Cannot update rate, SINK_IS_RUNNING, will keep using %u Hz",
                         s->sample_spec.rate);
             return FALSE;
         }
@@ -1374,15 +1354,22 @@ pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough)
             desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
         }
 
-        if (passthrough || pa_sink_used_by(s) == 0) {
-            pa_sink_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */
-        }
+        if (!passthrough && pa_sink_used_by(s) > 0)
+            return FALSE;
+
+        pa_sink_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */
 
         if (s->update_rate(s, desired_rate) == TRUE) {
             /* update monitor source as well */
             if (s->monitor_source && !passthrough)
                 pa_source_update_rate(s->monitor_source, desired_rate, FALSE);
             pa_log_info("Changed sampling rate successfully");
+
+            PA_IDXSET_FOREACH(i, s->inputs, idx) {
+                if (i->state == PA_SINK_INPUT_CORKED)
+                    pa_sink_input_update_rate(i);
+            }
+
             return TRUE;
         }
     }
@@ -1932,13 +1919,7 @@ void pa_sink_set_volume(
         }
 
         pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
-    }
-
-    /* If volume is NULL we synchronize the sink's real and reference
-     * volumes with the stream volumes. If it is not NULL we update
-     * the reference_volume with it. */
 
-    if (volume) {
         if (update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save)) {
             if (pa_sink_flat_volume_enabled(root_sink)) {
                 /* OK, propagate this volume change back to the inputs */
@@ -1951,6 +1932,9 @@ void pa_sink_set_volume(
         }
 
     } else {
+        /* If volume is NULL we synchronize the sink's real and
+         * reference volumes with the stream volumes. */
+
         pa_assert(pa_sink_flat_volume_enabled(root_sink));
 
         /* Ok, let's determine the new real volume */
@@ -3252,7 +3236,7 @@ int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
         return -PA_ERR_NOTIMPLEMENTED;
     }
 
-    if (!s->ports)
+    if (!s->ports || !name)
         return -PA_ERR_NOENTITY;
 
     if (!(port = pa_hashmap_get(s->ports, name)))
@@ -3362,7 +3346,7 @@ pa_bool_t pa_device_init_description(pa_proplist *p) {
 
     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
         if (pa_streq(s, "internal"))
-            d = _("Internal Audio");
+            d = _("Built-in Audio");
 
     if (!d)
         if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
@@ -3378,7 +3362,7 @@ pa_bool_t pa_device_init_description(pa_proplist *p) {
     k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
 
     if (d && k)
-        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, _("%s %s"), d, k);
+        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s %s", d, k);
     else if (d)
         pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);