summaryrefslogtreecommitdiff
path: root/sys/dshowdecwrapper
diff options
context:
space:
mode:
authorJulien MOUTTE <julien@moutte.net>2011-05-30 08:43:59 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2011-05-30 08:45:01 +0200
commitefd840bbb7e398d89ee9d4230e1f9c6250deee6b (patch)
tree86ed33f708aad9722f327030fbb0af1f0758b6da /sys/dshowdecwrapper
parent378a8d94dcfd0d1e9b19890a3c87622846d822d8 (diff)
downloadgstreamer-plugins-bad-efd840bbb7e398d89ee9d4230e1f9c6250deee6b.tar.gz
dshowdecwrapper: Fix COM initialization
Fixes bug #625190.
Diffstat (limited to 'sys/dshowdecwrapper')
-rw-r--r--sys/dshowdecwrapper/gstdshowaudiodec.cpp70
-rw-r--r--sys/dshowdecwrapper/gstdshowaudiodec.h7
-rw-r--r--sys/dshowdecwrapper/gstdshowvideodec.cpp70
-rw-r--r--sys/dshowdecwrapper/gstdshowvideodec.h7
4 files changed, 138 insertions, 16 deletions
diff --git a/sys/dshowdecwrapper/gstdshowaudiodec.cpp b/sys/dshowdecwrapper/gstdshowaudiodec.cpp
index b4ead2421..f10ac8cdc 100644
--- a/sys/dshowdecwrapper/gstdshowaudiodec.cpp
+++ b/sys/dshowdecwrapper/gstdshowaudiodec.cpp
@@ -366,11 +366,47 @@ gst_dshowaudiodec_class_init (GstDshowAudioDecClass * klass)
}
static void
+gst_dshowaudiodec_com_thread (GstDshowAudioDec * adec)
+{
+ HRESULT res;
+
+ g_mutex_lock (adec->com_init_lock);
+
+ /* Initialize COM with a MTA for this process. This thread will
+ * be the first one to enter the apartement and the last one to leave
+ * it, unitializing COM properly */
+
+ res = CoInitializeEx (0, COINIT_MULTITHREADED);
+ if (res == S_FALSE)
+ GST_WARNING_OBJECT (adec, "COM has been already initialized in the same process");
+ else if (res == RPC_E_CHANGED_MODE)
+ GST_WARNING_OBJECT (adec, "The concurrency model of COM has changed.");
+ else
+ GST_INFO_OBJECT (adec, "COM intialized succesfully");
+
+ adec->comInitialized = TRUE;
+
+ /* Signal other threads waiting on this condition that COM was initialized */
+ g_cond_signal (adec->com_initialized);
+
+ g_mutex_unlock (adec->com_init_lock);
+
+ /* Wait until the unitialize condition is met to leave the COM apartement */
+ g_mutex_lock (adec->com_deinit_lock);
+ g_cond_wait (adec->com_uninitialize, adec->com_deinit_lock);
+
+ CoUninitialize ();
+ GST_INFO_OBJECT (adec, "COM unintialized succesfully");
+ adec->comInitialized = FALSE;
+ g_cond_signal (adec->com_uninitialized);
+ g_mutex_unlock (adec->com_deinit_lock);
+}
+
+static void
gst_dshowaudiodec_init (GstDshowAudioDec * adec,
GstDshowAudioDecClass * adec_class)
{
GstElementClass *element_class = GST_ELEMENT_GET_CLASS (adec);
- HRESULT hr;
/* setup pads */
adec->sinkpad =
@@ -407,10 +443,21 @@ gst_dshowaudiodec_init (GstDshowAudioDec * adec,
adec->last_ret = GST_FLOW_OK;
- hr = CoInitialize (0);
- if (SUCCEEDED(hr)) {
- adec->comInitialized = TRUE;
- }
+ adec->com_init_lock = g_mutex_new();
+ adec->com_deinit_lock = g_mutex_new();
+ adec->com_initialized = g_cond_new();
+ adec->com_uninitialize = g_cond_new();
+ adec->com_uninitialized = g_cond_new();
+
+ g_mutex_lock (adec->com_init_lock);
+
+ /* create the COM initialization thread */
+ g_thread_create ((GThreadFunc)gst_dshowaudiodec_com_thread,
+ adec, FALSE, NULL);
+
+ /* wait until the COM thread signals that COM has been initialized */
+ g_cond_wait (adec->com_initialized, adec->com_init_lock);
+ g_mutex_unlock (adec->com_init_lock);
}
static void
@@ -428,11 +475,20 @@ gst_dshowaudiodec_dispose (GObject * object)
adec->codec_data = NULL;
}
+ /* signal the COM thread that it sould uninitialize COM */
if (adec->comInitialized) {
- CoUninitialize ();
- adec->comInitialized = FALSE;
+ g_mutex_lock (adec->com_deinit_lock);
+ g_cond_signal (adec->com_uninitialize);
+ g_cond_wait (adec->com_uninitialized, adec->com_deinit_lock);
+ g_mutex_unlock (adec->com_deinit_lock);
}
+ g_mutex_free (adec->com_init_lock);
+ g_mutex_free (adec->com_deinit_lock);
+ g_cond_free (adec->com_initialized);
+ g_cond_free (adec->com_uninitialize);
+ g_cond_free (adec->com_uninitialized);
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
diff --git a/sys/dshowdecwrapper/gstdshowaudiodec.h b/sys/dshowdecwrapper/gstdshowaudiodec.h
index 77d789193..5f52cb888 100644
--- a/sys/dshowdecwrapper/gstdshowaudiodec.h
+++ b/sys/dshowdecwrapper/gstdshowaudiodec.h
@@ -1,6 +1,6 @@
/*
* GStreamer DirectShow codecs wrapper
- * Copyright <2006, 2007, 2008> Fluendo <gstreamer@fluendo.com>
+ * Copyright <2006, 2007, 2008, 2009, 2010> Fluendo <support@fluendo.com>
* Copyright <2006, 2007, 2008> Pioneers of the Inevitable <songbird@songbirdnest.com>
* Copyright <2007,2008> Sebastien Moutte <sebastien@moutte.net>
*
@@ -113,6 +113,11 @@ struct _GstDshowAudioDec
GstClockTime timestamp;
gboolean comInitialized;
+ GMutex *com_init_lock;
+ GMutex *com_deinit_lock;
+ GCond *com_initialized;
+ GCond *com_uninitialize;
+ GCond *com_uninitialized;
};
struct _GstDshowAudioDecClass
diff --git a/sys/dshowdecwrapper/gstdshowvideodec.cpp b/sys/dshowdecwrapper/gstdshowvideodec.cpp
index 0dcc3fa7f..663e98043 100644
--- a/sys/dshowdecwrapper/gstdshowvideodec.cpp
+++ b/sys/dshowdecwrapper/gstdshowvideodec.cpp
@@ -418,11 +418,47 @@ gst_dshowvideodec_class_init (GstDshowVideoDecClass * klass)
}
static void
+gst_dshowvideodec_com_thread (GstDshowVideoDec * vdec)
+{
+ HRESULT res;
+
+ g_mutex_lock (vdec->com_init_lock);
+
+ /* Initialize COM with a MTA for this process. This thread will
+ * be the first one to enter the apartement and the last one to leave
+ * it, unitializing COM properly */
+
+ res = CoInitializeEx (0, COINIT_MULTITHREADED);
+ if (res == S_FALSE)
+ GST_WARNING_OBJECT (vdec, "COM has been already initialized in the same process");
+ else if (res == RPC_E_CHANGED_MODE)
+ GST_WARNING_OBJECT (vdec, "The concurrency model of COM has changed.");
+ else
+ GST_INFO_OBJECT (vdec, "COM intialized succesfully");
+
+ vdec->comInitialized = TRUE;
+
+ /* Signal other threads waiting on this condition that COM was initialized */
+ g_cond_signal (vdec->com_initialized);
+
+ g_mutex_unlock (vdec->com_init_lock);
+
+ /* Wait until the unitialize condition is met to leave the COM apartement */
+ g_mutex_lock (vdec->com_deinit_lock);
+ g_cond_wait (vdec->com_uninitialize, vdec->com_deinit_lock);
+
+ CoUninitialize ();
+ GST_INFO_OBJECT (vdec, "COM unintialized succesfully");
+ vdec->comInitialized = FALSE;
+ g_cond_signal (vdec->com_uninitialized);
+ g_mutex_unlock (vdec->com_deinit_lock);
+}
+
+static void
gst_dshowvideodec_init (GstDshowVideoDec * vdec,
GstDshowVideoDecClass * vdec_class)
{
GstElementClass *element_class = GST_ELEMENT_GET_CLASS (vdec);
- HRESULT hr;
/* setup pads */
vdec->sinkpad =
@@ -455,10 +491,21 @@ gst_dshowvideodec_init (GstDshowVideoDec * vdec,
vdec->setup = FALSE;
- hr = CoInitialize (0);
- if (SUCCEEDED(hr)) {
- vdec->comInitialized = TRUE;
- }
+ vdec->com_init_lock = g_mutex_new();
+ vdec->com_deinit_lock = g_mutex_new();
+ vdec->com_initialized = g_cond_new();
+ vdec->com_uninitialize = g_cond_new();
+ vdec->com_uninitialized = g_cond_new();
+
+ g_mutex_lock (vdec->com_init_lock);
+
+ /* create the COM initialization thread */
+ g_thread_create ((GThreadFunc)gst_dshowvideodec_com_thread,
+ vdec, FALSE, NULL);
+
+ /* wait until the COM thread signals that COM has been initialized */
+ g_cond_wait (vdec->com_initialized, vdec->com_init_lock);
+ g_mutex_unlock (vdec->com_init_lock);
}
static void
@@ -471,11 +518,20 @@ gst_dshowvideodec_dispose (GObject * object)
vdec->segment = NULL;
}
+ /* signal the COM thread that it sould uninitialize COM */
if (vdec->comInitialized) {
- CoUninitialize ();
- vdec->comInitialized = FALSE;
+ g_mutex_lock (vdec->com_deinit_lock);
+ g_cond_signal (vdec->com_uninitialize);
+ g_cond_wait (vdec->com_uninitialized, vdec->com_deinit_lock);
+ g_mutex_unlock (vdec->com_deinit_lock);
}
+ g_mutex_free (vdec->com_init_lock);
+ g_mutex_free (vdec->com_deinit_lock);
+ g_cond_free (vdec->com_initialized);
+ g_cond_free (vdec->com_uninitialize);
+ g_cond_free (vdec->com_uninitialized);
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
diff --git a/sys/dshowdecwrapper/gstdshowvideodec.h b/sys/dshowdecwrapper/gstdshowvideodec.h
index 4e2d7dc48..b5253a6f4 100644
--- a/sys/dshowdecwrapper/gstdshowvideodec.h
+++ b/sys/dshowdecwrapper/gstdshowvideodec.h
@@ -1,6 +1,6 @@
/*
* GStreamer DirectShow codecs wrapper
- * Copyright <2006, 2007, 2008> Fluendo <gstreamer@fluendo.com>
+ * Copyright <2006, 2007, 2008, 2009, 2010> Fluendo <support@fluendo.com>
* Copyright <2006, 2007, 2008> Pioneers of the Inevitable <songbird@songbirdnest.com>
* Copyright <2007,2008> Sebastien Moutte <sebastien@moutte.net>
*
@@ -113,6 +113,11 @@ struct _GstDshowVideoDec
gboolean setup;
gboolean comInitialized;
+ GMutex *com_init_lock;
+ GMutex *com_deinit_lock;
+ GCond *com_initialized;
+ GCond *com_uninitialize;
+ GCond *com_uninitialized;
};
struct _GstDshowVideoDecClass