[gstreamer-bugs] [Bug 592415] dshowsrcwrapper and wasapi uninitializes the COM library

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Thu Aug 20 12:12:26 PDT 2009


http://bugzilla.gnome.org/show_bug.cgi?id=592415


Michael Smith <msmith> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
                 CC|                            |msmith at xiph.org
     Ever Confirmed|0                           |1


--- Comment #1 from Michael Smith <msmith at xiph.org> 2009-08-20 19:12:18 UTC ---
We ran into this at songbird too (though with other elements: dshowdecwrapper
and another plugin that isn't in gst git yet).

The problem is actually a bit more complex than this - and I'm really not sure
how to fix it reliably. Any suggestions would be VERY welcome.

According to COM rules, you need to initialise COM on each thread that uses
COM, not just on the main thread. The COM initialisation refcount is then
maintained by COM for each... and here I couldn't figure out for certain what
the rules are... but I think for each apartment (i.e. for each thread where COM
is initialised with COINIT_MULTITHREADED, plus globally for _all_ threads that
initialise COM with COINIT_APARTMENTTHREADED).

Unfortunately, we have no way to ensure that we call CoInitialize() and
CoUninitialize() from the same thread. e.g. in dshowaudiosrc, CoInitialize()
happens in the object init method, and CoUninitialize() happens in the dispose
method (or it could be in the finalize method as you suggest). There's no way
to ensure that these two methods get called from the same thread - and indeed,
in gstreamer application, they're frequently NOT called from the same thread!

I think in practice this is mostly ok for dshowaudiosrc (the source is
typically created directly by the application, and then destroyed by the
application, from the main thread). It's not so good for other plugins though,
like dshowdecwrapper - typically, that will be created (from decodebin/etc) in
a streaming thread, but destroyed on the main thread. Even if we properly use
the return values from CoInitialize() then, we'll incorrectly call
CoUnitialize() on the main thread's apartment (which is, depending on the app,
either the single threaded apartment, or a multi threaded apartment), instead
of the streaming thread's apartment (typically a multi threaded apartment).

Additionally, we should technically be calling CoInitialize/CoUninitialize from
_every_ thread that uses COM objects - right now that doesn't seem to be
causing real problems, but at least in theory it can.

The only idea I've had to deal with this at all is to:
 - Initialize (and possibly uninitialize) COM somewhere in core gstreamer for
the main thread. Or rely on the app to do that.
 - For each task thread gstreamer creates, initialize COM at startup, and
uninitialize at shutdown of that thread. 

This is intrusive though - it seems like there should be a way to use COM
safely from a plugin without having to do this.

All that said: what you're suggesting is a step in the right direction at
least, so even if you don't have any good ideas on how to fix the deeper
problems, could you write/attach a patch to fix the problems you described?

-- 
Configure bugmail: http://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.




More information about the Gstreamer-bugs mailing list