Exemple #1
12
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #8
0
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);
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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); 
}
Exemple #16
0
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;
}
Exemple #18
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;
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
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);
}
Exemple #22
0
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;
}
Exemple #24
0
Boolean clientTearDownSession(Medium* client,
							  MediaSession* session) {
								  if (client == NULL || session == NULL) return False;
								  RTSPClient* rtspClient = (RTSPClient*)client;
								  return rtspClient->teardownMediaSession(*session);
}
Exemple #25
0
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);
}
Exemple #26
-9
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);
}