diff options
author | David Woodhouse <dwmw2@infradead.org> | 2018-04-20 12:20:29 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2018-04-20 12:20:29 +0100 |
commit | 4318ab3d192beccd7ec4538c21352f56dbcda193 (patch) | |
tree | 2f254476dfecfadd6c9301d1d25b0647d82315c6 | |
parent | 611a906efaaaba3aef2f984c0327eebff1636e3e (diff) | |
download | pidgin-4318ab3d192beccd7ec4538c21352f56dbcda193.tar.gz |
media: Send a signal when video caps change
This will allow the UI to adapt the aspect ratio (and possibly size if
appropriate) to the media stream.
-rw-r--r-- | libpurple/marshallers.list | 1 | ||||
-rw-r--r-- | libpurple/media.c | 6 | ||||
-rw-r--r-- | libpurple/mediamanager.c | 40 |
3 files changed, 46 insertions, 1 deletions
diff --git a/libpurple/marshallers.list b/libpurple/marshallers.list index d5e42418e1..47e8f8c0cf 100644 --- a/libpurple/marshallers.list +++ b/libpurple/marshallers.list @@ -7,3 +7,4 @@ VOID:ENUM,STRING,STRING,BOOLEAN VOID:FLAGS,FLAGS VOID:STRING,STRING,OBJECT,OBJECT VOID:POINTER,POINTER,OBJECT,OBJECT +VOID:STRING,STRING,POINTER diff --git a/libpurple/media.c b/libpurple/media.c index 5dad310e53..5f80b02d77 100644 --- a/libpurple/media.c +++ b/libpurple/media.c @@ -142,6 +142,7 @@ enum { STATE_CHANGED, STREAM_INFO, CANDIDATE_PAIR_ESTABLISHED, + VIDEO_CAPS, LAST_SIGNAL }; static guint purple_media_signals[LAST_SIGNAL] = {0}; @@ -280,6 +281,11 @@ purple_media_class_init (PurpleMediaClass *klass) purple_smarshal_VOID__POINTER_POINTER_OBJECT_OBJECT, G_TYPE_NONE, 4, G_TYPE_POINTER, G_TYPE_POINTER, PURPLE_TYPE_MEDIA_CANDIDATE, PURPLE_TYPE_MEDIA_CANDIDATE); + purple_media_signals[VIDEO_CAPS] = g_signal_new("video-caps", G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + purple_smarshal_VOID__STRING_STRING_POINTER, + G_TYPE_NONE, 3, G_TYPE_STRING, + G_TYPE_STRING, GST_TYPE_CAPS); g_type_class_add_private(klass, sizeof(PurpleMediaPrivate)); } diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c index 605b7dc1b9..6496b4c3dc 100644 --- a/libpurple/mediamanager.c +++ b/libpurple/mediamanager.c @@ -82,6 +82,7 @@ struct _PurpleMediaOutputWindow gchar *participant; gulong window_id; GstElement *sink; + guint caps_id; }; struct _PurpleMediaManagerPrivate @@ -1518,6 +1519,29 @@ purple_media_manager_get_active_element(PurpleMediaManager *manager, #endif /* USE_GSTREAMER */ #ifdef USE_VV +static gboolean +window_caps_cb_cb(PurpleMediaOutputWindow *ow) +{ + GstPad *pad = gst_element_get_static_pad(ow->sink, "sink"); + GstCaps *caps = gst_pad_get_current_caps(pad); + + if (caps) { + g_signal_emit_by_name(ow->media, "video-caps", ow->session_id, ow->participant, caps); + gst_caps_unref(caps); + } + + ow->caps_id = 0; + + return FALSE; +} + +static void +window_caps_cb(GstPad *pad, GParamSpec *pspec, PurpleMediaOutputWindow *ow) +{ + if (!ow->caps_id) + ow->caps_id = g_timeout_add(0, (GSourceFunc)window_caps_cb_cb, ow); +} + static void window_id_cb(GstBus *bus, GstMessage *msg, PurpleMediaOutputWindow *ow) { @@ -1573,6 +1597,7 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager, purple_strequal(participant, ow->participant) && purple_strequal(session_id, ow->session_id)) { GstBus *bus; + GstPad *pad; GstElement *queue, *convert, *scale; GstElement *tee = purple_media_get_tee(media, session_id, participant); @@ -1615,6 +1640,11 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager, G_CALLBACK(window_id_cb), ow); gst_object_unref(bus); + pad = gst_element_get_static_pad(ow->sink, "sink"); + g_signal_connect(pad, "notify::caps", + G_CALLBACK(window_caps_cb), ow); + gst_object_unref(pad); + gst_element_set_state(ow->sink, GST_STATE_PLAYING); gst_element_set_state(scale, GST_STATE_PLAYING); gst_element_set_state(convert, GST_STATE_PLAYING); @@ -1688,12 +1718,18 @@ purple_media_manager_remove_output_window(PurpleMediaManager *manager, if (output_window->sink != NULL) { GstElement *element = output_window->sink; + GstPad *pad; GstPad *teepad = NULL; GSList *to_remove = NULL; + pad = gst_element_get_static_pad(element, "sink"); + g_signal_handlers_disconnect_matched(pad, G_SIGNAL_MATCH_FUNC + | G_SIGNAL_MATCH_DATA, 0, 0, NULL, + window_caps_cb, output_window); + gst_object_unref(pad); + /* Find the tee element this output is connected to. */ while (!teepad) { - GstPad *pad; GstPad *peer; GstElementFactory *factory; const gchar *factory_name; @@ -1735,6 +1771,8 @@ purple_media_manager_remove_output_window(PurpleMediaManager *manager, to_remove = g_slist_delete_link(to_remove, to_remove); } } + if (output_window->caps_id) + g_source_remove(output_window->caps_id); g_free(output_window->session_id); g_free(output_window->participant); |