Exemple #1
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;
}
Exemple #2
0
/*****************************************************************************
 * Open: open the rtsp connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t *p_access = (access_t *)p_this;
    access_sys_t *p_sys;
    char* psz_server = NULL;
    int i_result;

    if( !p_access->psz_access || (
        strncmp( p_access->psz_access, "rtsp", 4 ) &&
        strncmp( p_access->psz_access, "pnm", 3 )  &&
        strncmp( p_access->psz_access, "realrtsp", 8 ) ))
    {
            return VLC_EGENERIC;
    }

    p_access->pf_read = NULL;
    p_access->pf_block = BlockRead;
    p_access->pf_seek = Seek;
    p_access->pf_control = Control;
    p_access->info.i_pos = 0;
    p_access->info.b_eof = false;
    p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;
    p_sys->p_rtsp = malloc( sizeof( rtsp_client_t) );
    if( !p_sys->p_rtsp )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    p_sys->p_header = NULL;
    p_sys->p_rtsp->p_userdata = p_access;
    p_sys->p_rtsp->pf_connect = RtspConnect;
    p_sys->p_rtsp->pf_disconnect = RtspDisconnect;
    p_sys->p_rtsp->pf_read = RtspRead;
    p_sys->p_rtsp->pf_read_line = RtspReadLine;
    p_sys->p_rtsp->pf_write = RtspWrite;

    i_result = rtsp_connect( p_sys->p_rtsp, p_access->psz_location, 0 );
    if( i_result )
    {
        msg_Dbg( p_access, "could not connect to: %s", p_access->psz_location );
        free( p_sys->p_rtsp );
        p_sys->p_rtsp = NULL;
        goto error;
    }

    msg_Dbg( p_access, "rtsp connected" );

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

    if( strstr( psz_server, "Real" ) || strstr( psz_server, "Helix" ) )
    {
        uint32_t bandwidth = 10485800;
        rmff_header_t *h;

        msg_Dbg( p_access, "found a real/helix rtsp server" );

        if( !(h = real_setup_and_get_header( p_sys->p_rtsp, bandwidth )) )
        {
            /* Check if we got a redirect */
            if( rtsp_search_answers( p_sys->p_rtsp, "Location" ) )
            {
                msg_Dbg( p_access, "redirect: %s",
                         rtsp_search_answers(p_sys->p_rtsp, "Location") );
                msg_Warn( p_access, "redirect not supported" );
                goto error;
            }


            msg_Err( p_access, "rtsp session can not be established" );
            dialog_Fatal( p_access, _("Session failed"), "%s",
                    _("The requested RTSP session could not be established.") );
            goto error;
        }

        p_sys->p_header = block_Alloc( 4096 );
        p_sys->p_header->i_buffer =
            rmff_dump_header( h, (char *)p_sys->p_header->p_buffer, 1024 );
        rmff_free_header( h );
    }
    else
    {
        msg_Warn( p_access, "only real/helix rtsp servers supported for now" );
        goto error;
    }

    free( psz_server );
    return VLC_SUCCESS;

 error:
    free( psz_server );
    Close( p_this );
    return VLC_EGENERIC;
}
Exemple #3
0
/*
 * start rtsp streaming.
 * 
 *    return value :   negative or 0  ... error
 *                                 1  ... success
 */
int rtsp_streaming_start(struct stream_t *stream)
{
    
    struct rtsp_header_t *rtsp_answer = NULL;

    int header_size;
  
    char *answer = NULL; /* temporary pointer */
    char *server = NULL;
    char *redirected = NULL;

    stream->stream_ctrl->status = STREAMING_HANDSHAKING;

    if(stream->dlopts->dl_protocol == RTSP_WMS) {
	server = strdup("WMServer");
    }
    else { /* still don't know which rtsp protocol, or REAL specified (need challenge) */
	
	stream->netsock->sock = rtsp_connect(stream);
	if(stream->netsock->sock < 0) {
	    display(MSDL_ERR,"cannot establish rtsp connection\n");
	    goto failed;
	}
	
	real_rtsp_options(stream,&rtsp_answer);

	if(rtsp_answer == NULL) {
	    display(MSDL_ERR,"rtsp connection failed\n");
	    goto failed;
	}
	
	/* get server name */
	if((answer = rtsp_get_field(rtsp_answer,"Server")) != NULL) {
	    while(*answer == ' ') answer++;  /* skip space */
	    server = strdup(answer);
	}
	else {
	    if((rtsp_get_field(rtsp_answer,"RealChallenge1")) != NULL) {
		server = strdup("Real");
	    }
	    else {
		server = strdup("Unknown Server");
	    }
	}
    }
  
    /* real or helix server (supported) */
    if(strstr(server,"Real") || strstr(server,"Helix")) {
	
	/* real-rtsp */
	struct rmff_header_t *rmff_header = NULL;	
	int ret = 0;

	/* connection is already setup, by real_rtsp_options called above */
	/* this is the function to do almost all setup process */
	ret = real_setup_and_get_header(stream,&rmff_header);
	
	if((!rmff_header) || (ret <= 0)) { /*  NOT OK  */
	    if((answer = rtsp_get_field(rtsp_answer,"Location")) != NULL) {
		/* redirected */
		while(*answer == ' ') answer++;
		
		redirected = strdup(answer);
		display(MSDL_NOR,"redirected to %s\n",redirected);
		/*
		  TODO redirection support
		  and I have never seen example...
		*/
		goto failed;
	    }
	    else {
		display(MSDL_ERR,"real/helix connection not established\n");
		goto failed;
	    }
	}
    
	/* OK, connection established */
	
	header_size = rmff_dump_header(rmff_header,
				       stream->stream_ctrl->write_buffer);
	stream->stream_ctrl->write_data_len = header_size;
    
	display(MSDL_VER,"rmff_header_size = %d\n",header_size);

	
	/* All Green */
	stream->stream_ctrl->rtsp_ctrl->rmff_header = rmff_header;
	stream->stream_ctrl->file_size     = rmff_header->data->size;
	stream->stream_ctrl->total_packets = rmff_header->data->num_packets;

	stream->stream_ctrl->rtsp_ctrl->get_media_packet = real_rdt_get_media_packet;
	/* to distinguish which rtsp */
	stream->stream_ctrl->rtsp_ctrl->rtsp_protocol = RTSP_REAL_PROTOCOL;
	/* for msdl function to know protocol */
	stream->stream_ctrl->protocol = RTSP_REAL;

    }
    else if(strstr(server,"WMServer")) {
	
	/* try rtsp-wms */
	struct asf_headerinfo_t *asf_headerinfo = NULL;
	int ret = 0;
	
	/*
	 * Clean up first.
	 */
	if(stream->netsock->sock) {
	    close(stream->netsock->sock);
	}
	
	/* free rtsp_ctrl_t */
	free_rtsp_ctrl_t(stream->stream_ctrl->rtsp_ctrl);
	stream->stream_ctrl->rtsp_ctrl = new_rtsp_ctrl_t();
	/* free serverinfo_t */
	free_serverinfo_t(stream->serverinfo);
	stream->serverinfo = new_serverinfo_t();
	
	/* DO NOT MESS WITH
	 * stream_t->netsock,
	 * stream_t->url,
	 * stream_t->dlopts,
	 * stream_t->resumeinfo,
	 * these are still valid (or just nothing (resumeinfo))
	 */

	/* re-establish rtsp connection for WMServer */
	stream->netsock->sock = rtsp_connect(stream);

	if(stream->netsock->sock < 0) {
	    /*
	      couldn't connect for some reason.
	      (rtsp port probably closed)
	     */
	    display(MSDL_ERR,"rtsp-wms connection not established\n");
	    display(MSDL_ERR,"server probably does not accept rtsp\n"
		    "retry using mmst protocol\n");

	    stream->stream_ctrl->status = STREAMING_OTHER_PROTOCOL;
	    stream->stream_ctrl->retry_protocol = MMST;	    
	    goto failed;
	}

    
	ret = wmserver_setup_and_get_header(stream,&asf_headerinfo);

	if(ret == 0) { /* retry    */
	    /* probably non-wmserver */
	    display(MSDL_ERR,"server probably does not accept rtsp\n"
		    "retry using mmst protocol\n",server);
	    stream->stream_ctrl->status = STREAMING_OTHER_PROTOCOL;
	    stream->stream_ctrl->retry_protocol = MMST;	    
	    
	    goto failed;
	}
	else if((!asf_headerinfo) || (ret < 0)) {       /* no retry */
	    display(MSDL_ERR,"rtsp setup failed\n");
	    goto failed;
	}

	
	/* All Green */
	stream->stream_ctrl->rtsp_ctrl->asf_headerinfo = asf_headerinfo;    /* set infomation */
	stream->stream_ctrl->packet_length = asf_headerinfo->fileh->max_packet_size;
	stream->stream_ctrl->file_size = asf_headerinfo->fileh->file_size;
	stream->stream_ctrl->total_packets = asf_headerinfo->fileh->num_packets;

	stream->stream_ctrl->rtsp_ctrl->get_media_packet = wmserver_rtp_get_media_packet;

	/* distinguish which rtsp */
	stream->stream_ctrl->rtsp_ctrl->rtsp_protocol = RTSP_WMS_PROTOCOL;
	/* for msdl function to know protocol */
	stream->stream_ctrl->protocol = RTSP_WMS;
	
    }
    else { /* unsupported servers */
	display(MSDL_ERR,"server type [%s] not supported\n",server);
	
	stream->stream_ctrl->rtsp_ctrl->rtsp_protocol = RTSP_UNKNOWN_PROTOCOL;
	goto failed;
    }

    
    if(server) free(server);
    if(rtsp_answer) free_rtsp_header(rtsp_answer);
    if(redirected) free(redirected);
  
    stream->stream_ctrl->status = STREAMING_DOWNLOADING;
    
    return 1; /* success */
  
  failed:
    if(server)      free(server);
    if(rtsp_answer) free_rtsp_header(rtsp_answer);
    if(redirected)  free(redirected);
    return -1;
}