diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index bec76547..9320bc6d 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -37,6 +37,7 @@ struct mpegts_table; #define DVB_NIT_PID 0x10 #define DVB_SDT_PID 0x11 #define DVB_BAT_PID 0x11 +#define DVB_VCT_PID 0x1FFB /* Tables */ @@ -58,6 +59,10 @@ struct mpegts_table; #define DVB_BAT_BASE 0x48 #define DVB_BAT_MASK 0xF8 +#define DVB_VCT_T_BASE 0xC8 +#define DVB_VCT_C_BASE 0xC9 +#define DVB_VCT_MASK 0xFF + #define DVB_TELETEXT_BASE 0x2000 /* Descriptors */ @@ -182,6 +187,8 @@ int dvb_sdt_callback (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); int dvb_tdt_callback (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); +int atsc_vct_callback + (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); /* * Delivery systems and DVB API wrappers diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 31495ed7..e1920c2a 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -1008,6 +1008,99 @@ done: return dvb_table_end(mt, st, sect); } +/* + * ATSC VCT processing + */ + /* Done */ +int +atsc_vct_callback + (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) +{ + int i, r, sect, last, ver, extraid, save, dlen; + int maj, min, count; + uint16_t tsid, sid, type; + char chname[256]; + mpegts_mux_t *mm = mt->mt_mux; + mpegts_network_t *mn = mm->mm_network; + mpegts_service_t *s; + mpegts_table_state_t *st = NULL; + + /* Validate */ + if (tableid != 0xc8 && tableid != 0xc9) return -1; + + /* Extra ID */ + tsid = ptr[0] << 8 | ptr[1]; + extraid = tsid; + + /* Begin */ + r = dvb_table_begin(mt, ptr, len, tableid, extraid, 7, + &st, §, &last, &ver); + if (r != 1) return r; + tvhdebug("vct", "tsid %04X (%d)", tsid, tsid); + + /* # channels */ + count = ptr[6]; + tvhdebug("vct", "channel count %d", count); + ptr += 7; + len -= 7; + for (i = 0; i < count && len >= 32; i++) { + dlen = ((ptr[30] & 0x3) << 8) | ptr[31]; + if (dlen + 32 > len) return -1; + + /* Extract fields */ + atsc_utf16_to_utf8(ptr, 7, chname, sizeof(chname)); + maj = (ptr[14] & 0xF) << 6 | ptr[15] >> 2; + min = (ptr[15] & 0x3) << 2 | ptr[16]; + tsid = (ptr[22]) << 8 | ptr[23]; + sid = (ptr[24]) << 8 | ptr[25]; + type = ptr[27] & 0x3f; + tvhdebug("vct", "tsid %04X (%d)", tsid, tsid); + tvhdebug("vct", "sid %04X (%d)", sid, sid); + tvhdebug("vct", "chname %s", chname); + tvhdebug("vct", "chnum %d.%d", maj, min); + tvhdebug("vct", "type %02X (%d)", type, type); + + /* Find mux */ + LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) + if (mm->mm_tsid == tsid) + break; + if (!mm) goto next; + + /* Find the service */ + if (!(s = mpegts_service_find(mm, sid, 0, 1, &save))) + goto next; + + /* Update */ + if (s->s_dvb_servicetype != type) { + s->s_dvb_servicetype = type; + save = 1; + } + if (strcmp(s->s_dvb_svcname ?: "", chname)) { + tvh_str_set(&s->s_dvb_svcname, chname); + save = 1; + } + if (s->s_dvb_channel_num != maj) { + // TODO: ATSC channel numbering is plain weird! + // could shift the major (*100 or something) and append + // minor, but that'll probably confuse people, as will this! + s->s_dvb_channel_num = maj; + save = 1; + } + + /* Save */ + if (save) + s->s_config_save((service_t*)s); + + /* Move on */ +next: + ptr += dlen + 32; + len -= dlen + 32; + } + + return dvb_table_end(mt, st, sect); +} + + /* * DVB BAT processing */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index d9067c03..04304cbb 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -414,15 +414,13 @@ linuxdvb_frontend_default_tables /* ATSC */ if (lfe->lfe_info.type == FE_ATSC) { -#if 0 int tableid; - if (lc->lm_tuning.dmc_fe_params.u.vsb.modulation == VSB_8) - tableid = ATSC_VCT_TERR; + if (lm->lm_tuning.dmc_fe_params.u.vsb.modulation == VSB_8) + tableid = DVB_VCT_T_BASE; else - tableid = ATSC_VCT_CAB; - mpegts_table_add(mm, tableid, 0xff, atsc_vct_callback, - NULL, "vct", MT_QUICKREQ | MT_CRC, ATSC_VCT_PID); -#endif + tableid = DVB_VCT_C_BASE; + mpegts_table_add(mm, tableid, DVB_VCT_MASK, atsc_vct_callback, + NULL, "vct", MT_QUICKREQ | MT_CRC, DVB_VCT_PID); /* DVB */ } else { diff --git a/src/input/mpegts/tsfile/tsfile.c b/src/input/mpegts/tsfile/tsfile.c index 35ea683c..d05fe469 100644 --- a/src/input/mpegts/tsfile/tsfile.c +++ b/src/input/mpegts/tsfile/tsfile.c @@ -40,18 +40,14 @@ static mpegts_service_t * tsfile_network_create_service ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) { - static int t = 0; pthread_mutex_lock(&tsfile_lock); mpegts_service_t *s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); pthread_mutex_unlock(&tsfile_lock); // TODO: HACK: REMOVE ME if (s) { - char buf[128]; - sprintf(buf, "channel-%d", t); - channel_t *c = channel_create(NULL, NULL, buf); + channel_t *c = channel_create(NULL, NULL, NULL); service_mapper_link((service_t*)s, c); - t++; } return s; } diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index b3f225bb..8fb7ec35 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -220,6 +220,10 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) NULL, "sdt", MT_QUICKREQ | MT_CRC, DVB_SDT_PID); mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL, "bat", MT_CRC, DVB_BAT_PID); + mpegts_table_add(mm, DVB_VCT_T_BASE, DVB_VCT_MASK, atsc_vct_callback, + NULL, "vct", MT_CRC, DVB_VCT_PID); + mpegts_table_add(mm, DVB_VCT_C_BASE, DVB_VCT_MASK, atsc_vct_callback, + NULL, "vct", MT_CRC, DVB_VCT_PID); #if 0 mpegts_table_add(mm, 0x1, 0xff, dvb_cat_callback, NULL, "cat", MT_CRC, 1);