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);
}
Exemple #3
0
    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);
    }
Exemple #4
0
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);
}
Exemple #5
0
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;
}