Я использую Live555 для реализации RTPS-клиента C ++ для IP-камер.
Я использую большую часть кода testRTSPClient.
Я также использовал библиотеку Poco и класс Poco :: Thread.
Другими словами, любой клиент для каждой камеры работает в отдельном потоке, который владеет своим экземпляром объектов Live555 (как предполагает live555-devel, любой поток использует экземпляр со своими UsageEnvironment и TaskScheduler.). Это позволяет избежать общих переменных и синхронизации. Кажется, работает хорошо и быстро.
Мой объект runcable (в соответствии с требованиями библиотеки 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: Запустите программу — закройте программу со всеми IP-камерами, которые работают должным образом.
а) В конце программы все деструкторы вызываются.
б) выйти из doEventLoop ().
c) присоединиться к потоку (фактически прекращается, потому что выходит из метода run.
г) уничтожить _myEnv и _myScheduler, как показано.
e) уничтожить все остальные объекты, включая связанные с IPCamera и Thread.
-> никаких утечек памяти не обнаружено у Valgrind. Хорошо
Теперь приходит проблема.
2) case: я реализую вариант использования, в котором Poco :: Timer проверяет каждые X секунд, если камера активна, используя ICMP-пинг. Это вызывает событие (с использованием событий Poco) на случай, если оно не отвечает, потому что сеть не работает, и я делаю следующее:
IPCamera отключен:
a) положить _watchEventLoopVariable = 1 для выхода из метода run;
б) выключить клиент, связанный с IPCamera, как показано
в) присоединиться к ветке
Я не уничтожаю поток, потому что я хотел бы использовать его снова, когда сеть снова работает, и камера снова работает. И в этом случае:
а) Я установил _eventWatchVariable = 0.
б) Позвольте начать поток снова с: myThread-> run ()
Valgrind сообщает мне, что утечки памяти обнаружены: прямые 60 байтов, 20 000 косвенных байтов теряются в потоке, в H264BufferdPackedFactory :: createNewPacket (…), классе Live555.
РЕШИТЬ
Я обнаружил, что проблема заключалась в туннелировании через TCP. В LIVE55 вы можете выбрать тип протокола.
Если я выберу:
#define REQUEST_STREAMING_OVER_TCP false
У меня нет утечки. Я использовал много раз Valgrind, чтобы быть уверенным (он обнаружил проблему).
Если я использую TCP, то вышеописанная проблема проявляется.