Browse Source

Add support for CAT

Georgi Chorbadzhiyski 13 years ago
parent
commit
743ce9edb9
4 changed files with 214 additions and 0 deletions
  1. 1
    0
      Makefile
  2. 13
    0
      tsdata.h
  3. 7
    0
      tsfuncs.h
  4. 193
    0
      tsfuncs_cat.c

+ 1
- 0
Makefile View File

@@ -9,6 +9,7 @@ OBJS = log.o tsfuncs.o tsfuncs_crc.o tsfuncs_misc.o tsfuncs_time.o \
9 9
 	tsfuncs_sections.o tsfuncs_section_data.o \
10 10
 	tsfuncs_descriptors.o \
11 11
 	tsfuncs_pat.o tsfuncs_pat_desc.o \
12
+	tsfuncs_cat.o \
12 13
 	tsfuncs_pmt.o \
13 14
 	tsfuncs_nit.o tsfuncs_nit_desc.o \
14 15
 	tsfuncs_sdt.o tsfuncs_sdt_desc.o \

+ 13
- 0
tsdata.h View File

@@ -223,6 +223,19 @@ struct ts_pat {
223 223
 	uint8_t						initialized;	// Set to 1 when full table is initialized
224 224
 };
225 225
 
226
+struct ts_cat {
227
+	struct ts_header			ts_header;
228
+	struct ts_section_header	*section_header;
229
+
230
+	int							program_info_size;
231
+	uint8_t						*program_info;
232
+
233
+	uint32_t					CRC;
234
+
235
+	// The variables bellow are nor part of the physical packet
236
+	uint8_t						initialized;	// Set to 1 when full table is initialized
237
+};
238
+
226 239
 struct ts_pmt_stream {
227 240
 	uint8_t		stream_type;
228 241
 

+ 7
- 0
tsfuncs.h View File

@@ -106,6 +106,13 @@ int             ts_pat_del_program	(struct ts_pat *pat, uint16_t program);
106 106
 
107 107
 int				ts_pat_is_same		(struct ts_pat *pat1, struct ts_pat *pat2);
108 108
 
109
+// CAT
110
+struct ts_cat *	ts_cat_alloc		();
111
+struct ts_cat *	ts_cat_push_packet	(struct ts_cat *cat, uint8_t *ts_packet);
112
+void            ts_cat_free			(struct ts_cat **cat);
113
+int				ts_cat_parse		(struct ts_cat *cat);
114
+void            ts_cat_dump			(struct ts_cat *cat);
115
+int				ts_cat_is_same		(struct ts_cat *cat1, struct ts_cat *cat2);
109 116
 
110 117
 // PMT
111 118
 struct ts_pmt *	ts_pmt_alloc		();

+ 193
- 0
tsfuncs_cat.c View File

@@ -0,0 +1,193 @@
1
+#include <stdio.h>
2
+#include <unistd.h>
3
+#include <netdb.h>
4
+#include <stdlib.h>
5
+#include <string.h>
6
+
7
+#include "tsfuncs.h"
8
+
9
+struct ts_cat *ts_cat_alloc() {
10
+	struct ts_cat *cat = calloc(1, sizeof(struct ts_cat));
11
+	cat->section_header	= ts_section_data_alloc();
12
+	return cat;
13
+}
14
+
15
+void ts_cat_free(struct ts_cat **pcat) {
16
+	struct ts_cat *cat = *pcat;
17
+	if (cat) {
18
+		ts_section_data_free(&cat->section_header);
19
+		FREE(cat->program_info);
20
+		FREE(*pcat);
21
+	}
22
+}
23
+
24
+static struct ts_cat *ts_cat_reset(struct ts_cat *cat) {
25
+	struct ts_cat *newcat = ts_cat_alloc();
26
+	ts_cat_free(&cat);
27
+	return newcat;
28
+}
29
+
30
+struct ts_cat *ts_cat_push_packet(struct ts_cat *cat, uint8_t *ts_packet) {
31
+	struct ts_header ts_header;
32
+	memset(&ts_header, 0, sizeof(struct ts_header));
33
+
34
+	if (ts_packet_header_parse(ts_packet, &ts_header)) {
35
+		if (!cat->ts_header.pusi)
36
+			cat->ts_header = ts_header;
37
+	}
38
+
39
+	if (ts_header.pusi) {
40
+		struct ts_section_header section_header;
41
+		memset(&section_header, 0, sizeof(struct ts_section_header));
42
+
43
+		uint8_t *section_data = ts_section_header_parse(ts_packet, &cat->ts_header, &section_header);
44
+		if (!section_data || !section_header.section_syntax_indicator) {
45
+			memset(&cat->ts_header, 0, sizeof(struct ts_header));
46
+			goto OUT;
47
+		}
48
+		// table_id should be 0x01 (ca_map_section)
49
+		if (section_header.table_id != 0x01) {
50
+			memset(&cat->ts_header, 0, sizeof(struct ts_header));
51
+			goto OUT;
52
+		}
53
+
54
+		// Set correct section_header
55
+		ts_section_header_parse(ts_packet, &cat->ts_header, cat->section_header);
56
+	}
57
+
58
+	if (!cat->initialized) {
59
+		if (cat->section_header->section_syntax_indicator) {
60
+			ts_section_add_packet(cat->section_header, &ts_header, ts_packet);
61
+			if (cat->section_header->initialized) {
62
+				if (!ts_cat_parse(cat))
63
+					goto ERROR;
64
+			}
65
+		}
66
+	}
67
+
68
+OUT:
69
+	return cat;
70
+
71
+ERROR:
72
+	return ts_cat_reset(cat);
73
+}
74
+
75
+int ts_cat_parse(struct ts_cat *cat) {
76
+	uint8_t *section_data = cat->section_header->section_data + 8; // + 8 to compensate for section table header
77
+	int section_len = cat->section_header->packet_section_len;
78
+
79
+	/* Handle streams */
80
+	uint8_t *stream_data = section_data;
81
+	cat->program_info_size = section_len;
82
+	cat->program_info = malloc(cat->program_info_size);
83
+	memcpy(cat->program_info, stream_data, cat->program_info_size);
84
+//	ts_print_bytes("DEBUG", cat->program_info, cat->program_info_size);
85
+	stream_data += cat->program_info_size;
86
+
87
+	cat->CRC = (cat->CRC << 8) | stream_data[3];
88
+	cat->CRC = (cat->CRC << 8) | stream_data[2];
89
+	cat->CRC = (cat->CRC << 8) | stream_data[1];
90
+	cat->CRC = (cat->CRC << 8) | stream_data[0];
91
+
92
+	u_int32_t check_crc = ts_crc32(cat->section_header->section_data, cat->section_header->data_size);
93
+	if (check_crc != 0) {
94
+		ts_LOGf("!!! Wrong cat CRC! It should be 0 but it is %08x (CRC in data is 0x%08x)\n", check_crc, cat->CRC);
95
+		return 0;
96
+	}
97
+
98
+	cat->initialized = 1;
99
+	return 1;
100
+}
101
+
102
+void ts_cat_generate(struct ts_cat *cat, uint8_t **ts_packets, int *num_packets) {
103
+	uint8_t *secdata = ts_section_data_alloc_section();
104
+	ts_section_header_generate(secdata, cat->section_header, 0);
105
+	int curpos = 8; // Compensate for the section header, frist data byte is at offset 8
106
+
107
+	memcpy(secdata + curpos, cat->program_info, cat->program_info_size);
108
+	curpos += cat->program_info_size;
109
+
110
+    cat->CRC = ts_section_data_calculate_crc(secdata, curpos);
111
+    curpos += 4; // CRC
112
+
113
+    ts_section_data_gen_ts_packets(&cat->ts_header, secdata, curpos, cat->section_header->pointer_field, ts_packets, num_packets);
114
+
115
+    FREE(secdata);
116
+}
117
+
118
+void ts_cat_regenerate_packets(struct ts_cat *cat) {
119
+	uint8_t *ts_packets;
120
+	int num_packets;
121
+	ts_cat_generate(cat, &ts_packets, &num_packets);
122
+	FREE(cat->section_header->packet_data);
123
+	cat->section_header->packet_data = ts_packets;
124
+	cat->section_header->num_packets = num_packets;
125
+}
126
+
127
+struct ts_cat *ts_cat_copy(struct ts_cat *cat) {
128
+	struct ts_cat *newcat = ts_cat_alloc();
129
+	int i;
130
+	for (i=0;i<cat->section_header->num_packets; i++) {
131
+		newcat = ts_cat_push_packet(newcat, cat->section_header->packet_data + (i * TS_PACKET_SIZE));
132
+	}
133
+	if (newcat->initialized) {
134
+		return newcat;
135
+	} else {
136
+		ts_LOGf("Error copying cat!\n");
137
+		ts_cat_free(&newcat);
138
+		return NULL;
139
+	}
140
+}
141
+
142
+void ts_cat_check_generator(struct ts_cat *cat) {
143
+	struct ts_cat *cat1 = ts_cat_copy(cat);
144
+	if (cat1) {
145
+		ts_compare_data("CAT (tspacket->struct)",
146
+			cat1->section_header->packet_data,
147
+			cat->section_header->packet_data,
148
+			cat->section_header->num_packets * TS_PACKET_SIZE);
149
+		ts_cat_free(&cat1);
150
+	}
151
+
152
+	uint8_t *ts_packets;
153
+	int num_packets;
154
+	ts_cat_generate(cat, &ts_packets, &num_packets);
155
+	if (num_packets != cat->section_header->num_packets) {
156
+		ts_LOGf("ERROR: num_packets:%d != sec->num_packets:%d\n", num_packets, cat->section_header->num_packets);
157
+	}
158
+	ts_compare_data("CAT (struct->tspacket)", cat->section_header->packet_data, ts_packets, num_packets * TS_PACKET_SIZE);
159
+	free(ts_packets);
160
+}
161
+
162
+void ts_cat_dump(struct ts_cat *cat) {
163
+	int i;
164
+	ts_LOGf("CAT table\n");
165
+    for(i=0;i<cat->section_header->num_packets;i++) {
166
+        struct ts_header tshdr;
167
+        ts_packet_header_parse(cat->section_header->packet_data + (i * TS_PACKET_SIZE), &tshdr);
168
+        ts_packet_header_dump(&tshdr);
169
+    }
170
+    ts_section_header_dump(cat->section_header);
171
+
172
+	if (cat->program_info_size > 0) {
173
+		ts_LOGf(" * Descriptor dump:\n");
174
+		ts_descriptor_dump(cat->program_info, cat->program_info_size);
175
+	}
176
+	ts_LOGf("  * CRC 0x%04x\n", cat->CRC);
177
+
178
+	ts_cat_check_generator(cat);
179
+}
180
+
181
+int ts_cat_is_same(struct ts_cat *cat1, struct ts_cat *cat2) {
182
+	if (cat1->CRC == cat2->CRC) // Same
183
+		return 1;
184
+
185
+	// If some version is not current, just claim the structures are the same
186
+	if (!cat1->section_header->current_next_indicator || cat2->section_header->version_number)
187
+		return 1;
188
+
189
+	if (cat1->section_header->version_number != cat2->section_header->version_number) // Different
190
+		return 0;
191
+
192
+	return 1; // Same
193
+}

Loading…
Cancel
Save