120
137
pa_resampler *resampler = NULL;
121
138
char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
122
139
pa_channel_map original_cm;
127
if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data) < 0)
130
pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
133
data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK, TRUE);
135
pa_return_null_if_fail(data->sink);
136
pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_UNLINKED);
137
pa_return_null_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED));
147
pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
149
if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
152
pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
155
data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
156
data->save_sink = FALSE;
159
pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
160
pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
161
pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
139
163
if (!data->sample_spec_is_set)
140
164
data->sample_spec = data->sink->sample_spec;
142
pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec));
166
pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
144
168
if (!data->channel_map_is_set) {
145
if (data->sink->channel_map.channels == data->sample_spec.channels)
169
if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
146
170
data->channel_map = data->sink->channel_map;
148
172
pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
151
pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
152
pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
175
pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
176
pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
154
178
if (!data->volume_is_set) {
155
179
pa_cvolume_reset(&data->volume, data->sample_spec.channels);
180
data->volume_is_absolute = FALSE;
181
data->save_volume = FALSE;
158
pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
159
pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
184
pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
185
pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
187
if (!data->volume_factor_is_set)
188
pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
190
pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID);
191
pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
161
193
if (!data->muted_is_set)
162
194
data->muted = FALSE;
221
257
i->state = PA_SINK_INPUT_INIT;
222
258
i->flags = flags;
223
259
i->proplist = pa_proplist_copy(data->proplist);
224
i->driver = pa_xstrdup(data->driver);
260
i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
225
261
i->module = data->module;
226
262
i->sink = data->sink;
227
263
i->client = data->client;
229
i->resample_method = data->resample_method;
265
i->requested_resample_method = data->resample_method;
266
i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
230
267
i->sample_spec = data->sample_spec;
231
268
i->channel_map = data->channel_map;
233
i->volume = data->volume;
270
if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
271
/* When the 'absolute' bool is not set then we'll treat the volume
272
* as relative to the sink volume even in flat volume mode */
274
pa_cvolume v = data->sink->reference_volume;
275
pa_cvolume_remap(&v, &data->sink->channel_map, &data->channel_map);
276
pa_sw_cvolume_multiply(&i->virtual_volume, &data->volume, &v);
278
i->virtual_volume = data->volume;
280
i->volume_factor = data->volume_factor;
281
pa_cvolume_init(&i->soft_volume);
282
memset(i->relative_volume, 0, sizeof(i->relative_volume));
283
i->save_volume = data->save_volume;
284
i->save_sink = data->save_sink;
285
i->save_muted = data->save_muted;
234
287
i->muted = data->muted;
236
289
if (data->sync_base) {
433
511
pa_assert(i->process_rewind);
434
512
pa_assert(i->kill);
436
i->thread_info.volume = i->volume;
437
i->thread_info.muted = i->muted;
439
514
state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
441
516
update_n_corked(i, state);
442
517
i->state = state;
519
/* We might need to update the sink's volume if we are in flat volume mode. */
520
if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
521
pa_cvolume new_volume;
522
pa_sink_update_flat_volume(i->sink, &new_volume);
523
pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE);
525
pa_sink_input_set_relative_volume(i, &i->virtual_volume);
527
i->thread_info.soft_volume = i->soft_volume;
528
i->thread_info.muted = i->muted;
444
530
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
446
pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
447
pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
532
pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
533
pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
535
pa_sink_update_status(i->sink);
450
538
/* Called from main context */
758
831
pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
759
832
pa_sink_input_assert_ref(i);
761
if (PA_SINK_INPUT_IS_LINKED(i->state))
834
if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
762
835
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
764
/* If this sink input is not realized yet, we have to touch
765
* the thread info data directly */
767
i->thread_info.requested_sink_latency = usec;
839
/* If this sink input is not realized yet or we are being moved,
840
* we have to touch the thread info data directly */
843
if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
844
usec = i->sink->fixed_latency;
846
if (usec != (pa_usec_t) -1) {
847
pa_usec_t min_latency, max_latency;
848
pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
849
usec = PA_CLAMP(usec, min_latency, max_latency);
853
i->thread_info.requested_sink_latency = usec;
772
858
/* Called from main context */
773
859
pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
776
860
pa_sink_input_assert_ref(i);
778
if (PA_SINK_INPUT_IS_LINKED(i->state))
862
if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
779
864
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
781
/* If this sink input is not realized yet, we have to touch
782
* the thread info data directly */
783
usec = i->thread_info.requested_sink_latency;
868
/* If this sink input is not realized yet or we are being moved,
869
* we have to touch the thread info data directly */
871
return i->thread_info.requested_sink_latency;
788
874
/* Called from main context */
789
void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
875
void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
790
878
pa_sink_input_assert_ref(i);
791
879
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
792
880
pa_assert(volume);
794
if (pa_cvolume_equal(&i->volume, volume))
881
pa_assert(pa_cvolume_valid(volume));
882
pa_assert(pa_cvolume_compatible(volume, &i->sample_spec));
884
if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
885
v = i->sink->reference_volume;
886
pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
887
volume = pa_sw_cvolume_multiply(&v, &v, volume);
890
if (pa_cvolume_equal(volume, &i->virtual_volume))
799
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &i->volume, 0, NULL) == 0);
800
pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
803
/* Called from main context */
804
const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) {
805
pa_sink_input_assert_ref(i);
806
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
811
/* Called from main context */
812
void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute) {
893
i->virtual_volume = *volume;
894
i->save_volume = save;
896
if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
897
pa_cvolume new_volume;
899
/* We are in flat volume mode, so let's update all sink input
900
* volumes and update the flat volume of the sink */
902
pa_sink_update_flat_volume(i->sink, &new_volume);
903
pa_sink_set_volume(i->sink, &new_volume, FALSE, TRUE, FALSE);
907
/* OK, we are in normal volume mode. The volume only affects
909
pa_sink_input_set_relative_volume(i, volume);
911
/* Hooks have the ability to play games with i->soft_volume */
912
pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);
914
/* Copy the new soft_volume to the thread_info struct */
915
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
918
/* The virtual volume changed, let's tell people so */
919
pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
922
/* Called from main context */
923
pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
924
pa_sink_input_assert_ref(i);
925
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
927
if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
928
pa_cvolume v = i->sink->reference_volume;
929
pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
930
pa_sw_cvolume_divide(volume, &i->virtual_volume, &v);
932
*volume = i->virtual_volume;
937
/* Called from main context */
938
pa_cvolume *pa_sink_input_get_relative_volume(pa_sink_input *i, pa_cvolume *v) {
941
pa_sink_input_assert_ref(i);
943
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
945
/* This always returns the relative volume. Converts the float
946
* version into a pa_cvolume */
948
v->channels = i->sample_spec.channels;
950
for (c = 0; c < v->channels; c++)
951
v->values[c] = pa_sw_volume_from_linear(i->relative_volume[c]);
956
/* Called from main context */
957
void pa_sink_input_set_relative_volume(pa_sink_input *i, const pa_cvolume *v) {
961
pa_sink_input_assert_ref(i);
962
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
963
pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
966
v = pa_cvolume_reset(&_v, i->sample_spec.channels);
968
/* This basically calculates:
970
* i->relative_volume := v
971
* i->soft_volume := i->relative_volume * i->volume_factor */
973
i->soft_volume.channels = i->sample_spec.channels;
975
for (c = 0; c < i->sample_spec.channels; c++) {
976
i->relative_volume[c] = pa_sw_volume_to_linear(v->values[c]);
978
i->soft_volume.values[c] = pa_sw_volume_from_linear(
979
i->relative_volume[c] *
980
pa_sw_volume_to_linear(i->volume_factor.values[c]));
983
/* We don't copy the data to the thread_info data. That's left for someone else to do */
986
/* Called from main context */
987
void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
814
989
pa_sink_input_assert_ref(i);
815
990
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
884
1073
pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
885
1074
pa_sink_input_assert_ref(i);
887
return i->resample_method;
1076
return i->actual_resample_method;
890
1079
/* Called from main context */
891
int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
892
pa_resampler *new_resampler;
894
pa_sink_input_move_hook_data hook_data;
895
pa_source_output *o, *p = NULL;
1080
pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
897
1081
pa_sink_input_assert_ref(i);
898
1082
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
899
pa_sink_assert_ref(dest);
906
1084
if (i->flags & PA_SINK_INPUT_DONT_MOVE)
909
1087
if (i->sync_next || i->sync_prev) {
910
1088
pa_log_warn("Moving synchronised streams not supported.");
1095
/* Called from main context */
1096
pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1097
pa_sink_input_assert_ref(i);
1098
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1099
pa_sink_assert_ref(dest);
1101
if (dest == i->sink)
1104
if (!pa_sink_input_may_move(i))
914
1107
if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
915
1108
pa_log_warn("Failed to move sink input: too many inputs per sink.");
1113
if (!i->may_move_to(i, dest))
1119
/* Called from main context */
1120
int pa_sink_input_start_move(pa_sink_input *i) {
1121
pa_source_output *o, *p = NULL;
1125
pa_sink_input_assert_ref(i);
1126
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1129
if (!pa_sink_input_may_move(i))
1130
return -PA_ERR_NOTSUPPORTED;
1132
if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
919
1137
/* Kill directly connected outputs */
920
1138
while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
921
1139
pa_assert(o != p);
922
1140
pa_source_output_kill(o);
1143
pa_assert(pa_idxset_isempty(i->direct_outputs));
1145
pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1147
if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1148
pa_assert_se(i->sink->n_corked-- >= 1);
1150
if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1151
pa_cvolume new_volume;
1153
/* Make the virtual volume relative */
1154
pa_sink_input_get_relative_volume(i, &i->virtual_volume);
1156
/* And reset the the relative volume */
1157
pa_sink_input_set_relative_volume(i, NULL);
1159
/* We might need to update the sink's volume if we are in flat
1161
pa_sink_update_flat_volume(i->sink, &new_volume);
1162
pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE);
1165
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1167
pa_sink_update_status(i->sink);
1170
pa_sink_input_unref(i);
1175
/* Called from main context */
1176
int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1177
pa_resampler *new_resampler;
1179
pa_sink_input_assert_ref(i);
1180
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1181
pa_assert(!i->sink);
1182
pa_sink_assert_ref(dest);
1184
if (!pa_sink_input_may_move_to(i, dest))
1185
return -PA_ERR_NOTSUPPORTED;
926
1187
if (i->thread_info.resampler &&
927
pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) &&
928
pa_channel_map_equal(&origin->channel_map, &dest->channel_map))
1188
pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1189
pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
930
1191
/* Try to reuse the old resampler if possible */
931
1192
new_resampler = i->thread_info.resampler;
937
1198
/* Okey, we need a new resampler for the new sink */
939
1200
if (!(new_resampler = pa_resampler_new(
941
1202
&i->sample_spec, &i->channel_map,
942
1203
&dest->sample_spec, &dest->channel_map,
1204
i->requested_resample_method,
944
1205
((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
945
1206
((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
946
1207
(i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
947
1208
pa_log_warn("Unsupported resampling operation.");
1209
return -PA_ERR_NOTSUPPORTED;
951
1212
new_resampler = NULL;
953
hook_data.sink_input = i;
954
hook_data.destination = dest;
955
pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE], &hook_data);
957
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
959
pa_idxset_remove_by_data(origin->inputs, i, NULL);
960
pa_idxset_put(dest->inputs, i, NULL);
1218
i->save_sink = save;
1219
pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
963
if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED) {
964
pa_assert_se(origin->n_corked-- >= 1);
1221
if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1222
i->sink->n_corked++;
968
1224
/* Replace resampler and render queue */
969
1225
if (new_resampler != i->thread_info.resampler) {
985
1241
&i->sink->silence);
988
pa_sink_update_status(origin);
989
1243
pa_sink_update_status(dest);
1245
if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1246
pa_cvolume new_volume;
1248
/* Make relative volume absolute again */
1249
pa_cvolume t = dest->reference_volume;
1250
pa_cvolume_remap(&t, &dest->channel_map, &i->channel_map);
1251
pa_sw_cvolume_multiply(&i->virtual_volume, &i->virtual_volume, &t);
1253
/* We might need to update the sink's volume if we are in flat volume mode. */
1254
pa_sink_update_flat_volume(i->sink, &new_volume);
1255
pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE);
991
1258
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
996
pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], i);
998
pa_log_debug("Successfully moved sink input %i from %s to %s.", i->index, origin->name, dest->name);
1260
pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1000
1262
/* Notify everyone */
1001
pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1263
pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1264
pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1269
/* Called from main context */
1270
int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1273
pa_sink_input_assert_ref(i);
1274
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1276
pa_sink_assert_ref(dest);
1278
if (dest == i->sink)
1281
if (!pa_sink_input_may_move_to(i, dest))
1282
return -PA_ERR_NOTSUPPORTED;
1284
pa_sink_input_ref(i);
1286
if ((r = pa_sink_input_start_move(i)) < 0) {
1287
pa_sink_input_unref(i);
1291
if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1292
pa_sink_input_unref(i);
1296
pa_sink_input_unref(i);
1052
1347
switch (code) {
1054
case PA_SINK_INPUT_MESSAGE_SET_VOLUME:
1055
i->thread_info.volume = *((pa_cvolume*) userdata);
1056
pa_sink_input_request_rewind(i, 0, TRUE, FALSE);
1349
case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1350
if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1351
i->thread_info.soft_volume = i->soft_volume;
1352
pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1059
case PA_SINK_INPUT_MESSAGE_SET_MUTE:
1060
i->thread_info.muted = PA_PTR_TO_UINT(userdata);
1061
pa_sink_input_request_rewind(i, 0, TRUE, FALSE);
1356
case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1357
if (i->thread_info.muted != i->muted) {
1358
i->thread_info.muted = i->muted;
1359
pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1064
1363
case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1065
1364
pa_usec_t *r = userdata;
1066
pa_usec_t sink_usec = 0;
1068
1366
r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1070
if (i->sink->parent.process_msg(PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_GET_LATENCY, &sink_usec, 0, NULL) >= 0)
1367
r[1] += pa_sink_get_latency_within_thread(i->sink);