⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsp_session.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
			}			sess->CurrentPos += paySize+4;			assert(sess->CurrentPos <= sess->CurrentSize);		} else {			/*missed end of pck ?*/			if (sess->payloadSize) {				ch = GetTCPChannel(sess, sess->InterID, sess->InterID, 0);				if (ch) {					IsRTCP = (ch->rtcpID == sess->InterID);					sess->RTSP_SignalData(sess, ch->ch_ptr, sess->rtsp_pck_buf, sess->payloadSize, IsRTCP);				}			}			sess->InterID = InterID;			sess->payloadSize = paySize;			sess->pck_start = Size-4;			if (sess->rtsp_pck_size < paySize) {				sess->rtsp_pck_buf = (char *)realloc(sess->rtsp_pck_buf, sizeof(char)*paySize);				sess->rtsp_pck_size = paySize;			}			memcpy(sess->rtsp_pck_buf, buffer+4, Size-4);			sess->CurrentPos += Size;			assert(sess->CurrentPos <= sess->CurrentSize);		}	} 	/*end of packet*/	else if (sess->payloadSize - sess->pck_start <= Size) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP over RTSP] Missed begining of packet (%d bytes)\n", Size));		res = sess->payloadSize - sess->pck_start;		memcpy(sess->rtsp_pck_buf + sess->pck_start, buffer, res);		//flush - same as above, don't complain if channel not found		ch = GetTCPChannel(sess, sess->InterID, sess->InterID, 0);		if (ch) {			IsRTCP = (ch->rtcpID == sess->InterID);			sess->RTSP_SignalData(sess, ch->ch_ptr, sess->rtsp_pck_buf, sess->payloadSize, IsRTCP);		}		sess->payloadSize = 0;		sess->pck_start = 0;		sess->InterID = (u8) -1;		sess->CurrentPos += res;		assert(sess->CurrentPos <= sess->CurrentSize);	}	/*middle of packet*/	else {		GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP over RTSP] Missed begining of RTP packet\n"));		memcpy(sess->rtsp_pck_buf + sess->pck_start, buffer, Size);		sess->pck_start += Size;		sess->CurrentPos += Size;		assert(sess->CurrentPos <= sess->CurrentSize);	}	return GF_OK;}/*		Exposed API, thread-safe*/GF_Err RTSP_ResetInterleaving(GF_RTSPSession *sess, Bool ResetChannels){	if (!sess) return GF_BAD_PARAM;	gf_mx_p(sess->mx);	sess->payloadSize = 0;	sess->pck_start = 0;	sess->InterID = (u8) -1;	if (ResetChannels) RemoveTCPChannels(sess);	gf_mx_v(sess->mx);		return GF_OK;}GF_EXPORTGF_Err gf_rtsp_session_read(GF_RTSPSession *sess){	GF_Err e;	if (!sess) return GF_BAD_PARAM;	gf_mx_p(sess->mx);	e = gf_rtsp_fill_buffer(sess);	if (!e) {		//only read if not RTSP		while (1) {			e = gf_rtsp_set_deinterleave(sess);			if (e) break;		}	}	gf_mx_v(sess->mx);	return e;}GF_EXPORTu32 gf_rtsp_unregister_interleave(GF_RTSPSession *sess, u8 LowInterID){	GF_TCPChan *ptr;	gf_mx_p(sess->mx);	ptr = GetTCPChannel(sess, LowInterID, LowInterID, 1);	if (ptr) free(ptr);	gf_mx_v(sess->mx);	return gf_list_count(sess->TCPChannels);}GF_EXPORTGF_Err gf_rtsp_register_interleave(GF_RTSPSession *sess, void *the_ch, u8 LowInterID, u8 HighInterID){	GF_TCPChan *ptr;	if (!sess) return GF_BAD_PARAM;	gf_mx_p(sess->mx);	//do NOT register twice	ptr = GetTCPChannel(sess, LowInterID, HighInterID, 0);	if (!ptr) {		ptr = (GF_TCPChan *)malloc(sizeof(GF_TCPChan));		ptr->ch_ptr = the_ch;		ptr->rtpID = LowInterID;		ptr->rtcpID = HighInterID;		gf_list_add(sess->TCPChannels, ptr);	}	gf_mx_v(sess->mx);	return GF_OK;}GF_EXPORTGF_Err gf_rtsp_set_interleave_callback(GF_RTSPSession *sess,						GF_Err (*SignalData)(GF_RTSPSession *sess, void *chan, char *buffer, u32 bufferSize, Bool IsRTCP)				){	if (!sess) return GF_BAD_PARAM;	gf_mx_p(sess->mx);	//only if existing	if (SignalData) sess->RTSP_SignalData = SignalData;	//realloc or alloc	if (sess->rtsp_pck_buf && sess->rtsp_pck_size != RTSP_PCK_SIZE) {		sess->rtsp_pck_size = RTSP_PCK_SIZE;		sess->rtsp_pck_buf = (char *)realloc(sess->rtsp_pck_buf, sizeof(char)*sess->rtsp_pck_size);	} else if (!sess->rtsp_pck_buf) {		sess->rtsp_pck_size = RTSP_PCK_SIZE;		sess->rtsp_pck_buf = (char *)realloc(sess->rtsp_pck_buf, sizeof(char)*sess->rtsp_pck_size);		sess->pck_start = 0;	}	gf_mx_v(sess->mx);	return GF_OK;}GF_EXPORTGF_Err gf_rtsp_set_buffer_size(GF_RTSPSession *sess, u32 BufferSize){	if (!sess) return GF_BAD_PARAM;	sess->SockBufferSize = BufferSize;	return GF_OK;}static Bool HTTP_RandInit = 1;#define HTTP_WAIT_SEC		30#define HTTP_RSP_OK	"HTTP/1.0 200 OK"void RTSP_GenerateHTTPCookie(GF_RTSPSession *sess){	u32 i, num, temp;	if (HTTP_RandInit) {		gf_rand_init(0);		HTTP_RandInit = 0;	}	if (!sess->CookieRadLen) {		strcpy(sess->HTTP_Cookie, "MPEG4M4");		sess->CookieRadLen = 8;	}	num = gf_rand();	for (i=0; i < 8; i++) {		temp = (num >> (i * 4)) & 0x0f;		sess->HTTP_Cookie[sess->CookieRadLen + i] = (u8) temp + sess->HTTP_Cookie[0];	}	sess->HTTP_Cookie[sess->CookieRadLen + i] = 0;	}//http tunnelling start.GF_Err gf_rtsp_http_tunnel_start(GF_RTSPSession *sess, char *UserAgent){	GF_Err e;	u32 size;	s32 pos;	char buffer[GF_RTSP_DEFAULT_BUFFER];	RTSP_GenerateHTTPCookie(sess);	//  1. send "GET /sample.mov HTTP/1.0\r\n ..."	memset(buffer, 0, GF_RTSP_DEFAULT_BUFFER);	pos = 0;	pos += sprintf(buffer + pos, "GET /%s HTTP/1.0\r\n", sess->Service);	pos += sprintf(buffer + pos, "User-Agent: %s\r\n", UserAgent);	pos += sprintf(buffer + pos, "x-sessioncookie: %s\r\n", sess->HTTP_Cookie);	pos += sprintf(buffer + pos, "Accept: application/x-rtsp-tunnelled\r\n" );	pos += sprintf(buffer + pos, "Pragma: no-cache\r\n" );	pos += sprintf(buffer + pos, "Cache-Control: no-cache\r\n\r\n" );			//	send it!	e = gf_sk_send_wait(sess->connection, buffer, strlen(buffer), HTTP_WAIT_SEC);	if (e) return e;		//	2. wait for "HTTP/1.0 200 OK"	e = gf_sk_receive_wait(sess->connection, buffer, GF_RTSP_DEFAULT_BUFFER, 0, &size, HTTP_WAIT_SEC);	if (e) return e;		//get HTTP/1.0 200 OK	if (strncmp(buffer, HTTP_RSP_OK, strlen(HTTP_RSP_OK))) return GF_REMOTE_SERVICE_ERROR;	//	3. send "POST /sample.mov HTTP/1.0\r\n ..."	sess->http = gf_sk_new(GF_SOCK_TYPE_TCP);	if (!sess->http ) return GF_IP_NETWORK_FAILURE;	if (gf_sk_connect(sess->http, sess->Server, sess->Port)) return GF_IP_CONNECTION_FAILURE; 	memset(buffer, 0, GF_RTSP_DEFAULT_BUFFER);	pos = 0;	pos += sprintf(buffer + pos, "POST /%s HTTP/1.0\r\n", sess->Service);	pos += sprintf(buffer + pos, "User-Agent: %s\r\n", UserAgent);	pos += sprintf(buffer + pos, "x-sessioncookie: %s\r\n", sess->HTTP_Cookie);	pos += sprintf(buffer + pos, "Accept: application/x-rtsp-tunnelled\r\n");	pos += sprintf(buffer + pos, "Pragma: no-cache\r\n");	pos += sprintf(buffer + pos, "Cache-Control: no-cache\r\n");		pos += sprintf(buffer + pos, "Content-Length: 32767\r\n");	pos += sprintf(buffer + pos, "Expires: Sun. 9 Jan 1972 00:00:00 GMT\r\n\r\n"); 	//	send it!	e = gf_sk_send_wait(sess->http, buffer, strlen(buffer), HTTP_WAIT_SEC);		return e;}/*server-side RTSP sockets*/static u32 SessionID_RandInit = 0;GF_EXPORTGF_RTSPSession *gf_rtsp_session_new_server(GF_Socket *rtsp_listener){	GF_RTSPSession *sess;	GF_Socket *new_conn;	GF_Err e;	u32 fam;	u16 port;	char name[GF_MAX_IP_NAME_LEN];	if (!rtsp_listener) return NULL;			e = gf_sk_accept(rtsp_listener, &new_conn);	if (!new_conn || e) return NULL;	e = gf_sk_get_local_info(new_conn, &port, &fam);	if (e) {		gf_sk_del(new_conn);		return NULL;	}	e = gf_sk_set_block_mode(new_conn, 1);	if (e) {		gf_sk_del(new_conn);		return NULL;	}	e = gf_sk_server_mode(new_conn, 1);	if (e) {		gf_sk_del(new_conn);		return NULL;	}		//OK create a new session	GF_SAFEALLOC(sess, GF_RTSPSession);	sess->connection = new_conn;	sess->Port = port;	sess->ConnectionType = fam;	gf_sk_get_host_name(name);	sess->Server = strdup(name);		sess->TCPChannels = gf_list_new();	return sess;}GF_EXPORTGF_Err gf_rtsp_load_service_name(GF_RTSPSession *sess, char *URL){	char server[1024], service[1024];	GF_Err e;	u16 Port;	Bool UseTCP;	u32 type;	if (!sess || !URL) return GF_BAD_PARAM;	e = RTSP_UnpackURL(URL, server, &Port, service, &UseTCP);	if (e) return e;	type = UseTCP ? GF_SOCK_TYPE_TCP : GF_SOCK_TYPE_UDP;	//check the network type matches, otherwise deny client	if (sess->ConnectionType != type) return GF_URL_ERROR;	if (sess->Port != Port) return GF_URL_ERROR;	//ok	sess->Server = strdup(server);	sess->Service = strdup(service);	return GF_OK;}GF_EXPORTchar *gf_rtsp_generate_session_id(GF_RTSPSession *sess){	u32 one, two;	u64 res;	char buffer[30];	if (!sess) return NULL;	if (!SessionID_RandInit) {		SessionID_RandInit = 1;		gf_rand_init(0);	}	one = gf_rand();	//try to be as random as possible. if we had some global stats that'd be better	two = (u32) sess + sess->CurrentPos + sess->CurrentSize;	res = one;	res <<= 32;	res += two;	sprintf(buffer, "%llu", res);	return strdup(buffer);}GF_EXPORTGF_Err gf_rtsp_get_session_ip(GF_RTSPSession *sess, char *buffer){	if (!sess || !sess->connection) return GF_BAD_PARAM;	gf_sk_get_local_ip(sess->connection, buffer);	return GF_OK;}GF_EXPORTu8 gf_rtsp_get_next_interleave_id(GF_RTSPSession *sess){	u32 i;	u8 id;	GF_TCPChan *ch;	id = 0;	i=0;	while ((ch = (GF_TCPChan *)gf_list_enum(sess->TCPChannels, &i))) {		if (ch->rtpID >= id) id = ch->rtpID + 1;		if (ch->rtcpID >= id) id = ch->rtcpID + 1;	}	return id;}GF_EXPORTGF_Err gf_rtsp_get_remote_address(GF_RTSPSession *sess, char *buf){	if (!sess || !sess->connection) return GF_BAD_PARAM;	return gf_sk_get_remote_address(sess->connection, buf);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -