From: Sjoerd Simons Date: Tue, 3 Feb 2009 09:02:55 +0000 (+0000) Subject: Add audio/video sink and source abstractions X-Git-Url: https://git.0d.be/?p=empathy.git;a=commitdiff_plain;h=cc5ffe66ab42ecb2fe0255b6ba0baee25624917f Add audio/video sink and source abstractions Signed-off-by: Sjoerd Simons svn path=/trunk/; revision=2384 --- diff --git a/configure.ac b/configure.ac index c5f912e5..80b208cc 100644 --- a/configure.ac +++ b/configure.ac @@ -111,6 +111,7 @@ PKG_CHECK_MODULES(EMPATHY, libebook-1.2 libcanberra-gtk >= 0.4 gstreamer-0.10 + gstreamer-interfaces-0.10 ]) PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED) diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index b9c44858..46d03167 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -37,6 +37,10 @@ libempathy_gtk_la_SOURCES = \ empathy-contact-selector.c \ empathy-contact-widget.c \ empathy-geometry.c \ + empathy-audio-sink.c \ + empathy-audio-src.c \ + empathy-video-src.c \ + empathy-video-widget.c \ empathy-irc-network-dialog.c \ empathy-log-window.c \ empathy-new-message-dialog.c \ @@ -85,6 +89,10 @@ libempathy_gtk_headers = \ empathy-contact-selector.h \ empathy-contact-widget.h \ empathy-geometry.h \ + empathy-audio-sink.h \ + empathy-audio-src.h \ + empathy-video-src.h \ + empathy-video-widget.h \ empathy-images.h \ empathy-irc-network-dialog.h \ empathy-log-window.h \ diff --git a/libempathy-gtk/empathy-audio-sink.c b/libempathy-gtk/empathy-audio-sink.c new file mode 100644 index 00000000..8db046a8 --- /dev/null +++ b/libempathy-gtk/empathy-audio-sink.c @@ -0,0 +1,124 @@ +/* + * empathy-gst-audio-sink.c - Source for EmpathyGstAudioSink + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include + +#include "empathy-audio-sink.h" + +G_DEFINE_TYPE(EmpathyGstAudioSink, empathy_audio_sink, GST_TYPE_BIN) + +/* signal enum */ +#if 0 +enum +{ + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; +#endif + +/* private structure */ +typedef struct _EmpathyGstAudioSinkPrivate EmpathyGstAudioSinkPrivate; + +struct _EmpathyGstAudioSinkPrivate +{ + gboolean dispose_has_run; + GstElement *sink; +}; + +#define EMPATHY_GST_AUDIO_SINK_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_GST_AUDIO_SINK, \ + EmpathyGstAudioSinkPrivate)) + +static void +empathy_audio_sink_init (EmpathyGstAudioSink *obj) +{ + EmpathyGstAudioSinkPrivate *priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (obj); + GstElement *resample; + GstPad *ghost, *sink; + + /* allocate any data required by the object here */ + resample = gst_element_factory_make ("audioresample", NULL); + + priv->sink = gst_element_factory_make ("gconfaudiosink", NULL); + + gst_bin_add_many (GST_BIN (obj), resample, priv->sink, NULL); + gst_element_link_many (resample, priv->sink, NULL); + + sink = gst_element_get_static_pad (resample, "sink"); + + ghost = gst_ghost_pad_new ("sink", sink); + gst_element_add_pad (GST_ELEMENT (obj), ghost); + + gst_object_unref (G_OBJECT (sink)); +} + +static void empathy_audio_sink_dispose (GObject *object); +static void empathy_audio_sink_finalize (GObject *object); + +static void +empathy_audio_sink_class_init (EmpathyGstAudioSinkClass + *empathy_audio_sink_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (empathy_audio_sink_class); + + g_type_class_add_private (empathy_audio_sink_class, + sizeof (EmpathyGstAudioSinkPrivate)); + + object_class->dispose = empathy_audio_sink_dispose; + object_class->finalize = empathy_audio_sink_finalize; +} + +void +empathy_audio_sink_dispose (GObject *object) +{ + EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (object); + EmpathyGstAudioSinkPrivate *priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self); + + if (priv->dispose_has_run) + return; + + priv->dispose_has_run = TRUE; + + /* release any references held by the object here */ + + if (G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose) + G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose (object); +} + +void +empathy_audio_sink_finalize (GObject *object) +{ + //EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (object); + //EmpathyGstAudioSinkPrivate *priv = + // EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self); + + /* free any data held directly by the object here */ + + G_OBJECT_CLASS (empathy_audio_sink_parent_class)->finalize (object); +} + +GstElement * +empathy_audio_sink_new (void) +{ + return GST_ELEMENT (g_object_new (EMPATHY_TYPE_GST_AUDIO_SINK, NULL)); +} diff --git a/libempathy-gtk/empathy-audio-sink.h b/libempathy-gtk/empathy-audio-sink.h new file mode 100644 index 00000000..2a222b2f --- /dev/null +++ b/libempathy-gtk/empathy-audio-sink.h @@ -0,0 +1,63 @@ +/* + * empathy-gst-video-sink.h - Header for EmpathyGstAudioSink + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_GST_AUDIO_SINK_H__ +#define __EMPATHY_GST_AUDIO_SINK_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyGstAudioSink EmpathyGstAudioSink; +typedef struct _EmpathyGstAudioSinkClass EmpathyGstAudioSinkClass; + +struct _EmpathyGstAudioSinkClass { + GstBinClass parent_class; +}; + +struct _EmpathyGstAudioSink { + GstBin parent; +}; + +GType empathy_audio_sink_get_type(void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_GST_AUDIO_SINK \ + (empathy_audio_sink_get_type()) +#define EMPATHY_GST_AUDIO_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_GST_AUDIO_SINK, \ + EmpathyGstAudioSink)) +#define EMPATHY_GST_AUDIO_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_GST_AUDIO_SINK, \ + EmpathyGstAudioSinkClass)) +#define EMPATHY_IS_GST_AUDIO_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_GST_AUDIO_SINK)) +#define EMPATHY_IS_GST_AUDIO_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_GST_AUDIO_SINK)) +#define EMPATHY_GST_AUDIO_SINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_GST_AUDIO_SINK, \ + EmpathyGstAudioSinkClass)) + +GstElement *empathy_audio_sink_new (void); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_GST_AUDIO_SINK_H__*/ diff --git a/libempathy-gtk/empathy-audio-src.c b/libempathy-gtk/empathy-audio-src.c new file mode 100644 index 00000000..c7437e93 --- /dev/null +++ b/libempathy-gtk/empathy-audio-src.c @@ -0,0 +1,125 @@ +/* + * empathy-gst-audio-src.c - Source for EmpathyGstAudioSrc + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include + +#include "empathy-audio-src.h" + +G_DEFINE_TYPE(EmpathyGstAudioSrc, empathy_audio_src, GST_TYPE_BIN) + +/* signal enum */ +#if 0 +enum +{ + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; +#endif + +/* private structure */ +typedef struct _EmpathyGstAudioSrcPrivate EmpathyGstAudioSrcPrivate; + +struct _EmpathyGstAudioSrcPrivate +{ + gboolean dispose_has_run; + GstElement *src; +}; + +#define EMPATHY_GST_AUDIO_SRC_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_GST_AUDIO_SRC, \ + EmpathyGstAudioSrcPrivate)) + +static void +empathy_audio_src_init (EmpathyGstAudioSrc *obj) +{ + EmpathyGstAudioSrcPrivate *priv = EMPATHY_GST_AUDIO_SRC_GET_PRIVATE (obj); + //GstElement *resample; + GstPad *ghost, *src; + + /* allocate any data required by the object here */ + //resample = gst_element_factory_make ("audioresample", NULL); + + priv->src = gst_element_factory_make ("gconfaudiosrc", NULL); + + //gst_bin_add_many (GST_BIN (obj), priv->src, resample, NULL); + gst_bin_add_many (GST_BIN (obj), priv->src, NULL); + //gst_element_link_many (priv->src, resample, NULL); + + //src = gst_element_get_static_pad (resample, "src"); + src = gst_element_get_static_pad (priv->src, "src"); + + ghost = gst_ghost_pad_new ("src", src); + gst_element_add_pad (GST_ELEMENT (obj), ghost); + + gst_object_unref (G_OBJECT (src)); +} + +static void empathy_audio_src_dispose (GObject *object); +static void empathy_audio_src_finalize (GObject *object); + +static void +empathy_audio_src_class_init (EmpathyGstAudioSrcClass + *empathy_audio_src_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (empathy_audio_src_class); + + g_type_class_add_private (empathy_audio_src_class, + sizeof (EmpathyGstAudioSrcPrivate)); + + object_class->dispose = empathy_audio_src_dispose; + object_class->finalize = empathy_audio_src_finalize; +} + +void +empathy_audio_src_dispose (GObject *object) +{ + EmpathyGstAudioSrc *self = EMPATHY_GST_AUDIO_SRC (object); + EmpathyGstAudioSrcPrivate *priv = EMPATHY_GST_AUDIO_SRC_GET_PRIVATE (self); + + if (priv->dispose_has_run) + return; + + priv->dispose_has_run = TRUE; + + /* release any references held by the object here */ + + if (G_OBJECT_CLASS (empathy_audio_src_parent_class)->dispose) + G_OBJECT_CLASS (empathy_audio_src_parent_class)->dispose (object); +} + +void +empathy_audio_src_finalize (GObject *object) +{ + //EmpathyGstAudioSrc *self = EMPATHY_GST_AUDIO_SRC (object); + //EmpathyGstAudioSrcPrivate *priv = EMPATHY_GST_AUDIO_SRC_GET_PRIVATE (self); + + /* free any data held directly by the object here */ + + G_OBJECT_CLASS (empathy_audio_src_parent_class)->finalize (object); +} + +GstElement * +empathy_audio_src_new (void) +{ + return GST_ELEMENT (g_object_new (EMPATHY_TYPE_GST_AUDIO_SRC, NULL)); +} diff --git a/libempathy-gtk/empathy-audio-src.h b/libempathy-gtk/empathy-audio-src.h new file mode 100644 index 00000000..73ebd157 --- /dev/null +++ b/libempathy-gtk/empathy-audio-src.h @@ -0,0 +1,63 @@ +/* + * empathy-gst-video-src.h - Header for EmpathyGstAudioSrc + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_GST_AUDIO_SRC_H__ +#define __EMPATHY_GST_AUDIO_SRC_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyGstAudioSrc EmpathyGstAudioSrc; +typedef struct _EmpathyGstAudioSrcClass EmpathyGstAudioSrcClass; + +struct _EmpathyGstAudioSrcClass { + GstBinClass parent_class; +}; + +struct _EmpathyGstAudioSrc { + GstBin parent; +}; + +GType empathy_audio_src_get_type(void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_GST_AUDIO_SRC \ + (empathy_audio_src_get_type()) +#define EMPATHY_GST_AUDIO_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_GST_AUDIO_SRC, \ + EmpathyGstAudioSrc)) +#define EMPATHY_GST_AUDIO_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_GST_AUDIO_SRC, \ + EmpathyGstAudioSrcClass)) +#define EMPATHY_IS_GST_AUDIO_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_GST_AUDIO_SRC)) +#define EMPATHY_IS_GST_AUDIO_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_GST_AUDIO_SRC)) +#define EMPATHY_GST_AUDIO_SRC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_GST_AUDIO_SRC, \ + EmpathyGstAudioSrcClass)) + +GstElement *empathy_audio_src_new (void); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_GST_AUDIO_SRC_H__*/ diff --git a/libempathy-gtk/empathy-video-src.c b/libempathy-gtk/empathy-video-src.c new file mode 100644 index 00000000..3a654830 --- /dev/null +++ b/libempathy-gtk/empathy-video-src.c @@ -0,0 +1,134 @@ +/* + * empathy-gst-video-src.c - Source for EmpathyGstVideoSrc + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include + +#include "empathy-video-src.h" + +G_DEFINE_TYPE(EmpathyGstVideoSrc, empathy_video_src, GST_TYPE_BIN) + +/* signal enum */ +#if 0 +enum +{ + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; +#endif + +/* private structure */ +typedef struct _EmpathyGstVideoSrcPrivate EmpathyGstVideoSrcPrivate; + +struct _EmpathyGstVideoSrcPrivate +{ + gboolean dispose_has_run; + GstElement *src; +}; + +#define EMPATHY_GST_VIDEO_SRC_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_GST_VIDEO_SRC, \ + EmpathyGstVideoSrcPrivate)) + +static void +empathy_video_src_init (EmpathyGstVideoSrc *obj) +{ + EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (obj); + GstElement *scale, *rate, *colorspace, *capsfilter; + GstPad *ghost, *src; + GstCaps *caps; + + /* allocate any data required by the object here */ + scale = gst_element_factory_make ("videoscale", NULL); + rate = gst_element_factory_make ("videorate", NULL); + colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL); + + capsfilter = gst_element_factory_make ("capsfilter", NULL); + caps = gst_caps_new_simple ("video/x-raw-yuv", + "width", G_TYPE_INT, 320, + "height", G_TYPE_INT, 240, + NULL); + + g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL); + + priv->src = gst_element_factory_make ("gconfvideosrc", NULL); + + gst_bin_add_many (GST_BIN (obj), priv->src, scale, rate, + colorspace, capsfilter, NULL); + gst_element_link_many (priv->src, scale, rate, colorspace, capsfilter, NULL); + + src = gst_element_get_static_pad (capsfilter, "src"); + + ghost = gst_ghost_pad_new ("src", src); + gst_element_add_pad (GST_ELEMENT (obj), ghost); + + gst_object_unref (G_OBJECT (src)); +} + +static void empathy_video_src_dispose (GObject *object); +static void empathy_video_src_finalize (GObject *object); + +static void +empathy_video_src_class_init (EmpathyGstVideoSrcClass *empathy_video_src_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (empathy_video_src_class); + + g_type_class_add_private (empathy_video_src_class, + sizeof (EmpathyGstVideoSrcPrivate)); + + object_class->dispose = empathy_video_src_dispose; + object_class->finalize = empathy_video_src_finalize; +} + +void +empathy_video_src_dispose (GObject *object) +{ + EmpathyGstVideoSrc *self = EMPATHY_GST_VIDEO_SRC (object); + EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (self); + + if (priv->dispose_has_run) + return; + + priv->dispose_has_run = TRUE; + + /* release any references held by the object here */ + + if (G_OBJECT_CLASS (empathy_video_src_parent_class)->dispose) + G_OBJECT_CLASS (empathy_video_src_parent_class)->dispose (object); +} + +void +empathy_video_src_finalize (GObject *object) +{ + //EmpathyGstVideoSrc *self = EMPATHY_GST_VIDEO_SRC (object); + //EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (self); + + /* free any data held directly by the object here */ + + G_OBJECT_CLASS (empathy_video_src_parent_class)->finalize (object); +} + +GstElement * +empathy_video_src_new (void) +{ + return GST_ELEMENT (g_object_new (EMPATHY_TYPE_GST_VIDEO_SRC, NULL)); +} diff --git a/libempathy-gtk/empathy-video-src.h b/libempathy-gtk/empathy-video-src.h new file mode 100644 index 00000000..3af2efe8 --- /dev/null +++ b/libempathy-gtk/empathy-video-src.h @@ -0,0 +1,63 @@ +/* + * empathy-gst-video-src.h - Header for EmpathyGstVideoSrc + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_GST_VIDEO_SRC_H__ +#define __EMPATHY_GST_VIDEO_SRC_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyGstVideoSrc EmpathyGstVideoSrc; +typedef struct _EmpathyGstVideoSrcClass EmpathyGstVideoSrcClass; + +struct _EmpathyGstVideoSrcClass { + GstBinClass parent_class; +}; + +struct _EmpathyGstVideoSrc { + GstBin parent; +}; + +GType empathy_video_src_get_type(void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_GST_VIDEO_SRC \ + (empathy_video_src_get_type()) +#define EMPATHY_GST_VIDEO_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_GST_VIDEO_SRC, \ + EmpathyGstVideoSrc)) +#define EMPATHY_GST_VIDEO_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_GST_VIDEO_SRC, \ + EmpathyGstVideoSrcClass)) +#define EMPATHY_IS_GST_VIDEO_SRC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_GST_VIDEO_SRC)) +#define EMPATHY_IS_GST_VIDEO_SRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_GST_VIDEO_SRC)) +#define EMPATHY_GST_VIDEO_SRC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_GST_VIDEO_SRC, \ + EmpathyGstVideoSrcClass)) + +GstElement *empathy_video_src_new (void); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_GST_VIDEO_SRC_H__*/ diff --git a/libempathy-gtk/empathy-video-widget.c b/libempathy-gtk/empathy-video-widget.c new file mode 100644 index 00000000..7941b319 --- /dev/null +++ b/libempathy-gtk/empathy-video-widget.c @@ -0,0 +1,298 @@ +/* + * empathy-gst-gtk-widget.c - Source for EmpathyVideoWidget + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include + +#include +#include +#include + +#include "empathy-video-widget.h" + +G_DEFINE_TYPE(EmpathyVideoWidget, empathy_video_widget, + GTK_TYPE_DRAWING_AREA) + +static void empathy_video_widget_element_added_cb ( + FsElementAddedNotifier *notifier, GstBin *bin, GstElement *element, + EmpathyVideoWidget *self); + +static void empathy_video_widget_sync_message_cb ( + GstBus *bus, GstMessage *message, EmpathyVideoWidget *self); + +/* signal enum */ +#if 0 +enum +{ + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; +#endif + +enum { + PROP_GST_ELEMENT = 1, + PROP_GST_BUS, +}; + +/* private structure */ +typedef struct _EmpathyVideoWidgetPriv EmpathyVideoWidgetPriv; + +struct _EmpathyVideoWidgetPriv +{ + gboolean dispose_has_run; + GstBus *bus; + GstElement *videosink; + GstPad *sink_pad; + GstElement *overlay; + FsElementAddedNotifier *notifier; +}; + +#define GET_PRIV(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + EMPATHY_TYPE_GST_GTK_WIDGET, EmpathyVideoWidgetPriv)) + +static void +empathy_video_widget_init (EmpathyVideoWidget *obj) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (obj); + + priv->notifier = fs_element_added_notifier_new (); + g_signal_connect (priv->notifier, "element-added", + G_CALLBACK (empathy_video_widget_element_added_cb), + obj); + + gtk_widget_set_size_request (GTK_WIDGET (obj), 320, 240); + + GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (obj), GTK_DOUBLE_BUFFERED); +} + +static void +empathy_video_widget_constructed (GObject *object) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (object); + + priv->videosink = gst_element_factory_make ("gconfvideosink", NULL); + priv->sink_pad = gst_element_get_static_pad (priv->videosink, "sink"); + + fs_element_added_notifier_add (priv->notifier, GST_BIN (priv->videosink)); + gst_bus_enable_sync_message_emission (priv->bus); + + g_signal_connect (priv->bus, "sync-message", + G_CALLBACK (empathy_video_widget_sync_message_cb), object); + +} + +static void empathy_video_widget_dispose (GObject *object); +static void empathy_video_widget_finalize (GObject *object); +static gboolean empathy_video_widget_expose_event (GtkWidget *widget, + GdkEventExpose *event); + +static void +empathy_video_widget_set_property (GObject *object, + guint property_id, const GValue *value, GParamSpec *pspec) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_GST_BUS: + priv->bus = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +empathy_video_widget_get_property (GObject *object, + guint property_id, GValue *value, GParamSpec *pspec) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_GST_ELEMENT: + g_value_set_object (value, priv->videosink); + break; + case PROP_GST_BUS: + g_value_set_object (value, priv->bus); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + + +static void +empathy_video_widget_class_init ( + EmpathyVideoWidgetClass *empathy_video_widget_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (empathy_video_widget_class); + GtkWidgetClass *widget_class = + GTK_WIDGET_CLASS (empathy_video_widget_class); + GParamSpec *param_spec; + + g_type_class_add_private (empathy_video_widget_class, + sizeof (EmpathyVideoWidgetPriv)); + + object_class->dispose = empathy_video_widget_dispose; + object_class->finalize = empathy_video_widget_finalize; + object_class->constructed = empathy_video_widget_constructed; + + object_class->set_property = empathy_video_widget_set_property; + object_class->get_property = empathy_video_widget_get_property; + + widget_class->expose_event = empathy_video_widget_expose_event; + + param_spec = g_param_spec_object ("gst-element", + "gst-element", "The underlaying gstreamer element", + GST_TYPE_ELEMENT, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_GST_ELEMENT, param_spec); + + param_spec = g_param_spec_object ("gst-bus", + "gst-bus", + "The toplevel bus from the pipeline in which this bin will be added", + GST_TYPE_BUS, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_GST_BUS, param_spec); +} + +void +empathy_video_widget_dispose (GObject *object) +{ + EmpathyVideoWidget *self = EMPATHY_VIDEO_WIDGET (object); + EmpathyVideoWidgetPriv *priv = GET_PRIV (self); + + if (priv->dispose_has_run) + return; + + priv->dispose_has_run = TRUE; + + if (priv->bus != NULL) + g_object_unref (priv->bus); + + priv->bus = NULL; + + /* release any references held by the object here */ + + if (G_OBJECT_CLASS (empathy_video_widget_parent_class)->dispose) + G_OBJECT_CLASS (empathy_video_widget_parent_class)->dispose (object); +} + +void +empathy_video_widget_finalize (GObject *object) +{ + //EmpathyVideoWidget *self = EMPATHY_VIDEO_WIDGET (object); + //EmpathyVideoWidgetPriv *priv = GET_PRIV (self); + + /* free any data held directly by the object here */ + + G_OBJECT_CLASS (empathy_video_widget_parent_class)->finalize (object); +} + +static void +empathy_video_widget_element_added_cb (FsElementAddedNotifier *notifier, + GstBin *bin, GstElement *element, EmpathyVideoWidget *self) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (self); + + if (priv->overlay == NULL && GST_IS_X_OVERLAY (element)) + { + priv->overlay = element; + gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay)); + } + + if (g_object_class_find_property ( + G_OBJECT_GET_CLASS (element), "force-aspect-ratio")) + { + g_object_set (G_OBJECT (element), "force-aspect-ratio", TRUE, NULL); + } +} + +static void +empathy_video_widget_sync_message_cb (GstBus *bus, GstMessage *message, + EmpathyVideoWidget *self) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (self); + const GstStructure *s; + + if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) + return; + + if (GST_MESSAGE_SRC (message) != (GstObject *) priv->overlay) + return; + + s = gst_message_get_structure (message); + + if (gst_structure_has_name (s, "prepare-xwindow-id")) + { + gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (priv->overlay), + GDK_WINDOW_XID (GTK_WIDGET (self)->window)); + } +} + +static gboolean +empathy_video_widget_expose_event (GtkWidget *widget, GdkEventExpose *event) +{ + EmpathyVideoWidget *self = EMPATHY_VIDEO_WIDGET (widget); + EmpathyVideoWidgetPriv *priv = GET_PRIV (self); + + if (event != NULL && event->count > 0) + return TRUE; + + if (priv->overlay == NULL) + return TRUE; + + gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (priv->overlay), + GDK_WINDOW_XID (widget->window)); + + gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay)); + + return TRUE; +} + + +GtkWidget * +empathy_video_widget_new (GstBus *bus) +{ + g_return_val_if_fail (bus != NULL, NULL); + + return GTK_WIDGET (g_object_new (EMPATHY_TYPE_GST_GTK_WIDGET, + "gst-bus", bus, + NULL)); +} + +GstPad * +empathy_video_widget_get_sink (EmpathyVideoWidget *widget) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (widget); + + return priv->sink_pad; +} + +GstElement * +empathy_video_widget_get_element (EmpathyVideoWidget *widget) +{ + EmpathyVideoWidgetPriv *priv = GET_PRIV (widget); + + return priv->videosink; +} diff --git a/libempathy-gtk/empathy-video-widget.h b/libempathy-gtk/empathy-video-widget.h new file mode 100644 index 00000000..3ced3beb --- /dev/null +++ b/libempathy-gtk/empathy-video-widget.h @@ -0,0 +1,67 @@ +/* + * empathy-gst-gtk-widget.h - Header for EmpathyVideoWidget + * Copyright (C) 2008 Collabora Ltd. + * @author Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_VIDEO_WIDGET_H__ +#define __EMPATHY_VIDEO_WIDGET_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyVideoWidget EmpathyVideoWidget; +typedef struct _EmpathyVideoWidgetClass EmpathyVideoWidgetClass; + +struct _EmpathyVideoWidgetClass { + GtkDrawingAreaClass parent_class; +}; + +struct _EmpathyVideoWidget { + GtkDrawingArea parent; +}; + +GType empathy_video_widget_get_type(void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_GST_GTK_WIDGET \ + (empathy_video_widget_get_type()) +#define EMPATHY_VIDEO_WIDGET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_GST_GTK_WIDGET, \ + EmpathyVideoWidget)) +#define EMPATHY_VIDEO_WIDGET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_GST_GTK_WIDGET, \ + EmpathyVideoWidgetClass)) +#define EMPATHY_IS_GST_GTK_WIDGET(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_GST_GTK_WIDGET)) +#define EMPATHY_IS_GST_GTK_WIDGET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_GST_GTK_WIDGET)) +#define EMPATHY_VIDEO_WIDGET_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_GST_GTK_WIDGET, \ + EmpathyVideoWidgetClass)) + +GtkWidget *empathy_video_widget_new (GstBus *bus); + +GstElement *empathy_video_widget_get_element (EmpathyVideoWidget *widget); +GstPad *empathy_video_widget_get_sink (EmpathyVideoWidget *widget); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_VIDEO_WIDGET_H__*/