tizenaudio-echo-cancel: Find reference sink by proplist 21/272921/6 accepted/tizen/unified/20220418.141309 submit/tizen/20220413.095656
authorJaechul Lee <jcsing.lee@samsung.com>
Mon, 28 Mar 2022 02:20:50 +0000 (11:20 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Thu, 31 Mar 2022 06:55:58 +0000 (15:55 +0900)
[Version] 15.0.9
[Issue Type] New Feature

Change-Id: I28c7c2cb5a569f7f1159ee1a6aa2a4ede54ed0cc
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/echo-cancel/module-tizenaudio-echo-cancel.c
src/stream-manager-priv.h
src/stream-manager.c

index 28cd7d8..38eda7d 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          15.0.8
+Version:          15.0.9
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index f6571d1..2f95314 100644 (file)
@@ -123,7 +123,7 @@ static int pa_processor_get_method(pa_source_output *o, const char *default_meth
     pa_assert(method);
     pa_assert(default_method);
 
-    requested = pa_proplist_gets(o->proplist, "echo_cancel");
+    requested = pa_proplist_gets(o->proplist, PA_PROP_MEDIA_ECHO_CANCEL_METHOD);
     if (!requested)
         return -1;
 
@@ -567,14 +567,14 @@ static int process_msg(
 
 static pa_hook_result_t source_output_new_cb(pa_core *c, pa_source_output_new_data *data, void *userdata) {
     struct userdata *u = (struct userdata *)userdata;
-    const char *echo_cancel;
+    const char *method;
 
     pa_assert(c);
     pa_assert(u);
     pa_assert(data);
 
-    echo_cancel = pa_proplist_gets(data->proplist, "echo_cancel");
-    if (!echo_cancel)
+    method = pa_proplist_gets(data->proplist, PA_PROP_MEDIA_ECHO_CANCEL_METHOD);
+    if (!method)
         return PA_HOOK_OK;
 
     if (CHECK_COUNT_SOURCE_OUTPUT_AEC(u) > 0) {
@@ -589,24 +589,28 @@ static pa_hook_result_t source_output_new_cb(pa_core *c, pa_source_output_new_da
     return PA_HOOK_OK;
 }
 
-static int find_reference_sink(struct userdata *u, pa_source_output *o) {
-    const char *sink_name;
+static pa_sink *find_reference_sink_by_proplist(pa_core *c, pa_proplist *p) {
+    const char *ref_idx;
+    int32_t idx;
+    pa_sink *s;
 
-    pa_assert(u);
-    pa_assert(o);
+    pa_assert(c);
+    pa_assert(p);
 
-    sink_name = pa_proplist_gets(o->proplist, "reference_sink");
-    if (!sink_name)
-        return -1;
+    ref_idx = pa_proplist_gets(p, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_SINK);
+    if (!ref_idx)
+        return NULL;
 
-    u->sink = pa_namereg_get(u->core, sink_name, PA_NAMEREG_SINK);
-    if (!u->sink)
-        return -1;
+    if (pa_atoi(ref_idx, &idx) < 0)
+        return NULL;
 
-    pa_log_debug("Requested AEC source(%s), sink(%s)",
-                    u->source->name, u->sink ? u->sink->name : "");
+    s = pa_idxset_get_by_index(c->sinks, idx);
+    if (!s)
+        return NULL;
 
-    return 0;
+    pa_log_info("Found reference sink(%d, %s)", s->index, s->name);
+
+    return s;
 }
 
 static int check_latency_validation(struct userdata *u, pa_sink *sink, pa_source *source) {
@@ -676,7 +680,8 @@ static pa_hook_result_t source_output_put_cb(pa_core *c, pa_source_output *o, vo
     }
 
     u->source = o->source;
-    if (find_reference_sink(u, o)) {
+    u->sink = find_reference_sink_by_proplist(c, o->proplist);
+    if (!u->sink) {
         pa_log_error("Can't find reference sink for AEC");
         goto fail;
     }
@@ -924,6 +929,8 @@ int pa__init(pa_module *m) {
         pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST],
                     PA_HOOK_EARLY, (pa_hook_cb_t) source_output_unlink_post_cb, u);
 
+    /* source_output_new_cb must be called after new_cb callback in stream manager.
+     * because stream-manager converts the device_id to the index of the sink */
     u->source_output_new_slot =
         pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW],
                     PA_HOOK_LATE, (pa_hook_cb_t) source_output_new_cb, u);
index e3d9298..b7c019f 100644 (file)
@@ -76,6 +76,7 @@ typedef enum _process_command_type {
     PROCESS_COMMAND_REMOVE_STREAM,
     PROCESS_COMMAND_UPDATE_BUFFER_ATTR,
     PROCESS_COMMAND_APPLY_FILTER,
+    PROCESS_COMMAND_SET_AEC_REFERENCE_DEVICE,
 } process_command_type_t;
 
 typedef enum _notify_command_type {
index e50e13b..36351ed 100644 (file)
@@ -93,6 +93,7 @@ static const char* process_command_type_str[] = {
     [PROCESS_COMMAND_REMOVE_STREAM] = "REMOVE_STREAM",
     [PROCESS_COMMAND_UPDATE_BUFFER_ATTR] = "UPDATE_BUFFER_ATTR",
     [PROCESS_COMMAND_APPLY_FILTER] = "APPLY_FILTER",
+    [PROCESS_COMMAND_SET_AEC_REFERENCE_DEVICE] = "SET_AEC_REFERENCE",
 };
 
 static const char* notify_command_type_str[] = {
@@ -2487,6 +2488,44 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea
         }
         break;
     }
+    case PROCESS_COMMAND_SET_AEC_REFERENCE_DEVICE: {
+        int32_t id;
+        pa_tz_device *device;
+        const char *ref_device;
+        pa_proplist *p = ((pa_source_output_new_data*)stream)->proplist;
+        pa_sink *s;
+
+        result = PROCESS_STREAM_RESULT_SKIP;
+
+        ref_device = pa_proplist_gets(p, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_DEVICE);
+        if (!ref_device)
+            break;
+
+        result = PROCESS_STREAM_RESULT_STOP;
+
+        if (pa_atoi(ref_device, &id) < 0) {
+            pa_log_error("Can't convert ref_device(%s) to integer", ref_device);
+            break;
+        }
+
+        device = pa_device_manager_get_device_by_id(m->dm, id);
+        if (!device) {
+            pa_log_error("Can't find device by id(%d)", id);
+            break;
+        }
+
+        s = pa_tz_device_get_sink(device, "normal");
+        if (!s) {
+            pa_log_error("Can't find sink by device");
+            break;
+        }
+
+        pa_proplist_setf(p, PA_PROP_MEDIA_ECHO_CANCEL_REFERENCE_SINK, "%d", s->index);
+
+        result = PROCESS_STREAM_RESULT_OK;
+
+        break;
+    }
     }
 
 finish:
@@ -2733,6 +2772,7 @@ static pa_hook_result_t source_output_new_cb(pa_core *core, pa_source_output_new
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_UPDATE_BUFFER_ATTR, true);
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_UPDATE_VOLUME, true);
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, true);
+    process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_SET_AEC_REFERENCE_DEVICE, true);
 
     return PA_HOOK_OK;
 }