📄 rtsp_session.c
字号:
} 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 + -