[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