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