diff options
author | Julien MOUTTE <julien@moutte.net> | 2011-05-30 08:43:59 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2011-05-30 08:45:01 +0200 |
commit | efd840bbb7e398d89ee9d4230e1f9c6250deee6b (patch) | |
tree | 86ed33f708aad9722f327030fbb0af1f0758b6da /sys/dshowdecwrapper | |
parent | 378a8d94dcfd0d1e9b19890a3c87622846d822d8 (diff) | |
download | gstreamer-plugins-bad-efd840bbb7e398d89ee9d4230e1f9c6250deee6b.tar.gz |
dshowdecwrapper: Fix COM initialization
Fixes bug #625190.
Diffstat (limited to 'sys/dshowdecwrapper')
-rw-r--r-- | sys/dshowdecwrapper/gstdshowaudiodec.cpp | 70 | ||||
-rw-r--r-- | sys/dshowdecwrapper/gstdshowaudiodec.h | 7 | ||||
-rw-r--r-- | sys/dshowdecwrapper/gstdshowvideodec.cpp | 70 | ||||
-rw-r--r-- | sys/dshowdecwrapper/gstdshowvideodec.h | 7 |
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 |