2f5a35c60c1f9bfd924f60c97f2fab6f0f16e94e
[scm/bb/meta-tizen.git] / recipes-multimedia / pulseaudio / pulseaudio_5.0 / 0062-sink-source-Assign-to-reference_volume-from-only-one.patch
1 From: Tanu Kaskinen <tanu.kaskinen@linux.intel.com>
2 Date: Mon, 7 Apr 2014 12:20:58 +0300
3 Subject: sink, source: Assign to reference_volume from only one place
4
5 Forcing all reference volume changes to go through
6 set_reference_volume_direct() makes it easier to check where the
7 reference volume is changed, and it also allows us to have only one
8 place where notifications for changed reference volume are sent.
9
10 Change-Id: I2e769b8a2b0d7031a02446dead8ca2e0c3402751
11 Signed-off-by: Jaska Uimonen <jaska.uimonen@intel.com>
12 ---
13  src/pulsecore/sink-input.c    | 23 ++++++++++-------------
14  src/pulsecore/sink.c          | 30 ++++++++++++++++++++++++++----
15  src/pulsecore/sink.h          |  7 +++++++
16  src/pulsecore/source-output.c | 23 ++++++++++-------------
17  src/pulsecore/source.c        | 30 ++++++++++++++++++++++++++----
18  src/pulsecore/source.h        |  7 +++++++
19  6 files changed, 86 insertions(+), 34 deletions(-)
20
21 diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
22 index d0509b3..6596eeb 100644
23 --- a/src/pulsecore/sink-input.c
24 +++ b/src/pulsecore/sink-input.c
25 @@ -1716,6 +1716,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
26   * their volume - this function does all that by using recursion. */
27  static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
28      pa_cvolume old_volume;
29 +    pa_cvolume new_volume;
30  
31      pa_assert(i);
32      pa_assert(dest);
33 @@ -1787,25 +1788,21 @@ static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
34           *         (sinks that use volume sharing should always have
35           *          soft_volume of 0 dB) */
36  
37 -        old_volume = i->origin_sink->reference_volume;
38 -
39 -        i->origin_sink->reference_volume = root_sink->reference_volume;
40 -        pa_cvolume_remap(&i->origin_sink->reference_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
41 +        new_volume = root_sink->reference_volume;
42 +        pa_cvolume_remap(&new_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
43 +        pa_sink_set_reference_volume_direct(i->origin_sink, &new_volume);
44  
45          i->origin_sink->real_volume = root_sink->real_volume;
46          pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
47  
48          pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
49  
50 -        /* Notify others about the changed sink volume. If you wonder whether
51 -         * i->origin_sink->set_volume() should be called somewhere, that's not
52 -         * the case, because sinks that use volume sharing shouldn't have any
53 -         * internal volume that set_volume() would update. If you wonder
54 -         * whether the thread_info variables should be synced, yes, they
55 -         * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
56 -         * handler. */
57 -        if (!pa_cvolume_equal(&i->origin_sink->reference_volume, &old_volume))
58 -            pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, i->origin_sink->index);
59 +        /* If you wonder whether i->origin_sink->set_volume() should be called
60 +         * somewhere, that's not the case, because sinks that use volume
61 +         * sharing shouldn't have any internal volume that set_volume() would
62 +         * update. If you wonder whether the thread_info variables should be
63 +         * synced, yes, they should, and it's done by the
64 +         * PA_SINK_MESSAGE_FINISH_MOVE message handler. */
65  
66          /* Recursively update origin sink inputs. */
67          PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
68 diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
69 index 11a6e77..e00dce5 100644
70 --- a/src/pulsecore/sink.c
71 +++ b/src/pulsecore/sink.c
72 @@ -2017,13 +2017,11 @@ static bool update_reference_volume(pa_sink *s, const pa_cvolume *v, const pa_ch
73      pa_cvolume_remap(&volume, channel_map, &s->channel_map);
74  
75      reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
76 -    s->reference_volume = volume;
77 +    pa_sink_set_reference_volume_direct(s, &volume);
78  
79      s->save_volume = (!reference_volume_changed && s->save_volume) || save;
80  
81 -    if (reference_volume_changed)
82 -        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
83 -    else if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
84 +    if (!reference_volume_changed && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
85          /* If the root sink's volume doesn't change, then there can't be any
86           * changes in the other sinks in the sink tree either.
87           *
88 @@ -3905,3 +3903,27 @@ done:
89  
90      return out_formats;
91  }
92 +
93 +/* Called from the main thread. */
94 +void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
95 +    pa_cvolume old_volume;
96 +    char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
97 +    char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
98 +
99 +    pa_assert(s);
100 +    pa_assert(volume);
101 +
102 +    old_volume = s->reference_volume;
103 +
104 +    if (pa_cvolume_equal(volume, &old_volume))
105 +        return;
106 +
107 +    s->reference_volume = *volume;
108 +    pa_log_debug("The reference volume of sink %s changed from %s to %s.", s->name,
109 +                 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
110 +                                            s->flags & PA_SINK_DECIBEL_VOLUME),
111 +                 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
112 +                                            s->flags & PA_SINK_DECIBEL_VOLUME));
113 +
114 +    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
115 +}
116 diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
117 index 576f34b..41a439b 100644
118 --- a/src/pulsecore/sink.h
119 +++ b/src/pulsecore/sink.h
120 @@ -512,6 +512,13 @@ void pa_sink_invalidate_requested_latency(pa_sink *s, bool dynamic);
121  
122  pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s);
123  
124 +/* Called from the main thread, from sink-input.c only. The normal way to set
125 + * the sink reference volume is to call pa_sink_set_volume(), but the flat
126 + * volume logic in sink-input.c needs also a function that doesn't do all the
127 + * extra stuff that pa_sink_set_volume() does. This function simply sets
128 + * s->reference_volume and fires change notifications. */
129 +void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume);
130 +
131  /* Verify that we called in IO context (aka 'thread context), or that
132   * the sink is not yet set up, i.e. the thread not set up yet. See
133   * pa_assert_io_context() in thread-mq.h for more information. */
134 diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
135 index b12758a..169d98d 100644
136 --- a/src/pulsecore/source-output.c
137 +++ b/src/pulsecore/source-output.c
138 @@ -1263,6 +1263,7 @@ int pa_source_output_start_move(pa_source_output *o) {
139   * their volume - this function does all that by using recursion. */
140  static void update_volume_due_to_moving(pa_source_output *o, pa_source *dest) {
141      pa_cvolume old_volume;
142 +    pa_cvolume new_volume;
143  
144      pa_assert(o);
145      pa_assert(dest);
146 @@ -1336,25 +1337,21 @@ static void update_volume_due_to_moving(pa_source_output *o, pa_source *dest) {
147           *         (sources that use volume sharing should always have
148           *          soft_volume of 0 dB) */
149  
150 -        old_volume = o->destination_source->reference_volume;
151 -
152 -        o->destination_source->reference_volume = root_source->reference_volume;
153 -        pa_cvolume_remap(&o->destination_source->reference_volume, &root_source->channel_map, &o->destination_source->channel_map);
154 +        new_volume = root_source->reference_volume;
155 +        pa_cvolume_remap(&new_volume, &root_source->channel_map, &o->destination_source->channel_map);
156 +        pa_source_set_reference_volume_direct(o->destination_source, &new_volume);
157  
158          o->destination_source->real_volume = root_source->real_volume;
159          pa_cvolume_remap(&o->destination_source->real_volume, &root_source->channel_map, &o->destination_source->channel_map);
160  
161          pa_assert(pa_cvolume_is_norm(&o->destination_source->soft_volume));
162  
163 -        /* Notify others about the changed source volume. If you wonder whether
164 -         * o->destination_source->set_volume() should be called somewhere, that's not
165 -         * the case, because sources that use volume sharing shouldn't have any
166 -         * internal volume that set_volume() would update. If you wonder
167 -         * whether the thread_info variables should be synced, yes, they
168 -         * should, and it's done by the PA_SOURCE_MESSAGE_FINISH_MOVE message
169 -         * handler. */
170 -        if (!pa_cvolume_equal(&o->destination_source->reference_volume, &old_volume))
171 -            pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, o->destination_source->index);
172 +        /* If you wonder whether o->destination_source->set_volume() should be
173 +         * called somewhere, that's not the case, because sources that use
174 +         * volume sharing shouldn't have any internal volume that set_volume()
175 +         * would update. If you wonder whether the thread_info variables should
176 +         * be synced, yes, they should, and it's done by the
177 +         * PA_SOURCE_MESSAGE_FINISH_MOVE message handler. */
178  
179          /* Recursively update origin source outputs. */
180          PA_IDXSET_FOREACH(destination_source_output, o->destination_source->outputs, idx)
181 diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
182 index d39193f..f58bb44 100644
183 --- a/src/pulsecore/source.c
184 +++ b/src/pulsecore/source.c
185 @@ -1562,13 +1562,11 @@ static bool update_reference_volume(pa_source *s, const pa_cvolume *v, const pa_
186      pa_cvolume_remap(&volume, channel_map, &s->channel_map);
187  
188      reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
189 -    s->reference_volume = volume;
190 +    pa_source_set_reference_volume_direct(s, &volume);
191  
192      s->save_volume = (!reference_volume_changed && s->save_volume) || save;
193  
194 -    if (reference_volume_changed)
195 -        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
196 -    else if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
197 +    if (!reference_volume_changed && !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
198          /* If the root source's volume doesn't change, then there can't be any
199           * changes in the other source in the source tree either.
200           *
201 @@ -2899,3 +2897,27 @@ done:
202  
203      return out_formats;
204  }
205 +
206 +/* Called from the main thread. */
207 +void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volume) {
208 +    pa_cvolume old_volume;
209 +    char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
210 +    char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
211 +
212 +    pa_assert(s);
213 +    pa_assert(volume);
214 +
215 +    old_volume = s->reference_volume;
216 +
217 +    if (pa_cvolume_equal(volume, &old_volume))
218 +        return;
219 +
220 +    s->reference_volume = *volume;
221 +    pa_log_debug("The reference volume of source %s changed from %s to %s.", s->name,
222 +                 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
223 +                                            s->flags & PA_SOURCE_DECIBEL_VOLUME),
224 +                 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
225 +                                            s->flags & PA_SOURCE_DECIBEL_VOLUME));
226 +
227 +    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
228 +}
229 diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
230 index 5c74a51..6318595 100644
231 --- a/src/pulsecore/source.h
232 +++ b/src/pulsecore/source.h
233 @@ -426,6 +426,13 @@ bool pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next);
234  void pa_source_invalidate_requested_latency(pa_source *s, bool dynamic);
235  pa_usec_t pa_source_get_latency_within_thread(pa_source *s);
236  
237 +/* Called from the main thread, from source-output.c only. The normal way to
238 + * set the source reference volume is to call pa_source_set_volume(), but the
239 + * flat volume logic in source-output.c needs also a function that doesn't do
240 + * all the extra stuff that pa_source_set_volume() does. This function simply
241 + * sets s->reference_volume and fires change notifications. */
242 +void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volume);
243 +
244  #define pa_source_assert_io_context(s) \
245      pa_assert(pa_thread_mq_get() || !PA_SOURCE_IS_LINKED((s)->state))
246