Playing multiple videos in sequence in using LIbVLCSharp causes memory to increase alot

Viewed 540

After playing a playlist for about two days the memory increases from a about 100 megabytes to a few gigabytes. The thread count remains the same about 20 threads. I'm disposing of media (when changin to new media) from mediaplayer element like so:

                            if(web.MediaPlayer.Media != null) {
                                web.MediaPlayer.Media.Dispose();
                            }
                    
                            web.MediaPlayer.Media = media;

and when creatinga new media player:

                            if(web.MediaPlayer != null) {
                                if(web.MediaPlayer.Media != null) {
                                    web.MediaPlayer.Media.Dispose();
                                }
                                web.MediaPlayer.Dispose();
                            }

                            web.MediaPlayer = new MediaPlayer(media) { EnableHardwareDecoding = true };

Is this enough to dispose of the media like this?

And when reaching end i play next media like this, calling init video calls the first piece of code. Switching the media in the media player.

                    web.MediaPlayer.EndReached += (s, e) => ThreadPool.QueueUserWorkItem(_ => { 
                        if(this.tab_objects.ContainsKey(tab_index)) {
                            tab tab_object = this.tab_objects[tab_index];
                            string next_media = tab_object.get_next_media();
                            ....some other code....
                            if(next_media != null) {
                                this.init_video(next_media, tab_index, true);
                            } else {
                                
                    
                            }
                        }
                    });

Any help is appreciated.

I've altered the code to this with no results:

            using(Media media = new Media(this.lib_vlc, uri)) {
                using(MediaPlayer p = web.MediaPlayer) {
                    if(p != null) {
                        /*using(Media last_media = p.Media) {
                            if(last_media != null) {
                                last_media.Dispose();
                            }
                        }*/
                    }   
                    web.MediaPlayer = null;
                    if(p != null) {
                        p.Dispose();
                    }
                    web.MediaPlayer = new MediaPlayer(media) { EnableHardwareDecoding = true };
                    media.Dispose();
                }
            }

I've commented out the "last_media" part because it has no effect. I set the web.MediaPlayer as null because it causes a crash when i dispose of the MediaPlayer object before setting it to something else.

I would wrapping the media in "using" and explicitly disposing of it would be enough. But the memory usage still climbs. What is the correct way of disposing of the last played media object?

1 Answers

Calling MediaPlayer.Media calls the native function that gets the media, and creates a new instance of Media. Every time you're calling the property, you'll get a new instance. This is not really a problem from the C# side, because all these instance will be garbage collected, but they are not Disposed of properly. The native get media function internally increments a reference counter, that is decremented when you call Dispose.

If you're calling N times MediaPlayer.Media, you're incrementing N times the ref counter, but releasing it only once when you call Dispose.

Another related note : when you pass a media to the media player, you can (and probably should if you're not reusing it) Dispose it immediately (i.e. decrement the reference count and let libvlc be the only reference usage)

EDIT : To clarify, instead of doing your operations on MediaPlayer.Media, you should store the result of the property and Dispose it when you're done with it

Related