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