9 static const char *desc_name1[] = {
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",
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",
30 /* 14 */ "assoc_tag_descr",
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",
60 /* print descr tag info */
62 static void prt_descr(uint32_t tag, int len)
66 printf("descr tag/len=0x%02x/%u (", tag, len);
67 if( tag < lengthof(desc_name1) )
69 else if( (n=tag-0x80) >= 0 && n<=lengthof(desc_name2) )
71 if( nm == 0 ) nm = "n/a";
75 static void prt_vct(zvct_t *vct)
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 : '.');
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 ) {
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 : '.');
116 static void prt_mgt(zmgt_t *mgt)
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 ) {
122 printf(" typ=0x%04x", item->type);
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);
149 static void prt_stt(zdvb_t *dvb, zstt_t *stt)
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));
155 static void prt_huf(zdvb_t *dvb,uint8_t *bp, int len)
157 char *text = dvb->mstring(bp,len);
158 if( text ) printf("%s",text);
162 static void prt_rrt(zrrt_t *rrt)
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 ) {
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");
181 static void prt_ett(zdvb_t *dvb,zetext_t *etxt)
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");
189 static void prt_eit(zdvb_t *dvb,zeit_t *eit)
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");
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)
214 dvb_t(zmpeg3_t *zsrc)
218 char *cp = getenv("DVB_STREAM_PROBE");
219 empirical = cp ? atoi(cp) : 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;
248 if( n > len ) n = len;
253 get_text(uint8_t *dat, int bytes)
255 int len = get8bits();
256 int count = len < bytes ? len : bytes;
257 for( int i=0; i<count; ++i ) *dat++ = get8bits();
263 append_text(char *msg, int n)
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;
274 memmove(text+text_length,msg,len);
275 text[text_length += len] = 0;
279 mstring(uint8_t *bp, int len)
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 ) {
287 //enc[0] = *bp++; enc[1] = *bp++;
288 //enc[2] = *bp++; enc[3] = 0;
291 for( int j=0; j<segs; ++j ) {
293 int mode = *bp++; (void)mode;
298 case 0x01: { // huffman 1
299 int len = huf::huf1_decode(dat,bytes*8,msg,sizeof(msg));
300 append_text(msg,len);
302 case 0x02: { // huffman 2
303 int len = huf::huf2_decode(dat,bytes*8,msg,sizeof(msg));
304 append_text(msg,len);
306 default: { // no compression
307 append_text((char*)&dat[0],bytes);
316 skip_descr(int descr_length)
318 if( descr_length > 0 && descr_length <= bfr_len() ) {
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;
335 if( len > bfr_alloc ) {
337 bfr = new uint8_t[len];
345 extract(uint8_t *dat, int len)
347 if( bfr_size+len <= bfr_alloc || (len=bfr_alloc-bfr_size) > 0 ) {
348 memcpy(bfr+bfr_size, dat, len);
358 bfr_size = bfr_alloc = 0;
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);
376 int descr_len = dvb->get16bits() & 0xfff;
377 dvb->skip_descr(descr_len);
384 delete [] mitems; mitems = 0;
391 mitem_t *item = mitems;
393 while( --i>=0 && item->pid!=pid ) ++item;
394 return i < 0 ? 0 : item;
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();
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();
430 int descr_length = dvb->get16bits() & 0x3ff;
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;
440 /* "Service Location Descriptor", extract common info */
441 pcr_pid = dvb->get16bits() & 0x1fff;
442 int num_elts = dvb->get8bits();
445 if( n > lengthof(elts) ) {
447 printf("num of pids = %d -- truncated to %d\n", num_elts,n);
449 /* step thru each channel element & extract info into the VCT */
451 for( int j=0; j<n; ++j )
452 elts[j].extract(dvb);
455 dvb->skp_bfr(len-count);
461 search(zvitem_t &new_item)
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;
474 append(zvitem_t &new_vitem)
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;
483 vct_tbl[items++] = new vitem_t(new_vitem);
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) )
499 int descr_len = dvb->get16bits() & 0x3ff;
500 dvb->skip_descr(descr_len);
507 for( int i=0; i<items; ++i ) delete vct_tbl[i];
508 delete [] vct_tbl; vct_tbl = 0;
509 items = items_allocated = 0;
515 rating_nlen = dvb->get_text(rating_name, lengthof(rating_name));
516 rating_tlen = dvb->get_text(rating_text, lengthof(rating_text));
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);
535 delete [] abrevs; abrevs = 0;
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);
557 delete [] ratings; ratings = 0;
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);
581 delete [] title_text; title_text = 0;
589 version = dvb->version;
590 source_id = dvb->stream_id;
591 nitems = dvb->get8bits();
592 infos = new einfo_t[nitems];
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();
605 for( int i=0; i<items; ++i ) infos[i].clear();
606 delete [] infos; infos = 0;
611 search(uint16_t evt_id)
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;
623 extract(dvb_t *dvb, uint32_t eid)
626 version = dvb->version;
627 table_id = dvb->stream_id;
629 int tlen = dvb->bfr_len() - sizeof(uint32_t);
630 msg_text = new uint8_t[tlen];
632 for( int i=0; i<msg_tlen; ++i )
633 msg_text[i] = dvb->get8bits();
640 delete [] msg_text; msg_text = 0;
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);
658 while( texts ) { etext_t *nxt = texts->next; delete texts; texts = nxt; }
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*/
687 return pid==0x1ffb ? &base_pid : !mgt ? 0 : mgt->search(pid);
691 atsc_tables(zdemuxer_t *demux, int pid)
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 ) {
703 zmsgs("atsc_tables, unfinished table %04x, len=%d\n",
704 active->tbl_id, active->bfr_len());
707 xbfr = dbfr; eob = dend;
708 uint32_t tbl_id = get16bits();
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);
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);
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;
743 else if( !active->tbl_id )
746 /* append data to buffer */
747 int len = dend - dbfr;
748 int want = active->bfr_len();
749 if( want < len ) len = want;
751 active->extract(dbfr, len);
754 dprintf("append tbl_id=%04x, len=%04x, size=%04x\n",
755 active->tbl_id, len, active->bfr_size);
757 /* if table assembled, extract data */
758 if( !active->bfr_len() )
765 void zdvb_t::extract()
768 eob = xbfr + active->bfr_size;
770 switch( active->tbl_id ) {
772 if( !mgt ) mgt = new mgt_t(this);
776 if( !tvct ) tvct = new vct_t(this);
780 if( !cvct ) cvct = new vct_t(this);
784 if( !rrt ) rrt = new rrt_t(this);
788 if( (id=active->type-0x100) < 0 || id >= 0x80 ) break;
789 id |= active->src_id << 16;
791 while( eip && eip->id != id ) eip = eip->next;
792 if( !eip ) { eip = new eit_t(this, id); eip->next = eit; eit = eip; }
796 if( active->type == 0x0004 ) id = -1; // channel ett
797 else if( (id=active->type-0x200) < 0 || id >= 0x80 ) break;
799 while( etp && etp->id != id ) etp = etp->next;
800 if( !etp ) { etp = new ett_t(this, id); etp->next = ett; ett = etp; }
804 if( !stt ) stt = new stt_t(this);
806 if( !stt_start_time )
807 stt_start_time = stt->system_time;
817 return stt_start_time ? stt->system_time - stt_start_time : 0;
823 vct_t *vct = tvct ? tvct : cvct;
824 return vct ? vct->items : -1;
828 get_channel(int n, int &major, int &minor)
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;
840 get_station_id(int n, char *name)
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];
848 int ch = item->short_name[i];
849 name[i] = ch >= 0x20 && ch < 0x80 ? ch : '_';
857 total_astreams(int n, int &count)
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];
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 */
876 astream_number(int n, int ord, int &stream, char *enc)
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;
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 ) {
888 elt = &item->elts[i];
895 int pid = elt->pes_pid;
897 while( trk < src->total_atracks ) {
898 if( src->atrack[trk]->pid == pid ) break;
901 if( trk >= src->total_atracks ) return 1;
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 : '.';
916 total_vstreams(int n,int &count)
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];
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 */
933 vstream_number(int n, int ord, int &stream)
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];
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 ) {
945 pid = item->elts[i].pes_pid;
951 if( pid < 0 ) return 1;
953 while( trk < src->total_vtracks ) {
954 if( src->vtrack[trk]->pid == pid ) break;
957 if( trk >= src->total_vtracks ) return 1;
963 read_dvb(zdemuxer_t *demux)
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;
982 case 0x03: /* MPEG1-audio */
983 case 0x04: /* MPEG1-audio */
984 demux->astream_table[pid] = afmt_MPEG;
986 case 0x81: /* AC3-audio */
987 demux->astream_table[pid] = afmt_AC3;
997 get_chan_info(int n, int ord, int i, char *txt, int len)
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];
1006 int eid = item->source_id << 16;
1007 if( ord >= 0 ) { // not channel info
1008 int xid = eid | ord;
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);
1021 if( len > 0 ) { // output end time
1022 n = snprintf(cp,len,"%02d:%02d:%02d ", etm.tm_hour, etm.tm_min, etm.tm_sec);
1025 if( len > 0 ) { // output title text
1026 char *text = mstring(eip->title_text,eip->title_tlen);
1029 while( *bp && len>0 ) { // no new lines, messes up decoding title
1030 *cp++ = *bp != '\n' ? *bp : ';';
1033 if( len > 0 ) { *cp++ = '\n'; --len; }
1037 if( len > 0 ) { // output start weekday
1038 n = snprintf(cp,len,"(%3.3s) ",&"sunmontuewedthufrisat"[stm.tm_wday*3]);
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);
1045 eid |= eip->event_id;
1047 if( len > 0 && (eip ? eip->location : ord == -1) ) {
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;
1054 if( ord < 0 ) { // channel ett exists
1055 n = snprintf(cp,len,"** ");
1058 char *text = mstring(tp->msg_text,tp->msg_tlen);
1060 n = snprintf(cp,len,"%s\n",text);
1067 if( len > 0 ) *cp = 0;