Boolean CRTSPClient::clientStartPlayingSession(Medium* client,MediaSession* session) { XBMC->Log(LOG_DEBUG, "CRTSPClient::clientStartPlayingSession()"); if (client == NULL || session == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; long dur=m_duration/1000; double fStart = m_fStart ; double fStartToEnd ; if (m_fDuration > 0.0) { fStartToEnd = m_fDuration-m_fStart ; if (fStartToEnd<0) fStartToEnd=0 ; fStart = dur - fStartToEnd ; if (fStart<0) fStart=0 ; } // long diff = (long) abs((int)((double) dur - m_fStart)); // if (diff <20 && m_fStart>1 ) // { // m_fStart=dur+5; // } XBMC->Log(LOG_DEBUG, "CRTSPClient::clientStartPlayingSession() play from %.3f / %.3f",fStart,(float)m_duration/1000); return rtspClient->playMediaSession(*session,fStart); }
Boolean CRTSPClient::clientSetupSubsession(Medium* client, MediaSubsession* subsession,Boolean streamUsingTCP) { XBMC->Log(LOG_DEBUG, "CRTSPClient::clientSetupSubsession()"); if (client == NULL || subsession == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->setupMediaSubsession(*subsession,False, streamUsingTCP); }
Boolean CRTSPClient::clientTearDownSession(Medium* client,MediaSession* session) { XBMC->Log(LOG_DEBUG, "CRTSPClient::clientTearDownSession()"); if (client == NULL || session == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->teardownMediaSession(*session); }
ProxyDemuxerTask* ProxyClientInfo::AddStream(QTSS_RTPStreamObject inStream) { // // Allocate some UDP sockets out of our pool to receive the UDP data from // the server. Demuxing is based on the origin server's (host's) IP addr, so // pass that to the socket pool so it can properly allocate a pair of UDP sockets. // We don't know what the remote port is yet (we only find out when we get the // SETUP response from the origin), so just pass in 0. UInt32 theHostAddr = fClient.GetSocket()->GetHostAddr(); UInt32 theLocalAddr = fClient.GetSocket()->GetLocalAddr(); UDPSocketPair* thePair = sSocketPool->GetUDPSocketPair(theLocalAddr, 0, theHostAddr, 0); fLastDemuxerTask = NEW ProxyDemuxerTask(inStream, thePair); fDemuxerTaskQueue.EnQueue(fLastDemuxerTask->GetQueueElem()); // // Tell the demuxers for these sockets to send any packets from this IP addr // to the ProxyDemuxerTask for this stream. This is how incoming UDP packets // will be routed to the proper QTSS_RTPStreamObject thePair->GetSocketA()->GetDemuxer()->RegisterTask(theHostAddr, 0, fLastDemuxerTask); thePair->GetSocketB()->GetDemuxer()->RegisterTask(theHostAddr, 0, fLastDemuxerTask); // // return the newly created ProxyDemuxerTask return fLastDemuxerTask; }
Boolean clientSetupSubsession(Medium* client, MediaSubsession* subsession, Boolean streamUsingTCP, unsigned *pResponseCode /*= NULL*/) { if (client == NULL || subsession == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->setupMediaSubsession(*subsession, False, streamUsingTCP, FALSE, pResponseCode); }
bool CRTSPClient::clientSetupSubsession(Medium* client, MediaSubsession* subsession, bool streamUsingTCP) { XBMC->Log(LOG_DEBUG, "CRTSPClient::clientSetupSubsession()"); if (client == NULL || subsession == NULL) return false; RTSPClient* rtspClient = (RTSPClient*) client; return ( rtspClient->setupMediaSubsession(*subsession, False, (streamUsingTCP ? True : False)) ? true : false); }
void subsessionByeHandler(void* clientData) { MediaSubsession* subsession = (MediaSubsession*)clientData; RTSPClient* rtspClient = (RTSPClient*)subsession->miscPtr; UsageEnvironment& env = rtspClient->envir(); // alias env << *rtspClient << "Received RTCP \"BYE\" on \"" << *subsession << "\" subsession\n"; // Now act as if the subsession had closed: subsessionAfterPlaying(subsession); }
void CRTSPClient::Continue() { if (m_ourClient != NULL && m_session != NULL) { RTSPClient* rtspClient = (RTSPClient*) m_ourClient; rtspClient->playMediaSession(*m_session, -1.0); StartBufferThread(); m_bPaused = false; } }
void subsessionByeHandler(void* clientData) { OUTPUT_DEBUG_STRING("%s \n", __FUNCTION__); MediaSubsession* subsession = (MediaSubsession*)clientData; RTSPClient* rtspClient = (RTSPClient*)subsession->miscPtr; UsageEnvironment& env = rtspClient->envir(); // alias //env << *rtspClient << "Received RTCP \"BYE\" on \"" << *subsession << "\" subsession\n"; OUTPUT_DEBUG_STRING("Received RTCP \"BYE\" on subsession\n"); // Now act as if the subsession had closed: subsessionAfterPlaying(subsession); }
char* CRTSPClient::getSDPDescription() { XBMC->Log(LOG_DEBUG, "CRTSPClient::getSDPDescription()"); RTSPClient *client = (RTSPClient*)m_ourClient; RTSPClient *rtspClient = RTSPClient::createNew(client->envir(), 0, "TSFileSource", tunnelOverHTTPPortNum); char* result; result = rtspClient->describeURL(m_url); XBMC->Log(LOG_DEBUG, "CRTSPClient::getSDPDescription() statusCode = %d", rtspClient->describeStatus()); Medium::close(rtspClient); return result; }
char* getSDPDescriptionFromURL(Medium* client, char const* url, char const* username, char const* password, char const* /*proxyServerName*/, unsigned short /*proxyServerPortNum*/, unsigned short /*clientStartPort*/) { RTSPClient* rtspClient = (RTSPClient*)client; char* result; if (username != NULL && password != NULL) { result = rtspClient->describeWithPassword(url, username, password); } else { result = rtspClient->describeURL(url); } return result; }
char* CRTSPClient::getOptionsResponse(Medium* client, char const* url,char* username, char* password) { XBMC->Log(LOG_DEBUG, "CRTSPClient::getOptionsResponse()"); RTSPClient* rtspClient = (RTSPClient*)client; char* optionsResponse = rtspClient->sendOptionsCmd(url, username, password); if (optionsResponse == NULL) { XBMC->Log(LOG_DEBUG, "CRTSPClient::getOptionsResponse(): \"OPTIONS\" request failed: %s", m_env->getResultMsg()); } else { XBMC->Log(LOG_DEBUG, "CRTSPClient::getOptionsResponse(): \"OPTIONS\" request returned: %s", optionsResponse); } return optionsResponse; }
RTSPClient * openURL(UsageEnvironment& env, char const* rtspURL) { RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, "RTSP Client"/*"rtsp_thread"*/); if (rtspClient == NULL) { rtsperror("connect failed: %s\n", env.getResultMsg()); //env << "Failed to create a RTSP client for URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n"; return NULL; } ++rtspClientCount; rtspClient->sendDescribeCommand(continueAfterDESCRIBE); return rtspClient; }
char* CRTSPClient::getSDPDescription() { // LogDebug("CRTSPClient::getSDPDescription()"); if (m_ourClient == NULL) return NULL; RTSPClient *client = (RTSPClient*)m_ourClient; RTSPClient *rtspClient = RTSPClient::createNew(client->envir(), 0, "TSFileSource", tunnelOverHTTPPortNum); char* result; result = rtspClient->describeURL(m_url); // LogDebug("CRTSPClient::getSDPDescription() statusCode = %d", rtspClient->describeStatus()); Medium::close(rtspClient); return result; }
void openURL(UsageEnvironment& env, char const* progName, char const* rtspURL) { // Begin by creating a "RTSPClient" object. Note that there is a separate "RTSPClient" object for each stream that we wish // to receive (even if more than stream uses the same "rtsp://" URL). RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, progName); if (rtspClient == NULL) { env << "Failed to create a RTSP client for URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n"; return; } ++rtspClientCount; // Next, send a RTSP "DESCRIBE" command, to get a SDP description for the stream. // Note that this command - like all RTSP commands - is sent asynchronously; we do not block, waiting for a response. // Instead, the following function call returns immediately, and we handle the RTSP response later, from within the event loop: rtspClient->sendDescribeCommand(continueAfterDESCRIBE); }
Boolean clientStartPlayingSession(Medium* client, MediaSession* session) { extern double initialSeekTime, duration, scale; double endTime = initialSeekTime; if (scale > 0) { if (duration <= 0) endTime = -1.0f; else endTime = initialSeekTime + duration; } else { endTime = initialSeekTime - duration; if (endTime < 0) endTime = 0.0f; } if (client == NULL || session == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->playMediaSession(*session, initialSeekTime, endTime, (float)scale); }
int CRTSPSession::openURL(UsageEnvironment& env, char const* progName, char const* rtspURL, int debugLevel) { m_rtspClient = ourRTSPClient::createNew(env, rtspURL, debugLevel, progName); if (m_rtspClient == NULL) { env << "Failed to create a RTSP client for URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n"; return -1; } ((ourRTSPClient*)m_rtspClient)->m_nID = m_nID; m_rtspClient->sendDescribeCommand(continueAfterDESCRIBE); return 0; }
RTSPClient* openURL(UsageEnvironment& env, RtspParam param, int channel, DataCallback cb) { // Begin by creating a "RTSPClient" object. Note that there is a separate "RTSPClient" object for each stream that we wish // to receive (even if more than stream uses the same "rtsp://" URL). RTSPClient* rtspClient = ourRTSPClient::createNew(env, param.url, RTSP_CLIENT_VERBOSITY_LEVEL, "RTSP-Live555"); if (rtspClient == NULL) { env << "Failed to create a RTSP client for URL \"" << param.url << "\": " << env.getResultMsg() << "\n"; return NULL; } ourRTSPClient* ourClient = (ourRTSPClient*)rtspClient; ourClient->_channel = channel; ourClient->_cb = cb; ourClient->_tranProtocol = param.tranProtocol; // Next, send a RTSP "DESCRIBE" command, to get a SDP description for the stream. // Note that this command - like all RTSP commands - is sent asynchronously; we do not block, waiting for a response. // Instead, the following function call returns immediately, and we handle the RTSP response later, from within the event loop: Authenticator auth(param.username, param.password); rtspClient->sendDescribeCommand(continueAfterDESCRIBE, &auth); return rtspClient; }
char* CRTSPClient::getSDPDescriptionFromURL(Medium* client, char const* url, char const* username, char const* password, char const* /*proxyServerName*/, unsigned short /*proxyServerPortNum*/, unsigned short /*clientStartPort*/) { XBMC->Log(LOG_DEBUG, "CRTSPClient::getSDPDescriptionFromURL()"); RTSPClient* rtspClient = (RTSPClient*)client; char* result; if (username != NULL && password != NULL) { result = rtspClient->describeWithPassword(url, username, password); } else { result = rtspClient->describeURL(url); } statusCode = rtspClient->describeStatus(); return result; }
int main() { string server_ip = "192.168.0.2"; int server_port = 554; string content = "/sample.ts"; RTSPClient rtspClient = RTSPClient(); if(rtspClient.init(&server_ip, server_port)!=0) return -101; if(rtspClient.conn()!=0) return -102; if(rtspClient.reqOPTIONS()!=0) return -103; sleep(1); if(rtspClient.reqDESCRIBE(content)!=0) return -104; sleep(1); if(rtspClient.exit()!=0) return -100; return 0; }
bool CRTSPClient::clientStartPlayingSession(Medium* client, MediaSession* session) { XBMC->Log(LOG_DEBUG, "CRTSPClient::clientStartPlayingSession()"); if (client == NULL || session == NULL) return false; RTSPClient* rtspClient = (RTSPClient*) client; long dur = m_duration/1000; double fStart = m_fStart; double fStartToEnd; if (m_fDuration > 0.0) { fStartToEnd = m_fDuration-m_fStart; if (fStartToEnd<0) fStartToEnd = 0; fStart = dur - fStartToEnd; if (fStart<0) fStart = 0; } XBMC->Log(LOG_DEBUG, "CRTSPClient::clientStartPlayingSession() play from %.3f / %.3f", fStart, (float) m_duration/1000); return (rtspClient->playMediaSession(*session,fStart) ? true : false); }
char* getOptionsResponse(Medium* client, char const* url, char* username, char* password) { RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->sendOptionsCmd(url, username, password); }
extern "C" demuxer_t* demux_open_rtp(demuxer_t* demuxer) { struct MPOpts *opts = demuxer->opts; Boolean success = False; do { TaskScheduler* scheduler = BasicTaskScheduler::createNew(); if (scheduler == NULL) break; UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); if (env == NULL) break; RTSPClient* rtspClient = NULL; SIPClient* sipClient = NULL; if (demuxer == NULL || demuxer->stream == NULL) break; // shouldn't happen demuxer->stream->eof = 0; // just in case // Look at the stream's 'priv' field to see if we were initiated // via a SDP description: char* sdpDescription = (char*)(demuxer->stream->priv); if (sdpDescription == NULL) { // We weren't given a SDP description directly, so assume that // we were given a RTSP or SIP URL: char const* protocol = demuxer->stream->streaming_ctrl->url->protocol; char const* url = demuxer->stream->streaming_ctrl->url->url; extern int verbose; if (strcmp(protocol, "rtsp") == 0) { rtspClient = RTSPClient::createNew(*env, verbose, "MPlayer"); if (rtspClient == NULL) { fprintf(stderr, "Failed to create RTSP client: %s\n", env->getResultMsg()); break; } sdpDescription = openURL_rtsp(rtspClient, url); } else { // SIP unsigned char desiredAudioType = 0; // PCMU (use 3 for GSM) sipClient = SIPClient::createNew(*env, desiredAudioType, NULL, verbose, "MPlayer"); if (sipClient == NULL) { fprintf(stderr, "Failed to create SIP client: %s\n", env->getResultMsg()); break; } sipClient->setClientStartPortNum(8000); sdpDescription = openURL_sip(sipClient, url); } if (sdpDescription == NULL) { fprintf(stderr, "Failed to get a SDP description from URL \"%s\": %s\n", url, env->getResultMsg()); break; } } // Now that we have a SDP description, create a MediaSession from it: MediaSession* mediaSession = MediaSession::createNew(*env, sdpDescription); if (mediaSession == NULL) break; // Create a 'RTPState' structure containing the state that we just created, // and store it in the demuxer's 'priv' field, for future reference: RTPState* rtpState = new RTPState; rtpState->sdpDescription = sdpDescription; rtpState->rtspClient = rtspClient; rtpState->sipClient = sipClient; rtpState->mediaSession = mediaSession; rtpState->audioBufferQueue = rtpState->videoBufferQueue = NULL; rtpState->flags = 0; rtpState->firstSyncTime.tv_sec = rtpState->firstSyncTime.tv_usec = 0; demuxer->priv = rtpState; int audiofound = 0, videofound = 0; // Create RTP receivers (sources) for each subsession: MediaSubsessionIterator iter(*mediaSession); MediaSubsession* subsession; unsigned desiredReceiveBufferSize; while ((subsession = iter.next()) != NULL) { // Ignore any subsession that's not audio or video: if (strcmp(subsession->mediumName(), "audio") == 0) { if (audiofound) { fprintf(stderr, "Additional subsession \"audio/%s\" skipped\n", subsession->codecName()); continue; } desiredReceiveBufferSize = 100000; } else if (strcmp(subsession->mediumName(), "video") == 0) { if (videofound) { fprintf(stderr, "Additional subsession \"video/%s\" skipped\n", subsession->codecName()); continue; } desiredReceiveBufferSize = 2000000; } else { continue; } if (rtsp_port) subsession->setClientPortNum (rtsp_port); if (!subsession->initiate()) { fprintf(stderr, "Failed to initiate \"%s/%s\" RTP subsession: %s\n", subsession->mediumName(), subsession->codecName(), env->getResultMsg()); } else { fprintf(stderr, "Initiated \"%s/%s\" RTP subsession on port %d\n", subsession->mediumName(), subsession->codecName(), subsession->clientPortNum()); // Set the OS's socket receive buffer sufficiently large to avoid // incoming packets getting dropped between successive reads from this // subsession's demuxer. Depending on the bitrate(s) that you expect, // you may wish to tweak the "desiredReceiveBufferSize" values above. int rtpSocketNum = subsession->rtpSource()->RTPgs()->socketNum(); int receiveBufferSize = increaseReceiveBufferTo(*env, rtpSocketNum, desiredReceiveBufferSize); if (verbose > 0) { fprintf(stderr, "Increased %s socket receive buffer to %d bytes \n", subsession->mediumName(), receiveBufferSize); } if (rtspClient != NULL) { // Issue a RTSP "SETUP" command on the chosen subsession: if (!rtspClient->setupMediaSubsession(*subsession, False, rtsp_transport_tcp)) break; if (!strcmp(subsession->mediumName(), "audio")) audiofound = 1; if (!strcmp(subsession->mediumName(), "video")) videofound = 1; } } } if (rtspClient != NULL) { // Issue a RTSP aggregate "PLAY" command on the whole session: if (!rtspClient->playMediaSession(*mediaSession)) break; } else if (sipClient != NULL) { sipClient->sendACK(); // to start the stream flowing } // Now that the session is ready to be read, do additional // MPlayer codec-specific initialization on each subsession: iter.reset(); while ((subsession = iter.next()) != NULL) { if (subsession->readSource() == NULL) continue; // not reading this unsigned flags = 0; if (strcmp(subsession->mediumName(), "audio") == 0) { rtpState->audioBufferQueue = new ReadBufferQueue(subsession, demuxer, "audio"); rtpState->audioBufferQueue->otherQueue = &(rtpState->videoBufferQueue); rtpCodecInitialize_audio(demuxer, subsession, flags); } else if (strcmp(subsession->mediumName(), "video") == 0) { rtpState->videoBufferQueue = new ReadBufferQueue(subsession, demuxer, "video"); rtpState->videoBufferQueue->otherQueue = &(rtpState->audioBufferQueue); rtpCodecInitialize_video(demuxer, subsession, flags); } rtpState->flags |= flags; } success = True; } while (0); if (!success) return NULL; // an error occurred // Hack: If audio and video are demuxed together on a single RTP stream, // then create a new "demuxer_t" structure to allow the higher-level // code to recognize this: if (demux_is_multiplexed_rtp_stream(demuxer)) { stream_t* s = new_ds_stream(demuxer->video); demuxer_t* od = demux_open(opts, s, DEMUXER_TYPE_UNKNOWN, opts->audio_id, opts->video_id, opts->sub_id, NULL); demuxer = new_demuxers_demuxer(od, od, od); } return demuxer; }
Boolean clientTearDownSession(Medium* client, MediaSession* session) { if (client == NULL || session == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->teardownMediaSession(*session); }
char* CRTSPClient::getOptionsResponse(Medium* client, char const* url,char* username, char* password) { LogDebug("CRTSPClient::getOptionsResponse()"); RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->sendOptionsCmd(url, username, password); }
Boolean clientSetupSubsession(Medium* client, MediaSubsession* subsession, Boolean streamUsingTCP) { if (client == NULL || subsession == NULL) return False; RTSPClient* rtspClient = (RTSPClient*)client; return rtspClient->setupMediaSubsession(*subsession, False, streamUsingTCP); }