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

📄 rtp.c

📁 一个关于 RTP的例子
💻 C
📖 第 1 页 / 共 2 页
字号:
	context_list[context_num]->time_elapsed = 0;
	context_list[context_num]->version = 0;
	context_list[context_num]->marker = 0;
	context_list[context_num]->padding = 0;
	context_list[context_num]->pt = 0;
	context_list[context_num]->hdr_extension = NULL;

	if (nb_context == 1)
	{
		MEM_ALLOC(tab_ssrc);
		tab_ssrc[0] = context_list[context_num]->my_ssrc;
	}
	else
	{
		tab_ssrc = realloc(tab_ssrc, sizeof(u_int32) * nb_context);
		tab_ssrc[nb_context - 1] = context_list[context_num]->my_ssrc;
	}
	return (0);
}


/**
 **  Create the context
 **/
int			RTP_Context_Create(context *cid)
{
	context		i;

	if (nb_context < above_context)
	{
		for (i = 0; i < above_context; i++)
		{
			if (context_list[i] == NULL)
				break;
		}
	}
	else if (context_list == NULL)
	{
		i = above_context;
		above_context = MAX_CONTEXT;
		context_list = (sess_context_t**) calloc(MAX_CONTEXT, sizeof(sess_context_t*));
	}
	else
	{
		i = above_context;
		above_context += 10;
		context_list = realloc(context_list, sizeof(sess_context_t*) *above_context);
	}
	context_list[i] = malloc(sizeof(sess_context_t));
	nb_context++;
	Init_Context(i, nb_context);
	*cid = i;
	return (0);
}


/**
 **  Destroy the context
 **/
int			RTP_Context_destroy(context cid)
{
	int		i1;
	int		i2;

	if (nb_context == 1)
	{
		free(tab_ssrc);
		nb_context--;
	}
	else
	{
		for (i1 = 0; i1 < nb_context; i1++)
		{
			if (context_list[cid]->my_ssrc == tab_ssrc[i1])
			{
				for (i2 = i1; i2 < nb_context; i2++)
					tab_ssrc[i2] = tab_ssrc[i2 + 1];
				tab_ssrc[nb_context - 1] = 0;
				nb_context--;
				tab_ssrc = realloc(tab_ssrc, sizeof(u_int32) * nb_context);
				break;
			}
		}
	}
	if (context_list[cid]->CSRCList)
		free(context_list[cid]->CSRCList);
	if (context_list[cid]->hdr_extension)
		free(context_list[cid]->hdr_extension);
	free(context_list[cid]);
	context_list[cid] = NULL;
	return (0);
}


/**
 **  Send the packet
 **/
int			RTP_Sd_Pkt(context cid, u_int32 ts, u_int8 marker, u_int16 pti, u_int8 *payload, int len, u_int8 padd_len)
{
	rtp_pkt		*rtp_packet;
	int		padding		= 0;
	int		ext		= 0;
	u_int8		csrc_len	= 0;
	u_int8		csrc_sz		= 0;
	SOCKADDR_IN	sin;
	u_int8		*sd_buffer	= NULL;
	u_int8		hd_len		= 12;
	u_int16		hd_ext_len	= 0;
	conx_context_t 	*conx_cc	= NULL;
	remote_address_t *remote_dev	= NULL;
	int		sd_buffer_len;

	MEM_ALLOC(rtp_packet);
	MEM_ALLOC(rtp_packet->RTP_header);
	if (context_list[cid]->CSRClen)
	{
		csrc_len = context_list[cid]->CSRClen;
		csrc_sz = csrc_len * 4;
		MEM_SALLOC(rtp_packet->RTP_header->csrc, csrc_sz);
		rtp_packet->RTP_header->csrc = context_list[cid]->CSRCList;
	}
	MEM_SALLOC(rtp_packet->payload, len + padd_len);

	rtp_packet->payload = payload;
	rtp_packet->payload_len = len;
	RTP_Session_Restore_Cxinfo(cid, (void **)&conx_cc);
	hd_len += csrc_sz;
	if (padd_len > 0)
		padding = 1;
	if (context_list[cid]->hdr_extension)
	{
		ext = 1;
		hd_ext_len = 4 * (1 + ntohs(context_list[cid]->hdr_extension->ext_len));
		hd_len += hd_ext_len;
		MEM_SALLOC(rtp_packet->RTP_extension, hd_ext_len);
		rtp_packet->RTP_extension = context_list[cid]->hdr_extension;
	}

	sd_buffer  = (u_int8 *) malloc(hd_len + len + padd_len);
	sd_buffer_len = hd_len + len + padd_len;
	RTP_Build_Header(cid, rtp_packet->RTP_header, padding, marker, ext, context_list[cid], pti, ts);
	memcpy(sd_buffer, rtp_packet->RTP_header, 12);
	memcpy(sd_buffer + 12, rtp_packet->RTP_header->csrc, csrc_sz);
	memcpy(sd_buffer + 12 + csrc_sz, rtp_packet->RTP_extension, 4);
	memcpy(sd_buffer + 16 + csrc_sz, rtp_packet->RTP_extension->hd_ext, (hd_ext_len - 4));
	memcpy(sd_buffer + hd_len, rtp_packet->payload, rtp_packet->payload_len);
	memset(sd_buffer + hd_len + len, 0, padd_len);
	if (padd_len > 0)
		sd_buffer[sd_buffer_len - 1] = padd_len;

	remote_dev = conx_cc->send_addr_list;
	while (remote_dev)
	{
		sin.sin_addr.s_addr	= inet_addr(remote_dev->address);
		sin.sin_family		= AF_INET;
		sin.sin_port		= htons(remote_dev->port);
		sendto(remote_dev->socket, sd_buffer, sd_buffer_len, 0,(SOCKADDR *)&sin, sizeof(sin));
		remote_dev = remote_dev->next;
	}
	free(sd_buffer);
	return (0);
}

u_int8			Get_Padding(rtp_hdr *rtp_hdr_msg, char *msg, int sz)
{
  char			padding;
  u_int8		len_padding;

  /*
   * Gestion du padding.
   */  
  padding = (rtp_hdr_msg->flags & 0x20) >> 5;
  if (padding)
    memcpy(&len_padding, msg + (sz - 1), 1);
  else
    len_padding = 0;
  return (len_padding);
}

rtp_pkt			*Get_RTP_Hdr(char *msg, int  sz)
{
  char			cc;
  char			ext;
  u_int16		hdr_sz;
  u_int8		len_padding;
  rtp_hdr		*rtp_hdr_msg;
  rtp_ext		*rtp_ext_msg;
  rtp_pkt		*rtp_pkt_msg;

  /*
   * Recuperation du rtp_header.
   */
  MEM_SALLOC(rtp_hdr_msg, sizeof(rtp_hdr));
  memcpy(rtp_hdr_msg, msg, 12);
  hdr_sz = 12;
    
  /*
   * Recuperation du csrc.
   */
  cc = (rtp_hdr_msg->flags) & 0x0f;
  if (cc)
    {
      MEM_SALLOC(rtp_hdr_msg->csrc, (cc * 4));
      memcpy(rtp_hdr_msg->csrc, msg + 12, (cc * 4));
      hdr_sz += (cc * 4);
    }
  
  /*
   * Recuperation de Ext_type et Ext_len, puis des Ext.
   */
  ext = (rtp_hdr_msg->flags & 0x10) >> 4;
  if (ext)
    {
      MEM_ALLOC(rtp_ext_msg);
      memcpy(rtp_ext_msg, msg + 12 + (cc * 4), 4);
      MEM_SALLOC(rtp_ext_msg->hd_ext, 4 * rtp_ext_msg->ext_len);
      memcpy(rtp_ext_msg->hd_ext, msg + 16 + (cc * 4), (rtp_ext_msg->ext_len * 4));
      hdr_sz += (ntohs(rtp_ext_msg->ext_len) * 4) + 4;
    }
    
  /*
   * Gestion du padding.
   */
  len_padding = Get_Padding(rtp_hdr_msg, msg, sz);
    
  /*
   * Revoie du packet.
   */
  MEM_ALLOC(rtp_pkt_msg);
  rtp_pkt_msg->RTP_header = rtp_hdr_msg;
  rtp_pkt_msg->RTP_extension = rtp_ext_msg;
  rtp_pkt_msg->payload_len = sz - (hdr_sz + len_padding);
  MEM_SALLOC(rtp_pkt_msg->payload, rtp_pkt_msg->payload_len);
  memcpy(rtp_pkt_msg->payload, msg + hdr_sz, rtp_pkt_msg->payload_len);

  return (rtp_pkt_msg);
}

void			Free_Tmp_Mem(rtp_pkt *pkt)
{
  /*
   * Free Memoire. 
   */
  free(pkt->RTP_extension->hd_ext);
  free(pkt->RTP_extension);
  free(pkt->RTP_header->csrc);
  free(pkt->RTP_header);
  free(pkt);
  return;
}

void			Put_Pkt_in_Context(rtp_pkt *pkt, char *msg, int cid, int sz)
{
  int			i;

  /* SSRC number - send/receive */
  context_list[cid]->my_ssrc = ntohl(pkt->RTP_header->ssrc);
  
  /* Number of packets sent - send/receive */
  context_list[cid]->sending_pkt_count++;

  /* Number of bytes sent - send/receive */
  context_list[cid]->sending_octet_count += sz;

  /* Version - receive */
  context_list[cid]->version = (pkt->RTP_header->flags & 0xd0) >> 6;

  /* Marker flag - receive */
  context_list[cid]->marker = (pkt->RTP_header->mk_pt & 0x10) >> 7;

  /* Padding length - receive */
  context_list[cid]->padding = Get_Padding(pkt->RTP_header, msg, sz);
  
  /* CSRC length - send/receive */
  context_list[cid]->CSRClen = (pkt->RTP_header->flags & 0x0f);

  /* Payload type - send/receive */
  context_list[cid]->pt = (pkt->RTP_header->mk_pt & 0x7f);

  /* CSRC list - send/receive */
  MEM_SALLOC(context_list[cid]->CSRCList, (context_list[cid]->CSRClen * 4));
  memcpy(context_list[cid]->CSRCList, pkt->RTP_header->csrc, (context_list[cid]->CSRClen * 4));
  
  /* current value of timestamp - receive */
  context_list[cid]->RTP_timestamp = ntohl(pkt->RTP_header->ts);

  /* First value of timestamp - send/receive */
  if (context_list[cid]->sending_pkt_count == 1)
    context_list[cid]->init_RTP_timestamp = context_list[cid]->RTP_timestamp;

  /* Time elapsed since the beginning - send/receive */
  if (context_list[cid]->sending_pkt_count == 1)
    context_list[cid]->time_elapsed = 0;
  else
    context_list[cid]->time_elapsed = context_list[cid]->RTP_timestamp  - context_list[cid]->init_RTP_timestamp;

  /* Current sequence number - send/receive */
  context_list[cid]->seq_no = ntohs(pkt->RTP_header->sq_nb);

  /* First sequence number - send/receive */
  if (context_list[cid]->sending_pkt_count == 1)
    context_list[cid]->init_seq_no = context_list[cid]->seq_no;

  /* Extension header - send/receive */
  MEM_ALLOC(context_list[cid]->hdr_extension);
  context_list[cid]->hdr_extension->ext_len = ntohs(pkt->RTP_extension->ext_len);
  context_list[cid]->hdr_extension->ext_type = ntohs(pkt->RTP_extension->ext_type);
  if (context_list[cid]->hdr_extension->ext_len)
    {
      MEM_SALLOC(context_list[cid]->hdr_extension->hd_ext,  (4 * context_list[cid]->hdr_extension->ext_len));
      memcpy(context_list[cid]->hdr_extension->hd_ext, pkt->RTP_extension->hd_ext, (4 * context_list[cid]->hdr_extension->ext_len));  
      for(i = 0; i < context_list[cid]->hdr_extension->ext_len; i++)
	context_list[cid]->hdr_extension->hd_ext[i] = ntohl(context_list[cid]->hdr_extension->hd_ext[i]);
    }
}

int			RTP_Receive(context cid, int fd, char *payload, int *len, struct sockaddr *sin)
{
  char			*msg;
  int			sin_len;
  int			sz;
  char	 		buf[MAX_PACKET_LEN];
  rtp_pkt		*pkt;
  
  /*
   * Reception du paquets.
   */
  sin_len = sizeof(struct sockaddr_in);
  sz =  recvfrom(fd, buf, MAX_PACKET_LEN, 0, sin, &sin_len);

  /*
   * Stockage du paquets.
   */
  MEM_SALLOC(msg, sz);
  memcpy(msg, buf, sz);
  bzero(buf,MAX_PACKET_LEN);

  /*
   * Recuperation du RTP_Header, RTP_extension, Payload.
   */
  pkt = Get_RTP_Hdr(msg, sz);
  
  /*
   * Integration du paquets dans le context.
   */
  Put_Pkt_in_Context(pkt, msg, cid, sz);

  /*
   * Gestion du payload.
   */
  *len = pkt->payload_len;
  memcpy(payload, pkt->payload, *len);
  
  /*
   * Print Structure.
   *
   * print_hdr(pkt);
   */
  
  /*
   * Free Memoire. 
   */
  Free_Tmp_Mem(pkt);
}

⌨️ 快捷键说明

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