我正在使用其SDK从DVR收到H.264 stream
。有内存泄漏,我认为这是导致所有泄漏的SDK。但是当我录制流并从磁盘上逐个读取帧时(没有任何第三方dll参与),我注意到问题不是dll而是流本身。
奇怪的是,DivX H264 Decoder
是唯一不会导致内存泄漏的编解码器,但是当流运行很长时间时,有时DivX解码器也会崩溃。我更喜欢使用Microsoft DTV-DVD Video Decoder
,但它会导致巨大的内存泄漏并丢失大量帧。我尝试过的许多其他H.264解码器的行为方式相同。
我使用一些h.264 frames
检查h.264 parsers
与其他一些无问题的流进行比较,但我没有注意到日志中的任何明显内容。
由于我的问题是关于h.264帧结构,我已经准备了一个名为FramesFromFileSourceFilter
的源过滤器,你可以在下面下载。
http://www.akaydin.com/directshow/FramesFromFileSourceFilter.zip
这是一个Visual Studio 2008
项目,所有依赖项都包含在相对定位的文件夹(包括h.264帧)中的zip文件中。因此,您需要做的就是编译项目,使用regsvr32.exe
注册输出,并使用GraphEdit或GraphStudio中的任何h.264解码器运行过滤器。示例图如下。
此外,h264帧可作为单个原始h264文件在下面的链接中使用,该链接可由VLC播放(错误的FPS,因为原始版本为12 FPS)。
http://www.akaydin.com/directshow/stream.zip
问题:
除DivX解码器外,许多着名的H264解码器可能导致内存泄漏问题。这个流有什么问题?
更新1
删除读取数据线程,并在不使用任何缓冲区和标志的情况下将功能移动到FillBuffer中。问题依然存在。
http://www.akaydin.com/directshow/FramesFromFileSourceFilterUpdate1.zip
更新2
Update1在Sleep()
函数中使用了FillBuffer()
,这导致了一些问题。现在我删除了Sleep()
并使用SetTime()
来获得~12 FPS。这也解决了Microsoft DTV-DVD Video Decoder
丢帧问题,但没有解决内存问题。
http://www.akaydin.com/directshow/FramesFromFileSourceFilterUpdate2.zip
内存增加仅发生在Working Set
。 Virtual Bytes
和Private Bytes
似乎很稳定。什么可能导致连续的Working Set
内存增量只发生在Microsoft DTV-DVD Video Decoder
?
答案 0 :(得分:3)
您不会围绕变量进行任何同步
BYTE* m_buffer;
DWORD m_bufferSize;
bool isFrameReady;
它们来自两个并发线程。您只是通过这种不准确的分配/释放来泄漏内存和/或让代码在访问冲突时崩溃。 DLL的调试版本通过在运行测试时向您显示“堆损坏”警报来指示此情况。运行时行为可能因解码器和环境而异,但这绝对是一个需要修复的严重错误。
例如,您可以在填充缓冲区的线程中使用CAutoLock cAutoLock(m_pLock);
,以防止在从文件读取数据时进行流线程访问。
请注意,您将下一帧读入相同的缓冲区指针,而不检查先前分配的内存是否已释放,您只是覆盖指针可能会留下泄漏。
内存泄漏/工作集更新:现在,当解决代码问题时,不需要的运行时行为会增加Working Set
大小。这不是泄漏。这表明Windows将该进程视为一种优先级(为什么不呢?它是活动的并且与内存一起工作)并向该进程抛出更多真实页面以促进其性能。有关进程内存指标如何与应用程序中的内存泄漏相对应的详细说明,请参阅this answer。
您可能会看到的解码器之间的差异很可能是由于某些解码器适用于较少量的缓冲区,或者更积极地重复使用它们,例如:喜欢从池中取出相同的缓冲区,而不是逐个选择所有可用的缓冲区。