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(); }
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); }
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; }