#include #include #include #include #include #include #include #include #include #include /* gettimeofday() */ #include /* inet_ntoa() */ #include #include /* write() */ #include #include "raw_rtp.h" #include "ansi.h" #include "sysdep.h" #include "global.h" #include "md5.h" #define MD_CTX MD5_CTX #define MDInit MD5Init #define MDUpdate MD5Update #define MDFinal MD5Final #define DEBUG static int verbose = 0; static FILE *in = stdin; static int sock[2]; /* output sockets */ static int loop = 0; /* play file indefinitely */ static u_long md_32(char *string, int length); u_int32 random32(int type); void getLocal(struct sockaddr_in *p, int ssock); int send_handler(u_int8 *raw_data, int buf, int nfds); u_int16 SendFrame(u_int16 start_seq, u_int32 ts, u_int32 ssrc, u_int8 *jpeg_data, int len, u_int8 x, u_int8 y, int width, int height); static void usage(char *argv0); int GetSendSocekt(char *host, struct sockaddr_in *sin, unsigned char *ttl, char* argv0); extern double tdbl(struct timeval *a); extern struct timeval db2tv(double d); extern void getLocal(struct sockaddr_in *p, int ssock); extern int OpenSock(u_int32_t addr, u_short port, unsigned char* ttl); extern char *optarg; extern int optind; extern int hpt(char *h, struct sockaddr *sa, unsigned char *ttl); static void usage(char *argv0) { fprintf(stderr, "Usage: %s [-f raw_date] [-l loop] [-b length_of_image][multicast]/port\n", argv0); } static u_long md_32(char *string, int length) { MD_CTX context; union { char c[16]; u_long x[4]; } digest; u_long r; int i; MDInit (&context); MDUpdate (&context, string, length); MDFinal ((unsigned char *)&digest, &context); r = 0; for (i = 0; i < 3; i++) { r ^= digest.x[i]; } return r; } /* md_32 */ /* * Return random unsigned 32-bit quantity. Use 'type' argument if you * need to generate several different values in close succession. */ u_int32 random32(int type) { struct { int type; struct timeval tv; clock_t cpu; pid_t pid; u_long hid; uid_t uid; gid_t gid; struct utsname name; } s; gettimeofday(&s.tv, 0); uname(&s.name); s.type = type; s.cpu = clock(); s.pid = getpid(); s.hid = gethostid(); s.uid = getuid(); s.gid = getgid(); return md_32((char *)&s, sizeof(s)); } /* random32 */ /* static int rtp(char *packet,int pad, int cc, int marker, int pt, u_int16 seq, u_int32 timestamp) { rtp_hdr_t *h = (rtp_hdr_t *)packet; int length = 0; memset(packet, 0, sizeof(rtp_hdr_t)); h->version = RTP_VERSION; h->p = pad; h->ts = htonl(timestamp); h->seq = htons(seq); h->pt = packet_type; h->ssrc = htonl(ssrc); h->p = padding; h->m = marker; } */ u_int16 SendFrame(u_int16 start_seq, u_int32 ts, u_int32 ssrc, u_int8 *jpeg_data, int len, u_int8 x, u_int8 y, int width, int height) { rtp_hdr_t rtphdr; struct jpeghdr jpghdr; u_int8 *packet_buf; u_int8 *ptr; int bytes_left = len; int data_len; /* Initialize RTP header */ rtphdr.version = 2; rtphdr.p = 0; rtphdr.x = 0; rtphdr.cc = 0; rtphdr.m = 0; rtphdr.pt = RTP_SVM_RAW; rtphdr.seq = start_seq; rtphdr.ts = htonl(ts); rtphdr.ssrc = htonl(ssrc); /* Initialize JPEG header */ //jpghdr.type =0; jpghdr.off = 0; jpghdr.x = x/2; jpghdr.y = y/2; jpghdr.width = width / 8; jpghdr.height = height / 8; packet_buf = (u_int8 *)calloc(PACKET_SIZE, sizeof(u_int8)); while (bytes_left > 0) { ptr = packet_buf + RTP_HDR_SZ; jpghdr.off = htonl(jpghdr.off); /*convert offset in hdr to network order, copy to packet*/ memcpy(ptr, &jpghdr, sizeof(jpghdr)); jpghdr.off = ntohl(jpghdr.off); ptr += sizeof(jpghdr); data_len = PACKET_SIZE - (ptr - packet_buf); if (data_len >= bytes_left) { data_len = bytes_left; rtphdr.m = 1; } rtphdr.seq = htons(rtphdr.seq); memcpy(packet_buf, &rtphdr, RTP_HDR_SZ); memcpy(ptr, jpeg_data + jpghdr.off, data_len); if(((ptr-packet_buf)+data_len) && send(sock[0], packet_buf, (ptr - packet_buf) + data_len, 0)<0) perror("hre"); jpghdr.off += data_len; bytes_left -= data_len; rtphdr.seq = ntohs(rtphdr.seq); rtphdr.seq++; } free(packet_buf); return rtphdr.seq; } int main(int argc, char *argv[]) { int buf; int nfds; unsigned char ttl = 16; static struct sockaddr_in sin; int c; char *filename = 0; unsigned char *raw_data; char *host; while ((c = getopt(argc, argv, "f:l:b:v")) != EOF) { switch(c) { case 'f': filename = optarg; break; case 'l': loop = atoi(optarg); break; case 'b': buf = atoi(optarg); case 'v': verbose = 1; break; case '?': case 'h': usage(argv[0]); break; } } if (filename) { in = fopen(filename, "rb"); if (!in) { perror(filename); exit(1); } raw_data = (unsigned char *)calloc(buf*buf, sizeof(unsigned char)); } if (optind < argc) { host = argv[optind]; } nfds = GetSendSocekt(host, &sin, &ttl, argv[0]); send_handler(raw_data, buf, nfds); return 0; } int GetSendSocekt(char *host, struct sockaddr_in *sin, unsigned char *ttl, char* argv0 ) { int i; struct sockaddr_in local; int nfds =0 ; if (hpt(host, (struct sockaddr *)sin, ttl) < 0) usage(argv0); for (i = 0; i < 2; i++) { sin->sin_port = htons(ntohs(sin->sin_port) + i); sock[i] = OpenSock(sin->sin_addr.s_addr, sin->sin_port,ttl); printf("\n"); printf("########### local socket[%d]information#############\n", i); printf(" Sending to %s\n", host); getLocal(&local, sock[i]); printf(" sock[%d] fd is %d\n", i, sock[i]); printf("########### local socket[%d] information#############\n", i); printf("\n"); if (nfds < sock[i]) nfds = sock[i]; } return nfds; } int send_handler(u_int8 *data, int buf, int nfds) { u_int32 ts; u_int32 ssrc; u_int32 start_seq = 1; struct timeval start; int i; struct sockaddr_in sin; struct timeval timeout; /* timeout to limit recording */ double dstart; /* time as double */ double duration = 0.02; /* maximum duration in seconds */ double laps; fd_set readfds; int count = 0; while(loop > 0) { gettimeofday(&start, 0); ts = (u_int32)(tdbl(&start)*1000); ssrc = random32(4); start_seq = SendFrame(start_seq, ts, ssrc, data, buf*buf, 0, 0, buf, buf); timeout.tv_usec = 200; timeout.tv_sec = 0; gettimeofday(&start, 0); dstart = tdbl(&start); while (1) { int c; int len; u_int8 rtcp_buf[100]; 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); // printf("c is %d\n", c); if (c < 0) { perror("select"); exit(1); } else if(c>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); laps = duration - (dnow - dstart); if (laps < 0){ timeout.tv_sec = 0; timeout.tv_usec = 0; } else timeout = db2tv(laps); len = recvfrom(sock[i], rtcp_buf, sizeof(rtcp_buf), 0, (struct sockaddr *)&sin, &alen); if(len > 0) printf("\n%s from sock[%d] count %d\n", rtcp_buf, i, count++); } } } /* end of recording time reached */ else if (c == 0) { // if (verbose) // fprintf(stderr, "Time limit reached.\n"); break; } } loop--; } return 0; }