Browse Source

Add support using FFdecsa as decryption library.

Use "make ffdecsa" to build tsdecrypt with ffdecsa support
or "make dvbcsa" to build with libdvbcsa (this is still the default).
Georgi Chorbadzhiyski 12 years ago
parent
commit
f23096eb58
7 changed files with 322 additions and 12 deletions
  1. 1
    0
      ChangeLog
  2. 151
    0
      FFdecsa_init
  3. 39
    6
      Makefile
  4. 79
    4
      csa.c
  5. 28
    0
      csa.h
  6. 23
    1
      process.c
  7. 1
    1
      tsdecrypt.c

+ 1
- 0
ChangeLog View File

1
 current : Version -next
1
 current : Version -next
2
+ * Add FFdecsa support. FFdecsa decrypts ~2 times faster than libdvcsa.
2
  * Add --const-cw (-Y) option. This option allows using of constant
3
  * Add --const-cw (-Y) option. This option allows using of constant
3
    code word for decryption.
4
    code word for decryption.
4
 
5
 

+ 151
- 0
FFdecsa_init View File

1
+#!/bin/sh
2
+# Compile FFdecsa in different modes to find the fastest
3
+# This script is based on the conigure script from getstream_a84
4
+# Copyright (C) 2012 Unix Solutions Ltd.
5
+#
6
+# This program is free software; you can redistribute it and/or modify
7
+# it under the terms of the GNU General Public License version 2
8
+# as published by the Free Software Foundation.
9
+#
10
+# This program is distributed in the hope that it will be useful,
11
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+# GNU General Public License for more details.
14
+#
15
+# You should have received a copy of the GNU General Public License
16
+# along with this program; if not, write to the Free Software
17
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
18
+
19
+cd $(dirname $0)
20
+
21
+CROSS="$1"
22
+CC="${2:-cc}"
23
+FFDECSA_CFLAGS="-O3 -fexpensive-optimizations -funroll-loops"
24
+
25
+MAX_MODE="PARALLEL_32_INT"
26
+
27
+FFDECSA_MODES="PARALLEL_32_INT"
28
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_64_2INT"
29
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_64_LONG"
30
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_64_MMX"
31
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_128_2LONG"
32
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_128_2MMX"
33
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_128_SSE"
34
+FFDECSA_MODES="$FFDECSA_MODES PARALLEL_128_SSE2"
35
+
36
+# Internal variables
37
+OUTPUT_FILE="FFdecsa.opts"
38
+FFDECSA_DIR="FFdecsa"
39
+LPREFIX="[FFdecsa]"
40
+MAX_SPEED=0
41
+TMPDIR=`mktemp -d FFdecsa.build.XXXXXXXX` || exit 1
42
+
43
+trap "{ rm -rf $TMPDIR ; exit 1; }" INT TERM
44
+
45
+cp $FFDECSA_DIR/Makefile $FFDECSA_DIR/*.{c,h} $TMPDIR
46
+
47
+log()  { printf "%s %-26s : %s\n" "$LPREFIX" "$1" "$2"; }
48
+logn() { printf "%s %-26s : %s"   "$LPREFIX" "$1" "$2"; }
49
+
50
+log "Using compiler" "$CROSS$CC"
51
+log "FFdecsa modes" "$FFDECSA_MODES"
52
+
53
+cpu_have() {
54
+	# Check whether option is supported by the host CPU
55
+	grep "^flags.* $1 " /proc/cpuinfo >/dev/null 2>&1
56
+	eval test $? -eq 0
57
+}
58
+
59
+cc_check() {
60
+	# Check whether option is supported by the target CC
61
+	$CROSS$CC $1 -xc -o /dev/null - 2>/dev/null << EOF
62
+int main(void) { return 0; }
63
+EOF
64
+	eval test $? -eq 0
65
+}
66
+
67
+test_ffdecsa_mode() {
68
+	MODE="$1"
69
+	logn "Testing $MODE"
70
+
71
+	ERRLOG="FFdecsa_build_$MODE.log"
72
+	MAKECMD="make -C $TMPDIR FFdecsa_test PARALLEL_MODE=$MODE FLAGS=\"$FFDECSA_CFLAGS\" COMPILER=\"$CROSS$CC\""
73
+	eval $MAKECMD >/dev/null 2>$TMPDIR/$ERRLOG
74
+
75
+	if [ $? -ne 0 ]
76
+	then
77
+		echo "ERROR: build failed, check $ERRLOG"
78
+		(echo "$MAKECMD" ; echo ; cat $TMPDIR/$ERRLOG) > $ERRLOG
79
+		return
80
+	fi
81
+
82
+	if [ "$CROSS" != "" ]
83
+	then
84
+		cp $TMPDIR/FFdecsa_test FFdecsa_test_$MODE
85
+		echo "CROSS COMPILE OK: You can run FFdecsa_test_$MODE on the target machine"
86
+		return
87
+	fi
88
+
89
+	RESULTS_FILE="$TMPDIR/test_results.txt"
90
+	$TMPDIR/FFdecsa_test >/dev/null 2>$RESULTS_FILE
91
+	if [ $? -ne 0 ]
92
+	then
93
+		echo "ERROR: test run failed"
94
+		return
95
+	fi
96
+
97
+	grep FAILED $RESULTS_FILE >/dev/null 2>&1
98
+	if test $? -ne 1; then
99
+		echo "ERROR: test failed"
100
+		return
101
+	fi
102
+
103
+	SPEED=`grep "speed=.*Mbit" $RESULTS_FILE | sed -e 's/^.*=\([0-9]*\)\.[0-9]* Mbit.*$/\1/'`
104
+	echo "OK $SPEED Mbit/s"
105
+	if [ $SPEED -gt $MAX_SPEED ]
106
+	then
107
+		MAX_SPEED=$SPEED
108
+		MAX_MODE=$MODE
109
+	fi
110
+}
111
+
112
+# Check CPU and compiler flags
113
+if cc_check -march=native
114
+then
115
+	FFDECSA_CFLAGS="$FFDECSA_CFLAGS -march=native"
116
+elif cc_check -march=pentium; then
117
+	FFDECSA_CFLAGS="$FFDECSA_CFLAGS -march=pentium"
118
+fi
119
+
120
+OPTS=""
121
+FLAGS=""
122
+for flag in mmx sse sse2
123
+do
124
+	if cpu_have $flag
125
+	then
126
+		OPTS="$OPTS $flag"
127
+		if cc_check -m$flag
128
+		then
129
+			FFDECSA_CFLAGS="$FFDECSA_CFLAGS -m$flag"
130
+		fi
131
+	fi
132
+done
133
+
134
+log "Host CPU" "$(uname -m) $OPTS"
135
+log "FFdecsa CFLAGS" "$FFDECSA_CFLAGS"
136
+
137
+for MODE in $FFDECSA_MODES
138
+do
139
+	test_ffdecsa_mode $MODE
140
+	make -C $TMPDIR clean >/dev/null 2>&1
141
+done
142
+
143
+log "Choosing PARALLEL_MODE" "$MAX_MODE ($MAX_SPEED Mbps)"
144
+
145
+echo "# This file is included from Makefile
146
+DECRYPT_LIB = ffdecsa
147
+FFDECSA_OBJ = FFdecsa/FFdecsa.o" > $OUTPUT_FILE
148
+echo "FFDECSA_MODE = $MAX_MODE" >> $OUTPUT_FILE
149
+echo "FFDECSA_FLAGS = \"$FFDECSA_CFLAGS\"" >> $OUTPUT_FILE
150
+
151
+rm -rf $TMPDIR

+ 39
- 6
Makefile View File

1
 CC = $(CROSS)$(TARGET)cc
1
 CC = $(CROSS)$(TARGET)cc
2
 STRIP = $(CROSS)$(TARGET)strip
2
 STRIP = $(CROSS)$(TARGET)strip
3
 MKDEP = $(CC) -M -o $*.d $<
3
 MKDEP = $(CC) -M -o $*.d $<
4
-RM = /bin/rm -f
4
+RM = rm -f
5
+MV = mv -f
5
 
6
 
6
 BUILD_ID = $(shell date +%F_%R)
7
 BUILD_ID = $(shell date +%F_%R)
7
 VERSION = $(shell cat RELEASE)
8
 VERSION = $(shell cat RELEASE)
20
 
21
 
21
 DEFS = -DBUILD_ID=\"$(BUILD_ID)\" \
22
 DEFS = -DBUILD_ID=\"$(BUILD_ID)\" \
22
  -DVERSION=\"$(VERSION)\" -DGIT_VER=\"$(GIT_VER)\"
23
  -DVERSION=\"$(VERSION)\" -DGIT_VER=\"$(GIT_VER)\"
23
-DEFS += -DUSE_LIBDVBCSA=1
24
 
24
 
25
 PREFIX ?= /usr/local
25
 PREFIX ?= /usr/local
26
 
26
 
47
  tables.c \
47
  tables.c \
48
  notify.c \
48
  notify.c \
49
  tsdecrypt.c
49
  tsdecrypt.c
50
-tsdecrypt_LIBS = -lcrypto -ldvbcsa -lpthread
51
-tsdecrypt_OBJS = $(FUNCS_LIB) $(TS_LIB) $(tsdecrypt_SRC:.c=.o)
50
+tsdecrypt_LIBS = -lcrypto -lpthread
51
+
52
+# If the file do not exist, libdvbcsa will be used
53
+-include FFdecsa.opts
54
+
55
+tsdecrypt_OBJS = $(FFDECSA_OBJ) $(FUNCS_LIB) $(TS_LIB) $(tsdecrypt_SRC:.c=.o)
52
 
56
 
53
 ifeq "$(shell uname -s)" "Linux"
57
 ifeq "$(shell uname -s)" "Linux"
54
 tsdecrypt_LIBS += -lcrypt -lrt
58
 tsdecrypt_LIBS += -lcrypt -lrt
55
 endif
59
 endif
56
 
60
 
57
-CLEAN_OBJS = tsdecrypt $(tsdecrypt_SRC:.c=.{o,d})
61
+ifeq "$(DECRYPT_LIB)" "ffdecsa"
62
+DEFS += -DDLIB=\"FFdecsa_$(FFDECSA_MODE)\"
63
+DEFS += -DUSE_FFDECSA=1
64
+else
65
+DEFS += -DDLIB=\"libdvbcsa\"
66
+DEFS += -DUSE_LIBDVBCSA=1
67
+tsdecrypt_LIBS += -ldvbcsa
68
+endif
69
+
70
+CLEAN_OBJS = $(FFDECSA_OBJ) tsdecrypt $(tsdecrypt_SRC:.c=.{o,d})
58
 
71
 
59
 PROGS = tsdecrypt
72
 PROGS = tsdecrypt
60
 
73
 
61
-.PHONY: distclean clean install uninstall
74
+.PHONY: ffdecsa dvbcsa help distclean clean install uninstall
62
 
75
 
63
 all: $(PROGS)
76
 all: $(PROGS)
64
 
77
 
78
+ffdecsa: clean
79
+	$(Q)echo "Switching build to FFdecsa."
80
+	@-if test -e FFdecsa.opts.saved; then $(MV) FFdecsa.opts.saved FFdecsa.opts; fi
81
+	@-if ! test -e FFdecsa.opts; then ./FFdecsa_init "$(CROSS)$(TARGET)" "$(CC)"; fi
82
+	$(Q)$(MAKE) -s tsdecrypt
83
+
84
+ffdecsa_force:
85
+	$(Q)$(RM) FFdecsa.opts
86
+	$(Q)$(MAKE) -s ffdecsa
87
+
88
+dvbcsa: clean
89
+	$(Q)echo "Switching build to libdvbcsa."
90
+	@-if test -f FFdecsa.opts; then $(MV) FFdecsa.opts FFdecsa.opts.saved; fi
91
+	$(Q)$(MAKE) -s tsdecrypt
92
+
65
 $(FUNCS_LIB): $(FUNCS_DIR)/libfuncs.h
93
 $(FUNCS_LIB): $(FUNCS_DIR)/libfuncs.h
66
 	$(Q)echo "  MAKE	$(FUNCS_LIB)"
94
 	$(Q)echo "  MAKE	$(FUNCS_LIB)"
67
 	$(Q)$(MAKE) -s -C $(FUNCS_DIR)
95
 	$(Q)$(MAKE) -s -C $(FUNCS_DIR)
79
 	$(Q)echo "  CC	tsdecrypt	$<"
107
 	$(Q)echo "  CC	tsdecrypt	$<"
80
 	$(Q)$(CC) $(CFLAGS) $(DEFS) -c $<
108
 	$(Q)$(CC) $(CFLAGS) $(DEFS) -c $<
81
 
109
 
110
+FFdecsa/FFdecsa.o:
111
+	$(Q)echo "  MAKE	FFdecsa"
112
+	$(Q)$(MAKE) -s -C FFdecsa FLAGS=$(FFDECSA_FLAGS) PARALLEL_MODE=$(FFDECSA_MODE) COMPILER=$(CROSS)$(CC) FFdecsa.o
113
+
82
 -include $(tsdecrypt_SRC:.c=.d)
114
 -include $(tsdecrypt_SRC:.c=.d)
83
 
115
 
84
 strip:
116
 strip:
92
 distclean: clean
124
 distclean: clean
93
 	$(Q)$(MAKE) -s -C $(TS_DIR) clean
125
 	$(Q)$(MAKE) -s -C $(TS_DIR) clean
94
 	$(Q)$(MAKE) -s -C $(FUNCS_DIR) clean
126
 	$(Q)$(MAKE) -s -C $(FUNCS_DIR) clean
127
+	$(Q)$(RM) FFdecsa.opts
95
 
128
 
96
 install: all strip
129
 install: all strip
97
 	@install -d "$(INSTALL_PRG_DIR)"
130
 	@install -d "$(INSTALL_PRG_DIR)"

+ 79
- 4
csa.c View File

32
 	key->s_csakey[1] = dvbcsa_key_alloc();
32
 	key->s_csakey[1] = dvbcsa_key_alloc();
33
 	key->bs_csakey[0] = dvbcsa_bs_key_alloc();
33
 	key->bs_csakey[0] = dvbcsa_bs_key_alloc();
34
 	key->bs_csakey[1] = dvbcsa_bs_key_alloc();
34
 	key->bs_csakey[1] = dvbcsa_bs_key_alloc();
35
+	key->ff_csakey = ffdecsa_key_alloc();
35
 	return (csakey_t *)key;
36
 	return (csakey_t *)key;
36
 }
37
 }
37
 
38
 
42
 		dvbcsa_key_free(key->s_csakey[1]);
43
 		dvbcsa_key_free(key->s_csakey[1]);
43
 		dvbcsa_bs_key_free(key->bs_csakey[0]);
44
 		dvbcsa_bs_key_free(key->bs_csakey[0]);
44
 		dvbcsa_bs_key_free(key->bs_csakey[1]);
45
 		dvbcsa_bs_key_free(key->bs_csakey[1]);
46
+		ffdecsa_key_free(key->ff_csakey);
45
 		FREE(*pcsakey);
47
 		FREE(*pcsakey);
46
 	}
48
 	}
47
 }
49
 }
50
 	if (use_dvbcsa) {
52
 	if (use_dvbcsa) {
51
 		return dvbcsa_bs_batch_size(); // 32?
53
 		return dvbcsa_bs_batch_size(); // 32?
52
 	}
54
 	}
55
+	if (use_ffdecsa) {
56
+		return ffdecsa_get_suggested_cluster_size() / 2;
57
+	}
53
 	return 0;
58
 	return 0;
54
 }
59
 }
55
 
60
 
57
 	struct csakey *key = (struct csakey *)csakey;
62
 	struct csakey *key = (struct csakey *)csakey;
58
 	dvbcsa_key_set(even_cw, key->s_csakey[0]);
63
 	dvbcsa_key_set(even_cw, key->s_csakey[0]);
59
 	dvbcsa_bs_key_set(even_cw, key->bs_csakey[0]);
64
 	dvbcsa_bs_key_set(even_cw, key->bs_csakey[0]);
65
+	ffdecsa_set_even_cw(key->ff_csakey, even_cw);
60
 }
66
 }
61
 
67
 
62
 inline void csa_set_odd_cw(csakey_t *csakey, uint8_t *odd_cw) {
68
 inline void csa_set_odd_cw(csakey_t *csakey, uint8_t *odd_cw) {
63
 	struct csakey *key = (struct csakey *)csakey;
69
 	struct csakey *key = (struct csakey *)csakey;
64
 	dvbcsa_key_set(odd_cw, key->s_csakey[1]);
70
 	dvbcsa_key_set(odd_cw, key->s_csakey[1]);
65
 	dvbcsa_bs_key_set(odd_cw, key->bs_csakey[1]);
71
 	dvbcsa_bs_key_set(odd_cw, key->bs_csakey[1]);
72
+	ffdecsa_set_odd_cw(key->ff_csakey, odd_cw);
66
 }
73
 }
67
 
74
 
68
 inline void csa_decrypt_single_packet(csakey_t *csakey, uint8_t *ts_packet) {
75
 inline void csa_decrypt_single_packet(csakey_t *csakey, uint8_t *ts_packet) {
73
 		ts_packet_set_not_scrambled(ts_packet);
80
 		ts_packet_set_not_scrambled(ts_packet);
74
 		dvbcsa_decrypt(key->s_csakey[key_idx], ts_packet + payload_offset, 188 - payload_offset);
81
 		dvbcsa_decrypt(key->s_csakey[key_idx], ts_packet + payload_offset, 188 - payload_offset);
75
 	}
82
 	}
83
+	if (use_ffdecsa) {
84
+		uint8_t *cluster[3] = { ts_packet, ts_packet + 188, NULL };
85
+		ffdecsa_decrypt_packets(key->ff_csakey, cluster);
86
+	}
76
 }
87
 }
77
 
88
 
78
 inline void csa_decrypt_multiple_even(csakey_t *csakey, struct csa_batch *batch) {
89
 inline void csa_decrypt_multiple_even(csakey_t *csakey, struct csa_batch *batch) {
85
 	dvbcsa_bs_decrypt(key->bs_csakey[1], (struct dvbcsa_bs_batch_s *)batch, 184);
96
 	dvbcsa_bs_decrypt(key->bs_csakey[1], (struct dvbcsa_bs_batch_s *)batch, 184);
86
 }
97
 }
87
 
98
 
99
+inline void csa_decrypt_multiple_ff(csakey_t *csakey, uint8_t **cluster) {
100
+	struct csakey *key = (struct csakey *)csakey;
101
+	ffdecsa_decrypt_packets(key->ff_csakey, cluster);
102
+}
103
+
88
 /* The following routine is taken from benchbitslice in libdvbcsa */
104
 /* The following routine is taken from benchbitslice in libdvbcsa */
89
-void csa_benchmark(void) {
105
+void dvbcsa_benchmark(void) {
90
 	struct timeval t0, t1;
106
 	struct timeval t0, t1;
91
 	struct dvbcsa_bs_key_s *key = dvbcsa_bs_key_alloc();
107
 	struct dvbcsa_bs_key_s *key = dvbcsa_bs_key_alloc();
92
 	unsigned int n, i, npackets = 0;
108
 	unsigned int n, i, npackets = 0;
95
 	struct dvbcsa_bs_batch_s pcks[batch_size + 1];
111
 	struct dvbcsa_bs_batch_s pcks[batch_size + 1];
96
 	uint8_t cw[8] = { 0x12, 0x34, 0x56, 0x78, 0x89, 0xab, 0xcd, 0xef, };
112
 	uint8_t cw[8] = { 0x12, 0x34, 0x56, 0x78, 0x89, 0xab, 0xcd, 0xef, };
97
 
113
 
98
-	srand(time(0));
99
-	puts("Single threaded CSA decoding benchmark");
100
-
101
 	dvbcsa_bs_key_set (cw, key);
114
 	dvbcsa_bs_key_set (cw, key);
102
 
115
 
103
 	printf("Batch size %d packets.\n\n", batch_size);
116
 	printf("Batch size %d packets.\n\n", batch_size);
129
 
142
 
130
 	dvbcsa_bs_key_free(key);
143
 	dvbcsa_bs_key_free(key);
131
 }
144
 }
145
+
146
+void ffdecsa_benchmark(void) {
147
+	struct timeval t0, t1;
148
+	ffdecsa_key_t *key = ffdecsa_key_alloc();
149
+	unsigned int n, i, d, npackets = 0;
150
+	unsigned int batch_size = ffdecsa_get_suggested_cluster_size() / 2;
151
+	uint8_t data[batch_size + 1][188];
152
+	uint8_t *pcks[batch_size * 2 + 1];
153
+	uint8_t ecw[8] = { 0x12, 0x34, 0x56, 0x78, 0x89, 0xab, 0xcd, 0xef, };
154
+	uint8_t ocw[8] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, };
155
+
156
+	ffdecsa_set_even_cw(key, ecw);
157
+	ffdecsa_set_odd_cw (key, ocw);
158
+
159
+	printf("Batch size %d packets.\n\n", batch_size);
160
+	for (i = 0; i < batch_size; i++) {
161
+		memset(data[i], rand(), 188);
162
+		data[i][0] = 0x47;
163
+		data[i][1] = 0x01;
164
+		data[i][2] = 0x02;
165
+		data[i][3] = i & 0x0f;
166
+	}
167
+
168
+	gettimeofday(&t0, NULL);
169
+	for (n = (1 << 12) / batch_size; n < (1 << 18) / batch_size; n *= 2) {
170
+		static unsigned int key_idx = 0;
171
+		printf(" Decrypting %6u mpegts packets\r", n * batch_size);
172
+		fflush(stdout);
173
+		for (i = 0; i < n; i++) {
174
+			// ffdecsa_decrypt function modifies data and pcks
175
+			for (d = 0; d < batch_size; d++) {
176
+				pcks[d * 2]     = data[d];
177
+				pcks[d * 2 + 1] = data[d] + 188;
178
+				data[d][3] |= (key_idx == 0) ? (2 << 6) : (3 << 6);
179
+			}
180
+			pcks[d * 2] = NULL;
181
+			key_idx = !!key_idx;
182
+			ffdecsa_decrypt_packets(key, pcks);
183
+		}
184
+		npackets += n * batch_size;
185
+	}
186
+	gettimeofday(&t1, NULL);
187
+
188
+	unsigned long long usec = timeval_diff_usec(&t0, &t1);
189
+	printf("DONE: %u packets (%u bytes) decrypted in %llu ms = %.1f Mbits/s\n\n",
190
+		npackets,
191
+		npackets * 188,
192
+		usec / 1000,
193
+		(double)(npackets * 188 * 8) / (double)usec
194
+	);
195
+
196
+	dvbcsa_bs_key_free(key);
197
+}
198
+
199
+void csa_benchmark(void) {
200
+	srand(time(0));
201
+	printf("Single threaded CSA decoding benchmark : %s\n", DLIB);
202
+	if (use_dvbcsa)
203
+		dvbcsa_benchmark();
204
+	if (use_ffdecsa)
205
+		ffdecsa_benchmark();
206
+}

+ 28
- 0
csa.h View File

43
 static inline void				dvbcsa_bs_decrypt(const dvbcsa_bs_key_t *key, const struct dvbcsa_bs_batch_s *pcks, unsigned int maxlen) { (void)key; (void)pcks; (void)maxlen; }
43
 static inline void				dvbcsa_bs_decrypt(const dvbcsa_bs_key_t *key, const struct dvbcsa_bs_batch_s *pcks, unsigned int maxlen) { (void)key; (void)pcks; (void)maxlen; }
44
 #endif
44
 #endif
45
 
45
 
46
+#define ffdecsa_key_t void
47
+
48
+#if USE_FFDECSA
49
+#include "FFdecsa/FFdecsa.h"
50
+#define use_ffdecsa 1
51
+static inline int				ffdecsa_get_internal_parallelism(void) { return get_internal_parallelism(); }
52
+static inline int				ffdecsa_get_suggested_cluster_size(void) { return get_suggested_cluster_size(); }
53
+static inline ffdecsa_key_t *	ffdecsa_key_alloc(void) { return get_key_struct(); }
54
+static inline void				ffdecsa_key_free(ffdecsa_key_t *keys) { free_key_struct(keys); }
55
+static inline void				ffdecsa_set_cw(ffdecsa_key_t *keys, const uint8_t *even, const uint8_t *odd) { set_control_words(keys, even, odd); }
56
+static inline void				ffdecsa_set_even_cw(void *keys, const uint8_t *even) { set_even_control_word(keys, even); }
57
+static inline void				ffdecsa_set_odd_cw(ffdecsa_key_t *keys, const uint8_t *odd) { return set_odd_control_word(keys, odd); }
58
+static inline int				ffdecsa_decrypt_packets(ffdecsa_key_t *keys, uint8_t **cluster) { return decrypt_packets(keys, cluster); }
59
+#else
60
+#define use_ffdecsa 0
61
+static inline int				ffdecsa_get_internal_parallelism(void) { return 0; }
62
+static inline int				ffdecsa_get_suggested_cluster_size(void) { return 0; }
63
+static inline ffdecsa_key_t *	ffdecsa_key_alloc(void) { return NULL; }
64
+static inline void				ffdecsa_key_free(ffdecsa_key_t *keys) { (void)keys; }
65
+static inline void				ffdecsa_set_cw(ffdecsa_key_t *keys, const uint8_t *even, const uint8_t *odd) { (void)keys; (void)even; (void)odd; }
66
+static inline void				ffdecsa_set_even_cw(void *keys, const uint8_t *even) { (void)keys; (void)even; }
67
+static inline void				ffdecsa_set_odd_cw(ffdecsa_key_t *keys, const uint8_t *odd) { (void)keys; (void)odd; }
68
+static inline int				ffdecsa_decrypt_packets(ffdecsa_key_t *keys, uint8_t **cluster) { (void)keys; (void)cluster; return 0; }
69
+#endif
70
+
46
 #include "data.h"
71
 #include "data.h"
47
 
72
 
48
 struct csakey {
73
 struct csakey {
49
 	dvbcsa_key_t		*s_csakey[2];
74
 	dvbcsa_key_t		*s_csakey[2];
50
 	dvbcsa_bs_key_t		*bs_csakey[2];
75
 	dvbcsa_bs_key_t		*bs_csakey[2];
76
+	ffdecsa_key_t		*ff_csakey;
51
 };
77
 };
52
 
78
 
53
 csakey_t *		csa_key_alloc		(void);
79
 csakey_t *		csa_key_alloc		(void);
62
 void			csa_decrypt_multiple_even	(csakey_t *csakey, struct csa_batch *batch);
88
 void			csa_decrypt_multiple_even	(csakey_t *csakey, struct csa_batch *batch);
63
 void			csa_decrypt_multiple_odd	(csakey_t *csakey, struct csa_batch *batch);
89
 void			csa_decrypt_multiple_odd	(csakey_t *csakey, struct csa_batch *batch);
64
 
90
 
91
+void			csa_decrypt_multiple_ff		(csakey_t *csakey, uint8_t **cluster);
92
+
65
 void csa_benchmark(void);
93
 void csa_benchmark(void);
66
 
94
 
67
 #endif
95
 #endif

+ 23
- 1
process.c View File

115
 
115
 
116
 static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
116
 static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
117
 	int i;
117
 	int i;
118
-	int batch_sz = csa_get_batch_size(); // 32?
118
+	int batch_sz = csa_get_batch_size(); // Tested with 32 for libdvbcsa, 70 for FFdecsa (must be multiplied by 2)
119
 	int even_packets = 0;
119
 	int even_packets = 0;
120
 	int odd_packets  = 0;
120
 	int odd_packets  = 0;
121
 	struct csa_batch even_pcks[batch_sz + 1];
121
 	struct csa_batch even_pcks[batch_sz + 1];
122
 	struct csa_batch odd_pcks [batch_sz + 1];
122
 	struct csa_batch odd_pcks [batch_sz + 1];
123
+	uint8_t *ff_even_pcks[batch_sz * 2 + 1];
124
+	uint8_t *ff_odd_pcks [batch_sz * 2 + 1];
123
 
125
 
124
 	int scramble_idx_old = 0;
126
 	int scramble_idx_old = 0;
125
 
127
 
147
 					}
149
 					}
148
 					ts_packet_set_not_scrambled(ts_packet);
150
 					ts_packet_set_not_scrambled(ts_packet);
149
 				}
151
 				}
152
+				if (use_ffdecsa) {
153
+					if (scramble_idx == 2) { // scramble_idx 2 == even key
154
+						ff_even_pcks[even_packets * 2    ] = ts_packet;
155
+						ff_even_pcks[even_packets * 2 + 1] = ts_packet + 188;
156
+						even_packets++;
157
+					}
158
+					if (scramble_idx == 3) { // scramble_idx 3 == odd key
159
+						ff_odd_pcks[odd_packets * 2    ] = ts_packet;
160
+						ff_odd_pcks[odd_packets * 2 + 1] = ts_packet + 188;
161
+						odd_packets++;
162
+					}
163
+				}
150
 				if (scramble_idx_old != scramble_idx && !ts->camd.constant_codeword) {
164
 				if (scramble_idx_old != scramble_idx && !ts->camd.constant_codeword) {
151
 					struct timeval tv;
165
 					struct timeval tv;
152
 					gettimeofday(&tv, NULL);
166
 					gettimeofday(&tv, NULL);
169
 			even_pcks[even_packets].data = NULL; // Last one...
183
 			even_pcks[even_packets].data = NULL; // Last one...
170
 			csa_decrypt_multiple_even(ts->key.csakey, even_pcks);
184
 			csa_decrypt_multiple_even(ts->key.csakey, even_pcks);
171
 		}
185
 		}
186
+		if (use_ffdecsa) {
187
+			ff_even_pcks[even_packets * 2] = NULL;
188
+			csa_decrypt_multiple_ff(ts->key.csakey, ff_even_pcks);
189
+		}
172
 	}
190
 	}
173
 	if (odd_packets) {
191
 	if (odd_packets) {
174
 		if (use_dvbcsa) {
192
 		if (use_dvbcsa) {
175
 			odd_pcks[odd_packets].data = NULL; // Last one...
193
 			odd_pcks[odd_packets].data = NULL; // Last one...
176
 			csa_decrypt_multiple_odd(ts->key.csakey, odd_pcks);
194
 			csa_decrypt_multiple_odd(ts->key.csakey, odd_pcks);
177
 		}
195
 		}
196
+		if (use_ffdecsa) {
197
+			ff_odd_pcks[odd_packets * 2] = NULL;
198
+			csa_decrypt_multiple_ff(ts->key.csakey, ff_odd_pcks);
199
+		}
178
 	}
200
 	}
179
 
201
 
180
 	// Fill write buffer
202
 	// Fill write buffer

+ 1
- 1
tsdecrypt.c View File

42
 #define FIRST_REPORT_SEC 3
42
 #define FIRST_REPORT_SEC 3
43
 
43
 
44
 #define PROGRAM_NAME "tsdecrypt"
44
 #define PROGRAM_NAME "tsdecrypt"
45
-static const char *program_id = PROGRAM_NAME " v" VERSION " (" GIT_VER ", build " BUILD_ID ")";
45
+static const char *program_id = PROGRAM_NAME " v" VERSION " (" GIT_VER ", build " BUILD_ID " " DLIB ")";
46
 
46
 
47
 static int keep_running = 1;
47
 static int keep_running = 1;
48
 static FILE *log_file = NULL;
48
 static FILE *log_file = NULL;

Loading…
Cancel
Save