1 /*
2 * MPEG TS Program Specific Information Library code
3 * Copyright (C) 2007 - 2010 Andreas Öman
4 * Copyright (C) 2015 Jaroslav Kysela
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 as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "tvheadend.h"
21 #include "input.h"
22 #include "dvb.h"
23
24 /* **************************************************************************
25 * Lookup tables
26 * *************************************************************************/
27
28 static const int dvb_servicetype_map[][2] = {
29 { 0x01, ST_SDTV }, /* SDTV (MPEG2) */
30 { 0x02, ST_RADIO },
31 { 0x11, ST_HDTV }, /* HDTV (MPEG2) */
32 { 0x16, ST_SDTV }, /* Advanced codec SDTV */
33 { 0x17, ST_SDTV }, /* Advanced codec SDTV - NVOD time-shifted */
34 { 0x18, ST_SDTV }, /* Advanced codec SDTV - NVOD reference */
35 { 0x19, ST_HDTV }, /* Advanced codec HDTV */
36 { 0x1A, ST_HDTV }, /* Advanced codec HDTV - NVOD time-shifted */
37 { 0x1B, ST_HDTV }, /* Advanced codec HDTV - NVOD reference */
38 { 0x1C, ST_HDTV }, /* Advanced codec HDTV - plano-stereoscopic */
39 { 0x1D, ST_HDTV }, /* Advanced codec HDTV - plano-stereoscopic - NVOD time-shifted */
40 { 0x1E, ST_HDTV }, /* Advanced codec HDTV - plano-stereoscopic - NVOID reference */
41 { 0x1F, ST_UHDTV }, /* HEVC (assume all HEVC content is UHD?) */
42 { 0x80, ST_SDTV }, /* NET POA - Cabo SDTV */
43 { 0x91, ST_HDTV }, /* Bell TV HDTV */
44 { 0x96, ST_SDTV }, /* Bell TV SDTV */
45 { 0xA0, ST_HDTV }, /* Bell TV tiered HDTV */
46 { 0xA4, ST_HDTV }, /* DN HDTV */
47 { 0xA6, ST_HDTV }, /* Bell TV tiered HDTV */
48 { 0xA8, ST_SDTV }, /* DN advanced SDTV */
49 { 0xD3, ST_SDTV }, /* SKY TV SDTV */
50 };
51
52 int
dvb_servicetype_lookup(int t)53 dvb_servicetype_lookup ( int t )
54 {
55 int i;
56 for (i = 0; i < ARRAY_SIZE(dvb_servicetype_map); i++) {
57 if (dvb_servicetype_map[i][0] == t)
58 return dvb_servicetype_map[i][1];
59 }
60 return -1;
61 }
62
63 /* **************************************************************************
64 * Tables
65 * *************************************************************************/
66
67 /*
68 * Section assembly
69 */
70 static int
mpegts_psi_section_reassemble0(mpegts_psi_table_t * mt,const char * logpref,const uint8_t * data,int len,int start,int crc,mpegts_psi_section_callback_t cb,void * opaque)71 mpegts_psi_section_reassemble0
72 ( mpegts_psi_table_t *mt, const char *logpref,
73 const uint8_t *data,
74 int len, int start, int crc,
75 mpegts_psi_section_callback_t cb, void *opaque)
76 {
77 uint8_t *p = mt->mt_sect.ps_data;
78 int excess, tsize;
79
80 if(len <= 0)
81 return -1;
82
83 if(start) {
84 /* Payload unit start indicator */
85 mt->mt_sect.ps_offset = 0;
86 mt->mt_sect.ps_lock = 1;
87 if((data[0] & mt->mt_sect.ps_mask) != mt->mt_sect.ps_table) {
88 if(len >= 3) {
89 tsize = 3 + (((data[1] & 0xf) << 8) | data[2]);
90 if(len >= tsize)
91 return tsize;
92 }
93 }
94 }
95
96 if(!mt->mt_sect.ps_lock)
97 return -1;
98
99 if(mt->mt_sect.ps_offset + len > MPEGTS_PSI_SECTION_SIZE) {
100 tvherror(mt->mt_subsys, "PSI section overflow");
101 return -1;
102 }
103
104 memcpy(p + mt->mt_sect.ps_offset, data, len);
105 mt->mt_sect.ps_offset += len;
106
107 if(mt->mt_sect.ps_offset < 3) {
108 /* We don't know the total length yet */
109 return len;
110 }
111
112 tsize = 3 + (((p[1] & 0xf) << 8) | p[2]);
113
114 if(mt->mt_sect.ps_offset < tsize)
115 return len; // Not there yet
116
117 if(p[0] == 0x72) { /* stuffing section */
118 cb = NULL;
119 crc = 0;
120 } else if((p[0] & mt->mt_sect.ps_mask) != mt->mt_sect.ps_table) {
121 cb = NULL;
122 }
123
124 if(crc && tvh_crc32(p, tsize, 0xffffffff)) {
125 if (cb && tvhlog_limit(&mt->mt_err_log, 10)) {
126 tvhwarn(mt->mt_subsys, "%s: %s: invalid checksum (len %i, errors %zi)",
127 mt->mt_name, logpref, tsize, mt->mt_err_log.count);
128 }
129 return -1;
130 }
131
132 excess = mt->mt_sect.ps_offset - tsize;
133
134 if (cb)
135 cb(p, tsize - (crc ? 4 : 0), opaque);
136
137 return len - excess;
138 }
139
140 /**
141 *
142 */
143 void
mpegts_psi_section_reassemble(mpegts_psi_table_t * mt,const char * logprefix,const uint8_t * tsb,int crc,mpegts_psi_section_callback_t cb,void * opaque)144 mpegts_psi_section_reassemble
145 (mpegts_psi_table_t *mt, const char *logprefix,
146 const uint8_t *tsb, int crc,
147 mpegts_psi_section_callback_t cb, void *opaque)
148 {
149 int pusi = tsb[1] & 0x40;
150 uint8_t cc = tsb[3];
151 int off = cc & 0x20 ? tsb[4] + 5 : 4;
152 int r;
153
154 if (cc & 0x10) {
155 if (mt->mt_sect.ps_cc != -1 && mt->mt_sect.ps_cc != (cc & 0x0f)) {
156 uint16_t pid = ((tsb[1] & 0x1f) << 8) | tsb[2];
157 tvhdebug(mt->mt_subsys, "%s: %s: PID %04X CC error %d != %d",
158 mt->mt_name, logprefix, pid, cc & 0x0f, mt->mt_sect.ps_cc);
159 mt->mt_sect.ps_lock = 0;
160 }
161 mt->mt_sect.ps_cc = (cc + 1) & 0x0f;
162 }
163
164 if(off >= 188) {
165 mt->mt_sect.ps_lock = 0;
166 return;
167 }
168
169 if(pusi) {
170 uint8_t len2 = tsb[off++];
171 uint8_t off2 = off;
172 off += len2;
173 if (off > 188)
174 goto wrong_state;
175 while (off2 < len2) {
176 r = mpegts_psi_section_reassemble0(mt, logprefix, tsb + off2, len2, 0, crc, cb, opaque);
177 if (r < 0)
178 goto wrong_state;
179 off2 += r;
180 len2 -= r;
181 }
182 }
183
184 while(off < 188) {
185 r = mpegts_psi_section_reassemble0(mt, logprefix, tsb + off, 188 - off, pusi, crc,
186 cb, opaque);
187 if (r < 0)
188 goto wrong_state;
189 off += r;
190 }
191 return;
192
193 wrong_state:
194 mt->mt_sect.ps_lock = 0;
195 }
196
197 /*
198 *
199 */
200
sect_cmp(mpegts_psi_table_state_t * a,mpegts_psi_table_state_t * b)201 static int sect_cmp
202 ( mpegts_psi_table_state_t *a, mpegts_psi_table_state_t *b )
203 {
204 if (a->tableid != b->tableid)
205 return a->tableid - b->tableid;
206 if (a->extraid < b->extraid)
207 return -1;
208 if (a->extraid > b->extraid)
209 return 1;
210 return 0;
211 }
212
213 static void
mpegts_table_state_reset(mpegts_psi_table_t * mt,mpegts_psi_table_state_t * st,int last)214 mpegts_table_state_reset
215 ( mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int last )
216 {
217 int i;
218 mt->mt_finished = 0;
219 st->complete = 0;
220 st->version = MPEGTS_PSI_VERSION_NONE;
221 st->last = last;
222 memset(st->sections, 0, sizeof(st->sections));
223 for (i = 0; i < last / 32; i++)
224 st->sections[i] = 0xFFFFFFFF;
225 st->sections[last / 32] = 0xFFFFFFFF << (31 - (last % 32));
226 }
227
228 static void
mpegts_table_state_restart(mpegts_psi_table_t * mt,mpegts_psi_table_state_t * st,int last,int ver)229 mpegts_table_state_restart
230 ( mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int last, int ver )
231 {
232 if (st->complete == 2)
233 mt->mt_complete--;
234 if (st->complete)
235 mt->mt_incomplete++;
236 mpegts_table_state_reset(mt, st, last);
237 st->version = ver;
238 }
239
240 static mpegts_psi_table_state_t *
mpegts_table_state_find(mpegts_psi_table_t * mt,int tableid,uint64_t extraid,int last)241 mpegts_table_state_find
242 ( mpegts_psi_table_t *mt, int tableid, uint64_t extraid, int last )
243 {
244 mpegts_psi_table_state_t *st, *st2, st_cmp;
245
246 /* Find state */
247 st_cmp.tableid = tableid;
248 st_cmp.extraid = extraid;
249 st = RB_FIND(&mt->mt_state, &st_cmp, link, sect_cmp);
250 if (st)
251 return st;
252 st = calloc(1, sizeof(*st));
253 st->tableid = tableid;
254 st->extraid = extraid;
255 st2 = RB_INSERT_SORTED(&mt->mt_state, st, link, sect_cmp);
256 assert(st2 == NULL);
257 mt->mt_incomplete++;
258 mpegts_table_state_reset(mt, st, last);
259 return st;
260 }
261
262 /*
263 * End table
264 */
265 static int
dvb_table_complete(mpegts_psi_table_t * mt)266 dvb_table_complete
267 (mpegts_psi_table_t *mt)
268 {
269 if (mt->mt_incomplete || !mt->mt_complete) {
270 int total = 0;
271 mpegts_psi_table_state_t *st;
272 RB_FOREACH(st, &mt->mt_state, link)
273 total++;
274 tvhtrace(mt->mt_subsys, "%s: incomplete %d complete %d total %d",
275 mt->mt_name, mt->mt_incomplete, mt->mt_complete, total);
276 return 2;
277 }
278 if (!mt->mt_finished)
279 tvhdebug(mt->mt_subsys, "%s: completed pid %d table %08X / %08x",
280 mt->mt_name, mt->mt_pid, mt->mt_table, mt->mt_mask);
281 mt->mt_finished = 1;
282 return 0;
283 }
284
285 int
dvb_table_end(mpegts_psi_table_t * mt,mpegts_psi_table_state_t * st,int sect)286 dvb_table_end
287 (mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int sect)
288 {
289 int sa, sb;
290 uint32_t rem;
291 if (st && !st->complete) {
292 assert(sect >= 0 && sect <= 255);
293 sa = sect / 32;
294 sb = sect % 32;
295 st->sections[sa] &= ~(0x1 << (31 - sb));
296 if (!st->sections[sa]) {
297 rem = 0;
298 for (sa = 0; sa < 8; sa++)
299 rem |= st->sections[sa];
300 if (rem) return 1;
301 tvhtrace(mt->mt_subsys, "%s: tableid %02X extraid %016" PRIx64 " completed",
302 mt->mt_name, st->tableid, st->extraid);
303 st->complete = 1;
304 mt->mt_incomplete--;
305 return dvb_table_complete(mt);
306 }
307 } else if (st)
308 return dvb_table_complete(mt);
309 return 2;
310 }
311
312 /*
313 * Begin table
314 */
315 int
dvb_table_begin(mpegts_psi_table_t * mt,const uint8_t * ptr,int len,int tableid,uint64_t extraid,int minlen,mpegts_psi_table_state_t ** ret,int * sect,int * last,int * ver)316 dvb_table_begin
317 (mpegts_psi_table_t *mt, const uint8_t *ptr, int len,
318 int tableid, uint64_t extraid, int minlen,
319 mpegts_psi_table_state_t **ret, int *sect, int *last, int *ver)
320 {
321 mpegts_psi_table_state_t *st;
322 uint32_t sa, sb;
323
324 /* Not long enough */
325 if (len < minlen) {
326 tvhdebug(mt->mt_subsys, "%s: invalid table length %d min %d", mt->mt_name, len, minlen);
327 return -1;
328 }
329
330 /* Ignore next */
331 if((ptr[2] & 1) == 0)
332 return -1;
333
334 tvhtrace(mt->mt_subsys, "%s: pid %02X tableid %02X extraid %016" PRIx64 " len %d",
335 mt->mt_name, mt->mt_pid, tableid, extraid, len);
336
337 /* Section info */
338 if (sect && ret) {
339 *sect = ptr[3];
340 *last = ptr[4];
341 *ver = (ptr[2] >> 1) & 0x1F;
342 *ret = st = mpegts_table_state_find(mt, tableid, extraid, *last);
343 tvhtrace(mt->mt_subsys, "%s: section %d last %d ver %d (ver %d st %d incomp %d comp %d)",
344 mt->mt_name, *sect, *last, *ver, st->version, st->complete, mt->mt_incomplete, mt->mt_complete);
345
346 #if 0 // FIXME, cannot be enabled in this form
347 /* Ignore previous version */
348 /* This check is for the broken PMT tables where:
349 * last 0 version 21 = PCR + Audio PID 0x0044
350 * last 0 version 22 = Audio PID 0x0044, PCR + Video PID 0x0045
351 */
352 if (*last == 0 && st->version - 1 == *ver)
353 return -1;
354 #endif
355
356 /* New version */
357 if (st->version == MPEGTS_PSI_VERSION_NONE)
358 st->version = *ver;
359 if (st->version != *ver) {
360 tvhtrace(mt->mt_subsys, "%s: new version, restart", mt->mt_name);
361 mpegts_table_state_restart(mt, st, *last, *ver);
362 }
363
364 /* Complete? */
365 if (st->complete) {
366 tvhtrace(mt->mt_subsys, "%s: skip, already complete (%i)", mt->mt_name, st->complete);
367 if (st->complete == 1) {
368 st->complete = 2;
369 mt->mt_complete++;
370 return dvb_table_complete(mt);
371 } else if (st->complete == 2) {
372 return dvb_table_complete(mt);
373 }
374 assert(0);
375 }
376
377 /* Already seen? */
378 sa = *sect / 32;
379 sb = *sect % 32;
380 if (!(st->sections[sa] & (0x1 << (31 - sb)))) {
381 tvhtrace(mt->mt_subsys, "%s: skip, already seen", mt->mt_name);
382 return -1;
383 }
384 }
385
386 tvhlog_hexdump(mt->mt_subsys, ptr, len);
387
388 return 1;
389 }
390
391 void
dvb_table_reset(mpegts_psi_table_t * mt)392 dvb_table_reset(mpegts_psi_table_t *mt)
393 {
394 mpegts_psi_table_state_t *st;
395
396 tvhtrace(mt->mt_subsys, "%s: pid %02X complete reset", mt->mt_name, mt->mt_pid);
397 mt->mt_incomplete = 0;
398 mt->mt_complete = 0;
399 while ((st = RB_FIRST(&mt->mt_state)) != NULL) {
400 RB_REMOVE(&mt->mt_state, st, link);
401 free(st);
402 }
403 }
404
405 void
dvb_table_release(mpegts_psi_table_t * mt)406 dvb_table_release(mpegts_psi_table_t *mt)
407 {
408 mpegts_psi_table_state_t *st;
409
410 while ((st = RB_FIRST(&mt->mt_state))) {
411 RB_REMOVE(&mt->mt_state, st, link);
412 free(st);
413 }
414 }
415
416 /*
417 *
418 */
419
dvb_table_parse_init(mpegts_psi_table_t * mt,const char * name,int subsys,int pid,uint8_t table,uint8_t mask,void * opaque)420 void dvb_table_parse_init
421 ( mpegts_psi_table_t *mt, const char *name, int subsys, int pid,
422 uint8_t table, uint8_t mask, void *opaque )
423 {
424 memset(mt, 0, sizeof(*mt));
425 mt->mt_name = strdup(name);
426 mt->mt_subsys = subsys;
427 mt->mt_opaque = opaque;
428 mt->mt_pid = pid;
429 mt->mt_sect.ps_cc = -1;
430 mt->mt_sect.ps_table = table;
431 mt->mt_sect.ps_mask = mask;
432 }
433
dvb_table_parse_done(mpegts_psi_table_t * mt)434 void dvb_table_parse_done( mpegts_psi_table_t *mt )
435 {
436 free(mt->mt_name);
437 }
438
439 struct psi_parse {
440 mpegts_psi_table_t *mt;
441 mpegts_psi_parse_callback_t cb;
442 int full;
443 };
444
445 static void
dvb_table_parse_cb(const uint8_t * sec,size_t len,void * opaque)446 dvb_table_parse_cb( const uint8_t *sec, size_t len, void *opaque )
447 {
448 struct psi_parse *parse = opaque;
449
450 parse->cb(parse->mt, sec + parse->full, len - parse->full);
451 }
452
dvb_table_parse(mpegts_psi_table_t * mt,const char * logprefix,const uint8_t * tsb,int len,int crc,int full,mpegts_psi_parse_callback_t cb)453 void dvb_table_parse
454 (mpegts_psi_table_t *mt, const char *logprefix,
455 const uint8_t *tsb, int len,
456 int crc, int full, mpegts_psi_parse_callback_t cb)
457 {
458 const uint8_t *end;
459 struct psi_parse parse;
460
461 parse.mt = mt;
462 parse.cb = cb;
463 parse.full = full ? 3 : 0;
464
465 for (end = tsb + len; tsb < end; tsb += 188)
466 mpegts_psi_section_reassemble(mt, logprefix, tsb, crc,
467 dvb_table_parse_cb, &parse);
468 }
469
dvb_table_append_crc32(uint8_t * dst,int off,int maxlen)470 int dvb_table_append_crc32(uint8_t *dst, int off, int maxlen)
471 {
472 if (off + 4 > maxlen)
473 return -1;
474
475 uint32_t crc = tvh_crc32(dst, off, 0xffffffff);
476 dst[off++] = crc >> 24;
477 dst[off++] = crc >> 16;
478 dst[off++] = crc >> 8;
479 dst[off++] = crc;
480 return off;
481 }
482
dvb_table_remux(mpegts_psi_table_t * mt,const uint8_t * buf,int len,uint8_t ** out)483 int dvb_table_remux
484 (mpegts_psi_table_t *mt, const uint8_t *buf, int len, uint8_t **out)
485 {
486 uint8_t *obuf, pusi;
487 int ol = 0, l, m;
488
489 /* try to guess the output size here */
490 obuf = malloc(((len + 183 + 1 /* pusi */) / 184) * 188);
491
492 pusi = 0x40;
493 while (len > 0) {
494 obuf[ol++] = 0x47;
495 obuf[ol++] = pusi | ((mt->mt_pid >> 8) & 0x1f);
496 obuf[ol++] = mt->mt_pid & 0xff;
497 obuf[ol++] = 0x10 | ((mt->mt_sect.ps_cco++) & 0x0f);
498 if (pusi) {
499 obuf[ol++] = 0;
500 m = 183;
501 pusi = 0;
502 } else {
503 m = 184;
504 }
505 l = MIN(m, len);
506 memcpy(obuf + ol, buf, l);
507 if (l < m)
508 memset(obuf + ol + l, 0xff, m - l);
509 ol += m;
510 len -= l;
511 buf += l;
512 }
513
514 if (ol <= 0) {
515 free(obuf);
516 return 0;
517 }
518 *out = obuf;
519 return ol;
520 }
521