/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A data structure that represents a session that consists of
// potentially multiple (audio and/or video) sub-sessions
// Implementation

#include "liveMedia.hh"
#include "Locale.hh"
#include "Base64.hh"
#include "GroupsockHelper.hh"
#include <ctype.h>

////////// MediaSession //////////

MediaSession* MediaSession::createNew(UsageEnvironment& env,
				      char const* sdpDescription) {
  MediaSession* newSession = new MediaSession(env);
  if (newSession != NULL) {
    if (!newSession->initializeWithSDP(sdpDescription)) {
      delete newSession;
      return NULL;
    }
  }

  return newSession;
}

Boolean MediaSession::lookupByName(UsageEnvironment& env,
				   char const* instanceName,
				   MediaSession*& resultSession) {
  resultSession = NULL; // unless we succeed

  Medium* medium;
  if (!Medium::lookupByName(env, instanceName, medium)) return False;

  if (!medium->isMediaSession()) {
    env.setResultMsg(instanceName, " is not a 'MediaSession' object");
    return False;
  }

  resultSession = (MediaSession*)medium;
  return True;
}

MediaSession::MediaSession(UsageEnvironment& env)
  : Medium(env),
    fSubsessionsHead(NULL), fSubsessionsTail(NULL),
    fConnectionEndpointName(NULL),
    fMaxPlayStartTime(0.0f), fMaxPlayEndTime(0.0f), fAbsStartTime(NULL), fAbsEndTime(NULL),
    fScale(1.0f), fSpeed(1.0f),
    fMediaSessionType(NULL), fSessionName(NULL), fSessionDescription(NULL), fControlPath(NULL),
    fMIKEYState(NULL), fCrypto(NULL) {
  fSourceFilterAddr.s_addr = 0;

  // Get our host name, and use this for the RTCP CNAME:
  const unsigned maxCNAMElen = 100;
  char CNAME[maxCNAMElen+1];
#ifndef CRIS
  gethostname((char*)CNAME, maxCNAMElen);
#else
  // "gethostname()" isn't defined for this platform
  sprintf(CNAME, "unknown host %d", (unsigned)(our_random()*0x7FFFFFFF));
#endif
  CNAME[maxCNAMElen] = '\0'; // just in case
  fCNAME = strDup(CNAME);
}

MediaSession::~MediaSession() {
  delete fSubsessionsHead;
  delete[] fCNAME;
  delete[] fConnectionEndpointName;
  delete[] fAbsStartTime; delete[] fAbsEndTime;
  delete[] fMediaSessionType;
  delete[] fSessionName;
  delete[] fSessionDescription;
  delete[] fControlPath;
  delete fCrypto; delete fMIKEYState;
}

Boolean MediaSession::isMediaSession() const {
  return True;
}

MediaSubsession* MediaSession::createNewMediaSubsession() {
  // default implementation:
  return new MediaSubsession(*this);
}

Boolean MediaSession::initializeWithSDP(char const* sdpDescription) {
  if (sdpDescription == NULL) return False;

  // Begin by processing all SDP lines until we see the first "m="
  char const* sdpLine = sdpDescription;
  char const* nextSDPLine;
  while (1) {
    if (!parseSDPLine(sdpLine, nextSDPLine)) return False;
    //##### We should really check for the correct SDP version (v=0)
    if (sdpLine[0] == 'm') break;
    sdpLine = nextSDPLine;
    if (sdpLine == NULL) break; // there are no m= lines at all

    // Check for various special SDP lines that we understand:
    if (parseSDPLine_s(sdpLine)) continue;
    if (parseSDPLine_i(sdpLine)) continue;
    if (parseSDPLine_c(sdpLine)) continue;
    if (parseSDPAttribute_control(sdpLine)) continue;
    if (parseSDPAttribute_range(sdpLine)) continue;
    if (parseSDPAttribute_type(sdpLine)) continue;
    if (parseSDPAttribute_source_filter(sdpLine)) continue;
    if (parseSDPAttribute_key_mgmt(sdpLine)) continue;
  }

  while (sdpLine != NULL) {
    // We have a "m=" line, representing a new sub-session:
    MediaSubsession* subsession = createNewMediaSubsession();
    if (subsession == NULL) {
      envir().setResultMsg("Unable to create new MediaSubsession");
      return False;
    }

    // Parse the line as "m=<medium_name> <client_portNum> <proto> <fmt>"
    // or "m=<medium_name> <client_portNum>/<num_ports> <proto> <fmt>"
    // (Should we be checking for >1 payload format number here?)#####
    char* mediumName = strDupSize(sdpLine); // ensures we have enough space
    char const* protocolName = NULL;
    unsigned payloadFormat;
    if ((sscanf(sdpLine, "m=%s %hu RTP/AVP %u",
		mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
	 sscanf(sdpLine, "m=%s %hu/%*u RTP/AVP %u",
		mediumName, &subsession->fClientPortNum, &payloadFormat) == 3)
	&& payloadFormat <= 127) {
      protocolName = "RTP";
    } else if ((sscanf(sdpLine, "m=%s %hu RTP/SAVP %u",
		       mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
		sscanf(sdpLine, "m=%s %hu/%*u RTP/SAVP %u",
		       mediumName, &subsession->fClientPortNum, &payloadFormat) == 3)
	       && payloadFormat <= 127) {
      protocolName = "SRTP";
    } else if ((sscanf(sdpLine, "m=%s %hu UDP %u",
		       mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
		sscanf(sdpLine, "m=%s %hu udp %u",
		       mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
		sscanf(sdpLine, "m=%s %hu RAW/RAW/UDP %u",
		       mediumName, &subsession->fClientPortNum, &payloadFormat) == 3)
	       && payloadFormat <= 127) {
      // This is a RAW UDP source
      protocolName = "UDP";
    } else {
      // This "m=" line is bad; output an error message saying so:
      char* sdpLineStr;
      if (nextSDPLine == NULL) {
	sdpLineStr = (char*)sdpLine;
      } else {
	sdpLineStr = strDup(sdpLine);
	sdpLineStr[nextSDPLine-sdpLine] = '\0';
      }
      envir() << "Bad SDP \"m=\" line: " <<  sdpLineStr << "\n";
      if (sdpLineStr != (char*)sdpLine) delete[] sdpLineStr;

      delete[] mediumName;
      delete subsession;

      // Skip the following SDP lines, up until the next "m=":
      while (1) {
	sdpLine = nextSDPLine;
	if (sdpLine == NULL) break; // we've reached the end
	if (!parseSDPLine(sdpLine, nextSDPLine)) return False;

	if (sdpLine[0] == 'm') break; // we've reached the next subsession
      }
      continue;
    }

    // Insert this subsession at the end of the list:
    if (fSubsessionsTail == NULL) {
      fSubsessionsHead = fSubsessionsTail = subsession;
    } else {
      fSubsessionsTail->setNext(subsession);
      fSubsessionsTail = subsession;
    }

    subsession->serverPortNum = subsession->fClientPortNum; // by default

    char const* mStart = sdpLine;
    subsession->fSavedSDPLines = strDup(mStart);

    subsession->fMediumName = strDup(mediumName);
    delete[] mediumName;
    subsession->fProtocolName = strDup(protocolName);
    subsession->fRTPPayloadFormat = payloadFormat;

    // Process the following SDP lines, up until the next "m=":
    while (1) {
      sdpLine = nextSDPLine;
      if (sdpLine == NULL) break; // we've reached the end
      if (!parseSDPLine(sdpLine, nextSDPLine)) return False;

      if (sdpLine[0] == 'm') break; // we've reached the next subsession

      // Check for various special SDP lines that we understand:
      if (subsession->parseSDPLine_c(sdpLine)) continue;
      if (subsession->parseSDPLine_b(sdpLine)) continue;
      if (subsession->parseSDPAttribute_rtpmap(sdpLine)) continue;
      if (subsession->parseSDPAttribute_rtcpmux(sdpLine)) continue;
      if (subsession->parseSDPAttribute_control(sdpLine)) continue;
      if (subsession->parseSDPAttribute_range(sdpLine)) continue;
      if (subsession->parseSDPAttribute_fmtp(sdpLine)) continue;
      if (subsession->parseSDPAttribute_source_filter(sdpLine)) continue;
      if (subsession->parseSDPAttribute_x_dimensions(sdpLine)) continue;
      if (subsession->parseSDPAttribute_framerate(sdpLine)) continue;
      if (subsession->parseSDPAttribute_key_mgmt(sdpLine)) continue;

      // (Later, check for malformed lines, and other valid SDP lines#####)
    }
    if (sdpLine != NULL) subsession->fSavedSDPLines[sdpLine-mStart] = '\0';

    // If we don't yet know the codec name, try looking it up from the
    // list of static payload types:
    if (subsession->fCodecName == NULL) {
      subsession->fCodecName
	= lookupPayloadFormat(subsession->fRTPPayloadFormat,
			      subsession->fRTPTimestampFrequency,
			      subsession->fNumChannels);
      if (subsession->fCodecName == NULL) {
	char typeStr[20];
	sprintf(typeStr, "%d", subsession->fRTPPayloadFormat);
	envir().setResultMsg("Unknown codec name for RTP payload type ",
			     typeStr);
	return False;
      }
    }

    // If we don't yet know this subsession's RTP timestamp frequency
    // (because it uses a dynamic payload type and the corresponding
    // SDP "rtpmap" attribute erroneously didn't specify it),
    // then guess it now:
    if (subsession->fRTPTimestampFrequency == 0) {
      subsession->fRTPTimestampFrequency
	= guessRTPTimestampFrequency(subsession->fMediumName,
				     subsession->fCodecName);
    }
  }

  return True;
}

Boolean MediaSession::parseSDPLine(char const* inputLine,
				   char const*& nextLine){
  // Begin by finding the start of the next line (if any):
  nextLine = NULL;
  for (char const* ptr = inputLine; *ptr != '\0'; ++ptr) {
    if (*ptr == '\r' || *ptr == '\n') {
      // We found the end of the line
      ++ptr;
      while (*ptr == '\r' || *ptr == '\n') ++ptr;
      nextLine = ptr;
      if (nextLine[0] == '\0') nextLine = NULL; // special case for end
      break;
    }
  }

  // Then, check that this line is a SDP line of the form <char>=<etc>
  // (However, we also accept blank lines in the input.)
  if (inputLine[0] == '\r' || inputLine[0] == '\n') return True;
  if (strlen(inputLine) < 2 || inputLine[1] != '='
      || inputLine[0] < 'a' || inputLine[0] > 'z') {
    envir().setResultMsg("Invalid SDP line: ", inputLine);
    return False;
  }

  return True;
}

// Common code used to parse many string values within SDP lines:
static Boolean parseStringValue(char const* sdpLine, char const* searchFormat, char*& result) {
  Boolean parseSuccess = False;
  char* buffer = strDupSize(sdpLine);

  if (sscanf(sdpLine, searchFormat, buffer) == 1) {
    delete[] result; result = strDup(buffer);
    parseSuccess = True;
  }
  delete[] buffer;

  return parseSuccess;
}

static Boolean parseTwoStringValues(char const* sdpLine, char const* searchFormat,
				    char*& result1, char*& result2) {
  Boolean parseSuccess = False;
  size_t sdpLineSize = strlen(sdpLine) + 1;
  char* buffer1 = new char[sdpLineSize];
  char* buffer2 = new char[sdpLineSize];

  if (sscanf(sdpLine, searchFormat, buffer1, buffer2) == 2) {
    delete[] result1; result1 = strDup(buffer1);
    delete[] result2; result2 = strDup(buffer2);
    parseSuccess = True;
  }
  delete[] buffer1;
  delete[] buffer2;

  return parseSuccess;
}

static MIKEYState* parseSDPAttribute_key_mgmtToMIKEY(char const* sdpLine) {
  char* keyMgmtPrtclId = NULL;
  char* keyMgmtData = NULL;
  MIKEYState* resultMIKEYState = NULL;

  do {
    // Check for a "a=key-mgmt:<prtcl-id> <keymgmt-data>" line:
    if (!parseTwoStringValues(sdpLine, "a=key-mgmt:%s %s", keyMgmtPrtclId, keyMgmtData)) break;

    // We understand only the 'protocol id' "mikey":
    if (strcmp(keyMgmtPrtclId, "mikey") != 0) break;

    // Base64-decode the "keyMgmtData" string:
    unsigned keyMgmtData_decodedSize;
    u_int8_t* keyMgmtData_decoded = base64Decode(keyMgmtData, keyMgmtData_decodedSize);
    if (keyMgmtData_decoded == NULL) break;

    resultMIKEYState = MIKEYState::createNew(keyMgmtData_decoded, keyMgmtData_decodedSize);
  } while (0);

  delete[] keyMgmtPrtclId;
  delete[] keyMgmtData;
  return resultMIKEYState;
}

Boolean MediaSession::parseSDPLine_s(char const* sdpLine) {
  // Check for "s=<session name>" line
  return parseStringValue(sdpLine, "s=%[^\r\n]", fSessionName);
}

Boolean MediaSession::parseSDPLine_i(char const* sdpLine) {
  // Check for "i=<session description>" line
  return parseStringValue(sdpLine, "i=%[^\r\n]", fSessionDescription);
}

Boolean MediaSession::parseSDPLine_c(char const* sdpLine) {
  // Check for "c=IN IP4 <connection-endpoint>"
  // or "c=IN IP4 <connection-endpoint>/<ttl+numAddresses>"
  // (Later, do something with <ttl+numAddresses> also #####)
  return parseStringValue(sdpLine, "c=IN IP4 %[^/\r\n]", fConnectionEndpointName);
}

Boolean MediaSession::parseSDPAttribute_type(char const* sdpLine) {
  // Check for a "a=type:broadcast|meeting|moderated|test|H.332|recvonly" line:
  return parseStringValue(sdpLine, "a=type: %[^ ]", fMediaSessionType);
}

Boolean MediaSession::parseSDPAttribute_control(char const* sdpLine) {
  // Check for a "a=control:<control-path>" line:
  return parseStringValue(sdpLine, "a=control: %s", fControlPath);
}

static Boolean parseRangeAttribute(char const* sdpLine, double& startTime, double& endTime) {
  return sscanf(sdpLine, "a=range: npt = %lg - %lg", &startTime, &endTime) == 2;
}

static Boolean parseRangeAttribute(char const* sdpLine, char*& absStartTime, char*& absEndTime) {
  size_t len = strlen(sdpLine) + 1;
  char* as = new char[len];
  char* ae = new char[len];
  int sscanfResult = sscanf(sdpLine, "a=range: clock = %[^-\r\n]-%[^\r\n]", as, ae);
  if (sscanfResult == 2) {
    absStartTime = as;
    absEndTime = ae;
  } else if (sscanfResult == 1) {
    absStartTime = as;
    delete[] ae;
  } else {
    delete[] as; delete[] ae;
    return False;
  }

  return True;
}

Boolean MediaSession::parseSDPAttribute_range(char const* sdpLine) {
  // Check for a "a=range:npt=<startTime>-<endTime>" line:
  // (Later handle other kinds of "a=range" attributes also???#####)
  Boolean parseSuccess = False;

  double playStartTime;
  double playEndTime;
  if (parseRangeAttribute(sdpLine, playStartTime, playEndTime)) {
    parseSuccess = True;
    if (playStartTime > fMaxPlayStartTime) {
      fMaxPlayStartTime = playStartTime;
    }
    if (playEndTime > fMaxPlayEndTime) {
      fMaxPlayEndTime = playEndTime;
    }
  } else if (parseRangeAttribute(sdpLine, _absStartTime(), _absEndTime())) {
    parseSuccess = True;
  }

  return parseSuccess;
}

static Boolean parseSourceFilterAttribute(char const* sdpLine,
					  struct in_addr& sourceAddr) {
  // Check for a "a=source-filter:incl IN IP4 <something> <source>" line.
  // Note: At present, we don't check that <something> really matches
  // one of our multicast addresses.  We also don't support more than
  // one <source> #####
  Boolean result = False; // until we succeed
  char* sourceName = NULL;
  do {
    if (!parseStringValue(sdpLine, "a=source-filter: incl IN IP4 %*s %s", sourceName)) break;

    // Now, convert this name to an address, if we can:
    NetAddressList addresses(sourceName);
    if (addresses.numAddresses() == 0) break;

    netAddressBits sourceAddrBits
      = *(netAddressBits*)(addresses.firstAddress()->data());
    if (sourceAddrBits == 0) break;

    sourceAddr.s_addr = sourceAddrBits;
    result = True;
  } while (0);

  delete[] sourceName;
  return result;
}

Boolean MediaSession
::parseSDPAttribute_source_filter(char const* sdpLine) {
  return parseSourceFilterAttribute(sdpLine, fSourceFilterAddr);
}

Boolean MediaSession::parseSDPAttribute_key_mgmt(char const* sdpLine) {
  MIKEYState* newMIKEYState = parseSDPAttribute_key_mgmtToMIKEY(sdpLine);
  if (newMIKEYState == NULL) return False;

  delete fCrypto; delete fMIKEYState;
  fMIKEYState = newMIKEYState;
  fCrypto = new SRTPCryptographicContext(*fMIKEYState);
  
  return True;
}

char* MediaSession::lookupPayloadFormat(unsigned char rtpPayloadType,
					unsigned& freq, unsigned& nCh) {
  // Look up the codec name and timestamp frequency for known (static)
  // RTP payload formats.
  char const* temp = NULL;
  switch (rtpPayloadType) {
  case 0: {temp = "PCMU"; freq = 8000; nCh = 1; break;}
  case 2: {temp = "G726-32"; freq = 8000; nCh = 1; break;}
  case 3: {temp = "GSM"; freq = 8000; nCh = 1; break;}
  case 4: {temp = "G723"; freq = 8000; nCh = 1; break;}
  case 5: {temp = "DVI4"; freq = 8000; nCh = 1; break;}
  case 6: {temp = "DVI4"; freq = 16000; nCh = 1; break;}
  case 7: {temp = "LPC"; freq = 8000; nCh = 1; break;}
  case 8: {temp = "PCMA"; freq = 8000; nCh = 1; break;}
  case 9: {temp = "G722"; freq = 8000; nCh = 1; break;}
  case 10: {temp = "L16"; freq = 44100; nCh = 2; break;}
  case 11: {temp = "L16"; freq = 44100; nCh = 1; break;}
  case 12: {temp = "QCELP"; freq = 8000; nCh = 1; break;}
  case 14: {temp = "MPA"; freq = 90000; nCh = 1; break;}
    // 'number of channels' is actually encoded in the media stream
  case 15: {temp = "G728"; freq = 8000; nCh = 1; break;}
  case 16: {temp = "DVI4"; freq = 11025; nCh = 1; break;}
  case 17: {temp = "DVI4"; freq = 22050; nCh = 1; break;}
  case 18: {temp = "G729"; freq = 8000; nCh = 1; break;}
  case 25: {temp = "CELB"; freq = 90000; nCh = 1; break;}
  case 26: {temp = "JPEG"; freq = 90000; nCh = 1; break;}
  case 28: {temp = "NV"; freq = 90000; nCh = 1; break;}
  case 31: {temp = "H261"; freq = 90000; nCh = 1; break;}
  case 32: {temp = "MPV"; freq = 90000; nCh = 1; break;}
  case 33: {temp = "MP2T"; freq = 90000; nCh = 1; break;}
  case 34: {temp = "H263"; freq = 90000; nCh = 1; break;}
  };

  return strDup(temp);
}

unsigned MediaSession::guessRTPTimestampFrequency(char const* mediumName,
						  char const* codecName) {
  // By default, we assume that audio sessions use a frequency of 8000,
  // video sessions use a frequency of 90000,
  // and text sessions use a frequency of 1000.
  // Begin by checking for known exceptions to this rule
  // (where the frequency is known unambiguously (e.g., not like "DVI4"))
  if (strcmp(codecName, "L16") == 0) return 44100;
  if (strcmp(codecName, "MPA") == 0
      || strcmp(codecName, "MPA-ROBUST") == 0
      || strcmp(codecName, "X-MP3-DRAFT-00") == 0) return 90000;

  // Now, guess default values:
  if (strcmp(mediumName, "video") == 0) return 90000;
  else if (strcmp(mediumName, "text") == 0) return 1000;
  return 8000; // for "audio", and any other medium
}

char* MediaSession::absStartTime() const {
  if (fAbsStartTime != NULL) return fAbsStartTime;

  // If a subsession has an 'absolute' start time, then use that:
  MediaSubsessionIterator iter(*this);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    if (subsession->_absStartTime() != NULL) return subsession->_absStartTime();
  }
  return NULL;
}

char* MediaSession::absEndTime() const {
  if (fAbsEndTime != NULL) return fAbsEndTime;

  // If a subsession has an 'absolute' end time, then use that:
  MediaSubsessionIterator iter(*this);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    if (subsession->_absEndTime() != NULL) return subsession->_absEndTime();
  }
  return NULL;
}

Boolean MediaSession
::initiateByMediaType(char const* mimeType,
		      MediaSubsession*& resultSubsession,
		      int useSpecialRTPoffset) {
  // Look through this session's subsessions for media that match "mimeType"
  resultSubsession = NULL;
  MediaSubsessionIterator iter(*this);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    Boolean wasAlreadyInitiated = subsession->readSource() != NULL;
    if (!wasAlreadyInitiated) {
      // Try to create a source for this subsession:
      if (!subsession->initiate(useSpecialRTPoffset)) return False;
    }

    // Make sure the source's MIME type is one that we handle:
    if (strcmp(subsession->readSource()->MIMEtype(), mimeType) != 0) {
      if (!wasAlreadyInitiated) subsession->deInitiate();
      continue;
    }

    resultSubsession = subsession;
    break; // use this
  }

  if (resultSubsession == NULL) {
    envir().setResultMsg("Session has no usable media subsession");
    return False;
  }

  return True;
}


////////// MediaSubsessionIterator //////////

MediaSubsessionIterator::MediaSubsessionIterator(MediaSession const& session)
  : fOurSession(session) {
  reset();
}

MediaSubsessionIterator::~MediaSubsessionIterator() {
}

MediaSubsession* MediaSubsessionIterator::next() {
  MediaSubsession* result = fNextPtr;

  if (fNextPtr != NULL) fNextPtr = fNextPtr->fNext;

  return result;
}

void MediaSubsessionIterator::reset() {
  fNextPtr = fOurSession.fSubsessionsHead;
}


////////// SDPAttribute definition //////////

class SDPAttribute {
public:
  SDPAttribute(char const* strValue, Boolean valueIsHexadecimal);
  virtual ~SDPAttribute();

  char const* strValue() const { return fStrValue; }
  char const* strValueToLower() const { return fStrValueToLower; }
  int intValue() const { return fIntValue; }
  Boolean valueIsHexadecimal() const { return fValueIsHexadecimal; }

private:
  char* fStrValue;
  char* fStrValueToLower;
  int fIntValue;
  Boolean fValueIsHexadecimal;
};


////////// MediaSubsession //////////

MediaSubsession::MediaSubsession(MediaSession& parent)
  : serverPortNum(0), sink(NULL), miscPtr(NULL),
    fParent(parent), fNext(NULL),
    fConnectionEndpointName(NULL),
    fClientPortNum(0), fRTPPayloadFormat(0xFF),
    fSavedSDPLines(NULL), fMediumName(NULL), fCodecName(NULL), fProtocolName(NULL),
    fRTPTimestampFrequency(0), fMultiplexRTCPWithRTP(False), fControlPath(NULL),
    fMIKEYState(NULL), fCrypto(NULL),
    fSourceFilterAddr(parent.sourceFilterAddr()), fBandwidth(0),
    fPlayStartTime(0.0), fPlayEndTime(0.0), fAbsStartTime(NULL), fAbsEndTime(NULL),
    fVideoWidth(0), fVideoHeight(0), fVideoFPS(0), fNumChannels(1), fScale(1.0f), fNPT_PTS_Offset(0.0f),
    fAttributeTable(HashTable::create(STRING_HASH_KEYS)),
    fRTPSocket(NULL), fRTCPSocket(NULL),
    fRTPSource(NULL), fRTCPInstance(NULL), fReadSource(NULL),
    fReceiveRawMP3ADUs(False), fReceiveRawJPEGFrames(False),
    fSessionId(NULL) {
  rtpInfo.seqNum = 0; rtpInfo.timestamp = 0; rtpInfo.infoIsNew = False;

  // A few attributes have unusual default values.  Set these now:
  setAttribute("profile-level-id", "0", True/*value is hexadecimal*/); // used with "video/H264"
    // This won't work for MPEG-4 (unless the value is <10), because for MPEG-4, the value
    // is assumed to be a decimal string, not a hexadecimal string.  NEED TO FIX #####
  setAttribute("profile-id", "1"); // used with "video/H265"
  setAttribute("level-id", "93"); // used with "video/H265"
  setAttribute("interop-constraints", "B00000000000"); // used with "video/H265"
  setAttribute("sampling", "RGB"); // used with "video/JPEG2000"
}

MediaSubsession::~MediaSubsession() {
  deInitiate();

  delete[] fConnectionEndpointName; delete[] fSavedSDPLines;
  delete[] fMediumName; delete[] fCodecName; delete[] fProtocolName;
  delete[] fControlPath;
  delete fCrypto; delete fMIKEYState;
  delete[] fAbsStartTime; delete[] fAbsEndTime;
  delete[] fSessionId;

  // Empty and delete our 'attributes table':
  SDPAttribute* attr;
  while ((attr = (SDPAttribute*)fAttributeTable->RemoveNext()) != NULL) {
    delete attr;
  }
  delete fAttributeTable;

  delete fNext;
}

void MediaSubsession::addFilter(FramedFilter* filter){
  fReadSource = filter;
}

double MediaSubsession::playStartTime() const {
  if (fPlayStartTime > 0) return fPlayStartTime;

  return fParent.playStartTime();
}

double MediaSubsession::playEndTime() const {
  if (fPlayEndTime > 0) return fPlayEndTime;

  return fParent.playEndTime();
}

char* MediaSubsession::absStartTime() const {
  if (fAbsStartTime != NULL) return fAbsStartTime;

  return fParent.absStartTime();
}

char* MediaSubsession::absEndTime() const {
  if (fAbsEndTime != NULL) return fAbsEndTime;

  return fParent.absEndTime();
}

static Boolean const honorSDPPortChoice
#ifdef IGNORE_UNICAST_SDP_PORTS
= False;
#else
= True;
#endif

Boolean MediaSubsession::initiate(int useSpecialRTPoffset) {
  if (fReadSource != NULL) return True; // has already been initiated

  do {
    if (fCodecName == NULL) {
      env().setResultMsg("Codec is unspecified");
      break;
    }

    // Create RTP and RTCP 'Groupsocks' on which to receive incoming data.
    // (Groupsocks will work even for unicast addresses)
    struct in_addr tempAddr;
    tempAddr.s_addr = connectionEndpointAddress();
        // This could get changed later, as a result of a RTSP "SETUP"

    Boolean const useSRTP = strcmp(fProtocolName, "SRTP") == 0;
    Boolean const protocolIsRTP = useSRTP || strcmp(fProtocolName, "RTP") == 0;

    if (fClientPortNum != 0 && (honorSDPPortChoice || IsMulticastAddress(tempAddr.s_addr))) {
      // The sockets' port numbers were specified for us.  Use these:
      if (protocolIsRTP && !fMultiplexRTCPWithRTP) {
	fClientPortNum = fClientPortNum&~1;
	    // use an even-numbered port for RTP, and the next (odd-numbered) port for RTCP
      }
      if (isSSM()) {
	fRTPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, fClientPortNum);
      } else {
	fRTPSocket = new Groupsock(env(), tempAddr, fClientPortNum, 255);
      }
      if (fRTPSocket == NULL) {
	env().setResultMsg("Failed to create RTP socket");
	break;
      }
      
      if (protocolIsRTP) {
	if (fMultiplexRTCPWithRTP) {
	  // Use the RTP 'groupsock' object for RTCP as well:
	  fRTCPSocket = fRTPSocket;
	} else {
	  // Set our RTCP port to be the RTP port + 1:
	  portNumBits const rtcpPortNum = fClientPortNum|1;
	  if (isSSM()) {
	    fRTCPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, rtcpPortNum);
	  } else {
	    fRTCPSocket = new Groupsock(env(), tempAddr, rtcpPortNum, 255);
	  }
	}
      }
    } else {
      // Port numbers were not specified in advance, so we use ephemeral port numbers.
      // Create sockets until we get a port-number pair (even: RTP; even+1: RTCP).
      // (However, if we're multiplexing RTCP with RTP, then we create only one socket,
      // and the port number can be even or odd.)
      // We need to make sure that we don't keep trying to use the same bad port numbers over
      // and over again, so we store bad sockets in a table, and delete them all when we're done.
      HashTable* socketHashTable = HashTable::create(ONE_WORD_HASH_KEYS);
      if (socketHashTable == NULL) break;
      Boolean success = False;
      NoReuse dummy(env());
          // ensures that our new ephemeral port number won't be one that's already in use

      while (1) {
	// Create a new socket:
	if (isSSM()) {
	  fRTPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, 0);
	} else {
	  fRTPSocket = new Groupsock(env(), tempAddr, 0, 255);
	}
	if (fRTPSocket == NULL) {
	  env().setResultMsg("MediaSession::initiate(): unable to create RTP and RTCP sockets");
	  break;
	}

	// Get the client port number:
	Port clientPort(0);
	if (!getSourcePort(env(), fRTPSocket->socketNum(), clientPort)) {
	  break;
	}
	fClientPortNum = ntohs(clientPort.num()); 

	if (fMultiplexRTCPWithRTP) {
	  // Use this RTP 'groupsock' object for RTCP as well:
	  fRTCPSocket = fRTPSocket;
	  success = True;
	  break;
	}	  

	// To be usable for RTP, the client port number must be even:
	if ((fClientPortNum&1) != 0) { // it's odd
	  // Record this socket in our table, and keep trying:
	  unsigned key = (unsigned)fClientPortNum;
	  Groupsock* existing = (Groupsock*)socketHashTable->Add((char const*)key, fRTPSocket);
	  delete existing; // in case it wasn't NULL
	  continue;
	}

	// Make sure we can use the next (i.e., odd) port number, for RTCP:
	portNumBits rtcpPortNum = fClientPortNum|1;
	if (isSSM()) {
	  fRTCPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, rtcpPortNum);
	} else {
	  fRTCPSocket = new Groupsock(env(), tempAddr, rtcpPortNum, 255);
	}
	if (fRTCPSocket != NULL && fRTCPSocket->socketNum() >= 0) {
	  // Success! Use these two sockets.
	  success = True;
	  break;
	} else {
	  // We couldn't create the RTCP socket (perhaps that port number's already in use elsewhere?).
	  delete fRTCPSocket; fRTCPSocket = NULL;

	  // Record the first socket in our table, and keep trying:
	  unsigned key = (unsigned)fClientPortNum;
	  Groupsock* existing = (Groupsock*)socketHashTable->Add((char const*)key, fRTPSocket);
	  delete existing; // in case it wasn't NULL
	  continue;
	}
      }

      // Clean up the socket hash table (and contents):
      Groupsock* oldGS;
      while ((oldGS = (Groupsock*)socketHashTable->RemoveNext()) != NULL) {
	delete oldGS;
      }
      delete socketHashTable;

      if (!success) break; // a fatal error occurred trying to create the RTP and RTCP sockets; we can't continue
    }

    // Try to use a big receive buffer for RTP - at least 0.1 second of
    // specified bandwidth and at least 50 KB
    unsigned rtpBufSize = fBandwidth * 25 / 2; // 1 kbps * 0.1 s = 12.5 bytes
    if (rtpBufSize < 50 * 1024)
      rtpBufSize = 50 * 1024;
    increaseReceiveBufferTo(env(), fRTPSocket->socketNum(), rtpBufSize);

    if (isSSM() && fRTCPSocket != NULL) {
      // Special case for RTCP SSM: Send RTCP packets back to the source via unicast:
      fRTCPSocket->changeDestinationParameters(fSourceFilterAddr,0,~0);
    }

    // Create "fRTPSource" and "fReadSource":
    if (!createSourceObjects(useSpecialRTPoffset)) break;

    if (fReadSource == NULL) {
      env().setResultMsg("Failed to create read source");
      break;
    }
    
    SRTPCryptographicContext* ourCrypto = NULL;
    if (useSRTP) {
      // For SRTP, we need key management.  If MIKEY (key management) state wasn't given
      // to us in the SDP description, then create it now:
      ourCrypto = getCrypto();
      if (ourCrypto == NULL) { // then fMIKEYState is also NULL; create both
	fMIKEYState = new MIKEYState();
	ourCrypto = fCrypto = new SRTPCryptographicContext(*fMIKEYState);
      }

      if (fRTPSource != NULL) fRTPSource->setCrypto(ourCrypto);
    }

    // Finally, create our RTCP instance. (It starts running automatically)
    if (fRTPSource != NULL && fRTCPSocket != NULL) {
      // If bandwidth is specified, use it and add 5% for RTCP overhead.
      // Otherwise make a guess at 500 kbps.
      unsigned totSessionBandwidth
	= fBandwidth ? fBandwidth + fBandwidth / 20 : 500;
      fRTCPInstance = RTCPInstance::createNew(env(), fRTCPSocket,
					      totSessionBandwidth,
					      (unsigned char const*)
					      fParent.CNAME(),
					      NULL /* we're a client */,
					      fRTPSource,
					      False /* we're not a data transmitter */,
					      ourCrypto);
      if (fRTCPInstance == NULL) {
	env().setResultMsg("Failed to create RTCP instance");
	break;
      }
    }

    return True;
  } while (0);

  deInitiate();
  fClientPortNum = 0;
  return False;
}

void MediaSubsession::deInitiate() {
  Medium::close(fRTCPInstance); fRTCPInstance = NULL;

  Medium::close(fReadSource); // this is assumed to also close fRTPSource
  fReadSource = NULL; fRTPSource = NULL;

  delete fRTPSocket;
  if (fRTCPSocket != fRTPSocket) delete fRTCPSocket;
  fRTPSocket = NULL; fRTCPSocket = NULL;
}

Boolean MediaSubsession::setClientPortNum(unsigned short portNum) {
  if (fReadSource != NULL) {
    env().setResultMsg("A read source has already been created");
    return False;
  }

  fClientPortNum = portNum;
  return True;
}

char const* MediaSubsession::attrVal_str(char const* attrName) const {
  SDPAttribute* attr = (SDPAttribute*)(fAttributeTable->Lookup(attrName));
  if (attr == NULL) return "";

  return attr->strValue();
}

char const* MediaSubsession::attrVal_strToLower(char const* attrName) const {
  SDPAttribute* attr = (SDPAttribute*)(fAttributeTable->Lookup(attrName));
  if (attr == NULL) return "";

  return attr->strValueToLower();
}

unsigned MediaSubsession::attrVal_int(char const* attrName) const {
  SDPAttribute* attr = (SDPAttribute*)(fAttributeTable->Lookup(attrName));
  if (attr == NULL) return 0;

  return attr->intValue();
}

char const* MediaSubsession::fmtp_config() const {
  char const* result = attrVal_str("config");
  if (result[0] == '\0') result = attrVal_str("configuration");

  return result;
}

netAddressBits MediaSubsession::connectionEndpointAddress() const {
  do {
    // Get the endpoint name from with us, or our parent session:
    char const* endpointString = connectionEndpointName();
    if (endpointString == NULL) {
      endpointString = parentSession().connectionEndpointName();
    }
    if (endpointString == NULL) break;

    // Now, convert this name to an address, if we can:
    NetAddressList addresses(endpointString);
    if (addresses.numAddresses() == 0) break;

    return *(netAddressBits*)(addresses.firstAddress()->data());
  } while (0);

  // No address known:
  return 0;
}

void MediaSubsession::setDestinations(netAddressBits defaultDestAddress) {
  // Get the destination address from the connection endpoint name
  // (This will be 0 if it's not known, in which case we use the default)
  netAddressBits destAddress = connectionEndpointAddress();
  if (destAddress == 0) destAddress = defaultDestAddress;
  struct in_addr destAddr; destAddr.s_addr = destAddress;

  // The destination TTL remains unchanged:
  int destTTL = ~0; // means: don't change

  if (fRTPSocket != NULL) {
    Port destPort(serverPortNum);
    fRTPSocket->changeDestinationParameters(destAddr, destPort, destTTL);
  }
  if (fRTCPSocket != NULL && !isSSM() && !fMultiplexRTCPWithRTP) {
    // Note: For SSM sessions, the dest address for RTCP was already set.
    Port destPort(serverPortNum+1);
    fRTCPSocket->changeDestinationParameters(destAddr, destPort, destTTL);
  }
}

void MediaSubsession::setSessionId(char const* sessionId) {
  delete[] fSessionId;
  fSessionId = strDup(sessionId);
}

double MediaSubsession::getNormalPlayTime(struct timeval const& presentationTime) {
  if (rtpSource() == NULL || rtpSource()->timestampFrequency() == 0) return 0.0; // no RTP source, or bad freq!

  // First, check whether our "RTPSource" object has already been synchronized using RTCP.
  // If it hasn't, then - as a special case - we need to use the RTP timestamp to compute the NPT.
  if (!rtpSource()->hasBeenSynchronizedUsingRTCP()) {
    if (!rtpInfo.infoIsNew) return 0.0; // the "rtpInfo" structure has not been filled in
    u_int32_t timestampOffset = rtpSource()->curPacketRTPTimestamp() - rtpInfo.timestamp;
    double nptOffset = (timestampOffset/(double)(rtpSource()->timestampFrequency()))*scale();
    double npt = playStartTime() + nptOffset;

    return npt;
  } else {
    // Common case: We have been synchronized using RTCP.  This means that the "presentationTime" parameter
    // will be accurate, and so we should use this to compute the NPT.
    double ptsDouble = (double)(presentationTime.tv_sec + presentationTime.tv_usec/1000000.0);

    if (rtpInfo.infoIsNew) {
      // This is the first time we've been called with a synchronized presentation time since the "rtpInfo"
      // structure was last filled in.  Use this "presentationTime" to compute "fNPT_PTS_Offset":
      if (seqNumLT(rtpSource()->curPacketRTPSeqNum(), rtpInfo.seqNum)) return -0.1; // sanity check; ignore old packets
      u_int32_t timestampOffset = rtpSource()->curPacketRTPTimestamp() - rtpInfo.timestamp;
      double nptOffset = (timestampOffset/(double)(rtpSource()->timestampFrequency()))*scale();
      double npt = playStartTime() + nptOffset;
      fNPT_PTS_Offset = npt - ptsDouble*scale();
      rtpInfo.infoIsNew = False; // for next time

      return npt;
    } else {
      // Use the precomputed "fNPT_PTS_Offset" to compute the NPT from the PTS:
      if (fNPT_PTS_Offset == 0.0) return 0.0; // error: The "rtpInfo" structure was apparently never filled in
      return (double)(ptsDouble*scale() + fNPT_PTS_Offset);
    }
  }
}

void MediaSubsession
::setAttribute(char const* name, char const* value, Boolean valueIsHexadecimal) {
  // Replace any existing attribute record with this name (except that the 'valueIsHexadecimal'
  // property will be inherited from it, if it exists).
  SDPAttribute* oldAttr = (SDPAttribute*)fAttributeTable->Lookup(name);
  if (oldAttr != NULL) {
    valueIsHexadecimal = oldAttr->valueIsHexadecimal();
    fAttributeTable->Remove(name);
    delete oldAttr;
  }

  SDPAttribute* newAttr = new SDPAttribute(value, valueIsHexadecimal);
  (void)fAttributeTable->Add(name, newAttr);
}

Boolean MediaSubsession::parseSDPLine_c(char const* sdpLine) {
  // Check for "c=IN IP4 <connection-endpoint>"
  // or "c=IN IP4 <connection-endpoint>/<ttl+numAddresses>"
  // (Later, do something with <ttl+numAddresses> also #####)
  return parseStringValue(sdpLine, "c=IN IP4 %[^/\r\n]", fConnectionEndpointName);
}

Boolean MediaSubsession::parseSDPLine_b(char const* sdpLine) {
  // Check for "b=<bwtype>:<bandwidth>" line
  // RTP applications are expected to use bwtype="AS"
  return sscanf(sdpLine, "b=AS:%u", &fBandwidth) == 1;
}

Boolean MediaSubsession::parseSDPAttribute_rtpmap(char const* sdpLine) {
  // Check for a "a=rtpmap:<fmt> <codec>/<freq>" line:
  // (Also check without the "/<freq>"; RealNetworks omits this)
  // Also check for a trailing "/<numChannels>".
  Boolean parseSuccess = False;

  unsigned rtpmapPayloadFormat;
  char* codecName = strDupSize(sdpLine); // ensures we have enough space
  unsigned rtpTimestampFrequency = 0;
  unsigned numChannels = 1;
  if (sscanf(sdpLine, "a=rtpmap: %u %[^/]/%u/%u",
	     &rtpmapPayloadFormat, codecName, &rtpTimestampFrequency,
	     &numChannels) == 4
      || sscanf(sdpLine, "a=rtpmap: %u %[^/]/%u",
	     &rtpmapPayloadFormat, codecName, &rtpTimestampFrequency) == 3
      || sscanf(sdpLine, "a=rtpmap: %u %s",
		&rtpmapPayloadFormat, codecName) == 2) {
    parseSuccess = True;
    if (rtpmapPayloadFormat == fRTPPayloadFormat) {
      // This "rtpmap" matches our payload format, so set our
      // codec name and timestamp frequency:
      // (First, make sure the codec name is upper case)
      {
	Locale l("POSIX");
	for (char* p = codecName; *p != '\0'; ++p) *p = toupper(*p);
      }
      delete[] fCodecName; fCodecName = strDup(codecName);
      fRTPTimestampFrequency = rtpTimestampFrequency;
      fNumChannels = numChannels;
    }
  }
  delete[] codecName;

  return parseSuccess;
}

Boolean MediaSubsession::parseSDPAttribute_rtcpmux(char const* sdpLine) {
  if (strncmp(sdpLine, "a=rtcp-mux", 10) == 0) {
    fMultiplexRTCPWithRTP = True;
    return True;
  }

  return False;
}

Boolean MediaSubsession::parseSDPAttribute_control(char const* sdpLine) {
  // Check for a "a=control:<control-path>" line:
  return parseStringValue(sdpLine, "a=control: %s", fControlPath);
}

Boolean MediaSubsession::parseSDPAttribute_range(char const* sdpLine) {
  // Check for a "a=range:npt=<startTime>-<endTime>" line:
  // (Later handle other kinds of "a=range" attributes also???#####)
  Boolean parseSuccess = False;

  double playStartTime;
  double playEndTime;
  if (parseRangeAttribute(sdpLine, playStartTime, playEndTime)) {
    parseSuccess = True;
    if (playStartTime > fPlayStartTime) {
      fPlayStartTime = playStartTime;
      if (playStartTime > fParent.playStartTime()) {
	fParent.playStartTime() = playStartTime;
      }
    }
    if (playEndTime > fPlayEndTime) {
      fPlayEndTime = playEndTime;
      if (playEndTime > fParent.playEndTime()) {
	fParent.playEndTime() = playEndTime;
      }
    }
  } else if (parseRangeAttribute(sdpLine, _absStartTime(), _absEndTime())) {
    parseSuccess = True;
  }

  return parseSuccess;
}

Boolean MediaSubsession::parseSDPAttribute_fmtp(char const* sdpLine) {
  // Check for a "a=fmtp:" line:
  // Later: Check that payload format number matches; #####
  do {
    if (strncmp(sdpLine, "a=fmtp:", 7) != 0) break; sdpLine += 7;
    while (isdigit(*sdpLine)) ++sdpLine;

    // The remaining "sdpLine" should be a sequence of
    //     <name>=<value>;
    // or
    //     <name>;
    // parameter assignments.  Look at each of these.
    unsigned const sdpLineLen = strlen(sdpLine);
    char* nameStr = new char[sdpLineLen+1];
    char* valueStr = new char[sdpLineLen+1];

    while (*sdpLine != '\0' && *sdpLine != '\r' && *sdpLine != '\n') {
      int sscanfResult = sscanf(sdpLine, " %[^=; \t\r\n] = %[^; \t\r\n]", nameStr, valueStr);
      if (sscanfResult >= 1) {
	// <name> or <name>=<value>
	// Convert <name> to lower-case, to ease comparison:
	Locale l("POSIX");
	for (char* c = nameStr; *c != '\0'; ++c) *c = tolower(*c);
	
	if (sscanfResult == 1) {
	  // <name>
	  setAttribute(nameStr);
	} else {
	  // <name>=<value>
	  setAttribute(nameStr, valueStr);
	}
      }

      // Move to the next parameter assignment string:
      while (*sdpLine != '\0' && *sdpLine != '\r' && *sdpLine != '\n' && *sdpLine != ';') ++sdpLine;
      while (*sdpLine == ';') ++sdpLine;
    }
    delete[] nameStr; delete[] valueStr;
    return True;
  } while (0);

  return False;
}

Boolean MediaSubsession
::parseSDPAttribute_source_filter(char const* sdpLine) {
  return parseSourceFilterAttribute(sdpLine, fSourceFilterAddr);
}

Boolean MediaSubsession::parseSDPAttribute_x_dimensions(char const* sdpLine) {
  // Check for a "a=x-dimensions:<width>,<height>" line:
  Boolean parseSuccess = False;

  int width, height;
  if (sscanf(sdpLine, "a=x-dimensions:%d,%d", &width, &height) == 2) {
    parseSuccess = True;
    fVideoWidth = (unsigned short)width;
    fVideoHeight = (unsigned short)height;
  }

  return parseSuccess;
}

Boolean MediaSubsession::parseSDPAttribute_framerate(char const* sdpLine) {
  // Check for a "a=framerate: <fps>" or "a=x-framerate: <fps>" line:
  Boolean parseSuccess = False;

  float frate;
  int rate;
  if (sscanf(sdpLine, "a=framerate: %f", &frate) == 1 || sscanf(sdpLine, "a=framerate:%f", &frate) == 1) {
    parseSuccess = True;
    fVideoFPS = (unsigned)frate;
  } else if (sscanf(sdpLine, "a=x-framerate: %d", &rate) == 1) {
    parseSuccess = True;
    fVideoFPS = (unsigned)rate;
  }

  return parseSuccess;
}

Boolean MediaSubsession::parseSDPAttribute_key_mgmt(char const* sdpLine) {
  MIKEYState* newMIKEYState = parseSDPAttribute_key_mgmtToMIKEY(sdpLine);
  if (newMIKEYState == NULL) return False;

  delete fCrypto; delete fMIKEYState;
  fMIKEYState = newMIKEYState;
  fCrypto = new SRTPCryptographicContext(*fMIKEYState);
  
  return True;
}

Boolean MediaSubsession::createSourceObjects(int useSpecialRTPoffset) {
  do {
    // First, check "fProtocolName"
    if (strcmp(fProtocolName, "UDP") == 0) {
      // A UDP-packetized stream (*not* a RTP stream)
      fReadSource = BasicUDPSource::createNew(env(), fRTPSocket);
      fRTPSource = NULL; // Note!
      
      if (strcmp(fCodecName, "MP2T") == 0) { // MPEG-2 Transport Stream
	fReadSource = MPEG2TransportStreamFramer::createNew(env(), fReadSource);
	// this sets "durationInMicroseconds" correctly, based on the PCR values
      }
    } else {
      // Check "fCodecName" against the set of codecs that we support,
      // and create our RTP source accordingly
      // (Later make this code more efficient, as this set grows #####)
      // (Also, add more fmts that can be implemented by SimpleRTPSource#####)
      Boolean createSimpleRTPSource = False; // by default; can be changed below
      Boolean doNormalMBitRule = False; // default behavior if "createSimpleRTPSource" is True
      if (strcmp(fCodecName, "QCELP") == 0) { // QCELP audio
	fReadSource =
	  QCELPAudioRTPSource::createNew(env(), fRTPSocket, fRTPSource,
					 fRTPPayloadFormat,
					 fRTPTimestampFrequency);
	// Note that fReadSource will differ from fRTPSource in this case
      } else if (strcmp(fCodecName, "AMR") == 0) { // AMR audio (narrowband)
	fReadSource =
	  AMRAudioRTPSource::createNew(env(), fRTPSocket, fRTPSource,
				       fRTPPayloadFormat, False /*isWideband*/,
				       fNumChannels, attrVal_bool("octet-align"),
				       attrVal_unsigned("interleaving"),
				       attrVal_bool("robust-sorting"),
				       attrVal_bool("crc"));
	// Note that fReadSource will differ from fRTPSource in this case
      } else if (strcmp(fCodecName, "AMR-WB") == 0) { // AMR audio (wideband)
	fReadSource =
	  AMRAudioRTPSource::createNew(env(), fRTPSocket, fRTPSource,
				       fRTPPayloadFormat, True /*isWideband*/,
				       fNumChannels, attrVal_bool("octet-align"),
				       attrVal_unsigned("interleaving"),
				       attrVal_bool("robust-sorting"),
				       attrVal_bool("crc"));
	// Note that fReadSource will differ from fRTPSource in this case
      } else if (strcmp(fCodecName, "MPA") == 0) { // MPEG-1 or 2 audio
	fReadSource = fRTPSource
	  = MPEG1or2AudioRTPSource::createNew(env(), fRTPSocket,
					      fRTPPayloadFormat,
					      fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "MPA-ROBUST") == 0) { // robust MP3 audio
	fReadSource = fRTPSource
	  = MP3ADURTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
				       fRTPTimestampFrequency);
	if (fRTPSource == NULL) break;
	
	if (!fReceiveRawMP3ADUs) {
	  // Add a filter that deinterleaves the ADUs after depacketizing them:
	  MP3ADUdeinterleaver* deinterleaver
	    = MP3ADUdeinterleaver::createNew(env(), fRTPSource);
	  if (deinterleaver == NULL) break;
	
	  // Add another filter that converts these ADUs to MP3 frames:
	  fReadSource = MP3FromADUSource::createNew(env(), deinterleaver);
	}
      } else if (strcmp(fCodecName, "X-MP3-DRAFT-00") == 0) {
	// a non-standard variant of "MPA-ROBUST" used by RealNetworks
	// (one 'ADU'ized MP3 frame per packet; no headers)
	fRTPSource
	  = SimpleRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
				       fRTPTimestampFrequency,
				       "audio/MPA-ROBUST" /*hack*/);
	if (fRTPSource == NULL) break;
	
	// Add a filter that converts these ADUs to MP3 frames:
	fReadSource = MP3FromADUSource::createNew(env(), fRTPSource,
						  False /*no ADU header*/);
       } else if (strcmp(fCodecName, "MP4A-LATM") == 0) { // MPEG-4 LATM audio
	fReadSource = fRTPSource
	  = MPEG4LATMAudioRTPSource::createNew(env(), fRTPSocket,
					       fRTPPayloadFormat,
					       fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "VORBIS") == 0) { // Vorbis audio
	fReadSource = fRTPSource
	  = VorbisAudioRTPSource::createNew(env(), fRTPSocket,
					    fRTPPayloadFormat,
					    fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "THEORA") == 0) { // Theora video
	fReadSource = fRTPSource
	  = TheoraVideoRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat);
      } else if (strcmp(fCodecName, "RAW") == 0) { // Uncompressed raw video (RFC 4175)
	fReadSource = fRTPSource
	  = RawVideoRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat, fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "VP8") == 0) { // VP8 video
	fReadSource = fRTPSource
	  = VP8VideoRTPSource::createNew(env(), fRTPSocket,
					 fRTPPayloadFormat,
					 fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "VP9") == 0) { // VP9 video
	fReadSource = fRTPSource
	  = VP9VideoRTPSource::createNew(env(), fRTPSocket,
					 fRTPPayloadFormat,
					 fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "AC3") == 0 || strcmp(fCodecName, "EAC3") == 0) { // AC3 audio
	fReadSource = fRTPSource
	  = AC3AudioRTPSource::createNew(env(), fRTPSocket,
					 fRTPPayloadFormat,
					 fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "MP4V-ES") == 0) { // MPEG-4 Elementary Stream video
	fReadSource = fRTPSource
	  = MPEG4ESVideoRTPSource::createNew(env(), fRTPSocket,
					     fRTPPayloadFormat,
					     fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "MPEG4-GENERIC") == 0) {
	fReadSource = fRTPSource
	  = MPEG4GenericRTPSource::createNew(env(), fRTPSocket,
					     fRTPPayloadFormat,
					     fRTPTimestampFrequency,
					     fMediumName, attrVal_strToLower("mode"),
					     attrVal_unsigned("sizelength"),
					     attrVal_unsigned("indexlength"),
					     attrVal_unsigned("indexdeltalength"));
      } else if (strcmp(fCodecName, "MPV") == 0) { // MPEG-1 or 2 video
	fReadSource = fRTPSource
	  = MPEG1or2VideoRTPSource::createNew(env(), fRTPSocket,
					      fRTPPayloadFormat,
					      fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "MP2T") == 0) { // MPEG-2 Transport Stream
	fRTPSource = SimpleRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
						fRTPTimestampFrequency, "video/MP2T",
						0, False);
	fReadSource = MPEG2TransportStreamFramer::createNew(env(), fRTPSource);
	// this sets "durationInMicroseconds" correctly, based on the PCR values
      } else if (strcmp(fCodecName, "H261") == 0) { // H.261
	fReadSource = fRTPSource
	  = H261VideoRTPSource::createNew(env(), fRTPSocket,
					  fRTPPayloadFormat,
					  fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "H263-1998") == 0 ||
		 strcmp(fCodecName, "H263-2000") == 0) { // H.263+
	fReadSource = fRTPSource
	  = H263plusVideoRTPSource::createNew(env(), fRTPSocket,
					      fRTPPayloadFormat,
					      fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "H264") == 0) {
	fReadSource = fRTPSource
	  = H264VideoRTPSource::createNew(env(), fRTPSocket,
					  fRTPPayloadFormat,
					  fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "H265") == 0) {
	Boolean expectDONFields = attrVal_unsigned("sprop-depack-buf-nalus") > 0;
	fReadSource = fRTPSource
	  = H265VideoRTPSource::createNew(env(), fRTPSocket,
					  fRTPPayloadFormat,
					  expectDONFields,
					  fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "DV") == 0) {
	fReadSource = fRTPSource
	  = DVVideoRTPSource::createNew(env(), fRTPSocket,
					fRTPPayloadFormat,
					fRTPTimestampFrequency);
      } else if (strcmp(fCodecName, "JPEG") == 0) { // motion JPEG
	if (fReceiveRawJPEGFrames) {
	  // Special case (used when proxying JPEG/RTP streams): Receive each JPEG/RTP packet, including the special RTP headers:
	  fReadSource = fRTPSource
	    = SimpleRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
					 fRTPTimestampFrequency, "video/JPEG",
					 0/*special offset*/, False/*doNormalMBitRule => ignore the 'M' bit*/);
	} else {
	  // Normal case: Receive each JPEG frame as a complete, displayable JPEG image:
	  fReadSource = fRTPSource
	    = JPEGVideoRTPSource::createNew(env(), fRTPSocket,
					    fRTPPayloadFormat,
					    fRTPTimestampFrequency,
					    videoWidth(),
					    videoHeight());
	}
      } else if (strcmp(fCodecName, "JPEG2000") == 0) { // JPEG 2000 video
        fReadSource = fRTPSource
          = JPEG2000VideoRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
					      fRTPTimestampFrequency,
					      attrVal_str("sampling"));
      } else if (strcmp(fCodecName, "X-QT") == 0
		 || strcmp(fCodecName, "X-QUICKTIME") == 0) {
	// Generic QuickTime streams, as defined in
	// <http://developer.apple.com/quicktime/icefloe/dispatch026.html>
	char* mimeType
	  = new char[strlen(mediumName()) + strlen(codecName()) + 2] ;
	sprintf(mimeType, "%s/%s", mediumName(), codecName());
	fReadSource = fRTPSource
	  = QuickTimeGenericRTPSource::createNew(env(), fRTPSocket,
						 fRTPPayloadFormat,
						 fRTPTimestampFrequency,
						 mimeType);
	delete[] mimeType;
      } else if (  strcmp(fCodecName, "PCMU") == 0 // PCM u-law audio
		   || strcmp(fCodecName, "GSM") == 0 // GSM audio
		   || strcmp(fCodecName, "DVI4") == 0 // DVI4 (IMA ADPCM) audio
		   || strcmp(fCodecName, "PCMA") == 0 // PCM a-law audio
		   || strcmp(fCodecName, "MP1S") == 0 // MPEG-1 System Stream
		   || strcmp(fCodecName, "MP2P") == 0 // MPEG-2 Program Stream
		   || strcmp(fCodecName, "L8") == 0 // 8-bit linear audio
		   || strcmp(fCodecName, "L16") == 0 // 16-bit linear audio
		   || strcmp(fCodecName, "L20") == 0 // 20-bit linear audio (RFC 3190)
		   || strcmp(fCodecName, "L24") == 0 // 24-bit linear audio (RFC 3190)
		   || strcmp(fCodecName, "G722") == 0 // G.722 audio (RFC 3551)
		   || strcmp(fCodecName, "G726-16") == 0 // G.726, 16 kbps
		   || strcmp(fCodecName, "G726-24") == 0 // G.726, 24 kbps
		   || strcmp(fCodecName, "G726-32") == 0 // G.726, 32 kbps
		   || strcmp(fCodecName, "G726-40") == 0 // G.726, 40 kbps
		   || strcmp(fCodecName, "SPEEX") == 0 // SPEEX audio
		   || strcmp(fCodecName, "ILBC") == 0 // iLBC audio
		   || strcmp(fCodecName, "OPUS") == 0 // Opus audio
		   || strcmp(fCodecName, "T140") == 0 // T.140 text (RFC 4103)
		   || strcmp(fCodecName, "DAT12") == 0 // 12-bit nonlinear audio (RFC 3190)
		   || strcmp(fCodecName, "VND.ONVIF.METADATA") == 0 // 'ONVIF' 'metadata' (a XML document)
		   ) {
	createSimpleRTPSource = True;
	useSpecialRTPoffset = 0;
	if (strcmp(fCodecName, "VND.ONVIF.METADATA") == 0) {
	  // This RTP payload format uses the RTP "M" bit to indicate the end of the content (a XML document):
	  doNormalMBitRule = True;
	}
      } else if (useSpecialRTPoffset >= 0) {
	// We don't know this RTP payload format, but try to receive
	// it using a 'SimpleRTPSource' with the specified header offset:
	createSimpleRTPSource = True;
      } else {
	env().setResultMsg("RTP payload format unknown or not supported");
	break;
      }
      
      if (createSimpleRTPSource) {
	char* mimeType
	  = new char[strlen(mediumName()) + strlen(codecName()) + 2] ;
	sprintf(mimeType, "%s/%s", mediumName(), codecName());
	fReadSource = fRTPSource
	  = SimpleRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
				       fRTPTimestampFrequency, mimeType,
				       (unsigned)useSpecialRTPoffset,
				       doNormalMBitRule);
	delete[] mimeType;
      }
    }

    return True;
  } while (0);

  return False; // an error occurred
}


////////// SDPAttribute implementation //////////

SDPAttribute::SDPAttribute(char const* strValue, Boolean valueIsHexadecimal)
  : fStrValue(strDup(strValue)), fStrValueToLower(NULL), fValueIsHexadecimal(valueIsHexadecimal) {
  if (fStrValue == NULL) {
    // No value was given for this attribute, so consider it to be a Boolean, with value True:
    fIntValue = 1;
  } else {
    // Create a 'tolower' version of "fStrValue", in case it's needed:
    Locale l("POSIX");
    size_t strSize;

    fStrValueToLower = strDupSize(fStrValue, strSize);
    for (unsigned i = 0; i < strSize-1; ++i) fStrValueToLower[i] = tolower(fStrValue[i]);
    fStrValueToLower[strSize-1] = '\0';
    
    // Try to parse "fStrValueToLower" as an integer.  If we can't, assume an integer value of 0:
    if (sscanf(fStrValueToLower, valueIsHexadecimal ? "%x" : "%d", &fIntValue) != 1) {
      fIntValue = 0;
    }
  }
}

SDPAttribute::~SDPAttribute() {
  delete[] fStrValue;
  delete[] fStrValueToLower;
}
