我使用Live555为IP摄像机实现C ++ RTPS客户端。 我使用了大部分testRTSPClient代码。
我也使用了Poco库和Poco :: Thread类。
换句话说,每个摄像头的任何客户端都在一个单独的线程中运行,并拥有他的Live555对象实例(正如live555-devel建议的那样,任何线程都使用带有UsageEnvironment和TaskScheduler的实例)。这样可以避免共享变量和同步内容。它看起来效果很好而且速度很快。
我的runnable(遵循Poco库要求)对象IPCamera的run方法简单如下:
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)case:运行程序 - 使用正确运行的所有IPCameras关闭程序。
a)在程序结束时调用所有析构函数。
b)退出doEventLoop()。
c)加入线程(实际上是因为它从run方法退出而被终止。
d)如图所示销毁_myEnv和_myScheduler。
e)销毁所有其他对象,包括IPCamera和Thread相关。
- > Valgrind没有发现内存泄漏。确定
现在出现了问题。
2)案例:我实现了一个用例,如果摄像机处于活动状态,Poco :: Timer会每隔X秒检查一次使用ICMP ping。它引发了一个事件(使用Poco事件),以防万一它没有回答,因为网络已经关闭,我做了以下事情:
IPCamera down:
a)将_watchEventLoopVariable = 1退出run方法;
b)关闭与IPCamera相关联的客户端,如图所示
c)加入主题
我没有销毁线程,因为我想在网络重新启动并且相机再次工作时重复使用它。在这种情况下: a)我设置_eventWatchVariable = 0。 b)让我们再次使用:myThread-> run()
重新开始Valgrind告诉我发现了内存泄漏:直接60字节,线程中丢失了20.000个间接字节,H264BufferdPackedFactory :: createNewPacket(...),一类Live555。
答案 0 :(得分:2)
解决 我发现问题是通过TCP进行隧道传输。在LIVE55中,您可以选择协议类型。 如果我选择:
#define REQUEST_STREAMING_OVER_TCP false
我没有任何泄漏。我曾多次使用Valgrind(它发现了问题)。
如果我使用TCP,则会出现上述问题。