예제 #1
0
파일: mpeg1dec.c 프로젝트: Cheeseness/ags
APEG_STREAM *apeg_open_stream_ex(void *ptr)
{
	APEG_LAYER *layer;

	Initialize_Decoder();

	layer = new_apeg_stream();
	if(!layer)
		return NULL;

	if(setjmp(jmp_buffer))
	{
		apeg_close_stream((APEG_STREAM*)layer);
		return NULL;
	}

	layer->ext_data.init = _init_func;
	layer->ext_data.request = _request_func;
	layer->ext_data.skip = _skip_func;
	layer->ext_data.ptr = ptr;

	layer->pf = pack_fopen_vtable(&ext_vtable, layer);
	if(!layer->pf)
		apeg_error_jump("Could not open stream");
	layer->buffer_type = USER_BUFFER;

	setup_stream(layer);

	return (APEG_STREAM*)layer;
}
예제 #2
0
파일: mpeg1dec.c 프로젝트: Cheeseness/ags
APEG_STREAM *apeg_open_memory_stream(void *mpeg_data, int data_len)
{
	APEG_LAYER *layer;

	Initialize_Decoder();

	layer = new_apeg_stream();
	if(!layer)
		return NULL;

	if(setjmp(jmp_buffer))
	{
		apeg_close_stream((APEG_STREAM*)layer);
		return NULL;
	}

	layer->mem_data.buf = mpeg_data;
	layer->mem_data.bytes_left = data_len;
	layer->pf = pack_fopen_vtable(&mem_vtable, layer);
	if(!layer->pf)
		apeg_error_jump("Could not open stream");

	layer->buffer_type = MEMORY_BUFFER;
	layer->buffer_size = data_len;

	setup_stream(layer);

	return (APEG_STREAM*)layer;
}
예제 #3
0
파일: mpeg1dec.c 프로젝트: Cheeseness/ags
// Open an MPEG or Ogg file. Returns a structure for stream manipulation.
APEG_STREAM *apeg_open_stream(const char *filename)
{
	APEG_LAYER *layer;

	// Initialize the decoder
	Initialize_Decoder();

	// Create a new stream structure
	layer = new_apeg_stream();
	if(!layer)
		return NULL;

	// Set the jump position in case the decoder faults on opening.
	if(setjmp(jmp_buffer))
	{
		apeg_close_stream((APEG_STREAM*)layer);
		return NULL;
	}

	// Copy the filename so we can (re)open the file when the buffer
	// gets initialized
	layer->fname = strdup(filename);
	if(!layer->fname)
		apeg_error_jump("Couldn't duplicate filename");

	// Set the buffer type and size
	layer->buffer_type = DISK_BUFFER;
	layer->buffer_size = F_BUF_SIZE;

	setup_stream(layer);

	return (APEG_STREAM*)layer;
}
예제 #4
0
/********************************************************************************
 *Function: search_stream
 *Description: Analyze the file by reading 1 chunk (default: 100MB) at a time and 
 *passing it to	search_chunk
 *Return: TRUE/FALSE
 **********************************************************************************/
int search_stream(f_state *s, f_info *i)
{
	u_int64_t		bytesread = 0;
	u_int64_t		f_offset = 0;
	u_int64_t		chunk_size = ((u_int64_t) s->chunk_size) * MEGABYTE;
	unsigned char	*buf = (unsigned char *)malloc(sizeof(char) * chunk_size);

	setup_stream(s, i);

	audit_layout(s);
#ifdef DEBUG
	printf("\n\t READING THE FILE INTO MEMORY\n");
#endif

	while ((bytesread = fread(buf, 1, chunk_size, i->handle)) > 0)
		{
		if (signal_caught == SIGTERM || signal_caught == SIGINT)
			{
			user_interrupt(s, i);
			printf("Cleaning up.\n");
			signal_caught = 0;
			}

#ifdef DEBUG
		printf("\n\tbytes_read:=%llu\n", bytesread);
#endif
		search_chunk(s, buf, i, bytesread, f_offset);
		f_offset += bytesread;
		if (!get_mode(s, mode_quiet))
			{
			fprintf(stderr, "*");

			//displayPosition(s,i,f_offset);
			}

		/*FIX ME***
	* We should jump back and make sure we didn't miss any headers that are 
	* bridged between chunks.  What is the best way to do this?\
  	*/
		}

	if (!get_mode(s, mode_quiet))
		{
		fprintf(stderr, "|\n");
		}

#ifdef DEBUG
	printf("\n\tDONE READING bytes_read:=%llu\n", bytesread);
#endif
	if (signal_caught == SIGTERM || signal_caught == SIGINT)
		{
		user_interrupt(s, i);
		printf("Cleaning up.\n");
		signal_caught = 0;
		}

	free(buf);
	return FALSE;
}
예제 #5
0
파일: stream.c 프로젝트: arn354/minisatip
char *describe_streams (sockets *s, char *req, char *sbuf, int size)
{
	char *str, *stream_id;
	int i, sidf, do_play = 0, streams_enabled = 0;
	streams *sid;
	int do_all = 1;

	if (s->sid == -1 && strchr(req, '?'))
		setup_stream(req, s);

	sidf = get_session_id(s->sid);
	sid = get_sid(s->sid);
	if(sid)
		do_play = sid->do_play;
//	else LOG_AND_RETURN(NULL, "No session associated with sock_id %d", s->sock_id);
		
	snprintf(sbuf,size-1,"v=0\r\no=- %010d %010d IN IP4 %s\r\ns=SatIPServer:1 %d %d %d\r\nt=0 0\r\n", sidf, sidf, get_sock_host(s->sock), getS2Adapters(), getTAdapters(), getCAdapters() );
	if(strchr(req, '?'))
		do_all = 0;
		
	if((stream_id = strstr(req, "stream=")))
	{
		do_all = 0;
		sid = get_sid(map_int(stream_id + 7, NULL) - 1);
		if(sid == NULL)
			return NULL;		
	}	
	
	if(do_all)
	{
		for( i=0; i<MAX_STREAMS; i++)
			if(st[i].enabled)
			{
				int slen=strlen(sbuf);
				streams_enabled ++;
				snprintf(sbuf + slen, size - slen - 1, "m=video %d RTP/AVP 33\r\nc=IN IP4 0.0.0.0\r\na=control:stream=%d\r\na=fmtp:33 %s\r\na=%s\r\n", 
					ntohs (st[i].sa.sin_port), i+1, describe_adapter(i, st[i].adapter), st[i].do_play?"sendonly":"inactive");
				if( size - slen < 10)LOG_AND_RETURN(sbuf, "DESCRIBE BUFFER is full");
			}
	}else{
		int slen = strlen(sbuf);
		snprintf(sbuf + slen, size - slen - 1, "m=video 0 RTP/AVP 33\r\nc=IN IP4 0.0.0.0\r\na=control:stream=%d\r\na=fmtp:33 %s\r\nb=AS:5000\r\na=%s\r\n", 
			sid->sid + 1, describe_adapter(sid->sid, sid->adapter), do_play?"sendonly":"inactive");
	}
	return sbuf;
}
예제 #6
0
파일: client.c 프로젝트: 0x00f/XSVF-Player
int main()
{
	if (setup_stream()) {
		exit(1);
	}

	xsvf_file = fopen("cram.xsvf","rb");

	while (1) {
		int n;
		char c;
		while (data_ready()>0) {
			read(serial_fd, &c, 1);
			if (process_command(c)>0) {
				goto sync_ok;
			}
		}
		printf("waiting for sync...\n");
		usleep(500000);
		c = 0;
		write(serial_fd, &c, 1);
		usleep(500000);
	}
sync_ok:
	printf("sync ok.\n");

	while (1) {
		char c;
		if (command_plus()) {
			break;
		}
		do {
			read(serial_fd, &c, 1);
		} while (process_command(c)<=0);
	}
	return 0;
}
예제 #7
0
/*
 * do ioctls and
 * send stuff down - dont care about
 * flow control
 */
static int
parsewput(
	queue_t *q,
	register mblk_t *mp
	)
{
	register int ok = 1;
	register mblk_t *datap;
	register struct iocblk *iocp;
	parsestream_t         *parse = (parsestream_t *)(void *)q->q_ptr;

	parseprintf(DD_WPUT,("parse: parsewput\n"));

	switch (mp->b_datap->db_type)
	{
	    default:
		putnext(q, mp);
		break;

	    case M_IOCTL:
		    iocp = (struct iocblk *)(void *)mp->b_rptr;
		switch (iocp->ioc_cmd)
		{
		    default:
			parseprintf(DD_WPUT,("parse: parsewput - forward M_IOCTL\n"));
			putnext(q, mp);
			break;

		    case CIOGETEV:
			/*
			 * taken from Craig Leres ppsclock module (and modified)
			 */
			datap = allocb(sizeof(struct ppsclockev), BPRI_MED);
			if (datap == NULL || mp->b_cont)
			{
				mp->b_datap->db_type = M_IOCNAK;
				iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL;
				if (datap != NULL)
				    freeb(datap);
				qreply(q, mp);
				break;
			}

			mp->b_cont = datap;
			*(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev;
			datap->b_wptr +=
				sizeof(struct ppsclockev) / sizeof(*datap->b_wptr);
			mp->b_datap->db_type = M_IOCACK;
			iocp->ioc_count = sizeof(struct ppsclockev);
			qreply(q, mp);
			break;

		    case PARSEIOC_ENABLE:
		    case PARSEIOC_DISABLE:
			    {
				    parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) |
					    (iocp->ioc_cmd == PARSEIOC_ENABLE) ?
					    PARSE_ENABLE : 0;
				    if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ?
						      M_PARSE : M_NOPARSE))
				    {
					    mp->b_datap->db_type = M_IOCNAK;
				    }
				    else
				    {
					    mp->b_datap->db_type = M_IOCACK;
				    }
				    qreply(q, mp);
				    break;
			    }

		    case PARSEIOC_TIMECODE:
		    case PARSEIOC_SETFMT:
		    case PARSEIOC_GETFMT:
		    case PARSEIOC_SETCS:
			if (iocp->ioc_count == sizeof(parsectl_t))
			{
				parsectl_t *dct = (parsectl_t *)(void *)mp->b_cont->b_rptr;

				switch (iocp->ioc_cmd)
				{
				    case PARSEIOC_TIMECODE:
					parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_TIMECODE\n"));
					ok = parse_timecode(dct, &parse->parse_io);
					break;

				    case PARSEIOC_SETFMT:
					parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETFMT\n"));
					ok = parse_setfmt(dct, &parse->parse_io);
					break;

				    case PARSEIOC_GETFMT:
					parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETFMT\n"));
					ok = parse_getfmt(dct, &parse->parse_io);
					break;

				    case PARSEIOC_SETCS:
					parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETCS\n"));
					ok = parse_setcs(dct, &parse->parse_io);
					break;
				}
				mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK;
			}
			else
			{
				mp->b_datap->db_type = M_IOCNAK;
			}
			parseprintf(DD_WPUT,("parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK"));
			qreply(q, mp);
			break;
		}
	}
	return 0;
}
예제 #8
0
/*ARGSUSED*/
static int
parseopen(
	queue_t *q,
	dev_t dev,
	int flag,
	int sflag
	)
{
	register parsestream_t *parse;
	static int notice = 0;

	parseprintf(DD_OPEN,("parse: OPEN\n"));

	if (sflag != MODOPEN)
	{			/* open only for modules */
		parseprintf(DD_OPEN,("parse: OPEN - FAILED - not MODOPEN\n"));
		return OPENFAIL;
	}

	if (q->q_ptr != (caddr_t)NULL)
	{
		u.u_error = EBUSY;
		parseprintf(DD_OPEN,("parse: OPEN - FAILED - EXCLUSIVE ONLY\n"));
		return OPENFAIL;
	}

#ifdef VDDRV
	parsebusy++;
#endif

	q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t));
	if (q->q_ptr == (caddr_t)0)
	{
		parseprintf(DD_OPEN,("parse: OPEN - FAILED - no memory\n"));
#ifdef VDDRV
		parsebusy--;
#endif
		return OPENFAIL;
	}
	WR(q)->q_ptr = q->q_ptr;

	parse = (parsestream_t *)(void *)q->q_ptr;
	bzero((caddr_t)parse, sizeof(*parse));
	parse->parse_queue     = q;
	parse->parse_status    = PARSE_ENABLE;
	parse->parse_ppsclockev.tv.tv_sec  = 0;
	parse->parse_ppsclockev.tv.tv_usec = 0;
	parse->parse_ppsclockev.serial     = 0;

	if (!parse_ioinit(&parse->parse_io))
	{
		/*
		 * ok guys - beat it
		 */
		kmem_free((caddr_t)parse, sizeof(parsestream_t));
#ifdef VDDRV
		parsebusy--;
#endif
		return OPENFAIL;
	}

	if (setup_stream(q, M_PARSE))
	{
		(void) init_linemon(q);	/* hook up PPS ISR routines if possible */

		parseprintf(DD_OPEN,("parse: OPEN - SUCCEEDED\n"));

		/*
		 * I know that you know the delete key, but you didn't write this
		 * code, did you ? - So, keep the message in here.
		 */
		if (!notice)
		{
#ifdef VDDRV
			printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", parsesync_vd.Drv_name);
#else
			printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A");
#endif
			notice = 1;
		}

		return MODOPEN;
	}
	else
	{
		kmem_free((caddr_t)parse, sizeof(parsestream_t));

#ifdef VDDRV
		parsebusy--;
#endif
		return OPENFAIL;
	}
}
예제 #9
0
/*ARGSUSED*/
static int
parseopen(
	  queue_t *q,
	  dev_t *dev,
	  int flag,
	  int sflag,
	  cred_t *credp
	  )
{
	register parsestream_t *parse;
	static int notice = 0;
  
	pprintf(DD_OPEN, "parse: OPEN - q=%x\n", q); 
  
	if (sflag != MODOPEN)
	{			/* open only for modules */
		pprintf(DD_OPEN, "parse: OPEN - FAILED - not MODOPEN\n"); 
		return EIO;
	}

	if (q->q_ptr != (caddr_t)NULL)
	{
		pprintf(DD_OPEN, "parse: OPEN - FAILED - EXCLUSIVE ONLY\n"); 
		return EBUSY;
	}

	q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t), KM_SLEEP);
	if (q->q_ptr == (caddr_t)0)
	{
		return ENOMEM;
	}

	pprintf(DD_OPEN, "parse: OPEN - parse area q=%x, q->q_ptr=%x\n", q, q->q_ptr); 
	WR(q)->q_ptr = q->q_ptr;
	pprintf(DD_OPEN, "parse: OPEN - WQ parse area q=%x, q->q_ptr=%x\n", WR(q), WR(q)->q_ptr); 
  
	parse = (parsestream_t *) q->q_ptr;
	bzero((caddr_t)parse, sizeof(*parse));
	parse->parse_queue     = q;
	parse->parse_status    = PARSE_ENABLE;
	parse->parse_ppsclockev.tv.tv_sec  = 0;
	parse->parse_ppsclockev.tv.tv_usec = 0;
	parse->parse_ppsclockev.serial     = 0;

	qprocson(q);

	pprintf(DD_OPEN, "parse: OPEN - initializing io subsystem q=%x\n", q); 

	if (!parse_ioinit(&parse->parse_io))
	{
		/*
		 * ok guys - beat it
		 */
		qprocsoff(q);

		kmem_free((caddr_t)parse, sizeof(parsestream_t));

		return EIO;
	}

	pprintf(DD_OPEN, "parse: OPEN - initializing stream q=%x\n", q); 

	if (setup_stream(q, M_PARSE))
	{
		(void) init_linemon(q);	/* hook up PPS ISR routines if possible */
		pprintf(DD_OPEN, "parse: OPEN - SUCCEEDED\n"); 

		/*
		 * I know that you know the delete key, but you didn't write this
		 * code, did you ? - So, keep the message in here.
		 */
		if (!notice)
		{
		  cmn_err(CE_CONT, "?%s: Copyright (c) 1993-2005, Frank Kardel\n", modlstrmod.strmod_linkinfo);
			notice = 1;
		}

		return 0;
	}
	else
	{
		qprocsoff(q);

		kmem_free((caddr_t)parse, sizeof(parsestream_t));

		return EIO;
	}
}
예제 #10
0
int
read_rtsp (sockets * s)
{
	char *arg[50];
	int cseq, la, i, rlen;
	char *proto, *transport = NULL, *useragent = NULL;
	int sess_id = 0;
	char buf[2000];
	streams *sid = get_sid(s->sid);

	if(s->buf[0]==0x24 && s->buf[1]<2)
	{
		if(sid)
			sid->rtime = s->rtime;

		int rtsp_len = s->buf[2]*256+s->buf[3];
		LOG("Received RTSP over tcp packet (sock_id %d, stream %d, rlen %d) packet len: %d, type %02X %02X discarding %s...", 
			s->id, s->sid, s->rlen, rtsp_len , s->buf[4], s->buf[5], (s->rlen == rtsp_len+4)?"complete":"fragment" );		
		if(s->rlen == rtsp_len+4){ // we did not receive the entire packet
			s->rlen = 0;			
			return 0;
		}
	}
	
	if (s->rlen < 4 || !end_of_header(s->buf + s->rlen - 4))
	{
		if( s->rlen > RBUF - 10 )
		{
			LOG("Discarding %d bytes from the socket buffer, request > %d, consider increasing  RBUF", s->rlen, RBUF);
			s->rlen = 0;
		}
		LOG("read_rtsp: read %d bytes from handle %d, sock_id %d, flags %d not ending with \\r\\n\\r\\n", s->rlen, s->sock, s->id, s->flags);
		if ( s->flags & 1 ) 
			return 0;		
		unsigned char *new_alloc = malloc1 (RBUF);
		memcpy(new_alloc, s->buf, s->rlen);
		s->buf = new_alloc;
		s->flags = s->flags | 1;
		return 0;
	}

	rlen = s->rlen;
	s->rlen = 0;

	LOG ("read RTSP (from handle %d sock_id %d, len: %d, sid %d):\n%s", s->sock, s->id, s->rlen, s->sid, s->buf);

	if( (s->type != TYPE_HTTP ) && (strncasecmp(s->buf, "GET", 3) == 0))
	{
		http_response (s , 404, NULL, NULL, 0, 0);
		return 0;
	}
	
	la = split (arg, s->buf, 50, ' ');
	cseq = 0;	
	if (la<2)
		LOG_AND_RETURN(0, "Most likely not an RTSP packet sock_id: %d sid: %d rlen: %d, dropping ....", s->id, s->sid, rlen); 
	
	if(s->sid<0)
		for (i = 0; i < la; i++)	
			if (strncasecmp ("Session:", arg[i], 8) == 0)
			{
				sess_id = map_int(header_parameter(arg, i), NULL);
				s->sid = find_session_id(sess_id);		
			}

	if(strstr(arg[1], "freq") || strstr(arg[1], "pids"))
	{
		int old_sid = s->sid;
		sid = (streams *) setup_stream (arg[1], s);
	}
	sid = get_sid(s->sid);
	if(sid)
		sid->rtime = s->rtime;

	if (sess_id)    
			set_session_id(s->sid, sess_id);
		
	
	for (i = 0; i < la; i++)
		if (strncasecmp ("CSeq:", arg[i], 5) == 0)
			cseq = map_int (header_parameter(arg, i), NULL);
		else if (strncasecmp ("Transport:", arg[i], 9) == 0){
			transport = header_parameter(arg, i);

			if( -1 == decode_transport (s, transport, opts.rrtp, opts.start_rtp))
			{
				http_response (s, 400, NULL, NULL, cseq, 0);
				return 0;
			}
		}
		else if (strstr (arg[i], "LIVE555"))
		{
			if(sid) sid->timeout = 0;
		}
		else if (strstr (arg[i], "Lavf"))
		{
			if(sid) sid->timeout = 0;
		}
		else if (strncasecmp ("User-Agent:", arg[i], 10) == 0)
			useragent = header_parameter(arg, i);
	
	if((strncasecmp (arg[0], "PLAY", 4) == 0) || (strncasecmp (arg[0], "GET", 3) == 0) || (strncasecmp (arg[0], "SETUP", 5) == 0)) 
	{
		char ra[100];
		int rv;
			
		if (!( sid = get_sid(s->sid)))
		{
			http_response (s, 454, NULL, NULL, cseq, 0);
			return 0;
		}

		if (useragent)
			strncpy(sid->useragent, useragent, 127);

		if ((strncasecmp (arg[0], "PLAY", 3) == 0) || (strncasecmp (arg[0], "GET", 3) == 0))
			if ((rv = start_play (sid, s)) < 0)
			{
				http_response (s, -rv , NULL, NULL, cseq, 0);
				return 0;
			}
		strcpy(ra, inet_ntoa (sid->sa.sin_addr));
		buf[0] = 0;
		if(transport)
		{
			int s_timeout = (sid->timeout ? sid->timeout : opts.timeout_sec) / 1000;
			switch (sid->type)
			{
				case STREAM_RTSP_UDP:
					if (atoi (ra) < 239)
						snprintf (buf, sizeof(buf), "Transport: RTP/AVP;unicast;destination=%s;source=%s;client_port=%d-%d;server_port=%d-%d\r\nSession: %010d;timeout=%d\r\ncom.ses.streamID: %d",
							ra, get_sock_host (s->sock), ntohs (sid->sa.sin_port), ntohs (sid->sa.sin_port) + 1,
//							opts.start_rtp, opts.start_rtp + 1, 
							get_sock_port(sid->rsock), get_sock_port(sid->rtcp),
							get_session_id (s->sid), s_timeout, sid->sid + 1);
					else
						snprintf (buf, sizeof(buf), "Transport: RTP/AVP;multicast;destination=%s;port=%d-%d\r\nSession: %010d;timeout=%d\r\ncom.ses.streamID: %d",
							ra, ntohs (sid->sa.sin_port), ntohs (sid->sa.sin_port) + 1,
							get_session_id (s->sid), s_timeout , sid->sid + 1);
					break;
				case STREAM_RTSP_TCP:
					snprintf(buf, sizeof(buf), "Transport: RTP/AVP/TCP;interleaved=0-1\r\nSession: %010d;timeout=%d\r\ncom.ses.streamID: %d", 
						get_session_id (s->sid), s_timeout, sid->sid + 1);
					break;
			}
		}
		
		if (strncasecmp(arg[0], "PLAY", 4) == 0)
		{
			char *qm = strchr(arg[1], '?');
			if(qm)
				*qm = 0;
			if(buf[0])
				strcat(buf, "\r\n");
			
			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1,  "RTP-Info: url=%s;seq=%d;rtptime=%lld\r\nRange: npt=0.000-", arg[1], getTick(),(long long int)(getTickUs()/1000000));
		}
		if(buf[0]==0 && sid->type == STREAM_HTTP)
				snprintf(buf, sizeof(buf), "Content-Type: video/mp2t");
		http_response (s, 200, buf, NULL, cseq, 0);
	}
	else if (strncmp (arg[0], "TEARDOWN", 8) == 0)
	{
		streams *sid;
		buf[0] = 0;
		if(get_sid(s->sid))
			sprintf(buf, "Session: %010d", get_session_id(s->sid));
		close_stream (s->sid);		
		http_response (s, 200, buf, NULL, cseq, 0);
	}
	else
	{
		if (strncmp (arg[0], "DESCRIBE", 8) == 0)
		{
			char sbuf[1000];
			char *rv = NULL;
			rv = describe_streams(s, arg[1], sbuf, sizeof(sbuf));
			if (! rv)
			{
				http_response (s, 404, NULL, NULL, cseq, 0);
				return 0;
			}	
			snprintf(buf, sizeof(buf), "Content-type: application/sdp\r\nContent-Base: rtsp://%s/", get_sock_host(s->sock));
			http_response (s, 200, buf, sbuf, cseq, 0);
				
		}
		else if (strncmp (arg[0], "OPTIONS", 8) == 0)
		{
			http_response (s, 200, public, NULL, cseq, 0);
		}
	}