Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
int rtsp_connect(struct rtsp_client * rtsp, const char * host,
		unsigned int port, const char * mrl)
{
	struct tcp_pcb * tp;
	in_addr_t host_addr;

	if (!inet_aton(host, (struct in_addr *)&host_addr)) {
		return -1;
	}

	if ((tp = tcp_alloc()) == NULL) {
		ERR("can't allocate socket!");
		return -1;
	}

	if (port == 0) {
		port = rtsp->port;
		if (port == 0)
			port = 554;
	}

	INF("RTSP://%s:%d/%s", host, port, mrl);

	if (tcp_connect(tp, host_addr, htons(port)) < 0) {
		ERR("can't connect to host!");
		tcp_close(tp);
		return -1;
	}

	rtsp->tcp = tp;
	rtsp->port = port;
	rtsp->host_addr = host_addr;
	rtsp->rtp.faddr = host_addr;
	rtsp->cseq = 1;

	strcpy(rtsp->host_name, host);
	strcpy(rtsp->media_name, mrl);

	if (rtsp_request_options(rtsp) < 0) {
		ERR("rtsp_request_options() failed!");
		return -1;
	}

	if (rtsp_request_describe(rtsp) < 0) {
		ERR("rtsp_request_describe() failed!");
		return -1;
	}

	if (rtsp_sdp_decode(rtsp) < 0) {
		ERR("rtsp_sdp_decode() failed!");
		return -1;
	}

	INF("Track:\"%s\"", rtsp->track_name);

	if (rtsp_request_setup(rtsp) < 0) {
		ERR("rtsp_request_setup() failed!");
		return -1;
	}

	if (rtsp_request_play(rtsp) < 0) {
		ERR("rtsp_request_play() failed!");
		return -1;
	}

	return 0;
}
rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth,
  char *username, char *password) {

  char *description=NULL;
  char *session_id=NULL;
  rmff_header_t *h = NULL;
  char *challenge1 = NULL;
  char challenge2[41];
  char checksum[9];
  char *subscribe = NULL;
  char *buf = xbuffer_init(256);
  char *mrl=rtsp_get_mrl(rtsp_session);
  unsigned int size;
  int status;
  uint32_t maxbandwidth = bandwidth;
  char* authfield = NULL;
  int i;

  /* get challenge */
  challenge1=rtsp_search_answers(rtsp_session,"RealChallenge1");
  if (!challenge1)
      goto out;
  challenge1=strdup(challenge1);
#ifdef LOG
  printf("real: Challenge1: %s\n", challenge1);
#endif

  /* set a reasonable default to get the best stream, unless bandwidth given */
  if (!bandwidth)
      bandwidth = 10485800;

  /* request stream description */
rtsp_send_describe:
  rtsp_schedule_field(rtsp_session, "Accept: application/sdp");
  sprintf(buf, "Bandwidth: %u", bandwidth);
  rtsp_schedule_field(rtsp_session, buf);
  rtsp_schedule_field(rtsp_session, "GUID: 00000000-0000-0000-0000-000000000000");
  rtsp_schedule_field(rtsp_session, "RegionData: 0");
  rtsp_schedule_field(rtsp_session, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586");
  rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1");
  rtsp_schedule_field(rtsp_session, "Language: en-US");
  rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup");
  if(authfield)
    rtsp_schedule_field(rtsp_session, authfield);
  status=rtsp_request_describe(rtsp_session,NULL);

  if (status == 401) {
    int authlen, b64_authlen;
    char *authreq;
    char* authstr = NULL;

    if (authfield) {
      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authorization failed, check your credentials\n");
      goto autherr;
    }
    if (!(authreq = rtsp_search_answers(rtsp_session,"WWW-Authenticate"))) {
      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: 401 but no auth request, aborting\n");
      goto autherr;
    }
    if (!username) {
      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: auth required but no username supplied\n");
      goto autherr;
    }
    if (!strstr(authreq, "Basic")) {
      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authenticator not supported (%s)\n", authreq);
      goto autherr;
    }
    authlen = strlen(username) + (password ? strlen(password) : 0) + 2;
    authstr = malloc(authlen);
    sprintf(authstr, "%s:%s", username, password ? password : "");
    authfield = malloc(authlen*2+22);
    strcpy(authfield, "Authorization: Basic ");
    b64_authlen = base64_encode(authstr, authlen, authfield+21, authlen*2);
    free(authstr);
    if (b64_authlen < 0) {
      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: base64 output overflow, this should never happen\n");
      goto autherr;
    }
    authfield[b64_authlen+21] = 0;
    goto rtsp_send_describe;
  }
autherr:

  if (authfield)
     free(authfield);

  if ( status<200 || status>299 )
  {
    char *alert=rtsp_search_answers(rtsp_session,"Alert");
    if (alert) {
      mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: got message from server:\n%s\n",
        alert);
    }
    rtsp_send_ok(rtsp_session);
    goto out;
  }

  /* receive description */
  size=0;
  if (!rtsp_search_answers(rtsp_session,"Content-length"))
    mp_msg(MSGT_STREAM, MSGL_WARN, "real: got no Content-length!\n");
  else
    size=atoi(rtsp_search_answers(rtsp_session,"Content-length"));

  // as size is unsigned this also catches the case (size < 0)
  if (size > MAX_DESC_BUF) {
    mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: Content-length for description too big (> %uMB)!\n",
            MAX_DESC_BUF/(1024*1024) );
    goto out;
  }

  if (!rtsp_search_answers(rtsp_session,"ETag"))
    mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: got no ETag!\n");
  else
    session_id=strdup(rtsp_search_answers(rtsp_session,"ETag"));

#ifdef LOG
  printf("real: Stream description size: %u\n", size);
#endif

  description=malloc(size+1);

  if( rtsp_read_data(rtsp_session, description, size) <= 0) {
    goto out;
  }
  description[size]=0;

  /* parse sdp (sdpplin) and create a header and a subscribe string */
  subscribe = xbuffer_init(256);
  strcpy(subscribe, "Subscribe: ");
  h=real_parse_sdp(description, &subscribe, bandwidth);
  if (!h) {
    goto out;
  }
  rmff_fix_header(h);

#ifdef LOG
  printf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
    h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);
#endif

  /* setup our streams */
  real_calc_response_and_checksum (challenge2, checksum, challenge1);
  buf = xbuffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32);
  sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum);
  rtsp_schedule_field(rtsp_session, buf);
  buf = xbuffer_ensure_size(buf, strlen(session_id) + 32);
  sprintf(buf, "If-Match: %s", session_id);
  rtsp_schedule_field(rtsp_session, buf);
  rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play");
  buf = xbuffer_ensure_size(buf, strlen(mrl) + 32);
  sprintf(buf, "%s/streamid=0", mrl);
  rtsp_request_setup(rtsp_session,buf,NULL);

  /* Do setup for all the other streams we subscribed to */
  for (i = 1; i < h->prop->num_streams; i++) {
    rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play");
    buf = xbuffer_ensure_size(buf, strlen(session_id) + 32);
    sprintf(buf, "If-Match: %s", session_id);
    rtsp_schedule_field(rtsp_session, buf);

    buf = xbuffer_ensure_size(buf, strlen(mrl) + 32);
    sprintf(buf, "%s/streamid=%d", mrl, i);
    rtsp_request_setup(rtsp_session,buf,NULL);
  }
  /* set stream parameter (bandwidth) with our subscribe string */
  rtsp_schedule_field(rtsp_session, subscribe);
  rtsp_request_setparameter(rtsp_session,NULL);

  /* set delivery bandwidth */
  if (maxbandwidth) {
      sprintf(buf, "SetDeliveryBandwidth: Bandwidth=%u;BackOff=0", maxbandwidth);
      rtsp_schedule_field(rtsp_session, buf);
      rtsp_request_setparameter(rtsp_session,NULL);
  }

  {
    int s_ss = 0, s_ms = 0, e_ss = 0, e_ms = 0;
    char *str;
    if ((str = rtsp_get_param(rtsp_session, "start"))) {
      convert_timestamp(str, &s_ss, &s_ms);
      free(str);
    }
    if ((str = rtsp_get_param(rtsp_session, "end"))) {
      convert_timestamp(str, &e_ss, &e_ms);
      free(str);
    }
    str = buf + sprintf(buf, s_ms ? "%s%d.%d-" : "%s%d-", "Range: npt=", s_ss, s_ms);
    if (e_ss || e_ms)
      sprintf(str, e_ms ? "%d.%d" : "%d", e_ss, e_ms);
  }
  rtsp_schedule_field(rtsp_session, buf);
  /* and finally send a play request */
  rtsp_request_play(rtsp_session,NULL);

out:
  subscribe = xbuffer_free(subscribe);
  buf = xbuffer_free(buf);
  free(description);
  free(session_id);
  free(challenge1);
  return h;
}
Ejemplo n.º 4
0
/*
 * send DESCRIBE request
 * return value:   -1: failure   status_code: success
 */
static int real_rtsp_describe(struct stream_t *stream,char **description_ret)
{
    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;
    struct rtsp_ctrl_t *rtsp_ctrl = stream_ctrl->rtsp_ctrl;
    struct rtsp_header_t *rtsp_hdr = NULL;

    char *description = NULL;
    char *buffer = (char *)xmalloc(BUFSIZE_1K);
    char *field = NULL;
    int len = 0;
    int ret = 0;
    
    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);
    rtsp_set_field(rtsp_hdr, "Accept: application/sdp");
    rtsp_set_field(rtsp_hdr, real_useragent);
    rtsp_set_field(rtsp_hdr, "Require: com.real.retain-entity-for-setup");
  
    snprintf(buffer,BUFSIZE_1K - 1,"Bandwidth: %u",stream_ctrl->bandwidth);
    rtsp_set_field(rtsp_hdr,buffer); 
  
    rtsp_set_field(rtsp_hdr, "Language: en-US");
    rtsp_set_field(rtsp_hdr, "RegionData: 0");
    rtsp_set_field(rtsp_hdr, real_clientid);
    rtsp_set_field(rtsp_hdr, "GUID: 00000000-0000-0000-0000-000000000000");
    rtsp_set_field(rtsp_hdr, "SupportsMaximumASMBandwidth: 1");
  
  
    rtsp_request_describe(rtsp_hdr,rtsp_ctrl->mrl);
    rtsp_send_request_and_free(stream,rtsp_hdr);
    
    rtsp_hdr = new_rtsp_header();
    ret = rtsp_recv_header(stream,rtsp_hdr);
    if(ret < 0) {
	free_rtsp_header(rtsp_hdr);
	goto failed;
    }
    
    /* NOT OK */
    if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { 
	display(MSDL_ERR,"DESCRIBE request returned: %d (%s)\n",
		rtsp_hdr->status_code,rtsp_hdr->reason_phrase);
	
	field = rtsp_get_field(rtsp_hdr,"Alert");
	if(field) {
	    while(*field == ' ') field++;
	    display(MSDL_ERR,"message from server --> %s\n",field);
	}
	free_rtsp_header(rtsp_hdr);
	goto failed;
    }

    len = 0;
    /* Content-length must be present */
    if((field = rtsp_get_field(rtsp_hdr,"Content-length")) != NULL) {
	while(*field == ' ') field++;
	len = atoi(field);
    }
    else { /* no Content-length */
	display(MSDL_ERR,"warning: No Content-length in fields!!\n");
    }
  
    if((field = rtsp_get_field(rtsp_hdr,"ETag")) != NULL) {
	while(*field == ' ') field++;
	rtsp_ctrl->etag = strdup(field);
    }
    else {
	display(MSDL_ERR,"warning: No ETag!!\n");
	rtsp_ctrl->etag = NULL;
    }

    free_rtsp_header(rtsp_hdr);  
    
    /*
      copy description (sdp)
    */
    description = (char *)xmalloc(len + 1);
    if(read_data(stream,(uint8_t *)description,len) < 0) {
	goto failed;
    }
    description[len] = '\0';
  
    display(MSDL_DBG,"==================\n%s\n=(%d bytes)========\n",
	    description,(int)strlen(description));
    
    
    if(buffer) free(buffer);
    *description_ret = description;
    return ret;
    
  failed:
    if(description) free(description);
    if(buffer) free(buffer);
    *description_ret = NULL;
    return -1;
}