summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2018-04-20 12:20:29 +0100
committerDavid Woodhouse <dwmw2@infradead.org>2018-04-20 12:20:29 +0100
commit4318ab3d192beccd7ec4538c21352f56dbcda193 (patch)
tree2f254476dfecfadd6c9301d1d25b0647d82315c6
parent611a906efaaaba3aef2f984c0327eebff1636e3e (diff)
downloadpidgin-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.list1
-rw-r--r--libpurple/media.c6
-rw-r--r--libpurple/mediamanager.c40
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);