|
@@ -1,4 +1,5 @@
|
1
|
1
|
#include <unistd.h>
|
|
2
|
+#include <string.h>
|
2
|
3
|
|
3
|
4
|
#include "data.h"
|
4
|
5
|
#include "tables.h"
|
|
@@ -6,6 +7,47 @@
|
6
|
7
|
static unsigned long ts_pack;
|
7
|
8
|
static int ts_pack_shown;
|
8
|
9
|
|
|
10
|
+static char *get_pid_desc(struct ts *ts, uint16_t pid) {
|
|
11
|
+ int i;
|
|
12
|
+ uint16_t nitpid = 0x0010, pmtpid = 0xffff, pcrpid = 0xffff;
|
|
13
|
+
|
|
14
|
+ if (ts->pat->initialized) {
|
|
15
|
+ for (i=0;i<ts->pat->programs_num;i++) {
|
|
16
|
+ struct ts_pat_program *prg = ts->pat->programs[i];
|
|
17
|
+ if (prg->pid) {
|
|
18
|
+ if (prg->program == 0)
|
|
19
|
+ nitpid = prg->pid;
|
|
20
|
+ }
|
|
21
|
+ }
|
|
22
|
+ }
|
|
23
|
+
|
|
24
|
+ if (ts->pmt->initialized) {
|
|
25
|
+ pmtpid = ts->pmt->ts_header.pid;
|
|
26
|
+ pcrpid = ts->pmt->PCR_pid;
|
|
27
|
+ for (i=0;i<ts->pmt->streams_num;i++) {
|
|
28
|
+ struct ts_pmt_stream *stream = ts->pmt->streams[i];
|
|
29
|
+ if (pid == stream->pid)
|
|
30
|
+ return h222_stream_type_desc(stream->stream_type);
|
|
31
|
+ }
|
|
32
|
+ }
|
|
33
|
+
|
|
34
|
+ switch (pid) {
|
|
35
|
+ case 0x0000: return "PAT"; break;
|
|
36
|
+ case 0x0001: return "CAT"; break;
|
|
37
|
+ case 0x0011: return "SDT"; break;
|
|
38
|
+ case 0x0012: return "EPG"; break;
|
|
39
|
+ case 0x0014: return "TDT/TOT"; break;
|
|
40
|
+ }
|
|
41
|
+
|
|
42
|
+ if (pid == nitpid) return "NIT";
|
|
43
|
+ else if (pid == pmtpid) return "PMT";
|
|
44
|
+ else if (pid == pcrpid) return "PCR";
|
|
45
|
+ else if (pid == ts->emm_pid) return "EMM";
|
|
46
|
+ else if (pid == ts->ecm_pid) return "ECM";
|
|
47
|
+
|
|
48
|
+ return "Unknown";
|
|
49
|
+}
|
|
50
|
+
|
9
|
51
|
void show_ts_pack(struct ts *ts, uint16_t pid, char *wtf, char *extra, uint8_t *ts_packet) {
|
10
|
52
|
char cw1_dump[8 * 6];
|
11
|
53
|
char cw2_dump[8 * 6];
|
|
@@ -160,6 +202,36 @@ void *write_thread(void *_ts) {
|
160
|
202
|
return NULL;
|
161
|
203
|
}
|
162
|
204
|
|
|
205
|
+static void detect_discontinuity(struct ts *ts, uint8_t *ts_packet) {
|
|
206
|
+ uint16_t pid;
|
|
207
|
+ uint8_t cur_cc, last_cc;
|
|
208
|
+
|
|
209
|
+ if (!ts->ts_discont)
|
|
210
|
+ return;
|
|
211
|
+
|
|
212
|
+ pid = ts_packet_get_pid(ts_packet);
|
|
213
|
+ cur_cc = ts_packet_get_cont(ts_packet);
|
|
214
|
+
|
|
215
|
+ if (!pidmap_get(&ts->pid_seen, pid)) {
|
|
216
|
+ if (strcmp(get_pid_desc(ts, pid), "Unknown") == 0)
|
|
217
|
+ return;
|
|
218
|
+
|
|
219
|
+ pidmap_set(&ts->pid_seen, pid);
|
|
220
|
+ pidmap_set_val(&ts->cc, pid, cur_cc);
|
|
221
|
+ ts_LOGf("Input PID 0x%03x appeared (%s)\n",
|
|
222
|
+ pid, get_pid_desc(ts, pid));
|
|
223
|
+ return;
|
|
224
|
+ }
|
|
225
|
+
|
|
226
|
+ last_cc = pidmap_get(&ts->cc, pid);
|
|
227
|
+ if (last_cc != cur_cc && ((last_cc + 1) & 0x0f) != cur_cc)
|
|
228
|
+ ts_LOGf("Input discontinuity (expected %2d got %2d) PID 0x%03x (%s)\n",
|
|
229
|
+ ((last_cc + 1) & 0x0f), cur_cc,
|
|
230
|
+ pid,
|
|
231
|
+ get_pid_desc(ts, pid));
|
|
232
|
+ pidmap_set_val(&ts->cc, pid, cur_cc);
|
|
233
|
+}
|
|
234
|
+
|
163
|
235
|
void process_packets(struct ts *ts, uint8_t *data, ssize_t data_len) {
|
164
|
236
|
ssize_t i;
|
165
|
237
|
for (i=0; i<data_len; i += 188) {
|
|
@@ -174,6 +246,8 @@ void process_packets(struct ts *ts, uint8_t *data, ssize_t data_len) {
|
174
|
246
|
process_emm(ts, pid, ts_packet);
|
175
|
247
|
process_ecm(ts, pid, ts_packet);
|
176
|
248
|
|
|
249
|
+ detect_discontinuity(ts, ts_packet);
|
|
250
|
+
|
177
|
251
|
if (!ts_pack_shown)
|
178
|
252
|
dump_ts_pack(ts, pid, ts_packet);
|
179
|
253
|
|