]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/source.c
Use pa_hashmap_remove_and_free() where appropriate
[pulseaudio] / src / pulsecore / source.c
index 5e59a406b49d26ba342317e7b9abed81c6601f53..67453445717791f5bd8318026b64906e1ccdb45b 100644 (file)
@@ -73,7 +73,7 @@ pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
 
     pa_zero(*data);
     data->proplist = pa_proplist_new();
-    data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     return data;
 }
@@ -133,7 +133,7 @@ void pa_source_new_data_done(pa_source_new_data *data) {
     pa_proplist_free(data->proplist);
 
     if (data->ports)
-        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(data->ports);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
@@ -218,10 +218,16 @@ pa_source* pa_source_new(
     if (data->card)
         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
 
-    pa_device_init_description(data->proplist);
+    pa_device_init_description(data->proplist, data->card);
     pa_device_init_icon(data->proplist, false);
     pa_device_init_intended_roles(data->proplist);
 
+    if (!data->active_port) {
+        pa_device_port *p = pa_device_port_find_best(data->ports);
+        if (p)
+            pa_source_new_data_set_port(data, p->name);
+    }
+
     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
         pa_xfree(s);
         pa_namereg_unregister(core, name);
@@ -288,14 +294,10 @@ pa_source* pa_source_new(
         if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
             s->save_port = data->save_port;
 
-    if (!s->active_port) {
-        void *state;
-        pa_device_port *p;
-
-        PA_HASHMAP_FOREACH(p, s->ports, state)
-            if (!s->active_port || p->priority > s->active_port->priority)
-                s->active_port = p;
-    }
+    /* Hopefully the active port has already been assigned in the previous call
+       to pa_device_port_find_best, but better safe than sorry */
+    if (!s->active_port)
+        s->active_port = pa_device_port_find_best(s->ports);
 
     if (s->active_port)
         s->latency_offset = s->active_port->latency_offset;
@@ -313,7 +315,8 @@ pa_source* pa_source_new(
             0);
 
     s->thread_info.rtpoll = NULL;
-    s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    s->thread_info.outputs = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
+                                                 (pa_free_cb_t) pa_source_output_unref);
     s->thread_info.soft_volume = s->soft_volume;
     s->thread_info.soft_muted = s->muted;
     s->thread_info.state = s->state;
@@ -660,7 +663,7 @@ static void source_free(pa_object *o) {
     pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
 
     pa_idxset_free(s->outputs, NULL);
-    pa_hashmap_free(s->thread_info.outputs, (pa_free_cb_t) pa_source_output_unref);
+    pa_hashmap_free(s->thread_info.outputs);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);
@@ -672,7 +675,7 @@ static void source_free(pa_object *o) {
         pa_proplist_free(s->proplist);
 
     if (s->ports)
-        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(s->ports);
 
     pa_xfree(s);
 }
@@ -967,40 +970,39 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
 }
 
 /* Called from main thread */
-bool pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
-    bool ret = false;
+int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
+    int ret;
     uint32_t desired_rate = rate;
     uint32_t default_rate = s->default_sample_rate;
     uint32_t alternate_rate = s->alternate_sample_rate;
     bool use_alternate = false;
 
     if (rate == s->sample_spec.rate)
-        return true;
+        return 0;
 
     if (!s->update_rate && !s->monitor_of)
-        return false;
+        return -1;
 
     if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough)) {
         pa_log_debug("Default and alternate sample rates are the same.");
-        return false;
+        return -1;
     }
 
     if (PA_SOURCE_IS_RUNNING(s->state)) {
         pa_log_info("Cannot update rate, SOURCE_IS_RUNNING, will keep using %u Hz",
                     s->sample_spec.rate);
-        return false;
+        return -1;
     }
 
     if (s->monitor_of) {
         if (PA_SINK_IS_RUNNING(s->monitor_of->state)) {
             pa_log_info("Cannot update rate, this is a monitor source and the sink is running.");
-            return false;
+            return -1;
         }
     }
 
-    if (PA_UNLIKELY (desired_rate < 8000 ||
-                     desired_rate > PA_RATE_MAX))
-        return false;
+    if (PA_UNLIKELY(!pa_sample_rate_valid(desired_rate)))
+        return -1;
 
     if (!passthrough) {
         pa_assert((default_rate % 4000 == 0) || (default_rate % 11025 == 0));
@@ -1024,10 +1026,10 @@ bool pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
     }
 
     if (desired_rate == s->sample_spec.rate)
-        return false;
+        return -1;
 
     if (!passthrough && pa_source_used_by(s) > 0)
-        return false;
+        return -1;
 
     pa_log_debug("Suspending source %s due to changing the sample rate.", s->name);
     pa_source_suspend(s, true, PA_SUSPEND_INTERNAL);
@@ -1046,7 +1048,7 @@ bool pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
             s->sample_spec.rate = desired_rate;
             ret = pa_sink_update_rate(s->monitor_of, desired_rate, false);
 
-            if (!ret) {
+            if (ret < 0) {
                 /* Changing the sink rate failed, roll back the old rate for
                  * the monitor source. Why did we set the source rate before
                  * calling pa_sink_update_rate(), you may ask. The reason is
@@ -1060,10 +1062,10 @@ bool pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
                 s->sample_spec.rate = old_rate;
             }
         } else
-            ret = false;
+            ret = -1;
     }
 
-    if (ret) {
+    if (ret >= 0) {
         uint32_t idx;
         pa_source_output *o;
 
@@ -1641,7 +1643,7 @@ void pa_source_set_volume(
 
         /* Let's 'push' the reference volume if necessary */
         pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_source->real_volume);
-        /* If the source and it's root don't have the same number of channels, we need to remap */
+        /* If the source and its root don't have the same number of channels, we need to remap */
         if (s != root_source && !pa_channel_map_equal(&s->channel_map, &root_source->channel_map))
             pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
         update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save);
@@ -2068,9 +2070,7 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
                 o->thread_info.direct_on_input = NULL;
             }
 
-            if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
-                pa_source_output_unref(o);
-
+            pa_hashmap_remove_and_free(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index));
             pa_source_invalidate_requested_latency(s, true);
 
             /* In flat volume mode we need to update the volume as
@@ -2160,18 +2160,6 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
             return 0;
         }
 
-        case PA_SOURCE_MESSAGE_DETACH:
-
-            /* Detach all streams */
-            pa_source_detach_within_thread(s);
-            return 0;
-
-        case PA_SOURCE_MESSAGE_ATTACH:
-
-            /* Reattach all streams */
-            pa_source_attach_within_thread(s);
-            return 0;
-
         case PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY: {
 
             pa_usec_t *usec = userdata;
@@ -2288,24 +2276,6 @@ int pa_source_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
     return ret;
 }
 
-/* Called from main thread */
-void pa_source_detach(pa_source *s) {
-    pa_source_assert_ref(s);
-    pa_assert_ctl_context();
-    pa_assert(PA_SOURCE_IS_LINKED(s->state));
-
-    pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_DETACH, NULL, 0, NULL) == 0);
-}
-
-/* Called from main thread */
-void pa_source_attach(pa_source *s) {
-    pa_source_assert_ref(s);
-    pa_assert_ctl_context();
-    pa_assert(PA_SOURCE_IS_LINKED(s->state));
-
-    pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
-}
-
 /* Called from IO thread */
 void pa_source_detach_within_thread(pa_source *s) {
     pa_source_output *o;