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

📄 rtptrans.c

📁 RTP 实现的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
        default:        rtp_hdr_send.pt=115;   /* hopefully unused */        perror(" unknown codecs ");        break;      }      rtp_hdr_send.ssrc    = sin_from.sin_addr.s_addr;      rtp_hdr_send.seq     = find_stream(rtp_hdr_send.ssrc, vat_hdr->ts,         vat_hdr->ts + samples, rtp_hdr_send.m);      rtp_hdr_send.version = RTP_VERSION;      rtp_hdr_send.p       = 0;      rtp_hdr_send.x       = 0;      rtp_hdr_send.cc      = 0;      rtp_hdr_send.ts      = vat_hdr->ts;#ifdef Linux       /*        * Stupid little Linux does not support sendmsg        * use copying instead; contributed by       * Lutz Grueneberg <gruen@rvs.uni-hannover.de>.       */      {        unsigned char mbuf[10000];        int mlength = 0;        memcpy (&mbuf[mlength], (char *)&(rtp_hdr_send), sizeof(rtp_hdr_t)-4);        mlength += sizeof(rtp_hdr_t)-4;        memcpy (&mbuf[mlength], packet+VAT_LEN, len-VAT_LEN);        mlength += len-VAT_LEN;        for (i = 0; i < hostc; i++) {          if (side[i][proto].sock != sock) {            if (sendto(side[i][2].sock, mbuf, mlength, 0,                        &(side[i][proto].sin), sizeof(side[i][proto].sin))!=                mlength)              perror("sendmsg RTCP");          }        }      }#else       iov[0].iov_base = (char *)&(rtp_hdr_send);      iov[0].iov_len = sizeof(rtp_hdr_t)-4;      iov[1].iov_base = packet+VAT_LEN;      iov[1].iov_len = len-VAT_LEN;      msg.msg_iov = iov;      msg.msg_iovlen = 2;      for (i = 0; i < hostc; i++) {        if (side[i][proto].sock != sock) {          msg.msg_name = (caddr_t ) &side[i][proto].sin;          msg.msg_namelen = sizeof(side[i][proto].sin);#if defined(__FreeBSD__) /* Or presumably other BSD 4.4 systems */	  msg.msg_control = 0;	  msg.msg_controllen = 0;#else          msg.msg_accrights = 0;          msg.msg_accrightslen = 0;#endif          if ((sendmsg(side[i][2].sock, &msg,0))!=             iov[0].iov_len +iov[1].iov_len)            perror("sendmsg RTCP");          }       }    }#endif /* Linux */    else if (((struct CtrlMsgHdr *)packet)->type == 1) /* vat ID messages */{      rtcp_t *rtcp_msg;      struct sdes_msg *ctl_msg;      rtcp_sdes_item_t *item;      int len=0;      int length;      item=NULL;      /* total length of the packet = IP address+ site entry of vat+ 2 type+ 2         length + 4 common header+ 4 ssrc + 8 empty RR */      length = strlen(inet_ntoa(sin_from.sin_addr)) +        strlen(packet+sizeof(struct CtrlMsgHdr)) + 12 + 8;      length = ((length/4)*4)+4;      rtcp_msg=(rtcp_t *)malloc(length);      memset(rtcp_msg,0,length);      /* init RR */      rtcp_msg->common.version=2;      rtcp_msg->common.p=0;      rtcp_msg->common.count=0;      rtcp_msg->common.pt=201;      rtcp_msg->r.rr.ssrc=sin_from.sin_addr.s_addr;      rtcp_msg->common.length=(8 >> 2) - 1;      ctl_msg=(struct sdes_msg *)&rtcp_msg->r.rr.rr[0];      item=( rtcp_sdes_item_t *) ((char *)ctl_msg+8);      /* init CNAME */      item->type=1;      strcpy(item->data,inet_ntoa(sin_from.sin_addr));      item->length=strlen(item->data);      len=item->length+2;      item=(rtcp_sdes_item_t *)((char *)item +len);      /* init NAME */      strcpy(item->data,packet+sizeof(struct CtrlMsgHdr));      item->length=strlen(item->data);      item->type=2;      len+=item->length+2;      ctl_msg->header.version=2;      ctl_msg->header.p=0;      ctl_msg->header.count=1;      ctl_msg->header.pt=202;      ctl_msg->sdes.src=sin_from.sin_addr.s_addr;      ctl_msg->header.length=((length-8) >> 2) - 1;      for (i = 0; i < hostc; i++) {        if (side[i][proto].sock != sock) {          if (sendto(side[i][2].sock,(char *)rtcp_msg,             ((rtcp_msg->common.length+1)+(ctl_msg->header.length+1))*4,             0, (struct sockaddr *)&side[i][proto].sin,             sizeof(side[i][proto].sin)) < 0)          perror("sendto RTCP");        }      }      free(rtcp_msg);    }/* control messages */  }  return NOTIFY_DONE;} /* socket_handler */void usage(char *argv0){  fprintf(stderr, "Usage: %s \[address]/port/ttl\[address]/port/ttl [...]\n", argv0);}int main(int argc, char *argv[]){  int c;  struct {    char *name;    unsigned char ttl;    struct sockaddr_in sin;    struct ip_mreq mreq;  } host[MAX_HOST];  struct sockaddr_in sin;   /* generic bind */  extern int optind;  char loop = 0;  /* multicast loop */  int reuse = 1;  /* reuse address */  int i, j;  extern struct in_addr host2ip(char *);  while ((c = getopt(argc, argv, "d?h")) != EOF) {    switch(c) {    case 'd':      debug = 1;      break;    case '?':    case 'h':      usage(argv[0]);      exit(1);      break;    }  }  if (optind == argc) {    usage(argv[0]);    exit(1);  }  /* Parse host descriptions. */  for (i = 0; i < argc-optind; i++) {    char *s;    if (i >= MAX_HOST) break;    host[i].ttl  = 16;    host[i].name = argv[optind+i];    host[i].sin.sin_family = AF_INET;    s = strchr(host[i].name, '/');    if (!s) {      usage(argv[0]);      exit(1);    }    else {      int port;      *s = '\0';      port = atoi(s+1);      if (port & 1) {        fprintf(stderr, "%s: Port must be even.\n", argv[0]);        /* exit(1); */      }      host[i].sin.sin_port = htons(port);      s = strchr(s+1, '/');      if (s) {        host[i].ttl = atoi(s+1);      }    }    host[i].sin.sin_addr = host2ip(host[i].name);    if (IN_CLASSD(host[i].sin.sin_addr.s_addr)) {      host[i].mreq.imr_multiaddr        = host[i].sin.sin_addr;      host[i].mreq.imr_interface.s_addr = htonl(INADDR_ANY);    }    hostc++;  }  /* Create/bind sockets. */  for (i = 0; i < hostc; i++) { /* hosts (unicast or multicast) */    for (j = 0; j < 3; j++) { /* receive ports (RTP, RTCP), send */      side[i][j].sock = socket(PF_INET, SOCK_DGRAM, 0);      if (side[i][j].sock < 0) {        perror("socket");        exit(1);      }      if (setsockopt(side[i][j].sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse,                   sizeof(reuse)) == -1)        perror("setsockopt: reuseaddr");      if (j < 2) {        side[i][j].sin = host[i].sin;        side[i][j].sin.sin_port = htons(ntohs(host[i].sin.sin_port) + j);      }      else {        side[i][j].sin.sin_addr.s_addr = INADDR_ANY;        side[i][j].sin.sin_port = 0;      }      /* Bind to multicast address. */      sin = side[i][j].sin;      if (IN_CLASSD(host[i].sin.sin_addr.s_addr)) {        if (!multi_sock[j]) {          multi_sock[j]=side[i][j].sock;  /* save number of multicast socket */        }        if (j < 2 && setsockopt(side[i][j].sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,            (char *)&host[i].mreq, sizeof(host[i].mreq)) < 0) {            perror("IP_ADD_MEMBERSHIP");            exit(1);        }        if (j==2 && setsockopt(side[i][j].sock, IPPROTO_IP, IP_MULTICAST_TTL,            (char *)&host[i].ttl, sizeof(host[i].ttl)) < 0) {          perror("IP_MULTICAST_TTL");          exit(1);        }again:        if (bind(side[i][j].sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {          if (errno == EADDRNOTAVAIL) {            sin.sin_addr.s_addr = INADDR_ANY;            goto again;          }          else {            perror("bind multicast");            exit(1);          }        }        if (j==2 && setsockopt(side[i][j].sock, IPPROTO_IP, IP_MULTICAST_LOOP,            (char *)&loop, sizeof(loop)) < 0) {          perror("IP_MULTICAST_LOOP");          exit(1);        }      } /* multicast */      /* unicast */      else {        sin.sin_addr.s_addr = INADDR_ANY;        if (bind(side[i][j].sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {          perror("bind unicast");          exit(1);        }      }      if (j < 2) {        notify_set_input_func((Notify_client)j, socket_handler,           side[i][j].sock);      }    } /* for j (protocols) */  } /* for i (hosts) */  if ((c = notify_start()) != NOTIFY_OK) {    fprintf(stderr, "%s: Notifier error %d.\n", argv[0], c);    perror("select");  };  return 0;} /* main */

⌨️ 快捷键说明

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