stream-state: add enforcement for stream state (ie. kill/cork/run streams)
authorJanos Kovacs <jankovac503@gmail.com>
Sun, 3 Feb 2013 22:31:09 +0000 (00:31 +0200)
committerJanos Kovacs <jankovac503@gmail.com>
Sun, 3 Feb 2013 22:31:09 +0000 (00:31 +0200)
murphy/Makefile.am
murphy/discover.c
murphy/murphyif.c
murphy/node.c
murphy/node.h
murphy/stream-state.c [new file with mode: 0644]
murphy/stream-state.h [new file with mode: 0644]

index c4625ed..01ead95 100644 (file)
@@ -22,6 +22,7 @@ module_murphy_ivi_la_SOURCES = \
                        router.c \
                        switch.c \
                        fader.c \
+                       stream-state.c \
                        multiplex.c \
                        loopback.c \
                        volume.c \
index f4eef5e..de37621 100644 (file)
@@ -45,6 +45,7 @@
 #include "classify.h"
 #include "utils.h"
 #include "extapi.h"
+#include "stream-state.h"
 
 #define MAX_CARD_TARGET   4
 #define MAX_NAME_LENGTH   256
@@ -808,7 +809,6 @@ void pa_discover_preroute_sink_input(struct userdata *u,
     }
     else {
         if (pa_streq(mnam, "module-loopback")) {
-
             if (!(node = pa_utils_get_node_from_data(u, mir_input, data))) {
                 pa_log_debug("can't find loopback node for sink-input");
                 return;
@@ -822,8 +822,15 @@ void pa_discover_preroute_sink_input(struct userdata *u,
             }
 
             data->sink = NULL;
+
+            type = pa_classify_guess_stream_node_type(u, pl);
+        }
+        else {
+            type = pa_classify_guess_stream_node_type(u, pl);
+            if (pa_stream_state_start_corked(u, data, type)) {
+                pa_log("start corked");
+            }
         }
-        type = pa_classify_guess_stream_node_type(u, pl);
         pa_utils_set_stream_routing_properties(pl, type, data->sink);
     }
 
index f9e7b31..8353ac4 100644 (file)
@@ -53,6 +53,7 @@
 
 #include "murphyif.h"
 #include "node.h"
+#include "stream-state.h"
 
 #ifdef WITH_RESOURCES
 #define INVALID_ID      (~(uint32_t)0)
@@ -1081,6 +1082,7 @@ static void resource_set_notification(struct userdata *u,
     const char *pid;
     const char *policy;
     mir_node *node;
+    int req;
 
     pa_assert(u);
     pa_assert(table);
@@ -1114,6 +1116,8 @@ static void resource_set_notification(struct userdata *u,
             continue;
         }
 
+        pa_assert(node->implement == mir_stream);
+
         autorel = cautorel->s32;
         state   = cstate->s32;
         grant   = cgrant->s32;
@@ -1138,6 +1142,21 @@ static void resource_set_notification(struct userdata *u,
                      autorel ? "yes":"no",
                      state == RSET_ACQUIRE ? "acquire":"release",
                      grant ? "yes":"no", pid, policy);
+
+        if (pa_streq(policy, "relaxed"))
+            req = PA_STREAM_RUN;
+        else {
+            if (state == RSET_RELEASE)
+                req = PA_STREAM_KILL;
+            else {
+                if (grant)
+                    req = PA_STREAM_RUN;
+                else
+                    req = /* node->localrset ? PA_STREAM_KILL : */ PA_STREAM_BLOCK;
+            }
+        }
+
+        pa_stream_state_change(u, node, req);
     }
 }
 
index f1926c0..cffc755 100644 (file)
@@ -291,15 +291,10 @@ mir_node *mir_node_create(struct userdata *u, mir_node *data)
     mir_router_register_node(u, node);
     
     if (node->implement == mir_stream) {
-        if (node->type >= mir_application_class_begin &&
-            node->type <  mir_application_class_end   &&
-            !node->rsetid && ns->need_resource[node->type])
-        {
+        if (!node->rsetid && mir_node_need_resource(u, node->type))
             pa_murphyif_create_resource_set(u, node);
-        }
-        else {
+        else
             pa_murphyif_add_node(u, node);
-        }
     }
 
     return node;
@@ -356,6 +351,21 @@ mir_node *mir_node_find_by_index(struct userdata *u, uint32_t nodidx)
     return node;
 }
 
+pa_bool_t mir_node_need_resource(struct userdata *u, mir_node_type type)
+{
+    pa_nodeset *ns;
+
+    pa_assert(u);
+    pa_assert_se((ns = u->nodeset));
+    pa_assert(ns->need_resource);
+
+    if (type <  mir_application_class_begin ||
+        type >= mir_application_class_end     )
+        return FALSE;
+
+    return ns->need_resource[type];
+}
+
 int mir_node_print(mir_node *node, char *buf, int len)
 {
     char *p, *e;
index ca79831..c955169 100644 (file)
@@ -172,6 +172,8 @@ void mir_node_destroy(struct userdata *, mir_node *);
 
 mir_node *mir_node_find_by_index(struct userdata *, uint32_t);
 
+pa_bool_t mir_node_need_resource(struct userdata *, mir_node_type);
+
 int mir_node_print(mir_node *, char *, int);
 
 const char *mir_direction_str(mir_direction);
diff --git a/murphy/stream-state.c b/murphy/stream-state.c
new file mode 100644 (file)
index 0000000..717f357
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * module-murphy-ivi -- PulseAudio module for providing audio routing support
+ * Copyright (c) 2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <pulsecore/pulsecore-config.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/source-output.h>
+
+#include "stream-state.h"
+#include "node.h"
+
+static void sink_input_block(pa_sink_input *, pa_bool_t);
+
+pa_bool_t pa_stream_state_start_corked(struct userdata *u,
+                                       pa_sink_input_new_data *data,
+                                       mir_node_type type)
+{
+    if (mir_node_need_resource(u, type)) {
+        data->flags |= PA_SINK_INPUT_START_CORKED;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+void pa_stream_state_change(struct userdata *u, mir_node *node, int req)
+{
+    pa_sink_input *sinp;
+    pa_source_output *sout;
+    pa_core *core;
+
+    pa_assert(u);
+    pa_assert(node);
+    pa_assert(node->implement == mir_stream);
+    pa_assert(node->direction == mir_input || node->direction == mir_output);
+
+    pa_assert_se((core = u->core));
+
+    if (node->direction == mir_input) {
+        sinp = pa_idxset_get_by_index(core->sink_inputs, node->paidx);
+        pa_assert(sinp);
+
+        switch (req) {
+        case PA_STREAM_BLOCK:
+            pa_log("blocking '%s'", node->amname);
+            sink_input_block(sinp, TRUE);
+            break;
+
+        case PA_STREAM_KILL:
+            pa_log("killing '%s'", node->amname);
+            sinp->kill(sinp);
+            break;
+
+        case PA_STREAM_RUN:
+            pa_log("unblock '%s'", node->amname);
+            sink_input_block(sinp, FALSE);
+            break;
+
+        default:
+            pa_assert_not_reached();
+            break;
+        }
+    }
+    else {
+        sinp = pa_idxset_get_by_index(core->source_outputs, node->paidx);
+        pa_assert(sinp);
+    }
+}
+
+
+static void sink_input_block(pa_sink_input *sinp, pa_bool_t block)
+{
+    const char *event;
+    pa_proplist *pl;
+
+    pa_assert(sinp);
+
+    if (sinp->send_event) {
+        if (block)
+            event = PA_STREAM_EVENT_REQUEST_CORK;
+        else
+            event = PA_STREAM_EVENT_REQUEST_UNCORK;
+
+        pl = pa_proplist_new();
+
+        sinp->send_event(sinp, event, pl);
+
+        pa_proplist_free(pl);
+    }
+
+    pa_sink_input_cork(sinp, block);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
diff --git a/murphy/stream-state.h b/murphy/stream-state.h
new file mode 100644 (file)
index 0000000..d885a01
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * module-murphy-ivi -- PulseAudio module for providing audio routing support
+ * Copyright (c) 2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ */
+#ifndef foostreamstatefoo
+#define foostreamstatefoo
+
+#include <sys/types.h>
+
+#include "userdata.h"
+
+#define PA_STREAM_BLOCK   1
+#define PA_STREAM_RUN     0
+#define PA_STREAM_KILL   -1
+
+
+pa_bool_t pa_stream_state_start_corked(struct userdata *,
+                                       pa_sink_input_new_data *,
+                                       mir_node_type);
+void pa_stream_state_change(struct userdata *u, mir_node *, int);
+
+
+#endif  /* foostreamstatefoo */
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */