示例#1
0
int play_cgi(struct httpctl * ctl)
{
	strcpy(rtsp_host, http_query_lookup(ctl, "host"));
	strcpy(rtsp_media, http_query_lookup(ctl, "mrl"));
	rtsp_port = atoi(http_query_lookup(ctl, "port"));
	audio_level = atoi(http_query_lookup(ctl, "vol"));
	if (audio_level > 800)
		audio_level = 800;

	if (rtsp_connect(&rtsp, rtsp_host, rtsp_port, rtsp_media) < 0) {
		int code;

		WARN("RTSP connection failed!");
		send_play_form(ctl);
		send_error(ctl, "RTSP playback failed");
		if ((code = rtsp_response_code(&rtsp)) > 200) {
			http_send(ctl, rtsp_iframe_html, sizeof(rtsp_iframe_html) - 1);
		}
	} else {
		audio_gain_set(audio_level * Q15(1.0) / 100);
		send_stop_form(ctl);
	}

	return http_send(ctl, footer_html, sizeof(footer_html) - 1);
}
示例#2
0
int netcam_setup_rtsp(netcam_context_ptr netcam, struct url_t *url)
{
  struct context *cnt = netcam->cnt;
  const char *ptr;
  
  netcam->caps.streaming = NCS_RTSP;
  netcam->rtsp = rtsp_new_context();
  if (netcam->rtsp == NULL) {
    MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: unable to create rtsp context");
    return -1;
  }
  
  /*
   * Allocate space for a working string to contain the path.
   * The extra 5 is for "://", ":" and string terminator.
   */
  
  // force port to a sane value
  if (netcam->connect_port > 65536) {
    netcam->connect_port = 65536;
  } else if (netcam->connect_port < 0) {
    netcam->connect_port = 0;
  }
  ptr = mymalloc(strlen(url->service) + strlen(netcam->connect_host)
		 + 5 + strlen(url->path) + 5);
  sprintf((char *)ptr, "%s://%s:%d%s", url->service,
	  netcam->connect_host, netcam->connect_port, url->path);
  
  netcam->rtsp->path = (char *)ptr;
  
  if (cnt->conf.netcam_userpass != NULL) {
    ptr = cnt->conf.netcam_userpass;
  } else {
    ptr = url->userpass;  /* Don't set this one NULL, gets freed. */
  }
  
  if (ptr != NULL) {
    char *cptr;
    
    if ((cptr = strchr(ptr, ':')) == NULL) {
      netcam->rtsp->user = mystrdup(ptr);
    } else {
      netcam->rtsp->user = mymalloc((cptr - ptr));
      memcpy(netcam->rtsp->user, ptr,(cptr - ptr));
      netcam->rtsp->pass = mystrdup(cptr + 1);
    }
  }

  netcam_url_free(url);

  /*
   * The RTSP context should be all ready to attempt a connection with
   * the server, so we try ....
   */
  rtsp_connect(netcam);

  netcam->get_image = netcam_read_rtsp_image;

  return 0;
}
示例#3
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;
}
示例#4
0
static int netcam_read_rtsp_image(netcam_context_ptr netcam)
{
  if (netcam->rtsp == NULL) {
    if (rtsp_connect(netcam) < 0) {
      return -1;
    }
  }

  AVCodecContext *cc = netcam->rtsp->codec_context;
  AVFormatContext *fc = netcam->rtsp->format_context;
  netcam_buff_ptr buffer;

  /* Point to our working buffer. */
  buffer = netcam->receiving;
  buffer->used = 0;

  AVFrame *frame = avcodec_alloc_frame();

  AVPacket packet;
  
  av_init_packet(&packet);

  packet.data = NULL;
  packet.size = 0;

  int size_decoded = 0;
  static int usual_size_decoded = 0;

  while (size_decoded == 0 && av_read_frame(fc, &packet) >= 0) {

    if(packet.stream_index != netcam->rtsp->video_stream_index) {
      // not our packet, skip
      continue;
    }

    size_decoded = decode_packet(&packet, buffer, frame, cc);
  }

  if (size_decoded == 0) {
    // something went wrong, end of stream?
    MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "%s: invalid frame!");
    return -1;
  }

  if (size_decoded != usual_size_decoded) {
    MOTION_LOG(WRN, TYPE_NETCAM, SHOW_ERRNO, "%s: unusual frame size of %d!", size_decoded);
    usual_size_decoded = size_decoded;
  }

  // at this point, we are finished with the packet and frame, so free them.
  av_free_packet(&packet);
  av_free(frame);
  
  struct timeval curtime;
  
  if (gettimeofday(&curtime, NULL) < 0) {
    MOTION_LOG(WRN, TYPE_NETCAM, SHOW_ERRNO, "%s: gettimeofday");
  }
  
  netcam->receiving->image_time = curtime;
  
  /*
   * Calculate our "running average" time for this netcam's
   * frame transmissions (except for the first time).
   * Note that the average frame time is held in microseconds.
   */
  if (netcam->last_image.tv_sec) {
    netcam->av_frame_time = ((9.0 * netcam->av_frame_time) + 1000000.0 *
			     (curtime.tv_sec - netcam->last_image.tv_sec) +
			     (curtime.tv_usec- netcam->last_image.tv_usec)) / 10.0;
    
    MOTION_LOG(DBG, TYPE_NETCAM, NO_ERRNO, "%s: Calculated frame time %f",
	       netcam->av_frame_time);
  }
  
  netcam->last_image = curtime;
  
  netcam_buff *xchg;
  
  /*
   * read is complete - set the current 'receiving' buffer atomically
   * as 'latest', and make the buffer previously in 'latest' become
   * the new 'receiving'.
   */
  pthread_mutex_lock(&netcam->mutex);

  xchg = netcam->latest;
  netcam->latest = netcam->receiving;
  netcam->receiving = xchg;
  netcam->imgcnt++;
  
  /*
   * We have a new frame ready.  We send a signal so that
   * any thread (e.g. the motion main loop) waiting for the
   * next frame to become available may proceed.
   */
  pthread_cond_signal(&netcam->pic_ready);
  
  pthread_mutex_unlock(&netcam->mutex);
  
  return 0;
}
示例#5
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;
}
示例#6
0
文件: rtsp.c 项目: clkao/msdl
/*
 * 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;
}