ChinnaSuhas / ossbuild

Automatically exported from code.google.com/p/ossbuild
Other
0 stars 1 forks source link

DirectShow Video Sink Thread Leak #48

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
From r640 comments:

Open and close windows a lot by doing a PLAYING -> NULL -> PLAYING 
transition and you'll quickly end up with hundreds of threads.

It appears that 1 thread is frozen on line 341: CoUninitialize ();

Others are frozen on line 259: while (sink->comInitialized);

It would seem that there's an issue with COM uninitialization that's 
causing it to block and therefore not dropping to line 343 which sets the 
flag other threads are waiting on to exit.

Original issue reported on code.google.com by david.g.hoyt on 25 May 2010 at 7:17

GoogleCodeExporter commented 9 years ago
I'll take a look more deeply this evening.

Original comment by ylatuya on 25 May 2010 at 7:56

GoogleCodeExporter commented 9 years ago
Weird,  ::init() and ::finalize() should be called only once. The READY_TO_NULL 
and 
NULL_TO_READY transitions is handled by the ::start() and ::stop() virtual 
methods. 
I'll need to review everything again.

Original comment by ylatuya on 25 May 2010 at 8:45

GoogleCodeExporter commented 9 years ago
Thank you for your commits, but I'm still seeing the thread leak. Got to 600+ 
threads before my last test died. The hang ups seem to be on the same lines as 
before.

Would you mind explaining your strategy, in detail, of how you're addressing 
the COM 
initialization issue and how you've structured the threads?

Original comment by david.g.hoyt on 25 May 2010 at 9:10

GoogleCodeExporter commented 9 years ago
Are you availabe on irc?

Original comment by ylatuya on 25 May 2010 at 9:29

GoogleCodeExporter commented 9 years ago
COM must be initialize and deinitialized from the same thread. Using 
CoInitializeEx
using a multithreaded apartement lets you create a single apartement for the 
process
that is going to be shared for all the threads. 
A GObject is initialized once and the init function is set in the
GST_BOILERPLATE_FULL macro, which is gst_dshowvideosink_init() and
deinitialized/destroyed in gst_dshowvideosink_finalize(). Since this functions 
are
called only once in the live cicle of the object it's the best place to 
init/uninit COM. 
In ::init(), a new thread is created which inititialize COM and this thread 
will be
waiting for a GCond to proceed with the deinitialization, which will be done 
when the
object is destroyed in the ::finalize() function.

This is the output I get running a simple pipeline and closing the window, 
which will
shoutdown the running pipeline:

Andoni@LONGO /c
$ GST_DEBUG=dshowvideosink:3 python play.py dshowvideosink file:///c:/test.avi

Andoni@LONGO /c
$ GST_DEBUG=dshowvideosink:3 gst-launch.exe videotestsrc ! ffmpegcolorspace ! d
showvideosink
0:00:00.531250000  1484   00B34AC0 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@00B34EF0
> COM
intialized succesfully
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
0:00:01.531250000  1484   00B7E1D8 INFO          dshowvideosink
dshowvideosink.cpp:1655:gst_caps_to_directshow_media_type: Set mediatype 
format: size
88, sample size 153600
0:00:01.578125000  1484   00B7E1D8 INFO          dshowvideosink
dshowvideosink.cpp:769:gst_dshowvideosink_connect_graph:<dshowvideosink0> 
Connecting
DirectShow pins
0:00:01.593750000  1484   00B41430 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<dshowvideosink0> 
Received
DirectShow graph event code 0x53
0:00:01.625000000  1484   00B7E1D8 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<dshowvideosink0> Running
DirectShow graph
0:00:01.625000000  1484   00B41430 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<dshowvideosink0> 
Received
DirectShow graph event code 0xd
0:00:01.640625000  1484   00B7E1D8 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<dshowvideosink0> Pausing
DirectShow graph
0:00:01.640625000  1484   00B41430 INFO    Pipeline is PREROLLED ...
      dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<dshowvideosink0> 
Received
DirectShow graph event code 0xe
Setting pipeline to PLAYING ...
0:00:01.640625000  1484   003942F8 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<dshowvideosink0> Running
DirectShow graph
New clock: GstSystemClock
0:00:03.343750000  1484   00B7E1D8 WARN          dshowvideosink
dshowvideosink.cpp:1440:gst_dshowvideosink_show_frame:<dshowvideosink0> Window 
has
been closed, stopping
ERROR: from element /GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0: 
Internal
data flow error.
Additional debug info:
..\..\..\Source\gstreamer\libs\gst\base\gstbasesrc.c(2507): gst_base_src_loop 
():
/GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0:
streaming task paused, reason error (-5)
Execution ended after 1703125000 ns.
Setting pipeline to PAUSED ...
0:00:03.359375000  1484   003942F8 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<dshowvideosink0> Pausing
DirectShow graph
Setting pipeline to READY ...
0:00:03.359375000  1484   003942F8 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<dshowvideosink0> Stopping
DirectShow graph
Setting pipeline to NULL ...
Freeing pipeline ...
0:00:03.640625000  1484   00B34AC0 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<dshowvideosink0> COM
unintialized succesfully

This shows that's COM is initialized properly in ::init() and deintialzed in
::finalize() when the GCond com_unitialized is signaled to the COM thread in 
::finalize()

I have also run an example in python where a change from PLAYING to NULL and 
back to
PLAYING a pipeline on eos several times.

The only way to leak a thread is creating several instances of the 
dshowvideosink and
not destroying them properly. For instance you might need to call
gst_ojbect_unref(sink) once the sink is not used anymore.

Are you using the test you commited last time?

Here is the output of the test I'm using (note the COM is properly intialized 
on each
transition):

Andoni@LONGO /c
$ GST_DEBUG=dshowvideosink:3 python play.py dshowvideosink file:///c:/test.avi
0:00:00.781250000  3192   01281CC8 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125B220
> COM
intialized succesfully
0:00:02.250000000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:1655:gst_caps_to_directshow_media_type: Set mediatype 
format: size
88, sample size 153600
0:00:02.296875000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:769:gst_dshowvideosink_connect_graph:<videosink-actual-sink-d
showvideo>
Connecting DirectShow pins
0:00:02.328125000  3192   0127EF08 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0x53
0:00:02.343750000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:02.359375000  3192   0127EF08 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xd
0:00:02.359375000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:02.375000000  3192   0127EF08 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xe
0:00:02.375000000  3192   012AE240 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:05.656250000  3192   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:05.656250000  3192   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:05.859375000  3192   01281CC8 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:05.968750000  3192   012C9DC0 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125B220
> COM
intialized succesfully
0:00:06.515625000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:1655:gst_caps_to_directshow_media_type: Set mediatype 
format: size
88, sample size 153600
0:00:06.531250000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:769:gst_dshowvideosink_connect_graph:<videosink-actual-sink-d
showvideo>
Connecting DirectShow pins
0:00:06.546875000  3192   012AE240 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0x53
0:00:06.562500000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:06.562500000  3192   012AE240 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xd
0:00:06.562500000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:06.562500000  3192   012AE240 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xe
0:00:06.578125000  3192   00E5C870 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:09.843750000  3192   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:09.843750000  3192   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:10.031250000  3192   012C9DC0 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:10.078125000  3192   012C9DC0 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125B220
> COM
intialized succesfully
0:00:10.625000000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:1655:gst_caps_to_directshow_media_type: Set mediatype 
format: size
88, sample size 153600
0:00:10.640625000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:769:gst_dshowvideosink_connect_graph:<videosink-actual-sink-d
showvideo>
Connecting DirectShow pins
0:00:10.671875000  3192   01281CC8 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0x53
0:00:10.671875000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:10.671875000  3192   01281CC8 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xd
0:00:10.687500000  3192   012A3D40 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:10.687500000  3192   00E5C870 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:10.703125000  3192   01281CC8 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xe
0:00:13.968750000  3192   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:13.968750000  3192   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:14.156250000  3192   012C9DC0 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:14.187500000  3192   01346C00 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125B220
> COM
intialized succesfully
0:00:14.781250000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:1655:gst_caps_to_directshow_media_type: Set mediatype 
format: size
88, sample size 153600
0:00:14.812500000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:769:gst_dshowvideosink_connect_graph:<videosink-actual-sink-d
showvideo>
Connecting DirectShow pins
0:00:14.828125000  3192   01212080 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0x53
0:00:14.843750000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph
0:00:14.859375000  3192   01212080 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xd
0:00:14.859375000  3192   00D8D168 INFO          dshowvideosink
dshowvideosink.cpp:846:gst_dshowvideosink_pause_graph:<videosink-actual-sink-dsh
owvideo>
Pausing DirectShow graph
0:00:14.859375000  3192   01212080 INFO          dshowvideosink
dshowvideosink.cpp:462:gst_dshowvideosink_handle_event:<videosink-actual-sink-ds
howvideo>
Received DirectShow graph event code 0xe
0:00:14.859375000  3192   00E020F8 INFO          dshowvideosink
dshowvideosink.cpp:813:gst_dshowvideosink_start_graph:<videosink-actual-sink-dsh
owvideo>
Running DirectShow graph

Original comment by ylatuya on 25 May 2010 at 9:46

GoogleCodeExporter commented 9 years ago
I'm on IRC.

Original comment by david.g.hoyt on 25 May 2010 at 10:18

GoogleCodeExporter commented 9 years ago
You can see my output w/ GST_DEBUG=dshowvideosink:3 at 
http://pastebin.com/sbm7EQUM 

The # of COM initializations != the # of COM uninitializations

My test is simple (in Java):

for(int i = 0; i < 300; ++i) {
    IPipeline pipeline = Pipeline.make("unit-test-pipeline");
    IElement videotestsrc = Element.make("videotestsrc", "videotestsrc");
    IElement ffmpegcolorspace = Element.make
("ffmpegcolorspace", "ffmpegcolorspace");
    IElement videosink = Element.make("dshowvideosink", "videosink");

    pipeline.addAndLinkMany(videotestsrc, ffmpegcolorspace, videosink);

    pipeline.changeState(State.Playing);
    Thread.sleep(50L);
    pipeline.changeState(State.Null);

    pipeline.unlinkAndRemoveMany(videotestsrc, ffmpegcolorspace, videosink);

    videotestsrc.dispose();
    ffmpegcolorspace.dispose();
    videosink.dispose();
    pipeline.dispose();

    gc();

    if ((i % 10) == 0 && i > 0) {
        System.out.println("Completed " + i + " iterations...");
    }
}

When this is run using fakesink, the # of threads is consistent (17/18 threads) 
with 
no memory leaks (insinuating that there isn't a reference count issue here) -- 
but 
using dshowvideosink, after 30+ iterations my thread count was 60+ and rising.

Original comment by david.g.hoyt on 25 May 2010 at 10:27

GoogleCodeExporter commented 9 years ago
It looks like you're not doing the transition quick enough to see the problem 
I'm 
experiencing. It looks like you're playing back a video that's 3-4 seconds long 
which is more than enough time for threads to settle and to not see 
synchronization 
issues.

Try speeding up your transitions - I'm doing one ~ every 50 milliseconds, but 
it 
should work no matter how fast I do it.

I would guess that for some reason COM initializations are happening before the 
COM 
uninitialization and that's causing a hangup.

It seems like the fix is straight forward enough, I'm just so unfamiliar with 
that 
element that it'd take me a while to figure it out. Probably a lot more time 
than 
it'd take you. :)

Original comment by david.g.hoyt on 25 May 2010 at 10:34

GoogleCodeExporter commented 9 years ago
To be honest I'm quite new to this element too and even more to the COM stuff, 
which
even worst than what I though in the beginning :)
With this examples I understand more what is going on. I didn't even consider 
this
use case and the fix be straigh forward. I'll try to commit a fix tomorrow ;) 

Original comment by ylatuya on 25 May 2010 at 11:22

GoogleCodeExporter commented 9 years ago
I'm unable to reproduce it. Using a timeout of 10 miliseconds I get the 
following
output (note the calls are even separated by more than 10ms, which means that
finalize is not called before the init function has finished)

0:00:01.593750000  3856   00DBB1F0 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:01.921875000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:02.015625000  3856   00DBB1F0 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:02.046875000  3856   011D2078 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:02.406250000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:02.484375000  3856   011D2078 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:02.562500000  3856   012B8EE0 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:02.890625000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:02.984375000  3856   012B8EE0 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:03.062500000  3856   01212438 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:03.406250000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:03.484375000  3856   01212438 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:03.578125000  3856   01316B70 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:03.890625000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:03.968750000  3856   01316B70 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:04.031250000  3856   0129E718 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:04.343750000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:04.453125000  3856   0129E718 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:04.515625000  3856   011EDA48 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:04.828125000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:04.906250000  3856   011EDA48 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:04.984375000  3856   011FC170 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:05.312500000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:05.406250000  3856   011FC170 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:05.437500000  3856   012B7030 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:05.781250000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:05.875000000  3856   012B7030 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:05.937500000  3856   012B43F0 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:06.265625000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:06.359375000  3856   012B43F0 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:06.390625000  3856   012A9968 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully
0:00:06.734375000  3856   00973FD0 INFO          dshowvideosink
dshowvideosink.cpp:880:gst_dshowvideosink_stop_graph:<videosink-actual-sink-dsho
wvideo>
Stopping DirectShow graph
0:00:06.812500000  3856   012A9968 INFO          dshowvideosink
dshowvideosink.cpp:342:gst_dshowvideosink_com_thread:<videosink-actual-sink-dsho
wvideo>
COM unintialized succesfully
0:00:06.859375000  3856   012A9968 INFO          dshowvideosink
dshowvideosink.cpp:329:gst_dshowvideosink_com_thread:<GstDshowVideoSink@0125BC38
> COM
intialized succesfully

Original comment by ylatuya on 25 May 2010 at 11:57

GoogleCodeExporter commented 9 years ago
I'm using the following code for the test:

#!/usr/bin/env python
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4

import pygtk
pygtk.require('2.0')

import sys

import gobject
gobject.threads_init()

import pygst
pygst.require('0.10')
import gst
import gst.interfaces

class GstPlayer:
    def __init__(self, videosink):
        self.playing = False
        self.player = gst.Pipeline()
        #self.videosink = gst.element_factory_make(videosink)
        self.playbin = gst.element_factory_make("playbin2")
        #self.playbin.set_property('video-sink', self.videosink)
        self.player.add(self.playbin)
        self.location = ""

        bus = self.player.get_bus()
        bus.add_signal_watch()
        bus.connect('message', self.on_message)

        self.play()
        self.playing = True
        gobject.timeout_add(10, self.transition)

    def transition(self):
        if self.playing:
            self.stop()
            gobject.timeout_add(10, self.transition)
            self.playing = False
        else:
            self.play()
            gobject.timeout_add(10, self.transition)
            self.playing = True

    def on_message(self, bus, message):
        t = message.type
        if t == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            self.playing = False
        elif t == gst.MESSAGE_EOS:
            print "EOS received! Setting state to NULL and back to play"
            self.stop()
            self.play()

    def set_location(self, location):
        self.location = location
        self.playbin.set_property('uri', location)

    def pause(self):
        gst.info("pausing player")
        self.player.set_state(gst.STATE_PAUSED)
        self.playing = False

    def play(self):
        print "playing player"
        self.player.set_state(gst.STATE_PLAYING)
        self.playing = True

    def stop(self):
        print "stopped player"
        self.player.set_state(gst.STATE_NULL)

    def is_playing(self):
        return self.playing

def main(args):
    def usage():
        sys.stderr.write("usage: %s VIDEOSINK-NAME URI-OF-MEDIA-FILE\n" % args[0])
        sys.exit(1)

    if len(args) != 3:
        usage()

    player = GstPlayer(args[1])
    player.set_location(args[2])
    player.play()

    gobject.MainLoop().run()

if __name__ == '__main__':
    sys.exit(main(sys.argv))

Original comment by ylatuya on 26 May 2010 at 12:00

GoogleCodeExporter commented 9 years ago
It appears that you're doing your state transitions primarily on the glib main 
loop -
- i'm doing them from a completely separate thread.

I suppose you could try spawning a thread and run the pipeline in there similar 
to 
my example.

I've rerun the tests w/ the latest commit - it's still appearing. If I can/have 
time, I'll see if I can get a C program together to demonstrate the issue.

Original comment by david.g.hoyt on 26 May 2010 at 12:21

GoogleCodeExporter commented 9 years ago
Okay, I added an example program to the solution called 
"videotestsrc-start-stop" 
which shows what I'm talking about.

It spins up a new thread which starts and stops the pipeline every 100 
milliseconds. 
After running it for ~3-4 seconds, if you watch task manager, the thread leak 
should 
become apparent.

Original comment by david.g.hoyt on 26 May 2010 at 2:43

GoogleCodeExporter commented 9 years ago
Hi David, 
I runned your test app adding gst_object_unref(app->pipeline) before
g_main_loop_quit() and I get the expected result (I added some prints the sink 
to
make it more clear)

$ /c/ossbuild/Build/Windows/Win32/Release/bin/videotestsrc-start-stop
file:///c:/test.avi 
** Message: creating elements
Initializing dshowvideosink
Waiting in the COM thread to finalize
** Message: elements added and linked
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Playing...
Null...
Test complete
Called gst_dshowvideosink_finalize()
Signaling COM thread to finalize
Uninitialized COM
** Message: stopping

As you see the sink is created only once and only one COM thread is created too 
and
COM is ununitialized in the end. Maybe the leak is somewhere else, for instance 
in
the Window thread, which is created for each new window, but no closed properly.

Original comment by ylatuya on 28 May 2010 at 12:04

GoogleCodeExporter commented 9 years ago
I would definitively blame the window thread for that, since a new one is 
created on
each transition but it's never stoped ;)

Original comment by ylatuya on 28 May 2010 at 12:20

GoogleCodeExporter commented 9 years ago
The window thread is blocking in GetMessage()

Original comment by ylatuya on 28 May 2010 at 12:45

GoogleCodeExporter commented 9 years ago
It should be fixed in trunk.
I have run the test and the process memory is fluctuating from 13.5 to 14.5 Mb,
whilst previously it was taking more than 20 Mb.
Can you confirm that the leak is now fixed?

Original comment by ylatuya on 28 May 2010 at 1:35

GoogleCodeExporter commented 9 years ago
Thread leak is gone, but I still get a memory leak -- can you commit your 
changes to 
the test app so I can see if it's something I missed?

Original comment by david.g.hoyt on 28 May 2010 at 5:37

GoogleCodeExporter commented 9 years ago
On my run, it starts out around 13-14 MB but by the end it's at >30 MB.

Original comment by david.g.hoyt on 28 May 2010 at 5:39

GoogleCodeExporter commented 9 years ago
On Vista and Windwos 7, the last while(com->initialized) is deadlocking. It 
needs to
be implemented using a GMutex/GCond.

Original comment by ylatuya on 28 May 2010 at 4:21

GoogleCodeExporter commented 9 years ago
I hace run several times the test both on XP and on Windows7 and I don't see any
leak, it never takes more than 13.5MB.

I pusheed a commit for threading issue uninitializting COM in Vista and 7

Original comment by ylatuya on 28 May 2010 at 7:10

GoogleCodeExporter commented 9 years ago
I think this can be closed now

Original comment by ylatuya on 3 Oct 2010 at 1:37