titler font fixups, debian i386 build
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / dvb.C
1 #include "libzmpeg3.h"
2 #include "huf.h"
3
4 #ifdef ZDVB
5
6 //#define DEBUG
7
8 #ifdef DEBUG
9 static const char *desc_name1[] = {
10 /* 00 */  0,
11 /* 01 */  0,
12 /* 02 */  "video_stream_descr",
13 /* 03 */  "audio_stream_descr",
14 /* 04 */  "hierarchy_descr",
15 /* 05 */  "registration_descr",
16 /* 06 */  "data_stream_align_descr",
17 /* 07 */  "target_background_grid_descr",
18 /* 08 */  "video_window_descr",
19 /* 09 */  "CA_descr",
20 /* 0a */  "ISO_639_lang_descr",
21 /* 0b */  "syst_clk_descr",
22 /* 0c */  "multiplex_buf_utilization_descr",
23 /* 0d */  "copyright_descr",
24 /* 0e */  "max_bitrate_descr",
25 /* 0f */  "private_data_indicator_descr",
26 /* 10 */  "smoothing_buf_descr",
27 /* 11 */  "STD_descr",
28 /* 12 */  "IBP_descr",
29 /* 13 */ 0,
30 /* 14 */ "assoc_tag_descr",
31 };
32
33 static const char *desc_name2[] = {
34 /* 80 */  "stuffing_descr",
35 /* 81 */  "AC-3 audio descr",
36 /* 82 */ 0, 0, 0, 0, /* - 85 */
37 /* 86 */ "caption_serv_descr",
38 /* 87 */ "content_advisory_descr",
39 /* 88 */ 0, 0, 0, 0, 0, 0, 0, 0, /* - 8f */
40 /* 90 */ 0, 0, 0, 0, 0, 0, 0, 0, /* - 97 */
41 /* 98 */ 0, 0, 0, 0, 0, 0, 0, 0, /* - 9f */
42 /* a0 */ "extended_ch_name_descr",
43 /* a1 */ "serv_location_descr",
44 /* a2 */ "time_shifted_serv_descr",
45 /* a3 */ "component_name_descr",
46 /* a4 */ "data_service_descr",
47 /* a5 */ "PID_count_descr",
48 /* a6 */ "Download_descr",
49 /* a7 */ "multiprotocol_encapsulate_descr",
50 /* a8 */ "DCC_departing_event_descr",
51 /* a9 */ "DCC_arriving_event_descr",
52 /* aa */ "Content_Protect_Copy_Mngt_descr",
53 /* ab */ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* - b3 */
54 /* b4 */ "Module_Link_descr",
55 /* b5 */ "CRC32_descr",
56 /* b6 */ 0, 0, /* - b7 */
57 /* b8 */ "Group_Link_descr",
58 };
59
60 /* print descr tag info */
61
62 static void prt_descr(uint32_t tag, int len)
63 {
64   int n;
65   const char *nm = 0;
66   printf("descr tag/len=0x%02x/%u (", tag, len);
67   if( tag < lengthof(desc_name1) )
68     nm = desc_name1[tag];
69   else if( (n=tag-0x80) >= 0 && n<=lengthof(desc_name2) )
70     nm = desc_name2[n];
71   if( nm == 0 ) nm = "n/a";
72   printf("%s)\n",nm);
73 }
74
75 static void prt_vct(zvct_t *vct)
76 {
77   printf("VCT table -\n");
78   printf(" ver=0x%04x\n", vct->version);
79   printf(" items=0x%04x\n", vct->items);
80   printf(" ts_stream_id=0x%04x\n", vct->transport_stream_id);
81   for( int i=0; i<vct->items; ++i ) {
82     zvitem_t *item = vct->vct_tbl[i];
83     printf(" %2d. name= ", i);
84     for( int j=0; j<7; ++j ) {
85       int ch = item->short_name[j];
86       printf("%c", ch>=0x20 && ch<0x80 ? ch : '.');
87     }
88     printf("\n");
89     printf(" maj =0x%04x", item->major_channel_number);
90     printf(" min =0x%04x", item->minor_channel_number);
91     printf(" mod =0x%04x", item->modulation_mode     );
92     printf(" freq=0x%04x", item->carrier_frequency   );
93     printf(" TSid=0x%04x", item->channel_TSID        );
94     printf(" prog=0x%04x\n", item->program_number      );
95     printf(" etm =0x%04x", item->etm_location        );
96     printf(" acc =0x%04x", item->access_controlled   );
97     printf(" hide=0x%04x", item->hidden              );
98     printf(" serv=0x%04x", item->service_type        );
99     printf(" s_id=0x%04x", item->source_id           );
100     printf(" pcr =0x%04x\n", item->pcr_pid             );
101     for( int k=0; k<item->num_ch_elts; ++k ) {
102       printf("   %2d.", k);
103       printf(" stream=0x%04x",item->elts[k].stream_id  );
104       printf(" pid=0x%04x",item->elts[k].pes_pid    );
105       int ch0 = item->elts[k].code_639[0];
106       int ch1 = item->elts[k].code_639[1];
107       int ch2 = item->elts[k].code_639[2];
108       printf(" lang_code=%c",ch0>=0x20 && ch0<0x80 ? ch0 : '.');
109       printf("%c",ch1>=0x20 && ch1<0x80 ? ch1 : '.');
110       printf("%c",ch2>=0x20 && ch2<0x80 ? ch2 : '.');
111       printf("\n");
112     }
113   }
114 }
115
116 static void prt_mgt(zmgt_t *mgt)
117 {
118   printf("MGT table - items=%d\n", mgt->items);
119   zmitem_t *item = mgt->mitems;
120   for( int i=0; i<mgt->items; ++i,++item ) {
121     printf("   %2d.", i);
122     printf(" typ=0x%04x", item->type);
123     char msg[16];
124     uint16_t type = item->type;
125      if( type >= 0x1500 ) sprintf(msg,"Reserved");
126 else if( type >= 0x1400 ) sprintf(msg,"DCCT %04x",type-0x1400);
127 else if( type >= 0x1000 ) sprintf(msg,"Reserved");
128 else if( type >= 0x0400 ) sprintf(msg,"Private%3d",type-0x0400);
129 else if( type >= 0x0301 ) sprintf(msg,"RRT %3d",type-0x0300);
130 else if( type >= 0x0280 ) sprintf(msg,"Reserved");
131 else if( type >= 0x0200 ) sprintf(msg,"ETT %3d",type-0x0200);
132 else if( type >= 0x0180 ) sprintf(msg,"Reserved");
133 else if( type >= 0x0100 ) sprintf(msg,"EIT %3d",type-0x0100);
134 else if( type >= 0x0006 ) sprintf(msg,"Reserved");
135 else if( type == 0x0005 ) sprintf(msg,"DCCSCT");
136 else if( type == 0x0004 ) sprintf(msg,"ChanETT");
137 else if( type == 0x0003 ) sprintf(msg,"CableVCT0");
138 else if( type == 0x0002 ) sprintf(msg,"CableVCT1");
139 else if( type == 0x0001 ) sprintf(msg,"TerraVCT0");
140 else if( type == 0x0000 ) sprintf(msg,"TerraVCT1");
141     printf("(%-10s)",msg);
142     printf(" pid=0x%04x", item->pid);
143     printf(" ver=0x%04x", item->version);
144     printf(" size=0x%04x", item->size);
145     printf("\n");
146   }
147 }
148
149 static void prt_stt(zdvb_t *dvb, zstt_t *stt)
150 {
151   time_t tm = stt->system_time + dvb->stt_offset();
152   printf("STT table  table_id=0x%04x - %s\n", stt->table_id, ctime(&tm));
153 }
154
155 static void prt_huf(zdvb_t *dvb,uint8_t *bp, int len)
156 {
157   char *text = dvb->mstring(bp,len);
158   if( text ) printf("%s",text);
159   delete [] text;
160 }
161
162 static void prt_rrt(zrrt_t *rrt)
163 {
164   int items = rrt->items;
165   printf("RRT table - items=%d\n      region=", items);
166   prt_huf(rrt->dvb,rrt->region_name,rrt->region_nlen);  printf("\n");
167   zritem_t *rp = rrt->ratings;
168   for( int i=0; i<items; ++i,++rp ) {
169     printf("  %d  ",i);
170     prt_huf(rrt->dvb,rp->dim_name,rp->dim_nlen);  printf("\n");
171     printf("   grad %d, num=%d\n", rp->graduated_scale, rp->num_values);
172     zrating_vt *ap = rp->abrevs;
173     int values = rp->num_values;
174     for( int j=0; j<values; ++j,++ap ) {
175       printf("   %3d ", j);  prt_huf(rrt->dvb,ap->rating_name,ap->rating_nlen);
176       printf(" = ");  prt_huf(rrt->dvb,ap->rating_text,ap->rating_tlen); printf("\n");
177     }
178   }
179 }
180
181 static void prt_ett(zdvb_t *dvb,zetext_t *etxt)
182 {
183   printf("ETT table - table_id=0x%04x, etm_id=%08x, ",etxt->table_id, etxt->etm_id);
184   printf("source_id=%04x, ", etxt->etm_id>>16);
185   printf("event_id=%04x\n    ", (etxt->etm_id & 0xffff) >> 2);
186   prt_huf(dvb,etxt->msg_text,etxt->msg_tlen); printf("\n");
187 }
188
189 static void prt_eit(zdvb_t *dvb,zeit_t *eit)
190 {
191   printf("EIT table - source_id=0x%04x, items=%d\n", eit->source_id, eit->items);
192   zeinfo_t *ep = eit->infos;
193   for( int i=0; i<eit->items; ++i,++ep ) {
194     time_t tm = ep->start_time + dvb->stt_offset();
195     printf(" %2d.  id=%04x  %02d:%02d %s    | ", i, ep->event_id,
196       ep->seconds/3600, (ep->seconds/60)%60, ctime(&tm));
197     prt_huf(eit->dvb,ep->title_text,ep->title_tlen); printf("\n");
198   }
199 }
200
201 #endif
202 // comment/uncomment to enable/disable prt
203 //#define dprintf(s...) printf(s)
204 #define dprintf(s...) do {} while(0)
205 #define prt_descr(s,t) do {} while(0)
206 #define prt_vct(s) do {} while(0)
207 #define prt_mgt(s) do {} while(0)
208 #define prt_stt(d,s) do {} while(0)
209 #define prt_rrt(s) do {} while(0)
210 #define prt_eit(d,s) do {} while(0)
211 #define prt_ett(d,s) do {} while(0)
212
213 zdvb_t::
214 dvb_t(zmpeg3_t *zsrc)
215 : src(zsrc),
216   base_pid(0x1ffb)
217 {
218   char *cp = getenv("DVB_STREAM_PROBE");
219   empirical = cp ? atoi(cp) : 0;
220   active = 0;
221 }
222
223 zdvb_t::
224 ~dvb_t()
225 {
226   reset();
227 }
228
229 void zdvb_t::
230 reset()
231 {
232   stt_start_time = 0;
233   delete mgt;  mgt = 0;
234   while( eit ) { eit_t *nxt = eit->next;  delete eit;  eit = nxt; }
235   while( ett ) { ett_t *nxt = ett->next;  delete ett;  ett = nxt; }
236   delete tvct; tvct = 0;
237   delete cvct; cvct = 0;
238   delete rrt;  rrt = 0;
239   delete stt;  stt = 0;
240   base_pid.clear();
241   active = 0;
242 }
243
244 void zdvb_t::
245 skip_bfr(int n)
246 {
247   int len = bfr_len();
248   if( n > len ) n = len;
249   xbfr += n;
250 }
251
252 int zdvb_t::
253 get_text(uint8_t *dat, int bytes)
254 {
255   int len = get8bits();
256   int count = len < bytes ? len : bytes;
257   for( int i=0; i<count; ++i ) *dat++ = get8bits();
258   skp_bfr(len-count);
259   return count;
260 }
261
262 void zdvb_t::
263 append_text(char *msg, int n)
264 {
265   int len = strnlen(msg, n);
266   int m = text_length + len + 1;
267   if( m > text_allocated ) {
268     int allocated = 2*text_allocated + len + 0x100;
269     char *new_text = new char[allocated];
270     text_allocated = allocated;
271     memcpy(new_text, text, text_length);
272     delete text;  text = new_text;
273   }
274   memmove(text+text_length,msg,len);
275   text[text_length += len] = 0;
276 }
277
278 char *zdvb_t::
279 mstring(uint8_t *bp, int len)
280 {
281   char msg[4096];
282   text_length = text_allocated = 0;
283   text = 0;  uint8_t *ep = bp + len;
284   int num = !len ? 0 : *bp++;
285   for( int i=0; i<num && bp<ep; ++i ) {
286     //uint8_t enc[4];
287     //enc[0] = *bp++; enc[1] = *bp++;
288     //enc[2] = *bp++; enc[3] = 0;
289     bp += 3; // enc
290     int segs = *bp++;
291     for( int j=0; j<segs; ++j ) {
292       int type = *bp++;
293       int mode = *bp++;  (void)mode;
294       int bytes = *bp++;
295       uint8_t *dat = bp;
296       bp += bytes;
297       switch( type ) {
298       case 0x01: { // huffman 1
299         int len = huf::huf1_decode(dat,bytes*8,msg,sizeof(msg));
300         append_text(msg,len);
301         break; }
302       case 0x02: { // huffman 2
303         int len = huf::huf2_decode(dat,bytes*8,msg,sizeof(msg));
304         append_text(msg,len);
305         break; }
306       default: { // no compression
307         append_text((char*)&dat[0],bytes);
308         break; }
309       }
310     }
311   }
312   return text;
313 }
314
315 void zdvb_t::
316 skip_descr(int descr_length)
317 {
318   if( descr_length > 0 && descr_length <= bfr_len() ) {
319     int descr_bytes = 0;
320     while( descr_bytes < descr_length ) {
321       uint32_t tag = get8bits();
322      (void)tag; /* avoid cmplr msg when debug off */
323       int len = get8bits() + 2;
324       int count = 2;
325       prt_descr(tag, len);
326       skp_bfr(len-count);
327       descr_bytes += len;
328     }
329   }
330 }
331
332 void zmitem_t::
333 init(int len)
334 {
335   if( len > bfr_alloc ) {
336     delete [] bfr;
337     bfr = new uint8_t[len];
338     bfr_alloc = len;
339   }
340   bfr_size = 0;
341   tbl_len = len;
342 }
343
344 void zmitem_t::
345 extract(uint8_t *dat, int len)
346 {
347   if( bfr_size+len <= bfr_alloc || (len=bfr_alloc-bfr_size) > 0 ) {
348     memcpy(bfr+bfr_size, dat, len);
349     bfr_size += len;
350   }
351 }
352
353 void zmitem_t::
354 clear()
355 {
356   delete [] bfr;
357   bfr = 0;
358   bfr_size = bfr_alloc = 0;
359 }
360
361 void zmgt_t::
362 extract()
363 {
364   clear();
365   items = dvb->get16bits();
366   mitems = new mitem_t[items];
367   mitem_t *item = mitems;
368   for( int i=0; i<items; ++i,++item ) {
369     item->type = dvb->get16bits();
370     item->pid = dvb->get16bits() & 0x1fff;
371     item->version = dvb->get8bits() & 0x1f;
372     item->size = dvb->get32bits();
373     int descr_len = dvb->get16bits() & 0xfff;
374     dvb->skip_descr(descr_len);
375   }
376   int descr_len = dvb->get16bits() & 0xfff;
377   dvb->skip_descr(descr_len);
378   prt_mgt(this);
379 }
380
381 void zmgt_t::
382 clear()
383 {
384   delete [] mitems;  mitems = 0;
385   items = 0;
386 }
387
388 zmitem_t *zmgt_t::
389 search(uint16_t pid)
390 {
391   mitem_t *item = mitems;
392   int i = items;
393   while( --i>=0 && item->pid!=pid ) ++item;
394   return i < 0 ? 0 : item;
395 }
396
397 void zch_elts_t::
398 extract(dvb_t *dvb)
399 {
400   stream_id = dvb->get8bits();
401   pes_pid = dvb->get16bits() & 0x1fff;
402   code_639[0] = dvb->get8bits();
403   code_639[1] = dvb->get8bits();
404   code_639[2] = dvb->get8bits();
405 }
406
407 void zvitem_t::
408 extract(dvb_t *dvb)
409 {
410   for( int i=0; i<7 ; ++i ) short_name[i] = dvb->get16bits();
411   uint8_t b0 = dvb->get8bits();
412   uint8_t b1 = dvb->get8bits();
413   uint8_t b2 = dvb->get8bits();
414   major_channel_number = ((b0&0x0f)<<6) | ((b1>>2)&0x3f);
415   minor_channel_number = ((b1&0x03)<<8) | b2;
416   modulation_mode = dvb->get8bits();
417   carrier_frequency = dvb->get32bits();
418   channel_TSID = dvb->get16bits();
419   program_number = dvb->get16bits();
420   b0 = dvb->get8bits();
421   etm_location = (b0 >> 6) & 0x03;
422   access_controlled = (b0 >> 5) & 1;
423   hidden = (b0 >> 4) & 1;
424   path_select = (b0 >> 3) & 1;
425   out_of_band = (b0 >> 2) & 1;
426   service_type = dvb->get8bits() & 0x3f;
427   source_id = dvb->get16bits();
428   num_ch_elts = 0;
429
430   int descr_length = dvb->get16bits() & 0x3ff;
431   int descr_bytes = 0;
432
433   while( descr_bytes < descr_length ) {
434     if( dvb->bfr_len() < 2 ) return;
435     uint32_t tag = dvb->get8bits();
436     int len = dvb->get8bits() + 2;
437     prt_descr(tag, len);
438     int count = 2;
439     if( tag == 0xa1 ) {
440       /* "Service Location Descriptor", extract common info */
441       pcr_pid = dvb->get16bits() & 0x1fff;
442       int num_elts = dvb->get8bits();
443       count += 3;
444       int n = num_elts;
445       if( n > lengthof(elts) ) {
446         n = lengthof(elts);
447         printf("num of pids = %d -- truncated to %d\n", num_elts,n);
448       }
449       /* step thru each channel element & extract info into the VCT */
450       num_ch_elts += n;
451       for( int j=0; j<n; ++j )
452         elts[j].extract(dvb);
453       count += n*6;
454     }
455     dvb->skp_bfr(len-count);
456     descr_bytes += len;
457   }
458 }
459
460 int zvct_t::
461 search(zvitem_t &new_item)
462 {
463   uint32_t maj = new_item.major_channel_number;
464   uint32_t min = new_item.minor_channel_number;
465   for( int i=items; --i>=0; ) {
466     vitem_t *item = vct_tbl[i];
467     if( maj == item->major_channel_number &&
468         min == item->minor_channel_number ) return 1;
469   }
470   return 0;
471 }
472
473 void zvct_t::
474 append(zvitem_t &new_vitem)
475 {
476   if( items >= items_allocated ) {
477     int allocated = 2*items_allocated + 16;
478     vitem_t **new_vct_tbl = new vitem_t *[allocated];
479     items_allocated = allocated;
480     for( int i=0; i<items; ++i ) new_vct_tbl[i] = vct_tbl[i];
481     delete [] vct_tbl;  vct_tbl = new_vct_tbl;
482   }
483   vct_tbl[items++] = new vitem_t(new_vitem);
484 }
485
486 void zvct_t::
487 extract()
488 {
489   transport_stream_id = dvb->stream_id;
490   version = dvb->version;
491   int nitems = dvb->get8bits();
492   /* append new entries */
493   for( int i=0; i<nitems; ++i ) {
494     vct_t::vitem_t new_item;
495     new_item.extract(dvb);
496     if( !search(new_item) )
497       append(new_item);
498   }
499   int descr_len = dvb->get16bits() & 0x3ff;
500   dvb->skip_descr(descr_len);
501   prt_vct(this);
502 }
503
504 void zvct_t::
505 clear()
506 {
507   for( int i=0; i<items; ++i ) delete vct_tbl[i];
508   delete [] vct_tbl;  vct_tbl = 0;
509   items = items_allocated = 0;
510 }
511
512 void zrating_vt::
513 extract(dvb_t *dvb)
514 {
515   rating_nlen = dvb->get_text(rating_name, lengthof(rating_name));
516   rating_tlen = dvb->get_text(rating_text, lengthof(rating_text));
517 }
518
519 void zritem_t::
520 extract(dvb_t *dvb)
521 {
522   clear();
523   dim_nlen = dvb->get_text(dim_name,lengthof(dim_name));
524   int len = dvb->get8bits();
525   graduated_scale = (len>>4) & 1;
526   num_values = len & 0x0f;
527   abrevs = new rating_vt[num_values];
528   for( int i=0; i<num_values; ++i )
529     abrevs[i].extract(dvb);
530 }
531
532 void zritem_t::
533 clear()
534 {
535   delete [] abrevs;  abrevs = 0;
536   num_values = 0;
537 }
538
539 void zrrt_t::
540 extract()
541 {
542   clear();
543   version = dvb->version;
544   region_nlen = dvb->get_text(region_name,lengthof(region_name));
545   items = dvb->get8bits();
546   ratings = new ritem_t[items];
547   for( int i=0; i<items; ++i )
548     ratings[i].extract(dvb);
549   int descr_len = dvb->get16bits() & 0x3ff;
550   dvb->skip_descr(descr_len);
551   prt_rrt(this);
552 }
553
554 void zrrt_t::
555 clear()
556 {
557   delete [] ratings;  ratings = 0;
558   items = 0;
559 }
560
561
562 void zeinfo_t::
563 extract(dvb_t *dvb)
564 {
565   event_id = dvb->get16bits() & 0x3fff;
566   start_time = dvb->get32bits();
567   uint32_t loc = dvb->get24bits();
568   location = (loc>>20) & 0x3;
569   seconds = loc & 0x0fffff;
570   title_tlen = dvb->get8bits();
571   title_text = new uint8_t[title_tlen];
572   for( int i=0; i<title_tlen; ++i )
573     title_text[i] = dvb->get8bits();
574   int descr_len = dvb->get16bits() & 0xfff;
575   dvb->skip_descr(descr_len);
576 }
577
578 void zeinfo_t::
579 clear()
580 {
581   delete [] title_text;  title_text = 0;
582   title_tlen = 0;
583 }
584
585 void zeit_t::
586 extract()
587 {
588   clear();
589   version = dvb->version;
590   source_id = dvb->stream_id;
591   nitems = dvb->get8bits();
592   infos = new einfo_t[nitems];
593   items = 0;
594   for( int i=0; i<nitems; ++i ) {
595     infos[items].extract(dvb);
596     if( !search(infos[items].event_id) ) ++items;
597     else infos[items].clear();
598   }
599   prt_eit(dvb,this);
600 }
601
602 void zeit_t::
603 clear()
604 {
605   for( int i=0; i<items; ++i ) infos[i].clear();
606   delete [] infos;  infos = 0;
607   items = nitems = 0;
608 }
609
610 int zeit_t::
611 search(uint16_t evt_id)
612 {
613   uint16_t src_id = id >> 16;
614   for( eit_t *ep=dvb->eit; ep; ep=ep->next ) {
615     if( (ep->id>>16) != src_id ) continue;
616     for( int i=0; i<ep->items; ++i )
617       if( ep->infos[i].event_id == evt_id ) return 1;
618   }
619   return 0;
620 }
621
622 void zetext_t::
623 extract(dvb_t *dvb, uint32_t eid)
624 {
625   clear();
626   version = dvb->version;
627   table_id = dvb->stream_id;
628   etm_id = eid;
629   int tlen = dvb->bfr_len() - sizeof(uint32_t);
630   msg_text = new uint8_t[tlen];
631   msg_tlen = tlen;
632   for( int i=0; i<msg_tlen; ++i )
633     msg_text[i] = dvb->get8bits();
634   prt_ett(dvb, this);
635 }
636
637 void zetext_t::
638 clear()
639 {
640   delete [] msg_text;  msg_text = 0;
641   msg_tlen = 0;
642 }
643
644 void zett_t::
645 extract()
646 {
647   uint32_t eid = dvb->get32bits();
648   int id = (eid & ~0xffff) | ((eid & 0xffff) >> 2);
649   etext_t *etp = texts;
650   while( etp && etp->id != id ) etp=etp->next;
651   if( !etp ) { etp = new etext_t(id);  etp->next = texts;  texts = etp; }
652   etp->extract(dvb, eid);
653 }
654
655 void zett_t::
656 clear()
657 {
658   while( texts ) { etext_t *nxt = texts->next;  delete texts;  texts = nxt; }
659 }
660
661
662 void zstt_t::
663 extract()
664 {
665   clear();
666   version = dvb->version;
667   table_id = dvb->stream_id;
668   system_time = dvb->get32bits();
669   utc_offset = dvb->get8bits();
670   daylight_saving = dvb->get16bits();
671   //doesnt seem to really be there
672   //int descr_len = len - sizeof(uint32_t);
673   //dvb->skip_descr(descr_len);
674   dvb->skp_bfr(sizeof(uint32_t)); /*crc32*/
675   prt_stt(dvb,this);
676 }
677
678 void zstt_t::
679 clear()
680 {
681 }
682
683
684 zmitem_t *zdvb_t::
685 atsc_pid(int pid)
686 {
687   return pid==0x1ffb ? &base_pid : !mgt ? 0 : mgt->search(pid);
688 }
689
690 int zdvb_t::
691 atsc_tables(zdemuxer_t *demux, int pid)
692 {
693   active = atsc_pid(pid);
694   if( !active ) return 0;
695   int dlen = demux->zdata.size;
696 //zmsgs("*** packet, pid = %04x, len=%04x\n", pid, dlen);
697   uint8_t *dbfr = demux->zdata.buffer;
698   uint8_t *dend = dbfr + dlen;
699   while( dbfr < dend ) {
700     if( demux->payload_unit_start_indicator ) {
701       if( active->tbl_id ) {
702         if( src->log_errs )
703           zmsgs("atsc_tables, unfinished table %04x, len=%d\n",
704             active->tbl_id, active->bfr_len());
705 //      extract();
706       }
707       xbfr = dbfr;  eob = dend;
708       uint32_t tbl_id = get16bits();
709       switch( tbl_id ) {
710       case 0xc7: dprintf("MGT: ");     break;
711       case 0xc8: dprintf("TVCT: ");    break;
712       case 0xc9: dprintf("CVCT: ");    break;
713       case 0xca: dprintf("RRT: ");     break;
714       case 0xcb: dprintf("EIT: ");     break;
715       case 0xcc: dprintf("ETT: ");     break;
716       case 0xcd: dprintf("STT: ");     break;
717       case 0xd3: dprintf("DCCT\n");    return 0;
718       case 0xd4: dprintf("DCCSCT\n");  return 0;
719       case 0xffff:                     return 0;
720       default:   dprintf("tbl_id = 0x%02x\n",tbl_id);
721         return 1;
722       }
723       /* read header */
724       sect_len = get16bits() & 0x0fff;  /* 1,2 */
725       if( (sect_len-=6) < 0 ) {
726         zmsgs("sect_len=%d too small for header\n",sect_len);
727         return 1;
728       }
729       stream_id = get16bits();          /* 3,4 */
730       uint8_t byt = get8bits();         /* 5 */
731       version = (byt >> 1) & 0x1f;
732       cur_next = byt & 0x01;
733       sect_num = get8bits();            /* 6 */
734       proto_ver = get16bits() & 0xff;   /* 7,8 */
735       dprintf("pid/tid=%04x/%02x  len=%04x strm=%04x ver=%d cur=%d sect=%d proto=%d\n",
736         pid, tbl_id, sect_len, stream_id, version, cur_next, sect_num, proto_ver);
737       if( proto_ver != 0 ) return 1;
738       active->init(sect_len);
739       active->tbl_id = tbl_id;
740       active->src_id = stream_id;
741       dbfr = xbfr;
742     }
743     else if( !active->tbl_id )
744       return 1;
745
746     /* append data to buffer */
747     int len = dend - dbfr;
748     int want = active->bfr_len();
749     if( want < len ) len = want;
750     if( len > 0 ) {
751       active->extract(dbfr, len);
752       dbfr += len;
753     }
754     dprintf("append tbl_id=%04x, len=%04x, size=%04x\n",
755       active->tbl_id, len, active->bfr_size);
756
757     /* if table assembled, extract data */
758     if( !active->bfr_len() )
759       extract();
760   }
761
762   return 0;
763 }
764
765 void zdvb_t::extract()
766 {
767   xbfr = active->bfr;
768   eob = xbfr + active->bfr_size;
769
770   switch( active->tbl_id ) {
771   case 0xc7:
772     if( !mgt ) mgt = new mgt_t(this);
773       mgt->extract();
774       break;
775   case 0xc8:
776     if( !tvct ) tvct = new vct_t(this);
777     tvct->extract();
778     break;
779   case 0xc9:
780     if( !cvct ) cvct = new vct_t(this);
781     cvct->extract();
782     break;
783   case 0xca:
784     if( !rrt ) rrt = new rrt_t(this);
785     rrt->extract();
786     break;
787   case 0xcb: { int id;
788     if( (id=active->type-0x100) < 0 || id >= 0x80 ) break;
789     id |= active->src_id << 16;
790     eit_t *eip = eit;
791     while( eip && eip->id != id ) eip = eip->next;
792     if( !eip ) { eip = new eit_t(this, id);  eip->next = eit;  eit = eip; }
793     eip->extract();
794     break; }
795   case 0xcc: { int id;
796     if( active->type == 0x0004 ) id = -1; // channel ett
797     else if( (id=active->type-0x200) < 0 || id >= 0x80 ) break;
798     ett_t *etp = ett;
799     while( etp && etp->id != id ) etp = etp->next;
800     if( !etp ) { etp = new ett_t(this, id);  etp->next = ett;  ett = etp; }
801     etp->extract();
802     break; }
803   case 0xcd:
804     if( !stt ) stt = new stt_t(this);
805     stt->extract();
806     if( !stt_start_time )
807       stt_start_time = stt->system_time;
808     break;
809   }
810
811   active->tbl_id = 0;
812 }
813
814 int zdvb_t::
815 signal_time()
816 {
817   return stt_start_time ? stt->system_time - stt_start_time : 0;
818 }
819
820 int zdvb_t::
821 channel_count()
822 {
823   vct_t *vct = tvct ? tvct : cvct;
824   return vct ? vct->items : -1;
825 }
826
827 int zdvb_t::
828 get_channel(int n, int &major, int &minor)
829 {
830   vct_t *vct = tvct ? tvct : cvct;
831   if( !vct ) return -1;
832   if( n < 0 || n >= vct->items ) return 1;
833   vct_t::vitem_t *item = vct->vct_tbl[n];
834   major = item->major_channel_number;
835   minor = item->minor_channel_number;
836   return 0;
837 }
838
839 int zdvb_t::
840 get_station_id(int n, char *name)
841 {
842   vct_t *vct = tvct ? tvct : cvct;
843   if( !vct ) return -1;
844   if( n < 0 || n >= vct->items ) return 1;
845   vct_t::vitem_t *item = vct->vct_tbl[n];
846   int i = 0;
847   while( i < 7 ) {
848     int ch = item->short_name[i];
849     name[i] = ch >= 0x20 && ch < 0x80 ? ch : '_';
850     ++i;
851   }
852   name[i] = 0;
853   return 0;
854 }
855
856 int zdvb_t::
857 total_astreams(int n, int &count)
858 {
859   vct_t *vct = tvct ? tvct : cvct;
860   if( !vct ) return -1;
861   if( n < 0 || n >= vct->items ) return 1;
862   vct_t::vitem_t *item = vct->vct_tbl[n];
863   count = 0;
864   for( int i=0; i<item->num_ch_elts; ++i ) {
865     int stream_id = item->elts[i].stream_id;
866     if( stream_id == 0x81 ||  /* AC3-audio */
867         stream_id == 0x03 ||  /* MPEG1-audio */
868         stream_id == 0x04 ) { /* MPEG1-audio */
869       ++count;
870     }
871   }
872   return 0;
873 }
874
875 int zdvb_t::
876 astream_number(int n, int ord, int &stream, char *enc)
877 {
878   vct_t *vct = tvct ? tvct : cvct;
879   if( !vct ) return -1;
880   if( n < 0 || n >= vct->items ) return 1;
881   vct_t::vitem_t *item = vct->vct_tbl[n];
882   vct_t::vitem_t::ch_elts_t *elt = 0;
883   int count = 0;
884   for( int i=0; i<item->num_ch_elts; ++i ) {
885     int stream_id = item->elts[i].stream_id;
886     if( stream_id == 0x81 || stream_id == 0x03 || stream_id == 0x04 ) {
887       if( count == ord ) {
888         elt = &item->elts[i];
889         break;
890       }
891       ++count;
892     }
893   }
894   if( !elt ) return 1;
895   int pid = elt->pes_pid;
896   int trk = 0;
897   while( trk < src->total_atracks ) {
898     if( src->atrack[trk]->pid == pid ) break;
899     ++trk;
900   }
901   if( trk >= src->total_atracks ) return 1;
902   stream = trk;
903   if( enc ) {
904     int ch0 = elt->code_639[0];
905     int ch1 = elt->code_639[1];
906     int ch2 = elt->code_639[2];
907     enc[0] = ch0>=0x20 && ch0<0x80 ? ch0 : '.';
908     enc[1] = ch1>=0x20 && ch1<0x80 ? ch1 : '.';
909     enc[2] = ch2>=0x20 && ch2<0x80 ? ch2 : '.';
910     enc[3] = 0;
911   }
912   return 0;
913 }
914
915 int zdvb_t::
916 total_vstreams(int n,int &count)
917 {
918   vct_t *vct = tvct ? tvct : cvct;
919   if( !vct ) return -1;
920   if( n < 0 || n >= vct->items ) return 1;
921   vct_t::vitem_t *item = vct->vct_tbl[n];
922   count = 0;
923   for( int i=0; i<item->num_ch_elts; ++i ) {
924     int stream_id = item->elts[i].stream_id;
925     if( stream_id == 0x02 || stream_id == 0x80 ) { /* video */
926       ++count;
927     }
928   }
929   return 0;
930 }
931
932 int zdvb_t::
933 vstream_number(int n, int ord, int &stream)
934 {
935   vct_t *vct = tvct ? tvct : cvct;
936   if( !vct ) return -1;
937   if( n < 0 || n >= vct->items ) return 1;
938   vct_t::vitem_t *item = vct->vct_tbl[n];
939   int pid = -1;
940   int count = 0;
941   for( int i=0; i<item->num_ch_elts; ++i ) {
942     int stream_id = item->elts[i].stream_id;
943     if( stream_id == 0x02 || stream_id == 0x80 ) {
944       if( count == ord ) {
945         pid = item->elts[i].pes_pid;
946         break;
947       }
948       ++count;
949     }
950   }
951   if( pid < 0 ) return 1;
952   int trk = 0;
953   while( trk < src->total_vtracks ) {
954     if( src->vtrack[trk]->pid == pid ) break;
955     ++trk;
956   }
957   if( trk >= src->total_vtracks ) return 1;
958   stream = trk;
959   return 0;
960 }
961
962 int zdvb_t::
963 read_dvb(zdemuxer_t *demux)
964 {
965   vct_t *vct = tvct ? tvct : cvct;
966   /* scan tables or use empirical data */
967   if( vct && !empirical ) {
968     memset(demux->astream_table,0,sizeof(demux->astream_table));
969     memset(demux->vstream_table,0,sizeof(demux->vstream_table));
970     /* mark active streams */
971     for( int n=0; n<vct->items; ++n ) {
972       vct_t::vitem_t *item = vct->vct_tbl[n];
973       for( int i=0; i<item->num_ch_elts; ++i ) {
974         int stream_id = item->elts[i].stream_id;
975         int pid = item->elts[i].pes_pid;
976 //zmsgs("** dvb stream %02x pid %04x\n",stream_id,pid);
977         switch( stream_id ) {
978         case 0x80: /* video */
979         case 0x02: /* video */
980           demux->vstream_table[pid] = 1;
981           break;
982         case 0x03: /* MPEG1-audio */
983         case 0x04: /* MPEG1-audio */
984           demux->astream_table[pid] = afmt_MPEG;
985           break;
986         case 0x81: /* AC3-audio */
987           demux->astream_table[pid] = afmt_AC3;
988           break;
989         }
990       }
991     }
992   }
993   return 0;
994 }
995
996 int zdvb_t::
997 get_chan_info(int n, int ord, int i, char *txt, int len)
998 {
999   char *cp = txt;
1000   if( len > 0 ) *cp = 0;
1001   vct_t *vct = tvct ? tvct : cvct;
1002   if( !vct ) return -1;
1003   if( n < 0 || n >= vct->items ) return -1;
1004   zvitem_t *item = vct->vct_tbl[n];
1005   zeinfo_t *eip = 0;
1006   int eid = item->source_id << 16;
1007   if( ord >= 0 ) {  // not channel info
1008     int xid = eid | ord;
1009     eit_t *ep = eit;
1010     while( ep && ep->id != xid ) ep = ep->next;
1011     if( !ep || i >= ep->items ) return -1;
1012     eip = &ep->infos[i];
1013     time_t st = eip->start_time + stt_offset();
1014     time_t et = st + eip->seconds;
1015     struct tm stm;  localtime_r(&st, &stm);
1016     struct tm etm;  localtime_r(&et, &etm);
1017     if( len > 0 ) { // output start time
1018       n = snprintf(cp,len,"%02d:%02d:%02d-", stm.tm_hour, stm.tm_min, stm.tm_sec);
1019       cp += n;  len -= n;
1020     }
1021     if( len > 0 ) { // output end time
1022       n = snprintf(cp,len,"%02d:%02d:%02d  ", etm.tm_hour, etm.tm_min, etm.tm_sec);
1023       cp += n;  len -= n;
1024     }
1025     if( len > 0 ) { // output title text
1026       char *text = mstring(eip->title_text,eip->title_tlen);
1027       if( text ) {
1028         char *bp = text;
1029         while( *bp && len>0 ) {  // no new lines, messes up decoding title
1030           *cp++ = *bp != '\n' ? *bp : ';';
1031           --len;  ++bp;
1032         }
1033         if( len > 0 ) { *cp++ = '\n'; --len; }
1034         delete [] text;
1035       }
1036     }
1037     if( len > 0 ) { // output start weekday
1038       n = snprintf(cp,len,"(%3.3s) ",&"sunmontuewedthufrisat"[stm.tm_wday*3]);
1039       cp += n;  len -= n;
1040     }
1041     if( len > 0 ) { // output start date
1042       n = snprintf(cp,len,"%04d/%02d/%02d\n", stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday);
1043       cp += n;  len -= n;
1044     }
1045     eid |= eip->event_id;
1046   }
1047   if( len > 0 && (eip ? eip->location : ord == -1) ) {
1048     ett_t *etp = ett;
1049     while( etp && etp->id != ord ) etp = etp->next;
1050     if( etp ) {    // output extended message text
1051       zetext_t *tp = etp->texts;
1052       while( tp && tp->id != eid ) tp = tp->next;
1053       if( tp ) {
1054         if( ord < 0 ) {  // channel ett exists
1055           n = snprintf(cp,len,"** ");
1056           cp += n;  len -= n;
1057         }
1058         char *text = mstring(tp->msg_text,tp->msg_tlen);
1059         if( text ) {
1060           n = snprintf(cp,len,"%s\n",text);
1061           cp += n;  len -= n;
1062           delete [] text;
1063         }
1064       }
1065     }
1066   }
1067   if( len > 0 ) *cp = 0;
1068   return cp - txt;
1069 }
1070
1071 #endif