[pulseaudio-commits] 2 commits - src/Makefile.am src/modules

Arun Raghavan arun at kemper.freedesktop.org
Tue Jul 17 22:24:52 PDT 2012


 src/Makefile.am                     |   13 +++--
 src/modules/alsa/alsa-sink.c        |   17 ------
 src/modules/alsa/alsa-source.c      |   17 ------
 src/modules/alsa/alsa-ucm.c         |   49 ++++++++++++++++++
 src/modules/alsa/alsa-ucm.h         |    6 ++
 src/modules/alsa/module-alsa-card.c |   93 ++++++++++++++++++++++++++++++++++++
 6 files changed, 158 insertions(+), 37 deletions(-)

New commits:
commit 3a92bda554c8f8cdd3257f289369e27c276c8801
Author: Feng Wei <b34248 at freescale.com>
Date:   Tue Jul 17 18:17:21 2012 +0800

    alsa: Catch role matched streams to enable/disable modifier
    
    In UCM basic functions, we only assign intended roles from modifier
    to sink/source, but we don't have a chance to set the ucm modifiers.
    Here we amend the functions so that when roled stream starts or
    stops, we have the following results:
    1. stream will be routed to sink/source specified in modifier by
       module-intended-roles
    2. After that, modifier will be enabled or disabled.
    3. when multiple streams with matched roles of modifier start, only
       the first one will enable the modifier, and when they end, the
       last one will disable the modifier.
    
    Signed-off-by: Feng Wei <wei.feng at freescale.com>
    Signed-off-by: Arun Raghavan <arun.raghavan at collabora.co.uk>

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 8509d8a..544399e 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -904,8 +904,6 @@ static int build_pollfd(struct userdata *u) {
 
 /* Called from IO context */
 static int suspend(struct userdata *u) {
-    const char *mod_name;
-
     pa_assert(u);
     pa_assert(u->pcm_handle);
 
@@ -916,13 +914,6 @@ static int suspend(struct userdata *u) {
     snd_pcm_close(u->pcm_handle);
     u->pcm_handle = NULL;
 
-    if ((mod_name = pa_proplist_gets(u->sink->proplist, PA_ALSA_PROP_UCM_MODIFIER))) {
-        pa_log_info("Disable ucm modifier %s", mod_name);
-
-        if (snd_use_case_set(u->ucm_context->ucm->ucm_mgr, "_dismod", mod_name) < 0)
-            pa_log("Failed to disable ucm modifier %s", mod_name);
-    }
-
     if (u->alsa_rtpoll_item) {
         pa_rtpoll_item_free(u->alsa_rtpoll_item);
         u->alsa_rtpoll_item = NULL;
@@ -1045,20 +1036,12 @@ static int unsuspend(struct userdata *u) {
     pa_bool_t b, d;
     snd_pcm_uframes_t period_size, buffer_size;
     char *device_name = NULL;
-    const char *mod_name;
 
     pa_assert(u);
     pa_assert(!u->pcm_handle);
 
     pa_log_info("Trying resume...");
 
-    if ((mod_name = pa_proplist_gets(u->sink->proplist, PA_ALSA_PROP_UCM_MODIFIER))) {
-        pa_log_info("Enable ucm modifier %s", mod_name);
-
-        if (snd_use_case_set(u->ucm_context->ucm->ucm_mgr, "_enamod", mod_name) < 0)
-            pa_log("Failed to enable ucm modifier %s", mod_name);
-    }
-
     if ((is_iec958(u) || is_hdmi(u)) && pa_sink_is_passthrough(u->sink)) {
         /* Need to open device in NONAUDIO mode */
         int len = strlen(u->device_name) + 8;
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 2957892..94d4a09 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -836,8 +836,6 @@ static int build_pollfd(struct userdata *u) {
 
 /* Called from IO context */
 static int suspend(struct userdata *u) {
-    const char *mod_name;
-
     pa_assert(u);
     pa_assert(u->pcm_handle);
 
@@ -847,13 +845,6 @@ static int suspend(struct userdata *u) {
     snd_pcm_close(u->pcm_handle);
     u->pcm_handle = NULL;
 
-    if ((mod_name = pa_proplist_gets(u->source->proplist, PA_ALSA_PROP_UCM_MODIFIER))) {
-        pa_log_info("Disable ucm modifier %s", mod_name);
-
-        if (snd_use_case_set(u->ucm_context->ucm->ucm_mgr, "_dismod", mod_name) < 0)
-            pa_log("Failed to disable ucm modifier %s", mod_name);
-    }
-
     if (u->alsa_rtpoll_item) {
         pa_rtpoll_item_free(u->alsa_rtpoll_item);
         u->alsa_rtpoll_item = NULL;
@@ -958,20 +949,12 @@ static int unsuspend(struct userdata *u) {
     int err;
     pa_bool_t b, d;
     snd_pcm_uframes_t period_size, buffer_size;
-    const char *mod_name;
 
     pa_assert(u);
     pa_assert(!u->pcm_handle);
 
     pa_log_info("Trying resume...");
 
-    if ((mod_name = pa_proplist_gets(u->source->proplist, PA_ALSA_PROP_UCM_MODIFIER))) {
-        pa_log_info("Enable ucm modifier %s", mod_name);
-
-        if (snd_use_case_set(u->ucm_context->ucm->ucm_mgr, "_enamod", mod_name) < 0)
-            pa_log("Failed to enable ucm modifier %s", mod_name);
-    }
-
     if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
                             SND_PCM_NONBLOCK|
                             SND_PCM_NO_AUTO_RESAMPLE|
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index 87ec293..81f1c2b 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -1561,3 +1561,52 @@ void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context) {
         pa_idxset_free(context->ucm_modifiers, NULL, NULL);
     }
 }
+
+/* Enable the modifier when the first stream with matched role starts */
+void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir) {
+    pa_alsa_ucm_modifier *mod;
+
+    if (!ucm->active_verb)
+        return;
+
+    PA_LLIST_FOREACH(mod, ucm->active_verb->modifiers) {
+        if ((mod->action_direction == dir) && (pa_streq(mod->media_role, role))) {
+            if (mod->enabled_counter == 0) {
+                const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
+
+                pa_log_info("Enable ucm modifier %s", mod_name);
+                if (snd_use_case_set(ucm->ucm_mgr, "_enamod", mod_name) < 0) {
+                    pa_log("Failed to enable ucm modifier %s", mod_name);
+                }
+            }
+
+            mod->enabled_counter++;
+            break;
+        }
+    }
+}
+
+/* Disable the modifier when the last stream with matched role ends */
+void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir) {
+    pa_alsa_ucm_modifier *mod;
+
+    if (!ucm->active_verb)
+        return;
+
+    PA_LLIST_FOREACH(mod, ucm->active_verb->modifiers) {
+        if ((mod->action_direction == dir) && (pa_streq(mod->media_role, role))) {
+
+            mod->enabled_counter--;
+            if (mod->enabled_counter == 0) {
+                const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
+
+                pa_log_info("Disable ucm modifier %s", mod_name);
+                if (snd_use_case_set(ucm->ucm_mgr, "_dismod", mod_name) < 0) {
+                    pa_log("Failed to disable ucm modifier %s", mod_name);
+                }
+            }
+
+            break;
+        }
+    }
+}
diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
index 4c5167f..cdeb469 100644
--- a/src/modules/alsa/alsa-ucm.h
+++ b/src/modules/alsa/alsa-ucm.h
@@ -106,6 +106,9 @@ int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *p
 void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
 void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
 
+void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
+void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
+
 /* UCM - Use Case Manager is available on some audio cards */
 
 struct pa_alsa_ucm_device {
@@ -147,6 +150,9 @@ struct pa_alsa_ucm_modifier {
     /* Non-NULL if the modifier has its own PlaybackPCM/CapturePCM */
     pa_alsa_mapping *playback_mapping;
     pa_alsa_mapping *capture_mapping;
+
+    /* Count how many role matched streams are running */
+    int enabled_counter;
 };
 
 struct pa_alsa_ucm_verb {
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index d9c0596..366f4ba 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -124,6 +124,13 @@ struct userdata {
     /* ucm stuffs */
     pa_bool_t use_ucm;
     pa_alsa_ucm_config ucm;
+
+    /* hooks for modifier action */
+    pa_hook_slot
+        *sink_input_put_hook_slot,
+        *source_output_put_hook_slot,
+        *sink_input_unlink_hook_slot,
+        *source_output_unlink_hook_slot;
 };
 
 struct profile_data {
@@ -459,6 +466,66 @@ static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *de
     pa_xfree(t);
 }
 
+static pa_hook_result_t sink_input_put_hook_callback(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
+    const char *role;
+    pa_sink *sink = sink_input->sink;
+
+    pa_assert(sink);
+
+    role = pa_proplist_gets(sink_input->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new sink input linked to sink of this card */
+    if (role && sink->card == u->card)
+        pa_alsa_ucm_roled_stream_begin(&u->ucm, role, PA_DIRECTION_OUTPUT);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_put_hook_callback(pa_core *c, pa_source_output *source_output, struct userdata *u) {
+    const char *role;
+    pa_source *source = source_output->source;
+
+    pa_assert(source);
+
+    role = pa_proplist_gets(source_output->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new source output linked to source of this card */
+    if (role && source->card == u->card)
+        pa_alsa_ucm_roled_stream_begin(&u->ucm, role, PA_DIRECTION_INPUT);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_unlink_hook_callback(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
+    const char *role;
+    pa_sink *sink = sink_input->sink;
+
+    pa_assert(sink);
+
+    role = pa_proplist_gets(sink_input->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new sink input unlinked from sink of this card */
+    if (role && sink->card == u->card)
+        pa_alsa_ucm_roled_stream_end(&u->ucm, role, PA_DIRECTION_OUTPUT);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_unlink_hook_callback(pa_core *c, pa_source_output *source_output, struct userdata *u) {
+    const char *role;
+    pa_source *source = source_output->source;
+
+    pa_assert(source);
+
+    role = pa_proplist_gets(source_output->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new source output unlinked from source of this card */
+    if (role && source->card == u->card)
+        pa_alsa_ucm_roled_stream_end(&u->ucm, role, PA_DIRECTION_INPUT);
+
+    return PA_HOOK_OK;
+}
+
 int pa__init(pa_module *m) {
     pa_card_new_data data;
     pa_modargs *ma;
@@ -515,6 +582,20 @@ int pa__init(pa_module *m) {
         pa_log_info("Found UCM profiles");
 
         u->profile_set = pa_alsa_ucm_add_profile_set(&u->ucm, &u->core->default_channel_map);
+
+        /* hook start of sink input/source output to enable modifiers */
+        /* A little bit later than module-role-cork */
+        u->sink_input_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) sink_input_put_hook_callback, u);
+        u->source_output_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) source_output_put_hook_callback, u);
+
+        /* hook end of sink input/source output to disable modifiers */
+        /* A little bit later than module-role-cork */
+        u->sink_input_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) sink_input_unlink_hook_callback, u);
+        u->source_output_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) source_output_unlink_hook_callback, u);
     }
     else {
         u->use_ucm = FALSE;
@@ -646,6 +727,18 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         goto finish;
 
+    if (u->sink_input_put_hook_slot)
+        pa_hook_slot_free(u->sink_input_put_hook_slot);
+
+    if (u->sink_input_unlink_hook_slot)
+        pa_hook_slot_free(u->sink_input_unlink_hook_slot);
+
+    if (u->source_output_put_hook_slot)
+        pa_hook_slot_free(u->source_output_put_hook_slot);
+
+    if (u->source_output_unlink_hook_slot)
+        pa_hook_slot_free(u->source_output_unlink_hook_slot);
+
     if (u->mixer_fdl)
         pa_alsa_fdlist_free(u->mixer_fdl);
     if (u->mixer_handle)

commit 801f286dfdf898213a4c6c21eadad55767be6a9c
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Tue Jul 17 13:08:20 2012 +0530

    build: Avoid libstdc++ dep for module-echo-cancel if possible
    
    This moves out the webrtc bits into a small helper library to shield the
    rest of module-echo-cancel from being linked with a C++ linker. This is
    required because automake will _always_ link module-echo-cancel in C++
    mode if any of its deps (even conditional ones) are in C++.

diff --git a/src/Makefile.am b/src/Makefile.am
index 4f6bd4f..65b2743 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1838,10 +1838,17 @@ if HAVE_SPEEX
 module_echo_cancel_la_SOURCES += modules/echo-cancel/speex.c
 endif
 if HAVE_WEBRTC
-module_echo_cancel_la_SOURCES += modules/echo-cancel/webrtc.cc
+# The webrtc code is split off into a helper library to avoid having automake
+# link module-echo-cancel with C++ (which it does if there are any C++ deps,
+# even conditional ones).
+modlibexec_LTLIBRARIES += libwebrtc-util.la
+
+libwebrtc_util_la_SOURCES = modules/echo-cancel/webrtc.cc
+libwebrtc_util_la_CXXFLAGS = $(AM_CXXFLAGS) $(SERVER_CFLAGS) $(WEBRTC_CFLAGS) -DHAVE_WEBRTC=1
+libwebrtc_util_la_LIBADD = $(WEBRTC_LIBS)
+
 module_echo_cancel_la_CFLAGS += -DHAVE_WEBRTC=1
-module_echo_cancel_la_CXXFLAGS = $(AM_CXXFLAGS) $(SERVER_CFLAGS) $(WEBRTC_CFLAGS) -DHAVE_WEBRTC=1
-module_echo_cancel_la_LIBADD += $(WEBRTC_LIBS)
+module_echo_cancel_la_LIBADD += libwebrtc-util.la
 endif
 
 # RTP modules



More information about the pulseaudio-commits mailing list