我正在使用 Live555 为 IP 摄像机实现 C++ RTPS 客户端。 我正在使用大部分 testRTSPClient 代码。
我也使用了 Poco 库和 Poco::Thread 类。
换句话说,每个摄像头的任何客户端都在一个单独的线程中运行,该线程拥有他的 Live555 对象实例(如 live555-devel 所建议的那样,任何线程都使用一个实例及其 UsageEnvironment 和 TaskScheduler。)。这是为了避免共享变量和同步的东西。它似乎运行良好且快速。
我的可运行(遵循 Poco 库要求)对象 IPCamera 的运行方法非常简单:
void IPCamera::run()
{
openURL(_myEnv, "", _myRtspCommand.c_str(), *this); //taken from the testRTSPClient example
_myEnv->TaskScheduler().doEventLoop(&_watchEventLoopVariable);
//it runs until _watchEventLoopVariable change to a value != 0
//exit from the run;
}
当运行完成时,我调用 join() 来关闭线程(顺便说一句,我认为如果我不调用 myThread->join(),内存不会完全释放)。
关闭后,按照 Live555-devel 中的要求,我输入了我的代码:
void IPCamera::shutdown()
{
...
_myEnv->reclaim();
delete _myScheduler;
}
使用 Valgrind 检测内存泄漏我看到了一个奇怪的行为:
1) 案例:运行程序 - 关闭所有以正确方式运行的 IPCameras 的程序。
a) 在程序结束时调用所有析构函数。
b) 退出 doEventLoop()。
c) 加入线程(实际上是终止了,因为它退出了 run 方法。
d) 如图所示销毁 _myEnv 和 _myScheduler。
e) 销毁所有其他对象,包括关联的 IPCamera 和 Thread。
-> Valgrind 没有发现内存泄漏。好的
问题来了
2) 案例:我正在实现一个用例,其中 Poco::Timer 使用 ICMP ping 每隔 X 秒检查一次相机是否处于事件状态。它会引发一个事件(使用 Poco 事件),以防它因为网络故障而没有回答,我会执行以下操作:
网络摄像头关闭:
a) 设置_watchEventLoopVariable = 1 退出run方法;
b) 如图所示关闭与 IPCamera 关联的客户端
c) 加入线程
我不会破坏线程,因为我想在网络再次启动并且相机再次工作时重新使用它。在那种情况下: a) 我设置 _eventWatchVariable = 0。 b) 让线程重新启动:myThread->run()
Valgrind 告诉我发现内存泄漏:在 H264BufferdPackedFactory::createNewPacket(...) 类 Live555 的线程中直接丢失了 60 个字节,间接字节丢失了 20.000 个字节。
最佳答案
已解决 我发现问题出在 TCP 隧道上。在 LIVE55 中你可以选择协议(protocol)的种类。 如果我选择:
#define REQUEST_STREAMING_OVER_TCP false
我没有任何泄漏。我多次使用 Valgrind 来确定(它发现了问题)。
如果我使用TCP那么就会出现上面的问题。
关于c++ - Live555 客户端流媒体内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27060245/