Mercurial > pidgin
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 |