hozuki / MonoGame.Extended2

A collection of extensions for MonoGame
BSD 3-Clause Clear License
38 stars 8 forks source link

Problems with disposing texture when using video, also memory leak #2

Open Kabaril opened 5 years ago

Kabaril commented 5 years ago

There is no texture.Dispose() called in the Draw method in the VideoPlayback Demo for DesktopGL I noticed that the memory usage of the program goes up linearly When I added said Dispose call, there was a System.NullReferenceException in FFmpegHelper Line 230

Same for the Code in the Readme in Monogame.Extended.VideoPlayback

hozuki commented 5 years ago

You should not dispose the texture you got from GetTexture(). (You shouldn't do it in XNA either.) This is stated in the documentation. The demo code in readme is an earlier version, which creates a new texture in every call. That behavior was not compatible with XNA, so I changed it, but forgot to update readme. I'll update readme and fix that code.

For the memory leak, I'll look into the problem.

hozuki commented 5 years ago

I cannot reproduce memory leak here.

I used a 1080p 60 FPS video (~2 min, plus multiple times of replaying) to test its performance under high pressure. When opening the video it takes ~81 MB (baseline). The highest memory usage recorded was +~10 MB (on replaying), and the average usage was +~5 MB. Seconds after replaying a GC was triggered and the usage falled back to average.

hozuki commented 4 years ago

Hmmm while playing the demo video, memory leak is observed...

hozuki commented 4 years ago

Can you test the latest commit aa5d9a583d448230b42451345cfcb65df1152c71?

gsenly commented 4 years ago

Found memory leak in AudioDecodingContext.cs in Dispose the _resampleContext was close but not freed. When new video loaded the closed resampleContext was not freed by ffmpeg. protected override void Dispose(bool disposing) { if (_resampleContext != null) { var resampleContext = _resampleContext; ffmpeg.swr_close(_resampleContext) Added ffmpeg.swr_free(&resampleContext); _resampleContext = null; }

        if (_codecContext != null) {
            ffmpeg.avcodec_close(_codecContext);
            _codecContext = null;
        }

        // Will be freed by AVFormatContext
        _audioStream = null;
    }
hozuki commented 4 years ago

Found memory leak in AudioDecodingContext.cs in Dispose the _resampleContext was close but not freed. When new video loaded the closed resampleContext was not freed by ffmpeg. protected override void Dispose(bool disposing) { if (_resampleContext != null) { var resampleContext = _resampleContext; ffmpeg.swr_close(_resampleContext) Added ffmpeg.swr_free(&resampleContext); _resampleContext = null; }

        if (_codecContext != null) {
            ffmpeg.avcodec_close(_codecContext);
            _codecContext = null;
        }

        // Will be freed by AVFormatContext
        _audioStream = null;
    }

Thanks, it helps.