diff options
Diffstat (limited to 'libempathy-gtk/empathy-video-src.c')
-rw-r--r-- | libempathy-gtk/empathy-video-src.c | 120 |
1 files changed, 107 insertions, 13 deletions
diff --git a/libempathy-gtk/empathy-video-src.c b/libempathy-gtk/empathy-video-src.c index aa4d35ac2..5c865daaa 100644 --- a/libempathy-gtk/empathy-video-src.c +++ b/libempathy-gtk/empathy-video-src.c @@ -56,37 +56,131 @@ struct _EmpathyGstVideoSrcPrivate #define EMPATHY_GST_VIDEO_SRC_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_GST_VIDEO_SRC, \ EmpathyGstVideoSrcPrivate)) +/** + * empathy_gst_add_to_bin - create a new gst element, add to bin and link it. + * @bin - bin to add the new element to. + * @src - src element for the new element (may be NULL). + * @name - name of the factory for the new element + * + * Returns: The newly created element ot %NULL on failure + */ +static GstElement * +empathy_gst_add_to_bin (GstBin *bin, + GstElement *src, + const gchar *factoryname) +{ + GstElement *ret; + + if ((ret = gst_element_factory_make (factoryname, NULL)) == NULL) + { + g_message ("Element factory \"%s\" not found.", factoryname); + goto error; + } + + if (!gst_bin_add (bin, ret)) + { + g_warning ("Couldn't add \"%s\" to bin.", factoryname); + goto error; + } + + /* do not link if src == NULL, just exit here */ + if (src == NULL) + return ret; + + if (!gst_element_link (src, ret)) + { + g_warning ("Failed to link \"%s\".", factoryname); + gst_bin_remove (bin, ret); + goto error; + } + + return ret; + +error: + if (ret != NULL) + gst_object_unref (ret); + return NULL; +} + static void empathy_video_src_init (EmpathyGstVideoSrc *obj) { EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (obj); - GstElement *scale, *colorspace, *capsfilter; + GstElement *element, *element_back; GstPad *ghost, *src; GstCaps *caps; + gchar *str; - /* allocate any data required by the object here */ - scale = gst_element_factory_make ("videoscale", NULL); - colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL); - - capsfilter = gst_element_factory_make ("capsfilter", NULL); + /* allocate caps here, so we can update it by optional elements */ 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); + /* allocate any data required by the object here */ + if ((element = empathy_gst_add_to_bin (GST_BIN (obj), + NULL, "gconfvideosrc")) == NULL) + g_error ("Couldn't add \"gconfvideosrc\" (gst-plugins-good missing?)"); + + /* we need to save our source to priv->src */ + priv->src = element; + + /* videomaxrate is optional as it's part of gst-plugins-bad. So don't + * fail if it doesn't exist. */ + element_back = element; + if ((element = empathy_gst_add_to_bin (GST_BIN (obj), + element, "videomaxrate")) == NULL) + { + g_message ("Couldn't add \"videomaxrate\" (gst-plugins-bad missing?)"); + element = element_back; + } + else + { + gst_caps_set_simple (caps, + "framerate", GST_TYPE_FRACTION, 15, 1, + NULL); + } + + str = gst_caps_to_string (caps); + g_debug ("Current video src caps are : %s", str); + g_free (str); - priv->src = gst_element_factory_make ("gconfvideosrc", NULL); + if ((element = empathy_gst_add_to_bin (GST_BIN (obj), + element, "ffmpegcolorspace")) == NULL) + g_error ("Failed to add \"ffmpegcolorspace\" (gst-plugins-base missing?)"); - gst_bin_add_many (GST_BIN (obj), priv->src, scale, colorspace, capsfilter, - NULL); - gst_element_link_many (priv->src, scale, colorspace, capsfilter, NULL); + if ((element = empathy_gst_add_to_bin (GST_BIN (obj), + element, "videoscale")) == NULL) + g_error ("Failed to add \"videoscale\", (gst-plugins-base missing?)"); - src = gst_element_get_static_pad (capsfilter, "src"); + if ((element = empathy_gst_add_to_bin (GST_BIN (obj), + element, "capsfilter")) == NULL) + g_error ( + "Failed to add \"capsfilter\" (gstreamer core elements missing?)"); + + g_object_set (G_OBJECT (element), "caps", caps, NULL); + + + /* optionally add postproc_tmpnoise to improve the performance of encoders */ + element_back = element; + if ((element = empathy_gst_add_to_bin (GST_BIN (obj), + element, "postproc_tmpnoise")) == NULL) + { + g_message ("Failed to add \"postproc_tmpnoise\" (gst-ffmpeg missing?)"); + element = element_back; + } + + src = gst_element_get_static_pad (element, "src"); + g_assert (src != NULL); ghost = gst_ghost_pad_new ("src", src); - gst_element_add_pad (GST_ELEMENT (obj), ghost); + if (ghost == NULL) + g_error ("Unable to create ghost pad for the videosrc"); + + if (!gst_element_add_pad (GST_ELEMENT (obj), ghost)) + g_error ("pad with the same name already existed or " + "the pad already had another parent."); gst_object_unref (G_OBJECT (src)); } |