Browse Source

Rewrite input address parsing to allow rtp and udp inputs.

Georgi Chorbadzhiyski 10 years ago
parent
commit
1c83de1881
5 changed files with 46 additions and 34 deletions
  1. 3
    0
      ChangeLog
  2. 21
    16
      tsdumper2.c
  3. 4
    5
      tsdumper2.h
  4. 17
    12
      util.c
  5. 1
    1
      util.h

+ 3
- 0
ChangeLog View File

1
+xxxx-xx-xx : Version -dev
2
+ * Add support for RTP input.
3
+
1
 2013-07-22 : Version 0.9
4
 2013-07-22 : Version 0.9
2
  * Initial public release.
5
  * Initial public release.

+ 21
- 16
tsdumper2.c View File

66
 	printf(" -D --create-dirs           | Save files in subdirs YYYY/MM/DD/HH/file.\n");
66
 	printf(" -D --create-dirs           | Save files in subdirs YYYY/MM/DD/HH/file.\n");
67
 	printf("\n");
67
 	printf("\n");
68
 	printf("Input options:\n");
68
 	printf("Input options:\n");
69
-	printf(" -i --input <source>        | Where to read from. Multicast address.\n");
69
+	printf(" -i --input <source>        | Where to read from.\n");
70
 	printf("                            .  -i udp://224.0.0.1:5000    (v4 multicast)\n");
70
 	printf("                            .  -i udp://224.0.0.1:5000    (v4 multicast)\n");
71
 	printf("                            .  -i udp://[ff01::1111]:5000 (v6 multicast)\n");
71
 	printf("                            .  -i udp://[ff01::1111]:5000 (v6 multicast)\n");
72
+	printf("                            .  -i rtp://224.0.0.1:5000    (v4 RTP input)\n");
73
+	printf("                            .  -i rtp://[ff01::1111]:5000 (v6 RTP input)\n");
72
 	printf(" -z --input-ignore-disc     | Do not report discontinuty errors in input.\n");
74
 	printf(" -z --input-ignore-disc     | Do not report discontinuty errors in input.\n");
73
 	printf(" -4 --ipv4                  | Use only IPv4 addresses.\n");
75
 	printf(" -4 --ipv4                  | Use only IPv4 addresses.\n");
74
 	printf(" -6 --ipv6                  | Use only IPv6 addresses.\n");
76
 	printf(" -6 --ipv6                  | Use only IPv6 addresses.\n");
79
 	printf("\n");
81
 	printf("\n");
80
 }
82
 }
81
 
83
 
82
-static int parse_io_param(struct io *io, char *opt) {
83
-	int port_set = 0;
84
-	io->type = NET_IO;
85
-	int host_set = parse_host_and_port(opt, &io->hostname, &io->service, &port_set);
86
-	return !(!port_set || !host_set);
87
-}
88
-
89
 extern char *optarg;
84
 extern char *optarg;
90
 extern int optind, opterr, optopt;
85
 extern int optind, opterr, optopt;
91
 
86
 
111
 				ts->create_dirs = !ts->create_dirs;
106
 				ts->create_dirs = !ts->create_dirs;
112
 				break;
107
 				break;
113
 			case 'i': // --input
108
 			case 'i': // --input
114
-				input_addr_err = !parse_io_param(&ts->input, optarg);
109
+				input_addr_err = !parse_host_and_port(optarg, &ts->input);
115
 				break;
110
 				break;
116
 			case 'z': // --input-ignore-disc
111
 			case 'z': // --input-ignore-disc
117
 				ts->ts_discont = !ts->ts_discont;
112
 				ts->ts_discont = !ts->ts_discont;
140
 	}
135
 	}
141
 
136
 
142
 	p_info("Prefix     : %s\n", ts->prefix);
137
 	p_info("Prefix     : %s\n", ts->prefix);
143
-	p_info("Input addr : udp://%s:%s/\n", ts->input.hostname, ts->input.service);
138
+	p_info("Input addr : %s://%s:%s/\n",
139
+		ts->input.type == UDP ? "udp" :
140
+		ts->input.type == RTP ? "rtp" : "???",
141
+		ts->input.hostname, ts->input.service);
144
 	p_info("Seconds    : %u\n", ts->rotate_secs);
142
 	p_info("Seconds    : %u\n", ts->rotate_secs);
145
 	p_info("Output dir : %s (create directories: %s)\n", ts->output_dir,
143
 	p_info("Output dir : %s (create directories: %s)\n", ts->output_dir,
146
 		ts->create_dirs ? "YES" : "no");
144
 		ts->create_dirs ? "YES" : "no");
204
 static struct ts ts;
202
 static struct ts ts;
205
 
203
 
206
 int main(int argc, char **argv) {
204
 int main(int argc, char **argv) {
207
-	ssize_t readen;
208
 	int i;
205
 	int i;
209
 	int have_data = 1;
206
 	int have_data = 1;
210
 	int ntimeouts = 0;
207
 	int ntimeouts = 0;
244
 
241
 
245
 	p_info("Start %s\n", program_id);
242
 	p_info("Start %s\n", program_id);
246
 
243
 
247
-	if (ts.input.type == NET_IO && udp_connect_input(&ts.input) < 1)
248
-		goto EXIT;
244
+	switch (ts.input.type) {
245
+	case UDP:
246
+	case RTP:
247
+		if (udp_connect_input(&ts.input) < 1)
248
+			exit(EXIT_FAILURE);
249
+		break;
250
+	}
249
 
251
 
250
 	signal(SIGCHLD, SIG_IGN);
252
 	signal(SIGCHLD, SIG_IGN);
251
 	signal(SIGPIPE, SIG_IGN);
253
 	signal(SIGPIPE, SIG_IGN);
257
 
259
 
258
 	int data_received = 0;
260
 	int data_received = 0;
259
 	do {
261
 	do {
262
+		ssize_t readen = -1;
260
 		set_log_io_errors(0);
263
 		set_log_io_errors(0);
261
-		if (!ts.rtp_input) {
264
+		switch (ts.input.type) {
265
+		case UDP:
262
 			readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE, 250, 4, 1);
266
 			readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE, 250, 4, 1);
263
-		} else {
267
+			break;
268
+		case RTP:
264
 			readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE + RTP_HDR_SZ, 250, 4, 1);
269
 			readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE + RTP_HDR_SZ, 250, 4, 1);
265
 			if (readen > RTP_HDR_SZ) {
270
 			if (readen > RTP_HDR_SZ) {
266
 				memcpy(rtp_hdr[rtp_hdr_pos], ts_packet, RTP_HDR_SZ);
271
 				memcpy(rtp_hdr[rtp_hdr_pos], ts_packet, RTP_HDR_SZ);
275
 							pssrc, ssrc, ((ssrc - pssrc)-1) & 0xffff);
280
 							pssrc, ssrc, ((ssrc - pssrc)-1) & 0xffff);
276
 				num_packets++;
281
 				num_packets++;
277
 			}
282
 			}
283
+			break;
278
 		}
284
 		}
279
 		set_log_io_errors(1);
285
 		set_log_io_errors(1);
280
 		if (readen < 0) {
286
 		if (readen < 0) {
297
 		if (!keep_running)
303
 		if (!keep_running)
298
 			break;
304
 			break;
299
 	} while (have_data);
305
 	} while (have_data);
300
-EXIT:
301
 
306
 
302
 	queue_add(ts.packet_queue, ts.current_packet);
307
 	queue_add(ts.packet_queue, ts.current_packet);
303
 	queue_add(ts.packet_queue, NULL); // Exit write_thread
308
 	queue_add(ts.packet_queue, NULL); // Exit write_thread

+ 4
- 5
tsdumper2.h View File

20
 #include <stdbool.h>
20
 #include <stdbool.h>
21
 
21
 
22
 #include "libfuncs/libfuncs.h"
22
 #include "libfuncs/libfuncs.h"
23
-#include "util.h"
24
 
23
 
25
 // Supported values 0, 1 and 2. Higher value equals more spam in the log.
24
 // Supported values 0, 1 and 2. Higher value equals more spam in the log.
26
 #define DEBUG 0
25
 #define DEBUG 0
32
 #define THREAD_STACK_SIZE (64 * 1024)
31
 #define THREAD_STACK_SIZE (64 * 1024)
33
 
32
 
34
 enum io_type {
33
 enum io_type {
35
-	FILE_IO,
36
-	NET_IO,
37
-	WTF_IO
34
+	UDP,
35
+	RTP,
38
 };
36
 };
39
 
37
 
40
 // 1.2MB = ~13Mbit/s
38
 // 1.2MB = ~13Mbit/s
72
 	int					create_dirs;
70
 	int					create_dirs;
73
 	int					rotate_secs;
71
 	int					rotate_secs;
74
 	int					ts_discont;
72
 	int					ts_discont;
75
-	int					rtp_input;
76
 	struct io			input;
73
 	struct io			input;
77
 
74
 
78
 	pthread_attr_t		thread_attr;
75
 	pthread_attr_t		thread_attr;
91
 	char				output_full_filename[OUTFILE_NAME_MAX];
88
 	char				output_full_filename[OUTFILE_NAME_MAX];
92
 };
89
 };
93
 
90
 
91
+#include "util.h"
92
+
94
 // From tsdumper2.c
93
 // From tsdumper2.c
95
 struct packet *alloc_packet(struct ts *ts);
94
 struct packet *alloc_packet(struct ts *ts);
96
 void free_packet(struct packet *packet);
95
 void free_packet(struct packet *packet);

+ 17
- 12
util.c View File

41
 
41
 
42
 #endif
42
 #endif
43
 
43
 
44
-int parse_host_and_port(char *input, char **hostname, char **service, int *port_set) {
44
+int parse_host_and_port(char *input, struct io *io) {
45
+	int port_set = 0;
45
 	char *p, *proto;
46
 	char *p, *proto;
47
+	io->type = UDP;
46
 	if (strlen(input) == 0)
48
 	if (strlen(input) == 0)
47
 		return 0;
49
 		return 0;
48
-	proto = strstr(input, "http://");
49
-	if (proto == input)
50
-		die("HTTP input is unsupported (patch welcome): %s", input);
50
+	if (strstr(input, "udp://") == input)       io->type = UDP;
51
+	else if (strstr(input, "rtp://") == input)  io->type = RTP;
52
+	else
53
+		die("Unsupported protocol (patch welcome): %s", input);
51
 	proto = strstr(input, "://");
54
 	proto = strstr(input, "://");
52
 	if (proto)
55
 	if (proto)
53
 		input = proto + 3;
56
 		input = proto + 3;
54
-	*hostname = input;
57
+	io->hostname = input;
55
 	if (input[0] == '[') { // Detect IPv6 static address
58
 	if (input[0] == '[') { // Detect IPv6 static address
56
 		p = strrchr(input, ']');
59
 		p = strrchr(input, ']');
57
 		if (!p)
60
 		if (!p)
58
 			die("Invalid IPv6 address format: %s\n", input);
61
 			die("Invalid IPv6 address format: %s\n", input);
59
-		*hostname = input + 1; // Remove first [
62
+		io->hostname = input + 1; // Remove first [
60
 		*p = 0x00; // Remove last ]
63
 		*p = 0x00; // Remove last ]
61
 		char *p2 = strchr(p + 1, ':');
64
 		char *p2 = strchr(p + 1, ':');
62
 		if (p2) {
65
 		if (p2) {
63
 			*p2 = 0x00;
66
 			*p2 = 0x00;
64
-			*service = p2 + 1;
65
-			*port_set = 1;
67
+			io->service = p2 + 1;
68
+			port_set = 1;
66
 		}
69
 		}
67
 	} else {
70
 	} else {
68
 		p = strrchr(input, ':');
71
 		p = strrchr(input, ':');
69
 		if (p) {
72
 		if (p) {
70
 			*p = 0x00;
73
 			*p = 0x00;
71
-			*service = p + 1;
72
-			*port_set = 1;
74
+			io->service = p + 1;
75
+			port_set = 1;
73
 		}
76
 		}
74
 	}
77
 	}
75
-	if (*service) {
76
-		char *path = strstr(*service, "/");
78
+	if (io->service) {
79
+		char *path = strstr(io->service, "/");
77
 		if (path)
80
 		if (path)
78
 			path[0] = 0;
81
 			path[0] = 0;
79
 	}
82
 	}
83
+	if (!port_set)
84
+		die("Port is not set in the input url.");
80
 	return 1;
85
 	return 1;
81
 }
86
 }
82
 
87
 

+ 1
- 1
util.h View File

20
 
20
 
21
 void set_thread_name(char *thread_name);
21
 void set_thread_name(char *thread_name);
22
 
22
 
23
-int parse_host_and_port(char *input, char **hostname, char **service, int *port_set);
23
+int parse_host_and_port(char *input, struct io *io);
24
 char *my_inet_ntop(int family, struct sockaddr *addr, char *dest, int dest_len);
24
 char *my_inet_ntop(int family, struct sockaddr *addr, char *dest, int dest_len);
25
 
25
 
26
 int create_dir(const char *dir, mode_t mode);
26
 int create_dir(const char *dir, mode_t mode);

Loading…
Cancel
Save