ServerMediaSession* DynamicRTSPServer::lookupServerMediaSession(char const* streamName) { // First, check whether the specified "streamName" exists as a local file: FILE* fid = fopen(streamName, "rb"); Boolean fileExists = fid != NULL; // Next, check whether we already have a "ServerMediaSession" for this file: ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(streamName); Boolean smsExists = sms != NULL; // Handle the four possibilities for "fileExists" and "smsExists": if (!fileExists) { if (smsExists) { // "sms" was created for a file that no longer exists. Remove it: removeServerMediaSession(sms); } return NULL; } else { if (!smsExists) { // Create a new "ServerMediaSession" object for streaming from the named file. sms = createNewSMS(envir(), streamName, fid); addServerMediaSession(sms); } fclose(fid); return sms; } }
ServerMediaSession* DynamicRTSPServer ::lookupServerMediaSession(char const* streamName, Boolean isFirstLookupInSession) { // First, check whether the specified "streamName" exists as a local file: FILE* fid = fopen(streamName, "rb"); Boolean fileExists = fid != NULL; ALOGE("lookupServerMediaSession streamName: %s, %p", streamName, fid); // Next, check whether we already have a "ServerMediaSession" for this file: ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(streamName); Boolean smsExists = sms != NULL; // Handle the four possibilities for "fileExists" and "smsExists": if (!fileExists) { if (smsExists) { // "sms" was created for a file that no longer exists. Remove it: removeServerMediaSession(sms); sms = NULL; } if (sms == NULL) { sms = createNewSMS(envir(), streamName, fid, mH264Pool); addServerMediaSession(sms); } return sms; } else { if (smsExists && isFirstLookupInSession) { // Remove the existing "ServerMediaSession" and create a new one, in case the underlying // file has changed in some way: removeServerMediaSession(sms); sms = NULL; } if (sms == NULL) { sms = createNewSMS(envir(), streamName, fid, mH264Pool); addServerMediaSession(sms); } fclose(fid); return sms; } }
void RTSPServerWithREGISTERProxying ::implementCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/, char const* url, char const* /*urlSuffix*/, int socketToRemoteServer, Boolean deliverViaTCP, char const* proxyURLSuffix) { // Continue setting up proxying for the specified URL. // By default: // - We use "registeredProxyStream-N" as the (front-end) stream name (ignoring the back-end stream's 'urlSuffix'), // unless "proxyURLSuffix" is non-NULL (in which case we use that) // - There is no 'username' and 'password' for the back-end stream. (Thus, access-controlled back-end streams will fail.) // - If "fStreamRTPOverTCP" is True, then we request delivery over TCP, regardless of the value of "deliverViaTCP". // (Otherwise, if "fStreamRTPOverTCP" is False, we use the value of "deliverViaTCP" to decide this.) // To change this default behavior, you will need to subclass "RTSPServerWithREGISTERProxying", and reimplement this function. char const* proxyStreamName; char proxyStreamNameBuf[100]; if (proxyURLSuffix == NULL) { sprintf(proxyStreamNameBuf, "registeredProxyStream-%u", ++fRegisteredProxyCounter); proxyStreamName = proxyStreamNameBuf; } else { proxyStreamName = proxyURLSuffix; } if (strcmp(cmd, "REGISTER") == 0) { if (fStreamRTPOverTCP) deliverViaTCP = True; portNumBits tunnelOverHTTPPortNum = deliverViaTCP ? (portNumBits)(~0) : 0; // We don't support streaming from the back-end via RTSP/RTP/RTCP-over-HTTP; only via RTP/RTCP-over-TCP or RTP/RTCP-over-UDP ServerMediaSession* sms = ProxyServerMediaSession::createNew(envir(), this, url, proxyStreamName, fBackEndUsername, fBackEndPassword, tunnelOverHTTPPortNum, fVerbosityLevelForProxying, socketToRemoteServer); addServerMediaSession(sms); // (Regardless of the verbosity level) announce the fact that we're proxying this new stream, and the URL to use to access it: char* proxyStreamURL = rtspURL(sms); envir() << "Proxying the registered back-end stream \"" << url << "\".\n"; envir() << "\tPlay this stream using the URL: " << proxyStreamURL << "\n"; delete[] proxyStreamURL; } else { // "DEREGISTER" deleteServerMediaSession(lookupServerMediaSession(proxyStreamName)); } }
void LiveRtspServer::addRtspMediaSession(const Channel& channel) { const std::string sSessionName = channel.ChannelName; // Next, check whether we already have an RTSP "ServerMediaSession" for this media stream: ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(sSessionName.c_str()); Boolean bSmsExists = sms != NULL; if (!bSmsExists) { VLOG(2) << "Creating Session " << sSessionName << " on RTSP server"; // Create a new "ServerMediaSession" object for streaming from the named file. sms = createNewSMS(envir(), *this, channel, m_pFactory, m_pGlobalRateControl); VLOG(2) << "Adding ServerMediaSession " << sSessionName; addServerMediaSession(sms); announceStream(this, sms, sSessionName.c_str()); } else { LOG(WARNING) << "Session " << sSessionName << " already exists on RTSP server"; } }