void continueAfterPLAY(RTSPClient* rtspClient, int resultCode, char* resultString) { do { UsageEnvironment& env = rtspClient->envir(); // alias StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias if (resultCode != 0) { env << *rtspClient << "Failed to start playing session: " << resultString << "\n"; break; } // Set a timer to be handled at the end of the stream's expected duration (if the stream does not already signal its end // using a RTCP "BYE"). This is optional. If, instead, you want to keep the stream active - e.g., so you can later // 'seek' back within it and do another RTSP "PLAY" - then you can omit this code. // (Alternatively, if you don't want to receive the entire stream, you could set this timer for some shorter value.) if (scs.duration > 0) { unsigned const delaySlop = 2; // number of seconds extra to delay, after the stream's expected duration. (This is optional.) scs.duration += delaySlop; unsigned uSecsToDelay = (unsigned)(scs.duration*1000000); scs.streamTimerTask = env.taskScheduler().scheduleDelayedTask(uSecsToDelay, (TaskFunc*)streamTimerHandler, rtspClient); } env << *rtspClient << "Started playing session"; if (scs.duration > 0) { env << " (for up to " << scs.duration << " seconds)"; } env << "...\n"; return; } while (0); // An unrecoverable error occurred with this stream. shutdownStream(rtspClient, 1); }
void setupNextSubsession(RTSPClient* rtspClient) { UsageEnvironment& env = rtspClient->envir(); // alias StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias scs.subsession = scs.iter->next(); if (scs.subsession != NULL) { if ( strcmp(scs.subsession->mediumName(),"audio") != 0 || (scs.subsession->getFlag() == 0 && bEnableBackChannel) // flag= 0:receive only 1:send only || !scs.subsession->initiate()) { env << *rtspClient << "Failed to initiate the \"" << *scs.subsession << "\" subsession: " << env.getResultMsg() << "\n"; setupNextSubsession(rtspClient); // give up on this subsession; go to the next one } else { env << *rtspClient << "Initiated the \"" << *scs.subsession << "\" subsession (client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1 << ")\n"; // 20140625 albert.liao modified start // Continue setting up this subsession, by sending a RTSP "SETUP" command: rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP, False, REQUEST_STREAMING_OVER_TCP); // TODO: rtsp server should create PassiveServerMediaSubsession, // so that multicast can work // rtspClient->sendSetupCommand(*scs.subsession, // continueAfterSETUP, // False,//True, /* streamOutgoing, for darwin */ // REQUEST_STREAMING_OVER_TCP, // True, /*Multicast*/ // NULL); // 20140625 albert.liao modified end } return; } //startPlay(rtspClient); shutdownStream(rtspClient); }
void HttpInterface::run() { do { sendAvailableResponses(); pingNetwork(); if (!run2s()) break; if (verbose && streamsToShutdown.size() > 0) { cerr << "HttpInterface::run "<< streamsToShutdown.size() <<" streams to shut down"; for (std::set<Dashel::Stream*>::iterator si = streamsToShutdown.begin(); si != streamsToShutdown.end(); si++) cerr << " " << *si; cerr << endl; } if (!streamsToShutdown.empty()) { std::set<Dashel::Stream*>::iterator i = streamsToShutdown.begin(); Dashel::Stream* stream_to_shutdown = *i; streamsToShutdown.erase(*i); // invalidates iterator try { if (verbose) cerr << stream_to_shutdown << " shutting down stream" << endl; shutdownStream(stream_to_shutdown); } catch(Dashel::DashelException& e) { } } } while (iterations-- != 0 and asebaStream != 0); for (StreamResponseQueueMap::iterator i = pendingResponses.begin(); i != pendingResponses.end(); i++) unscheduleAllResponses(i->first); }
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString) { do { UsageEnvironment& env = rtspClient->envir(); // alias StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias if (resultCode != 0) { env << *rtspClient << "Failed to get a SDP description: " << resultString << "\n"; break; } char* const sdpDescription = resultString; env << *rtspClient << "Got a SDP description:\n" << sdpDescription << "\n"; // Create a media session object from this SDP description: scs.session = MediaSession::createNew(env, sdpDescription); delete[] sdpDescription; // because we don't need it anymore if (scs.session == NULL) { env << *rtspClient << "Failed to create a MediaSession object from the SDP description: " << env.getResultMsg() << "\n"; break; } else if (!scs.session->hasSubsessions()) { env << *rtspClient << "This session has no media subsessions (i.e., no \"m=\" lines)\n"; break; } // Then, create and set up our data source objects for the session. We do this by iterating over the session's 'subsessions', // calling "MediaSubsession::initiate()", and then sending a RTSP "SETUP" command, on each one. // (Each 'subsession' will have its own data source.) scs.iter = new MediaSubsessionIterator(*scs.session); setupNextSubsession(rtspClient); return; } while (0); // An unrecoverable error occurred with this stream. shutdownStream(rtspClient); }
void streamTimerHandler(void* clientData) { ourRTSPClient* rtspClient = (ourRTSPClient*)clientData; StreamClientState& scs = rtspClient->scs; // alias scs.streamTimerTask = NULL; // Shut down the stream: shutdownStream(rtspClient); }
void streamTimerHandler(void* clientData) { OUTPUT_DEBUG_STRING("%s \n", __FUNCTION__); ourRTSPClient* rtspClient = (ourRTSPClient*)clientData; StreamClientState& scs = rtspClient->scs; // alias scs.streamTimerTask = NULL; // Shut down the stream: shutdownStream(rtspClient); }
void live555Thread::shutdownLiveStream(void* rtspClient) { if( (fLive555Env == NULL) || (rtspClient == NULL) ) return; //停止主线程 this->fLive555EventLoopWatchVariable = ~0; OSMutexLocker locker(&fMutex); shutdownStream((RTSPClient*)rtspClient); }
void CAimer39RTSPClient::continueAfterPLAY(RTSPClient* rtspClient, int resultCode, char* resultString) { Boolean success = False; do { UsageEnvironment& env = rtspClient->envir(); // alias StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias CAimer39RTSPClient * arc = findClient( (ourRTSPClient*)rtspClient ); if ( NULL == arc ) { env << "some how the system in to a dangerous situation!" << "\n"; break; } arc->m_errorCode = resultCode; if (resultCode != 0) { arc->m_lastErrorMsg = resultString; env << *rtspClient << "Failed to start playing session: " << resultString << "\n"; break; } // Set a timer to be handled at the end of the stream's expected duration (if the stream does not already signal its end // using a RTCP "BYE"). This is optional. If, instead, you want to keep the stream active - e.g., so you can later // 'seek' back within it and do another RTSP "PLAY" - then you can omit this code. // (Alternatively, if you don't want to receive the entire stream, you could set this timer for some shorter value.) /*if (scs.duration > 0) { unsigned const delaySlop = 2; // number of seconds extra to delay, after the stream's expected duration. (This is optional.) scs.duration += delaySlop; unsigned uSecsToDelay = (unsigned)((scs.duration - scs.session->playStartTime())*1000000); if (scs.streamTimerTask) env.taskScheduler().unscheduleDelayedTask(scs.streamTimerTask); scs.streamTimerTask = env.taskScheduler().scheduleDelayedTask(uSecsToDelay, (TaskFunc*)streamTimerHandler, rtspClient); }*/ env << *rtspClient << "Started playing session"; if (scs.duration > 0) { env << " (for up to " << scs.duration << " seconds)"; } env << "...\n"; if (arc->m_pStartPlayCB) arc->m_pStartPlayCB(scs.duration, scs.session->playStartTime(), arc->m_pStartPlayCBP, arc); success = True; } while (0); delete[] resultString; if (!success) { // An unrecoverable error occurred with this stream. shutdownStream(rtspClient); return; } }
// Implementation of the RTSP 'response handlers': void CAimer39RTSPClient::continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString) { do { UsageEnvironment& env = rtspClient->envir(); // alias StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias CAimer39RTSPClient * arc = findClient( (ourRTSPClient*)rtspClient ); arc->m_bIsPrepare = false; if ( NULL == arc ) { arc->m_errorCode = -1; env << "some how the system in to a dangerous situation!" << "\n"; break; } arc->m_errorCode = resultCode; if (resultCode != 0) { arc->m_lastErrorMsg = resultString; env << *rtspClient << "Failed to get a SDP description: " << resultString << "\n"; delete[] resultString; break; } char* const sdpDescription = resultString; env << *rtspClient << "Got a SDP description:\n" << sdpDescription << "\n"; // Create a media session object from this SDP description: scs.session = MediaSession::createNew(env, sdpDescription); delete[] sdpDescription; // because we don't need it anymore if (scs.session == NULL) { env << *rtspClient << "Failed to create a MediaSession object from the SDP description: " << env.getResultMsg() << "\n"; arc->m_errorCode = -1; arc->m_lastErrorMsg = env.getResultMsg(); break; } else if (!scs.session->hasSubsessions()) { env << *rtspClient << "This session has no media subsessions (i.e., no \"m=\" lines)\n"; arc->m_errorCode = 2; arc->m_lastErrorMsg = "This session has no media subsessions (i.e., no \"m=\" lines)\n"; break; } arc->m_bIsPrepare = true; return; } while (0); // An unrecoverable error occurred with this stream. shutdownStream(rtspClient); }
void subsessionAfterPlaying(void* clientData) { MediaSubsession* subsession = (MediaSubsession*)clientData; RTSPClient* rtspClient = (RTSPClient*)(subsession->miscPtr); // Begin by closing this subsession's stream: Medium::close(subsession->sink); subsession->sink = NULL; // Next, check whether *all* subsessions' streams have now been closed: MediaSession& session = subsession->parentSession(); MediaSubsessionIterator iter(session); while ((subsession = iter.next()) != NULL) { if (subsession->sink != NULL) return; // this subsession is still active } // All subsessions' streams have now been closed, so shutdown the client: shutdownStream(rtspClient, 1); }
int CAimer39RTSPClient::Close() { m_eventLoopWatchVariable = 1; //wait for thread return Join(); if ( !m_bIsShutDown ) { shutdownStream( m_pRTSPClient ); } m_Env->reclaim(); m_Env = NULL; delete m_Scheduler; m_Scheduler = NULL; m_pRTSPClient = NULL; m_bIsPrepare = m_bIsPlay = m_bIsShutDown = false; return m_errorCode; }
void CRTSPSession::rtsp_fun() { //::startRTSP(m_progName.c_str(), m_rtspUrl.c_str(), m_ndebugLever); TaskScheduler* scheduler = BasicTaskScheduler::createNew(); UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); if (openURL(*env, m_progName.c_str(), m_rtspUrl.c_str(), m_debugLevel) == 0) { m_nStatus = 1; env->taskScheduler().doEventLoop(&eventLoopWatchVariable); m_running = false; eventLoopWatchVariable = 0; if (m_rtspClient) { shutdownStream(m_rtspClient,0); } m_rtspClient = NULL; } env->reclaim(); env = NULL; delete scheduler; scheduler = NULL; m_nStatus = 2; }