diff --git a/src/channels.c b/src/channels.c index a302e9d8..460e0880 100644 --- a/src/channels.c +++ b/src/channels.c @@ -162,7 +162,7 @@ channel_set_name(channel_t *ch, const char *name) * */ static channel_t * -channel_create(const char *name) +channel_create(const char *name, int number) { channel_t *ch, *x; xmltv_channel_t *xc; @@ -179,6 +179,7 @@ channel_create(const char *name) RB_INIT(&ch->ch_epg_events); LIST_INSERT_HEAD(&channels_not_xmltv_mapped, ch, ch_xc_link); channel_set_name(ch, name); + ch->ch_number = number; ch->ch_id = id; x = RB_INSERT_SORTED(&channel_identifier_tree, ch, @@ -200,7 +201,7 @@ channel_create(const char *name) * */ channel_t * -channel_find_by_name(const char *name, int create) +channel_find_by_name(const char *name, int create, int channel_number) { channel_t skel, *ch; @@ -210,7 +211,7 @@ channel_find_by_name(const char *name, int create) ch = RB_FIND(&channel_name_tree, &skel, ch_name_link, channelcmp); if(ch != NULL || create == 0) return ch; - return channel_create(name); + return channel_create(name, channel_number); } @@ -352,7 +353,7 @@ channel_rename(channel_t *ch, const char *newname) lock_assert(&global_lock); - if(channel_find_by_name(newname, 0)) + if(channel_find_by_name(newname, 0, 0)) return -1; tvhlog(LOG_NOTICE, "channels", "Channel \"%s\" renamed to \"%s\"", diff --git a/src/channels.h b/src/channels.h index fc666b27..bcb9517a 100644 --- a/src/channels.h +++ b/src/channels.h @@ -101,7 +101,7 @@ typedef struct channel_tag_mapping { void channels_init(void); -channel_t *channel_find_by_name(const char *name, int create); +channel_t *channel_find_by_name(const char *name, int create, int number); channel_t *channel_find_by_identifier(int id); diff --git a/src/dvb/dvb_support.h b/src/dvb/dvb_support.h index cb32d4f2..055cfdd0 100644 --- a/src/dvb/dvb_support.h +++ b/src/dvb/dvb_support.h @@ -47,6 +47,7 @@ #define DVB_DESC_SUBTITLE 0x59 #define DVB_DESC_AC3 0x6a #define DVB_DESC_AAC 0x7c +#define DVB_DESC_LOCAL_CHAN 0x83 int dvb_get_string(char *dst, size_t dstlen, const uint8_t *src, const size_t srclen); diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index 105190ff..efbb07d2 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -1039,6 +1039,46 @@ dvb_table_sat_delivery(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, } +/** + * + */ +static void +dvb_table_local_channel(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, + uint16_t tsid) +{ + uint16_t sid, chan; + th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + th_transport_t *t; + + LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) + if(tdmi->tdmi_transport_stream_id == tsid) + break; + + if(tdmi == NULL) + return; + + while(len > 4) { + sid = (ptr[0] << 8) | ptr[1]; + chan = ((ptr[2] & 3) << 8) | ptr[3]; + + if(chan != 0) { + t = dvb_transport_find(tdmi, sid, 0, NULL); + if(t != NULL) { + + if(t->tht_channel_number != chan) { + t->tht_channel_number = chan; + t->tht_config_save(t); + transport_refresh_channel(t); + printf("%s channel %d\n", transport_nicename(t), chan); + } + } + } + ptr += 4; + len -= 4; + } +} + + /** * NIT - Network Information Table @@ -1132,6 +1172,9 @@ dvb_nit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, case DVB_DESC_CABLE: dvb_table_cable_delivery(tdmi, ptr, tlen, tsid); break; + case DVB_DESC_LOCAL_CHAN: + dvb_table_local_channel(tdmi, ptr, tlen, tsid); + break; } ptr += tlen; diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index e4dbff97..48650d81 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -221,6 +221,10 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi) u32 = 0; t->tht_scrambled = u32; + if(htsmsg_get_u32(c, "channel", &u32)) + u32 = 0; + t->tht_channel_number = u32; + s = htsmsg_get_str(c, "provider"); t->tht_provider = s ? strdup(s) : NULL; @@ -237,7 +241,7 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi) u32 = 0; if(s && u32) - transport_map_channel(t, channel_find_by_name(s, 1), 0); + transport_map_channel(t, channel_find_by_name(s, 1, 0), 0); } htsmsg_destroy(l); } @@ -256,6 +260,7 @@ dvb_transport_save(th_transport_t *t) htsmsg_add_u32(m, "pmt", t->tht_pmt_pid); htsmsg_add_u32(m, "stype", t->tht_servicetype); htsmsg_add_u32(m, "scrambled", t->tht_scrambled); + htsmsg_add_u32(m, "channel", t->tht_channel_number); if(t->tht_provider != NULL) htsmsg_add_str(m, "provider", t->tht_provider); @@ -408,6 +413,7 @@ dvb_transport_build_msg(th_transport_t *t) htsmsg_add_str(m, "id", t->tht_identifier); htsmsg_add_u32(m, "enabled", t->tht_enabled); + htsmsg_add_u32(m, "channel", t->tht_channel_number); htsmsg_add_u32(m, "sid", t->tht_dvb_service_id); htsmsg_add_u32(m, "pmt", t->tht_pmt_pid); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index c080a9a9..73929cf1 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -318,7 +318,7 @@ autorec_record_update(void *opaque, const char *id, htsmsg_t *values, LIST_REMOVE(dae, dae_channel_link); dae->dae_channel = NULL; } - if((ch = channel_find_by_name(s, 0)) != NULL) { + if((ch = channel_find_by_name(s, 0, 0)) != NULL) { LIST_INSERT_HEAD(&ch->ch_autorecs, dae, dae_channel_link); dae->dae_channel = ch; } @@ -436,7 +436,7 @@ dvr_autorec_add(const char *title, const char *channel, tvh_str_set(&dae->dae_creator, creator); tvh_str_set(&dae->dae_comment, comment); - if(channel != NULL && (ch = channel_find_by_name(channel, 0)) != NULL) { + if(channel != NULL && (ch = channel_find_by_name(channel, 0, 0)) != NULL) { LIST_INSERT_HEAD(&ch->ch_autorecs, dae, dae_channel_link); dae->dae_channel = ch; } diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 2ac67877..44892b5a 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -399,7 +399,7 @@ dvr_db_load_one(htsmsg_t *c, int id) if((s = htsmsg_get_str(c, "channel")) == NULL) return; - if((ch = channel_find_by_name(s, 0)) == NULL) + if((ch = channel_find_by_name(s, 0, 0)) == NULL) return; if((title = htsmsg_get_str(c, "title")) == NULL) diff --git a/src/epg.c b/src/epg.c index f51691ed..38f135ec 100644 --- a/src/epg.c +++ b/src/epg.c @@ -672,7 +672,7 @@ void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag, const char *contentgroup, const char *title) { - channel_t *ch = channel ? channel_find_by_name(channel, 0) : NULL; + channel_t *ch = channel ? channel_find_by_name(channel, 0, 0) : NULL; channel_tag_t *ct = tag ? channel_tag_find_by_name(tag, 0) : NULL; epg_content_group_t *ecg = contentgroup ? epg_content_group_find_by_name(contentgroup) : NULL; diff --git a/src/iptv_input.c b/src/iptv_input.c index 3664bdba..f9c27773 100644 --- a/src/iptv_input.c +++ b/src/iptv_input.c @@ -470,7 +470,7 @@ iptv_transport_load(void) u32 = 0; if(s && u32) - transport_map_channel(t, channel_find_by_name(s, 1), 0); + transport_map_channel(t, channel_find_by_name(s, 1, 0), 0); } htsmsg_destroy(l); } diff --git a/src/rawtsinput.c b/src/rawtsinput.c index 8ee5c67e..202d0662 100644 --- a/src/rawtsinput.c +++ b/src/rawtsinput.c @@ -134,7 +134,7 @@ rawts_transport_add(rawts_t *rt, uint16_t sid, int pmt_pid) LIST_INSERT_HEAD(&rt->rt_transports, t, tht_group_link); - ch = channel_find_by_name(tmp, 1); + ch = channel_find_by_name(tmp, 1, 0); transport_map_channel(t, ch, 0); return t; diff --git a/src/rtsp.c b/src/rtsp.c index 5806a1ea..4f9be83c 100644 --- a/src/rtsp.c +++ b/src/rtsp.c @@ -531,7 +531,7 @@ rtsp_subscribe(http_connection_t *hc, rtsp_t *rtsp, channel_t *ch; scopedgloballock(); - if((ch = channel_find_by_name(components[1], 0)) == NULL) { + if((ch = channel_find_by_name(components[1], 0, 0)) == NULL) { rtsp_error(hc, RTSP_STATUS_SERVICE, "Channel name not found"); return -1; } diff --git a/src/serviceprobe.c b/src/serviceprobe.c index a431218e..777a3c86 100644 --- a/src/serviceprobe.c +++ b/src/serviceprobe.c @@ -165,7 +165,7 @@ serviceprobe_thread(void *aux) } else if(t->tht_ch == NULL) { const char *str; - ch = channel_find_by_name(t->tht_svcname, 1); + ch = channel_find_by_name(t->tht_svcname, 1, t->tht_channel_number); transport_map_channel(t, ch, 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: mapped to channel \"%s\"", diff --git a/src/tvhead.h b/src/tvhead.h index fb4b25a4..e3086f4f 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -595,6 +595,8 @@ typedef struct th_transport { */ uint16_t tht_dvb_service_id; + uint16_t tht_channel_number; + /** * Service name (eg. DVB service name as specified by EN 300 468) */ diff --git a/src/v4l.c b/src/v4l.c index 9f273a31..6d1d3308 100644 --- a/src/v4l.c +++ b/src/v4l.c @@ -712,7 +712,7 @@ v4l_service_create_by_msg(v4l_adapter_t *va, htsmsg_t *c, const char *name) t->tht_v4l_frequency = u32; if(s && u32) - transport_map_channel(t, channel_find_by_name(s, 1), 0); + transport_map_channel(t, channel_find_by_name(s, 1, 0), 0); } /** diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 1ed48ca7..94a1c117 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -1026,7 +1026,7 @@ transport_update(htsmsg_t *in) transport_set_enable(t, u32); if((chname = htsmsg_get_str(c, "channelname")) != NULL) - transport_map_channel(t, channel_find_by_name(chname, 1), 1); + transport_map_channel(t, channel_find_by_name(chname, 1, 0), 1); } } @@ -1335,7 +1335,7 @@ extjs_transport_update(htsmsg_t *in) transport_set_enable(t, u32); if((chname = htsmsg_get_str(c, "channelname")) != NULL) - transport_map_channel(t, channel_find_by_name(chname, 1), 1); + transport_map_channel(t, channel_find_by_name(chname, 1, 0), 1); } }