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

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Wed Aug 19 23:17:21 PDT 2009


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

           Summary: dshowsrcwrapper and wasapi uninitializes the COM
                    library
    Classification: Desktop
           Product: GStreamer
           Version: git
        OS/Version: Windows
            Status: UNCONFIRMED
          Severity: major
          Priority: Normal
         Component: gst-plugins-bad
        AssignedTo: gstreamer-bugs at lists.sourceforge.net
        ReportedBy: youness.alaoui at collabora.co.uk
         QAContact: gstreamer-bugs at lists.sourceforge.net
      GNOME target: ---
     GNOME version: ---


--- Comment #0 from Youness Alaoui <youness.alaoui at collabora.co.uk> 2009-08-20 06:17:17 UTC ---
Hi,

So here's the situation, aMSN is a tcl/tk application which uses multiple
different extensions for specific tasks, one of these extensions is called
'tkvideo' and uses dshow to capture video from webcam devices/other..

The problem now is that when gstreamer (specifically
dshowaudiosrc/dshowvideosrc/wasapisrc elements) are used, then completely break
tkvideo, and here's why :

tkvideo does a CoInitialize(NULL) when initialized then creates/uses COM
objects...
dshowaudiosrc/dshowvideosrc call CoInitializeEx(NULL, COINIT_MULTITHREADED) in
the _init and call CoUninitialize() in the dispose. The CoInitializeEx tries to
initialize the COM library in a multithreaded model, which fails with
RPC_E_CHANGED_MODE.. but it doesn't check the return value... The problem being
that CoInitialize(NULL) initializes the COM library in a singlethreaded mode,
and when calling CoInitialize or CoInitializeEx, if the threading model
changes, the call fails...
later on when dispose is called, dshowaudiosrc/dshowvideosrc call
CoUninitialize() which will uninitialize the COM library and free its
resources.. but tkvideo is *still* using the COM library and may have COM
objects allocated.. this causes it to fail, or crash...
wasapisrc does the same thing, but it uses CoInitialize(NULL), which means that
the same problem would occur if any application creates a pipeline using both
wasapisrc and dshowvideosrc for example.. you end up initializing COM once (the
other initialization failing) but uninitializing it TWICE...

Also note that the fact that the CoUninitialize() is called in the dispose is
bad, since dispose *could* be called more than once, it should instead be put
in the finalize function of the gobject...

I have to solutions, first, use this :

    HRESULT hr = CoInitializeEx (NULL, COINIT_MULTITHREADED);
    if (hr == RPC_E_CHANGED_MODE)
      hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);

and then check if it failed or not for the second CoInitializeEx, if it failed,
either fail to create the element, or just ignore it (a bit risky) but store a
variable saying whether or not we should call CoUninitialize later on in the
finalize...
second solution would be to do the same code as above, but do it in the
class_init and completely remove any call to CoUninitialize()...

not checking for RPC_E_CHANGED_MODE after calling the second CoInitializeEx
would mean that we know the COM library is initialized and we can use it, BUT
if the main application that initialized it calls CoUninitialize at some point,
we're risking a crash... so we could just cross our fingers and hope it never
calls CoUninitialize (the other concurrency models possible are :
COINIT_DISABLE_OLE1DDE and COINIT_SPEED_OVER_MEMORY, but will most probably
never be seen in real life situations).

Note that wasapisrc should also be modified to use CoInitializeEx instead of
CoInitialize... with the above solution(s) of course...

KaKaRoTo

-- 
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