Attached is a patch file for changes we've made to LIVE555 to support functionality we needed for our application.
The patch is a diff of the 1/26/2009 release and our changes.

I hope this patch isn't to big and all of the changes make sense and work with in your vision for the library.

If anything looks wrong or doesn't follow the direction you had intended for the library please let me know.

We intend to make more changes and would like to submit any improvements we make back to the project so let me know if there are any problems.

Thanks, for the great library and all the support.
Matt Schuckmann

A synopsis of the changes are listed below.

1. Modified BasicUsageEnvironment0::reportBackgroundError() to get the errorResultMsgBuffer contents via a call to getResultMsg() instead of accessing the private member directly so that it will work with derived class that doesn't use fResultMsgBuffer

2. Modified RTSPServer to use a virtual factory function, createNewClientSession(), to create RTSPClientSession objects (or derived children of that class) so that users that want to use a class derived from RTSPClientSession don't have to re-impliment all of the incomingConnectionHandler() code.

3. Added support recognizing SET_PARAMETER commands and passing the command body into the RTSPClientSession.

4. Added support to specify a range of ports that can be used for RTP/RTCP streams instead of just a starting port. Also added failure condition for when you run out of ports. Range is specified by a starting port and a count of following ports. The count can be set to -1 to allow a open ended range.

5. Added an iterator class to iterate over ServerMediaSession objects.

6. Added accessors to OnDemandServerMediaSubsession to get the RTP port and RTCP port for a client session ID associated with a void* streamToken. This primarily so that the server application can list the ports in use with each session. We will probably be adding more of these types of accessors please tell me if we aren't following your vision got this type of access.

7. Changed MS Visual Studio Makefile.tail make files to name the pdb files uniquely for each library so that all the libraries and there pdb files can be copied to a common directory.
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/BasicUsageEnvironment/BasicUsageEnvironment0.cpp
 
c:/builds/junk/SDKs/Lib/LIVE555/Live/BasicUsageEnvironment/BasicUsageEnvironment0.cpp
--- 
c:/builds/SDKs/LIVE555/LIVE555/Live/BasicUsageEnvironment/BasicUsageEnvironment0.cpp
        2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/BasicUsageEnvironment/BasicUsageEnvironment0.cpp
       2009-02-05 15:17:13.505834700 -0800
@@ -83,6 +83,6 @@ void BasicUsageEnvironment0::appendToRes
 }
 
 void BasicUsageEnvironment0::reportBackgroundError() {
-  fputs(fResultMsgBuffer, stderr);
+  fputs(getResultMsg(), stderr);
 }
 
Only in c:/builds/SDKs/LIVE555/LIVE555/Live/BasicUsageEnvironment: COPYING
Only in c:/builds/junk/SDKs/Lib/LIVE555/Live/BasicUsageEnvironment: COPYING.lnk
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/BasicUsageEnvironment/Makefile.tail 
c:/builds/junk/SDKs/Lib/LIVE555/Live/BasicUsageEnvironment/Makefile.tail
--- c:/builds/SDKs/LIVE555/LIVE555/Live/BasicUsageEnvironment/Makefile.tail     
2009-01-26 11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/BasicUsageEnvironment/Makefile.tail    
2009-02-05 15:17:13.646460600 -0800
@@ -1,5 +1,11 @@
 ##### End of variables to change
 
+!IFDEF NODEBUG
+PDBFILE = libBasicUsageEnvironment.pdb
+!ELSE
+PDBFILE = libBasicUsageEnvironmentD.pdb
+!ENDIF
+
 LIB = libBasicUsageEnvironment.$(LIB_SUFFIX)
 ALL = $(LIB)
 all:   $(ALL)
@@ -13,10 +19,10 @@ libBasicUsageEnvironment.$(LIB_SUFFIX): 
                $(OBJS)
 
 .$(C).$(OBJ):
-       $(C_COMPILER) -c $(C_FLAGS) $<       
+       $(C_COMPILER) /Fd$(PDBFILE) -c $(C_FLAGS) $<       
 
 .$(CPP).$(OBJ):
-       $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
+       $(CPLUSPLUS_COMPILER) /Fd$(PDBFILE) -c $(CPLUSPLUS_FLAGS) $<
 
 BasicUsageEnvironment0.$(CPP): include/BasicUsageEnvironment0.hh
 include/BasicUsageEnvironment0.hh:     
include/BasicUsageEnvironment_version.hh include/DelayQueue.hh
@@ -28,6 +34,6 @@ DelayQueue.$(CPP):            include/DelayQueue.h
 BasicHashTable.$(CPP):         include/BasicHashTable.hh
 
 clean:
-       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~
+       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~ $(PDBFILE)
 
 ##### Any additional, platform-specific rules come here:
Only in c:/builds/SDKs/LIVE555/LIVE555/Live/UsageEnvironment: COPYING
Only in c:/builds/junk/SDKs/Lib/LIVE555/Live/UsageEnvironment: COPYING.lnk
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/UsageEnvironment/Makefile.tail 
c:/builds/junk/SDKs/Lib/LIVE555/Live/UsageEnvironment/Makefile.tail
--- c:/builds/SDKs/LIVE555/LIVE555/Live/UsageEnvironment/Makefile.tail  
2009-01-26 11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/UsageEnvironment/Makefile.tail 
2009-02-05 15:17:13.771461400 -0800
@@ -1,5 +1,11 @@
 ##### End of variables to change
 
+!IFDEF NODEBUG
+PDBFILE = libUsageEnvironment.pdb
+!ELSE
+PDBFILE = libUsageEnvironmentD.pdb
+!ENDIF
+
 USAGE_ENVIRONMENT_LIB = libUsageEnvironment.$(LIB_SUFFIX)
 ALL = $(USAGE_ENVIRONMENT_LIB)
 all:   $(ALL)
@@ -10,10 +16,10 @@ $(USAGE_ENVIRONMENT_LIB): $(OBJS)
        $(LIBRARY_LINK)$@ $(LIBRARY_LINK_OPTS) $(OBJS)
 
 .$(C).$(OBJ):
-       $(C_COMPILER) -c $(C_FLAGS) $<       
+       $(C_COMPILER) /Fd$(PDBFILE) -c $(C_FLAGS) $<       
 
 .$(CPP).$(OBJ):
-       $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
+       $(CPLUSPLUS_COMPILER) /Fd$(PDBFILE) -c $(CPLUSPLUS_FLAGS) $<
 
 UsageEnvironment.$(CPP):       include/UsageEnvironment.hh
 include/UsageEnvironment.hh:   include/UsageEnvironment_version.hh 
include/strDup.hh
@@ -22,6 +28,6 @@ include/HashTable.hh:         include/Boolean.h
 strDup.$(CPP):                 include/strDup.hh
 
 clean:
-       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~
+       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~ $(PDBFILE)
 
 ##### Any additional, platform-specific rules come here:
Only in c:/builds/SDKs/LIVE555/LIVE555/Live/groupsock: COPYING
Only in c:/builds/junk/SDKs/Lib/LIVE555/Live/groupsock: COPYING.lnk
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/groupsock/Makefile.tail 
c:/builds/junk/SDKs/Lib/LIVE555/Live/groupsock/Makefile.tail
--- c:/builds/SDKs/LIVE555/LIVE555/Live/groupsock/Makefile.tail 2009-01-26 
11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/groupsock/Makefile.tail        
2009-02-05 15:17:14.755842700 -0800
@@ -1,13 +1,19 @@
 ##### End of variables to change
 
+!IFDEF NODEBUG
+PDBFILE = libgroupsock.pdb
+!ELSE
+PDBFILE = libgroupsockD.pdb
+!ENDIF
+
 ALL = libgroupsock.$(LIB_SUFFIX)
 all:   $(ALL)
 
 .$(C).$(OBJ):
-       $(C_COMPILER) -c $(C_FLAGS) $<       
+       $(C_COMPILER) /Fd$(PDBFILE) -c $(C_FLAGS) $<       
 
 .$(CPP).$(OBJ):
-       $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
+       $(CPLUSPLUS_COMPILER) /Fd$(PDBFILE) -c $(CPLUSPLUS_FLAGS) $<
 
 GROUPSOCK_LIB_OBJS = GroupsockHelper.$(OBJ) GroupEId.$(OBJ) inet.$(OBJ) 
Groupsock.$(OBJ) NetInterface.$(OBJ) NetAddress.$(OBJ) IOHandlers.$(OBJ)
 
@@ -31,6 +37,6 @@ libgroupsock.$(LIB_SUFFIX): $(GROUPSOCK_
                $(GROUPSOCK_LIB_OBJS)
 
 clean:
-       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~
+       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~ $(PDBFILE)
 
 ##### Any additional, platform-specific rules come here:
Only in c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia: COPYING
Only in c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia: COPYING.lnk
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/Makefile.tail 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/Makefile.tail
--- c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/Makefile.tail 2009-01-26 
11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/Makefile.tail        
2009-02-05 15:17:15.318346300 -0800
@@ -1,14 +1,20 @@
 ##### End of variables to change
 
+!IFDEF NODEBUG
+PDBFILE = libliveMedia.pdb
+!ELSE
+PDBFILE = libliveMediaD.pdb
+!ENDIF
+
 LIVEMEDIA_LIB = libliveMedia.$(LIB_SUFFIX)
 ALL = $(LIVEMEDIA_LIB)
 all:   $(ALL)
 
 .$(C).$(OBJ):
-       $(C_COMPILER) -c $(C_FLAGS) $<       
+       $(C_COMPILER) /Fd$(PDBFILE) -c $(C_FLAGS) $<       
 
 .$(CPP).$(OBJ):
-       $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
+       $(CPLUSPLUS_COMPILER) /Fd$(PDBFILE) -c $(CPLUSPLUS_FLAGS) $<
 
 MP3_SOURCE_OBJS = MP3FileSource.$(OBJ) MP3HTTPSource.$(OBJ) 
MP3Transcoder.$(OBJ) MP3ADU.$(OBJ) MP3ADUdescriptor.$(OBJ) 
MP3ADUinterleaving.$(OBJ) MP3ADUTranscoder.$(OBJ) MP3StreamState.$(OBJ) 
MP3Internals.$(OBJ) MP3InternalsHuffman.$(OBJ) MP3InternalsHuffmanTable.$(OBJ) 
MP3ADURTPSource.$(OBJ)
 MPEG_SOURCE_OBJS = MPEG1or2Demux.$(OBJ) MPEG1or2DemuxedElementaryStream.$(OBJ) 
MPEGVideoStreamFramer.$(OBJ) MPEG1or2VideoStreamFramer.$(OBJ) 
MPEG1or2VideoStreamDiscreteFramer.$(OBJ) MPEG4VideoStreamFramer.$(OBJ) 
MPEG4VideoStreamDiscreteFramer.$(OBJ) H264VideoStreamFramer.$(OBJ) 
MPEGVideoStreamParser.$(OBJ) MPEG1or2AudioStreamFramer.$(OBJ) 
MPEG1or2AudioRTPSource.$(OBJ) MPEG4LATMAudioRTPSource.$(OBJ) 
MPEG4ESVideoRTPSource.$(OBJ) MPEG4GenericRTPSource.$(OBJ) $(MP3_SOURCE_OBJS) 
MPEG1or2VideoRTPSource.$(OBJ) MPEG2TransportStreamMultiplexor.$(OBJ) 
MPEG2TransportStreamFromPESSource.$(OBJ) 
MPEG2TransportStreamFromESSource.$(OBJ) MPEG2TransportStreamFramer.$(OBJ) 
ADTSAudioFileSource.$(OBJ)
@@ -289,6 +295,6 @@ include/liveMedia.hh::      include/H261Video
 include/liveMedia.hh:: include/RTSPServer.hh include/RTSPOverHTTPServer.hh 
include/RTSPClient.hh include/SIPClient.hh include/QuickTimeFileSink.hh 
include/QuickTimeGenericRTPSource.hh include/AVIFileSink.hh 
include/PassiveServerMediaSubsession.hh 
include/MPEG4VideoFileServerMediaSubsession.hh 
include/WAVAudioFileServerMediaSubsession.hh 
include/AMRAudioFileServerMediaSubsession.hh include/AMRAudioFileSource.hh 
include/AMRAudioRTPSink.hh include/MP3AudioFileServerMediaSubsession.hh 
include/MPEG1or2VideoFileServerMediaSubsession.hh 
include/MPEG1or2FileServerDemux.hh 
include/MPEG2TransportFileServerMediaSubsession.hh 
include/H263plusVideoFileServerMediaSubsession.hh 
include/ADTSAudioFileServerMediaSubsession.hh include/DarwinInjector.hh
 
 clean:
-       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~
+       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~ $(PDBFILE)
 
 ##### Any additional, platform-specific rules come here:
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/OnDemandServerMediaSubsession.cpp 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/OnDemandServerMediaSubsession.cpp
--- 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/OnDemandServerMediaSubsession.cpp 
    2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/OnDemandServerMediaSubsession.cpp
    2009-02-05 15:17:15.333971400 -0800
@@ -27,10 +27,11 @@ along with this library; if not, write t
 OnDemandServerMediaSubsession
 ::OnDemandServerMediaSubsession(UsageEnvironment& env,
                                Boolean reuseFirstSource,
-                               portNumBits initialPortNum)
+                               portNumBits initialPortNum,
+                               int numPorts)
   : ServerMediaSubsession(env),
     fReuseFirstSource(reuseFirstSource), fInitialPortNum(initialPortNum),
-    fLastStreamToken(NULL), fSDPLines(NULL) {
+       fNumPorts(numPorts), fLastStreamToken(NULL), fSDPLines(NULL) {  /*D*/
   fDestinationsHashTable = HashTable::create(ONE_WORD_HASH_KEYS);
   gethostname(fCNAME, sizeof fCNAME);
   fCNAME[sizeof fCNAME-1] = '\0'; // just in case
@@ -141,7 +142,7 @@ private:
   Groupsock* fRTPgs; Groupsock* fRTCPgs;
 };
 
-void OnDemandServerMediaSubsession
+bool OnDemandServerMediaSubsession
 ::getStreamParameters(unsigned clientSessionId,
                      netAddressBits clientAddress,
                      Port const& clientRTPPort,
@@ -171,6 +172,7 @@ void OnDemandServerMediaSubsession
     unsigned streamBitrate;
     FramedSource* mediaSource
       = createNewStreamSource(clientSessionId, streamBitrate);
+       bool bFoundSockets = false;     // set to true to indicate we 
successfully found a (set of) sockets we could use        /*D*/
 
     // Create 'groupsock' and 'sink' objects for the destination,
     // using previously unused server port numbers:
@@ -182,14 +184,27 @@ void OnDemandServerMediaSubsession
     if (clientRTCPPort.num() == 0) {
       // We're streaming raw UDP (not RTP). Create a single groupsock:
       NoReuse dummy; // ensures that we skip over ports that are already in use
-      for (serverPortNum = fInitialPortNum; ; ++serverPortNum) {
-       struct in_addr dummyAddr; dummyAddr.s_addr = 0;
-
-       serverRTPPort = serverPortNum;
-       rtpGroupsock = new Groupsock(envir(), dummyAddr, serverRTPPort, 255);
-       if (rtpGroupsock->socketNum() >= 0) break; // success
+         portNumBits portNumLimit = fInitialPortNum + fNumPorts;       /*T*/
+      for (serverPortNum = fInitialPortNum; (-1 == fNumPorts) || 
(serverPortNum < portNumLimit); ++serverPortNum) {    /*T*/
+               struct in_addr dummyAddr; dummyAddr.s_addr = 0;
+
+               serverRTPPort = serverPortNum;
+               rtpGroupsock = new Groupsock(envir(), dummyAddr, serverRTPPort, 
255);
+               if (rtpGroupsock->socketNum() >= 0)     /*T*/
+               {
+                       bFoundSockets = true;   /*T*/
+                       break; // success
+               }
       }
 
+         if (!bFoundSockets)   /*T*/
+         {
+                 // failure to find a socket we could use
+                 mediaSource->close(mediaSource->envir(), 
mediaSource->name());        /*T*/
+                 envir() << "Unable to allocate socket -- no more ports in 
allowed port range\n";      /*T*/
+                 return  false;
+         }
+
       rtcpGroupsock = NULL;
       rtpSink = NULL;
       udpSink = BasicUDPSink::createNew(envir(), rtpGroupsock);
@@ -197,7 +212,8 @@ void OnDemandServerMediaSubsession
       // Normal case: We're streaming RTP (over UDP or TCP).  Create a pair of
       // groupsocks (RTP and RTCP), with adjacent port numbers (RTP port 
number even):
       NoReuse dummy; // ensures that we skip over ports that are already in use
-      for (portNumBits serverPortNum = fInitialPortNum; ; serverPortNum += 2) {
+         portNumBits portNumLimit = fInitialPortNum + ((fNumPorts / 2) * 2);   
// need ports in pairs, so round down num of avail ports to even number /*D*/
+      for (portNumBits serverPortNum = fInitialPortNum; (-1 == fNumPorts) || 
(serverPortNum < portNumLimit); serverPortNum += 2) {     /*D*/
        struct in_addr dummyAddr; dummyAddr.s_addr = 0;
 
        serverRTPPort = serverPortNum;
@@ -215,9 +231,18 @@ void OnDemandServerMediaSubsession
          continue; // try again
        }
 
+       bFoundSockets = true;   /*D*/
        break; // success
       }
 
+       if (!bFoundSockets)     /*D*/
+       {
+               // failure to find a socket we could use
+               mediaSource->close(mediaSource->envir(), mediaSource->name());  
/*D*/
+               envir() << "Unable to allocate socket -- no more ports in 
allowed port range\n";        /*D*/
+               return  false;
+       }
+
       unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic
       rtpSink = createNewRTPSink(rtpGroupsock, rtpPayloadType, mediaSource);
       udpSink = NULL;
@@ -243,6 +268,9 @@ void OnDemandServerMediaSubsession
     destinations = new Destinations(tcpSocketNum, rtpChannelId, rtcpChannelId);
   }
   fDestinationsHashTable->Add((char const*)clientSessionId, destinations);
+
+  // success
+  return  true;        /*D*/
 }
 
 void OnDemandServerMediaSubsession::startStream(unsigned clientSessionId,
@@ -326,6 +354,30 @@ void OnDemandServerMediaSubsession::dele
   delete destinations;
 }
 
+bool OnDemandServerMediaSubsession
+::getRTPPortForStream(unsigned /*clientSessionId*/, void*& streamToken, Port 
&port)
+{
+  StreamState* streamState = (StreamState*)streamToken;        /*D*/
+  if (streamState != NULL)     /*D*/
+  {
+         port = streamState->serverRTPPort();  /*D*/
+         return true;
+  }
+  return false;        /*D*/
+}
+
+bool OnDemandServerMediaSubsession
+::getRTCPPortForStream(unsigned /*clientSessionId*/, void*& streamToken, Port 
&port)
+{
+  StreamState* streamState = (StreamState*)streamToken;        /*D*/
+  if (streamState != NULL)     /*D*/
+  {
+         port = streamState->serverRTCPPort(); /*D*/
+         return true;
+  }
+  return false;        /*D*/
+}
+
 char const* OnDemandServerMediaSubsession
 ::getAuxSDPLine(RTPSink* rtpSink, FramedSource* /*inputSource*/) {
   // Default implementation:
@@ -346,6 +398,16 @@ void OnDemandServerMediaSubsession::clos
   Medium::close(inputSource);
 }
 
+void OnDemandServerMediaSubsession::setStartOfPortRange( int newInitialPortNum 
 )
+{
+       fInitialPortNum = newInitialPortNum;    /*T*/
+}
+
+void OnDemandServerMediaSubsession::setNumOfPorts( int newNumPorts  )
+{
+       fNumPorts = newNumPorts;        /*T*/
+}
+
 void OnDemandServerMediaSubsession
 ::setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource) {
   if (rtpSink == NULL) return;
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/PassiveServerMediaSubsession.cpp 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/PassiveServerMediaSubsession.cpp
--- 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/PassiveServerMediaSubsession.cpp  
    2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/PassiveServerMediaSubsession.cpp 
    2009-02-05 15:17:15.333971400 -0800
@@ -88,7 +88,7 @@ PassiveServerMediaSubsession::sdpLines()
   return fSDPLines;
 }
 
-void PassiveServerMediaSubsession
+bool PassiveServerMediaSubsession
 ::getStreamParameters(unsigned /*clientSessionId*/,
                      netAddressBits /*clientAddress*/,
                      Port const& /*clientRTPPort*/,
@@ -121,6 +121,9 @@ void PassiveServerMediaSubsession
     serverRTCPPort = rtcpGS->port();
   }
   streamToken = NULL; // not used
+
+  // success
+  return true;
 }
 
 void PassiveServerMediaSubsession::startStream(unsigned /*clientSessionId*/,
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/RTSPOverHTTPServer.cpp 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/RTSPOverHTTPServer.cpp
--- c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/RTSPOverHTTPServer.cpp        
2009-01-26 11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/RTSPOverHTTPServer.cpp       
2009-02-05 15:17:15.349596500 -0800
@@ -232,7 +232,8 @@ void RTSPOverHTTPServer::HTTPClientConne
     } else if (strcmp(cmdName, "TEARDOWN") == 0
                || strcmp(cmdName, "PLAY") == 0
                || strcmp(cmdName, "PAUSE") == 0
-               || strcmp(cmdName, "GET_PARAMETER") == 0) {
+               || strcmp(cmdName, "GET_PARAMETER") == 0
+               || strcmp(cmdName, "SET_PARAMETER") == 0) {
       handleCmd_withinSession(cmdName, urlPreSuffix, urlSuffix, cseq,
                               (char const*)fRequestBuffer);
     } else {
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/RTSPServer.cpp 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/RTSPServer.cpp
--- c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/RTSPServer.cpp        
2009-01-26 11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/RTSPServer.cpp       
2009-02-05 15:17:15.349596500 -0800
@@ -236,15 +236,21 @@ void RTSPServer::incomingConnectionHandl
   increaseSendBufferTo(envir(), clientSocket, 50*1024);
 
 #if defined(DEBUG) || defined(DEBUG_CONNECTIONS)
-  fprintf(stderr, "accept()ed connection from %s\n", 
our_inet_ntoa(clientAddr.sin_addr));
+  envir() << "accept()ed connection from " << 
our_inet_ntoa(clientAddr.sin_addr) << '\n';
 #endif
 
+  //Create a new object for this RTSP session:
+  (void)this->createNewClientSession(++fSessionIdCounter, clientSocket, 
clientAddr);
+}
+
+RTSPServer::RTSPClientSession* RTSPServer::createNewClientSession(unsigned 
sessionId,
+                     int clientSocket, struct sockaddr_in clientAddr )
+{
   // Create a new object for this RTSP session:
-  new RTSPClientSession(*this, ++fSessionIdCounter,
+  return new RTSPClientSession(*this, ++fSessionIdCounter,
                        clientSocket, clientAddr);
 }
 
-
 ////////// RTSPServer::RTSPClientSession //////////
 
 RTSPServer::RTSPClientSession
@@ -378,7 +384,8 @@ void RTSPServer::RTSPClientSession::inco
     } else if (strcmp(cmdName, "TEARDOWN") == 0
               || strcmp(cmdName, "PLAY") == 0
               || strcmp(cmdName, "PAUSE") == 0
-              || strcmp(cmdName, "GET_PARAMETER") == 0) {
+              || strcmp(cmdName, "GET_PARAMETER") == 0
+         || strcmp(cmdName, "SET_PARAMETER") == 0) {
       handleCmd_withinSession(cmdName, urlPreSuffix, urlSuffix, cseq,
                              (char const*)fRequestBuffer);
     } else {
@@ -405,7 +412,7 @@ void RTSPServer::RTSPClientSession::inco
 // Handler routines for specific RTSP commands:
 
 // Generate a "Date:" header for use in a RTSP response:
-static char const* dateHeader() {
+char const* dateHeader() {
   static char buf[200];
 #if !defined(_WIN32_WCE)
   time_t tt = time(NULL);
@@ -433,7 +440,7 @@ static char const* dateHeader() {
 }
 
 static char const* allowedCommandNames
-  = "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE";
+  = "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, 
SET_PARAMETER";
 
 void RTSPServer::RTSPClientSession::handleCmd_bad(char const* /*cseq*/) {
   // Don't do anything with "cseq", because it might be nonsense
@@ -725,12 +732,17 @@ void RTSPServer::RTSPClientSession
   delete[] clientsDestinationAddressStr;
   Port serverRTPPort(0);
   Port serverRTCPPort(0);
-  subsession->getStreamParameters(fOurSessionId, fClientAddr.sin_addr.s_addr,
+  if (!subsession->getStreamParameters(fOurSessionId, 
fClientAddr.sin_addr.s_addr,     /*D*/
                                  clientRTPPort, clientRTCPPort,
                                  tcpSocketNum, rtpChannelId, rtcpChannelId,
                                  destinationAddress, destinationTTL, 
fIsMulticast,
                                  serverRTPPort, serverRTCPPort,
-                                 fStreamStates[streamNum].streamToken);
+                                 fStreamStates[streamNum].streamToken))
+  {
+         // failed to get stream paramters.. clean up and exit
+         delete[] streamingModeString; /*D*/
+         return;
+  }
   struct in_addr destinationAddr; destinationAddr.s_addr = destinationAddress;
   char* destAddrStr = strDup(our_inet_ntoa(destinationAddr));
   struct sockaddr_in sourceAddr; SOCKLEN_T namelen = sizeof sourceAddr;
@@ -861,10 +873,11 @@ void RTSPServer::RTSPClientSession
   } else if (strcmp(cmdName, "SET_PARAMETER") == 0) {
     handleCmd_SET_PARAMETER(subsession, cseq, fullRequestStr);
   }
+
 }
 
-void RTSPServer::RTSPClientSession
-::handleCmd_TEARDOWN(ServerMediaSubsession* /*subsession*/, char const* cseq) {
+void RTSPServer::RTSPClientSession::handleCmd_TEARDOWN(ServerMediaSubsession* 
/*subsession*/, char const* cseq) 
+{
   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
           "RTSP/1.0 200 OK\r\nCSeq: %s\r\n%s\r\n",
           cseq, dateHeader());
@@ -1258,3 +1271,26 @@ void UserAuthenticationDatabase::removeU
 char const* UserAuthenticationDatabase::lookupPassword(char const* username) {
   return (char const*)(fTable->Lookup(username));
 }
+
+////////// ServerMediaSessionIterator //////////
+
+ServerMediaSessionIterator
+::ServerMediaSessionIterator(RTSPServer& server)
+: fOurIterator( (NULL == server.fServerMediaSessions) ? NULL : 
HashTable::Iterator::create( *server.fServerMediaSessions ) )
+{      /*T*/
+}
+
+ServerMediaSessionIterator::~ServerMediaSessionIterator()
+{
+       delete fOurIterator;    /*T*/
+#ifdef _DEBUG
+       fOurIterator = NULL;
+#endif  /* _DEBUG */
+}
+
+ServerMediaSession* ServerMediaSessionIterator::next(char const*& sessionName)
+{
+       return  (fOurIterator) ? 
(ServerMediaSession*)fOurIterator->next(sessionName) : NULL;   /*T*/
+}
+
+////////// ServerMediaSessionIterator //////////
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/OnDemandServerMediaSubsession.hh
 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/OnDemandServerMediaSubsession.hh
--- 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/OnDemandServerMediaSubsession.hh
      2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/OnDemandServerMediaSubsession.hh
     2009-02-05 15:17:15.521472600 -0800
@@ -31,13 +31,22 @@ along with this library; if not, write t
 
 class OnDemandServerMediaSubsession: public ServerMediaSubsession {
 protected: // we're a virtual base class
+       /**
+        * constructor.
+        *
+        * @param initialPortNum        The start of the port range used by the 
server.
+        *              Default 6970.  This value can be changed on the fly 
using setStartOfPortRange().
+        * @param numPorts      The number of ports in the range the server is 
allowed
+        *              to use.  -1 is a special value that allows unlimited 
ports.  Default -1.
+        *              This value change be changed on the fly using 
setNumOfPorts().
+        */
   OnDemandServerMediaSubsession(UsageEnvironment& env, Boolean 
reuseFirstSource,
-                               portNumBits initialPortNum = 6970);
+                               portNumBits initialPortNum = 6970, int numPorts 
= -1);
   virtual ~OnDemandServerMediaSubsession();
 
 protected: // redefined virtual functions
   virtual char const* sdpLines();
-  virtual void getStreamParameters(unsigned clientSessionId,
+  virtual bool getStreamParameters(unsigned clientSessionId,
                                   netAddressBits clientAddress,
                                    Port const& clientRTPPort,
                                    Port const& clientRTCPPort,
@@ -59,6 +68,8 @@ protected: // redefined virtual function
   virtual void seekStream(unsigned clientSessionId, void* streamToken, double 
seekNPT);
   virtual void setStreamScale(unsigned clientSessionId, void* streamToken, 
float scale);
   virtual void deleteStream(unsigned clientSessionId, void*& streamToken);
+  virtual bool getRTPPortForStream(unsigned clientSessionId, void*& 
streamToken, Port &port);  // fills in port, returns true on suiccess, false on 
failure
+  virtual bool getRTCPPortForStream(unsigned clientSessionId, void*& 
streamToken, Port& port); // fills in port, returns true on suiccess, false on 
failure
 
 protected: // new virtual functions, possibly redefined by subclasses
   virtual char const* getAuxSDPLine(RTPSink* rtpSink,
@@ -67,6 +78,27 @@ protected: // new virtual functions, pos
   virtual void setStreamSourceScale(FramedSource* inputSource, float scale);
   virtual void closeStreamSource(FramedSource *inputSource);
 
+public:
+  /**
+   * Set the start of the port range that new streams will be bound to.
+   * Overrides the value initialPortNum passed on the constructor.  Existing
+   * sessions will be unchanged -- only new sessions will be affected.
+   *
+   * @param newInitialPortNum The new start of the port range to be used for
+   *           all new sessions.  RTP servers typically start serving on port 
6970.
+   */
+  virtual void setStartOfPortRange( int newInitialPortNum );
+
+  /**
+   * Set the number of ports in the range that the server can use.
+   * Overrides the value numPorts passed on the constructor.  Existing
+   * sessions will be unchanged -- only new sessions will be affected.
+   *
+   * @param newInitialPortNum The new size of the range of ports to be
+   *           used when constructing new sessions.  
+   */
+  virtual void setNumOfPorts( int newNumPorts );
+
 protected: // new virtual functions, defined by all subclasses
   virtual FramedSource* createNewStreamSource(unsigned clientSessionId,
                                              unsigned& estBitrate) = 0;
@@ -82,6 +114,7 @@ private:
 private:
   Boolean fReuseFirstSource;
   portNumBits fInitialPortNum;
+  int fNumPorts;       // num of ports in block, -1 if unlimited
   HashTable* fDestinationsHashTable; // indexed by client session id
   void* fLastStreamToken;
   char* fSDPLines;
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/PassiveServerMediaSubsession.hh
 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/PassiveServerMediaSubsession.hh
--- 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/PassiveServerMediaSubsession.hh
       2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/PassiveServerMediaSubsession.hh
      2009-02-05 15:17:15.521472600 -0800
@@ -45,7 +45,7 @@ protected:
 
 protected: // redefined virtual functions
   virtual char const* sdpLines();
-  virtual void getStreamParameters(unsigned clientSessionId,
+  virtual bool getStreamParameters(unsigned clientSessionId,
                                   netAddressBits clientAddress,
                                    Port const& clientRTPPort,
                                    Port const& clientRTCPPort,
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/RTSPOverHTTPServer.hh 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/RTSPOverHTTPServer.hh
--- c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/RTSPOverHTTPServer.hh 
2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/RTSPOverHTTPServer.hh    
    2009-02-05 15:17:15.537097700 -0800
@@ -86,6 +86,8 @@ private:
                         char const* cseq);
     void handleCmd_GET_PARAMETER(ServerMediaSubsession* subsession,
                                 char const* cseq, char const* fullRequestStr);
+    void handleCmd_SET_PARAMETER(ServerMediaSubsession* subsession,
+                                char const* cseq, char const* fullRequestStr);
     Boolean authenticationOK(char const* cmdName, char const* cseq,
                             char const* fullRequestStr);
     void noteLiveness();
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/RTSPServer.hh 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/RTSPServer.hh
--- c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/RTSPServer.hh 
2009-01-26 11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/RTSPServer.hh        
2009-02-05 15:17:15.537097700 -0800
@@ -59,6 +59,9 @@ protected:
 
 #define RTSP_BUFFER_SIZE 10000 // for incoming requests, and outgoing responses
 
+// Generate a "Date:" header for use in a RTSP response:
+char const* dateHeader();
+
 class RTSPServer: public Medium {
 public:
   static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
@@ -75,7 +78,18 @@ public:
                              RTSPServer*& resultServer);
 
   void addServerMediaSession(ServerMediaSession* serverMediaSession);
+
+  /**
+   * lookup server media session by name.
+   * Returns ptr to the server media session or NULL if none found.
+   *
+   * @param streamName Name to look up.  Names are compared using strcmp().
+   *
+   * @return Returns a pointer to the ServerMediaSession or NULL if no such
+   *   session.  This pointer should not be deleted by the caller.
+   */
   virtual ServerMediaSession* lookupServerMediaSession(char const* streamName);
+
   void removeServerMediaSession(ServerMediaSession* serverMediaSession);
   void removeServerMediaSession(char const* streamName);
 
@@ -110,6 +124,15 @@ private: // redefined virtual functions
   virtual Boolean isRTSPServer() const;
 
 protected:
+  class RTSPClientSession;
+
+  static void incomingConnectionHandler(void*, int /*mask*/);
+  void incomingConnectionHandler1();
+
+  virtual RTSPClientSession* createNewClientSession(unsigned sessionId,
+      int clientSocket, struct sockaddr_in clientAddr ); 
+
+protected:
   // The state of each individual session handled by a RTSP server:
   class RTSPClientSession {
   public:
@@ -117,6 +140,11 @@ protected:
                      int clientSocket, struct sockaddr_in clientAddr);
     virtual ~RTSPClientSession();
   protected:
+    UsageEnvironment& envir() { return fOurServer.envir(); }
+    void reclaimStreamStates();
+    void resetRequestBuffer();
+    static void incomingRequestHandler(void*, int /*mask*/);
+    void incomingRequestHandler1();
     // Make the handler functions for each command virtual, to allow 
subclasses to redefine them:
     virtual void handleCmd_bad(char const* cseq);
     virtual void handleCmd_notSupported(char const* cseq);
@@ -141,12 +169,8 @@ protected:
                                         char const* cseq, char const* 
fullRequestStr);
     virtual void handleCmd_SET_PARAMETER(ServerMediaSubsession* subsession,
                                         char const* cseq, char const* 
fullRequestStr);
-  private:
-    UsageEnvironment& envir() { return fOurServer.envir(); }
-    void reclaimStreamStates();
-    void resetRequestBuffer();
-    static void incomingRequestHandler(void*, int /*mask*/);
-    void incomingRequestHandler1();
+  
+
     Boolean authenticationOK(char const* cmdName, char const* cseq,
                              char const* urlSuffix,
                              char const* fullRequestStr);
@@ -154,7 +178,8 @@ protected:
     Boolean isMulticast() const { return fIsMulticast; }
     static void noteClientLiveness(RTSPClientSession* clientSession);
     static void livenessTimeoutTask(RTSPClientSession* clientSession);
-  private:
+
+  protected:
     RTSPServer& fOurServer;
     unsigned fOurSessionId;
     ServerMediaSession* fOurServerMediaSession;
@@ -176,11 +201,8 @@ protected:
   };
 
 private:
-  static void incomingConnectionHandler(void*, int /*mask*/);
-  void incomingConnectionHandler1();
-
-private:
   friend class RTSPClientSession;
+  friend class ServerMediaSessionIterator;
   int fServerSocket;
   Port fServerPort;
   UserAuthenticationDatabase* fAuthDB;
@@ -189,4 +211,26 @@ private:
   unsigned fSessionIdCounter;
 };
 
+// Iterator for the ServerMediaSession instances in an RTSPServer.
+class ServerMediaSessionIterator {
+public:
+  ServerMediaSessionIterator(RTSPServer& server);
+  virtual ~ServerMediaSessionIterator();
+
+  /**
+   * Get ptr to next ServerMediaSession, NULL if no more.  Name of
+   * session also returned in sessionName.
+   *
+   * @param sessionName        [OUT] The name of the session.
+   *
+   * @return   Pointer to the session or NULL if no more sessions.  sessionName
+   *   is not valid if return is NULL.
+   */
+  ServerMediaSession* next(char const*& sessionName);
+
+private:
+  HashTable::Iterator *fOurIterator;
+  ServerMediaSession* fNextPtr;
+};
+
 #endif
diff -rup 
c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/ServerMediaSession.hh 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/ServerMediaSession.hh
--- c:/builds/SDKs/LIVE555/LIVE555/Live/liveMedia/include/ServerMediaSession.hh 
2009-01-26 11:18:41.000000000 -0800
+++ 
c:/builds/junk/SDKs/Lib/LIVE555/Live/liveMedia/include/ServerMediaSession.hh    
    2009-02-05 15:17:15.537097700 -0800
@@ -115,7 +115,9 @@ public:
   unsigned trackNumber() const { return fTrackNumber; }
   char const* trackId();
   virtual char const* sdpLines() = 0;
-  virtual void getStreamParameters(unsigned clientSessionId, // in
+
+  // returns true on success, false on failure
+  virtual bool getStreamParameters(unsigned clientSessionId, // in
                                   netAddressBits clientAddress, // in
                                   Port const& clientRTPPort, // in
                                   Port const& clientRTCPPort, // in
Only in c:/builds/SDKs/LIVE555/LIVE555/Live/mediaServer: COPYING
Only in c:/builds/junk/SDKs/Lib/LIVE555/Live/mediaServer: COPYING.lnk
diff -rup c:/builds/SDKs/LIVE555/LIVE555/Live/mediaServer/Makefile.tail 
c:/builds/junk/SDKs/Lib/LIVE555/Live/mediaServer/Makefile.tail
--- c:/builds/SDKs/LIVE555/LIVE555/Live/mediaServer/Makefile.tail       
2009-01-26 11:18:41.000000000 -0800
+++ c:/builds/junk/SDKs/Lib/LIVE555/Live/mediaServer/Makefile.tail      
2009-02-05 15:17:16.099601300 -0800
@@ -1,15 +1,21 @@
 ##### End of variables to change
 
+!IFDEF NODEBUG
+PDBFILE = live555MediaServer.pdb
+!ELSE
+PDBFILE = live555MediaServerD.pdb
+!ENDIF
+
 MEDIA_SERVER = live555MediaServer$(EXE)
 
 ALL = $(MEDIA_SERVER)
 all: $(ALL)
 
 .$(C).$(OBJ):
-       $(C_COMPILER) -c $(C_FLAGS) $<       
+       $(C_COMPILER) /Fd$(PDBFILE) -c $(C_FLAGS) $<       
 
 .$(CPP).$(OBJ):
-       $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
+       $(CPLUSPLUS_COMPILER) /Fd$(PDBFILE) -c $(CPLUSPLUS_FLAGS) $<
 
 MEDIA_SERVER_OBJS = live555MediaServer.$(OBJ) DynamicRTSPServer.$(OBJ)
 
@@ -29,9 +35,9 @@ LOCAL_LIBS =  $(LIVEMEDIA_LIB) $(GROUPSOC
 LIBS =                 $(LOCAL_LIBS) $(LIBS_FOR_CONSOLE_APPLICATION)
 
 live555MediaServer$(EXE):      $(MEDIA_SERVER_OBJS) $(LOCAL_LIBS)
-       $(LINK)$@ $(CONSOLE_LINK_OPTS) $(MEDIA_SERVER_OBJS) $(LIBS)
+       $(LINK)$@ /PDB:$(PDBFILE) $(CONSOLE_LINK_OPTS) $(MEDIA_SERVER_OBJS) 
$(LIBS)
 
 clean:
-       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~
+       -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~ $(PDBFILE)
 
 ##### Any additional, platform-specific rules come here:
Only in c:/builds/SDKs/LIVE555/LIVE555/Live/testProgs: COPYING
Only in c:/builds/junk/SDKs/Lib/LIVE555/Live/testProgs: COPYING.lnk
_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel

Reply via email to