+++ /dev/null
-diff -ur -x Makefile live/liveMedia/BasicUDPSource.cpp live.2004.10.28a/liveMedia/BasicUDPSource.cpp
---- live/liveMedia/BasicUDPSource.cpp 2004-10-28 09:12:03.000000000 +0100
-+++ live.2004.10.28a/liveMedia/BasicUDPSource.cpp 2004-10-28 14:47:18.000000000 +0100
-@@ -33,6 +33,11 @@
- envir().taskScheduler().turnOffBackgroundReadHandling(fInputGS->socketNum());
- }
-
-+Groupsock* BasicUDPSource::groupSock()
-+{
-+ return fInputGS;
-+}
-+
- void BasicUDPSource::doGetNextFrame() {
- // Await the next incoming packet:
- envir().taskScheduler().turnOnBackgroundReadHandling(fInputGS->socketNum(),
-diff -ur -x Makefile live/liveMedia/include/BasicUDPSource.hh live.2004.10.28a/liveMedia/include/BasicUDPSource.hh
---- live/liveMedia/include/BasicUDPSource.hh 2004-10-28 09:12:02.000000000 +0100
-+++ live.2004.10.28a/liveMedia/include/BasicUDPSource.hh 2004-10-28 14:47:45.000000000 +0100
-@@ -33,6 +33,7 @@
- static BasicUDPSource* createNew(UsageEnvironment& env, Groupsock* inputGS);
-
- virtual ~BasicUDPSource();
-+ virtual Groupsock* groupSock();
-
- private:
- BasicUDPSource(UsageEnvironment& env, Groupsock* inputGS);
-diff -ur -x Makefile live/liveMedia/include/RTSPClient.hh live.2004.10.28a/liveMedia/include/RTSPClient.hh
---- live/liveMedia/include/RTSPClient.hh 2004-10-28 09:12:02.000000000 +0100
-+++ live.2004.10.28a/liveMedia/include/RTSPClient.hh 2004-10-29 14:40:37.000000000 +0100
-@@ -43,7 +43,7 @@
- char const* sourceName,
- RTSPClient*& resultClient);
-
-- char* describeURL(char const* url, Authenticator* authenticator = NULL);
-+ char* describeURL(char const* url, Authenticator* authenticator = NULL, bool kasennaFlag = false);
- // Issues a RTSP "DESCRIBE" command
- // Returns the SDP description of a session, or NULL if none
- // (This is dynamically allocated, and must later be freed
-@@ -178,6 +178,9 @@
- #endif
- unsigned fDescribeStatusCode;
- // 0: OK; 1: connection failed; 2: stream unavailable
-+
-+ bool kasennaServer;
-+ char kasennaContentType[10];
- };
-
- #endif
-diff -ur -x Makefile live/liveMedia/RTSPClient.cpp live.2004.10.28a/liveMedia/RTSPClient.cpp
---- live/liveMedia/RTSPClient.cpp 2004-10-28 09:12:02.000000000 +0100
-+++ live.2004.10.28a/liveMedia/RTSPClient.cpp 2004-11-01 15:06:47.026406304 +0000
-@@ -127,7 +127,7 @@
- return NULL;
- }
-
--char* RTSPClient::describeURL(char const* url, Authenticator* authenticator) {
-+char* RTSPClient::describeURL(char const* url, Authenticator* authenticator, bool kasennaFlag) {
- char* cmd = NULL;
- fDescribeStatusCode = 0;
- do {
-@@ -149,13 +149,21 @@
- char* authenticatorStr
- = createAuthenticatorString(authenticator, "DESCRIBE", url);
-
-+ char * acceptStr;
-+
-+ if (kasennaFlag)
-+ acceptStr = "Accept: application/sdp\r\n";
-+ else
-+ acceptStr = "Accept: application/x-rtsp-mh, application/sdp\r\n";
-+
-+
- // (Later implement more, as specified in the RTSP spec, sec D.1 #####)
- char* const cmdFmt =
- "DESCRIBE %s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
-- "Accept: application/sdp\r\n"
- "%s"
-- "%s"
-+ "%s"
-+ "%s"
- #ifdef SUPPORT_REAL_RTSP
- REAL_DESCRIBE_HEADERS
- #endif
-@@ -163,12 +171,14 @@
- unsigned cmdSize = strlen(cmdFmt)
- + strlen(url)
- + 20 /* max int len */
-+ + strlen(acceptStr)
- + strlen(authenticatorStr)
- + fUserAgentHeaderStrSize;
- cmd = new char[cmdSize];
- sprintf(cmd, cmdFmt,
- url,
- ++fCSeq,
-+ acceptStr,
- authenticatorStr,
- fUserAgentHeaderStr);
- delete[] authenticatorStr;
-@@ -214,6 +224,7 @@
- // "Content-location", "CSeq", etc. #####
- int contentLength = -1;
- char* lineStart;
-+ char serverType[20];
- while (1) {
- lineStart = nextLineStart;
- if (lineStart == NULL) break;
-@@ -221,6 +232,10 @@
- nextLineStart = getLine(lineStart);
- if (lineStart[0] == '\0') break; // this is a blank line
-
-+ if (sscanf(lineStart, "Server: %s", serverType) == 1)
-+ if (strncmp(serverType, "Kasenna", 7) == 0)
-+ kasennaServer = true;
-+
- if (sscanf(lineStart, "Content-Length: %d", &contentLength) == 1
- || sscanf(lineStart, "Content-length: %d", &contentLength) == 1) {
- if (contentLength < 0) {
-@@ -318,6 +333,94 @@
- bodyStart[to] = '\0'; // trims any extra data
- }
-
-+ if (kasennaServer && strncmp(bodyStart, "<MediaDescription>", 18) == 0)
-+ {
-+ // Translate from x-rtsp-mh to sdp
-+
-+ int videoPid, audioPid;
-+ unsigned mh_duration;
-+ char sdpBuf[2048], currentWord[20], ipAddressBuf[20];
-+
-+ char * currentPos = bodyStart;
-+
-+ while (strcmp(currentWord, "</MediaDescription>") != 0)
-+ {
-+ sscanf(currentPos, "%s", currentWord);
-+
-+ if (strcmp(currentWord, "VideoPid") == 0) {
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%s", currentWord);
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%d", &videoPid);
-+ currentPos += 3;
-+ }
-+
-+ if (strcmp(currentWord, "AudioPid") == 0) {
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%s", currentWord);
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%d", &audioPid);
-+ currentPos += 3;
-+ }
-+
-+ if (strcmp(currentWord, "Duration") == 0) {
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%s", currentWord);
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%d", &mh_duration);
-+ currentPos += 3;
-+ }
-+
-+
-+ if (strcmp(currentWord, "TypeSpecificData") == 0) {
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%s", currentWord);
-+ currentPos += strlen(currentWord) + 1;
-+ sscanf(currentPos, "%s", kasennaContentType);
-+ currentPos += 3;
-+ printf("Kasenna Content Type: %s\n", kasennaContentType);
-+ }
-+
-+ currentPos += strlen(currentWord) + 1;
-+ }
-+
-+ if (strcmp(kasennaContentType, "PARTNER_41_MPEG-4") == 0)
-+ {
-+ char * describeSDP = describeURL(url, authenticator, true);
-+
-+ delete[] cmd;
-+ return describeSDP;
-+ }
-+
-+ unsigned char byte1 = fServerAddress & 0x000000ff;
-+ unsigned char byte2 = (fServerAddress & 0x0000ff00) >> 8;
-+ unsigned char byte3 = (fServerAddress & 0x00ff0000) >> 16;
-+ unsigned char byte4 = (fServerAddress & 0xff000000) >> 24;
-+
-+ sprintf(ipAddressBuf, "%u%s%u%s%u%s%u%s%c",
-+ byte1, ".",
-+ byte2, ".",
-+ byte3, ".",
-+ byte4, " ",
-+ '\0');
-+
-+ sprintf(sdpBuf, "%s\r\n%s%s\r\n%s%s\r\n%s%s\r\n%s\r\n%s\r\n%s%u\r\n%s\r\n%s%d\r\n",
-+ "v=0",
-+ "o=NoSpacesAllowed 1 1 IN IP4 ", ipAddressBuf,
-+ "s=", url,
-+ "c=IN IP4 ", ipAddressBuf,
-+ "t=0 0",
-+ "a=control:*",
-+ "a=range:npt=0-",
-+ (unsigned)(mh_duration / 1000000),
-+ "m=video 1554 RAW/RAW/UDP 33",
-+ "a=control:trackID=", videoPid);
-+
-+ delete[] cmd;
-+ return strDup(sdpBuf);
-+ }
-+
-+
- delete[] cmd;
- return strDup(bodyStart);
- } while (0);
-@@ -569,6 +672,11 @@
- Boolean streamOutgoing,
- Boolean streamUsingTCP) {
- char* cmd = NULL;
-+
-+ char* setupStr = NULL;
-+ char* setupFmt = NULL;
-+ char* transportFmt = NULL;
-+
- do {
- // Construct the SETUP command:
-
-@@ -613,6 +721,32 @@
- rdtSource->setInputSocket(fSocketNum);
- }
- #endif
-+
-+ char const *prefix, *separator, *suffix;
-+ constructSubsessionURL(subsession, prefix, separator, suffix);
-+
-+ if (kasennaServer && (strncmp(kasennaContentType, "MPEG-2", 6) == 0) ||
-+ (strncmp(kasennaContentType, "MPEG-1", 6) == 0))
-+ {
-+ setupFmt = "SETUP %s%s RTSP/1.0\r\n";
-+ transportFmt = "Transport: RAW/RAW/UDP%s%s%s=%d-%d\r\n";
-+
-+ unsigned setupSize = strlen(setupFmt)
-+ + strlen(prefix) + strlen (separator);
-+
-+ setupStr = new char[setupSize];
-+ sprintf(setupStr, setupFmt, prefix, separator);
-+ } else {
-+ setupFmt = "SETUP %s%s%s RTSP/1.0\r\n";
-+ transportFmt = "Transport: RTP/AVP%s%s%s=%d-%d\r\n";
-+
-+ unsigned setupSize = strlen(setupFmt)
-+ + strlen(prefix) + strlen (separator) + strlen(suffix);
-+
-+ setupStr = new char[setupSize];
-+ sprintf(setupStr, setupFmt, prefix, separator, suffix);
-+ }
-+
- if (transportStr == NULL) {
- // Use a standard "Transport:" header.
- char const* transportTypeStr;
-@@ -637,7 +771,7 @@
- }
- rtcpNumber = rtpNumber + 1;
- }
-- char const* transportFmt = "Transport: RTP/AVP%s%s%s=%d-%d\r\n";
-+
- unsigned transportSize = strlen(transportFmt)
- + strlen(transportTypeStr) + strlen(modeStr) + strlen(portTypeStr) + 2*5 /* max port len */;
- transportStr = new char[transportSize];
-@@ -647,7 +781,7 @@
-
- // (Later implement more, as specified in the RTSP spec, sec D.1 #####)
- char* const cmdFmt =
-- "SETUP %s%s%s RTSP/1.0\r\n"
-+ "%s"
- "CSeq: %d\r\n"
- "%s"
- "%s"
-@@ -655,11 +789,8 @@
- "%s"
- "\r\n";
-
-- char const *prefix, *separator, *suffix;
-- constructSubsessionURL(subsession, prefix, separator, suffix);
--
- unsigned cmdSize = strlen(cmdFmt)
-- + strlen(prefix) + strlen(separator) + strlen(suffix)
-+ + strlen(setupStr)
- + 20 /* max int len */
- + strlen(transportStr)
- + strlen(sessionStr)
-@@ -667,7 +798,7 @@
- + fUserAgentHeaderStrSize;
- cmd = new char[cmdSize];
- sprintf(cmd, cmdFmt,
-- prefix, separator, suffix,
-+ setupStr,
- ++fCSeq,
- transportStr,
- sessionStr,
-@@ -896,7 +1027,7 @@
-
- char const *prefix, *separator, *suffix;
- constructSubsessionURL(subsession, prefix, separator, suffix);
-- if (hackForDSS) {
-+ if (hackForDSS || kasennaServer) {
- // When "PLAY" is used to inject RTP packets into a DSS
- // (violating the RTSP spec, btw; "RECORD" should have been used)
- // the DSS can crash (or hang) if the '/trackid=...' portion of
-@@ -1068,6 +1199,10 @@
-
- char const *prefix, *separator, *suffix;
- constructSubsessionURL(subsession, prefix, separator, suffix);
-+
-+ if (kasennaServer)
-+ separator = suffix = "";
-+
- unsigned cmdSize = strlen(cmdFmt)
- + strlen(prefix) + strlen(separator) + strlen(suffix)
- + 20 /* max int len */