[Live-devel] RTSP client runs on 100% CPU
Miklos Szeles
mszeles at netavis.hu
Thu Aug 18 02:03:09 PDT 2011
Hi,
We are using live555 to get RTSP streams from IP cameras. It has been
running fine with every kind of cameras for years. Unfortunately
recently we've experienced problems with Sanyo cameras. In the beginning
everything runs smoothly and approximately after a 60-70 secs the camera
closes the TCP socket for the RTSP stream. The RTP stream runs without
problem after this issue, but the streamer eats 100% of the CPU from
this point.
It looks like the select() always returns without blocking after the
camera closed the socket so it results in an endless loop of calling
select(). The RTSPClient's packet handler can read 0 bytes all the time
and simply writes an error message but no handling of this issue happens.
We are using a relatively old version of the live555 library. We haven't
upgraded since till now everything worked fine. Is it possible that the
latest version can correctly handle this issue?
Best regards,
Miklós
void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {
fd_set readSet = fReadSet; // make a copy for this select() call
DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();
struct timeval tv_timeToDelay;
tv_timeToDelay.tv_sec = timeToDelay.seconds();
tv_timeToDelay.tv_usec = timeToDelay.useconds();
// Very large "tv_sec" values cause select() to fail.
// Don't make it any larger than 1 million seconds (11.5 days)
const long MAX_TV_SEC = MILLION;
if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {
tv_timeToDelay.tv_sec = MAX_TV_SEC;
}
// Also check our "maxDelayTime" parameter (if it's > 0):
if (maxDelayTime > 0 &&
(tv_timeToDelay.tv_sec > (long)maxDelayTime/MILLION ||
(tv_timeToDelay.tv_sec == (long)maxDelayTime/MILLION &&
tv_timeToDelay.tv_usec > (long)maxDelayTime%MILLION))) {
tv_timeToDelay.tv_sec = maxDelayTime/MILLION;
tv_timeToDelay.tv_usec = maxDelayTime%MILLION;
}
int selectResult = select(fMaxNumSockets, &readSet, NULL, NULL,
&tv_timeToDelay);
if (selectResult < 0) {
#if defined(__WIN32__) || defined(_WIN32)
int err = WSAGetLastError();
// For some unknown reason, select() in Windoze sometimes fails
with WSAEINVAL if
// it was called with no entries set in "readSet". If this
happens, ignore it:
if (err == WSAEINVAL && readSet.fd_count == 0) {
err = 0;
// To stop this from happening again, create a dummy readable socket:
int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);
FD_SET((unsigned)dummySocketNum, &fReadSet);
}
if (err != 0) {
#else
if (errno != EINTR && errno != EAGAIN) {
#endif
// Unexpected error - treat this as fatal:
#if !defined(_WIN32_WCE)
perror("BasicTaskScheduler::SingleStep(): select() fails");
#endif
exit(0);
}
}
--
Miklós Szeles
NETAVIS Kft.
Web: www.netavis.net
Mail: mszeles at netavis.hu
Hűvösvölgyi út 54.
H-1021 Budapest
Hungary
Tel: +36 1 225 31 38
Fax: +36 1 225 31 39
More information about the live-devel
mailing list