Mercurial > pidgin
comparison libpurple/media.c @ 26109:fcfb7571515c
Have all src_pads for a stream be funneled into the same stream.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Thu, 19 Feb 2009 11:26:37 +0000 |
parents | 76104100cb87 |
children | 730e760ca39f |
comparison
equal
deleted
inserted
replaced
26108:d6e23439b77c | 26109:fcfb7571515c |
---|---|
67 { | 67 { |
68 PurpleMediaSession *session; | 68 PurpleMediaSession *session; |
69 gchar *participant; | 69 gchar *participant; |
70 FsStream *stream; | 70 FsStream *stream; |
71 GstElement *sink; | 71 GstElement *sink; |
72 GstElement *src; | |
73 GstElement *tee; | |
72 | 74 |
73 GList *local_candidates; | 75 GList *local_candidates; |
74 GList *remote_candidates; | 76 GList *remote_candidates; |
75 | 77 |
76 gboolean candidates_prepared; | 78 gboolean candidates_prepared; |
1595 } | 1597 } |
1596 | 1598 |
1597 void | 1599 void |
1598 purple_media_audio_init_recv(GstElement **recvbin, GstElement **recvlevel) | 1600 purple_media_audio_init_recv(GstElement **recvbin, GstElement **recvlevel) |
1599 { | 1601 { |
1600 GstElement *sink, *volume; | 1602 GstElement *sink, *volume, *queue; |
1601 GstPad *pad, *ghost; | 1603 GstPad *pad, *ghost; |
1602 double output_volume = purple_prefs_get_int( | 1604 double output_volume = purple_prefs_get_int( |
1603 "/purple/media/audio/volume/output")/10.0; | 1605 "/purple/media/audio/volume/output")/10.0; |
1604 | 1606 |
1605 g_return_if_fail(recvbin != NULL && recvlevel != NULL); | 1607 g_return_if_fail(recvbin != NULL && recvlevel != NULL); |
1608 sink = gst_element_factory_make("alsasink", "asink"); | 1610 sink = gst_element_factory_make("alsasink", "asink"); |
1609 g_object_set(G_OBJECT(sink), "sync", FALSE, NULL); | 1611 g_object_set(G_OBJECT(sink), "sync", FALSE, NULL); |
1610 volume = gst_element_factory_make("volume", "purpleaudiooutputvolume"); | 1612 volume = gst_element_factory_make("volume", "purpleaudiooutputvolume"); |
1611 g_object_set(volume, "volume", output_volume, NULL); | 1613 g_object_set(volume, "volume", output_volume, NULL); |
1612 *recvlevel = gst_element_factory_make("level", "recvlevel"); | 1614 *recvlevel = gst_element_factory_make("level", "recvlevel"); |
1613 gst_bin_add_many(GST_BIN(*recvbin), sink, volume, *recvlevel, NULL); | 1615 queue = gst_element_factory_make("queue", NULL); |
1616 gst_bin_add_many(GST_BIN(*recvbin), sink, volume, | |
1617 *recvlevel, queue, NULL); | |
1614 gst_element_link(*recvlevel, sink); | 1618 gst_element_link(*recvlevel, sink); |
1615 gst_element_link(volume, *recvlevel); | 1619 gst_element_link(volume, *recvlevel); |
1616 pad = gst_element_get_pad(volume, "sink"); | 1620 gst_element_link(queue, volume); |
1621 pad = gst_element_get_pad(queue, "sink"); | |
1617 ghost = gst_ghost_pad_new("ghostsink", pad); | 1622 ghost = gst_ghost_pad_new("ghostsink", pad); |
1618 gst_element_add_pad(*recvbin, ghost); | 1623 gst_element_add_pad(*recvbin, ghost); |
1619 g_object_set(G_OBJECT(*recvlevel), "message", TRUE, NULL); | 1624 g_object_set(G_OBJECT(*recvlevel), "message", TRUE, NULL); |
1620 } | 1625 } |
1621 | 1626 |
1757 | 1762 |
1758 static void | 1763 static void |
1759 purple_media_src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, | 1764 purple_media_src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, |
1760 FsCodec *codec, PurpleMediaStream *stream) | 1765 FsCodec *codec, PurpleMediaStream *stream) |
1761 { | 1766 { |
1762 PurpleMediaSessionType type = purple_media_from_fs(codec->media_type, FS_DIRECTION_RECV); | 1767 PurpleMediaPrivate *priv; |
1763 GstPad *sinkpad = NULL; | 1768 GstPad *sinkpad; |
1764 | 1769 |
1765 g_return_if_fail(FS_IS_STREAM(fsstream)); | 1770 g_return_if_fail(FS_IS_STREAM(fsstream)); |
1766 g_return_if_fail(stream != NULL); | 1771 g_return_if_fail(stream != NULL); |
1767 | 1772 |
1768 if (stream->sink == NULL) | 1773 priv = stream->session->media->priv; |
1769 stream->sink = purple_media_manager_get_element( | 1774 |
1770 stream->session->media->priv->manager, type); | 1775 if (stream->src == NULL) { |
1771 | 1776 GstElement *sink; |
1772 gst_bin_add(GST_BIN(stream->session->media->priv->confbin), | 1777 |
1773 stream->sink); | 1778 if (codec->media_type == FS_MEDIA_TYPE_AUDIO) { |
1774 sinkpad = gst_element_get_static_pad(stream->sink, "ghostsink"); | 1779 /* |
1780 * Should this instead be: | |
1781 * audioconvert ! audioresample ! liveadder ! | |
1782 * audioresample ! audioconvert ! realsink | |
1783 */ | |
1784 stream->src = gst_element_factory_make( | |
1785 "liveadder", NULL); | |
1786 sink = purple_media_manager_get_element(priv->manager, | |
1787 PURPLE_MEDIA_RECV_AUDIO); | |
1788 } else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) { | |
1789 stream->src = gst_element_factory_make( | |
1790 "fsfunnel", NULL); | |
1791 sink = gst_element_factory_make( | |
1792 "fakesink", NULL); | |
1793 g_object_set(G_OBJECT(sink), "async", FALSE, NULL); | |
1794 } | |
1795 stream->tee = gst_element_factory_make("tee", NULL); | |
1796 gst_bin_add_many(GST_BIN(priv->confbin), | |
1797 stream->src, stream->tee, sink, NULL); | |
1798 gst_element_sync_state_with_parent(sink); | |
1799 gst_element_sync_state_with_parent(stream->tee); | |
1800 gst_element_sync_state_with_parent(stream->src); | |
1801 gst_element_link_many(stream->src, stream->tee, sink, NULL); | |
1802 } | |
1803 | |
1804 sinkpad = gst_element_get_request_pad(stream->src, "sink%d"); | |
1775 gst_pad_link(srcpad, sinkpad); | 1805 gst_pad_link(srcpad, sinkpad); |
1776 gst_element_set_state(stream->sink, GST_STATE_PLAYING); | 1806 gst_object_unref(sinkpad); |
1807 | |
1808 if (codec->media_type == FS_MEDIA_TYPE_VIDEO && | |
1809 stream->sink != NULL) { | |
1810 gst_bin_add(GST_BIN(priv->confbin), stream->sink); | |
1811 gst_element_set_state(stream->sink, GST_STATE_PLAYING); | |
1812 gst_element_link(stream->tee, stream->sink); | |
1813 } | |
1777 | 1814 |
1778 g_timeout_add_full(G_PRIORITY_HIGH, 0, | 1815 g_timeout_add_full(G_PRIORITY_HIGH, 0, |
1779 (GSourceFunc)purple_media_connected_cb, stream, NULL); | 1816 (GSourceFunc)purple_media_connected_cb, stream, NULL); |
1780 } | 1817 } |
1781 | 1818 |
2395 } | 2432 } |
2396 } else if (session_id != NULL && participant != NULL) { | 2433 } else if (session_id != NULL && participant != NULL) { |
2397 PurpleMediaStream *stream = purple_media_get_stream( | 2434 PurpleMediaStream *stream = purple_media_get_stream( |
2398 media, session_id, participant); | 2435 media, session_id, participant); |
2399 GstBus *bus; | 2436 GstBus *bus; |
2400 GstElement *bin, *sink; | 2437 GstElement *bin, *queue, *sink; |
2401 GstPad *pad, *peer = NULL, *ghostpad; | 2438 GstPad *pad, *peer = NULL, *ghostpad; |
2402 PurpleMediaXOverlayData *data; | 2439 PurpleMediaXOverlayData *data; |
2403 gchar *name; | 2440 gchar *name; |
2404 | 2441 |
2405 if (stream == NULL) | 2442 if (stream == NULL) |
2442 | 2479 |
2443 bin = gst_bin_new(NULL); | 2480 bin = gst_bin_new(NULL); |
2444 | 2481 |
2445 name = g_strdup_printf("stream-sink_%s_%s", | 2482 name = g_strdup_printf("stream-sink_%s_%s", |
2446 session_id, participant); | 2483 session_id, participant); |
2484 queue = gst_element_factory_make("queue", NULL); | |
2447 sink = gst_element_factory_make("autovideosink", name); | 2485 sink = gst_element_factory_make("autovideosink", name); |
2448 | 2486 |
2449 gst_bin_add(GST_BIN(bin), sink); | 2487 gst_bin_add_many(GST_BIN(bin), queue, sink, NULL); |
2450 pad = gst_element_get_static_pad(sink, "sink"); | 2488 gst_element_link(queue, sink); |
2489 pad = gst_element_get_static_pad(queue, "sink"); | |
2451 ghostpad = gst_ghost_pad_new("ghostsink", pad); | 2490 ghostpad = gst_ghost_pad_new("ghostsink", pad); |
2452 gst_element_add_pad(bin, ghostpad); | 2491 gst_element_add_pad(bin, ghostpad); |
2453 | 2492 |
2454 /* Connect callback for prepared-xwindow-id signal */ | 2493 /* Connect callback for prepared-xwindow-id signal */ |
2455 data = g_new0(PurpleMediaXOverlayData, 1); | 2494 data = g_new0(PurpleMediaXOverlayData, 1); |
2461 data->handler_id = g_signal_connect(bus, | 2500 data->handler_id = g_signal_connect(bus, |
2462 "sync-message::element", | 2501 "sync-message::element", |
2463 G_CALLBACK(window_id_cb), data); | 2502 G_CALLBACK(window_id_cb), data); |
2464 gst_object_unref(bus); | 2503 gst_object_unref(bus); |
2465 | 2504 |
2466 if (stream->sink != NULL) { | 2505 if (stream->tee != NULL) { |
2506 gst_bin_add(GST_BIN(GST_ELEMENT_PARENT( | |
2507 stream->tee)), bin); | |
2467 gst_element_set_state(bin, GST_STATE_PLAYING); | 2508 gst_element_set_state(bin, GST_STATE_PLAYING); |
2468 gst_pad_link(peer, ghostpad); | 2509 gst_element_link(stream->tee, bin); |
2469 } | 2510 } |
2470 | 2511 |
2471 stream->sink = bin; | 2512 stream->sink = bin; |
2472 return TRUE; | 2513 return TRUE; |
2473 } | 2514 } |