Пример #1
0
/*****************************************************************************
 * Close: close the target
 *****************************************************************************/
static void Close( vlc_object_t * p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys = p_access->p_sys;

    if( p_sys->p_rtsp ) rtsp_close( p_sys->p_rtsp );
    free( p_sys->p_rtsp );
    free( p_sys );
}
Пример #2
0
static void demux_close_rtp(demuxer_t* demuxer)
{
    Nemesi_DemuxerStreamData * ndsd = demuxer->priv;
    rtsp_ctrl * ctl = ndsd->rtsp;
    RTSP_Error err;

    mp_msg(MSGT_DEMUX, MSGL_INFO, "Closing libNemesi RTSP Stream...\n");

    if (ndsd == NULL)
        return;

    free(ndsd);

    if (rtsp_close(ctl)) {
        err = rtsp_wait(ctl);
        if (err.got_error)
            mp_msg(MSGT_DEMUX, MSGL_ERR,
                   "Error Closing Stream: %s\n",
                   err.message.reply_str);
    }

    rtsp_uninit(ctl);
}
Пример #3
0
int rtsp_connect( rtsp_client_t *rtsp, const char *psz_mrl,
                  const char *psz_user_agent )
{
    rtsp_t *s;
    char *mrl_ptr;
    char *slash, *colon;
    unsigned int hostend, pathbegin, i;

    if( !psz_mrl ) return -1;
    s = xmalloc( sizeof(rtsp_t) );
    rtsp->p_private = s;

    if( !strncmp( psz_mrl, "rtsp://", 7 ) ) psz_mrl += 7;
    mrl_ptr = strdup( psz_mrl );

    for( i=0; i<MAX_FIELDS; i++ )
    {
        s->answers[i]=NULL;
        s->scheduled[i]=NULL;
    }

    s->host = NULL;
    s->port = 554; /* rtsp standard port */
    s->path = NULL;
    s->mrl  = strdup(psz_mrl);

    s->server = NULL;
    s->server_state = 0;
    s->server_caps = 0;

    s->cseq = 0;
    s->session = NULL;

    if( psz_user_agent ) s->user_agent = strdup( psz_user_agent );
    else s->user_agent = strdup( "User-Agent: RealMedia Player Version "
                                 "6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)" );

    slash = strchr( mrl_ptr, '/' );
    colon = strchr( mrl_ptr, ':' );

    if( !slash ) slash = mrl_ptr + strlen(mrl_ptr) + 1;
    if( !colon ) colon = slash;
    if( colon > slash ) colon = slash;

    pathbegin = slash - mrl_ptr;
    hostend = colon - mrl_ptr;

    s->host = xmalloc(hostend+1);
    strncpy( s->host, mrl_ptr, hostend );
    s->host[hostend] = 0;

    if( pathbegin < strlen(mrl_ptr) ) s->path = strdup(mrl_ptr+pathbegin+1);
    if( colon != slash )
    {
        char buffer[pathbegin-hostend];

        strncpy( buffer, mrl_ptr+hostend+1, pathbegin-hostend-1 );
        buffer[pathbegin-hostend-1] = 0;
        s->port = atoi(buffer);
        if( s->port < 0 || s->port > 65535 ) s->port = 554;
    }

    free( mrl_ptr );
    //fprintf( stderr, "got mrl: %s %i %s\n", s->host, s->port, s->path );

    s->s = rtsp->pf_connect( rtsp->p_userdata, s->host, s->port );

    if( s->s < 0 )
    {
        //fprintf(stderr, "rtsp: failed to connect to '%s'\n", s->host);
        rtsp_close( rtsp );
        return -1;
    }

    s->server_state = RTSP_CONNECTED;

    /* now lets send an options request. */
    rtsp_schedule_field( rtsp, "CSeq: 1");
    rtsp_schedule_field( rtsp, s->user_agent);
    rtsp_schedule_field( rtsp, "ClientChallenge: "
                               "9e26d33f2984236010ef6253fb1887f7");
    rtsp_schedule_field( rtsp, "PlayerStarttime: [28/03/2003:22:50:23 00:00]");
    rtsp_schedule_field( rtsp, "CompanyID: KnKV4M4I/B2FjJ1TToLycw==" );
    rtsp_schedule_field( rtsp, "GUID: 00000000-0000-0000-0000-000000000000" );
    rtsp_schedule_field( rtsp, "RegionData: 0" );
    rtsp_schedule_field( rtsp, "ClientID: "
                               "Linux_2.4_6.0.9.1235_play32_RN01_EN_586" );
    /*rtsp_schedule_field( rtsp, "Pragma: initiate-session" );*/
    rtsp_request_options( rtsp, NULL );

    return 0;
}
Пример #4
0
static void rtsp_parse_thread(void *rtsp_handle2)
{
	SDP_Info* sdp_info=NULL;
	
		RTSP_HANDLE *rtsp_handle = (RTSP_HANDLE *)rtsp_handle2;
		
//		char url[1024] = {0};
		
		char buff[512] = {0};
		rtsp_client_t *handle = rtsp_handle->client;
		int ret = 0;
		int x = 0;
		if(handle == NULL)
		{
			PRINTF("rtsp_parse_thread:ERROR,the rtsp handle is NULL\n");
			goto MSG_EXIT;
		}

		ret = 	reach_rtsp_connect(handle, rtsp_handle->rtsp_url,"User-Agent: LibVLC/2.0.1 (LIVE555 Streaming Media v2011.12.23)" );
		if(ret != 0)
		{
			PRINTF("rtsp_parse_thread:ERROR!!!!!!!!! reach_rtsp_connect\n");
			goto MSG_EXIT;
		}
	
		PRINTF("rtsp_parse_thread:*** rtsp_request_describe ***\n");
		rtsp_schedule_field( handle, "Accept: application/sdp");	
		ret = rtsp_request_describe(handle,NULL);		
		if(ret != 200)
		{
			PRINTF("rtsp_parse_thread:rtsp_request_describe ERROR!\n");
			goto MSG_EXIT;
		}
		
		PRINTF("\nrtsp_parse_thread:*** rtsp_recv_sdp_info ***\n");
		ret =rtsp_recv_sdp_info(handle,rtsp_handle->sdp_info,sizeof(rtsp_handle->sdp_info));	
		if(ret != 0)
		{
			PRINTF("rtsp_parse_thread:rtsp_request_describe ERROR! \n");
			goto MSG_EXIT;
		}
		PRINTF("rtsp_parse_thread:sdp_info=#%s#",rtsp_handle->sdp_info);

		/** sdp info **/
		sdp_info = parse_sdp(rtsp_handle->sdp_info,strlen(rtsp_handle->sdp_info));
		if(sdp_info==NULL){
			PRINTF("rtsp_parse_thread:parse_sdp ERROR\n");
			goto MSG_EXIT; ;
		}
		if( sdp_info->video_port == 0 )
			sdp_info->video_port = 8436;
	
		if(sdp_info->audio_port == 0 )
			sdp_info->audio_port = sdp_info->video_port+2;
		
		PRINTF("rtsp_parse_thread:*** rtsp_request_setup ***\n");
		sprintf(buff,"Transport: RTP/AVP;unicast;client_port=%d-%d",
			sdp_info->video_port,sdp_info->video_port+1);
		rtsp_schedule_field( handle, buff);	
		memset(buff,0,sizeof(buff));
		sprintf(buff,"rtsp://%s:554/trackID=1",sdp_info->IP);
		ret = rtsp_request_setup(handle,buff); //"rtsp://192.168.4.161:554/trackID=1");
		if(ret != 200)
		{
			PRINTF("rtsp_parse_thread:rtsp_request_setup ERROR! \n");
			goto MSG_EXIT;
		}		
		
		PRINTF("rtsp_parse_thread:*** rtsp_request_setup ***\n");
		memset(buff,0,sizeof(buff));
		sprintf(buff,"Transport: RTP/AVP;unicast;client_port=%d-%d",
			sdp_info->audio_port,sdp_info->audio_port+1);
		rtsp_schedule_field( handle,buff);// "Transport: RTP/AVP;unicast;client_port=8502-8503");	
		memset(buff,0,sizeof(buff));
		sprintf(buff,"rtsp://%s:554/trackID=2",sdp_info->IP);
		ret = rtsp_request_setup(handle, buff);//"rtsp://192.168.4.161:554/trackID=2");	
		if(ret != 200)
		{
			PRINTF("rtsp_parse_thread: rtsp_request_setup ERROR!\n");
			goto MSG_EXIT;
		}

		PRINTF("rtsp_parse_thread:*** rtsp_request_play ***\n");
		rtsp_schedule_field( handle, "Range: npt=0.000-");	
		ret = rtsp_request_play(handle, NULL);			
		if(ret != 200)
		{
			PRINTF("rtsp_parse_thread:rtsp_request_play ERROR! \n");
			goto MSG_EXIT;
		}	
				
		//add rtp handle
		ret = rtsp_rtp_recv_start(rtsp_handle);
		if( ret < 0){
			PRINTF("rtsp_parse_thread:rtsp_rtp_recv_start ERROR! \n");
			goto MSG_EXIT;
			}
		

    while(1)
    {
    	
    	//if need stop
    	if(rtsp_handle ->status == 1 
			|| rtsp_handle->video_handle == NULL 
			|| rtsp_handle->audio_handle == NULL)
    	{
    		rtsp_rtp_recv_stop(rtsp_handle);
			Sleep(1000);
    		rtsp_request_tearoff(handle, "");
    		Sleep(1000);
    		break;
    	}
    	Sleep(3000);
    	if(x++ != DEFAULT_HEARTBIT_TIME/3)
    		continue;
  		x =0;
#if 0
		ret = 	rtsp_request_getparameter(handle, NULL);
		PRINTF("rtsp_request_play ret =%d\n",ret);	
		if(ret != 200)
		{
			PRINTF("ERROR! rtsp_request_play\n");
			rtsp_rtp_recv_stop( rtsp_handle);
			break;
		}
#endif
    }       	

EXIT:
	if(handle)
		rtsp_close(handle );          	
	if(rtsp_handle)
	{
		rtsp_handle->fCCEvent=NULL;
		rtsp_handle->fGetAudioEs=NULL;
		rtsp_handle->fGetVideoEs=NULL;
		free(rtsp_handle);
		rtsp_handle = NULL;
		}
	return;
MSG_EXIT:
	if(rtsp_handle != NULL  && rtsp_handle->fCCEvent)
		rtsp_handle->fCCEvent(RTSP_STREAM,MSG_RECV_FAIL);
	
	if(handle)
		rtsp_close(handle );          	
	if(rtsp_handle)
	{
		rtsp_handle->fCCEvent=NULL;
		rtsp_handle->fGetAudioEs=NULL;
		rtsp_handle->fGetVideoEs=NULL;
		free(rtsp_handle);
		rtsp_handle = NULL;
		}
	return;
}
Пример #5
0
int main(int argc, char **argv)
{

        int opt;
        char *url, *out = "nemesi.dump";
        FILE *outfile = NULL;
        rtsp_ctrl *ctl;
        rtsp_session *sess;
        rtsp_medium *med;
        nms_rtsp_hints rtsp_hints = { -1 };
        sdp_attr *attr;
        RTSP_Error reply;

        if (argc < 2) {
                fprintf(stderr, "\tPlease specify at least an url.\n");
                fprintf(stderr,
                        "\tUsage: %s [-f outputfile ] [-p rtp_port] [-t url\n",
                        argv[0]);
                exit(1);
        }

#ifndef WIN32
        while ((opt = getopt(argc, argv, "df:p:v:")) != -1) {
                switch (opt) {

                        /*  Set output file  */
                case 'f':
                        out = strdup(optarg);
                        break;
                        /*  Set rtp port  */
                case 'p':
                        rtsp_hints.first_rtp_port = atoi(optarg);
                        break;
                        /*  Set verbosity  */
                case 'v':
                        nms_verbosity_set(atoi(optarg));
                        break;
                        /* Unknown option  */
                case '?':
                        fprintf(stderr, "\n  Unknown option `-%c'.\n", optopt);
                        fprintf(stderr,
                                "\tUsage: %s [-f outputfile ] [-d] url\n\n",
                                argv[0]);

                        return 1;
                }
        }
#endif

        outfile = fopen(out, "rb");
        if (outfile == NULL)
                outfile = stderr;

        url = argv[argc - 1];

        fprintf(stderr, "URL %s.\n", url);

        /* initialize the rtsp state machine, starts the rtsp and the rtp threads
         * the hints available are just one:
         *  - the first port to use (instead of picking one at random)
         */
        if ((ctl = rtsp_init(&rtsp_hints)) == NULL) {
                fprintf(stderr, "Cannot init rtsp.\n");
                return 1;
        }

        if (rtsp_open(ctl, url)) {
                fprintf(stderr, "rtsp_open failed.\n");
                // die
                return 1;
        }

        // you must call rtsp_wait after issuing any command
        reply = rtsp_wait(ctl);
        printf("OPEN: Received reply from server: %s\n", reply.message.reply_str);

        // Get the session information
        sess = ctl->rtsp_queue;

        if (!sess) {
                fprintf(stderr, "No session available.\n");
                return 1;
        }

        while (sess) {        // foreach session...
                fprintf(outfile, "\tSession %s\n", sess->pathname);
                fprintf(outfile, "\tSession Duration %s\n", sess->info->t);
                for (attr = sess->info->attr_list;
                                attr;
                                attr = attr->next) {
                        fprintf(outfile, "\t* %s %s\n", attr->name, attr->value);
                }

                med = sess->media_queue;
                while (med) {    //... foreach medium
                        switch (med->medium_info->media_type) {
                                // Just care about audio and video
                        case 'A':
                        case 'V':
                                fprintf(outfile, "\tTransport %s\n",
                                        med->medium_info->transport);
                                fprintf(outfile, "\tMedia Type %s\n",
                                        (med->medium_info->media_type == 'A'?
                                         "Audio" : "Video"));
                                fprintf(outfile, "\tMedia format %s\n",
                                        med->medium_info->fmts);
                                break;
                        default:
                                //do nothing
                                break;
                        }

                        // attributes are already parsed, get them from the list
                        for (attr = med->medium_info->attr_list;
                                        attr;
                                        attr = attr->next) {
                                fprintf(outfile, "\t* %s %s\n", attr->name, attr->value);
                        }

                        med = med->next;
                }
                sess = sess->next;
        }

        /*
         * Close the rtsp connection, we are polite
         */

        rtsp_close(ctl);
        reply = rtsp_wait(ctl);
        printf("CLOSE: Received reply from server: %s\n", reply.message.reply_str);

        /*
         * Kill the threads, dealloc everything.
         */

        rtsp_uninit(ctl);

        return 0;
}
Пример #6
0
rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) {

  rtsp_session_t *rtsp_session = calloc(1, sizeof(rtsp_session_t));
  xine_t *xine = stream->xine;
  char *server;
  char *mrl_line=strdup(mrl);
  rmff_header_t *h;
  int bandwidth_id;
  uint32_t bandwidth;

  bandwidth_id = xine->config->register_enum(xine->config, "media.network.bandwidth", 10,
			      rtsp_bandwidth_strs,
			      _("network bandwidth"),
			      _("Specify the bandwidth of your internet connection here. "
			        "This will be used when streaming servers offer different versions "
              "with different bandwidth requirements of the same stream."),
			      0, NULL, NULL);
  bandwidth = rtsp_bandwidths[bandwidth_id];

  rtsp_session->recv = xine_buffer_init(BUF_SIZE);

connect:

  /* connect to server */
  rtsp_session->s=rtsp_connect(stream, mrl_line, NULL);
  if (!rtsp_session->s)
  {
    xprintf(stream->xine, XINE_VERBOSITY_LOG,
	    _("rtsp_session: failed to connect to server %s\n"), mrl_line);
    xine_buffer_free(rtsp_session->recv);
    free(rtsp_session);
    return NULL;
  }

  /* looking for server type */
  if (rtsp_search_answers(rtsp_session->s,"Server"))
    server=strdup(rtsp_search_answers(rtsp_session->s,"Server"));
  else {
    if (rtsp_search_answers(rtsp_session->s,"RealChallenge1"))
      server=strdup("Real");
    else
      server=strdup("unknown");
  }

  if (strstr(server,"Real") || strstr(server,"Helix"))
  {
    /* we are talking to a real server ... */

    h=real_setup_and_get_header(rtsp_session->s, bandwidth);
    if (!h) {
      /* got an redirect? */
      if (rtsp_search_answers(rtsp_session->s, "Location"))
      {
        free(mrl_line);
	mrl_line=strdup(rtsp_search_answers(rtsp_session->s, "Location"));
        xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "rtsp_session: redirected to %s\n", mrl_line);
	rtsp_close(rtsp_session->s);
	free(server);
	goto connect; /* *shudder* i made a design mistake somewhere */
      } else
      {
        xprintf(stream->xine, XINE_VERBOSITY_LOG,
		_("rtsp_session: session can not be established.\n"));
        rtsp_close(rtsp_session->s);
        xine_buffer_free(rtsp_session->recv);
        free(rtsp_session);
        return NULL;
      }
    }

	  rtsp_session->header_left =
    rtsp_session->header_len  = rmff_dump_header(h,rtsp_session->header,HEADER_SIZE);
    if (rtsp_session->header_len < 0) {
      xprintf (stream->xine, XINE_VERBOSITY_LOG,
	       _("rtsp_session: rtsp server returned overly-large headers, session can not be established.\n"));
      goto session_abort;
    }

    xine_buffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len);
    rtsp_session->recv_size = rtsp_session->header_len;
    rtsp_session->recv_read = 0;

  } else
  {
    xprintf(stream->xine, XINE_VERBOSITY_LOG,
	    _("rtsp_session: rtsp server type '%s' not supported yet. sorry.\n"), server);
    session_abort:
    rtsp_close(rtsp_session->s);
    free(server);
    xine_buffer_free(rtsp_session->recv);
    free(rtsp_session);
    return NULL;
  }
  free(server);

  return rtsp_session;
}
Пример #7
0
rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_agent) {

  rtsp_t *s = malloc(sizeof(rtsp_t));
  char *mrl_ptr=strdup(mrl);
  char *slash, *colon, *amp;
  int hostend, i;
  size_t pathbegin;

  if (strncmp(mrl,"rtsp://",7))
  {
    xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp: bad mrl: %s\n"), mrl);
    free(s);
    return NULL;
  }

  mrl_ptr+=7;

  for (i=0; i<MAX_FIELDS; i++) {
    s->answers[i]=NULL;
    s->scheduled[i]=NULL;
  }

  s->stream=stream;
  s->host=NULL;
  s->port=554; /* rtsp standard port */
  s->path=NULL;
  s->mrl=NULL;
  s->mrl=strdup(mrl);

  s->server=NULL;
  s->server_state=0;
  s->server_caps=0;

  s->cseq=0;
  s->session=NULL;

  if (user_agent)
    s->user_agent=strdup(user_agent);
  else
    s->user_agent=strdup("User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)");

  amp  =strchr(mrl_ptr,'@');
  slash=strchr(mrl_ptr,'/');
  colon=strchr(mrl_ptr,':');

  if (amp && (!slash || amp < slash)) {
    char *username = NULL, *password = NULL;
    /* xxx@host:port/ */
    if (colon && colon < amp) {
      /* xxx:yyy@host:port/ */
      username = strndup(mrl_ptr, colon - mrl_ptr);
      password = strndup(colon + 1, amp - colon - 1);
    } else {
      username = strndup(mrl_ptr, amp - mrl_ptr);
    }

    mrl_ptr = amp + 1;
    slash = strchr(mrl_ptr, '/');
    colon = strchr(mrl_ptr, ':');

    if (username) {
      char *auth;
      rtsp_basicauth(username, password, &auth);
      s->auth = _x_asprintf("Authorization: Basic %s", auth);
      free(auth);
    }
    free(username);
    free(password);
  }

  if(!slash) slash=mrl_ptr+strlen(mrl_ptr)+1;
  if(!colon) colon=slash;
  if(colon > slash) colon=slash;

  pathbegin=slash-mrl_ptr;
  hostend=colon-mrl_ptr;

  s->host = strndup(mrl_ptr, hostend);

  if (pathbegin < strlen(mrl_ptr)) s->path=strdup(mrl_ptr+pathbegin+1);
  if (colon != slash) {
    char buffer[pathbegin-hostend];

    strncpy(buffer,mrl_ptr+hostend+1, pathbegin-hostend-1);
    buffer[pathbegin-hostend-1]=0;
    s->port=atoi(buffer);
    if (s->port < 0 || s->port > 65535) s->port = 554; /* rtsp standard port */
  }

  lprintf("got mrl: %s %i %s\n",s->host,s->port,s->path);

  s->s = _x_io_tcp_connect (stream, s->host, s->port);

  if (s->s < 0) {
    xprintf (stream->xine, XINE_VERBOSITY_LOG, _("rtsp: failed to connect to '%s'\n"), s->host);
    rtsp_close(s);
    return NULL;
  }

  s->server_state=RTSP_CONNECTED;

  /* now lets send an options request. */
  rtsp_schedule_field(s, "CSeq: 1");
  rtsp_schedule_field(s, s->user_agent);
  rtsp_schedule_field(s, "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7");
  rtsp_schedule_field(s, "PlayerStarttime: [28/03/2003:22:50:23 00:00]");
  rtsp_schedule_field(s, "CompanyID: KnKV4M4I/B2FjJ1TToLycw==");
  rtsp_schedule_field(s, "GUID: 00000000-0000-0000-0000-000000000000");
  rtsp_schedule_field(s, "RegionData: 0");
  rtsp_schedule_field(s, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586");
  /*rtsp_schedule_field(s, "Pragma: initiate-session");*/
  rtsp_request_options(s, NULL);

  return s;
}