2
* parse various TV stuff out of DVB TS streams.
14
#include "parse-mpeg.h"
16
/* ----------------------------------------------------------------------- */
18
static unsigned int unbcd(unsigned int bcd)
20
unsigned int factor = 1;
26
ret += digit * factor;
33
static int iconv_string(char *from, char *to,
34
char *src, size_t len,
35
char *dst, size_t max)
37
size_t ilen = (-1 != len) ? len : strlen(src);
41
ic = iconv_open(to,from);
46
if (-1 == iconv(ic,&src,&ilen,&dst,&olen)) {
47
/* skip + quote broken byte unless we are out of space */
52
sprintf(dst,"\\x%02x",(int)(unsigned char)src[0]);
64
static int handle_control_8(unsigned char *src, int slen,
65
unsigned char *dest, int dlen)
69
for (s = 0, d = 0; s < slen && d < dlen;) {
70
if (src[s] >= 0x80 && src[s] <= 0x9f) {
73
case 0x87: /* </em> */
94
void mpeg_parse_psi_string(unsigned char *src, int slen,
95
unsigned char *dest, int dlen)
110
tlen = handle_control_8(src, slen, tmp, slen);
111
iconv_string(psi_charset[ch], "UTF-8", tmp, tlen, dest, dlen);
115
iconv_string(psi_charset[ch], "UTF-8", src, slen, dest, dlen);
119
static void parse_nit_desc_1(unsigned char *desc, int dlen,
124
for (i = 0; i < dlen; i += desc[i+1] +2) {
130
mpeg_parse_psi_string(desc+i+2,l,dest,max);
136
static void parse_nit_desc_2(unsigned char *desc, int dlen,
137
struct psi_stream *stream)
139
static char *bw[4] = {
144
static char *co_t[4] = {
149
static char *co_c[16] = {
157
static char *hi[4] = {
163
static char *ra_t[8] = {
170
static char *ra_sc[8] = {
177
static char *gu[4] = {
183
static char *tr[2] = {
187
static char *po[4] = {
190
[ 2 ] = "L", // circular left
191
[ 3 ] = "R", // circular right
193
unsigned int freq,rate,fec;
196
for (i = 0; i < dlen; i += desc[i+1] +2) {
201
case 0x43: /* dvb-s */
202
freq = mpeg_getbits(desc+i+2, 0, 32);
203
rate = mpeg_getbits(desc+i+2, 56, 28);
204
fec = mpeg_getbits(desc+i+2, 85, 3);
205
stream->frequency = unbcd(freq) * 10;
206
stream->symbol_rate = unbcd(rate*16) * 10;
207
stream->fec_inner = ra_sc[fec];
208
stream->polarization = po[ mpeg_getbits(desc+i+2, 49, 2) ];
210
case 0x44: /* dvb-c */
211
freq = mpeg_getbits(desc+i+2, 0, 32);
212
rate = mpeg_getbits(desc+i+2, 56, 28);
213
fec = mpeg_getbits(desc+i+2, 85, 3);
214
stream->frequency = unbcd(freq) * 100;
215
stream->symbol_rate = unbcd(rate*16) * 10;
216
stream->fec_inner = ra_sc[fec];
217
stream->constellation = co_c[ mpeg_getbits(desc+i+2, 52, 4) ];
219
case 0x5a: /* dvb-t */
220
stream->frequency = mpeg_getbits(desc+i+2, 0, 32) * 10;
221
stream->bandwidth = bw[ mpeg_getbits(desc+i+2, 33, 2) ];
222
stream->constellation = co_t[ mpeg_getbits(desc+i+2, 40, 2) ];
223
stream->hierarchy = hi[ mpeg_getbits(desc+i+2, 43, 2) ];
224
stream->code_rate_hp = ra_t[ mpeg_getbits(desc+i+2, 45, 3) ];
225
stream->code_rate_lp = ra_t[ mpeg_getbits(desc+i+2, 48, 3) ];
226
stream->guard = gu[ mpeg_getbits(desc+i+2, 51, 2) ];
227
stream->transmission = tr[ mpeg_getbits(desc+i+2, 54, 1) ];
234
static void parse_sdt_desc(unsigned char *desc, int dlen,
235
struct psi_program *pr)
240
for (i = 0; i < dlen; i += desc[i+1] +2) {
246
pr->type = desc[i+2];
249
name = net + net[0] + 1;
250
mpeg_parse_psi_string(net+1, net[0], pr->net, sizeof(pr->net));
251
mpeg_parse_psi_string(name+1, name[0], pr->name, sizeof(pr->name));
257
/* ----------------------------------------------------------------------- */
259
int mpeg_parse_psi_sdt(struct psi_info *info, unsigned char *data, int verbose)
261
static const char *running[] = {
263
[ 1 ] = "not running",
264
[ 2 ] = "starts soon",
267
[ 5 ... 8 ] = "reserved",
269
struct psi_program *pr;
270
int tsid,pnr,version,current;
271
int j,len,dlen,run,ca;
273
len = mpeg_getbits(data,12,12) + 3 - 4;
274
tsid = mpeg_getbits(data,24,16);
275
version = mpeg_getbits(data,42,5);
276
current = mpeg_getbits(data,47,1);
279
if (info->tsid == tsid && info->sdt_version == version)
281
info->sdt_version = version;
285
"ts [sdt]: tsid %d ver %2d [%d/%d]\n",
287
mpeg_getbits(data,48, 8),
288
mpeg_getbits(data,56, 8));
291
pnr = mpeg_getbits(data,j,16);
292
run = mpeg_getbits(data,j+24,3);
293
ca = mpeg_getbits(data,j+27,1);
294
dlen = mpeg_getbits(data,j+28,12);
296
fprintf(stderr," pnr %3d ca %d %s #",
297
pnr, ca, running[run]);
298
mpeg_dump_desc(data+j/8+5,dlen);
299
fprintf(stderr,"\n");
301
pr = psi_program_get(info, tsid, pnr, 1);
302
parse_sdt_desc(data+j/8+5,dlen,pr);
308
fprintf(stderr,"\n");
312
int mpeg_parse_psi_nit(struct psi_info *info, unsigned char *data, int verbose)
314
struct psi_stream *stream;
315
char network[PSI_STR_MAX] = "";
316
int id,version,current,len;
319
len = mpeg_getbits(data,12,12) + 3 - 4;
320
id = mpeg_getbits(data,24,16);
321
version = mpeg_getbits(data,42,5);
322
current = mpeg_getbits(data,47,1);
325
if (0 /* info->id == id */ && info->nit_version == version)
327
info->nit_version = version;
330
dlen = mpeg_getbits(data,68,12);
331
parse_nit_desc_1(data + j/8, dlen, network, sizeof(network));
334
"ts [nit]: id %3d ver %2d [%d/%d] #",
336
mpeg_getbits(data,48, 8),
337
mpeg_getbits(data,56, 8));
338
mpeg_dump_desc(data + j/8, dlen);
339
fprintf(stderr,"\n");
344
tsid = mpeg_getbits(data,j,16);
345
dlen = mpeg_getbits(data,j+36,12);
347
stream = psi_stream_get(info, tsid, 1);
350
strcpy(stream->net, network);
351
parse_nit_desc_2(data + j/8, dlen, stream);
353
fprintf(stderr," tsid %3d #", tsid);
354
mpeg_dump_desc(data + j/8, dlen);
355
fprintf(stderr,"\n");
361
fprintf(stderr,"\n");