Browse Source

Add --input-buffer (-T) option.

Georgi Chorbadzhiyski 12 years ago
parent
commit
0ddae6e3f7
7 changed files with 65 additions and 7 deletions
  1. 3
    1
      ChangeLog
  2. 1
    0
      README
  3. 4
    0
      data.c
  4. 8
    0
      data.h
  5. 31
    4
      process.c
  6. 8
    0
      tsdecrypt.1
  7. 10
    2
      tsdecrypt.c

+ 3
- 1
ChangeLog View File

@@ -1,5 +1,7 @@
1 1
 now : Version next
2
- * Add --log-file option.
2
+ * Add --input-buffer (-T) option. This option allows uninterrupted
3
+   decryption even if OSCAM returns code words too late.
4
+ * Add --log-file (-F) option.
3 5
  * Fixed newcamd protocol issues when OSCAM disappeared.
4 6
 
5 7
 2012-02-24 : Version 6.0

+ 1
- 0
README View File

@@ -34,6 +34,7 @@ Input options:
34 34
  -R --input-rtp             | Enable RTP input
35 35
  -z --input-ignore-disc     | Do not report discontinuty errors in input.
36 36
  -M --input-service <srvid> | Choose service id when input is MPTS.
37
+ -T --input-buffer <ms>     | Set input buffer time in ms. Default: 0
37 38
  -W --input-dump <filename> | Save input stream in file.
38 39
 
39 40
 Output options:

+ 4
- 0
data.c View File

@@ -103,6 +103,8 @@ void data_init(struct ts *ts) {
103 103
 
104 104
 	ts->decode_buf  = cbuf_init((7 * dvbcsa_bs_batch_size() * 188) * 16, "decode"); // ~658Kb
105 105
 	ts->write_buf   = cbuf_init((7 * dvbcsa_bs_batch_size() * 188) *  8, "write");  // ~324Kb
106
+
107
+	ts->input_buffer= list_new("input");
106 108
 }
107 109
 
108 110
 void data_free(struct ts *ts) {
@@ -133,4 +135,6 @@ void data_free(struct ts *ts) {
133 135
 
134 136
 	FREE(ts->input.fname);
135 137
 	FREE(ts->output.fname);
138
+
139
+	list_free(&ts->input_buffer, free, NULL);
136 140
 }

+ 8
- 0
data.h View File

@@ -173,6 +173,11 @@ struct io {
173 173
 	struct in_addr		intf;
174 174
 };
175 175
 
176
+struct packet_buf {
177
+	int64_t		time;
178
+	uint8_t		data[188];
179
+};
180
+
176 181
 #define MAX_PIDS 8192
177 182
 
178 183
 struct ts {
@@ -273,6 +278,9 @@ struct ts {
273 278
 
274 279
 	struct notify		*notify;
275 280
 	char				*notify_program;
281
+
282
+	unsigned int		input_buffer_time;
283
+	LIST				*input_buffer;
276 284
 };
277 285
 
278 286
 void data_init(struct ts *ts);

+ 31
- 4
process.c View File

@@ -297,6 +297,8 @@ static void detect_discontinuity(struct ts *ts, uint8_t *ts_packet) {
297 297
 
298 298
 void process_packets(struct ts *ts, uint8_t *data, ssize_t data_len) {
299 299
 	ssize_t i;
300
+	int64_t now = get_time();
301
+
300 302
 	for (i=0; i<data_len; i += 188) {
301 303
 		uint8_t *ts_packet = data + i;
302 304
 		uint16_t pid = ts_packet_get_pid(ts_packet);
@@ -333,10 +335,35 @@ void process_packets(struct ts *ts, uint8_t *data, ssize_t data_len) {
333 335
 
334 336
 		if (ts->threaded) {
335 337
 			// Add to decode buffer. The decoder thread will handle it
336
-			if (cbuf_fill(ts->decode_buf, ts_packet, 188) != 0) {
337
-				ts_LOGf("Decode buffer is full, waiting...\n");
338
-				cbuf_dump(ts->decode_buf);
339
-				usleep(10000);
338
+			if (ts->input_buffer_time == 0) {
339
+				// No input buffer, move packets to decoding buffer
340
+				if (cbuf_fill(ts->decode_buf, ts_packet, 188) != 0) {
341
+					ts_LOGf("Decode buffer is full, waiting...\n");
342
+					cbuf_dump(ts->decode_buf);
343
+					usleep(10000);
344
+				}
345
+			} else {
346
+				// Handle input buffer
347
+				struct packet_buf *p = malloc(sizeof(struct packet_buf));
348
+				p->time = now + (ts->input_buffer_time * 1000); //buffer time is in ms, p->time is in us
349
+				memcpy(p->data, ts_packet, 188);
350
+				list_add(ts->input_buffer, p);
351
+				// Move packets to decrypt buffer
352
+				LNODE *lc, *lctmp;
353
+				list_for_each(ts->input_buffer, lc, lctmp) {
354
+					p = lc->data;
355
+					if (p->time <= now) {
356
+						if (cbuf_fill(ts->decode_buf, p->data, 188) != 0) {
357
+							ts_LOGf("Decode buffer is full, waiting...\n");
358
+							cbuf_dump(ts->decode_buf);
359
+							usleep(10000);
360
+						}
361
+						list_del(ts->input_buffer, &lc);
362
+						free(p);
363
+					} else {
364
+						break;
365
+					}
366
+				}
340 367
 			}
341 368
 		} else {
342 369
 			decode_packet(ts, ts_packet);

+ 8
- 0
tsdecrypt.1 View File

@@ -86,6 +86,14 @@ in order to select the correct service (program). If the input is MPTS
86 86
 and \fB\-\-input\-service\fR is not used, tsdecrypt chooses the last service
87 87
 listed in PAT.
88 88
 .TP
89
+\fB\-T\fR, \fB\-\-input\-buffer\fR <miliseconds>
90
+Using this option delays the decoding for given amount of milliseconds. This
91
+allows tsdecrypt to decode services even if OSCAM returns code word too late.
92
+For example SkyUK sends code words ~700 ms before it starts using them. This
93
+means that if OSCAM is unable to return code word in less than 700 ms the
94
+decryption will fail for a small amount of time. Setting --input-buffer 1000
95
+will solve the problem in this case.
96
+.TP
89 97
 \fB\-W\fR, \fB\-\-input\-dump\fR <filename>
90 98
 Save input stream in <filename>. If the input is RTP, the file will contain
91 99
 the data without RTP headers (pure mpeg transport stream). Easiest way to

+ 10
- 2
tsdecrypt.c View File

@@ -113,9 +113,9 @@ void run_benchmark(void) {
113 113
 	puts("* Done *");
114 114
 }
115 115
 
116
-static const char short_options[] = "i:d:N:Sl:L:F:I:RzM:W:O:o:t:rk:g:pwxyc:C:A:s:U:P:B:eZ:Ef:X:H:G:KJ:D:jbhV";
116
+static const char short_options[] = "i:d:N:Sl:L:F:I:RzM:T:W:O:o:t:rk:g:pwxyc:C:A:s:U:P:B:eZ:Ef:X:H:G:KJ:D:jbhV";
117 117
 
118
-// Unused short options: QTYamnquv0123456789
118
+// Unused short options: QYamnquv0123456789
119 119
 static const struct option long_options[] = {
120 120
 	{ "ident",				required_argument, NULL, 'i' },
121 121
 	{ "daemon",				required_argument, NULL, 'd' },
@@ -129,6 +129,7 @@ static const struct option long_options[] = {
129 129
 	{ "input-rtp",			no_argument,       NULL, 'R' },
130 130
 	{ "input-ignore-disc",	no_argument,       NULL, 'z' },
131 131
 	{ "input-service",		required_argument, NULL, 'M' },
132
+	{ "input-buffer",		required_argument, NULL, 'T' },
132 133
 	{ "input-dump",			required_argument, NULL, 'W' },
133 134
 
134 135
 	{ "output",				required_argument, NULL, 'O' },
@@ -191,6 +192,7 @@ static void show_help(struct ts *ts) {
191 192
 	printf(" -R --input-rtp             | Enable RTP input\n");
192 193
 	printf(" -z --input-ignore-disc     | Do not report discontinuty errors in input.\n");
193 194
 	printf(" -M --input-service <srvid> | Choose service id when input is MPTS.\n");
195
+	printf(" -T --input-buffer <ms>     | Set input buffer time in ms. Default: %u\n", ts->input_buffer_time);
194 196
 	printf(" -W --input-dump <filename> | Save input stream in file.\n");
195 197
 	printf("\n");
196 198
 	printf("Output options:\n");
@@ -330,6 +332,9 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
330 332
 			case 'M':
331 333
 				ts->forced_service_id = strtoul(optarg, NULL, 0) & 0xffff;
332 334
 				break;
335
+			case 'T':
336
+				ts->input_buffer_time = strtoul(optarg, NULL, 0);
337
+				break;
333 338
 			case 'W':
334 339
 				ts->input_dump_filename = optarg;
335 340
 				break;
@@ -549,6 +554,9 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
549 554
 		ts_LOGf("Input addr : %s://%s:%u/\n",
550 555
 			ts->rtp_input ? "rtp" : "udp",
551 556
 			inet_ntoa(ts->input.addr), ts->input.port);
557
+		if (ts->input_buffer_time) {
558
+			ts_LOGf("Input buff : %u ms\n", ts->input_buffer_time);
559
+		}
552 560
 	} else if (ts->input.type == FILE_IO) {
553 561
 		ts_LOGf("Input file : %s\n", ts->input.fd == 0 ? "STDIN" : ts->input.fname);
554 562
 	}

Loading…
Cancel
Save