具有某些解码器的H.264帧内存泄漏 [英] H.264 Frames Memory Leak With Some Decoders

查看:213
本文介绍了具有某些解码器的H.264帧内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用其SDK从DVR收到H.264 stream.有内存泄漏,我认为这是导致所有泄漏的SDK.但是,当我记录流并从磁盘上逐一读取播放帧(不涉及任何第三方dll)时,我注意到问题不在于dll,而在于流本身.

I'm receiving an H.264 stream from a DVR using its SDK. There were memory leaks and i thought it was the SDK causing all the leaks. But when i recorded the stream and played the frames one by one reading from the disk (without any 3rd party dlls involved), i noticed that the problem is not the dll but the stream itself.

奇怪的是,DivX H264 Decoder是唯一不会导致内存泄漏的编解码器,但是当流长时间运行时,有时DivX解码器也会崩溃.我更喜欢使用Microsoft DTV-DVD Video Decoder,但是它会导致大量的内存泄漏并丢弃很多帧.我尝试过的其他许多H.264解码器的行为也相同.

Strange enough, DivX H264 Decoder is the only codec which doesn't cause a memory leak but when the stream runs for a long time, sometimes DivX decoder crashes as well. I'd prefer to use Microsoft DTV-DVD Video Decoder but it causes huge memory leaks and drops a lot of frames. Many other H.264 decoders I've tried behaves the same way.

我用一些h.264 parsers与其他无问题的流进行了比较,检查了h.264 frames,但是我没有从日志中注意到任何明显的东西.

I examined the h.264 frames using some h.264 parsers comparing with some other problem-free streams but i didn't notice anything obvious from the logs.

由于我的问题是关于h.264帧结构的,所以我准备了一个名为FramesFromFileSourceFilter的源过滤器,您可以在下面下载它.

Since my problem is about the h.264 frames structure, i've prepared a source filter named FramesFromFileSourceFilter which you can download below.

http://www.akaydin.com/directshow/FramesFromFileSourceFilter.zip

这是一个Visual Studio 2008项目,所有依赖项都包含在zip文件中的相对位置的文件夹中(包括h.264帧).因此,您所需要做的就是编译项目,在regsvr32.exe中注册输出,并使用GraphEdit或GraphStudio中所需的任何h.264解码器运行过滤器.图表示例如下.

It's a Visual Studio 2008 project and all dependencies are included in the zip file in relatively located folders (including the h.264 frames). So, all you need to do is to compile the project, register the output with regsvr32.exe and run the filter with any h.264 decoder you want from GraphEdit or GraphStudio. Example graphs are below.

h264帧也可以在下面的链接中作为单个原始h264文件获得,VLC可以播放该文件(FPS错误,因为原始为12 FPS).

Also h264 frames are available as a single raw h264 file at the link below which is playable by VLC (with wrong FPS since original was 12 FPS).

http://www.akaydin.com/directshow/stream.zip

问题:

除DivX解码器外,许多著名的H264解码器可能导致内存泄漏问题的原因.此流有什么问题?

What might be causing the memory leak problems with many famous H264 Decoders except DivX decoder. What is wrong with this stream?

更新1

删除了读取数据线程,并将功能移到了FillBuffer中,而无需使用任何缓冲区和标志.问题依旧.

Reading data thread is removed and functionality moved into FillBuffer without using any buffers and flags. Problem remains the same.

http://www.akaydin.com/directshow/FramesFromFileSourceFilterUpdate1.zip

更新2

Update1在FillBuffer()函数中使用了Sleep(),这引起了一些问题.现在,我删除了Sleep()并使用SetTime()拥有约12 FPS.这也解决了Microsoft DTV-DVD Video Decoder的掉帧问题,但没有解决内存问题.

Update1 was using Sleep() in FillBuffer() function which was causing some problems. Now i removed the Sleep() and used SetTime() to have ~12 FPS. This also solved Microsoft DTV-DVD Video Decoder's dropping frame issues but didn't solve memory problems.

http://www.akaydin.com/directshow/FramesFromFileSourceFilterUpdate2.zip

内存增加仅在Working Set处发生. Virtual BytesPrivate Bytes似乎稳定.是什么导致连续的Working Set内存增量(仅在Microsoft DTV-DVD Video Decoder上发生)?

Memory increase occurs at Working Set only. Virtual Bytes and Private Bytes seem to be stable. What might be causing continuous Working Set memory increment which only happens with Microsoft DTV-DVD Video Decoder?

推荐答案

您不对变量进行任何同步

You don't do any synchronization around your variables

BYTE* m_buffer;
DWORD m_bufferSize;
bool isFrameReady;

它们从两个并发线程中使用.您只是由于这种不正确的分配/取消分配和/或使您的代码在访问冲突时崩溃而泄漏了内存. DLL的调试版本通过在运行测试时向您显示堆损坏"警报来表明这一点.运行时行为可能会因解码器和环境而异,但这绝对是一个严重的错误,需要修复.

And they are used from two concurrent threads. You just leak your memory by this inaccurate allocation/deallocation AND/OR letting your code crash on access violation. Debug build of your DLL indicates this by showing you "heap corruption" alert as you run your test. The runtime behavoir might vary with decoders and environment, however this is definitely a severe bug to be fixed.

例如,您可以在填充缓冲区的线程中使用CAutoLock cAutoLock(m_pLock);,以防止在从文件中读取数据时流式访问线程.

For instance, you can use CAutoLock cAutoLock(m_pLock); in your thread that fills buffer to prevent streaming thread access while you are reading data from file.

请注意,您将下一帧读入相同的缓冲区指针,而不检查是否释放了先前分配的内存,只是覆盖了指针,可能会导致泄漏.

Note that you read next frame into the same buffer pointer without a check whether previously allocated memory is freed or not, you just overwrite the pointer possibly leaving a leak.

内存泄漏/工作集更新:现在,解决了代码问题后,不必要的运行时行为是Working Set大小的增加.这不是泄漏.这表明Windows将进程视为一种优先级(为什么不这样做?它是活动的并且可以与内存一起使用),并向该进程投入更多的实际页面以促进其性能.请参阅此答案,以更好地说明进程内存指标如何对应于应用程序中的内存泄漏.

Memory Leak/Working Set Update: Now, when code issues are sorted out, the unwanted runtime behavior is an increase in Working Set size. This is not a leak. It is an indication that Windows considers the process as a sort of priority (why not? it is active and works with memory) and throws more real pages towards this process to facilitate its performance. See this answer on good explanation of how process memory metrics correspond to memory leaks in an application.

您可能会看到的解码器之间的差异可能是由于以下事实造成的:某些解码器在缓冲区数量较少的情况下性能良好,或者更积极地重用它们,例如宁愿从池中取出相同的缓冲区,而不是从所有可用缓冲区中一个接一个地选择缓冲区.

The difference between decoders you might be seeing is likely to be caused by the fact that some decoders are good with smaller amount of buffers, or reuse them more actively, e.g. prefer to take the same buffer out of a pool rather than picking one by one through all available.

这篇关于具有某些解码器的H.264帧内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆