diff --git a/config.c b/config.c index 80e3d99..e12b51a 100644 --- a/config.c +++ b/config.c @@ -118,6 +118,8 @@ int config_load_channels(CONFIG *conf) { continue; int is_radio = ini_get_bool(ini, 0, "Channel%d:radio", i); + int lcn = ini_get_int(ini, 0, "Channel%d:lcn", i); + int is_lcn_visible = ini_get_bool(ini, 0, "Channel%d:lcn_visible", i); char *id = ini_get_string(ini, NULL, "Channel%d:id", i); if (!id) { @@ -145,7 +147,7 @@ int config_load_channels(CONFIG *conf) { } // Init channel if (channel == NULL) { - channel = channel_new(service_id, is_radio, id, name, eit_mode, source, i); + channel = channel_new(service_id, is_radio, id, name, eit_mode, source, i, lcn, is_lcn_visible); } else { chansrc_add(channel, source); } @@ -225,7 +227,7 @@ int config_load_channels(CONFIG *conf) { if (r->cookie != cookie) { proxy_log(r, "Remove"); /* Replace channel reference with real object and instruct free_restreamer to free it */ - r->channel = channel_new(r->channel->service_id, r->channel->radio, r->channel->id, r->channel->name, r->channel->eit_mode, r->channel->source, r->channel->index); + r->channel = channel_new(r->channel->service_id, r->channel->radio, r->channel->id, r->channel->name, r->channel->eit_mode, r->channel->source, r->channel->index, r->channel->lcn, r->channel->lcn_visible); r->freechannel = 1; r->dienow = 1; } @@ -450,6 +452,7 @@ static void show_usage(void) { puts("\t-W\t\tWrite output file (recommended to use with -N)"); puts("\t-f\t\tThe output filename (default: mptsd-output.ts) (use - for stdout)"); puts("\t-E\t\tWrite input file"); + puts("\t-9\t\tEnable LCN support (default: disabled)"); puts(""); } @@ -466,7 +469,7 @@ void config_load(CONFIG *conf, int argc, char **argv) { conf->server_socket = -1; conf->write_output_network = 1; - while ((j = getopt(argc, argv, "i:b:p:g:c:n:e:d:t:o:O:P:l:L:B:m:s:f:qDHhEWN")) != -1) { + while ((j = getopt(argc, argv, "i:b:p:g:c:n:e:d:t:o:O:P:l:L:B:m:s:f:qDHhEWN9")) != -1) { switch (j) { case 'i': conf->ident = strdup(optarg); @@ -556,6 +559,9 @@ void config_load(CONFIG *conf, int argc, char **argv) { case 'f': conf->output_filename = strdup(optarg); break; + case '9': + conf->use_lcn = 1; + break; case 'D': conf->debug = 1; break; @@ -638,6 +644,7 @@ void config_load(CONFIG *conf, int argc, char **argv) { conf->pcr_mode == 2 ? "Rewrite PCRs using output bitrate" : conf->pcr_mode == 3 ? "Move PCRs and rewrite them" : "???" ); + LOGf("\tLCN : %s\n", (conf->use_lcn)? "enabled" : "disabled"); if (conf->write_output_file) LOGf("\tWrite output file : %s\n", conf->output_filename); if (conf->write_input_file) diff --git a/config.h b/config.h index ea4a55a..aac0b1a 100644 --- a/config.h +++ b/config.h @@ -61,6 +61,7 @@ typedef struct { // 1 - move PCRs to their calculated place // 2 - rewrite PCRs using output bitrate // 3 - move PCRs and rewrite them + int use_lcn; uint16_t network_id; // For NIT && SDT uint16_t transport_stream_id;// For NIT diff --git a/data.c b/data.c index 9099f0f..02e3ccc 100644 --- a/data.c +++ b/data.c @@ -121,7 +121,7 @@ void chansrc_set(CHANNEL *c, uint8_t src_id) { -CHANNEL *channel_new(int service_id, int is_radio, const char *id, const char *name, int eit_mode, const char *source, int channel_index){ +CHANNEL *channel_new(int service_id, int is_radio, const char *id, const char *name, int eit_mode, const char *source, int channel_index, int lcn, int is_lcn_visible){ if (channel_index<=0 || channel_index>=256) { @@ -135,6 +135,8 @@ CHANNEL *channel_new(int service_id, int is_radio, const char *id, const char *n c->service_id = service_id; c->radio = is_radio; c->index = channel_index; + c->lcn = lcn; + c->lcn_visible = is_lcn_visible; c->base_pid = c->index * 32; // The first pid is saved for PMT , channel_index must > 0 c->pmt_pid = c->base_pid; // The first pid is saved for PMT c->id = strdup(id); diff --git a/data.h b/data.h index 7029168..6ca8335 100644 --- a/data.h +++ b/data.h @@ -64,6 +64,8 @@ typedef struct { int service_id; int pmt_pid; int radio; + int lcn; + int lcn_visible; char * id; char * name; int eit_mode; /* 0 = ignore EIT data from input @@ -229,7 +231,7 @@ EPG_ENTRY * epg_new (time_t start, int duration, char *encoding, char *event, void epg_free (EPG_ENTRY **e); int epg_changed (EPG_ENTRY *a, EPG_ENTRY *b); -CHANNEL * channel_new (int service_id, int is_radio, const char *id, const char *name, int eit_mode, const char *source, int channel_index); +CHANNEL * channel_new (int service_id, int is_radio, const char *id, const char *name, int eit_mode, const char *source, int channel_index, int lcn, int is_lcn_visible); void channel_free (CHANNEL **c); void channel_free_epg(CHANNEL *c); diff --git a/mptsd_channels.conf b/mptsd_channels.conf index d05fb81..6ec58ff 100644 --- a/mptsd_channels.conf +++ b/mptsd_channels.conf @@ -6,50 +6,64 @@ transport_stream_id = 1 service_id = 1 id = btv name = bTV -eit_mode = 0 # 0 = ignore EIT data from input +eit_mode = 0 # 0 = ignore EIT data from input # 1 = forward EIT data for the configured service, ignore any other EIT data source1 = http://signal-server/stb/btv.mpg #source2 = http://signal-server2/stb/btv.mpg #source3 = http://signal-server3/stb/btv.mpg #source4 = udp://239.0.0.1:5000/ -#source5 = rtp://239.78.78.2:5000/ +#source5 = rtp://239.78.78.2:5000/ #worktime = 14:18-14:19 +lcn = 2 +lcn_visible = yes [Channel2] service_id = 2 id = kanal1 name = "Kanal 1" source = http://signal-server/stb/kanal1.mpg +lcn = 2 +lcn_visible = yes [Channel3] service_id = 3 id = novatv name = "Nova" source1 = http://signal-server/stb/novatv.mpg +lcn = 3 +lcn_visible = yes [Channel4] service_id = 4 id = tv2 name = "TV 2" source1 = http://signal-server/stb/tv2.mpg +lcn = 7 +lcn_visible = yes [Channel5] service_id = 5 id = ngc name = "NatGeo" source1 = http://signal-server/stb/ngc.mpg +lcn = 72 +lcn_visible = yes [Channel6] service_id = 6 id = tv1 name = "TV 1" source1 = http://signal-server/stb/tv1.mpg +lcn = 25 +lcn_visible = yes [Channel7] service_id = 7 id = planetahit name = "Planeta HIT" source1 = http://signal-server/stb/planetahit.mpg +lcn = 33 +lcn_visible = no [Channel8] service_id = 8 @@ -57,6 +71,8 @@ id = fresh name = "Radio Fresh" radio = yes source = http://signal-server/stb/fresh.mpg +lcn = 201 +lcn_visible = yes [Channel9] service_id = 9 @@ -64,3 +80,5 @@ id = bgradio name = "BG Radio" radio = yes source1 = http://signal-server/stb/bgradio.mpg +lcn = 202 +lcn_visible = yes diff --git a/output_psi.c b/output_psi.c index 2a28cc0..b2c3e10 100644 --- a/output_psi.c +++ b/output_psi.c @@ -44,40 +44,119 @@ static void output_psi_init_nit(CONFIG *conf, OUTPUT *o) { ts_nit_add_network_name_descriptor(nit, conf->network_name); - if (conf->nit->items < 64) { + if (!conf->use_lcn) { + + if (conf->nit->items < 64) { + int num; + LNODE *lc, *lctmp; + uint32_t *freqs = malloc(conf->nit->items * sizeof(uint32_t)); + uint32_t *services = malloc(conf->channels->items * sizeof(uint32_t)); + + num = 0; + list_lock(conf->nit); + list_for_each(conf->nit, lc, lctmp) { + NIT *ndata = lc->data; + freqs[num++] = ndata->_freq; + } + + ts_nit_add_frequency_list_descriptor_cable(nit, conf->transport_stream_id, conf->network_id, freqs, num); + + list_for_each(conf->nit, lc, lctmp) { + NIT *ndata = lc->data; + ts_nit_add_cable_delivery_descriptor(nit, ndata->ts_id, conf->network_id, ndata->_freq, ndata->_modulation, ndata->_symbol_rate); + } + list_unlock(conf->nit); + + num = 0; + list_lock(conf->channels); + list_for_each(conf->channels, lc, lctmp) { + CHANNEL *c = lc->data; + uint32_t srv = 0; + srv = (c->service_id &~ 0x00ff) << 8; + srv |= (c->service_id &~ 0xff00) << 8; + srv |= c->radio ? 0x02 : 0x01; + services[num++] = srv; + } + list_unlock(conf->channels); + + ts_nit_add_service_list_descriptor(nit, conf->transport_stream_id, conf->network_id, services, num); + free(freqs); + free(services); + } else { + LOG("CONF : Too much items in the NIT, maximum is 64! NIT not generated.\n"); + } + + } else { + int num; + char *ts_freq = NULL; + char *ts_modulation = NULL; + char *ts_symbol_rate = NULL; + uint32_t ts__freq = 0; + uint8_t ts__modulation = 0; + uint32_t ts__symbol_rate = 0; LNODE *lc, *lctmp; - uint32_t *freqs = malloc(conf->nit->items * sizeof(uint32_t)); - uint32_t *services = malloc(conf->channels->items * sizeof(uint32_t)); - num = 0; + uint32_t *svc_services = malloc(conf->channels->items * sizeof(uint32_t)); + uint32_t *lcn_services = malloc(conf->channels->items * sizeof(uint32_t)); + list_lock(conf->nit); list_for_each(conf->nit, lc, lctmp) { NIT *ndata = lc->data; - freqs[num++] = ndata->_freq; - } - ts_nit_add_frequency_list_descriptor_cable(nit, conf->transport_stream_id, conf->network_id, freqs, num); - list_for_each(conf->nit, lc, lctmp) { - NIT *ndata = lc->data; - ts_nit_add_cable_delivery_descriptor(nit, ndata->ts_id, conf->network_id, ndata->_freq, ndata->_modulation, ndata->_symbol_rate); + if (ndata->ts_id == conf->transport_stream_id) { + ts_freq = ndata->freq; + ts_modulation = ndata->modulation; + ts_symbol_rate = ndata->symbol_rate; + ts__freq = ndata->_freq; + ts__modulation = ndata->_modulation; + ts__symbol_rate = ndata->_symbol_rate; + } } list_unlock(conf->nit); - num = 0; + list_lock(conf->channels); + num = 0; + list_for_each(conf->channels, lc, lctmp) { + CHANNEL *c = lc->data; + uint32_t srv = 0; + srv = (c->service_id &~ 0x00ff) << 16; + srv |= (c->service_id &~ 0xff00) << 16; + srv |= (c->lcn_visible ? 0x01 : 0x00 &~ 0xf0 ) << 15; + srv |= (0X00 &~ 0xf0 ) << 14; + srv |= (c->lcn &~ 0xc0ff); + srv |= (c->lcn &~ 0xff00); + lcn_services[num++] = srv; + } + + num = 0; list_for_each(conf->channels, lc, lctmp) { - CHANNEL *c = lc->data; - uint32_t srv = 0; - srv = (c->service_id &~ 0x00ff) << 8; - srv |= (c->service_id &~ 0xff00) << 8; - srv |= c->radio ? 0x02 : 0x01; - services[num++] = srv; + CHANNEL *c = lc->data; + uint32_t srv = 0; + srv = (c->service_id &~ 0x00ff) << 8; + srv |= (c->service_id &~ 0xff00) << 8; + srv |= c->radio ? 0x02 : 0x01; + svc_services[num++] = srv; } list_unlock(conf->channels); - ts_nit_add_service_list_descriptor(nit, conf->transport_stream_id, conf->network_id, services, num); - free(freqs); - free(services); - } else { - LOG("CONF : Too much items in the NIT, maximum is 64! NIT not generated.\n"); + + NIT *ts_ndata = nit_new(conf->transport_stream_id, ts_freq, ts_modulation, ts_symbol_rate); + ts_nit_add_stream_descriptors(nit, ts_ndata->ts_id, conf->network_id, ts__freq, ts__modulation, ts__symbol_rate, lcn_services, svc_services, num); + + if (conf->nit->items < 64) { + list_lock(conf->nit); + list_for_each(conf->nit, lc, lctmp) { + NIT *ndata = lc->data; + ts_nit_add_cable_delivery_descriptor(nit, ndata->ts_id, conf->network_id, ndata->_freq, ndata->_modulation, ndata->_symbol_rate); + } + list_unlock(conf->nit); + + free(lcn_services); + free(svc_services); + } else { + LOG("CONF : Too much items in the NIT, maximum is 64! NIT not generated.\n"); + } + } + gettimeofday(&o->nit_ts, NULL); o->nit = nit; }