comparison libpurple/media.c @ 29298:fb99a0067812

propagate from branch 'im.pidgin.pidgin' (head 70d69397ed952b26b453423c381c70d6783eb66d) to branch 'im.pidgin.cpw.attention_ui' (head 1cf0dea282a0d0e4aeac4770e0150d6d0c10830a)
author Marcus Lundblad <ml@update.uu.se>
date Thu, 13 Aug 2009 17:42:44 +0000
parents f77978e6968e
children 98d8c11e4937 8c991e09efcb
comparison
equal deleted inserted replaced
29297:338d6a211055 29298:fb99a0067812
92 PurpleMediaSession *session; 92 PurpleMediaSession *session;
93 gchar *participant; 93 gchar *participant;
94 FsStream *stream; 94 FsStream *stream;
95 GstElement *src; 95 GstElement *src;
96 GstElement *tee; 96 GstElement *tee;
97 GstElement *volume;
98 GstElement *level;
97 99
98 GList *local_candidates; 100 GList *local_candidates;
99 GList *remote_candidates; 101 GList *remote_candidates;
100 102
101 gboolean initiator; 103 gboolean initiator;
155 157
156 158
157 159
158 enum { 160 enum {
159 S_ERROR, 161 S_ERROR,
160 ACCEPTED,
161 CANDIDATES_PREPARED, 162 CANDIDATES_PREPARED,
162 CODECS_CHANGED, 163 CODECS_CHANGED,
164 LEVEL,
163 NEW_CANDIDATE, 165 NEW_CANDIDATE,
164 STATE_CHANGED, 166 STATE_CHANGED,
165 STREAM_INFO, 167 STREAM_INFO,
166 LAST_SIGNAL 168 LAST_SIGNAL
167 }; 169 };
270 "PURPLE_MEDIA_INFO_REJECT", "reject" }, 272 "PURPLE_MEDIA_INFO_REJECT", "reject" },
271 { PURPLE_MEDIA_INFO_MUTE, 273 { PURPLE_MEDIA_INFO_MUTE,
272 "PURPLE_MEDIA_INFO_MUTE", "mute" }, 274 "PURPLE_MEDIA_INFO_MUTE", "mute" },
273 { PURPLE_MEDIA_INFO_UNMUTE, 275 { PURPLE_MEDIA_INFO_UNMUTE,
274 "PURPLE_MEDIA_INFO_UNMUTE", "unmute" }, 276 "PURPLE_MEDIA_INFO_UNMUTE", "unmute" },
277 { PURPLE_MEDIA_INFO_PAUSE,
278 "PURPLE_MEDIA_INFO_PAUSE", "pause" },
279 { PURPLE_MEDIA_INFO_UNPAUSE,
280 "PURPLE_MEDIA_INFO_UNPAUSE", "unpause" },
275 { PURPLE_MEDIA_INFO_HOLD, 281 { PURPLE_MEDIA_INFO_HOLD,
276 "PURPLE_MEDIA_INFO_HOLD", "hold" }, 282 "PURPLE_MEDIA_INFO_HOLD", "hold" },
277 { PURPLE_MEDIA_INFO_UNHOLD, 283 { PURPLE_MEDIA_INFO_UNHOLD,
278 "PURPLE_MEDIA_INFO_HOLD", "unhold" }, 284 "PURPLE_MEDIA_INFO_HOLD", "unhold" },
279 { 0, NULL, NULL } 285 { 0, NULL, NULL }
330 336
331 purple_media_signals[S_ERROR] = g_signal_new("error", G_TYPE_FROM_CLASS(klass), 337 purple_media_signals[S_ERROR] = g_signal_new("error", G_TYPE_FROM_CLASS(klass),
332 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 338 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
333 g_cclosure_marshal_VOID__STRING, 339 g_cclosure_marshal_VOID__STRING,
334 G_TYPE_NONE, 1, G_TYPE_STRING); 340 G_TYPE_NONE, 1, G_TYPE_STRING);
335 purple_media_signals[ACCEPTED] = g_signal_new("accepted", G_TYPE_FROM_CLASS(klass),
336 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
337 purple_smarshal_VOID__STRING_STRING,
338 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
339 purple_media_signals[CANDIDATES_PREPARED] = g_signal_new("candidates-prepared", G_TYPE_FROM_CLASS(klass), 341 purple_media_signals[CANDIDATES_PREPARED] = g_signal_new("candidates-prepared", G_TYPE_FROM_CLASS(klass),
340 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 342 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
341 purple_smarshal_VOID__STRING_STRING, 343 purple_smarshal_VOID__STRING_STRING,
342 G_TYPE_NONE, 2, G_TYPE_STRING, 344 G_TYPE_NONE, 2, G_TYPE_STRING,
343 G_TYPE_STRING); 345 G_TYPE_STRING);
344 purple_media_signals[CODECS_CHANGED] = g_signal_new("codecs-changed", G_TYPE_FROM_CLASS(klass), 346 purple_media_signals[CODECS_CHANGED] = g_signal_new("codecs-changed", G_TYPE_FROM_CLASS(klass),
345 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 347 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
346 g_cclosure_marshal_VOID__STRING, 348 g_cclosure_marshal_VOID__STRING,
347 G_TYPE_NONE, 1, G_TYPE_STRING); 349 G_TYPE_NONE, 1, G_TYPE_STRING);
350 purple_media_signals[LEVEL] = g_signal_new("level", G_TYPE_FROM_CLASS(klass),
351 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
352 purple_smarshal_VOID__STRING_STRING_DOUBLE,
353 G_TYPE_NONE, 3, G_TYPE_STRING,
354 G_TYPE_STRING, G_TYPE_DOUBLE);
348 purple_media_signals[NEW_CANDIDATE] = g_signal_new("new-candidate", G_TYPE_FROM_CLASS(klass), 355 purple_media_signals[NEW_CANDIDATE] = g_signal_new("new-candidate", G_TYPE_FROM_CLASS(klass),
349 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 356 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
350 purple_smarshal_VOID__POINTER_POINTER_OBJECT, 357 purple_smarshal_VOID__POINTER_POINTER_OBJECT,
351 G_TYPE_NONE, 3, G_TYPE_POINTER, 358 G_TYPE_NONE, 3, G_TYPE_POINTER,
352 G_TYPE_POINTER, PURPLE_TYPE_MEDIA_CANDIDATE); 359 G_TYPE_POINTER, PURPLE_TYPE_MEDIA_CANDIDATE);
1897 gst_object_unref(pad); 1904 gst_object_unref(pad);
1898 gst_pad_set_active(ghost, TRUE); 1905 gst_pad_set_active(ghost, TRUE);
1899 gst_element_add_pad(session->media->priv->confbin, ghost); 1906 gst_element_add_pad(session->media->priv->confbin, ghost);
1900 } 1907 }
1901 1908
1909 gst_element_set_state(session->tee, GST_STATE_PLAYING);
1902 gst_element_link(session->src, session->media->priv->confbin); 1910 gst_element_link(session->src, session->media->priv->confbin);
1903 gst_element_set_state(session->tee, GST_STATE_PLAYING);
1904 1911
1905 g_object_get(session->session, "sink-pad", &sinkpad, NULL); 1912 g_object_get(session->session, "sink-pad", &sinkpad, NULL);
1906 srcpad = gst_element_get_request_pad(session->tee, "src%d"); 1913 if (session->type & PURPLE_MEDIA_SEND_AUDIO) {
1914 gchar *name = g_strdup_printf("volume_%s", session->id);
1915 GstElement *level;
1916 GstElement *volume = gst_element_factory_make("volume", name);
1917 double input_volume = purple_prefs_get_int(
1918 "/purple/media/audio/volume/input")/10.0;
1919 g_free(name);
1920 name = g_strdup_printf("sendlevel_%s", session->id);
1921 level = gst_element_factory_make("level", name);
1922 g_free(name);
1923 gst_bin_add(GST_BIN(session->media->priv->confbin), volume);
1924 gst_bin_add(GST_BIN(session->media->priv->confbin), level);
1925 gst_element_set_state(level, GST_STATE_PLAYING);
1926 gst_element_set_state(volume, GST_STATE_PLAYING);
1927 gst_element_link(volume, level);
1928 gst_element_link(session->tee, volume);
1929 srcpad = gst_element_get_static_pad(level, "src");
1930 g_object_set(volume, "volume", input_volume, NULL);
1931 } else {
1932 srcpad = gst_element_get_request_pad(session->tee, "src%d");
1933 }
1907 purple_debug_info("media", "connecting pad: %s\n", 1934 purple_debug_info("media", "connecting pad: %s\n",
1908 gst_pad_link(srcpad, sinkpad) == GST_PAD_LINK_OK 1935 gst_pad_link(srcpad, sinkpad) == GST_PAD_LINK_OK
1909 ? "success" : "failure"); 1936 ? "success" : "failure");
1910 gst_element_set_locked_state(session->src, FALSE); 1937 gst_element_set_locked_state(session->src, FALSE);
1911 gst_object_unref(session->src); 1938 gst_object_unref(session->src);
1958 static gboolean 1985 static gboolean
1959 media_bus_call(GstBus *bus, GstMessage *msg, PurpleMedia *media) 1986 media_bus_call(GstBus *bus, GstMessage *msg, PurpleMedia *media)
1960 { 1987 {
1961 switch(GST_MESSAGE_TYPE(msg)) { 1988 switch(GST_MESSAGE_TYPE(msg)) {
1962 case GST_MESSAGE_ELEMENT: { 1989 case GST_MESSAGE_ELEMENT: {
1990 if (g_signal_has_handler_pending(media,
1991 purple_media_signals[LEVEL], 0, FALSE)
1992 && gst_structure_has_name(
1993 gst_message_get_structure(msg), "level")) {
1994 GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
1995 gchar *name;
1996 gchar *participant = NULL;
1997 PurpleMediaSession *session = NULL;
1998 gdouble rms_db;
1999 gdouble percent;
2000 const GValue *list;
2001 const GValue *value;
2002
2003 if (!PURPLE_IS_MEDIA(media) ||
2004 GST_ELEMENT_PARENT(src) !=
2005 media->priv->confbin)
2006 break;
2007
2008 name = gst_element_get_name(src);
2009 if (!strncmp(name, "sendlevel_", 10)) {
2010 session = purple_media_get_session(
2011 media, name+10);
2012 } else {
2013 GList *iter = media->priv->streams;
2014 for (; iter; iter = g_list_next(iter)) {
2015 PurpleMediaStream *stream = iter->data;
2016 if (stream->level == src) {
2017 session = stream->session;
2018 participant = stream->participant;
2019 break;
2020 }
2021 }
2022 }
2023 g_free(name);
2024 if (!session)
2025 break;
2026
2027 list = gst_structure_get_value(
2028 gst_message_get_structure(msg), "rms");
2029 value = gst_value_list_get_value(list, 0);
2030 rms_db = g_value_get_double(value);
2031 percent = pow(10, rms_db / 20) * 5;
2032 if(percent > 1.0)
2033 percent = 1.0;
2034
2035 g_signal_emit(media, purple_media_signals[LEVEL],
2036 0, session->id, participant, percent);
2037 break;
2038 }
1963 if (!FS_IS_CONFERENCE(GST_MESSAGE_SRC(msg)) || 2039 if (!FS_IS_CONFERENCE(GST_MESSAGE_SRC(msg)) ||
1964 !PURPLE_IS_MEDIA(media) || 2040 !PURPLE_IS_MEDIA(media) ||
1965 media->priv->conference != 2041 media->priv->conference !=
1966 FS_CONFERENCE(GST_MESSAGE_SRC(msg))) 2042 FS_CONFERENCE(GST_MESSAGE_SRC(msg)))
1967 break; 2043 break;
2153 g_object_set(G_OBJECT(stream->stream), "direction", 2229 g_object_set(G_OBJECT(stream->stream), "direction",
2154 purple_media_to_fs_stream_direction( 2230 purple_media_to_fs_stream_direction(
2155 stream->session->type), NULL); 2231 stream->session->type), NULL);
2156 stream->accepted = TRUE; 2232 stream->accepted = TRUE;
2157 } 2233 }
2158
2159 g_signal_emit(media, purple_media_signals[ACCEPTED],
2160 0, NULL, NULL);
2161 } else if (local == TRUE && (type == PURPLE_MEDIA_INFO_MUTE || 2234 } else if (local == TRUE && (type == PURPLE_MEDIA_INFO_MUTE ||
2162 type == PURPLE_MEDIA_INFO_UNMUTE)) { 2235 type == PURPLE_MEDIA_INFO_UNMUTE)) {
2163 GList *sessions; 2236 GList *sessions;
2164 gboolean active = (type == PURPLE_MEDIA_INFO_MUTE); 2237 gboolean active = (type == PURPLE_MEDIA_INFO_MUTE);
2165 2238
2178 2251
2179 for (; sessions; sessions = g_list_delete_link( 2252 for (; sessions; sessions = g_list_delete_link(
2180 sessions, sessions)) { 2253 sessions, sessions)) {
2181 PurpleMediaSession *session = sessions->data; 2254 PurpleMediaSession *session = sessions->data;
2182 if (session->type & PURPLE_MEDIA_SEND_AUDIO) { 2255 if (session->type & PURPLE_MEDIA_SEND_AUDIO) {
2256 gchar *name = g_strdup_printf("volume_%s",
2257 session->id);
2183 GstElement *volume = gst_bin_get_by_name( 2258 GstElement *volume = gst_bin_get_by_name(
2184 GST_BIN(session->src), 2259 GST_BIN(session->media->
2185 "purpleaudioinputvolume"); 2260 priv->confbin), name);
2261 g_free(name);
2186 g_object_set(volume, "mute", active, NULL); 2262 g_object_set(volume, "mute", active, NULL);
2263 }
2264 }
2265 } else if (local == TRUE && (type == PURPLE_MEDIA_INFO_PAUSE ||
2266 type == PURPLE_MEDIA_INFO_UNPAUSE)) {
2267 gboolean active = (type == PURPLE_MEDIA_INFO_PAUSE);
2268 GList *streams = purple_media_get_streams(media,
2269 session_id, participant);
2270 for (; streams; streams = g_list_delete_link(streams, streams)) {
2271 PurpleMediaStream *stream = streams->data;
2272 if (stream->session->type & PURPLE_MEDIA_SEND_VIDEO) {
2273 g_object_set(stream->stream, "direction",
2274 purple_media_to_fs_stream_direction(
2275 stream->session->type & ((active) ?
2276 ~PURPLE_MEDIA_SEND_VIDEO :
2277 PURPLE_MEDIA_VIDEO)), NULL);
2187 } 2278 }
2188 } 2279 }
2189 } 2280 }
2190 2281
2191 g_signal_emit(media, purple_media_signals[STREAM_INFO], 2282 g_signal_emit(media, purple_media_signals[STREAM_INFO],
2344 2435
2345 if (stream->src == NULL) { 2436 if (stream->src == NULL) {
2346 GstElement *sink = NULL; 2437 GstElement *sink = NULL;
2347 2438
2348 if (codec->media_type == FS_MEDIA_TYPE_AUDIO) { 2439 if (codec->media_type == FS_MEDIA_TYPE_AUDIO) {
2440 GstElement *queue = NULL;
2441 double output_volume = purple_prefs_get_int(
2442 "/purple/media/audio/volume/output")/10.0;
2349 /* 2443 /*
2350 * Should this instead be: 2444 * Should this instead be:
2351 * audioconvert ! audioresample ! liveadder ! 2445 * audioconvert ! audioresample ! liveadder !
2352 * audioresample ! audioconvert ! realsink 2446 * audioresample ! audioconvert ! realsink
2353 */ 2447 */
2448 queue = gst_element_factory_make("queue", NULL);
2449 stream->volume = gst_element_factory_make(
2450 "volume", NULL);
2451 g_object_set(stream->volume, "volume",
2452 output_volume, NULL);
2453 stream->level = gst_element_factory_make(
2454 "level", NULL);
2354 stream->src = gst_element_factory_make( 2455 stream->src = gst_element_factory_make(
2355 "liveadder", NULL); 2456 "liveadder", NULL);
2356 sink = purple_media_manager_get_element(priv->manager, 2457 sink = purple_media_manager_get_element(priv->manager,
2357 PURPLE_MEDIA_RECV_AUDIO, 2458 PURPLE_MEDIA_RECV_AUDIO,
2358 stream->session->media, 2459 stream->session->media,
2359 stream->session->id, 2460 stream->session->id,
2360 stream->participant); 2461 stream->participant);
2462 gst_bin_add(GST_BIN(priv->confbin), queue);
2463 gst_bin_add(GST_BIN(priv->confbin), stream->volume);
2464 gst_bin_add(GST_BIN(priv->confbin), stream->level);
2465 gst_bin_add(GST_BIN(priv->confbin), sink);
2466 gst_element_set_state(sink, GST_STATE_PLAYING);
2467 gst_element_set_state(stream->level, GST_STATE_PLAYING);
2468 gst_element_set_state(stream->volume, GST_STATE_PLAYING);
2469 gst_element_set_state(queue, GST_STATE_PLAYING);
2470 gst_element_link(stream->level, sink);
2471 gst_element_link(stream->volume, stream->level);
2472 gst_element_link(queue, stream->volume);
2473 sink = queue;
2361 } else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) { 2474 } else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) {
2362 stream->src = gst_element_factory_make( 2475 stream->src = gst_element_factory_make(
2363 "fsfunnel", NULL); 2476 "fsfunnel", NULL);
2364 sink = gst_element_factory_make( 2477 sink = gst_element_factory_make(
2365 "fakesink", NULL); 2478 "fakesink", NULL);
2366 g_object_set(G_OBJECT(sink), "async", FALSE, NULL); 2479 g_object_set(G_OBJECT(sink), "async", FALSE, NULL);
2480 gst_bin_add(GST_BIN(priv->confbin), sink);
2481 gst_element_set_state(sink, GST_STATE_PLAYING);
2367 } 2482 }
2368 stream->tee = gst_element_factory_make("tee", NULL); 2483 stream->tee = gst_element_factory_make("tee", NULL);
2369 gst_bin_add_many(GST_BIN(priv->confbin), 2484 gst_bin_add_many(GST_BIN(priv->confbin),
2370 stream->src, stream->tee, sink, NULL); 2485 stream->src, stream->tee, NULL);
2371 gst_element_sync_state_with_parent(sink); 2486 gst_element_set_state(stream->tee, GST_STATE_PLAYING);
2372 gst_element_sync_state_with_parent(stream->tee); 2487 gst_element_set_state(stream->src, GST_STATE_PLAYING);
2373 gst_element_sync_state_with_parent(stream->src);
2374 gst_element_link_many(stream->src, stream->tee, sink, NULL); 2488 gst_element_link_many(stream->src, stream->tee, sink, NULL);
2375 } 2489 }
2376 2490
2377 sinkpad = gst_element_get_request_pad(stream->src, "sink%d"); 2491 sinkpad = gst_element_get_request_pad(stream->src, "sink%d");
2378 gst_pad_link(srcpad, sinkpad); 2492 gst_pad_link(srcpad, sinkpad);
2502 purple_media_add_session(media, session); 2616 purple_media_add_session(media, session);
2503 g_signal_emit(media, purple_media_signals[STATE_CHANGED], 2617 g_signal_emit(media, purple_media_signals[STATE_CHANGED],
2504 0, PURPLE_MEDIA_STATE_NEW, 2618 0, PURPLE_MEDIA_STATE_NEW,
2505 session->id, NULL); 2619 session->id, NULL);
2506 2620
2507 session_type = purple_media_from_fs(media_type, 2621 if (type_direction & FS_DIRECTION_SEND) {
2508 FS_DIRECTION_SEND); 2622 session_type = purple_media_from_fs(media_type,
2509 src = purple_media_manager_get_element( 2623 FS_DIRECTION_SEND);
2510 media->priv->manager, session_type, 2624 src = purple_media_manager_get_element(
2511 media, session->id, who); 2625 media->priv->manager, session_type,
2512 if (!GST_IS_ELEMENT(src)) { 2626 media, session->id, who);
2513 purple_debug_error("media", 2627 if (!GST_IS_ELEMENT(src)) {
2514 "Error creating src for session %s\n", 2628 purple_debug_error("media",
2515 session->id); 2629 "Error creating src for session %s\n",
2516 purple_media_end(media, session->id, NULL); 2630 session->id);
2517 return FALSE; 2631 purple_media_end(media, session->id, NULL);
2632 return FALSE;
2633 }
2634
2635 purple_media_set_src(media, session->id, src);
2636 gst_element_set_state(session->src, GST_STATE_PLAYING);
2637 purple_media_manager_create_output_window(
2638 media->priv->manager,
2639 session->media,
2640 session->id, NULL);
2518 } 2641 }
2519
2520 purple_media_set_src(media, session->id, src);
2521 gst_element_set_state(session->src, GST_STATE_PLAYING);
2522
2523 purple_media_manager_create_output_window(
2524 media->priv->manager,
2525 session->media,
2526 session->id, NULL);
2527 } 2642 }
2528 2643
2529 if (!(participant = purple_media_add_participant(media, who))) { 2644 if (!(participant = purple_media_add_participant(media, who))) {
2530 purple_media_remove_session(media, session); 2645 purple_media_remove_session(media, session);
2531 g_free(session); 2646 g_free(session);
2887 PurpleMediaSession *session; 3002 PurpleMediaSession *session;
2888 session = purple_media_get_session(media, sess_id); 3003 session = purple_media_get_session(media, sess_id);
2889 3004
2890 if (session == NULL) 3005 if (session == NULL)
2891 return FALSE; 3006 return FALSE;
2892 3007 if (session->type & (PURPLE_MEDIA_SEND_AUDIO |
2893 g_object_get(session->session, "codecs-ready", &ret, NULL); 3008 PURPLE_MEDIA_SEND_VIDEO))
3009 g_object_get(session->session,
3010 "codecs-ready", &ret, NULL);
3011 else
3012 ret = TRUE;
2894 } else { 3013 } else {
2895 GList *values = g_hash_table_get_values(media->priv->sessions); 3014 GList *values = g_hash_table_get_values(media->priv->sessions);
2896 for (; values; values = g_list_delete_link(values, values)) { 3015 for (; values; values = g_list_delete_link(values, values)) {
2897 PurpleMediaSession *session = values->data; 3016 PurpleMediaSession *session = values->data;
2898 g_object_get(session->session, 3017 if (session->type & (PURPLE_MEDIA_SEND_AUDIO |
2899 "codecs-ready", &ret, NULL); 3018 PURPLE_MEDIA_SEND_VIDEO))
3019 g_object_get(session->session,
3020 "codecs-ready", &ret, NULL);
3021 else
3022 ret = TRUE;
3023
2900 if (ret == FALSE) 3024 if (ret == FALSE)
2901 break; 3025 break;
2902 } 3026 }
2903 if (values != NULL) 3027 if (values != NULL)
2904 g_list_free(values); 3028 g_list_free(values);
2981 #ifdef USE_VV 3105 #ifdef USE_VV
2982 GList *sessions; 3106 GList *sessions;
2983 3107
2984 g_return_if_fail(PURPLE_IS_MEDIA(media)); 3108 g_return_if_fail(PURPLE_IS_MEDIA(media));
2985 3109
3110 purple_prefs_set_int("/purple/media/audio/volume/input", level);
3111
2986 if (session_id == NULL) 3112 if (session_id == NULL)
2987 sessions = g_hash_table_get_values(media->priv->sessions); 3113 sessions = g_hash_table_get_values(media->priv->sessions);
2988 else 3114 else
2989 sessions = g_list_append(NULL, 3115 sessions = g_list_append(NULL,
2990 purple_media_get_session(media, session_id)); 3116 purple_media_get_session(media, session_id));
2991 3117
2992 for (; sessions; sessions = g_list_delete_link(sessions, sessions)) { 3118 for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
2993 PurpleMediaSession *session = sessions->data; 3119 PurpleMediaSession *session = sessions->data;
2994 3120
2995 if (session->type & PURPLE_MEDIA_SEND_AUDIO) { 3121 if (session->type & PURPLE_MEDIA_SEND_AUDIO) {
3122 gchar *name = g_strdup_printf("volume_%s",
3123 session->id);
2996 GstElement *volume = gst_bin_get_by_name( 3124 GstElement *volume = gst_bin_get_by_name(
2997 GST_BIN(session->src), 3125 GST_BIN(session->media->priv->confbin),
2998 "purpleaudioinputvolume"); 3126 name);
2999 g_object_set(volume, "volume", level, NULL); 3127 g_free(name);
3128 g_object_set(volume, "volume", level/10.0, NULL);
3000 } 3129 }
3001 } 3130 }
3002 #endif 3131 #endif
3003 } 3132 }
3004 3133
3009 #ifdef USE_VV 3138 #ifdef USE_VV
3010 GList *streams; 3139 GList *streams;
3011 3140
3012 g_return_if_fail(PURPLE_IS_MEDIA(media)); 3141 g_return_if_fail(PURPLE_IS_MEDIA(media));
3013 3142
3143 purple_prefs_set_int("/purple/media/audio/volume/output", level);
3144
3014 streams = purple_media_get_streams(media, 3145 streams = purple_media_get_streams(media,
3015 session_id, participant); 3146 session_id, participant);
3016 3147
3017 for (; streams; streams = g_list_delete_link(streams, streams)) { 3148 for (; streams; streams = g_list_delete_link(streams, streams)) {
3018 PurpleMediaStream *stream = streams->data; 3149 PurpleMediaStream *stream = streams->data;
3019 3150
3020 if (stream->session->type & PURPLE_MEDIA_RECV_AUDIO) { 3151 if (stream->session->type & PURPLE_MEDIA_RECV_AUDIO
3021 GstElement *tee = stream->tee; 3152 && GST_IS_ELEMENT(stream->volume)) {
3022 GstIterator *iter = gst_element_iterate_src_pads(tee); 3153 g_object_set(stream->volume, "volume", level/10.0, NULL);
3023 GstPad *sinkpad;
3024 while (gst_iterator_next(iter, (gpointer)&sinkpad)
3025 == GST_ITERATOR_OK) {
3026 GstPad *peer = gst_pad_get_peer(sinkpad);
3027 GstElement *volume;
3028
3029 if (peer == NULL) {
3030 gst_object_unref(sinkpad);
3031 continue;
3032 }
3033
3034 volume = gst_bin_get_by_name(GST_BIN(
3035 GST_OBJECT_PARENT(peer)),
3036 "purpleaudiooutputvolume");
3037 g_object_set(volume, "volume", level, NULL);
3038 gst_object_unref(peer);
3039 gst_object_unref(sinkpad);
3040 }
3041 gst_iterator_free(iter);
3042 } 3154 }
3043 } 3155 }
3044 #endif 3156 #endif
3045 } 3157 }
3046 3158