Exemple #1
0
RTPSource::RTPSource(UsageEnvironment& env, Groupsock* RTPgs,
		     unsigned char rtpPayloadFormat,
		     u_int32_t rtpTimestampFrequency)
  : FramedSource(env),
    fRTPInterface(this, RTPgs),
    fCurPacketHasBeenSynchronizedUsingRTCP(False), fLastReceivedSSRC(0),
    fRTPPayloadFormat(rtpPayloadFormat), fTimestampFrequency(rtpTimestampFrequency),
    fSSRC(our_random32()), fEnableRTCPReports(True) {
  fReceptionStatsDB = new RTPReceptionStatsDB();
}
Exemple #2
0
char* SIPClient::invite(char const* url, Authenticator* authenticator) {
  // First, check whether "url" contains a username:password to be used:
  char* username; char* password;
  if (authenticator == NULL
      && parseSIPURLUsernamePassword(url, username, password)) {
    char* result = inviteWithPassword(url, username, password);
    delete[] username; delete[] password; // they were dynamically allocated
    return result;
  }

  if (!processURL(url)) return NULL;

  delete[] (char*)fURL; fURL = strDup(url);
  fURLSize = strlen(fURL);

  fCallId = our_random32();
  fFromTag = our_random32();

  return invite1(authenticator);
}
Exemple #3
0
RTPSink::RTPSink(UsageEnvironment& env,
		 Groupsock* rtpGS, unsigned char rtpPayloadType,
		 unsigned rtpTimestampFrequency,
		 char const* rtpPayloadFormatName,
		 unsigned numChannels)
  : MediaSink(env), fRTPInterface(this, rtpGS),
    fRTPPayloadType(rtpPayloadType),
    fPacketCount(0), fOctetCount(0), fTotalOctetCount(0),
    fTimestampFrequency(rtpTimestampFrequency), fNextTimestampHasBeenPreset(True),
    fNumChannels(numChannels) {
  fRTPPayloadFormatName
    = strDup(rtpPayloadFormatName == NULL ? "???" : rtpPayloadFormatName);
  gettimeofday(&fCreationTime, NULL);
  fTotalOctetCountStartTime = fCreationTime;

  fSeqNo = (u_int16_t)our_random();
  fSSRC = our_random32();
  fTimestampBase = our_random32();

  fTransmissionStatsDB = new RTPTransmissionStatsDB(*this);
}
GenericMediaServer::ClientSession* GenericMediaServer::createNewClientSessionWithId() {
  u_int32_t sessionId;
  char sessionIdStr[8+1];

  // Choose a random (unused) 32-bit integer for the session id
  // (it will be encoded as a 8-digit hex number).  (We avoid choosing session id 0,
  // because that has a special use by some servers.)
  do {
    sessionId = (u_int32_t)our_random32();  //使用 random 方式创建一个 sessionId
    snprintf(sessionIdStr, sizeof sessionIdStr, "%08X", sessionId);
  } while (sessionId == 0 || lookupClientSession(sessionIdStr) != NULL);

  ClientSession* clientSession = createNewClientSession(sessionId);
  fClientSessions->Add(sessionIdStr, clientSession);

  return clientSession;
}
Boolean DarwinInjector
::setDestination(char const* remoteRTSPServerNameOrAddress,
		 char const* remoteFileName,
		 char const* sessionName,
		 char const* sessionInfo,
		 portNumBits remoteRTSPServerPortNumber,
		 char const* remoteUserName,
		 char const* remotePassword,
		 char const* sessionAuthor,
		 char const* sessionCopyright,
		 int timeout) {
  char* sdp = NULL;
  char* url = NULL;
  Boolean success = False; // until we learn otherwise

  do {
    // Construct a RTSP URL for the remote stream:
    char const* const urlFmt = "rtsp://%s:%u/%s";
    unsigned urlLen
      = strlen(urlFmt) + strlen(remoteRTSPServerNameOrAddress) + 5 /* max short len */ + strlen(remoteFileName);
    url = new char[urlLen];
    sprintf(url, urlFmt, remoteRTSPServerNameOrAddress, remoteRTSPServerPortNumber, remoteFileName);

    // Begin by creating our RTSP client object:
    fRTSPClient = new RTSPClientForDarwinInjector(envir(), url, fVerbosityLevel, fApplicationName, this);
    if (fRTSPClient == NULL) break;

    // Get the remote RTSP server's IP address:
    struct in_addr addr;
    {
      NetAddressList addresses(remoteRTSPServerNameOrAddress);
      if (addresses.numAddresses() == 0) break;
      NetAddress const* address = addresses.firstAddress();
      addr.s_addr = *(unsigned*)(address->data());
    }
    AddressString remoteRTSPServerAddressStr(addr);

    // Construct a SDP description for the session that we'll be streaming:
    char const* const sdpFmt =
      "v=0\r\n"
      "o=- %u %u IN IP4 127.0.0.1\r\n"
      "s=%s\r\n"
      "i=%s\r\n"
      "c=IN IP4 %s\r\n"
      "t=0 0\r\n"
      "a=x-qt-text-nam:%s\r\n"
      "a=x-qt-text-inf:%s\r\n"
      "a=x-qt-text-cmt:source application:%s\r\n"
      "a=x-qt-text-aut:%s\r\n"
      "a=x-qt-text-cpy:%s\r\n";
      // plus, %s for each substream SDP
    unsigned sdpLen = strlen(sdpFmt)
      + 20 /* max int len */ + 20 /* max int len */
      + strlen(sessionName)
      + strlen(sessionInfo)
      + strlen(remoteRTSPServerAddressStr.val())
      + strlen(sessionName)
      + strlen(sessionInfo)
      + strlen(fApplicationName)
      + strlen(sessionAuthor)
      + strlen(sessionCopyright)
      + fSubstreamSDPSizes;
    unsigned const sdpSessionId = our_random32();
    unsigned const sdpVersion = sdpSessionId;
    sdp = new char[sdpLen];
    sprintf(sdp, sdpFmt,
	    sdpSessionId, sdpVersion, // o= line
	    sessionName, // s= line
	    sessionInfo, // i= line
	    remoteRTSPServerAddressStr.val(), // c= line
	    sessionName, // a=x-qt-text-nam: line
	    sessionInfo, // a=x-qt-text-inf: line
	    fApplicationName, // a=x-qt-text-cmt: line
	    sessionAuthor, // a=x-qt-text-aut: line
	    sessionCopyright // a=x-qt-text-cpy: line
	    );
    char* p = &sdp[strlen(sdp)];
    SubstreamDescriptor* ss;
    for (ss = fHeadSubstream; ss != NULL; ss = ss->next()) {
      sprintf(p, "%s", ss->sdpLines());
      p += strlen(p);
    }

    // Do a RTSP "ANNOUNCE" with this SDP description:
    Authenticator auth;
    Authenticator* authToUse = NULL;
    if (remoteUserName[0] != '\0' || remotePassword[0] != '\0') {
      auth.setUsernameAndPassword(remoteUserName, remotePassword);
      authToUse = &auth;
    }
    fWatchVariable = 0;
    (void)fRTSPClient->sendAnnounceCommand(sdp, genericResponseHandler, authToUse);

    // Now block (but handling events) until we get a response:
    envir().taskScheduler().doEventLoop(&fWatchVariable);

    delete[] fResultString;
    if (fResultCode != 0) break; // an error occurred with the RTSP "ANNOUNCE" command

    // Next, tell the remote server to start receiving the stream from us.
    // (To do this, we first create a "MediaSession" object from the SDP description.)
    fSession = MediaSession::createNew(envir(), sdp);
    if (fSession == NULL) break;

    ss = fHeadSubstream;
    MediaSubsessionIterator iter(*fSession);
    MediaSubsession* subsession;
    ss = fHeadSubstream;
    unsigned streamChannelId = 0;
    while ((subsession = iter.next()) != NULL) {
      if (!subsession->initiate()) break;

      fWatchVariable = 0;
      (void)fRTSPClient->sendSetupCommand(*subsession, genericResponseHandler,
					  True /*streamOutgoing*/,
					  True /*streamUsingTCP*/);
      // Now block (but handling events) until we get a response:
      envir().taskScheduler().doEventLoop(&fWatchVariable);

      delete[] fResultString;
      if (fResultCode != 0) break; // an error occurred with the RTSP "SETUP" command

      // Tell this subsession's RTPSink and RTCPInstance to use
      // the RTSP TCP connection:
      ss->rtpSink()->setStreamSocket(fRTSPClient->socketNum(), streamChannelId++);
      if (ss->rtcpInstance() != NULL) {
	ss->rtcpInstance()->setStreamSocket(fRTSPClient->socketNum(),
					    streamChannelId++);
      }
      ss = ss->next();
    }
    if (subsession != NULL) break; // an error occurred above

    // Tell the RTSP server to start:
    fWatchVariable = 0;
    (void)fRTSPClient->sendPlayCommand(*fSession, genericResponseHandler);

    // Now block (but handling events) until we get a response:
    envir().taskScheduler().doEventLoop(&fWatchVariable);

    delete[] fResultString;
    if (fResultCode != 0) break; // an error occurred with the RTSP "PLAY" command

    // Finally, make sure that the output TCP buffer is a reasonable size:
    increaseSendBufferTo(envir(), fRTSPClient->socketNum(), 100*1024);

    success = True;
  } while (0);

  delete[] sdp;
  delete[] url;
  return success;
}