-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtsdecode.c
213 lines (164 loc) · 4.39 KB
/
tsdecode.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/select.h>
#include <time.h>
#include <unistd.h>
#include "getstream.h"
#include "psi.h"
#define TS_PID_OFF1 1
#define TS_PID_OFF2 2
#define TS_CC_OFF 3
#define TS_CC_MASK 0xf
#define TS_AFC_OFF 3
#define TS_AFC_MASK 0x30
#define TS_AFC_SHIFT 4
#define TS_AFC_LEN 4
#define TS_HEAD_MIN 4
void _dump_hex(char *prefix, uint8_t *buf, int size) {
int i;
unsigned char ch;
char sascii[17];
char linebuffer[16*4+1];
sascii[16]=0x0;
for(i=0;i<size;i++) {
ch=buf[i];
if (i%16 == 0) {
sprintf(linebuffer, "%04x ", i);
}
sprintf(&linebuffer[(i%16)*3], "%02x ", ch);
if (ch >= ' ' && ch <= '}')
sascii[i%16]=ch;
else
sascii[i%16]='.';
if (i%16 == 15)
printf("%s %s %s\n", prefix, linebuffer, sascii);
}
/* i++ after loop */
if (i%16 != 0) {
for(;i%16 != 0;i++) {
sprintf(&linebuffer[(i%16)*3], " ");
sascii[i%16]=' ';
}
printf("%s %s %s\n", prefix, linebuffer, sascii);
}
}
static int pktno;
void decodebits(unsigned int bits, unsigned int mask,
unsigned int len, char *prefix, char *name) {
char line[128];
int val=0, i, j=0;
for(i=len-1;i>=0;i--) {
if (mask & (1<<i)) {
line[j++]=(bits & (1<<i)) ? '1' : '0';
val=val<<1|((bits & (1<<i)) ? 1 : 0);
} else {
line[j++]='.';
}
}
line[j++]=0x0;
printf("%s%s %s (%d)\n", prefix, line, name, val);
}
static void decode_tspkt(uint8_t *ts) {
unsigned int bits;
printf("Packet: %u\n", pktno);
_dump_hex(" ", ts, TS_PACKET_SIZE);
bits=ts[1]<<8|ts[2];
printf(" PID: 0x%04x\n", bits);
decodebits(bits, 0x8000, 16, " ", "transport error indicator");
decodebits(bits, 0x4000, 16, " ", "payload_unit_start_indicator");
decodebits(bits, 0x2000, 16, " ", "transport priority");
decodebits(bits, 0x1fff, 16, " ", "PID");
bits=ts[3];
printf(" AFC: 0x%02x\n", bits);
decodebits(bits, 0xc0, 8, " ", "transport scrambling control");
decodebits(bits, 0x30, 8, " ", "adaption field control");
decodebits(bits, 0x0f, 8, " ", "continuity counter");
if (ts_has_af(ts)) {
printf(" TS Packet has Adaption field (%d)\n", ts_af_len(ts));
}
}
#define ts_sync(ts) (ts[0] == 0x47)
static struct psisec_s patsec;
static struct psi_s pat;
void tsd_pat_section_dump(struct psisec_s *s) {
uint8_t *pat=s->data;
unsigned int bits;
unsigned int off;
decodebits(pat[0], 0xff, 8, " ", "table_id");
bits=pat[1]<<8|pat[2];
decodebits(bits, 0x8000, 16, " ", "section syntax indicator");
decodebits(bits, 0x4000, 16, " ", "0");
decodebits(bits, 0x3000, 16, " ", "reserved");
decodebits(bits, 0x0fff, 16, " ", "section length");
bits=pat[3]<<8|pat[4];
printf(" 0x%04x transport stream id\n", bits);
bits=pat[5];
decodebits(bits, 0xc0, 8, " ", "reserved");
decodebits(bits, 0x3e, 8, " ", "version");
decodebits(bits, 0x01, 8, " ", "current next indicator");
printf(" 0x%02x section number\n", pat[PAT_SECTION_OFF]);
printf(" 0x%02x last section number\n", pat[PAT_LAST_SECTION_OFF]);
off=PAT_HDR_LEN;
printf(" Program_number program_map_pid\n");
while(off < _psi_len(pat)-4) {
uint16_t pnr;
uint16_t pid;
pnr=pat[off]<<8|pat[off+1];
pid=(pat[off+2]<<8|pat[off+3])&PID_MASK;
printf(" %04x %04x\n", pnr, pid);
off+=4;
}
}
void tsd_pat(uint8_t *ts, uint16_t pid) {
int off=0;
while(off < TS_PACKET_SIZE) {
off=psi_reassemble(&patsec, ts, off);
if (off < 0)
break;
printf("%u pid %04x new pat section complete\n", pktno, pid);
tsd_pat_section_dump(&patsec);
psi_update_table(&pat, &patsec);
}
}
void tsd_packetin(uint8_t *ts) {
uint16_t pid;
if (!ts_sync(ts)) {
fprintf(stderr, "%06d Missing sync\n", pktno);
return;
}
if (ts_tei(ts))
fprintf(stderr, "%06d Packet has set TEI\n", pktno);
pid=ts_pid(ts);
switch(pid) {
case(0):
tsd_pat(ts, pid);
break;
}
}
int main(void ) {
uint8_t tsbuf[TS_PACKET_SIZE];
int len, valid=0, toread, no;
fd_set fdin;
while(1) {
toread=TS_PACKET_SIZE-valid;
FD_ZERO(&fdin);
FD_SET(fileno(stdin), &fdin);
no=select(1, &fdin, NULL, NULL, NULL);
if (!no)
continue;
len=read(fileno(stdin), &tsbuf, toread);
if (len == 0 || len < 0) {
printf("Aborting - short read %d/%d\n", len, toread);
exit(0);
}
valid+=len;
if (valid != TS_PACKET_SIZE)
continue;
pktno++;
tsd_packetin(tsbuf);
valid=0;
}
}