summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Krishnamurthy <pavan.krishnamurthy@nokia.com>2010-09-21 17:55:19 (GMT)
committerPavan Krishnamurthy <pavan.krishnamurthy@nokia.com>2010-09-21 17:55:19 (GMT)
commit0e59c508135571e33feeea072b05aa8e5644e698 (patch)
tree8cc8464306c8bea688470e46d2e7a632b47fccac
parent300f3731e61b88b21066aa558675e48aff1e978e (diff)
parentc89e4c7d6788621d0ae62a19ab7ca98575939ede (diff)
downloadtelepathy-stream-engine-0e59c508135571e33feeea072b05aa8e5644e698.tar.gz
telepathy-stream-engine-0e59c508135571e33feeea072b05aa8e5644e698.tar.xz
Merge branch 'master' into local-maemo-debian-harmattan
Conflicts: .gitignore
-rw-r--r--.gitignore17
-rw-r--r--configure.ac7
-rw-r--r--gstcodecs.conf36
-rw-r--r--gstelements.conf31
-rw-r--r--src/Makefile.am4
-rw-r--r--src/audiostream.c33
-rw-r--r--src/stream-engine-main.c7
-rw-r--r--src/thread-tracker.c315
-rw-r--r--src/thread-tracker.h66
-rw-r--r--src/tp-stream-engine.c413
-rw-r--r--src/videosink.c181
-rw-r--r--src/videostream.c4
12 files changed, 608 insertions, 506 deletions
diff --git a/.gitignore b/.gitignore
index 369871b..7323c8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,23 +20,6 @@ src/telepathy-stream-engine
src/tp-stream-engine-signals-marshal.[ch]
src/tp-stream-engine-signals-marshal.list
-telepathy-farsight/tf-signals-marshal.[ch]
-telepathy-farsight/tf-signals-marshal.list
-
-telepathy-farsight/telepathy-farsight.pc
-
-
-doc/lib/telepathy-farsight-libs-decl-list.txt
-doc/lib/telepathy-farsight-libs-decl-list.txt.bak
-doc/lib/telepathy-farsight-libs-decl.txt
-doc/lib/telepathy-farsight-libs-decl.txt.bak
-doc/lib/telepathy-farsight-libs-undocumented.txt
-doc/lib/telepathy-farsight-libs-unused.txt
-doc/lib/telepathy-farsight-libs.args
-doc/lib/telepathy-farsight-libs.hierarchy
-doc/lib/telepathy-farsight-libs.interfaces
-doc/lib/telepathy-farsight-libs.prerequisites
-doc/lib/telepathy-farsight-libs.signals
aclocal.m4
autom4te.cache
diff --git a/configure.ac b/configure.ac
index f2cb2cf..f7c24ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,7 +10,7 @@ AC_PREREQ([2.59])
m4_define([stream_engine_major_version], [0])
m4_define([stream_engine_minor_version], [5])
m4_define([stream_engine_micro_version], [15])
-m4_define([stream_engine_nano_version], [0])
+m4_define([stream_engine_nano_version], [1])
# Some magic
m4_define([stream_engine_base_version],
@@ -139,11 +139,6 @@ PKG_CHECK_MODULES(HAL, [hal])
AC_SUBST(HAL_CFLAGS)
AC_SUBST(HAL_LIBS)
-dnl libx11
-PKG_CHECK_MODULES(X11, [x11 gtk+-2.0])
-AC_SUBST(X11_CFLAGS)
-AC_SUBST(X11_LIBS)
-
AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
AC_DEFINE_UNQUOTED(SYSCONFDIR, "$SYSCONFDIR", [System configuration directory])
diff --git a/gstcodecs.conf b/gstcodecs.conf
index dbe8d9e..a5e861d 100644
--- a/gstcodecs.conf
+++ b/gstcodecs.conf
@@ -1,28 +1,31 @@
+[audio/G729]
+clock-rate=8000
+
[audio/iLBC]
mode=30
clock-rate=8000
-[audio/AMR]
+[audio/PCMA]
clock-rate=8000
-[audio/GSM]
+[audio/PCMU]
clock-rate=8000
-[audio/G729]
+[audio/speex]
clock-rate=8000
-[audio/PCMA]
+# Disable because the current codec is broken
+[audio/AMR]
+id=-1
clock-rate=8000
-[audio/PCMU]
+[audio/GSM]
clock-rate=8000
-[audio/speex]
-id=-1
-
[video/THEORA]
id=-1
+# Not good for voip
[audio/VORBIS]
id=-1
@@ -32,12 +35,27 @@ id=-1
[audio/MPV]
id=-1
-[video/H263]
+#Disable DV, its 90000
+[audio/DV]
+id=-1
+
+# 16000Hz not supported
+[audio/AMR-WB]
+id=-1
[video/H264]
+[video/H263]
+
[video/H263-1998]
# Payloader is broken, see gnome bug #577784
[video/H263-2000]
id=-1
+
+[video/JPEG]
+id=-1
+
+#Disable DV.. wtf
+[video/DV]
+id=-1
diff --git a/gstelements.conf b/gstelements.conf
index 27290cb..f7a9f43 100644
--- a/gstelements.conf
+++ b/gstelements.conf
@@ -1,2 +1,33 @@
[gstrtpbin]
latency=100
+
+[gstrtpjitterbuffer]
+do-lost=1
+
+[pulsesrc]
+device=source.voice
+latency-time=40000
+
+[pulsesink]
+device=sink.voice
+latency-time=40000
+buffer-time=80000
+
+[v4l2camsrc]
+device=/dev/video1
+queue-size=8
+driver-name=omap3cam
+
+[subdevsrc]
+camera-device=1
+
+[rtph264pay]
+spspps-interval=3
+config-interval=3
+
+[dsph263enc]
+mode=1
+
+[dsph264enc]
+mode=1
+
diff --git a/src/Makefile.am b/src/Makefile.am
index e92061d..e797745 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,8 @@ libexec_PROGRAMS = telepathy-stream-engine
telepathy_stream_engine_SOURCES = \
stream-engine-main.c \
+ thread-tracker.c \
+ thread-tracker.h \
tp-stream-engine.h \
tp-stream-engine.c \
util.h \
@@ -29,7 +31,6 @@ AM_CFLAGS = \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \
$(HAL_CFLAGS) \
- $(X11_CFLAGS) \
$(GST_CFLAGS) \
$(GST_VIDEO_CFLAGS) \
$(GST_INTERFACES_CFLAGS) \
@@ -43,7 +44,6 @@ AM_LDFLAGS = \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(HAL_LIBS) \
- $(X11_LIBS) \
$(GST_LIBS) \
$(GST_VIDEO_LIBS) \
$(GST_INTERFACES_LIBS) \
diff --git a/src/audiostream.c b/src/audiostream.c
index eb74c9d..30093df 100644
--- a/src/audiostream.c
+++ b/src/audiostream.c
@@ -107,6 +107,7 @@ static void tp_stream_engine_audio_stream_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
+static void sink_pad_unlinked (GstPad *pad, GstPad *peer, gpointer user_data);
static void src_pad_added_cb (TfStream *stream, GstPad *pad,
FsCodec *codec, gpointer user_data);
@@ -217,6 +218,10 @@ free_sinkbin (gpointer data, gpointer user_data)
{
TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (user_data);
GstElement *bin = data;
+ GstPad *sinkpad = gst_element_get_static_pad (bin, "sink");
+
+ g_signal_handlers_disconnect_by_func (sinkpad, sink_pad_unlinked, self);
+ gst_object_unref (sinkpad);
gst_element_set_locked_state (bin, TRUE);
gst_element_set_state (bin, GST_STATE_NULL);
@@ -392,7 +397,8 @@ tp_stream_engine_audio_stream_make_src_bin (TpStreamEngineAudioStream *self,
GError **error)
{
const gchar *audiosrc = "pulsesrc ! "
- "capsfilter caps=\"audio/x-raw-int,rate=(int)8000,channels=(int)1\"";
+ "capsfilter caps=\"audio/x-raw-int,rate=(int)8000,channels=(int)1,"
+ "width=(int)16,height=(int)16\"";
if (g_getenv ("FS_AUDIOSRC"))
audiosrc = g_getenv ("FS_AUDIOSRC");
@@ -428,6 +434,28 @@ tp_stream_engine_audio_stream_new (TfStream *stream,
return self;
}
+static void
+sink_pad_unlinked (GstPad *pad, GstPad *peer, gpointer user_data)
+{
+ TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (user_data);
+ GstElement *sink = gst_pad_get_parent_element (pad);
+
+ if (!sink)
+ {
+ WARNING (self, "Sink pad unlinked, but has no parent left");
+ return;
+ }
+
+ DEBUG (self, "Unlinked %s:%s -> %s:%s", GST_DEBUG_PAD_NAME (peer),
+ GST_DEBUG_PAD_NAME (pad));
+
+ g_mutex_lock (self->priv->mutex);
+ self->priv->sinkbins = g_list_remove (self->priv->sinkbins, sink);
+ g_mutex_unlock (self->priv->mutex);
+
+ free_sinkbin (sink, self);
+}
+
static gboolean
src_pad_added_idle_error (gpointer user_data)
{
@@ -493,6 +521,9 @@ src_pad_added_cb (TfStream *stream, GstPad *pad, FsCodec *codec,
sinkpad = gst_element_get_static_pad (sink, "sink");
+ g_signal_connect (sinkpad, "unlinked", G_CALLBACK (sink_pad_unlinked),
+ self);
+
if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sinkpad)))
{
WARNING (self, "Could not link farsight pad to sink");
diff --git a/src/stream-engine-main.c b/src/stream-engine-main.c
index bd6598f..d2c474c 100644
--- a/src/stream-engine-main.c
+++ b/src/stream-engine-main.c
@@ -42,8 +42,6 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-
#include <dbus/dbus-glib.h>
#include <gst/gst.h>
@@ -178,8 +176,8 @@ int main(int argc, char **argv)
if (setrlimit(RLIMIT_RTPRIO, &rl) < 0)
g_warning("setrlimit rtprio: %s", strerror (errno));
- rl.rlim_max = 15;
- rl.rlim_cur = 15;
+ rl.rlim_max = 20;
+ rl.rlim_cur = 20;
if (setrlimit(RLIMIT_NICE, &rl) < 0)
g_warning("setrlimit rtprio: %s", strerror (errno));
@@ -202,7 +200,6 @@ int main(int argc, char **argv)
optcontext = g_option_context_new ("Telepathy Stream Engine");
g_option_context_add_group (optcontext, gst_init_get_option_group ());
- g_option_context_add_group (optcontext, gtk_get_option_group (TRUE));
if (g_option_context_parse (optcontext, &argc, &argv, &error) == FALSE) {
g_print ("%s\nRun '%s --help' to see a full list of available command line options.\n",
diff --git a/src/thread-tracker.c b/src/thread-tracker.c
new file mode 100644
index 0000000..92d5824
--- /dev/null
+++ b/src/thread-tracker.c
@@ -0,0 +1,315 @@
+/*
+ * thread-tracker.c - Tracks threads in a GstPipeline
+ * Copyright (C) 2009-2010 Collabora Ltd.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "thread-tracker.h"
+
+#include <pthread.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include <gst/gst.h>
+
+static gboolean add_pad_locked (struct ObjectTrackingData *otd, GstPad *pad);
+
+
+void
+thread_tracking_init (struct ThreadTrackingData *ttd,
+ GMutex *mutex,
+ setup_thread_prio restore_thread_prio)
+{
+ ttd->object_threads =
+ g_hash_table_new (g_direct_hash, g_direct_equal);
+ ttd->object_tids =
+ g_hash_table_new (g_direct_hash, g_direct_equal);
+ ttd->otds = g_ptr_array_new ();
+ ttd->mutex = mutex;
+ ttd->restore_thread_prio = restore_thread_prio;
+}
+
+void
+object_tracking_init (struct ThreadTrackingData *ttd,
+ struct ObjectTrackingData *otd,
+ setup_thread_prio setup_thread_prio)
+{
+ otd->ttd = ttd;
+ otd->objects = g_ptr_array_new ();
+ otd->setup_thread_prio = setup_thread_prio;
+ g_ptr_array_add (ttd->otds, otd);
+}
+
+
+void
+thread_tracking_data_free (struct ThreadTrackingData *ttd)
+{
+ g_hash_table_destroy (ttd->object_threads);
+ g_hash_table_destroy (ttd->object_tids);
+ g_ptr_array_free (ttd->otds, TRUE);
+}
+
+void
+object_tracking_data_free (struct ObjectTrackingData *otd)
+{
+ g_ptr_array_free (otd->objects, TRUE);
+ g_ptr_array_remove (otd->ttd->otds, otd);
+}
+
+
+
+static void
+remove_object (gpointer data, GObject *where_the_obj_was)
+{
+ struct ObjectTrackingData *otd = data;
+
+ g_mutex_lock (otd->ttd->mutex);
+ g_ptr_array_remove (otd->objects, where_the_obj_was);
+ g_mutex_unlock (otd->ttd->mutex);
+}
+
+static void
+pad_linked (GstPad *pad, GstPad *peer, struct ObjectTrackingData *otd);
+
+/* Returns TRUE if it is a object
+ * Returns FALSE if it was already added
+ */
+
+static gboolean
+insert_object_locked (struct ObjectTrackingData *otd, gpointer object)
+{
+ guint i;
+ pthread_t thread;
+ pid_t tid;
+
+ for (i = 0; i < otd->objects->len; i++)
+ if (g_ptr_array_index (otd->objects, i) == object)
+ return FALSE;
+
+ g_ptr_array_add (otd->objects, object);
+ g_object_weak_ref (G_OBJECT (object), remove_object, otd);
+
+
+ thread = GPOINTER_TO_UINT (
+ g_hash_table_lookup (otd->ttd->object_threads, object));
+ tid = GPOINTER_TO_UINT (
+ g_hash_table_lookup (otd->ttd->object_tids, object));
+
+ if (thread && tid)
+ otd->setup_thread_prio (thread, tid);
+
+ return TRUE;
+}
+
+static void
+pad_added (GstElement *element, GstPad *pad, struct ObjectTrackingData *otd)
+{
+ add_pad_locked (otd, pad);
+}
+
+/* Returns TRUE if it is a new pad
+ * Returns FALSE if it was already added
+ */
+
+static gboolean
+add_pad_locked (struct ObjectTrackingData *otd, GstPad *pad)
+{
+ GstObject *parent;
+
+ if (!insert_object_locked (otd, pad))
+ return FALSE;
+
+ parent = gst_pad_get_parent (pad);
+
+ if (parent)
+ {
+ if (GST_IS_PAD (parent))
+ {
+ add_pad_locked (otd, GST_PAD_CAST (parent));
+ }
+ else
+ {
+ if (insert_object_locked (otd, parent) &&
+ (GST_IS_ELEMENT (parent) && !GST_IS_BIN (parent)))
+ {
+ g_signal_connect (parent, "pad-added", G_CALLBACK (pad_added),
+ otd);
+ }
+ }
+ gst_object_unref (parent);
+ }
+
+ g_signal_connect (pad, "linked", G_CALLBACK (pad_linked), otd);
+
+ return TRUE;
+}
+
+static void
+pad_iter_locked (gpointer data, gpointer user_data)
+{
+ struct ObjectTrackingData *otd = user_data;
+ GstPad *pad = data;
+
+ if (add_pad_locked (otd, pad))
+ {
+ GstPad *peerpad = gst_pad_get_peer (pad);
+
+ if (peerpad)
+ {
+ if (add_pad_locked (otd, peerpad))
+ {
+ GstIterator *iter;
+
+ iter = gst_pad_iterate_internal_links (peerpad);
+ if (iter)
+ {
+ while (gst_iterator_foreach (iter, pad_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+ gst_iterator_free (iter);
+ }
+ }
+ gst_object_unref (peerpad);
+ }
+ }
+ gst_object_unref (pad);
+}
+
+static void
+pad_linked (GstPad *pad, GstPad *peer, struct ObjectTrackingData *otd)
+{
+ g_mutex_lock (otd->ttd->mutex);
+ if (add_pad_locked (otd, peer))
+ {
+ GstIterator *iter = gst_pad_iterate_internal_links (peer);
+
+ if (iter)
+ {
+ while (gst_iterator_foreach (iter, pad_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+
+ gst_iterator_free (iter);
+ }
+ }
+ g_mutex_unlock (otd->ttd->mutex);
+}
+
+static void
+pad_internal_links_iter_locked (gpointer data, gpointer user_data)
+{
+ struct ObjectTrackingData *otd = user_data;
+ GstPad *pad = data;
+ GstIterator *iter;
+
+ iter = gst_pad_iterate_internal_links (pad);
+ while (gst_iterator_foreach (iter, pad_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+ gst_iterator_free (iter);
+
+ gst_object_unref (pad);
+}
+
+
+void
+object_tracker_add_sink (struct ObjectTrackingData *otd, GstElement *sink)
+{
+ GstIterator *iter;
+
+ g_mutex_lock (otd->ttd->mutex);
+
+ iter = gst_element_iterate_sink_pads (sink);
+ while (gst_iterator_foreach (iter, pad_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+
+ gst_iterator_resync (iter);
+ while (gst_iterator_foreach (iter, pad_internal_links_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+ gst_iterator_free (iter);
+
+ g_mutex_unlock (otd->ttd->mutex);
+}
+
+void
+object_tracker_add_src (struct ObjectTrackingData *otd, GstElement *src)
+{
+ GstIterator *iter;
+
+ g_mutex_lock (otd->ttd->mutex);
+
+ iter = gst_element_iterate_src_pads (src);
+ while (gst_iterator_foreach (iter, pad_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+
+ gst_iterator_resync (iter);
+ while (gst_iterator_foreach (iter, pad_internal_links_iter_locked, otd) ==
+ GST_ITERATOR_RESYNC)
+ gst_iterator_resync (iter);
+ gst_iterator_free (iter);
+
+ g_mutex_unlock (otd->ttd->mutex);
+}
+
+
+void
+enter_thread (struct ThreadTrackingData *ttd, GstObject *src)
+{
+ pthread_t thread = pthread_self ();
+ pid_t tid = syscall (__NR_gettid);
+ guint i, j;
+
+ g_mutex_lock (ttd->mutex);
+ g_hash_table_insert (ttd->object_threads, src, GINT_TO_POINTER (thread));
+ g_hash_table_insert (ttd->object_tids, src, GINT_TO_POINTER (tid));
+
+ for (i = 0; g_ptr_array_index (ttd->otds, i); i++)
+ {
+ struct ObjectTrackingData *otd = g_ptr_array_index (ttd->otds, i);
+
+ for (j = 0; j < otd->objects->len; j++)
+ {
+ if (g_ptr_array_index (otd->objects, j) == src)
+ otd->setup_thread_prio (thread, tid);
+ break;
+ }
+ }
+
+ g_mutex_unlock (ttd->mutex);
+}
+
+
+void
+leave_thread (struct ThreadTrackingData *ttd, GstObject *src, GstElement *owner)
+{
+ pthread_t thread = pthread_self ();
+ pid_t tid = syscall (__NR_gettid);
+
+ g_mutex_lock (ttd->mutex);
+ g_hash_table_remove (ttd->object_threads, src);
+ g_hash_table_remove (ttd->object_tids, src);
+ g_mutex_unlock (ttd->mutex);
+
+ ttd->restore_thread_prio (thread, tid);
+}
diff --git a/src/thread-tracker.h b/src/thread-tracker.h
new file mode 100644
index 0000000..2ef4c32
--- /dev/null
+++ b/src/thread-tracker.h
@@ -0,0 +1,66 @@
+/*
+ * thread-tracker.h - Tracks threads in a GstPipeline
+ * Copyright (C) 2009-2010 Collabora Ltd.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * 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 __THREAD_TRACKER_H__
+#define __THREAD_TRACKER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+typedef void (*setup_thread_prio) (pthread_t thread, pid_t tid);
+
+struct ThreadTrackingData {
+ GMutex *mutex;
+
+ GHashTable *object_threads;
+ GHashTable *object_tids;
+
+ GPtrArray *otds;
+
+ setup_thread_prio restore_thread_prio;
+};
+
+struct ObjectTrackingData {
+ struct ThreadTrackingData *ttd;
+ GPtrArray *objects;
+
+ setup_thread_prio setup_thread_prio;
+};
+
+void thread_tracking_init (struct ThreadTrackingData *ttd,
+ GMutex *mutex,
+ setup_thread_prio restore_thread_prio);
+void object_tracking_init (struct ThreadTrackingData *ttd,
+ struct ObjectTrackingData *otd,
+ setup_thread_prio setup_thread_prio);
+
+void thread_tracking_data_free (struct ThreadTrackingData *ttd);
+void object_tracking_data_free (struct ObjectTrackingData *otd);
+
+void object_tracker_add_sink (struct ObjectTrackingData *otd, GstElement *sink);
+void object_tracker_add_src (struct ObjectTrackingData *otd, GstElement *src);
+
+void enter_thread (struct ThreadTrackingData *ttd, GstObject *src);
+
+G_END_DECLS
+
+#endif /* __THREAD_TRACKER_H__ */
diff --git a/src/tp-stream-engine.c b/src/tp-stream-engine.c
index eee0781..8f44278 100644
--- a/src/tp-stream-engine.c
+++ b/src/tp-stream-engine.c
@@ -37,6 +37,8 @@
#include <sys/types.h>
#include <unistd.h>
+#include <linux/pkt_sched.h>
+
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
@@ -56,6 +58,7 @@
#include "api/api.h"
#include "audiostream.h"
+#include "thread-tracker.h"
#include "videosink.h"
#include "videostream.h"
#include "videopreview.h"
@@ -71,12 +74,14 @@ static void _create_pipeline (TpStreamEngine *self);
static void setup_realtime_thread (pthread_t thread, pid_t tid);
static void low_prio_thread (pthread_t thread, pid_t tid);
+static void restore_thread_prio (pthread_t thread, pid_t tid);
-static void
-update_video_src_caps (TpStreamEngine *self, TfStream *forcedstream,
+static void update_video_src_caps (TpStreamEngine *self, TfStream *forcedstream,
gboolean force_send);
+static GstElement *make_video_src (TpStreamEngine *self);
+
static void
register_dbus_signal_marshallers()
{
@@ -142,14 +147,6 @@ enum
static guint signals[LAST_SIGNAL] = {0};
-struct ObjectTrackingData {
- TpStreamEngine *self;
- GPtrArray *objects;
-
- void (*setup_thread_prio) (pthread_t thread, pid_t tid);
-
-};
-
/* private structure */
struct _TpStreamEnginePrivate
{
@@ -170,7 +167,6 @@ struct _TpStreamEnginePrivate
FsElementAddedNotifier *notifier;
- gboolean video_source_started;
gint video_source_use_count;
gboolean failcount;
@@ -190,9 +186,7 @@ struct _TpStreamEnginePrivate
struct ObjectTrackingData audio_object_data;
struct ObjectTrackingData video_object_data;
-
- GHashTable *object_threads;
- GHashTable *object_tids;
+ struct ThreadTrackingData thread_tracking_data;
DBusGConnection *system_bus_connection;
LibHalContext *libhal_ctx;
@@ -203,6 +197,7 @@ struct _TpStreamEnginePrivate
guint camera_width;
};
+
static void
set_element_props (FsElementAddedNotifier *notifier,
GstBin *bin,
@@ -277,19 +272,14 @@ tp_stream_engine_init (TpStreamEngine *self)
priv->channels_by_path = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
- priv->object_threads = g_hash_table_new (g_direct_hash, g_direct_equal);
- priv->object_tids = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- priv->audio_object_data.self = self;
- priv->audio_object_data.objects = g_ptr_array_new ();
- priv->audio_object_data.setup_thread_prio = setup_realtime_thread;
-
- priv->video_object_data.self = self;
- priv->video_object_data.objects = g_ptr_array_new ();
- priv->video_object_data.setup_thread_prio = low_prio_thread;
-
priv->mutex = g_mutex_new ();
+ thread_tracking_init (&priv->thread_tracking_data, priv->mutex,
+ restore_thread_prio);
+ object_tracking_init (&priv->thread_tracking_data,
+ &priv->audio_object_data, setup_realtime_thread);
+ object_tracking_init (&priv->thread_tracking_data,
+ &priv->video_object_data, low_prio_thread);
priv->notifier = fs_element_added_notifier_new ();
g_signal_connect (priv->notifier, "element-added",
@@ -303,7 +293,6 @@ static void tp_stream_engine_dispose (GObject *object);
static void tp_stream_engine_finalize (GObject *object);
-
static void
tp_stream_engine_get_property (GObject *object,
guint property_id,
@@ -456,12 +445,9 @@ tp_stream_engine_dispose (GObject *object)
* if it fails or is async, it will crash on the following
* unref anyways
*/
- gst_element_set_state (priv->videosrc, GST_STATE_NULL);
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
- gst_object_unref (priv->videosrc);
gst_object_unref (priv->pipeline);
priv->pipeline = NULL;
- priv->videosrc = NULL;
}
if (priv->notifier)
@@ -483,11 +469,9 @@ tp_stream_engine_finalize (GObject *object)
g_mutex_free (self->priv->mutex);
- g_ptr_array_free (self->priv->audio_object_data.objects, TRUE);
- g_ptr_array_free (self->priv->video_object_data.objects, TRUE);
- g_hash_table_destroy (self->priv->object_threads);
- g_hash_table_destroy (self->priv->object_tids);
-
+ object_tracking_data_free (&self->priv->audio_object_data);
+ object_tracking_data_free (&self->priv->video_object_data);
+ thread_tracking_data_free (&self->priv->thread_tracking_data);
G_OBJECT_CLASS (tp_stream_engine_parent_class)->finalize (object);
}
@@ -515,39 +499,46 @@ static gboolean
tp_stream_engine_start_video_source (TpStreamEngine *self)
{
GstStateChangeReturn state_ret;
+ GstElement *videosrc;
- if (self->priv->video_source_started)
+ if (self->priv->videosrc)
return TRUE;
+ videosrc = make_video_src (self);
+
g_debug ("Starting video source");
- if (!gst_bin_add (GST_BIN (self->priv->pipeline), self->priv->videosrc))
+ if (!gst_bin_add (GST_BIN (self->priv->pipeline), videosrc))
{
g_warning ("Could not add videosrc to pipeline");
+ gst_object_unref (videosrc);
return FALSE;
}
- if (!gst_element_link (self->priv->videosrc, self->priv->capsfilter))
+ if (!gst_element_link (videosrc, self->priv->capsfilter))
{
g_warning ("Could not link videosrc to capsfilter");
- gst_bin_remove (GST_BIN (self->priv->pipeline), self->priv->videosrc);
- return FALSE;
+ goto error;
}
- state_ret = gst_element_set_state (self->priv->videosrc, GST_STATE_PLAYING);
+ state_ret = gst_element_set_state (videosrc, GST_STATE_PLAYING);
if (state_ret == GST_STATE_CHANGE_FAILURE)
{
g_warning ("Error starting the video source");
- gst_bin_remove (GST_BIN (self->priv->pipeline), self->priv->videosrc);
- gst_element_set_state (self->priv->videosrc, GST_STATE_NULL);
- return FALSE;
- }
- else
- {
- self->priv->video_source_started = TRUE;
- return TRUE;
+ goto error;
+
}
+
+ self->priv->videosrc = videosrc;
+ return TRUE;
+
+ error:
+ gst_element_set_locked_state (videosrc, TRUE);
+ gst_element_set_state (videosrc, GST_STATE_NULL);
+ gst_bin_remove (GST_BIN (self->priv->pipeline), videosrc);
+
+ return FALSE;
}
@@ -558,31 +549,48 @@ tp_stream_engine_inc_video_source (TpStreamEngine *self)
ret = tp_stream_engine_start_video_source (self);
- self->priv->video_source_use_count++;
+ if (ret)
+ self->priv->video_source_use_count++;
return ret;
}
+static gpointer
+stop_video_source_thread (gpointer data)
+{
+ GstElement *videosrc = data;
+ GstStateChangeReturn state_ret;
+
+ state_ret = gst_element_set_state (videosrc, GST_STATE_NULL);
+
+ if (state_ret == GST_STATE_CHANGE_FAILURE)
+ g_error ("Error stopping the video source");
+ else if (state_ret == GST_STATE_CHANGE_ASYNC)
+ g_debug ("Stopping video src async??");
+
+ gst_object_unref (videosrc);
+}
+
static void
tp_stream_engine_stop_video_source (TpStreamEngine *self)
{
- GstStateChangeReturn state_ret;
+ GstElement *videosrc;
- if (!self->priv->video_source_started)
+ if (!self->priv->videosrc)
return;
- self->priv->video_source_started = FALSE;
+
+ videosrc = self->priv->videosrc;
+ self->priv->videosrc = NULL;
g_debug ("Stopping video source");
- if (!gst_bin_remove (GST_BIN (self->priv->pipeline), self->priv->videosrc))
- g_warning ("Could not remove video src from pipeline");
+ gst_object_ref (videosrc);
- state_ret = gst_element_set_state (self->priv->videosrc, GST_STATE_NULL);
+ if (!gst_bin_remove (GST_BIN (self->priv->pipeline), videosrc))
+ g_warning ("Could not remove video src from pipeline");
- if (state_ret == GST_STATE_CHANGE_FAILURE)
- g_error ("Error stopping the video source");
- else if (state_ret == GST_STATE_CHANGE_ASYNC)
- g_debug ("Stopping video src async??");
+ if (!g_thread_create (stop_video_source_thread, videosrc, FALSE, NULL))
+ g_error ("Could not create thread to stop the video source");
}
@@ -650,7 +658,7 @@ update_video_src_caps (TpStreamEngine *self, TfStream *forcedstream,
gst_caps_unref (caps);
- if (self->priv->videosrc && self->priv->video_source_use_count)
+ if (self->priv->video_source_use_count)
if (!tp_stream_engine_start_video_source (self))
g_warning ("Could not start video source");
}
@@ -830,143 +838,10 @@ stream_receiving (TpStreamEngineVideoStream *videostream, gpointer user_data)
}
static void
-remove_object (gpointer data, GObject *where_the_obj_was)
-{
- struct ObjectTrackingData *otd = data;
-
- g_mutex_lock (otd->self->priv->mutex);
- g_ptr_array_remove (otd->objects, where_the_obj_was);
- g_mutex_unlock (otd->self->priv->mutex);
-}
-
-static void
-pad_linked (GstPad *pad, GstPad *peer, struct ObjectTrackingData *otd);
-
-static gboolean
-insert_object_locked (struct ObjectTrackingData *otd, gpointer object)
-{
- guint i;
- pthread_t thread;
- pid_t tid;
-
- for (i = 0; i < otd->objects->len; i++)
- if (g_ptr_array_index (otd->objects, i) == object)
- return FALSE;
-
- g_ptr_array_add (otd->objects, object);
- g_object_weak_ref (G_OBJECT (object), remove_object, otd);
-
-
- thread = GPOINTER_TO_UINT (
- g_hash_table_lookup (otd->self->priv->object_threads, object));
- tid = GPOINTER_TO_UINT (
- g_hash_table_lookup (otd->self->priv->object_tids, object));
-
- if (thread && tid)
- otd->setup_thread_prio (thread, tid);
-
- return TRUE;
-}
-
-static void
-add_pad (struct ObjectTrackingData *otd, GstPad *pad)
-{
- GstElement *el;
-
- insert_object_locked (otd, pad);
-
- el = gst_pad_get_parent_element (pad);
-
- if (el)
- {
- insert_object_locked (otd, el);
- gst_object_unref (el);
- }
-
- g_signal_connect (pad, "linked", G_CALLBACK (pad_linked), otd);
-}
-
-static void
-pad_iter (gpointer data, gpointer user_data)
-{
- struct ObjectTrackingData *otd = user_data;
- GstPad *pad = data;
- GstPad *peerpad = gst_pad_get_peer (pad);
-
- add_pad (otd, pad);
-
- if (peerpad)
- {
- GstIterator *iter;
- add_pad (otd, peerpad);
-
- iter = gst_pad_iterate_internal_links (peerpad);
- if (iter)
- {
- while (gst_iterator_foreach (iter, pad_iter, otd) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
- gst_iterator_free (iter);
- }
-
- gst_object_unref (peerpad);
- }
-
- gst_object_unref (pad);
-}
-
-static void
-pad_linked (GstPad *pad, GstPad *peer, struct ObjectTrackingData *otd)
-{
- GstIterator *iter = gst_pad_iterate_internal_links (pad);
-
- g_mutex_lock (otd->self->priv->mutex);
- add_pad (otd, peer);
-
- while (gst_iterator_foreach (iter, pad_iter, otd) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
-
- gst_iterator_free (iter);
- g_mutex_unlock (otd->self->priv->mutex);
-}
-
-static void
-pad_internal_links_iter (gpointer data, gpointer user_data)
-{
- struct ObjectTrackingData *otd = user_data;
- GstPad *pad = data;
- GstIterator *iter;
-
- iter = gst_pad_iterate_internal_links (pad);
- while (gst_iterator_foreach (iter, pad_iter, otd) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
- gst_iterator_free (iter);
-
- gst_object_unref (pad);
-}
-
-static void
sink_added_cb (gpointer stream,
GstElement *sink, struct ObjectTrackingData *otd)
{
- GstIterator *iter;
-
- g_mutex_lock (otd->self->priv->mutex);
-
- iter = gst_element_iterate_sink_pads (sink);
- while (gst_iterator_foreach (iter, pad_iter, otd) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
-
- gst_iterator_resync (iter);
- while (gst_iterator_foreach (iter, pad_internal_links_iter, otd) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
- gst_iterator_free (iter);
-
- g_mutex_unlock (otd->self->priv->mutex);
+ object_tracker_add_sink (otd, sink);
}
static void
@@ -1007,10 +882,11 @@ channel_stream_created (TfChannel *chan G_GNUC_UNUSED,
if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO)
{
TpStreamEngineAudioStream *audiostream;
- GstIterator *iter;
GstElement *src;
- g_object_set (stream, "tos", IPTOS_LOWDELAY, NULL);
+ /* The value IPTOS_PREC_NETCONTROL (which is 0xE0)
+ * is from bug NB#175648 */
+ g_object_set (stream, "tos", IPTOS_PREC_NETCONTROL, NULL);
audiostream = tp_stream_engine_audio_stream_new (stream,
GST_BIN (self->priv->pipeline), &error);
@@ -1032,21 +908,7 @@ channel_stream_created (TfChannel *chan G_GNUC_UNUSED,
g_mutex_unlock (self->priv->mutex);
g_object_get (audiostream, "src", &src, NULL);
-
- g_mutex_lock (self->priv->mutex);
- iter = gst_element_iterate_src_pads (src);
- while (gst_iterator_foreach (iter, pad_iter,
- &self->priv->audio_object_data) == GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
-
- gst_iterator_resync (iter);
- while (gst_iterator_foreach (iter, pad_internal_links_iter,
- &self->priv->audio_object_data) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
- gst_iterator_free (iter);
- g_mutex_unlock (self->priv->mutex);
-
+ object_tracker_add_src (&self->priv->audio_object_data, src);
gst_object_unref (src);
g_signal_connect (audiostream, "sink-added",
@@ -1058,7 +920,9 @@ channel_stream_created (TfChannel *chan G_GNUC_UNUSED,
TpStreamEngineVideoStream *videostream = NULL;
GstPad *pad;
- g_object_set (stream, "tos", IPTOS_THROUGHPUT, NULL);
+ /* The value IPTOS_PREC_CRITIC_ECP (which is 0xA0)
+ * is from bug NB#175648 */
+ g_object_set (stream, "tos", IPTOS_PREC_CRITIC_ECP, NULL);
pad = gst_element_get_request_pad (self->priv->videotee, "src%d");
@@ -1245,8 +1109,6 @@ restart_pipeline (gpointer data)
ret = gst_element_set_state (self->priv->pipeline, GST_STATE_NULL);
g_assert (ret != GST_STATE_CHANGE_FAILURE);
- ret = gst_element_set_state (self->priv->videosrc, GST_STATE_NULL);
- g_assert (ret != GST_STATE_CHANGE_FAILURE);
g_mutex_lock (self->priv->mutex);
try_stop_again:
@@ -1273,12 +1135,6 @@ restart_pipeline (gpointer data)
ret = gst_element_set_state (self->priv->pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
goto fail;
- if (self->priv->video_source_use_count)
- {
- ret = gst_element_set_state (self->priv->videosrc, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto fail;
- }
g_mutex_lock (self->priv->mutex);
try_start_again:
@@ -1410,47 +1266,10 @@ low_prio_thread (pthread_t thread, pid_t tid)
}
static void
-enter_thread (TpStreamEngine *self, GstObject *src, GstElement *owner)
-{
- pthread_t thread = pthread_self ();
- pid_t tid = syscall (__NR_gettid);
- guint i;
-
- g_mutex_lock (self->priv->mutex);
- g_hash_table_insert (self->priv->object_threads, src,
- GINT_TO_POINTER (thread));
- g_hash_table_insert (self->priv->object_tids, src,
- GINT_TO_POINTER (tid));
-
- for (i = 0; i < self->priv->audio_object_data.objects->len; i++)
- if (g_ptr_array_index (self->priv->audio_object_data.objects, i) == src)
- {
- self->priv->audio_object_data.setup_thread_prio (thread, tid);
- break;
- }
-
- for (i = 0; i < self->priv->video_object_data.objects->len; i++)
- if (g_ptr_array_index (self->priv->video_object_data.objects, i) == src)
- {
- self->priv->video_object_data.setup_thread_prio (thread, tid);
- break;
- }
-
- g_mutex_unlock (self->priv->mutex);
-}
-
-static void
-leave_thread (TpStreamEngine *self, GstObject *src, GstElement *owner)
+restore_thread_prio (pthread_t thread, pid_t tid)
{
- pthread_t thread = pthread_self ();
- pid_t tid = syscall (__NR_gettid);
struct sched_param param;
- g_mutex_lock (self->priv->mutex);
- g_hash_table_remove (self->priv->object_threads, src);
- g_hash_table_remove (self->priv->object_tids, src);
- g_mutex_unlock (self->priv->mutex);
-
if (setpriority (PRIO_PROCESS, tid, 0))
g_warning ("Could not restore thread priority to 0: %lX %s", (unsigned long int) thread, strerror (errno));
@@ -1458,6 +1277,7 @@ leave_thread (TpStreamEngine *self, GstObject *src, GstElement *owner)
pthread_setschedparam (thread, SCHED_OTHER, &param);
}
+
static GstBusSyncReply
bus_sync_handler (GstBus *bus G_GNUC_UNUSED, GstMessage *message, gpointer data)
{
@@ -1526,10 +1346,12 @@ bus_sync_handler (GstBus *bus G_GNUC_UNUSED, GstMessage *message, gpointer data)
switch (type)
{
case GST_STREAM_STATUS_TYPE_ENTER:
- enter_thread (self, GST_MESSAGE_SRC (message), owner);
+ enter_thread (&self->priv->thread_tracking_data,
+ GST_MESSAGE_SRC (message));
break;
case GST_STREAM_STATUS_TYPE_LEAVE:
- leave_thread (self, GST_MESSAGE_SRC (message), owner);
+ leave_thread (&self->priv->thread_tracking_data,
+ GST_MESSAGE_SRC (message));
break;
default:
break;
@@ -1542,17 +1364,11 @@ bus_sync_handler (GstBus *bus G_GNUC_UNUSED, GstMessage *message, gpointer data)
return GST_BUS_PASS;
}
-
-static void
-_build_base_video_elements (TpStreamEngine *self)
+static GstElement *
+make_video_src (TpStreamEngine *self)
{
- TpStreamEnginePrivate *priv = self->priv;
GstElement *videosrc = NULL;
- GstElement *tee;
- GstElement *capsfilter;
const gchar *elem;
- gboolean ret;
- GstIterator *iter;
if ((elem = getenv ("FS_VIDEO_SRC")) || (elem = getenv ("FS_VIDEOSRC")))
{
@@ -1567,13 +1383,13 @@ _build_base_video_elements (TpStreamEngine *self)
videosrc = gst_element_factory_make ("gconfvideosrc", NULL);
if (videosrc == NULL)
- videosrc = gst_element_factory_make ("v4l2camsrc", NULL);
+ videosrc = gst_element_factory_make ("subdevsrc", NULL);
if (videosrc == NULL)
- videosrc = gst_element_factory_make ("v4l2src", NULL);
+ videosrc = gst_element_factory_make ("v4l2camsrc", NULL);
if (videosrc == NULL)
- videosrc = gst_element_factory_make ("v4lsrc", NULL);
+ videosrc = gst_element_factory_make ("v4l2src", NULL);
if (videosrc != NULL)
{
@@ -1588,37 +1404,26 @@ _build_base_video_elements (TpStreamEngine *self)
}
}
- gst_element_set_locked_state (videosrc, TRUE);
+ object_tracker_add_src (&self->priv->video_object_data, videosrc);
+
+ return videosrc;
+}
+
- iter = gst_element_iterate_src_pads (videosrc);
- while (gst_iterator_foreach (iter, pad_iter,
- &self->priv->video_object_data) == GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
+static void
+_build_base_video_elements (TpStreamEngine *self)
+{
+ TpStreamEnginePrivate *priv = self->priv;
+ GstElement *tee;
+ GstElement *capsfilter;
+ gboolean ret;
- gst_iterator_resync (iter);
- while (gst_iterator_foreach (iter, pad_internal_links_iter,
- &self->priv->video_object_data) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (iter);
- gst_iterator_free (iter);
tee = gst_element_factory_make ("tee", "videotee");
g_assert (tee);
if (!gst_bin_add (GST_BIN (priv->pipeline), tee))
g_error ("Could not add tee to pipeline");
-#if 0
- /* <wtay> Tester_, yes, videorate does not play nice with live pipelines */
- tmp = gst_element_factory_make ("videorate", NULL);
- if (tmp != NULL)
- {
- g_debug ("linking videorate");
- gst_bin_add (GST_BIN (priv->pipeline), tmp);
- gst_element_link (videosrc, tmp);
- videosrc = tmp;
- }
-#endif
-
capsfilter = gst_element_factory_make ("capsfilter", NULL);
g_assert (capsfilter);
ret = gst_bin_add (GST_BIN (priv->pipeline), capsfilter);
@@ -1628,7 +1433,6 @@ _build_base_video_elements (TpStreamEngine *self)
g_assert (ret);
priv->capsfilter = capsfilter;
- priv->videosrc = gst_object_ref (videosrc);
priv->videotee = tee;
}
@@ -1768,14 +1572,21 @@ tp_stream_engine_create_preview_window (StreamEngineSvcStreamEngine *iface,
g_object_get (preview, "window-id", &window_id, NULL);
- stream_engine_svc_stream_engine_return_from_create_preview_window (context,
- window_id);
-
update_video_src_caps (self, NULL, FALSE);
- tp_stream_engine_inc_video_source (self);
-
- g_signal_emit (self, signals[HANDLING_CHANNEL], 0);
+ if (tp_stream_engine_inc_video_source (self))
+ {
+ stream_engine_svc_stream_engine_return_from_create_preview_window (
+ context,
+ window_id);
+ g_signal_emit (self, signals[HANDLING_CHANNEL], 0);
+ }
+ else
+ {
+ GError error = {TP_ERRORS, TP_ERROR_RESOURCE_UNAVAILABLE,
+ "Could not start camera"};
+ dbus_g_method_return_error (context, &error);
+ }
}
diff --git a/src/videosink.c b/src/videosink.c
index f71b949..ff3a123 100644
--- a/src/videosink.c
+++ b/src/videosink.c
@@ -33,8 +33,6 @@
#include <tp-stream-engine.h>
-#include <gtk/gtk.h>
-
#include "tp-stream-engine-signals-marshal.h"
#include "util.h"
@@ -46,7 +44,6 @@ G_DEFINE_ABSTRACT_TYPE (TpStreamEngineVideoSink, tp_stream_engine_video_sink,
struct _TpStreamEngineVideoSinkPrivate
{
GstElement *sink;
- GtkWidget *plug;
GstPad *sinkpad;
@@ -54,9 +51,6 @@ struct _TpStreamEngineVideoSinkPrivate
gboolean is_preview;
- gulong delete_event_handler_id;
- gulong embedded_handler_id;
-
GstClockTime last_timestamp;
gdouble framerate;
GstElement *textoverlay;
@@ -168,12 +162,28 @@ size_change_idle_cb (gpointer data)
{
TpStreamEngineVideoSink *self = data;
gint width, height;
+ gboolean have_size = FALSE;
g_static_mutex_lock (&self->priv->mutex);
self->priv->size_change_idle_id = 0;
g_static_mutex_unlock (&self->priv->mutex);
+ GST_OBJECT_LOCK (self->priv->sinkpad);
if (gst_video_get_size (self->priv->sinkpad, &width, &height))
+ {
+ gint par_n, par_d;
+
+ if (gst_video_parse_caps_pixel_aspect_ratio (
+ GST_PAD_CAPS (self->priv->sinkpad), &par_n, &par_d))
+ {
+ width *= par_n;
+ width /= par_d;
+ }
+ have_size = TRUE;
+ }
+ GST_OBJECT_UNLOCK (self->priv->sinkpad);
+
+ if (have_size)
g_signal_emit (self, signals[SIZE_CHANGED], 0, width, height);
return FALSE;
@@ -209,14 +219,7 @@ make_video_sink (TpStreamEngineVideoSink *self, gboolean is_preview)
}
else
{
- if (sink == NULL)
- sink = gst_element_factory_make ("autovideosink", NULL);
-
- if (sink == NULL)
- sink = gst_element_factory_make ("xvimagesink", NULL);
-
- if (sink == NULL)
- sink = gst_element_factory_make ("ximagesink", NULL);
+ sink = gst_element_factory_make ("xvimagesink", NULL);
}
if (sink == NULL)
@@ -241,49 +244,6 @@ make_video_sink (TpStreamEngineVideoSink *self, gboolean is_preview)
return NULL;
}
- tmp = gst_element_factory_make ("videoscale", NULL);
- if (tmp != NULL)
- {
- g_object_set (tmp, "qos", FALSE, NULL);
- g_debug ("linking videoscale");
- if (!gst_bin_add (GST_BIN (bin), tmp))
- {
- g_warning ("Could not add videoscale to the source bin");
- gst_object_unref (tmp);
- gst_object_unref (bin);
- return NULL;
- }
- if (!gst_element_link (tmp, sink))
- {
- g_warning ("Could not link sink and videoscale elements");
- gst_object_unref (bin);
- return NULL;
- }
- sink = tmp;
- }
-
- tmp = gst_element_factory_make ("ffmpegcolorspace", NULL);
- if (tmp != NULL)
- {
- g_object_set (tmp, "qos", FALSE, NULL);
- g_debug ("linking ffmpegcolorspace");
-
- if (!gst_bin_add (GST_BIN (bin), tmp))
- {
- g_warning ("Could not add ffmpegcolorspace to the source bin");
- gst_object_unref (tmp);
- gst_object_unref (bin);
- return NULL;
- }
- if (!gst_element_link (tmp, sink))
- {
- g_warning ("Could not link sink and ffmpegcolorspace elements");
- gst_object_unref (bin);
- return NULL;
- }
- sink = tmp;
- }
-
if (g_getenv ("STREAM_ENGINE_FPS") &&
!strcmp (g_getenv ("STREAM_ENGINE_FPS"), "overlay"))
{
@@ -343,35 +303,6 @@ make_video_sink (TpStreamEngineVideoSink *self, gboolean is_preview)
return sink;
}
-
-static gboolean
-delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
-{
- g_signal_emit (user_data, signals[PLUG_DELETED], 0);
-
- gtk_widget_hide (widget);
- return TRUE;
-}
-
-static void
-embedded_event (GtkWidget *widget, gpointer user_data)
-{
- gboolean embedded;
-
- g_object_get (widget, "embedded", &embedded, NULL);
-
- if (embedded)
- gtk_widget_show (widget);
-}
-
-static gboolean
-expose_handler (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
-{
- return TRUE;
-}
-
static GObject *
tp_stream_engine_video_sink_constructor (GType type,
guint n_props,
@@ -389,19 +320,6 @@ tp_stream_engine_video_sink_constructor (GType type,
if (self->priv->sink)
gst_object_ref (self->priv->sink);
- self->priv->plug = gtk_plug_new (0);
- gtk_widget_set_size_request (self->priv->plug, 176, 144);
- gtk_widget_set_double_buffered (self->priv->plug, FALSE);
- gtk_widget_set_app_paintable (self->priv->plug, TRUE);
- self->priv->delete_event_handler_id = g_signal_connect (self->priv->plug,
- "delete-event", G_CALLBACK (delete_event), self);
- self->priv->embedded_handler_id = g_signal_connect (self->priv->plug,
- "embedded", G_CALLBACK (embedded_event), NULL);
- g_signal_connect (self->priv->plug, "expose-event",
- G_CALLBACK (expose_handler), NULL);
-
- self->priv->window_id = gtk_plug_get_id (GTK_PLUG (self->priv->plug));
-
return obj;
}
@@ -433,26 +351,6 @@ tp_stream_engine_video_sink_dispose (GObject *object)
self->priv->size_change_idle_id = 0;
g_static_mutex_unlock (&self->priv->mutex);
- if (self->priv->delete_event_handler_id)
- {
- g_signal_handler_disconnect (self->priv->plug,
- self->priv->delete_event_handler_id);
- self->priv->delete_event_handler_id = 0;
- }
-
- if (self->priv->embedded_handler_id)
- {
- g_signal_handler_disconnect (self->priv->plug,
- self->priv->embedded_handler_id);
- self->priv->embedded_handler_id = 0;
- }
-
- if (self->priv->plug)
- {
- gtk_widget_destroy (self->priv->plug);
- self->priv->plug = NULL;
- }
-
if (G_OBJECT_CLASS (tp_stream_engine_video_sink_parent_class)->dispose)
G_OBJECT_CLASS (tp_stream_engine_video_sink_parent_class)->dispose (
object);
@@ -666,53 +564,10 @@ tp_stream_engine_video_sink_class_init (TpStreamEngineVideoSinkClass *klass)
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
}
-struct xid_data
-{
- GstElement *src;
- gulong window_id;
- gboolean found;
-};
-
-static void
-set_window_xid (gpointer data, gpointer user_data)
-{
- GstXOverlay *xov = GST_X_OVERLAY (data);
- struct xid_data *xiddata = (struct xid_data *) user_data;
-
- if (GST_ELEMENT_CAST(xov) == xiddata->src) {
- gst_x_overlay_set_xwindow_id (xov, xiddata->window_id);
- xiddata->found = TRUE;
- }
-
- gst_object_unref (data);
-}
-
gboolean
tp_stream_engine_video_sink_bus_sync_message (
TpStreamEngineVideoSink *self,
GstMessage *message)
{
- const GstStructure *s;
- GstIterator *it = NULL;
- struct xid_data xiddata;
-
- if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
- return FALSE;
-
- s = gst_message_get_structure (message);
- if (!gst_structure_has_name (s, "prepare-xwindow-id"))
- return FALSE;
-
- xiddata.src = GST_ELEMENT (GST_MESSAGE_SRC (message));
- xiddata.window_id = self->priv->window_id;
- xiddata.found = FALSE;
-
- it = gst_bin_iterate_all_by_interface (GST_BIN (self->priv->sink),
- GST_TYPE_X_OVERLAY);
- while (gst_iterator_foreach (it, set_window_xid, &xiddata) ==
- GST_ITERATOR_RESYNC)
- gst_iterator_resync (it);
- gst_iterator_free (it);
-
- return xiddata.found;
+ return FALSE;
}
diff --git a/src/videostream.c b/src/videostream.c
index 329dfe2..0441ae5 100644
--- a/src/videostream.c
+++ b/src/videostream.c
@@ -805,8 +805,6 @@ src_pad_added_cb (TfStream *stream, GstPad *pad, FsCodec *codec,
goto error;
}
- g_signal_emit (self, signals[SINK_ADDED_SIGNAL], 0, funnel);
-
sinkpad = gst_element_get_request_pad (funnel, "sink%d");
if (!sinkpad)
{
@@ -815,6 +813,8 @@ src_pad_added_cb (TfStream *stream, GstPad *pad, FsCodec *codec,
goto error;
}
+ g_signal_emit (self, signals[SINK_ADDED_SIGNAL], 0, funnel);
+
gst_object_unref (funnel);
ghost = gst_ghost_pad_new (NULL, sinkpad);