Browse Source

Add support for RTP output.

Georgi Chorbadzhiyski 12 years ago
parent
commit
d4d833d3bd
9 changed files with 78 additions and 5 deletions
  1. 2
    0
      ChangeLog
  2. 1
    1
      Makefile
  3. 2
    0
      README
  4. 3
    0
      data.h
  5. 31
    1
      process.c
  6. 7
    0
      tsdecrypt.1
  7. 22
    3
      tsdecrypt.c
  8. 9
    0
      util.c
  9. 1
    0
      util.h

+ 2
- 0
ChangeLog View File

@@ -2,6 +2,8 @@ next : Version next
2 2
  * Add --output-tos (-g) option used to set output TOS value.
3 3
  * Add --input-dump (-W) option used save input stream in file.
4 4
  * Add --pid-report (-j) option used to turn on PID reporting.
5
+ * Add RTP output enabled by --output-rtp (-r) option.
6
+ * Add --output-rtp-ssrc (-k) option used to set RTP SSRC.
5 7
 
6 8
 2011-12-23 : Version 5.0
7 9
  * Add --bench (-b) option that benchmarks libdvbcsa decryption.

+ 1
- 1
Makefile View File

@@ -45,7 +45,7 @@ tsdecrypt_SRC = data.c \
45 45
  tables.c \
46 46
  notify.c \
47 47
  tsdecrypt.c
48
-tsdecrypt_LIBS = -lcrypto -ldvbcsa -lpthread
48
+tsdecrypt_LIBS = -lcrypto -ldvbcsa -lpthread -lrt
49 49
 tsdecrypt_OBJS = $(FUNCS_LIB) $(TS_LIB) $(tsdecrypt_SRC:.c=.o)
50 50
 
51 51
 ifeq "$(shell uname -s)" "Linux"

+ 2
- 0
README View File

@@ -47,6 +47,8 @@ Output options:
47 47
  -o --output-intf <addr>    | Set multicast output interface. Default: 0.0.0.0
48 48
  -t --output-ttl <ttl>      | Set multicast ttl. Default: 1
49 49
  -g --output-tos <tos>      | Set TOS value of output packets. Default: none
50
+ -r --output-rtp            | Enable RTP output.
51
+ -k --output-rtp-ssrc <id>  | Set RTP SSRC. Default: 0
50 52
  -p --no-output-filter      | Disable output filtering. Default: enabled
51 53
  -y --output-nit-pass       | Pass through NIT.
52 54
  -w --output-eit-pass       | Pass through EIT (EPG).

+ 3
- 0
data.h View File

@@ -244,6 +244,9 @@ struct ts {
244 244
 	int					ecm_cw_log;
245 245
 
246 246
 	int					rtp_input;
247
+	int					rtp_output;
248
+	uint32_t			rtp_ssrc;
249
+	uint16_t			rtp_seqnum;
247 250
 
248 251
 	struct io			input;
249 252
 	struct io			output;

+ 31
- 1
process.c View File

@@ -204,7 +204,37 @@ void *decode_thread(void *_ts) {
204 204
 static inline void output_write(struct ts *ts, uint8_t *data, unsigned int data_size) {
205 205
 	if (!data)
206 206
 		return;
207
-	write(ts->output.fd, data, data_size);
207
+	if (!ts->rtp_output) {
208
+		write(ts->output.fd, data, data_size);
209
+	} else {
210
+		struct iovec iov[2];
211
+		uint8_t rtp_header[12];
212
+		uint32_t rtime = get_time() * 9 / 100;
213
+
214
+		ts->rtp_seqnum++;
215
+
216
+		rtp_header[ 0] = 0x80;
217
+		rtp_header[ 1] = 33; // MPEG TS rtp payload type
218
+		rtp_header[ 2] = ts->rtp_seqnum >> 8;
219
+		rtp_header[ 3] = ts->rtp_seqnum & 0xff;
220
+		rtp_header[ 4] = (rtime >> 24) & 0xff;
221
+		rtp_header[ 5] = (rtime >> 16) & 0xff;
222
+		rtp_header[ 6] = (rtime >>  8) & 0xff;
223
+		rtp_header[ 7] =  rtime        & 0xff;
224
+
225
+		rtp_header[ 8] = (ts->rtp_ssrc >> 24) & 0xff;
226
+		rtp_header[ 9] = (ts->rtp_ssrc >> 16) & 0xff;
227
+		rtp_header[10] = (ts->rtp_ssrc >>  8) & 0xff;
228
+		rtp_header[11] =  ts->rtp_ssrc        & 0xff;
229
+
230
+		iov[0].iov_base = rtp_header;
231
+		iov[0].iov_len  = sizeof(rtp_header);
232
+
233
+		iov[1].iov_base = data;
234
+		iov[1].iov_len  = data_size;
235
+
236
+		writev(ts->output.fd, iov, 2);
237
+	}
208 238
 }
209 239
 
210 240
 void *write_thread(void *_ts) {

+ 7
- 0
tsdecrypt.1 View File

@@ -106,6 +106,13 @@ Set multicast ttl. The default value is \fB1\fR.
106 106
 \fB\-g\fR, \fB\-\-output\-tos\fR
107 107
 Set TOS value of output packets. The default is not to set any specific TOS.
108 108
 .TP
109
+\fB\-r\fR, \fB\-\-output\-rtp\fR
110
+Enable RTP output. The default output is standart MPEG TS over UDP, this
111
+option enables tsdecrypt to output RTP packets.
112
+.TP
113
+\fB\-k\fR, \fB\-\-output\-rtp\-ssrc\fR <ssrc>
114
+Set RTP SSRC field to <ssrc>. By default is is set to \fB0\fR.
115
+.TP
109 116
 \fB\-p\fR, \fB\-\-no\-output\-filter\fR
110 117
 Disable output filtering. By default the output filter is enabled and only
111 118
 PAT/PMT/SDT and data packets are left in the output. Everything else not

+ 22
- 3
tsdecrypt.c View File

@@ -27,6 +27,7 @@
27 27
 #include <syslog.h>
28 28
 
29 29
 #include <dvbcsa/dvbcsa.h>
30
+#include <openssl/rand.h>
30 31
 
31 32
 #include "libfuncs/libfuncs.h"
32 33
 
@@ -103,9 +104,9 @@ void run_benchmark(void) {
103 104
 	puts("* Done *");
104 105
 }
105 106
 
106
-static const char short_options[] = "i:d:N:Sl:L:I:RzM:W:O:o:t:g:pwxyc:C:A:s:U:P:B:eZ:Ef:X:H:G:KJ:D:jbhV";
107
+static const char short_options[] = "i:d:N:Sl:L:I:RzM:W:O:o:t:rk:g:pwxyc:C:A:s:U:P:B:eZ:Ef:X:H:G:KJ:D:jbhV";
107 108
 
108
-// Unused short options: FQTYakmnqruv0123456789
109
+// Unused short options: FQTYamnquv0123456789
109 110
 static const struct option long_options[] = {
110 111
 	{ "ident",				required_argument, NULL, 'i' },
111 112
 	{ "daemon",				required_argument, NULL, 'd' },
@@ -123,6 +124,8 @@ static const struct option long_options[] = {
123 124
 	{ "output",				required_argument, NULL, 'O' },
124 125
 	{ "output-intf",		required_argument, NULL, 'o' },
125 126
 	{ "output-ttl",			required_argument, NULL, 't' },
127
+	{ "output-rtp",			no_argument,       NULL, 'r' },
128
+	{ "output-rtp-ssrc",	required_argument, NULL, 'k' },
126 129
 	{ "output-tos",			required_argument, NULL, 'g' },
127 130
 	{ "output-filter",		no_argument,       NULL, 'p' },
128 131
 	{ "no-output-filter",	no_argument,       NULL, 'p' },
@@ -191,6 +194,8 @@ static void show_help(struct ts *ts) {
191 194
 	printf("                            .    -O -              (write to stdout) (default)\n");
192 195
 	printf(" -o --output-intf <addr>    | Set multicast output interface. Default: %s\n", inet_ntoa(ts->output.intf));
193 196
 	printf(" -t --output-ttl <ttl>      | Set multicast ttl. Default: %d\n", ts->output.ttl);
197
+	printf(" -r --output-rtp            | Enable RTP output.\n");
198
+	printf(" -k --output-rtp-ssrc <id>  | Set RTP SSRC. Default: %u\n", ts->rtp_ssrc);
194 199
 	printf(" -g --output-tos <tos>      | Set TOS value of output packets. Default: none\n");
195 200
 	printf(" -p --no-output-filter      | Disable output filtering. Default: %s\n", ts->pid_filter ? "enabled" : "disabled");
196 201
 	printf(" -y --output-nit-pass       | Pass through NIT.\n");
@@ -331,6 +336,12 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
331 336
 			case 't':
332 337
 				ts->output.ttl = atoi(optarg);
333 338
 				break;
339
+			case 'r':
340
+				ts->rtp_output = 1;
341
+				break;
342
+			case 'k':
343
+				ts->rtp_ssrc = strtoul(optarg, NULL, 0);
344
+				break;
334 345
 			case 'g':
335 346
 				ts->output.tos = (uint8_t)strtol(optarg, NULL, 0);
336 347
 				break;
@@ -539,11 +550,19 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
539 550
 	if (!ts->emm_only)
540 551
 	{
541 552
 		if (ts->output.type == NET_IO) {
542
-			ts_LOGf("Output addr: udp://%s:%u/\n", inet_ntoa(ts->output.addr), ts->output.port);
553
+			ts_LOGf("Output addr: %s://%s:%u/\n",
554
+				ts->rtp_output ? "rtp" : "udp",
555
+				inet_ntoa(ts->output.addr), ts->output.port);
543 556
 			ts_LOGf("Output intf: %s\n", inet_ntoa(ts->output.intf));
544 557
 			ts_LOGf("Output ttl : %d\n", ts->output.ttl);
545 558
 			if (ts->output.tos > -1)
546 559
 				ts_LOGf("Output TOS : %u (0x%02x)\n", ts->output.tos, ts->output.tos);
560
+			if (ts->rtp_output) {
561
+				ts_LOGf("RTP SSRC   : %u (0x%04x)\n",
562
+					ts->rtp_ssrc, ts->rtp_ssrc);
563
+				// It is recommended that RTP seqnum starts with random number
564
+				RAND_bytes((unsigned char *)&(ts->rtp_seqnum), 2);
565
+			}
547 566
 		} else if (ts->output.type == FILE_IO) {
548 567
 			ts_LOGf("Output file: %s\n", ts->output.fd == 1 ? "STDOUT" : ts->output.fname);
549 568
 		}

+ 9
- 0
util.c View File

@@ -16,7 +16,9 @@
16 16
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
17 17
  */
18 18
 
19
+#include <time.h>
19 20
 #include <string.h>
21
+#include <errno.h>
20 22
 
21 23
 #include "util.h"
22 24
 
@@ -154,3 +156,10 @@ int decode_hex_string(char *hex, uint8_t *bin, int asc_len) {
154 156
 	}
155 157
 	return asc_len / 2;
156 158
 }
159
+
160
+int64_t get_time(void) {
161
+	struct timespec ts;
162
+	if (clock_gettime(CLOCK_MONOTONIC, &ts) == EINVAL) // Shouldn't happen on modern Linux
163
+		clock_gettime(CLOCK_REALTIME, &ts);
164
+	return ts.tv_sec * 1000000ll + ts.tv_nsec / 1000;
165
+}

+ 1
- 0
util.h View File

@@ -27,5 +27,6 @@ uint8_t *init_4l(uint32_t val, uint8_t *b);
27 27
 uint8_t *init_2b(uint32_t val, uint8_t *b);
28 28
 void set_thread_name(char *thread_name);
29 29
 int decode_hex_string(char *hex, uint8_t *bin, int asc_len);
30
+int64_t get_time(void);
30 31
 
31 32
 #endif

Loading…
Cancel
Save