stream-manager: Consider virtual streams when a device connection is changed 55/201455/1 accepted/tizen/unified/20190325.070912 submit/tizen/20190322.073406
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 14 Mar 2019 08:01:11 +0000 (17:01 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 14 Mar 2019 08:37:12 +0000 (17:37 +0900)
Null device of a virtual stream is taken into account in case of the device
connection changes.

The device of the virtual stream should always be a null device. In addition,
the available device defined in stream-map.json for virtual stream type is
used to set the audio routing path of internal codec, so these information
must propagate to the audio HAL properly.

[Version] 11.1.35
[Issue type] Bug fix

Change-Id: Idb18334db04ed7d28ca657b1e58a4bb263e6af73
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/stream-manager.c

index 216a3b9..96f254c 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          11.1.34
+Version:          11.1.35
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 6486172..d2f931f 100644 (file)
@@ -946,7 +946,7 @@ static bool check_name_is_vstream(void *stream, stream_type_t type, bool is_new_
 
     if (pa_safe_streq(name, VIRTUAL_STREAM_NAME)) {
         ret = true;
-        pa_log_info("name is [%s]", name);
+        pa_log_debug("name is [%s]", name);
     }
 
     return ret;
@@ -2625,9 +2625,13 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_
                     if ((cur_device_type = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) {
                         is_available_device_for_auto_route(m, route_type, cur_device_type, device_type, role, stream_type, &available);
                         if (available) {
-                            pa_sink_input_move_to(s, sink, false);
-                            pa_log_debug("  -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)",
-                                         s, ((pa_sink_input*)s)->index, sink, sink->name, device_type);
+                            if (check_name_is_vstream(s, STREAM_SINK_INPUT, false)) {
+                                pa_log_debug("  -- *** keep null sink for a virtual stream");
+                            } else {
+                                pa_sink_input_move_to(s, sink, false);
+                                pa_log_debug("  -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)",
+                                            s, ((pa_sink_input*)s)->index, sink, sink->name, device_type);
+                            }
                         }
                     } else
                         pa_log_error("  -- could not find current device type for s->sink(%p)", ((pa_sink_input*)s)->sink);
@@ -2635,9 +2639,13 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_
                     if ((cur_device_type = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) {
                         is_available_device_for_auto_route(m, route_type, cur_device_type, device_type, role, stream_type, &available);
                         if (available) {
-                            pa_source_output_move_to(s, source, false);
-                            pa_log_debug("  -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)",
-                                         s, ((pa_source_output*)s)->index, source, source->name, device_type);
+                            if (check_name_is_vstream(s, STREAM_SOURCE_OUTPUT, false)) {
+                                pa_log_debug("  -- *** keep null source for a virtual stream");
+                            } else {
+                                pa_source_output_move_to(s, source, false);
+                                pa_log_debug("  -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)",
+                                            s, ((pa_source_output*)s)->index, source, source->name, device_type);
+                            }
                         }
                     } else
                         pa_log_error("  -- could not find current device type for s->source(%p)", ((pa_source_output*)s)->source);
@@ -2651,7 +2659,7 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_
                 }
             } else if (!is_connected) {
                 /* DISCONNECTED: find a connected device that has the next priority */
-                if ((sink && (sink == ((pa_sink_input*)s)->sink))) {
+                if (sink && ((sink == ((pa_sink_input*)s)->sink) || check_name_is_vstream(s, STREAM_SINK_INPUT, false))) {
                     if (!is_active_device_of_stream(s, stream_type, device_type))
                         continue;
                     find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device);
@@ -2664,10 +2672,14 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_
                             /* trigger to update routing path if the next device uses internal audio codec */
                             process_stream_as_device_change_for_auto_route(m, s, stream_type, is_connected, next_device);
 
-                            pa_sink_input_move_to(s, next_sink, false);
-                            pa_log_debug("  -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)",
-                                         s, ((pa_sink_input*)s)->index, next_sink, next_sink->name, new_device_type);
+                            if (check_name_is_vstream(s, STREAM_SINK_INPUT, false)) {
+                                pa_log_debug("  -- *** keep null sink for a virtual stream");
+                            } else {
+                                pa_sink_input_move_to(s, next_sink, false);
+                                pa_log_debug("  -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)",
+                                            s, ((pa_sink_input*)s)->index, next_sink, next_sink->name, new_device_type);
                             }
+                        }
                     }
 
                     if (!next_device || !next_sink) {
@@ -2676,7 +2688,7 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_
                             s, ((pa_sink_input*)s)->index, null_sink, null_sink->name);
                     }
 
-                } else if (source && (source == ((pa_source_output*)s)->source)) {
+                } else if (source && ((source == ((pa_source_output*)s)->source) || check_name_is_vstream(s, STREAM_SOURCE_OUTPUT, false))) {
                     if (!is_active_device_of_stream(s, stream_type, device_type))
                         continue;
                     find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device);
@@ -2690,10 +2702,14 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_
                             if (next_source->use_internal_codec)
                                 process_stream_as_device_change_for_auto_route(m, s, stream_type, is_connected, next_device);
 
-                            pa_source_output_move_to(s, next_source, false);
-                            pa_log_warn("  -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)",
-                                         s, ((pa_source_output*)s)->index, next_source, next_source->name, new_device_type);
+                            if (check_name_is_vstream(s, STREAM_SOURCE_OUTPUT, false)) {
+                                pa_log_debug("  -- *** keep null source for a virtual stream");
+                            } else {
+                                pa_source_output_move_to(s, next_source, false);
+                                pa_log_warn("  -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)",
+                                             s, ((pa_source_output*)s)->index, next_source, next_source->name, new_device_type);
                             }
+                        }
                     }
                     if (!next_device || !next_source) {
                         pa_source_output_move_to(s, null_source, false);
@@ -2881,6 +2897,8 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi
     pa_sink *sink = NULL;
     pa_source *source = NULL;
     pa_sink_input *si = NULL;
+    pa_sink_input *highest_prior_si = NULL;
+    pa_source_output *highest_prior_so = NULL;
 
     pa_assert(c);
     pa_assert(data);
@@ -2951,10 +2969,11 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi
     }
 
     /* If the route type is AUTO SERIES, notify again */
-    if ((device_direction & DM_DEVICE_DIRECTION_IN) && m->cur_highest_priority.source_output &&
-        !get_route_type(m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT, false, &route_type)) {
+    highest_prior_so = m->cur_highest_priority.source_output;
+    if ((device_direction & DM_DEVICE_DIRECTION_IN) && highest_prior_so &&
+        !get_route_type(highest_prior_so, STREAM_SOURCE_OUTPUT, false, &route_type)) {
         if (IS_AUTO_ROUTE_TYPE_SERIES(route_type) && use_internal_codec) {
-            PA_IDXSET_FOREACH(s, m->cur_highest_priority.source_output->source->outputs, s_idx) {
+            PA_IDXSET_FOREACH(s, highest_prior_so->source->outputs, s_idx) {
                 if (!data->is_connected && !get_route_type(s, STREAM_SOURCE_OUTPUT, false, &route_type) &&
                     ((route_type == STREAM_ROUTE_TYPE_AUTO) || (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED))) {
                     /* remove activated device info. if it has the AUTO route type */
@@ -2963,20 +2982,22 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi
                         pa_proplist_sets(GET_STREAM_PROPLIST(s, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, ACTIVE_DEV_REMOVED);
                 }
             }
-            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, false, m->cur_highest_priority.source_output);
-            if (!((pa_source_output*)(m->cur_highest_priority.source_output))->source->use_internal_codec) {
+            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, false, highest_prior_so);
+            if (!highest_prior_so->source->use_internal_codec &&
+                !check_name_is_vstream(highest_prior_so, STREAM_SOURCE_OUTPUT, false)) {
                 /* If the source of the cur_highest_priority stream uses external codec, it should be updated.
                  * As only the process_stream(PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED)
                  * can update the cur_highest_priority, call it here */
-                process_stream(m, m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
+                process_stream(m, highest_prior_so, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
             }
         }
     }
 
-    if ((device_direction & DM_DEVICE_DIRECTION_OUT) && m->cur_highest_priority.sink_input &&
-        !get_route_type(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT, false, &route_type)) {
+    highest_prior_si = m->cur_highest_priority.sink_input;
+    if ((device_direction & DM_DEVICE_DIRECTION_OUT) && highest_prior_si &&
+        !get_route_type(highest_prior_si, STREAM_SINK_INPUT, false, &route_type)) {
         if (IS_AUTO_ROUTE_TYPE_SERIES(route_type) && use_internal_codec) {
-            PA_IDXSET_FOREACH(s, m->cur_highest_priority.sink_input->sink->inputs, s_idx) {
+            PA_IDXSET_FOREACH(s, highest_prior_si->sink->inputs, s_idx) {
                 if (!data->is_connected && !get_route_type(s, STREAM_SINK_INPUT, false, &route_type) &&
                     ((route_type == STREAM_ROUTE_TYPE_AUTO) || (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED))) {
                     /* remove activated device info. if it has the AUTO route type */
@@ -2985,16 +3006,18 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi
                         pa_proplist_sets(GET_STREAM_PROPLIST(s, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, ACTIVE_DEV_REMOVED);
                 }
             }
-            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, m->cur_highest_priority.sink_input);
+            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, highest_prior_si);
             if (((route_type == STREAM_ROUTE_TYPE_AUTO) || (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED)) &&
-               (!((pa_sink_input*)(m->cur_highest_priority.sink_input))->sink->use_internal_codec) && !is_filter_apply_stream(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT)) {
+                !highest_prior_si->sink->use_internal_codec &&
+                !check_name_is_vstream(highest_prior_si, STREAM_SINK_INPUT, false) &&
+                !is_filter_apply_stream(highest_prior_si, STREAM_SINK_INPUT)) {
                 /* If the sink of the cur_highest_priority stream uses external codec, it should be updated.
                  * As only the process_stream(PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED)
                  * can update the cur_highest_priority, call it here */
-                process_stream(m, m->cur_highest_priority.sink_input, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
+                process_stream(m, highest_prior_si, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
             }
         } else if (route_type == STREAM_ROUTE_TYPE_AUTO_ALL)
-            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, m->cur_highest_priority.sink_input);
+            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, highest_prior_si);
     }
 
     if (m->on_call) {