bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.39k stars 1.56k forks source link

bugfix memory leaks #2214

Closed Lwine closed 2 months ago

Lwine commented 2 months ago

This is the solution for the issue https://github.com/bytedeco/javacv/issues/2119 When release AVFormatContext use avformat_close_input instead of avformat_free_context.

saudet commented 2 months ago

avformat_close_input() already gets called when inputStream == null. This line only gets reached when inputStream != null. In that case, oc is allocated using avformat_alloc_context(), and according to the documentation of that, it should be released with avformat_free_context(), not avformat_close_input(): https://github.com/bytedeco/javacpp-presets/blob/1.5.10/ffmpeg/src/gen/java/org/bytedeco/ffmpeg/global/avformat.java#L1538

Could you try to ask upstream about this? If this is an error in the documentation, let's get that fixed first.

Lwine commented 2 months ago

avformat_close_input() already gets called when inputStream == null. This line only gets reached when inputStream != null. In that case, oc is allocated using avformat_alloc_context(), and according to the documentation of that, it should be released with avformat_free_context(), not avformat_close_input(): https://github.com/bytedeco/javacpp-presets/blob/1.5.10/ffmpeg/src/gen/java/org/bytedeco/ffmpeg/global/avformat.java#L1538

Could you try to ask upstream about this? If this is an error in the documentation, let's get that fixed first.

code is like this

InputStream inputStream = new ByteArrayInputStream(slice);
try (FFmpegFrameGrabber ff = new FFmpegFrameGrabber(inputStream)){
    ...
}

but i found didn't execute

if (inputStream == null && oc != null && !oc.isNull()) {
            avformat_close_input(oc);
            oc = null;
}

should i set inputStream null and call ff.close()?

saudet commented 2 months ago

In your case, avformat_free_context() should get called, so that's correct. We don't need to call avformat_close_input().

Lwine commented 2 months ago

In your case, avformat_free_context() should get called, so that's correct. We don't need to call avformat_close_input().

https://github.com/bytedeco/javacpp-presets/blob/1.5.10/ffmpeg/src/gen/java/org/bytedeco/ffmpeg/global/avformat.java#L1538

The stream must be closed with avformat_close_input().

ret = avformat_open_input(oc, filename, f, options)) Don't need to call avformat_close_input here?

saudet commented 2 months ago

When input_stream != null, avformat_open_input() is not called, so we cannot call avformat_close_input().

Lwine commented 2 months ago

When input_stream != null, avformat_open_input() is not called, so we cannot call avformat_close_input().

https://github.com/bytedeco/javacv/blob/master/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java#L978

Isn't this a call to avformat_open_input() when input_stream != null?

xiaobei2019 commented 2 months ago

@saudet
https://github.com/bytedeco/javacv/issues/2119 In this issue, I see you confirmed that this is a problem and suggested to submit MR to fix this issue? image

saudet commented 2 months ago

https://github.com/bytedeco/javacv/blob/master/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java#L978

Isn't this a call to avformat_open_input() when input_stream != null?

I see. What happens if we don't call avformat_open_input() there?

xiaobei2019 commented 2 months ago

https://github.com/bytedeco/javacv/issues/2119

https://github.com/bytedeco/javacv/blob/master/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java#L978 Isn't this a call to avformat_open_input() when input_stream != null?

I see. What happens if we don't call avformat_open_input() there? We use the jemalloc tool to trace the memory and find that a large number of memory leaks occur, which is the same as this issue,https://github.com/bytedeco/javacv/issues/2119

image