soc.2008.vv: bf98d5aa: Preliminary video embedded in the conver...
maiku at soc.pidgin.im
maiku at soc.pidgin.im
Tue Jun 10 01:25:50 EDT 2008
-----------------------------------------------------------------
Revision: bf98d5aa636e703a012f08daaa1fd2a7cfff716c
Ancestor: abb70b8005b3219cf51fa57178e0510beef74f97
Author: maiku at soc.pidgin.im
Date: 2008-06-10T05:18:29
Branch: im.pidgin.soc.2008.vv
URL: http://d.pidgin.im/viewmtn/revision/info/bf98d5aa636e703a012f08daaa1fd2a7cfff716c
Modified files:
libpurple/media.c pidgin/gtkconv.c pidgin/gtkconv.h
pidgin/gtkmedia.c pidgin/gtkmedia.h
ChangeLog:
Preliminary video embedded in the conversation window. It's still kind of buggy.
-------------- next part --------------
============================================================
--- libpurple/media.c 69c3ed1d6909e7a7c47ad19ff878941fa39631c4
+++ libpurple/media.c 1a7c1d7a9854f561ed97f2a5287d5c7852cfa4f4
@@ -676,7 +676,7 @@ purple_media_video_init_src(GstElement *
void
purple_media_video_init_src(GstElement **sendbin)
{
- GstElement *src;
+ GstElement *src, *tee, *queue, *local_sink;
GstPad *pad;
GstPad *ghost;
const gchar *video_plugin = purple_prefs_get_string("/purple/media/video/plugin");
@@ -685,17 +685,34 @@ purple_media_video_init_src(GstElement *
purple_debug_info("media", "purple_media_video_init_src\n");
*sendbin = gst_bin_new("purplesendvideobin");
- src = gst_element_factory_make(video_plugin, "videosrc");
+ src = gst_element_factory_make(video_plugin, "purplevideosource");
gst_bin_add(GST_BIN(*sendbin), src);
+ tee = gst_element_factory_make("tee", NULL);
+ gst_bin_add(GST_BIN(*sendbin), tee);
+ gst_element_link(src, tee);
+
+ queue = gst_element_factory_make("queue", NULL);
+ gst_bin_add(GST_BIN(*sendbin), queue);
+ gst_element_link(tee, queue);
+
if (!strcmp(video_plugin, "videotestsrc")) {
/* unless is-live is set to true it doesn't throttle videotestsrc */
g_object_set (G_OBJECT(src), "is-live", TRUE, NULL);
}
- pad = gst_element_get_pad(src, "src");
+
+ pad = gst_element_get_pad(queue, "src");
ghost = gst_ghost_pad_new("ghostsrc", pad);
gst_element_add_pad(*sendbin, ghost);
+ queue = gst_element_factory_make("queue", NULL);
+ gst_bin_add(GST_BIN(*sendbin), queue);
+ gst_element_link(tee, queue);
+
+ local_sink = gst_element_factory_make("autovideosink", "purplelocalvideosink");
+ gst_bin_add(GST_BIN(*sendbin), local_sink);
+ gst_element_link(queue, local_sink);
+
/* set current video device on "src"... */
if (video_device) {
GList *devices = purple_media_get_devices(src);
============================================================
--- pidgin/gtkconv.c 7b2cf562f5f111869f46ca1d4c056003a414f003
+++ pidgin/gtkconv.c 78a31883798a3fbf2829ddce2013027b923f3a28
@@ -4743,7 +4743,7 @@ setup_common_pane(PidginConversation *gt
static GtkWidget *
setup_common_pane(PidginConversation *gtkconv)
{
- GtkWidget *vbox, *frame, *imhtml_sw, *event_box;
+ GtkWidget *vbox, *hpaned, *frame, *imhtml_sw, *event_box;
GtkCellRenderer *rend;
GtkTreePath *path;
PurpleConversation *conv = gtkconv->active_conv;
@@ -4823,23 +4823,21 @@ setup_common_pane(PidginConversation *gt
/* Setup the gtkimhtml widget */
frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw);
gtk_widget_set_size_request(gtkconv->imhtml, -1, 0);
- if (chat) {
- GtkWidget *hpaned;
+ /* Add the gtkimhtml frame */
+ gtkconv->middle_hpaned = hpaned = gtk_hpaned_new();
+ gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0);
+ gtk_widget_show(hpaned);
+ gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE);
+
+ if (chat) {
/* Add the topic */
setup_chat_topic(gtkconv, vbox);
- /* Add the gtkimhtml frame */
- hpaned = gtk_hpaned_new();
- gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0);
- gtk_widget_show(hpaned);
- gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE);
-
/* Now add the userlist */
setup_chat_userlist(gtkconv, hpaned);
- } else {
- gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
}
+
gtk_widget_show(frame);
gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml");
@@ -7727,6 +7725,9 @@ pidgin_conv_new_media_cb(PurpleMediaMana
gtkconv->gtkmedia = gtkmedia;
g_signal_connect(G_OBJECT(gtkmedia), "destroy", G_CALLBACK(gtk_widget_destroyed), &(gtkconv->gtkmedia));
+
+ gtk_paned_pack2(GTK_PANED(gtkconv->middle_hpaned),
+ pidgin_media_get_display_widget(gtkmedia), FALSE, TRUE);
}
#endif
============================================================
--- pidgin/gtkconv.h 5036f2250c314d599e0b25d73854487b0a05cd74
+++ pidgin/gtkconv.h cfe6730a8323fa2464f55cc035da708adcf2dbe4
@@ -150,6 +150,7 @@ struct _PidginConversation
gpointer depr1;
#endif
+ GtkWidget *middle_hpaned;
GtkWidget *lower_hbox;
GtkWidget *toolbar;
============================================================
--- pidgin/gtkmedia.c 952215222430cccf9855ddacfe5f76e3f95a6e32
+++ pidgin/gtkmedia.c 875b88881a1f72f3da9d05294922696d56fdc06a
@@ -28,11 +28,14 @@
#include "internal.h"
#include "connection.h"
#include "media.h"
+#include "pidgin.h"
#include "gtkmedia.h"
#ifdef USE_VV
+#include <gst/interfaces/xoverlay.h>
+
typedef enum
{
/* Waiting for response */
@@ -60,6 +63,10 @@ struct _PidginMediaPrivate
GtkWidget *recv_progress;
PidginMediaState state;
+
+ GtkWidget *display;
+ GtkWidget *local_video;
+ GtkWidget *remote_video;
};
#define PIDGIN_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PIDGIN_TYPE_MEDIA, PidginMediaPrivate))
@@ -178,6 +185,8 @@ pidgin_media_init (PidginMedia *media)
gtk_widget_show_all(media->priv->accept);
gtk_widget_show_all(media->priv->reject);
+
+ media->priv->display = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
}
static gboolean
@@ -246,6 +255,8 @@ pidgin_media_finalize (GObject *media)
gst_object_unref(gtkmedia->priv->send_level);
if (gtkmedia->priv->recv_level)
gst_object_unref(gtkmedia->priv->recv_level);
+ if (gtkmedia->priv->display)
+ gtk_widget_destroy(gtkmedia->priv->display);
}
static void
@@ -254,6 +265,12 @@ pidgin_media_emit_message(PidginMedia *g
g_signal_emit(gtkmedia, pidgin_media_signals[MESSAGE], 0, msg);
}
+GtkWidget *
+pidgin_media_get_display_widget(GtkWidget *gtkmedia)
+{
+ return PIDGIN_MEDIA_GET_PRIVATE(gtkmedia)->display;
+}
+
static gboolean
media_bus_call(GstBus *bus, GstMessage *msg, gpointer gtkmedia)
{
@@ -284,30 +301,57 @@ media_bus_call(GstBus *bus, GstMessage *
return TRUE;
}
+static gboolean
+create_window (GstBus *bus, GstMessage *message, PidginMedia *gtkmedia)
+{
+ char *name;
+
+ if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT)
+ return TRUE;
+
+ if (!gst_structure_has_name(message->structure, "prepare-xwindow-id"))
+ return TRUE;
+
+ name = gst_object_get_name(GST_MESSAGE_SRC (message));
+ purple_debug_info("gtkmedia", "prepare-xwindow-id object name: %s\n", name);
+
+ /* The XOverlay's name is the sink's name with a suffix */
+ if (!strncmp(name, "purplevideosink", strlen("purplevideosink")))
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)),
+ GDK_WINDOW_XWINDOW(gtkmedia->priv->remote_video->window));
+ else if (!strncmp(name, "purplelocalvideosink", strlen("purplelocalvideosink")))
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)),
+ GDK_WINDOW_XWINDOW(gtkmedia->priv->local_video->window));
+ g_free(name);
+ return TRUE;
+}
+
static void
pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia)
{
GstElement *element = purple_media_get_pipeline(media);
- GstElement *audiosendbin, *audiosendlevel;
- GstElement *audiorecvbin, *audiorecvlevel;
- GstElement *videosendbin;
- GstElement *videorecvbin;
+ GstElement *audiosendbin = NULL, *audiosendlevel = NULL;
+ GstElement *audiorecvbin = NULL, *audiorecvlevel = NULL;
+ GstElement *videosendbin = NULL;
+ GstElement *videorecvbin = NULL;
GList *sessions = purple_media_get_session_names(media);
GstBus *bus;
- purple_media_audio_init_src(&audiosendbin, &audiosendlevel);
- purple_media_audio_init_recv(&audiorecvbin, &audiorecvlevel);
-
- purple_media_video_init_src(&videosendbin);
- purple_media_video_init_recv(&videorecvbin);
-
for (; sessions; sessions = sessions->next) {
if (purple_media_get_session_type(media, sessions->data) & PURPLE_MEDIA_AUDIO) {
+ if (!audiosendbin)
+ purple_media_audio_init_src(&audiosendbin, &audiosendlevel);
+ if (!audiorecvbin)
+ purple_media_audio_init_recv(&audiorecvbin, &audiorecvlevel);
purple_media_set_src(media, sessions->data, audiosendbin);
purple_media_set_sink(media, sessions->data, audiorecvbin);
} else if (purple_media_get_session_type(media, sessions->data) & PURPLE_MEDIA_VIDEO) {
+ if (!videosendbin)
+ purple_media_video_init_src(&videosendbin);
+ if (!videorecvbin)
+ purple_media_video_init_recv(&videorecvbin);
purple_media_set_src(media, sessions->data, videosendbin);
purple_media_set_sink(media, sessions->data, videorecvbin);
}
@@ -320,9 +364,42 @@ pidgin_media_ready_cb(PurpleMedia *media
NULL);
}
+ if (videorecvbin || videosendbin) {
+ GtkWidget *aspect;
+ GtkWidget *remote_video;
+ GtkWidget *local_video;
+
+ gtk_widget_show(gtkmedia->priv->display);
+
+ aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE);
+ gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display), aspect, TRUE, TRUE, 0);
+
+ remote_video = gtk_drawing_area_new();
+ gtk_container_add(GTK_CONTAINER(aspect), remote_video);
+ gtk_widget_set_size_request (GTK_WIDGET(remote_video), 100, -1);
+ gtk_widget_show(remote_video);
+ gtk_widget_show(aspect);
+
+ aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE);
+ gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display), aspect, TRUE, TRUE, 0);
+
+ local_video = gtk_drawing_area_new();
+ gtk_container_add(GTK_CONTAINER(aspect), local_video);
+ gtk_widget_show(local_video);
+ gtk_widget_show(aspect);
+
+ gtkmedia->priv->local_video = local_video;
+ gtkmedia->priv->remote_video = remote_video;
+ }
+
bus = gst_pipeline_get_bus(GST_PIPELINE(element));
gst_bus_add_signal_watch(GST_BUS(bus));
- g_signal_connect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), "message", G_CALLBACK(level_message_cb), gtkmedia);
+ g_signal_connect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))),
+ "message", G_CALLBACK(level_message_cb), gtkmedia);
+ if (videorecvbin || videosendbin)
+ gst_bus_set_sync_handler(bus, (GstBusSyncHandler)create_window, gtkmedia);
gst_bus_add_watch(bus, media_bus_call, gtkmedia);
gst_object_unref(bus);
}
============================================================
--- pidgin/gtkmedia.h be5ac6f0e1d7ce0e844b111c3c28431761e24b83
+++ pidgin/gtkmedia.h c1e4ba66efda8001b5f97304072a6f51f5765adb
@@ -60,6 +60,7 @@ GtkWidget *pidgin_media_new(PurpleMedia
GType pidgin_media_get_type(void);
GtkWidget *pidgin_media_new(PurpleMedia *media);
+GtkWidget *pidgin_media_get_display_widget(GtkWidget *gtkmedia);
G_END_DECLS
More information about the Commits
mailing list