28 #include <sys/socket.h> 29 #include <netinet/in.h> 30 #include <sys/types.h> 32 #include <arpa/inet.h> 36 #define TS_PACKET_SIZE 188 39 static long long int usecDiff(
struct timespec* time_stop,
struct timespec* time_start)
41 long long int temp = 0;
42 long long int utemp = 0;
44 if (time_stop && time_start) {
45 if (time_stop->tv_nsec >= time_start->tv_nsec) {
46 utemp = time_stop->tv_nsec - time_start->tv_nsec;
47 temp = time_stop->tv_sec - time_start->tv_sec;
49 utemp = time_stop->tv_nsec + 1000000000 - time_start->tv_nsec;
50 temp = time_stop->tv_sec - 1 - time_start->tv_sec;
52 if (temp >= 0 && utemp >= 0) {
53 temp = (temp * 1000000000) + utemp;
55 fprintf(stderr,
"start time %ld.%ld is after stop time %ld.%ld\n", time_start->tv_sec, time_start->tv_nsec, time_stop->tv_sec, time_stop->tv_nsec);
59 fprintf(stderr,
"memory is garbaged?\n");
67 int tsudpsend(
int argc,
char *argv[],
volatile int *exit_flag)
75 unsigned char option_ttl;
77 struct sockaddr_in addr;
78 unsigned long int packet_size;
80 unsigned char* send_buf;
82 unsigned long long int packet_time;
83 unsigned long long int real_time;
84 struct timespec time_start;
85 struct timespec time_stop;
86 struct timespec nano_sleep_packet;
90 memset(&addr, 0,
sizeof(addr));
91 memset(&time_start, 0,
sizeof(time_start));
92 memset(&time_stop, 0,
sizeof(time_stop));
93 memset(&nano_sleep_packet, 0,
sizeof(nano_sleep_packet));
96 fprintf(stderr,
"Usage: %s file.ts ipaddr port bitrate [ts_packet_per_ip_packet] [udp_packet_ttl]\n", argv[0]);
97 fprintf(stderr,
"ts_packet_per_ip_packet default is 7\n");
98 fprintf(stderr,
"bit rate refers to transport stream bit rate\n");
99 fprintf(stderr,
"zero bitrate is 100.000.000 bps\n");
103 addr.sin_family = AF_INET;
104 addr.sin_addr.s_addr = inet_addr(argv[2]);
105 addr.sin_port = htons(atoi(argv[3]));
106 bitrate = atoi(argv[4]);
111 packet_size = strtoul(argv[5], 0, 0) * TS_PACKET_SIZE;
113 packet_size = 7 * TS_PACKET_SIZE;
117 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
119 perror(
"socket(): error ");
124 option_ttl = atoi(argv[6]);
126 memcpy(start_addr, argv[2], 3);
128 is_multicast = atoi(start_addr);
129 is_multicast = (is_multicast >= 224) || (is_multicast <= 239);
131 ret = setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &option_ttl,
sizeof(option_ttl));
133 ret = setsockopt(sockfd, IPPROTO_IP, IP_TTL, &option_ttl,
sizeof(option_ttl));
137 perror(
"ttl configuration fail");
142 transport_fd = open(tsfile, O_RDONLY);
143 if(transport_fd < 0) {
144 fprintf(stderr,
"can't open file %s\n", tsfile);
150 send_buf = malloc(packet_size);
154 nano_sleep_packet.tv_nsec = 665778;
156 clock_gettime(CLOCK_MONOTONIC, &time_start);
159 printf(
"starting streaming... \n");
160 while (!completed && !(*exit_flag) ) {
163 clock_gettime(CLOCK_MONOTONIC, &time_stop);
164 real_time = usecDiff(&time_stop, &time_start);
165 while (real_time * bitrate > packet_time * 1000000 && !completed &&
167 len = read(transport_fd, send_buf, packet_size);
169 fprintf(stderr,
"ts file read error \n");
171 }
else if (len == 0) {
172 fprintf(stderr,
"ts sent done\n");
175 sent = sendto(sockfd, send_buf, len, 0, (
struct sockaddr *)&addr,
sizeof(
struct sockaddr_in));
177 perror(
"send(): error ");
180 packet_time += packet_size * 8;
184 nanosleep(&nano_sleep_packet, 0);
Header file for 3rd party source code "tsudpsend.c".