X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/210d172f0776d7144b26c46a061b1a9d6bca9599..11680e1989c6c867f207be7197602776e05cae6a:/clients/rtpmon.c diff --git a/clients/rtpmon.c b/clients/rtpmon.c index 66e2f01..32974e8 100644 --- a/clients/rtpmon.c +++ b/clients/rtpmon.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "syscalls.h" #include "timeval.h" @@ -61,7 +62,7 @@ static unsigned bpf = 4; static uint32_t serial; /** @brief Size of ring buffer */ -#define RINGSIZE 16384 +#define RINGSIZE 131072 /** @brief Ring buffer */ static struct entry ring[RINGSIZE]; @@ -104,14 +105,23 @@ static double rate(unsigned earlier, unsigned later) { * @param n How many frames of audio data we received */ static void frames(const struct timeval *when, size_t n) { + const time_t prev = ring[(ringtail - 1) % RINGSIZE].when.tv_sec; + ring[ringtail].when = *when; ring[ringtail].serial = serial; serial += n; ringtail = (ringtail + 1) % RINGSIZE; - // Report rates every couple of hundred packets - if(!(ringtail & 1023)) { - - if(printf("%8.2f %8.2f %8.2f\n", + // Report once a second + if(prev != when->tv_sec) { + if(printf("%8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f\n", + rate((ringtail - RINGSIZE / 128) % RINGSIZE, + (ringtail - 1) % RINGSIZE), + rate((ringtail - RINGSIZE / 64) % RINGSIZE, + (ringtail - 1) % RINGSIZE), + rate((ringtail - RINGSIZE / 32) % RINGSIZE, + (ringtail - 1) % RINGSIZE), + rate((ringtail - RINGSIZE / 16) % RINGSIZE, + (ringtail - 1) % RINGSIZE), rate((ringtail - RINGSIZE / 8) % RINGSIZE, (ringtail - 1) % RINGSIZE), rate((ringtail - RINGSIZE / 4) % RINGSIZE, @@ -119,7 +129,7 @@ static void frames(const struct timeval *when, size_t n) { rate((ringtail - RINGSIZE / 2) % RINGSIZE, (ringtail - 1) % RINGSIZE)) < 0 || fflush(stdout) < 0) - fatal(errno, "stdout"); + disorder_fatal(errno, "stdout"); } } @@ -149,13 +159,13 @@ int main(int argc, char **argv) { mem_init(); if(!setlocale(LC_CTYPE, "")) - fatal(errno, "error calling setlocale"); + disorder_fatal(errno, "error calling setlocale"); while((n = getopt_long(argc, argv, "hVb:", options, 0)) >= 0) { switch(n) { case 'h': help(); case 'V': version("rtpmon"); case 'b': bpf = atoi(optarg); break; - default: fatal(0, "invalid option"); + default: disorder_fatal(0, "invalid option"); } } argc -= optind; @@ -168,7 +178,7 @@ int main(int argc, char **argv) { sl.s = argv; break; default: - fatal(0, "usage: rtpmon [OPTIONS] [ADDRESS] PORT"); + disorder_fatal(0, "usage: rtpmon [OPTIONS] [ADDRESS] PORT"); } if(!(res = get_address(&sl, &prefs, &sockname))) exit(1); @@ -176,7 +186,7 @@ int main(int argc, char **argv) { if((rtpfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) - fatal(errno, "error creating socket"); + disorder_fatal(errno, "error creating socket"); /* Allow multiple listeners */ xsetsockopt(rtpfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); is_multicast = multicast(res->ai_addr); @@ -194,11 +204,12 @@ int main(int argc, char **argv) { mgroup.in6.sin6_port = 0; break; default: - fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family); + disorder_fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family); } /* Bind to to the multicast group address */ if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0) - fatal(errno, "error binding socket to %s", format_sockaddr(res->ai_addr)); + disorder_fatal(errno, "error binding socket to %s", + format_sockaddr(res->ai_addr)); /* Add multicast group membership */ switch(mgroup.sa.sa_family) { case PF_INET: @@ -206,21 +217,21 @@ int main(int argc, char **argv) { mreq.imr_interface.s_addr = 0; /* use primary interface */ if(setsockopt(rtpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof mreq) < 0) - fatal(errno, "error calling setsockopt IP_ADD_MEMBERSHIP"); + disorder_fatal(errno, "error calling setsockopt IP_ADD_MEMBERSHIP"); break; case PF_INET6: mreq6.ipv6mr_multiaddr = mgroup.in6.sin6_addr; memset(&mreq6.ipv6mr_interface, 0, sizeof mreq6.ipv6mr_interface); if(setsockopt(rtpfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof mreq6) < 0) - fatal(errno, "error calling setsockopt IPV6_JOIN_GROUP"); + disorder_fatal(errno, "error calling setsockopt IPV6_JOIN_GROUP"); break; default: - fatal(0, "unsupported address family %d", res->ai_family); + disorder_fatal(0, "unsupported address family %d", res->ai_family); } /* Report what we did */ - info("listening on %s multicast group %s", - format_sockaddr(res->ai_addr), format_sockaddr(&mgroup.sa)); + disorder_info("listening on %s multicast group %s", + format_sockaddr(res->ai_addr), format_sockaddr(&mgroup.sa)); } else { /* Bind to 0/port */ switch(res->ai_addr->sa_family) { @@ -229,8 +240,8 @@ int main(int argc, char **argv) { memset(&in->sin_addr, 0, sizeof (struct in_addr)); if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0) - fatal(errno, "error binding socket to 0.0.0.0 port %d", - ntohs(in->sin_port)); + disorder_fatal(errno, "error binding socket to 0.0.0.0 port %d", + ntohs(in->sin_port)); break; } case AF_INET6: { @@ -240,12 +251,13 @@ int main(int argc, char **argv) { break; } default: - fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family); + disorder_fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family); } if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0) - fatal(errno, "error binding socket to %s", format_sockaddr(res->ai_addr)); + disorder_fatal(errno, "error binding socket to %s", + format_sockaddr(res->ai_addr)); /* Report what we did */ - info("listening on %s", format_sockaddr(res->ai_addr)); + disorder_info("listening on %s", format_sockaddr(res->ai_addr)); } for(;;) { struct rtp_header header; @@ -264,11 +276,11 @@ int main(int argc, char **argv) { case EINTR: continue; default: - fatal(errno, "error reading from socket"); + disorder_fatal(errno, "error reading from socket"); } } if((size_t)n <= sizeof (struct rtp_header)) { - info("ignored a short packet"); + disorder_info("ignored a short packet"); continue; } frames(&when, (n - sizeof header) / bpf);