/* raw_rcv.c * * Receive raw data from network, * parse the packet header to decide where to put the packet data into * display a frame after it is ready */ #include #include #include /* struct sockaddr_in */ #include /* inet_ntoa() */ #include /* gettimeofday() */ #include #include #include #include #include /* select(), perror() */ #include /* getopt(), atoi() */ // header from receiver.c #include #include #include #if !defined(nextstep) #include #endif #include "raw_rtp.h" #include "ansi.h" #include "sysdep.h" #include "X11/Xlib.h" #include "X11/Xutil.h" #include "svm.h" #include "segment.h" #define OFFSET 0 /* headroom for image processing */ /* my definition starts here */ #define DISP_MAG 2 typedef struct noname2 { unsigned char img[FW*FH]; u_int32 ts; int flag; } DISPBUF; unsigned char bg[FW*FH]; DISPBUF dispBuf; // end of header from receiver.c #define VERSION "1.0" static int verbose = 1; /* decode */ static void usage(char *argv0) { fprintf(stderr, "Usage: %s [IP]/port\n", argv0); } static void done(int sig) { exit(0); } static double tdbl(struct timeval *a) { return a->tv_sec + a->tv_usec/1e6; } /* * Open network sockets. */ static int open_network(char *host, int sock[], struct sockaddr_in *sin) { struct ip_mreq mreq; /* multicast group */ int i; int nfds = 0; extern int hpt(char *h, struct sockaddr *sa, unsigned char *ttl); #ifdef DEBUG printf(" host = %s\n", host); #endif if (hpt(host, (struct sockaddr *)sin, 0) < 0) { usage(""); } /* multicast */ if (host) { mreq.imr_multiaddr = sin->sin_addr; mreq.imr_interface.s_addr = htonl(INADDR_ANY); sin->sin_addr = mreq.imr_multiaddr; } /* unicast */ else { mreq.imr_multiaddr.s_addr = INADDR_ANY; sin->sin_addr.s_addr = INADDR_ANY; } /* create/bind sockets */ for (i = 0; i < 2; i++) { int one = 1; /* open data socket only if necessary */ // sock[i] = -1; sock[i] = socket(PF_INET, SOCK_DGRAM, 0); #ifdef DEBUG printf("SOCK[%d] is %d\n", i, sock[i]); #endif if (sock[i] < 0) { perror("socket"); exit(1); } if (sock[i] > nfds) nfds = sock[i]; if (IN_CLASSD(ntohl(mreq.imr_multiaddr.s_addr))) { if (setsockopt(sock[i], SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) perror("setsockopt: reuseaddr"); } #ifdef SO_REUSEPORT /* BSD 4.4 */ if (setsockopt(sock[i], SOL_SOCKET, SO_REUSEPORT, (char *) &one, sizeof(one)) == -1) perror("setsockopt: reuseport"); #endif sin->sin_port = htons(ntohs(sin->sin_port) + i); if (bind(sock[i], (struct sockaddr *)sin, sizeof(*sin)) < 0) { if (errno == EADDRNOTAVAIL) { sin->sin_addr.s_addr = INADDR_ANY; if (bind(sock[i], (struct sockaddr *)sin, sizeof(*sin)) < 0) { perror("bind"); exit(1); } } else { perror("bind"); exit(1); } } if (IN_CLASSD(ntohl(mreq.imr_multiaddr.s_addr))) { if (setsockopt(sock[i], IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { perror("IP_ADD_MEMBERSHIP"); exit(1); } } } return nfds; } /* open_network */ void packet_handler(struct timeval now, struct sockaddr_in sin, int len, u_int8* packet) { int x, y, width, height; u_int32 offset; int i, mark, k, jump, data_len; unsigned char *ptr; static long tt; rtp_hdr_t *r = (rtp_hdr_t *)packet; struct jpeghdr *raw = (struct jpeghdr*)(packet+RTP_HDR_SZ); printf("%8ld.%06ld len=%d from=%s:%u \n", now.tv_sec, now.tv_usec,len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); if (len < RTP_HDR_SZ) { printf("RTP header too short (%d bytes for %d CSRCs).\n", len, r->cc); exit(0); } printf( "v=%d p=%d x=%d cc=%d m=%d pt=%d seq=%u ts=%lu ssrc=0x%lx\n", r->version, r->p, r->x, r->cc, r->m,r->pt,ntohs(r->seq), (unsigned long)ntohl(r->ts),(unsigned long)ntohl(r->ssrc)); if(r->m == 1) printf("end of frame \n"); /* start of a new frame*/ if (dispBuf.ts == 0) { dispBuf.ts = (unsigned long)ntohl(r->ts); if (tt > 8) { memcpy (dispBuf.img, bg, FW*FH); } } /*current frame */ else if (dispBuf.ts == (unsigned long)ntohl(r->ts)) { offset = ntohl(raw->off); x = 2*raw->x; y = 2*raw->y; width = 2*raw->width; height = 2*raw->height; mark = x+width; x += offset%width; y += offset/width; k = y*FW + x; jump = FW - width; data_len = len - TOTHDR; ptr = (unsigned char *)(packet + TOTHDR); for (i=0;im) { if (tt == 8) memcpy (bg, dispBuf.img, FW*FH); tt ++; dispBuf.flag = 1; dispBuf.ts = 0; printf ("end of frame, ready for display"); } } /* if ts > current ts, flush current buffer and increase dispBuf.ts */ else if( dispBuf.ts < (unsigned long)ntohl(r->ts)) { dispBuf.flag = 1; dispBuf.ts = (unsigned long)ntohl(r->ts); } else printf(" sorry discarded! your frame is flushed already! \n"); printf ("seq = %u\n",ntohs(r->seq)); if (r->m) { printf ("---------end of frame\n"); } #ifdef DEBUG printf(" offset in packet is %u\n", raw->off); #endif } int main(int argc, char *argv[]) { int c; struct sockaddr_in sin; struct timeval start; struct timeval timeout; /* timeout to limit recording */ double dstart; /* time as double */ int duration = 1000000; /* maximum duration in seconds */ int sock[2]; fd_set readfds; extern char *optarg; extern int optind; int i; int nfds = 0; extern double tdbl(struct timeval *); // declarations from receiver.c XImage *xim1; /* image buffers for display */ Window win1; /* display windows */ GC gc1; // end of declarations from receiver.c // overhead of initializing hardware and XWindows stuff svmOpenDisplay(NULL); /* svmDisplay and svmScreen are the display and screen used by SVM. */ win1 = XCreateSimpleWindow(svmDisplay, DefaultRootWindow(svmDisplay), 0, 0, FW*DISP_MAG, FH*DISP_MAG, 2, BlackPixel(svmDisplay, svmScreen), BlackPixel(svmDisplay, svmScreen)); XMapWindow(svmDisplay, win1); gc1 = XCreateGC(svmDisplay,win1,0,NULL); /* svmColormap is the colormap used by SVM */ XSetWindowColormap(svmDisplay,win1,svmColormap); /* get a place to store the images */ xim1 = svmGetImageBuffer(win1, FW*DISP_MAG, FH*DISP_MAG); memset (dispBuf.img, 0, FW*FH); dispBuf.ts = 0; dispBuf.flag = 0; // end of initializing hardware and XWindows startupSocket(); while ((c = getopt(argc, argv, "h")) != EOF) { switch(c) { case 'h': usage(argv[0]); exit(1); break; } } /* set maximum time to gather packets */ timeout.tv_usec = 0; timeout.tv_sec = duration; /* if no optional arguments, we are reading from a file */ if (optind < argc) { #ifdef DEBUG printf("%s\n", argv[optind]); #endif nfds = open_network(argv[optind],sock, &sin); gettimeofday(&start, 0); dstart = tdbl(&start); #ifdef DEBUG printf("%f\n", dstart); #endif } /* signal handler */ signal(SIGINT, done); signal(SIGTERM, done); signal(SIGHUP, done); #ifdef DEBUG printf("after signals\n"); #endif /* main loop */ while (1) { int len; u_int8 packet_buf[PACKET_SIZE]; struct timeval now; double dnow; FD_ZERO(&readfds); if (sock[0] >= 0) FD_SET(sock[0], &readfds); if (sock[1] >= 0) FD_SET(sock[1], &readfds); c = select(nfds+1, &readfds, 0, 0, &timeout); if (c < 0) { perror("select"); exit(1); } /* end of recording time reached */ else if (c == 0) { if (verbose) fprintf(stderr, "Time limit reached.\n"); exit(0); } for (i = 0; i < 2; i++) { if (sock[i] >= 0 && FD_ISSET(sock[i], &readfds)) { int alen = sizeof(sin); /* subtract elapsed time from remaining timeout */ gettimeofday(&now, 0); dnow = tdbl(&now); timeout.tv_sec = duration - (dnow - dstart); if (timeout.tv_sec < 0) timeout.tv_sec = 0; len = recvfrom(sock[i], packet_buf, sizeof(packet_buf), 0, (struct sockaddr *)&sin, &alen); if(len > 0) packet_handler(now, sin, len, packet_buf); if (dispBuf.flag) { printf ("in display\n"); svmConvertImage(dispBuf.img, xim1->data, svmNONE, FW, FH, FW, FW, svmDepth, DISP_MAG, OFFSET, OFFSET); svmDisplayImage(xim1, win1, gc1, 0, 0); dispBuf.flag = 0; } } } } return 0; } /* main */