From 3dfc1eba787f336e5754c7f6e5fdfcf0fe202178 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 18 Mar 2015 11:45:04 +0100 Subject: [PATCH] SAT>IP Server/Client: Add more tuner types (atsc, dvbcb, dvbs, dvbc2) --- src/input/mpegts/satip/satip.c | 22 +++++++-- src/input/mpegts/satip/satip_frontend.c | 28 +++++++++-- src/input/mpegts/satip/satip_private.h | 5 +- src/input/mpegts/satip/satip_rtsp.c | 14 +++++- src/satip/rtsp.c | 50 ++++++++++++++++--- src/satip/server.c | 66 ++++++++++++++++--------- src/webui/extjs.c | 22 ++++++--- src/webui/static/app/config.js | 41 +++++++++++---- 8 files changed, 194 insertions(+), 54 deletions(-) diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index a0a2a950..77770508 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -390,7 +390,7 @@ satip_device_create( satip_device_info_t *info ) tvh_uuid_t uuid; htsmsg_t *conf = NULL, *feconf = NULL; char *argv[10]; - int i, j, n, m, fenum, t2, save = 0; + int i, j, n, m, fenum, v2, save = 0; dvb_fe_type_t type; char buf2[60]; @@ -454,20 +454,34 @@ satip_device_create( satip_device_info_t *info ) n = http_tokenize(sd->sd_info.tunercfg, argv, 10, ','); for (i = 0, fenum = 1; i < n; i++) { type = DVB_TYPE_NONE; - t2 = 0; + v2 = 0; if (strncmp(argv[i], "DVBS2-", 6) == 0) { type = DVB_TYPE_S; m = atoi(argv[i] + 6); + v2 = 1; + } else if (strncmp(argv[i], "DVBS-", 5) == 0) { + type = DVB_TYPE_S; + m = atoi(argv[i] + 5); } else if (strncmp(argv[i], "DVBT2-", 6) == 0) { type = DVB_TYPE_T; m = atoi(argv[i] + 6); - t2 = 1; + v2 = 1; } else if (strncmp(argv[i], "DVBT-", 5) == 0) { type = DVB_TYPE_T; m = atoi(argv[i] + 5); + } else if (strncmp(argv[i], "DVBC2-", 6) == 0) { + type = DVB_TYPE_C; + m = atoi(argv[i] + 6); + v2 = 1; } else if (strncmp(argv[i], "DVBC-", 5) == 0) { type = DVB_TYPE_C; m = atoi(argv[i] + 5); + } else if (strncmp(argv[i], "ATSC-", 5) == 0) { + type = DVB_TYPE_ATSC; + m = atoi(argv[i] + 5); + } else if (strncmp(argv[i], "DVBCB-", 6) == 0) { + m = atoi(argv[i] + 6); + v2 = 2; } if (type == DVB_TYPE_NONE) { tvhlog(LOG_ERR, "satip", "%s: bad tuner type [%s]", @@ -477,7 +491,7 @@ satip_device_create( satip_device_info_t *info ) satip_device_nicename(sd, buf2, sizeof(buf2)), argv[i]); } else { for (j = 0; j < m; j++) - if (satip_frontend_create(feconf, sd, type, t2, fenum)) + if (satip_frontend_create(feconf, sd, type, v2, fenum)) fenum++; } } diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 35f05622..0ca09870 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -65,7 +65,14 @@ satip_frontend_signal_cb( void *aux ) return; if (!lfe->sf_tables) { psi_tables_default(mmi->mmi_mux); - psi_tables_dvb(mmi->mmi_mux); + if (lfe->sf_type == DVB_TYPE_ATSC) { + if (lfe->sf_atsc_c) + psi_tables_atsc_c(mmi->mmi_mux); + else + psi_tables_atsc_t(mmi->mmi_mux); + } else { + psi_tables_dvb(mmi->mmi_mux); + } lfe->sf_tables = 1; } sigstat.status_text = signal2str(lfe->sf_status); @@ -335,6 +342,16 @@ const idclass_t satip_frontend_dvbc_class = } }; +const idclass_t satip_frontend_atsc_class = +{ + .ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_atsc", + .ic_caption = "SAT>IP ATSC Frontend", + .ic_properties = (const property_t[]){ + {} + } +}; + /* ************************************************************************** * Class methods * *************************************************************************/ @@ -500,6 +517,7 @@ satip_frontend_start_mux lfe->sf_req = tr; lfe->sf_running = 1; lfe->sf_tables = 0; + lfe->sf_atsc_c = lm->lm_tuning.dmc_fe_modulation != DVB_MOD_VSB_8; lfe->sf_status = SIGNAL_NONE; pthread_mutex_unlock(&lfe->sf_dvr_lock); @@ -618,6 +636,8 @@ satip_frontend_network_list ( mpegts_input_t *mi ) idc = &dvb_network_dvbs_class; else if (lfe->sf_type == DVB_TYPE_C) idc = &dvb_network_dvbc_class; + else if (lfe->sf_type == DVB_TYPE_ATSC) + idc = &dvb_network_atsc_class; else return NULL; @@ -1562,7 +1582,7 @@ satip_frontend_hacks( satip_frontend_t *lfe, int *def_positions ) satip_frontend_t * satip_frontend_create - ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int t2, int num ) + ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int v2, int num ) { const idclass_t *idc; const char *uuid = NULL, *override = NULL; @@ -1606,6 +1626,8 @@ satip_frontend_create idc = &satip_frontend_dvbt_class; else if (type == DVB_TYPE_C) idc = &satip_frontend_dvbc_class; + else if (type == DVB_TYPE_ATSC) + idc = &satip_frontend_atsc_class; else { tvherror("satip", "unknown FE type %d", type); return NULL; @@ -1618,7 +1640,7 @@ satip_frontend_create lfe->sf_device = sd; lfe->sf_number = num; lfe->sf_type = type; - lfe->sf_type_t2 = t2; + lfe->sf_type_v2 = v2; lfe->sf_master = master; lfe->sf_type_override = override ? strdup(override) : NULL; satip_frontend_hacks(lfe, &def_positions); diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index 1715afeb..5e95d2bb 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -110,7 +110,7 @@ struct satip_frontend */ int sf_number; dvb_fe_type_t sf_type; - int sf_type_t2; + int sf_type_v2; char *sf_type_override; int sf_master; int sf_udp_rtp_port; @@ -127,6 +127,7 @@ struct satip_frontend int sf_thread; int sf_running; int sf_tables; + int sf_atsc_c; int sf_position; signal_state_t sf_status; gtimer_t sf_monitor_timer; @@ -183,7 +184,7 @@ char *satip_device_nicename ( satip_device_t *sd, char *buf, int len ); satip_frontend_t * satip_frontend_create - ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int t2, int num ); + ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int v2, int num ); void satip_frontend_save ( satip_frontend_t *lfe, htsmsg_t *m ); diff --git a/src/input/mpegts/satip/satip_rtsp.c b/src/input/mpegts/satip/satip_rtsp.c index d8db4271..9c09d576 100644 --- a/src/input/mpegts/satip/satip_rtsp.c +++ b/src/input/mpegts/satip/satip_rtsp.c @@ -77,8 +77,9 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, { .t = DVB_SYS_DVBS, "dvbs" }, { .t = DVB_SYS_DVBS2, "dvbs2" }, { .t = DVB_SYS_DVBC_ANNEX_A, "dvbc" }, - { .t = DVB_SYS_DVBC_ANNEX_B, "dvbc" }, { .t = DVB_SYS_DVBC_ANNEX_C, "dvbc" }, + { .t = DVB_SYS_ATSC, "atsc" }, + { .t = DVB_SYS_DVBC_ANNEX_B, "dvbcb" }, { .t = TABLE_EOD } }; static tvh2satip_t pol[] = { @@ -190,7 +191,8 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, dmc->u.dmc_fe_qam.fec_inner != DVB_FEC_AUTO) /* note: OctopusNet device does not handle 'fec=auto' */ ADD(u.dmc_fe_qam.fec_inner, fec, "auto"); - } else { + } else if (dmc->dmc_fe_delsys == DVB_SYS_DVBT || + dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); if (dmc->u.dmc_fe_ofdm.bandwidth != DVB_BANDWIDTH_AUTO && dmc->u.dmc_fe_ofdm.bandwidth != DVB_BANDWIDTH_NONE) @@ -209,6 +211,14 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, if (dmc->dmc_fe_delsys == DVB_SYS_DVBT2) if (dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER) satip_rtsp_add_val("pls", buf, (dmc->dmc_fe_stream_id & 0xff) * 1000); + } else if (dmc->dmc_fe_delsys == DVB_SYS_ATSC || + dmc->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_B) { + satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); + if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && + dmc->dmc_fe_modulation != DVB_MOD_NONE && + dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) + ADD(dmc_fe_modulation, mtype, + dmc->dmc_fe_delsys == DVB_SYS_ATSC ? "8vsb" : "64qam"); } if (flags & SATIP_SETUP_PIDS0) strcat(buf, "&pids=0"); diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index ffd62d58..419a04b1 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -88,23 +88,53 @@ rtsp_delsys(int fe, int *findex) if (fe < 1) return DVB_SYS_NONE; pthread_mutex_lock(&global_lock); - i = config_get_int("satip_dvbt", 0); - if (fe <= i) { - res = DVB_SYS_DVBT; - goto result; - } - fe -= i; i = config_get_int("satip_dvbs", 0); if (fe <= i) { res = DVB_SYS_DVBS; goto result; } fe -= i; + i = config_get_int("satip_dvbs2", 0); + if (fe <= i) { + res = DVB_SYS_DVBS; + goto result; + } + fe -= i; + i = config_get_int("satip_dvbt", 0); + if (fe <= i) { + res = DVB_SYS_DVBT; + goto result; + } + fe -= i; + i = config_get_int("satip_dvbt2", 0); + if (fe <= i) { + res = DVB_SYS_DVBT; + goto result; + } + fe -= i; i = config_get_int("satip_dvbc", 0); if (fe <= i) { res = DVB_SYS_DVBC_ANNEX_A; goto result; } + fe -= i; + i = config_get_int("satip_dvbc2", 0); + if (fe <= i) { + res = DVB_SYS_DVBC_ANNEX_A; + goto result; + } + fe -= i; + i = config_get_int("satip_atsc", 0); + if (fe <= i) { + res = DVB_SYS_ATSC; + goto result; + } + fe -= i; + i = config_get_int("satip_dvbcb", 0); + if (fe <= i) { + res = DVB_SYS_DVBC_ANNEX_B; + goto result; + } pthread_mutex_unlock(&global_lock); return DVB_SYS_NONE; result: @@ -688,6 +718,8 @@ msys_to_tvh(http_connection_t *hc) { "dvbt2", DVB_SYS_DVBT2 }, { "dvbc", DVB_SYS_DVBC_ANNEX_A }, { "dvbc2", DVB_SYS_DVBC_ANNEX_C }, + { "atsc", DVB_SYS_ATSC }, + { "dvbcb", DVB_SYS_DVBC_ANNEX_B } }; const char *s = http_arg_get_remove(&hc->hc_req_args, "msys"); return s[0] ? str2val(s, tab) : DVB_SYS_NONE; @@ -811,6 +843,7 @@ mtype_to_tvh(http_connection_t *hc) { "64qam", DVB_MOD_QAM_64 }, { "128qam", DVB_MOD_QAM_128 }, { "256qam", DVB_MOD_QAM_256 }, + { "8vsb", DVB_MOD_VSB_8 }, }; const char *s = http_arg_get_remove(&hc->hc_req_args, "mtype"); if (s[0]) { @@ -1088,6 +1121,11 @@ rtsp_process_play(http_connection_t *hc, int setup) dmc->dmc_fe_stream_id = plp; dmc->dmc_fe_pls_code = ds; /* check */ + } else if (msys == DVB_SYS_ATSC || msys == DVB_SYS_DVBC_ANNEX_B) { + + if (!TAILQ_EMPTY(&hc->hc_req_args)) + goto error; + } else { goto error; diff --git a/src/satip/server.c b/src/satip/server.c index 47ec23fc..d809d163 100644 --- a/src/satip/server.c +++ b/src/satip/server.c @@ -46,6 +46,12 @@ int satip_server_match_uuid(const char *uuid) * XML description */ +struct xml_type_xtab { + const char *id; + const char *cname; + int *count; +}; + static int satip_server_http_xml(http_connection_t *hc) { @@ -103,9 +109,24 @@ satip_server_http_xml(http_connection_t *hc) char *devicelist = NULL; htsbuf_queue_t q; mpegts_network_t *mn; - int dvbt = 0, dvbs = 0, dvbc = 0, srcs = 0, delim = 0, i; + int dvbt = 0, dvbs = 0, dvbc = 0, atsc = 0; + int srcs = 0, delim = 0, tuners = 0, i; + struct xml_type_xtab *p; http_arg_list_t args; + struct xml_type_xtab xtab[] = { + { "DVBS", "satip_dvbs", &dvbs }, + { "DVBS2", "satip_dvbs2", &dvbs }, + { "DVBT", "satip_dvbt", &dvbt }, + { "DVBT2", "satip_dvbt2", &dvbt }, + { "DVBC", "satip_dvbc", &dvbc }, + { "DVBC2", "satip_dvbc2", &dvbc }, + { "ATSC", "satip_atsc", &atsc }, + { "DVBCB", "satip_dvbcb", &dvbc }, + {} + }; + + htsbuf_queue_init(&q, 0); pthread_mutex_lock(&global_lock); @@ -120,36 +141,31 @@ satip_server_http_xml(http_connection_t *hc) srcs = mn->mn_satip_source; } else if (idnode_is_instance(&mn->mn_id, &dvb_network_dvbc_class)) dvbc++; + else if (idnode_is_instance(&mn->mn_id, &dvb_network_atsc_class)) + atsc++; } - if (dvbs && (i = config_get_int("satip_dvbs", 0)) > 0) { - htsbuf_qprintf(&q, "%sDVBS2-%d", delim ? "," : "", i); - delim++; - } else { - dvbs = 0; - } - if (dvbt && (i = config_get_int("satip_dvbt", 0)) > 0) { - htsbuf_qprintf(&q, "%sDVBT-%d", delim ? "," : "", i); - delim++; - } else { - dvbt = 0; - } - if (dvbc && (i = config_get_int("satip_dvbc", 0)) > 0) { - htsbuf_qprintf(&q, "%sDVBC-%d", delim ? "," : "", i); - delim++; - } else { - dvbc = 0; + for (p = xtab; p->id; p++) { + i = config_get_int(p->cname, 0); + if (i > 0) { + tuners += i; + if (*p->count && i > 0) { + htsbuf_qprintf(&q, "%s%s-%d", delim ? "," : "", p->id, i); + delim++; + } + } } pthread_mutex_unlock(&global_lock); if (!dvbs) srcs = 0; devicelist = htsbuf_to_string(&q); + printf("devicelist: '%s'\n", devicelist); htsbuf_queue_flush(&q); if (devicelist == NULL || devicelist[0] == '\0') { tcp_get_ip_str((struct sockaddr*)hc->hc_peer, buf, sizeof(buf)); tvhwarn("satips", "SAT>IP server announces an empty tuner list to a client %s (missing %s)", - buf, dvbt + dvbs + dvbc ? "tuner settings - global config" : "network assignment"); + buf, !tuners ? "tuner settings - global config" : "network assignment"); } if (satip_server_rtsp_port != 554) @@ -495,14 +511,20 @@ static void satip_server_info(const char *prefix, int descramble, int muxcnf) { tvhinfo("satips", "SAT>IP Server %sinitialized " "(HTTP %s:%d, RTSP %s:%d, " - "descramble %d, muxcnf %d, DVB-T %d, DVB-S2 %d, DVB-C %d)", + "descramble %d, muxcnf %d)", prefix, http_server_ip, http_server_port, http_server_ip, satip_server_rtsp_port, - descramble, muxcnf, + descramble, muxcnf); + tvhinfo("satips", "SAT>IP Server tuners: DVB-T/T2 %d/%d, DVB-S/S2 %d/%d, DVB-C/C2 %d/%d, ATSC %d, DVB-Cable/AnnexB %d", config_get_int("satip_dvbt", 0), + config_get_int("satip_dvbt2", 0), config_get_int("satip_dvbs", 0), - config_get_int("satip_dvbc", 0)); + config_get_int("satip_dvbs2", 0), + config_get_int("satip_dvbc", 0), + config_get_int("satip_dvbc2", 0), + config_get_int("satip_atsc", 0), + config_get_int("satip_dvbcb", 0)); } /* diff --git a/src/webui/extjs.c b/src/webui/extjs.c index b99b976c..8237823f 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -531,14 +531,24 @@ extjs_config(http_connection_t *hc, const char *remain, void *opaque) ssave |= config_set_int("satip_weight", atoi(str)); if ((str = http_arg_get(&hc->hc_req_args, "satip_descramble"))) ssave |= config_set_int("satip_descramble", atoi(str)); - if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbt"))) - ssave |= config_set_int("satip_dvbt", atoi(str)); - if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbs"))) - ssave |= config_set_int("satip_dvbs", atoi(str)); - if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbc"))) - ssave |= config_set_int("satip_dvbc", atoi(str)); if ((str = http_arg_get(&hc->hc_req_args, "satip_muxcnf"))) ssave |= config_set_int("satip_muxcnf", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbs"))) + ssave |= config_set_int("satip_dvbs", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbs2"))) + ssave |= config_set_int("satip_dvbs2", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbt"))) + ssave |= config_set_int("satip_dvbt", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbt2"))) + ssave |= config_set_int("satip_dvbt2", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbc"))) + ssave |= config_set_int("satip_dvbc", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbc2"))) + ssave |= config_set_int("satip_dvbc2", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_atsc"))) + ssave |= config_set_int("satip_atsc", atoi(str)); + if ((str = http_arg_get(&hc->hc_req_args, "satip_dvbcb"))) + ssave |= config_set_int("satip_dvbcb", atoi(str)); if (save | ssave) config_save(); if (ssave) diff --git a/src/webui/static/app/config.js b/src/webui/static/app/config.js index ee88e117..03adc053 100644 --- a/src/webui/static/app/config.js +++ b/src/webui/static/app/config.js @@ -45,8 +45,9 @@ tvheadend.miscconf = function(panel, index) { 'tvhtime_update_enabled', 'tvhtime_ntp_enabled', 'tvhtime_tolerance', 'prefer_picon', 'chiconpath', 'piconpath', - 'satip_rtsp', 'satip_weight', 'satip_descramble', - 'satip_dvbt', 'satip_dvbs', 'satip_dvbc' + 'satip_rtsp', 'satip_weight', 'satip_descramble', 'satip_muxcnf', + 'satip_dvbs', 'satip_dvbs2', 'satip_dvbt', 'satip_dvbt2', + 'satip_dvbc', 'satip_dvbc2', 'satip_atsc', 'satip_dvbcb' ]); /* **************************************************************** @@ -234,21 +235,41 @@ tvheadend.miscconf = function(panel, index) { name: 'satip_descramble', fieldLabel: 'Descramble Services (Limit Per Mux)' }); + var muxcnf = new Ext.form.NumberField({ + name: 'satip_muxcnf', + fieldLabel: 'Muxes Handling (0 = auto, 1 = keep, 2 = reject)' + }); + var dvbs = new Ext.form.NumberField({ + name: 'satip_dvbs', + fieldLabel: 'Exported DVB-S Tuners' + }); + var dvbs2 = new Ext.form.NumberField({ + name: 'satip_dvbs2', + fieldLabel: 'Exported DVB-S2 Tuners' + }); var dvbt = new Ext.form.NumberField({ name: 'satip_dvbt', fieldLabel: 'Exported DVB-T Tuners' }); - var dvbs = new Ext.form.NumberField({ - name: 'satip_dvbs', - fieldLabel: 'Exported DVB-S2 Tuners' + var dvbt2 = new Ext.form.NumberField({ + name: 'satip_dvbt2', + fieldLabel: 'Exported DVB-T2 Tuners' }); var dvbc = new Ext.form.NumberField({ name: 'satip_dvbc', fieldLabel: 'Exported DVB-C Tuners' }); - var muxcnf = new Ext.form.NumberField({ - name: 'satip_muxcnf', - fieldLabel: 'Muxes Handling (0 = auto, 1 = keep, 2 = reject)' + var dvbc2 = new Ext.form.NumberField({ + name: 'satip_dvbc2', + fieldLabel: 'Exported DVB-C2 Tuners' + }); + var atsc = new Ext.form.NumberField({ + name: 'satip_atsc', + fieldLabel: 'Exported ATSC Tuners' + }); + var dvbcb = new Ext.form.NumberField({ + name: 'satip_dvbcb', + fieldLabel: 'Exported DVB-Cable/AnnexB Tuners' }); satipPanel = new Ext.form.FieldSet({ @@ -256,8 +277,10 @@ tvheadend.miscconf = function(panel, index) { width: 700, autoHeight: true, collapsible: true, + collapsed: true, animCollapse: true, - items: [rtsp, weight, descramble, dvbt, dvbs, dvbc, muxcnf] + items: [rtsp, weight, descramble, muxcnf, + dvbs, dvbs2, dvbt, dvbt2, dvbc, dvbc2, atsc, dvbcb] }); }