Moved almost everything out from tdmi
This commit is contained in:
parent
f991e1376e
commit
963a0502d3
29 changed files with 624 additions and 770 deletions
|
@ -629,7 +629,7 @@ capmt_table_input(struct th_descrambler *td, struct service *t,
|
|||
{
|
||||
capmt_service_t *ct = (capmt_service_t *)td;
|
||||
capmt_t *capmt = ct->ct_capmt;
|
||||
int adapter_num = t->s_dvb_mux_instance->tdmi_adapter->tda_adapter_num;
|
||||
int adapter_num = t->s_dvb_mux->dm_current_tdmi->tdmi_adapter->tda_adapter_num;
|
||||
int total_caids = 0, current_caid = 0;
|
||||
int i;
|
||||
|
||||
|
@ -893,7 +893,7 @@ capmt_service_start(service_t *t)
|
|||
tvhlog(LOG_INFO, "capmt",
|
||||
"Starting capmt server for service \"%s\" on tuner %d",
|
||||
t->s_svcname,
|
||||
t->s_dvb_mux_instance->tdmi_adapter->tda_adapter_num);
|
||||
t->s_dvb_mux->dm_current_tdmi->tdmi_adapter->tda_adapter_num);
|
||||
|
||||
elementary_stream_t *st;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ LIST_HEAD(th_dvb_mux_instance_list, th_dvb_mux_instance);
|
|||
TAILQ_HEAD(dvb_satconf_queue, dvb_satconf);
|
||||
LIST_HEAD(dvb_mux_list, dvb_mux);
|
||||
TAILQ_HEAD(dvb_mux_queue, dvb_mux);
|
||||
LIST_HEAD(dvb_network_list, dvb_network);
|
||||
|
||||
/**
|
||||
* Satconf
|
||||
|
@ -89,7 +90,7 @@ typedef struct dvb_mux_conf {
|
|||
*/
|
||||
typedef struct dvb_network {
|
||||
|
||||
struct th_dvb_mux_instance_list dn_mux_instances; // Should go away
|
||||
LIST_ENTRY(dvb_network) dn_global_link;
|
||||
|
||||
struct dvb_mux_queue dn_initial_scan_queue;
|
||||
int dn_initial_num_mux;
|
||||
|
@ -102,6 +103,12 @@ typedef struct dvb_network {
|
|||
|
||||
gtimer_t dn_mux_scanner_timer;
|
||||
|
||||
uint32_t dn_disable_pmt_monitor;
|
||||
uint32_t dn_autodiscovery;
|
||||
uint32_t dn_nitoid;
|
||||
|
||||
char *dn_uuid;
|
||||
|
||||
} dvb_network_t;
|
||||
|
||||
|
||||
|
@ -125,8 +132,6 @@ typedef struct dvb_mux {
|
|||
|
||||
TAILQ_HEAD(, epggrab_ota_mux) dm_epg_grab;
|
||||
|
||||
struct th_dvb_mux_instance *dm_tdmi; // wrong
|
||||
|
||||
TAILQ_ENTRY(dvb_mux) dm_scan_link;
|
||||
struct dvb_mux_queue *dm_scan_queue;
|
||||
|
||||
|
@ -138,6 +143,15 @@ typedef struct dvb_mux {
|
|||
|
||||
struct th_dvb_mux_instance *dm_current_tdmi;
|
||||
|
||||
struct th_dvb_mux_instance_list dm_tdmis;
|
||||
|
||||
// Derived from dm_conf (more or less)
|
||||
char *dm_local_identifier;
|
||||
|
||||
char *dm_uuid;
|
||||
|
||||
int dm_enabled;
|
||||
|
||||
} dvb_mux_t;
|
||||
|
||||
|
||||
|
@ -149,12 +163,11 @@ typedef struct dvb_mux {
|
|||
typedef struct th_dvb_mux_instance {
|
||||
|
||||
dvb_mux_t *tdmi_mux;
|
||||
|
||||
RB_ENTRY(th_dvb_mux_instance) tdmi_global_link;
|
||||
|
||||
LIST_ENTRY(th_dvb_mux_instance) tdmi_adapter_link; // wrong
|
||||
LIST_ENTRY(th_dvb_mux_instance) tdmi_mux_link;
|
||||
|
||||
struct th_dvb_adapter *tdmi_adapter;
|
||||
LIST_ENTRY(th_dvb_mux_instance) tdmi_adapter_link;
|
||||
|
||||
|
||||
uint16_t tdmi_snr, tdmi_signal;
|
||||
uint32_t tdmi_ber, tdmi_unc;
|
||||
|
@ -177,10 +190,8 @@ typedef struct th_dvb_mux_instance {
|
|||
|
||||
int tdmi_quality;
|
||||
|
||||
int tdmi_enabled;
|
||||
|
||||
|
||||
char *tdmi_identifier;
|
||||
int tdmi_tune_failed; // Adapter failed to tune this frequency
|
||||
// Don't try again
|
||||
|
||||
struct th_subscription_list tdmi_subscriptions;
|
||||
|
||||
|
@ -216,6 +227,8 @@ typedef struct th_dvb_adapter {
|
|||
|
||||
dvb_network_t *tda_dn;
|
||||
|
||||
struct th_dvb_mux_instance_list tda_tdmis;
|
||||
|
||||
th_dvb_mux_instance_t *tda_current_tdmi;
|
||||
char *tda_tune_reason; // Reason for last tune
|
||||
|
||||
|
@ -223,17 +236,14 @@ typedef struct th_dvb_adapter {
|
|||
|
||||
const char *tda_rootpath;
|
||||
char *tda_identifier;
|
||||
uint32_t tda_autodiscovery;
|
||||
uint32_t tda_idleclose;
|
||||
uint32_t tda_skip_initialscan;
|
||||
uint32_t tda_skip_checksubscr;
|
||||
uint32_t tda_qmon;
|
||||
uint32_t tda_poweroff;
|
||||
uint32_t tda_sidtochan;
|
||||
uint32_t tda_nitoid;
|
||||
uint32_t tda_diseqc_version;
|
||||
uint32_t tda_diseqc_repeats;
|
||||
uint32_t tda_disable_pmt_monitor;
|
||||
int32_t tda_full_mux_rx;
|
||||
char *tda_displayname;
|
||||
|
||||
|
@ -340,8 +350,9 @@ typedef struct th_dvb_table {
|
|||
} th_dvb_table_t;
|
||||
|
||||
|
||||
extern struct dvb_network_list dvb_networks;
|
||||
extern struct th_dvb_adapter_queue dvb_adapters;
|
||||
extern struct th_dvb_mux_instance_tree dvb_muxes;
|
||||
//extern struct th_dvb_mux_instance_tree dvb_muxes;
|
||||
|
||||
void dvb_init(uint32_t adapter_mask, const char *rawfile);
|
||||
|
||||
|
@ -418,17 +429,17 @@ int dvb_mux_str2mode(const char *str);
|
|||
int dvb_mux_str2guard(const char *str);
|
||||
int dvb_mux_str2hier(const char *str);
|
||||
|
||||
void dvb_mux_save(th_dvb_mux_instance_t *tdmi);
|
||||
void dvb_mux_save(dvb_mux_t *dm);
|
||||
|
||||
void dvb_mux_load(th_dvb_adapter_t *tda);
|
||||
void dvb_mux_load(dvb_network_t *dn);
|
||||
|
||||
void dvb_mux_destroy(th_dvb_mux_instance_t *tdmi);
|
||||
void dvb_mux_destroy(dvb_mux_t *dm);
|
||||
|
||||
th_dvb_mux_instance_t *dvb_mux_create(th_dvb_adapter_t *tda,
|
||||
const struct dvb_mux_conf *dmc,
|
||||
uint16_t onid, uint16_t tsid, const char *network,
|
||||
const char *logprefix, int enabled,
|
||||
int initialscan, const char *identifier);
|
||||
dvb_mux_t *dvb_mux_create(dvb_network_t *tda,
|
||||
const struct dvb_mux_conf *dmc,
|
||||
uint16_t onid, uint16_t tsid, const char *network,
|
||||
const char *logprefix, int enabled,
|
||||
int initialscan, const char *uuid);
|
||||
|
||||
void dvb_mux_set_networkname(dvb_mux_t *dm, const char *name);
|
||||
|
||||
|
@ -441,11 +452,11 @@ void dvb_mux_set_enable(th_dvb_mux_instance_t *tdmi, int enabled);
|
|||
void dvb_mux_set_satconf(th_dvb_mux_instance_t *tdmi, const char *scid,
|
||||
int save);
|
||||
|
||||
htsmsg_t *dvb_mux_build_msg(th_dvb_mux_instance_t *tdmi);
|
||||
htsmsg_t *dvb_mux_build_msg(dvb_mux_t *dm);
|
||||
|
||||
void dvb_mux_notify(th_dvb_mux_instance_t *tdmi);
|
||||
void dvb_mux_notify(dvb_mux_t *dm);
|
||||
|
||||
const char *dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
||||
const char *dvb_mux_add_by_params(dvb_network_t *dn,
|
||||
int freq,
|
||||
int symrate,
|
||||
int bw,
|
||||
|
@ -464,27 +475,33 @@ int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src,
|
|||
dvb_satconf_t *satconf);
|
||||
#endif
|
||||
|
||||
th_dvb_mux_instance_t *dvb_mux_find
|
||||
(th_dvb_adapter_t *tda, const char *netname, uint16_t onid, uint16_t tsid,
|
||||
int enabled );
|
||||
dvb_mux_t *dvb_mux_find(dvb_network_t *dn, const char *netname, uint16_t onid,
|
||||
uint16_t tsid, int enabled);
|
||||
|
||||
|
||||
/**
|
||||
* DVB Transport (aka DVB service)
|
||||
*/
|
||||
void dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier);
|
||||
void dvb_tdmi_destroy(th_dvb_mux_instance_t *tdmi);
|
||||
|
||||
struct service *dvb_service_find(th_dvb_mux_instance_t *tdmi,
|
||||
uint16_t sid, int pmt_pid,
|
||||
const char *identifier);
|
||||
/**
|
||||
* DVB Transport (aka DVB service)
|
||||
*/
|
||||
void dvb_service_load(dvb_mux_t *dm);
|
||||
|
||||
struct service *dvb_service_find2(th_dvb_mux_instance_t *tdmi,
|
||||
uint16_t sid, int pmt_pid,
|
||||
const char *identifier, int *save);
|
||||
struct service *dvb_service_find(dvb_mux_t *dm,
|
||||
uint16_t sid, int pmt_pid,
|
||||
const char *identifier);
|
||||
|
||||
struct service *dvb_service_find3
|
||||
(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi,
|
||||
const char *netname, uint16_t onid, uint16_t tsid, uint16_t sid,
|
||||
int enabled, int epgprimary);
|
||||
struct service *dvb_service_find2(dvb_mux_t *dm,
|
||||
uint16_t sid, int pmt_pid,
|
||||
const char *identifier, int *save);
|
||||
|
||||
struct service *dvb_service_find3(dvb_network_t *dn,
|
||||
dvb_mux_t *dm,
|
||||
const char *netname, uint16_t onid,
|
||||
uint16_t tsid, uint16_t sid,
|
||||
int enabled, int epgprimary);
|
||||
|
||||
void dvb_service_notify(struct service *t);
|
||||
|
||||
|
|
|
@ -76,18 +76,15 @@ tda_save(th_dvb_adapter_t *tda)
|
|||
|
||||
htsmsg_add_str(m, "type", dvb_adaptertype_to_str(tda->tda_fe_type));
|
||||
htsmsg_add_str(m, "displayname", tda->tda_displayname);
|
||||
htsmsg_add_u32(m, "autodiscovery", tda->tda_autodiscovery);
|
||||
htsmsg_add_u32(m, "idleclose", tda->tda_idleclose);
|
||||
htsmsg_add_u32(m, "skip_checksubscr", tda->tda_skip_checksubscr);
|
||||
htsmsg_add_u32(m, "sidtochan", tda->tda_sidtochan);
|
||||
htsmsg_add_u32(m, "qmon", tda->tda_qmon);
|
||||
htsmsg_add_u32(m, "poweroff", tda->tda_poweroff);
|
||||
htsmsg_add_u32(m, "nitoid", tda->tda_nitoid);
|
||||
htsmsg_add_u32(m, "diseqc_version", tda->tda_diseqc_version);
|
||||
htsmsg_add_u32(m, "diseqc_repeats", tda->tda_diseqc_repeats);
|
||||
htsmsg_add_u32(m, "extrapriority", tda->tda_extrapriority);
|
||||
htsmsg_add_u32(m, "skip_initialscan", tda->tda_skip_initialscan);
|
||||
htsmsg_add_u32(m, "disable_pmt_monitor", tda->tda_disable_pmt_monitor);
|
||||
htsmsg_add_s32(m, "full_mux_rx", tda->tda_full_mux_rx);
|
||||
hts_settings_save(m, "dvbadapters/%s", tda->tda_identifier);
|
||||
htsmsg_destroy(m);
|
||||
|
@ -117,25 +114,6 @@ dvb_adapter_set_displayname(th_dvb_adapter_t *tda, const char *s)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_adapter_set_auto_discovery(th_dvb_adapter_t *tda, int on)
|
||||
{
|
||||
if(tda->tda_autodiscovery == on)
|
||||
return;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" mux autodiscovery set to: %s",
|
||||
tda->tda_displayname, on ? "On" : "Off");
|
||||
|
||||
tda->tda_autodiscovery = on;
|
||||
tda_save(tda);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -247,26 +225,6 @@ dvb_adapter_set_poweroff(th_dvb_adapter_t *tda, int on)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_adapter_set_nitoid(th_dvb_adapter_t *tda, int nitoid)
|
||||
{
|
||||
lock_assert(&global_lock);
|
||||
|
||||
if(tda->tda_nitoid == nitoid)
|
||||
return;
|
||||
|
||||
tvhlog(LOG_NOTICE, "dvb", "NIT-o network id \"%d\" changed to \"%d\"",
|
||||
tda->tda_nitoid, nitoid);
|
||||
|
||||
tda->tda_nitoid = nitoid;
|
||||
|
||||
tda_save(tda);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -322,25 +280,6 @@ dvb_adapter_set_extrapriority(th_dvb_adapter_t *tda, int extrapriority)
|
|||
tda_save(tda);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_adapter_set_disable_pmt_monitor(th_dvb_adapter_t *tda, int on)
|
||||
{
|
||||
if(tda->tda_disable_pmt_monitor == on)
|
||||
return;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" disabled PMT monitoring set to: %s",
|
||||
tda->tda_displayname, on ? "On" : "Off");
|
||||
|
||||
tda->tda_disable_pmt_monitor = on;
|
||||
tda_save(tda);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -475,8 +414,6 @@ tda_add(int adapter_num)
|
|||
|
||||
tda->tda_identifier = strdup(buf);
|
||||
|
||||
tda->tda_autodiscovery = tda->tda_fe_type != FE_QPSK;
|
||||
|
||||
tda->tda_sat = tda->tda_fe_type == FE_QPSK;
|
||||
|
||||
/* Come up with an initial displayname, user can change it and it will
|
||||
|
@ -521,11 +458,7 @@ tda_add_from_file(const char *filename)
|
|||
buf[i] = '_';
|
||||
|
||||
tda->tda_identifier = strdup(buf);
|
||||
|
||||
tda->tda_autodiscovery = 0;
|
||||
|
||||
tda->tda_sat = 0;
|
||||
|
||||
tda->tda_full_mux_rx = 1;
|
||||
|
||||
/* Come up with an initial displayname, user can change it and it will
|
||||
|
@ -661,18 +594,15 @@ dvb_adapter_init(uint32_t adapter_mask, const char *rawfile)
|
|||
free(tda->tda_displayname);
|
||||
tda->tda_displayname = strdup(name);
|
||||
|
||||
htsmsg_get_u32(c, "autodiscovery", &tda->tda_autodiscovery);
|
||||
htsmsg_get_u32(c, "idleclose", &tda->tda_idleclose);
|
||||
htsmsg_get_u32(c, "skip_checksubscr", &tda->tda_skip_checksubscr);
|
||||
htsmsg_get_u32(c, "sidtochan", &tda->tda_sidtochan);
|
||||
htsmsg_get_u32(c, "qmon", &tda->tda_qmon);
|
||||
htsmsg_get_u32(c, "poweroff", &tda->tda_poweroff);
|
||||
htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid);
|
||||
htsmsg_get_u32(c, "diseqc_version", &tda->tda_diseqc_version);
|
||||
htsmsg_get_u32(c, "diseqc_repeats", &tda->tda_diseqc_repeats);
|
||||
htsmsg_get_u32(c, "extrapriority", &tda->tda_extrapriority);
|
||||
htsmsg_get_u32(c, "skip_initialscan", &tda->tda_skip_initialscan);
|
||||
htsmsg_get_u32(c, "disable_pmt_monitor", &tda->tda_disable_pmt_monitor);
|
||||
if (htsmsg_get_s32(c, "full_mux_rx", &tda->tda_full_mux_rx))
|
||||
if (!htsmsg_get_u32(c, "disable_full_mux_rx", &u32) && u32)
|
||||
tda->tda_full_mux_rx = 0;
|
||||
|
@ -685,8 +615,6 @@ dvb_adapter_init(uint32_t adapter_mask, const char *rawfile)
|
|||
|
||||
if(tda->tda_sat)
|
||||
dvb_satconf_init(tda);
|
||||
|
||||
dvb_mux_load(tda);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -776,6 +704,7 @@ dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src)
|
|||
/**
|
||||
*
|
||||
*/
|
||||
#if 0
|
||||
int
|
||||
dvb_adapter_destroy(th_dvb_adapter_t *tda)
|
||||
{
|
||||
|
@ -788,8 +717,8 @@ dvb_adapter_destroy(th_dvb_adapter_t *tda)
|
|||
|
||||
hts_settings_remove("dvbadapters/%s", tda->tda_identifier);
|
||||
|
||||
while((tdmi = LIST_FIRST(&tda->tda_dn->dn_mux_instances)) != NULL)
|
||||
dvb_mux_destroy(tdmi);
|
||||
while((tdmi = LIST_FIRST(&tda->tda_tdmis)) != NULL)
|
||||
dvb_tdmi_destroy(tdmi);
|
||||
|
||||
TAILQ_REMOVE(&dvb_adapters, tda, tda_global_link);
|
||||
|
||||
|
@ -801,6 +730,7 @@ dvb_adapter_destroy(th_dvb_adapter_t *tda)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -940,8 +870,7 @@ dvb_adapter_input_dvr(void *aux)
|
|||
}
|
||||
} else {
|
||||
LIST_FOREACH(t, &tda->tda_transports, s_active_link)
|
||||
if(t->s_dvb_mux_instance == tda->tda_current_tdmi)
|
||||
ts_recv_packet1(t, tsb + i, NULL);
|
||||
ts_recv_packet1(t, tsb + i, NULL);
|
||||
}
|
||||
|
||||
i += 188;
|
||||
|
@ -981,33 +910,17 @@ dvb_adapter_build_msg(th_dvb_adapter_t *tda)
|
|||
{
|
||||
char buf[100];
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
service_t *t;
|
||||
int nummux = 0;
|
||||
int numsvc = 0;
|
||||
int fdiv;
|
||||
|
||||
htsmsg_add_str(m, "identifier", tda->tda_identifier);
|
||||
htsmsg_add_str(m, "name", tda->tda_displayname);
|
||||
|
||||
// XXX: bad bad bad slow slow slow
|
||||
LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) {
|
||||
nummux++;
|
||||
LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) {
|
||||
numsvc++;
|
||||
}
|
||||
}
|
||||
|
||||
htsmsg_add_str(m, "type", "dvb");
|
||||
|
||||
htsmsg_add_u32(m, "services", numsvc);
|
||||
htsmsg_add_u32(m, "muxes", nummux);
|
||||
htsmsg_add_u32(m, "initialMuxes", tda->tda_dn->dn_initial_num_mux);
|
||||
|
||||
if(tda->tda_current_tdmi != NULL) {
|
||||
th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi;
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tda->tda_current_tdmi);
|
||||
dvb_mux_nicename(buf, sizeof(buf), tda->tda_current_tdmi->tdmi_mux);
|
||||
htsmsg_add_str(m, "currentMux", buf);
|
||||
|
||||
htsmsg_add_u32(m, "signal", MIN(tdmi->tdmi_signal * 100 / 65535, 100));
|
||||
|
|
|
@ -97,7 +97,6 @@ dvb_fe_monitor(void *aux)
|
|||
streaming_message_t sm;
|
||||
struct service *t;
|
||||
|
||||
int store = 0;
|
||||
int notify = 0;
|
||||
|
||||
gtimer_arm(&tda->tda_fe_monitor_timer, dvb_fe_monitor, tda, 1);
|
||||
|
@ -191,11 +190,10 @@ dvb_fe_monitor(void *aux)
|
|||
if(status != tdmi->tdmi_fe_status) {
|
||||
tdmi->tdmi_fe_status = status;
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi->tdmi_mux);
|
||||
tvhlog(LOG_DEBUG,
|
||||
"dvb", "\"%s\" on adapter \"%s\", status changed to %s",
|
||||
buf, tda->tda_displayname, dvb_mux_status(tdmi));
|
||||
store = 1;
|
||||
notify = 1;
|
||||
}
|
||||
|
||||
|
@ -208,12 +206,13 @@ dvb_fe_monitor(void *aux)
|
|||
}
|
||||
if(q != tdmi->tdmi_quality) {
|
||||
tdmi->tdmi_quality = q;
|
||||
store = 1;
|
||||
notify = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(notify) {
|
||||
|
||||
#if 0 // XXX(dvbreorg)
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "id", tdmi->tdmi_identifier);
|
||||
htsmsg_add_u32(m, "quality", tdmi->tdmi_quality);
|
||||
|
@ -222,8 +221,9 @@ dvb_fe_monitor(void *aux)
|
|||
htsmsg_add_u32(m, "ber", tdmi->tdmi_ber);
|
||||
htsmsg_add_u32(m, "unc", tdmi->tdmi_unc);
|
||||
notify_by_msg("dvbMux", m);
|
||||
#endif
|
||||
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "identifier", tda->tda_identifier);
|
||||
htsmsg_add_u32(m, "signal", MIN(tdmi->tdmi_signal * 100 / 65535, 100));
|
||||
htsmsg_add_u32(m, "snr", tdmi->tdmi_snr);
|
||||
|
@ -233,8 +233,10 @@ dvb_fe_monitor(void *aux)
|
|||
notify_by_msg("tvAdapter", m);
|
||||
}
|
||||
|
||||
#if 0 // XXX(dvbreorg)
|
||||
if(store)
|
||||
dvb_mux_save(tdmi);
|
||||
#endif
|
||||
|
||||
/* Streaming message */
|
||||
sigstat.status_text = dvb_mux_status(tdmi);
|
||||
|
@ -244,14 +246,11 @@ dvb_fe_monitor(void *aux)
|
|||
sigstat.unc = tdmi->tdmi_unc;
|
||||
sm.sm_type = SMT_SIGNAL_STATUS;
|
||||
sm.sm_data = &sigstat;
|
||||
LIST_FOREACH(t, &tda->tda_transports, s_active_link)
|
||||
if(t->s_dvb_mux_instance == tda->tda_current_tdmi &&
|
||||
t->s_status == SERVICE_RUNNING ) {
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
streaming_pad_deliver(&t->s_streaming_pad, &sm);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
}
|
||||
|
||||
LIST_FOREACH(t, &tda->tda_transports, s_active_link) {
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
streaming_pad_deliver(&t->s_streaming_pad, &sm);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,7 +269,7 @@ dvb_fe_stop(th_dvb_adapter_t *tda, int retune)
|
|||
if(dm->dm_table_initial) {
|
||||
dm->dm_table_initial = 0;
|
||||
dm->dm_dn->dn_initial_num_mux--;
|
||||
dvb_mux_save(dm->dm_tdmi);
|
||||
dvb_mux_save(dm);
|
||||
}
|
||||
|
||||
dvb_table_flush_all(dm);
|
||||
|
@ -395,10 +394,10 @@ dvb_fe_tune_s2(th_dvb_mux_instance_t *tdmi, dvb_mux_conf_t *dmc)
|
|||
int
|
||||
dvb_fe_tune(dvb_mux_t *dm, const char *reason)
|
||||
{
|
||||
th_dvb_adapter_t *tda = dm->dm_tdmi->tdmi_adapter;
|
||||
dvb_network_t *dn = dm->dm_dn;
|
||||
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
th_dvb_mux_instance_t *tdmi = NULL; // dm->dm_tdmi;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
|
||||
// copy dmc, cause frequency may be change with FE_QPSK
|
||||
dvb_mux_conf_t dmc = dm->dm_conf;
|
||||
|
@ -475,7 +474,7 @@ dvb_fe_tune(dvb_mux_t *dm, const char *reason)
|
|||
tvhlog(LOG_ERR, "dvb", "diseqc setup failed %d\n", r);
|
||||
}
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi->tdmi_mux);
|
||||
|
||||
tda->tda_fe_monitor_hold = 4;
|
||||
|
||||
|
@ -507,9 +506,9 @@ dvb_fe_tune(dvb_mux_t *dm, const char *reason)
|
|||
}
|
||||
|
||||
/* Mark as bad */
|
||||
dvb_mux_set_enable(tdmi, 0);
|
||||
tdmi->tdmi_tune_failed = 1;
|
||||
return SM_CODE_TUNING_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
tda->tda_current_tdmi = tdmi;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ open_service(th_dvb_adapter_t *tda, service_t *s)
|
|||
st->es_demuxer_fd = -1;
|
||||
tvhlog(LOG_ERR, "dvb",
|
||||
"\"%s\" unable to open demuxer \"%s\" for pid %d -- %s",
|
||||
s->s_identifier, tda->tda_demux_path,
|
||||
s->s_uuid, tda->tda_demux_path,
|
||||
st->es_pid, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ open_service(th_dvb_adapter_t *tda, service_t *s)
|
|||
if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) {
|
||||
tvhlog(LOG_ERR, "dvb",
|
||||
"\"%s\" unable to configure demuxer \"%s\" for pid %d -- %s",
|
||||
s->s_identifier, tda->tda_demux_path,
|
||||
s->s_uuid, tda->tda_demux_path,
|
||||
st->es_pid, strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
|
|
@ -58,9 +58,6 @@ static struct strtab muxfestatustab[] = {
|
|||
{ "OK", TDMI_FE_OK },
|
||||
};
|
||||
|
||||
static void tdmi_set_enable(th_dvb_mux_instance_t *tdmi, int enabled);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -87,18 +84,8 @@ dvb_mux_status(th_dvb_mux_instance_t *tdmi)
|
|||
*
|
||||
*/
|
||||
static int
|
||||
tdmi_global_cmp(th_dvb_mux_instance_t *a, th_dvb_mux_instance_t *b)
|
||||
{
|
||||
return strcmp(a->tdmi_identifier, b->tdmi_identifier);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
tdmi_compare_key(const struct dvb_mux_conf *a,
|
||||
const struct dvb_mux_conf *b)
|
||||
dmc_compare_key(const struct dvb_mux_conf *a,
|
||||
const struct dvb_mux_conf *b)
|
||||
{
|
||||
int32_t fd = (int32_t)a->dmc_fe_params.frequency
|
||||
- (int32_t)b->dmc_fe_params.frequency;
|
||||
|
@ -112,9 +99,9 @@ tdmi_compare_key(const struct dvb_mux_conf *a,
|
|||
* Return 0 if configuration does not differ. return 1 if it does
|
||||
*/
|
||||
static int
|
||||
tdmi_compare_conf(int adapter_type,
|
||||
const struct dvb_mux_conf *a,
|
||||
const struct dvb_mux_conf *b)
|
||||
dcm_compare_conf(int adapter_type,
|
||||
const struct dvb_mux_conf *a,
|
||||
const struct dvb_mux_conf *b)
|
||||
{
|
||||
switch(adapter_type) {
|
||||
case FE_OFDM:
|
||||
|
@ -146,60 +133,60 @@ tdmi_compare_conf(int adapter_type,
|
|||
/**
|
||||
* Create a new mux on the given adapter, return NULL if it already exists
|
||||
*/
|
||||
th_dvb_mux_instance_t *
|
||||
dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
||||
uint16_t onid, uint16_t tsid, const char *network, const char *source,
|
||||
int enabled, int initialscan, const char *identifier)
|
||||
dvb_mux_t *
|
||||
dvb_mux_create(dvb_network_t *dn, const struct dvb_mux_conf *dmc,
|
||||
uint16_t onid, uint16_t tsid, const char *network,
|
||||
const char *source, int enabled, int initialscan,
|
||||
const char *uuid)
|
||||
{
|
||||
dvb_network_t *dn = tda->tda_dn;
|
||||
th_dvb_mux_instance_t *tdmi, *c;
|
||||
char buf[200];
|
||||
dvb_mux_t *dm;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
/* HACK - we hash/compare based on 2KHz spacing and compare on +/-500Hz */
|
||||
LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) {
|
||||
if(tdmi_compare_key(&tdmi->tdmi_mux->dm_conf, dmc))
|
||||
LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) {
|
||||
if(dmc_compare_key(&dm->dm_conf, dmc))
|
||||
break; /* Mux already exist */
|
||||
}
|
||||
|
||||
if(tdmi != NULL) {
|
||||
if(dm != NULL) {
|
||||
/* Update stuff ... */
|
||||
int save = 0;
|
||||
char buf2[1024];
|
||||
buf2[0] = 0;
|
||||
|
||||
if(tdmi_compare_conf(tda->tda_fe_type, &tdmi->tdmi_mux->dm_conf, dmc)) {
|
||||
if(dcm_compare_conf(dn->dn_fe_type, &dm->dm_conf, dmc)) {
|
||||
#if DVB_API_VERSION >= 5
|
||||
snprintf(buf2, sizeof(buf2), " (");
|
||||
if (tdmi->tdmi_mux->dm_conf.dmc_fe_modulation != dmc->dmc_fe_modulation)
|
||||
if (dm->dm_conf.dmc_fe_modulation != dmc->dmc_fe_modulation)
|
||||
sprintf(buf2, "%s %s->%s, ", buf2,
|
||||
dvb_mux_qam2str(tdmi->tdmi_mux->dm_conf.dmc_fe_modulation),
|
||||
dvb_mux_qam2str(dm->dm_conf.dmc_fe_modulation),
|
||||
dvb_mux_qam2str(dmc->dmc_fe_modulation));
|
||||
if (tdmi->tdmi_mux->dm_conf.dmc_fe_delsys != dmc->dmc_fe_delsys)
|
||||
if (dm->dm_conf.dmc_fe_delsys != dmc->dmc_fe_delsys)
|
||||
sprintf(buf2, "%s %s->%s, ", buf2,
|
||||
dvb_mux_delsys2str(tdmi->tdmi_mux->dm_conf.dmc_fe_delsys),
|
||||
dvb_mux_delsys2str(dm->dm_conf.dmc_fe_delsys),
|
||||
dvb_mux_delsys2str(dmc->dmc_fe_delsys));
|
||||
if (tdmi->tdmi_mux->dm_conf.dmc_fe_rolloff != dmc->dmc_fe_rolloff)
|
||||
if (dm->dm_conf.dmc_fe_rolloff != dmc->dmc_fe_rolloff)
|
||||
sprintf(buf2, "%s %s->%s, ", buf2,
|
||||
dvb_mux_rolloff2str(tdmi->tdmi_mux->dm_conf.dmc_fe_rolloff),
|
||||
dvb_mux_rolloff2str(dm->dm_conf.dmc_fe_rolloff),
|
||||
dvb_mux_rolloff2str(dmc->dmc_fe_rolloff));
|
||||
sprintf(buf2, "%s)", buf2);
|
||||
#endif
|
||||
|
||||
memcpy(&tdmi->tdmi_mux->dm_conf, dmc, sizeof(struct dvb_mux_conf));
|
||||
memcpy(&dm->dm_conf, dmc, sizeof(struct dvb_mux_conf));
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if(tsid != 0xFFFF && tdmi->tdmi_mux->dm_transport_stream_id != tsid) {
|
||||
tdmi->tdmi_mux->dm_transport_stream_id = tsid;
|
||||
if(tsid != 0xFFFF && dm->dm_transport_stream_id != tsid) {
|
||||
dm->dm_transport_stream_id = tsid;
|
||||
save = 1;
|
||||
}
|
||||
if(onid && tdmi->tdmi_mux->dm_network_id != onid) {
|
||||
tdmi->tdmi_mux->dm_network_id = onid;
|
||||
if(onid && dm->dm_network_id != onid) {
|
||||
dm->dm_network_id = onid;
|
||||
save = 1;
|
||||
}
|
||||
|
||||
#if 0 // XXX(dvbreorg)
|
||||
/* HACK - load old transports and remove old mux config */
|
||||
if(identifier) {
|
||||
save = 1;
|
||||
|
@ -207,20 +194,22 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
|||
hts_settings_remove("dvbmuxes/%s/%s",
|
||||
tda->tda_identifier, identifier);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(save) {
|
||||
dvb_mux_save(tdmi);
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
char buf[128];
|
||||
dvb_mux_save(dm);
|
||||
dvb_mux_nicename(buf, sizeof(buf), dm);
|
||||
tvhlog(LOG_DEBUG, "dvb",
|
||||
"Configuration for mux \"%s\" updated by %s%s",
|
||||
buf, source, buf2);
|
||||
dvb_mux_notify(tdmi);
|
||||
dvb_mux_notify(dm);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dvb_mux_t *dm = calloc(1, sizeof(dvb_mux_t));
|
||||
dm = calloc(1, sizeof(dvb_mux_t));
|
||||
|
||||
dm->dm_network_id = onid;
|
||||
dm->dm_transport_stream_id = tsid;
|
||||
|
@ -228,103 +217,67 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
|||
TAILQ_INIT(&dm->dm_epg_grab);
|
||||
TAILQ_INIT(&dm->dm_table_queue);
|
||||
|
||||
dm->dm_dn = tda->tda_dn;
|
||||
LIST_INSERT_HEAD(&tda->tda_dn->dn_muxes, dm, dm_network_link);
|
||||
dm->dm_dn = dn;
|
||||
LIST_INSERT_HEAD(&dn->dn_muxes, dm, dm_network_link);
|
||||
|
||||
tdmi = calloc(1, sizeof(th_dvb_mux_instance_t));
|
||||
tdmi->tdmi_mux = dm;
|
||||
dm->dm_tdmi = tdmi;
|
||||
char identifier[128];
|
||||
snprintf(identifier, sizeof(identifier),
|
||||
"%d%s", dmc->dmc_fe_params.frequency,
|
||||
dn->dn_fe_type == FE_QPSK ?
|
||||
dvb_polarisation_to_str(dmc->dmc_polarisation) : "");
|
||||
dm->dm_local_identifier = strdup(identifier);
|
||||
|
||||
if(identifier == NULL) {
|
||||
char qpsktxt[20];
|
||||
|
||||
if(tda->tda_sat)
|
||||
snprintf(qpsktxt, sizeof(qpsktxt), "_%s",
|
||||
dvb_polarisation_to_str(dmc->dmc_polarisation));
|
||||
else
|
||||
qpsktxt[0] = 0;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%d%s",
|
||||
tda->tda_identifier, dmc->dmc_fe_params.frequency, qpsktxt);
|
||||
tdmi->tdmi_identifier = strdup(buf);
|
||||
} else {
|
||||
tdmi->tdmi_identifier = strdup(identifier);
|
||||
}
|
||||
dm->dm_enabled = enabled;
|
||||
|
||||
c = RB_INSERT_SORTED(&dvb_muxes, tdmi, tdmi_global_link, tdmi_global_cmp);
|
||||
memcpy(&dm->dm_conf, dmc, sizeof(struct dvb_mux_conf));
|
||||
|
||||
if(c != NULL) {
|
||||
/* Global identifier collision, not good, not good at all */
|
||||
|
||||
tvhlog(LOG_ERR, "dvb",
|
||||
"Multiple DVB multiplexes with same identifier \"%s\" "
|
||||
"one is skipped", tdmi->tdmi_identifier);
|
||||
free(tdmi->tdmi_identifier);
|
||||
free(tdmi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
tdmi->tdmi_enabled = enabled;
|
||||
|
||||
|
||||
|
||||
tdmi->tdmi_adapter = tda;
|
||||
tdmi->tdmi_quality = 100;
|
||||
|
||||
memcpy(&tdmi->tdmi_mux->dm_conf, dmc, sizeof(struct dvb_mux_conf));
|
||||
|
||||
LIST_INSERT_HEAD(&tda->tda_dn->dn_mux_instances, tdmi, tdmi_adapter_link);
|
||||
dm->dm_table_initial = initialscan;
|
||||
|
||||
if(source != NULL) {
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
char buf[128];
|
||||
dvb_mux_nicename(buf, sizeof(buf), dm);
|
||||
tvhlog(LOG_NOTICE, "dvb", "New mux \"%s\" created by %s", buf, source);
|
||||
|
||||
dvb_mux_save(tdmi);
|
||||
dvb_adapter_notify(tda);
|
||||
dvb_mux_save(dm);
|
||||
}
|
||||
|
||||
dvb_service_load(tdmi, identifier);
|
||||
dvb_mux_notify(tdmi);
|
||||
dvb_service_load(dm);
|
||||
|
||||
if(enabled && dm->dm_table_initial) {
|
||||
dn->dn_initial_num_mux++;
|
||||
mux_link_initial(dn, dm);
|
||||
}
|
||||
|
||||
return tdmi;
|
||||
return dm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_tdmi_destroy(th_dvb_mux_instance_t *tdmi)
|
||||
{
|
||||
LIST_REMOVE(tdmi, tdmi_mux_link);
|
||||
LIST_REMOVE(tdmi, tdmi_adapter_link);
|
||||
free(tdmi);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy a DVB mux (it might come back by itself very soon though :)
|
||||
*/
|
||||
void
|
||||
dvb_mux_destroy(th_dvb_mux_instance_t *tdmi)
|
||||
dvb_mux_destroy(dvb_mux_t *dm)
|
||||
{
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
dvb_mux_t *dm = tdmi->tdmi_mux;
|
||||
service_t *t;
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
hts_settings_remove("dvbmuxes/%s/%s",
|
||||
tda->tda_identifier, tdmi->tdmi_identifier);
|
||||
|
||||
while((t = LIST_FIRST(&tdmi->tdmi_mux->dm_services)) != NULL) {
|
||||
hts_settings_remove("dvbtransports/%s/%s",
|
||||
t->s_dvb_mux_instance->tdmi_identifier,
|
||||
t->s_identifier);
|
||||
service_destroy(t);
|
||||
}
|
||||
LIST_REMOVE(dm, dm_network_link);
|
||||
|
||||
dvb_service_notify_by_adapter(tda);
|
||||
|
||||
if(tda->tda_current_tdmi == tdmi)
|
||||
dvb_fe_stop(tda, 0);
|
||||
|
||||
RB_REMOVE(&dvb_muxes, tdmi, tdmi_global_link);
|
||||
LIST_REMOVE(tdmi, tdmi_adapter_link);
|
||||
while((tdmi = LIST_FIRST(&dm->dm_tdmis)) != NULL)
|
||||
dvb_tdmi_destroy(tdmi);
|
||||
|
||||
if(dm->dm_scan_queue != NULL)
|
||||
TAILQ_REMOVE(dm->dm_scan_queue, dm, dm_scan_link);
|
||||
|
@ -334,28 +287,9 @@ dvb_mux_destroy(th_dvb_mux_instance_t *tdmi)
|
|||
|
||||
epggrab_mux_delete(dm);
|
||||
|
||||
hts_settings_remove("dvbmuxes/%s", tdmi->tdmi_identifier);
|
||||
|
||||
// free(tdmi->tdmi_network_name); // XXX(dvbreorg)
|
||||
free(tdmi->tdmi_identifier);
|
||||
free(tdmi);
|
||||
|
||||
dvb_adapter_notify(tda);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
th_dvb_mux_instance_t *
|
||||
dvb_mux_find_by_identifier(const char *identifier)
|
||||
{
|
||||
th_dvb_mux_instance_t skel;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
skel.tdmi_identifier = (char *)identifier;
|
||||
return RB_FIND(&dvb_muxes, &skel, tdmi_global_link, tdmi_global_cmp);
|
||||
free(dm->dm_local_identifier);
|
||||
free(dm->dm_uuid);
|
||||
free(dm);
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,30 +476,28 @@ int dvb_mux_str2hier(const char *str)
|
|||
*
|
||||
*/
|
||||
void
|
||||
dvb_mux_save(th_dvb_mux_instance_t *tdmi)
|
||||
dvb_mux_save(dvb_mux_t *dm)
|
||||
{
|
||||
const dvb_mux_conf_t *dmc = &tdmi->tdmi_mux->dm_conf;
|
||||
const dvb_mux_conf_t *dmc = &dm->dm_conf;
|
||||
const struct dvb_frontend_parameters *f = &dmc->dmc_fe_params;
|
||||
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
|
||||
htsmsg_add_u32(m, "quality", tdmi->tdmi_adapter->tda_qmon ? tdmi->tdmi_quality : 100);
|
||||
htsmsg_add_u32(m, "enabled", tdmi->tdmi_enabled);
|
||||
htsmsg_add_str(m, "status", dvb_mux_status(tdmi));
|
||||
htsmsg_add_u32(m, "enabled", dm->dm_enabled);
|
||||
|
||||
htsmsg_add_u32(m, "transportstreamid", tdmi->tdmi_mux->dm_transport_stream_id);
|
||||
htsmsg_add_u32(m, "originalnetworkid", tdmi->tdmi_mux->dm_network_id);
|
||||
if(tdmi->tdmi_mux->dm_network_name != NULL)
|
||||
htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name);
|
||||
htsmsg_add_u32(m, "transportstreamid", dm->dm_transport_stream_id);
|
||||
htsmsg_add_u32(m, "originalnetworkid", dm->dm_network_id);
|
||||
if(dm->dm_network_name != NULL)
|
||||
htsmsg_add_str(m, "network", dm->dm_network_name);
|
||||
|
||||
htsmsg_add_u32(m, "frequency", f->frequency);
|
||||
|
||||
htsmsg_add_u32(m, "initialscan", tdmi->tdmi_mux->dm_table_initial);
|
||||
htsmsg_add_u32(m, "initialscan", dm->dm_table_initial);
|
||||
|
||||
if(tdmi->tdmi_mux->dm_default_authority)
|
||||
htsmsg_add_str(m, "default_authority", tdmi->tdmi_mux->dm_default_authority);
|
||||
if(dm->dm_default_authority)
|
||||
htsmsg_add_str(m, "default_authority", dm->dm_default_authority);
|
||||
|
||||
switch(tdmi->tdmi_adapter->tda_fe_type) {
|
||||
switch(dm->dm_dn->dn_fe_type) {
|
||||
case FE_OFDM:
|
||||
htsmsg_add_str(m, "bandwidth",
|
||||
val2str(f->u.ofdm.bandwidth, bwtab));
|
||||
|
@ -626,31 +558,30 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi)
|
|||
break;
|
||||
}
|
||||
|
||||
hts_settings_save(m, "dvbmuxes/%s/%s",
|
||||
tdmi->tdmi_adapter->tda_identifier, tdmi->tdmi_identifier);
|
||||
hts_settings_save(m, "dvb/networks/%s/muxes/%s/config",
|
||||
dm->dm_dn->dn_uuid,
|
||||
dm->dm_local_identifier);
|
||||
|
||||
htsmsg_destroy(m);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static const char *
|
||||
tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier)
|
||||
dvb_mux_create_by_msg(dvb_network_t *dn, htsmsg_t *m, const char *fname)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
dvb_mux_t *dm;
|
||||
struct dvb_mux_conf dmc;
|
||||
const char *s;
|
||||
int r;
|
||||
unsigned int onid, tsid, u32, enabled, initscan;
|
||||
unsigned int onid, tsid, enabled, initscan;
|
||||
|
||||
memset(&dmc, 0, sizeof(dmc));
|
||||
|
||||
dmc.dmc_fe_params.inversion = INVERSION_AUTO;
|
||||
htsmsg_get_u32(m, "frequency", &dmc.dmc_fe_params.frequency);
|
||||
|
||||
|
||||
switch(tda->tda_fe_type) {
|
||||
switch(dn->dn_fe_type) {
|
||||
case FE_OFDM:
|
||||
s = htsmsg_get_str(m, "bandwidth");
|
||||
if(s == NULL || (r = str2val(s, bwtab)) < 0)
|
||||
|
@ -764,48 +695,43 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier)
|
|||
enabled = 1;
|
||||
|
||||
initscan = htsmsg_get_u32_or_default(m, "initialscan", 0);
|
||||
tdmi = dvb_mux_create(tda, &dmc,
|
||||
onid, tsid, htsmsg_get_str(m, "network"), NULL, enabled,
|
||||
initscan,
|
||||
identifier);
|
||||
if(tdmi != NULL) {
|
||||
|
||||
if((s = htsmsg_get_str(m, "status")) != NULL)
|
||||
tdmi->tdmi_fe_status = str2val(s, muxfestatustab);
|
||||
|
||||
if(tda->tda_qmon && !htsmsg_get_u32(m, "quality", &u32))
|
||||
tdmi->tdmi_quality = u32;
|
||||
dm = dvb_mux_create(dn, &dmc,
|
||||
onid, tsid, htsmsg_get_str(m, "network"), NULL, enabled,
|
||||
initscan,
|
||||
htsmsg_get_str(m, "uuid"));
|
||||
if(dm != NULL) {
|
||||
|
||||
if((s = htsmsg_get_str(m, "default_authority")))
|
||||
tdmi->tdmi_mux->dm_default_authority = strdup(s);
|
||||
dm->dm_default_authority = strdup(s);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_mux_load(th_dvb_adapter_t *tda)
|
||||
dvb_mux_load(dvb_network_t *dn)
|
||||
{
|
||||
htsmsg_t *l, *c;
|
||||
htsmsg_field_t *f;
|
||||
|
||||
if((l = hts_settings_load("dvbmuxes/%s", tda->tda_identifier)) == NULL)
|
||||
if((l = hts_settings_load_r(1, "dvb/networks/%s/muxes",
|
||||
dn->dn_uuid)) == NULL)
|
||||
return;
|
||||
|
||||
|
||||
HTSMSG_FOREACH(f, l) {
|
||||
if((c = htsmsg_get_map_by_field(f)) == NULL)
|
||||
continue;
|
||||
|
||||
tdmi_create_by_msg(tda, c, f->hmf_name);
|
||||
|
||||
dvb_mux_create_by_msg(dn, c, f->hmf_name);
|
||||
}
|
||||
htsmsg_destroy(l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -817,13 +743,11 @@ dvb_mux_set_networkname(dvb_mux_t *dm, const char *networkname)
|
|||
free(dm->dm_network_name);
|
||||
dm->dm_network_name = strdup(networkname);
|
||||
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
|
||||
dvb_mux_save(tdmi);
|
||||
dvb_mux_save(dm);
|
||||
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "id", tdmi->tdmi_identifier);
|
||||
htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name ?: "");
|
||||
htsmsg_add_str(m, "id", dm->dm_local_identifier);
|
||||
htsmsg_add_str(m, "network", dm->dm_network_name ?: "");
|
||||
notify_by_msg("dvbMux", m);
|
||||
}
|
||||
|
||||
|
@ -838,13 +762,11 @@ dvb_mux_set_tsid(dvb_mux_t *dm, uint16_t tsid)
|
|||
|
||||
dm->dm_transport_stream_id = tsid;
|
||||
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
|
||||
dvb_mux_save(tdmi);
|
||||
dvb_mux_save(dm);
|
||||
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "id", tdmi->tdmi_identifier);
|
||||
htsmsg_add_u32(m, "muxid", tdmi->tdmi_mux->dm_transport_stream_id);
|
||||
htsmsg_add_str(m, "uuid", dm->dm_uuid);
|
||||
htsmsg_add_u32(m, "muxid", dm->dm_transport_stream_id);
|
||||
notify_by_msg("dvbMux", m);
|
||||
}
|
||||
|
||||
|
@ -858,17 +780,15 @@ dvb_mux_set_onid(dvb_mux_t *dm, uint16_t onid)
|
|||
|
||||
dm->dm_network_id = onid;
|
||||
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
|
||||
dvb_mux_save(tdmi);
|
||||
dvb_mux_save(dm);
|
||||
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "id", tdmi->tdmi_identifier);
|
||||
htsmsg_add_u32(m, "onid", tdmi->tdmi_mux->dm_network_id);
|
||||
htsmsg_add_str(m, "uuid", dm->dm_uuid);
|
||||
htsmsg_add_u32(m, "onid", dm->dm_network_id);
|
||||
notify_by_msg("dvbMux", m);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -909,8 +829,9 @@ dvb_mux_set_enable(th_dvb_mux_instance_t *tdmi, int enabled)
|
|||
tdmi_set_enable(tdmi, enabled);
|
||||
dvb_mux_save(tdmi);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -942,17 +863,18 @@ dvb_mux_fe_status(char *buf, size_t size, th_dvb_mux_instance_t *tdmi)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
dvb_mux_modulation(char *buf, size_t size, th_dvb_mux_instance_t *tdmi)
|
||||
dvb_mux_modulation(char *buf, size_t size, const dvb_mux_t *dm)
|
||||
{
|
||||
const dvb_mux_conf_t *dmc = &tdmi->tdmi_mux->dm_conf;
|
||||
const dvb_mux_conf_t *dmc = &dm->dm_conf;
|
||||
const struct dvb_frontend_parameters *f = &dmc->dmc_fe_params;
|
||||
|
||||
switch(tdmi->tdmi_adapter->tda_fe_type) {
|
||||
switch(dm->dm_dn->dn_fe_type) {
|
||||
case FE_OFDM:
|
||||
snprintf(buf, size, "%s, %s, %s-mode",
|
||||
val2str(f->u.ofdm.constellation, qamtab),
|
||||
|
@ -990,37 +912,32 @@ dvb_mux_modulation(char *buf, size_t size, th_dvb_mux_instance_t *tdmi)
|
|||
*
|
||||
*/
|
||||
htsmsg_t *
|
||||
dvb_mux_build_msg(th_dvb_mux_instance_t *tdmi)
|
||||
dvb_mux_build_msg(dvb_mux_t *dm)
|
||||
{
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
char buf[100];
|
||||
|
||||
htsmsg_add_str(m, "id", tdmi->tdmi_identifier);
|
||||
htsmsg_add_u32(m, "enabled", tdmi->tdmi_enabled);
|
||||
htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name ?: "");
|
||||
htsmsg_add_str(m, "uuid", dm->dm_uuid);
|
||||
htsmsg_add_u32(m, "enabled", dm->dm_enabled);
|
||||
htsmsg_add_str(m, "network", dm->dm_network_name ?: "");
|
||||
|
||||
dvb_mux_nicefreq(buf, sizeof(buf), tdmi->tdmi_mux);
|
||||
dvb_mux_nicefreq(buf, sizeof(buf), dm);
|
||||
htsmsg_add_str(m, "freq", buf);
|
||||
|
||||
dvb_mux_modulation(buf, sizeof(buf), tdmi);
|
||||
dvb_mux_modulation(buf, sizeof(buf), dm);
|
||||
htsmsg_add_str(m, "mod", buf);
|
||||
|
||||
dvb_mux_fe_status(buf, sizeof(buf), tdmi);
|
||||
htsmsg_add_str(m, "fe_status", buf);
|
||||
const dvb_mux_conf_t *dmc = &dm->dm_conf;
|
||||
|
||||
const dvb_mux_conf_t *dmc = &tdmi->tdmi_mux->dm_conf;
|
||||
|
||||
|
||||
htsmsg_add_str(m, "pol",
|
||||
htsmsg_add_str(m, "pol",
|
||||
dvb_polarisation_to_str_long(dmc->dmc_polarisation));
|
||||
|
||||
if(tdmi->tdmi_mux->dm_transport_stream_id != 0xffff)
|
||||
htsmsg_add_u32(m, "muxid", tdmi->tdmi_mux->dm_transport_stream_id);
|
||||
if(dm->dm_transport_stream_id != 0xffff)
|
||||
htsmsg_add_u32(m, "muxid", dm->dm_transport_stream_id);
|
||||
|
||||
if(tdmi->tdmi_mux->dm_network_id)
|
||||
htsmsg_add_u32(m, "onid", tdmi->tdmi_mux->dm_network_id);
|
||||
if(dm->dm_network_id)
|
||||
htsmsg_add_u32(m, "onid", dm->dm_network_id);
|
||||
|
||||
htsmsg_add_u32(m, "quality", tdmi->tdmi_quality);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -1029,9 +946,9 @@ dvb_mux_build_msg(th_dvb_mux_instance_t *tdmi)
|
|||
*
|
||||
*/
|
||||
void
|
||||
dvb_mux_notify(th_dvb_mux_instance_t *tdmi)
|
||||
dvb_mux_notify(dvb_mux_t *dm)
|
||||
{
|
||||
notify_by_msg("dvbMux", dvb_mux_build_msg(tdmi));
|
||||
// notify_by_msg("dvbMux", dvb_mux_build_msg(tdmi));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1039,7 +956,7 @@ dvb_mux_notify(th_dvb_mux_instance_t *tdmi)
|
|||
*
|
||||
*/
|
||||
const char *
|
||||
dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
||||
dvb_mux_add_by_params(dvb_network_t *dn,
|
||||
int freq,
|
||||
int symrate,
|
||||
int bw,
|
||||
|
@ -1054,13 +971,12 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
|||
int polarisation,
|
||||
const char *satconf)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
struct dvb_mux_conf dmc;
|
||||
|
||||
memset(&dmc, 0, sizeof(dmc));
|
||||
dmc.dmc_fe_params.inversion = INVERSION_AUTO;
|
||||
|
||||
switch(tda->tda_fe_type) {
|
||||
switch(dn->dn_fe_type) {
|
||||
case FE_OFDM:
|
||||
dmc.dmc_fe_params.frequency = freq * 1000;
|
||||
if(!val2str(bw, bwtab))
|
||||
|
@ -1146,14 +1062,14 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
|||
|
||||
dmc.dmc_polarisation = polarisation;
|
||||
|
||||
tdmi = dvb_mux_create(tda, &dmc, 0, 0xffff, NULL, NULL, 1, 1, NULL);
|
||||
dvb_mux_t *dm = dvb_mux_create(dn, &dmc, 0, 0xffff, NULL, NULL, 1, 1, NULL);
|
||||
|
||||
if(tdmi == NULL)
|
||||
if(dm == NULL)
|
||||
return "Mux already exist";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
|
@ -1234,23 +1150,33 @@ dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src,
|
|||
}
|
||||
#endif
|
||||
|
||||
th_dvb_mux_instance_t *dvb_mux_find
|
||||
( th_dvb_adapter_t *tda, const char *netname, uint16_t onid, uint16_t tsid,
|
||||
int enabled )
|
||||
dvb_mux_t *
|
||||
dvb_mux_find(dvb_network_t *dn, const char *netname, uint16_t onid,
|
||||
uint16_t tsid, int enabled)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
if (tda) {
|
||||
LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) {
|
||||
if (enabled && !tdmi->tdmi_enabled) continue;
|
||||
if (onid && onid != tdmi->tdmi_mux->dm_network_id) continue;
|
||||
if (tsid && tsid != tdmi->tdmi_mux->dm_transport_stream_id) continue;
|
||||
if (netname && strcmp(netname, tdmi->tdmi_mux->dm_network_name ?: "")) continue;
|
||||
return tdmi;
|
||||
dvb_mux_t *dm;
|
||||
|
||||
if(dn != NULL) {
|
||||
LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) {
|
||||
|
||||
if (enabled && !dm->dm_enabled)
|
||||
continue;
|
||||
|
||||
if (onid && onid != dm->dm_network_id)
|
||||
continue;
|
||||
|
||||
if (tsid && tsid != dm->dm_transport_stream_id)
|
||||
continue;
|
||||
|
||||
if (netname && strcmp(netname, dm->dm_network_name ?: ""))
|
||||
continue;
|
||||
return dm;
|
||||
}
|
||||
} else {
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link)
|
||||
if ((tdmi = dvb_mux_find(tda, netname, onid, tsid, enabled)))
|
||||
return tdmi;
|
||||
dvb_network_t *dn;
|
||||
LIST_FOREACH(dn, &dvb_networks, dn_global_link)
|
||||
if ((dm = dvb_mux_find(dn, netname, onid, tsid, enabled)))
|
||||
return dm;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "dvb.h"
|
||||
#include "epggrab.h"
|
||||
|
||||
|
||||
struct dvb_network_list dvb_networks;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -33,9 +33,96 @@ dvb_network_create(int fe_type)
|
|||
dn->dn_fe_type = fe_type;
|
||||
TAILQ_INIT(&dn->dn_initial_scan_queue);
|
||||
gtimer_arm(&dn->dn_mux_scanner_timer, dvb_network_mux_scanner, dn, 1);
|
||||
|
||||
dn->dn_autodiscovery = fe_type != FE_QPSK;
|
||||
LIST_INSERT_HEAD(&dvb_networks, dn, dn_global_link);
|
||||
return dn;
|
||||
}
|
||||
|
||||
#if 0
|
||||
htsmsg_get_u32(c, "autodiscovery", &tda->tda_autodiscovery);
|
||||
htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid);
|
||||
htsmsg_get_u32(c, "disable_pmt_monitor", &tda->tda_disable_pmt_monitor);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
dvb_network_save(dvb_network_t *dn)
|
||||
{
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
htsmsg_add_u32(m, "autodiscovery", dn->dn_autodiscovery);
|
||||
htsmsg_add_u32(m, "nitoid", dn->dn_nitoid);
|
||||
htsmsg_add_u32(m, "disable_pmt_monitor", dn->dn_disable_pmt_monitor);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_network_set_auto_discovery(dvb_network_t *dn, int on)
|
||||
{
|
||||
if(dn->dn_autodiscovery == on)
|
||||
return;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
tvhlog(LOG_NOTICE, "dvb", "Network \"%s\" mux autodiscovery set to: %s",
|
||||
dn->dn_displayname, on ? "On" : "Off");
|
||||
|
||||
dn->dn_autodiscovery = on;
|
||||
dvb_network_save(dn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_network_set_nitoid(dvb_network_t *dn, int nitoid)
|
||||
{
|
||||
lock_assert(&global_lock);
|
||||
|
||||
if(dn->dn_nitoid == nitoid)
|
||||
return;
|
||||
|
||||
tvhlog(LOG_NOTICE, "dvb", "NIT-o network id \"%d\" changed to \"%d\"",
|
||||
dn->dn_nitoid, nitoid);
|
||||
|
||||
dn->dn_nitoid = nitoid;
|
||||
dvb_network_save(dn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_network_set_disable_pmt_monitor(th_dvb_network_t *dn, int on)
|
||||
{
|
||||
if(dn->dn_disable_pmt_monitor == on)
|
||||
return;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
tvhlog(LOG_NOTICE, "dvb", "Network \"%s\" disabled PMT monitoring set to: %s",
|
||||
dn->dn_displayname, on ? "On" : "Off");
|
||||
|
||||
dn->dn_disable_pmt_monitor = on;
|
||||
dvb_network_save(dn);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
*
|
||||
*/
|
||||
static void
|
||||
dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net,
|
||||
dvb_mux_preconf_add(dvb_network_t *dn, const network_t *net,
|
||||
const char *source)
|
||||
{
|
||||
const mux_t *m;
|
||||
|
@ -48,7 +48,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net,
|
|||
dmc.dmc_fe_params.inversion = INVERSION_AUTO;
|
||||
dmc.dmc_fe_params.frequency = m->freq;
|
||||
|
||||
switch(tda->tda_fe_type) {
|
||||
switch(dn->dn_fe_type) {
|
||||
case FE_OFDM:
|
||||
dmc.dmc_fe_params.u.ofdm.bandwidth = m->bw;
|
||||
dmc.dmc_fe_params.u.ofdm.constellation = m->constellation;
|
||||
|
@ -96,7 +96,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net,
|
|||
break;
|
||||
}
|
||||
|
||||
dvb_mux_create(tda, &dmc, 0, 0xffff, NULL, source, 1, 1, NULL);
|
||||
dvb_mux_create(dn, &dmc, 0, 0xffff, NULL, source, 1, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const network_t *net,
|
|||
*
|
||||
*/
|
||||
int
|
||||
dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id)
|
||||
dvb_mux_preconf_add_network(dvb_network_t *dn, const char *id)
|
||||
{
|
||||
region_list_t *list;
|
||||
const region_t *r;
|
||||
|
@ -114,7 +114,7 @@ dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id)
|
|||
|
||||
snprintf(source, sizeof(source), "built-in configuration from \"%s\"", id);
|
||||
|
||||
switch(tda->tda_fe_type) {
|
||||
switch(dn->dn_fe_type) {
|
||||
case FE_QAM:
|
||||
list = ®ions_DVBC;
|
||||
break;
|
||||
|
@ -134,7 +134,7 @@ dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id)
|
|||
LIST_FOREACH(r, list, link) {
|
||||
LIST_FOREACH(n, &r->networks, link) {
|
||||
if(!strcmp(n->id, id)) {
|
||||
dvb_mux_preconf_add(tda, n, source);
|
||||
dvb_mux_preconf_add(dn, n, source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
|
||||
htsmsg_t *dvb_mux_preconf_get_node(int fetype, const char *node);
|
||||
|
||||
int dvb_mux_preconf_add_network(th_dvb_adapter_t *tda, const char *id);
|
||||
int dvb_mux_preconf_add_network(dvb_network_t *dn, const char *id);
|
||||
|
||||
#endif /* DVB_MUXCONFIG_H */
|
||||
|
|
|
@ -46,6 +46,14 @@
|
|||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Switch the adapter (which is implicitly tied to our transport)
|
||||
|
@ -57,6 +65,7 @@
|
|||
static int
|
||||
dvb_service_start(service_t *t, unsigned int weight, int force_start)
|
||||
{
|
||||
#if 0
|
||||
int w, r;
|
||||
th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter;
|
||||
th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi;
|
||||
|
@ -100,6 +109,8 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
dvb_table_add_pmt(t->s_dvb_mux_instance->tdmi_mux, t->s_pmt_pid);
|
||||
|
||||
return r;
|
||||
#endif
|
||||
return SM_CODE_NO_HW_ATTACHED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,6 +120,7 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
static void
|
||||
dvb_service_stop(service_t *t)
|
||||
{
|
||||
#if 0
|
||||
th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
@ -120,6 +132,7 @@ dvb_service_stop(service_t *t)
|
|||
tda->tda_close_service(tda, t);
|
||||
|
||||
t->s_status = SERVICE_IDLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -129,10 +142,12 @@ dvb_service_stop(service_t *t)
|
|||
static void
|
||||
dvb_service_refresh(service_t *t)
|
||||
{
|
||||
#if 0
|
||||
th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
tda->tda_open_service(tda, t);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,7 +180,7 @@ dvb_service_save(service_t *t)
|
|||
|
||||
if(t->s_dvb_charset != NULL)
|
||||
htsmsg_add_str(m, "dvb_charset", t->s_dvb_charset);
|
||||
|
||||
|
||||
htsmsg_add_u32(m, "dvb_eit_enable", t->s_dvb_eit_enable);
|
||||
|
||||
if(t->s_default_authority)
|
||||
|
@ -174,13 +189,15 @@ dvb_service_save(service_t *t)
|
|||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
psi_save_service_settings(m, t);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
||||
hts_settings_save(m, "dvbtransports/%s/%s",
|
||||
t->s_dvb_mux_instance->tdmi_identifier,
|
||||
t->s_identifier);
|
||||
|
||||
dvb_mux_t *dm = t->s_dvb_mux;
|
||||
|
||||
hts_settings_save(m, "dvb/networks/%s/muxes/%s/services/%04x",
|
||||
dm->dm_dn->dn_uuid,
|
||||
dm->dm_local_identifier,
|
||||
t->s_dvb_service_id);
|
||||
|
||||
htsmsg_destroy(m);
|
||||
dvb_service_notify(t);
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,7 +205,7 @@ dvb_service_save(service_t *t)
|
|||
* Load config for the given mux
|
||||
*/
|
||||
void
|
||||
dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier)
|
||||
dvb_service_load(dvb_mux_t *dm)
|
||||
{
|
||||
htsmsg_t *l, *c;
|
||||
htsmsg_field_t *f;
|
||||
|
@ -196,19 +213,14 @@ dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier)
|
|||
const char *s;
|
||||
unsigned int u32;
|
||||
service_t *t;
|
||||
int old;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
/* HACK - use provided identifier to load config incase we've migrated
|
||||
* mux freq */
|
||||
if (!tdmi_identifier)
|
||||
tdmi_identifier = tdmi->tdmi_identifier;
|
||||
old = strcmp(tdmi_identifier, tdmi->tdmi_identifier);
|
||||
|
||||
if((l = hts_settings_load("dvbtransports/%s", tdmi_identifier)) == NULL)
|
||||
l = hts_settings_load("dvb/networks/%s/muxes/%s/services",
|
||||
dm->dm_dn->dn_uuid, dm->dm_local_identifier);
|
||||
if(l == NULL)
|
||||
return;
|
||||
|
||||
|
||||
HTSMSG_FOREACH(f, l) {
|
||||
if((c = htsmsg_get_map_by_field(f)) == NULL)
|
||||
continue;
|
||||
|
@ -218,8 +230,8 @@ dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier)
|
|||
|
||||
if(htsmsg_get_u32(c, "pmt", &pmt))
|
||||
continue;
|
||||
|
||||
t = dvb_service_find(tdmi, sid, pmt, f->hmf_name);
|
||||
|
||||
t = dvb_service_find(dm, sid, pmt, f->hmf_name);
|
||||
|
||||
htsmsg_get_u32(c, "stype", &t->s_servicetype);
|
||||
if(htsmsg_get_u32(c, "scrambled", &u32))
|
||||
|
@ -258,39 +270,11 @@ dvb_service_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier)
|
|||
|
||||
if(s && u32)
|
||||
service_map_channel(t, channel_find_by_name(s, 1, 0), 0);
|
||||
|
||||
/* HACK - force save for old config */
|
||||
if(old)
|
||||
dvb_service_save(t);
|
||||
}
|
||||
|
||||
/* HACK - remove old settings */
|
||||
if(old) {
|
||||
HTSMSG_FOREACH(f, l)
|
||||
hts_settings_remove("dvbtransports/%s/%s", tdmi_identifier, f->hmf_name);
|
||||
hts_settings_remove("dvbtransports/%s", tdmi_identifier);
|
||||
}
|
||||
|
||||
htsmsg_destroy(l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called to get quality for the given transport
|
||||
*
|
||||
* We keep track of this for the entire mux (if we see errors), soo..
|
||||
* return that value
|
||||
*/
|
||||
static int
|
||||
dvb_service_quality(service_t *t)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
return tdmi->tdmi_adapter->tda_qmon ? tdmi->tdmi_quality : 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a descriptive name for the source
|
||||
|
@ -298,7 +282,7 @@ dvb_service_quality(service_t *t)
|
|||
static void
|
||||
dvb_service_setsourceinfo(service_t *t, struct source_info *si)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance;
|
||||
dvb_mux_t *dm = t->s_dvb_mux;
|
||||
char buf[100];
|
||||
|
||||
memset(si, 0, sizeof(struct source_info));
|
||||
|
@ -307,15 +291,10 @@ dvb_service_setsourceinfo(service_t *t, struct source_info *si)
|
|||
|
||||
si->si_type = S_MPEG_TS;
|
||||
|
||||
if(tdmi->tdmi_adapter->tda_rootpath != NULL)
|
||||
si->si_device = strdup(tdmi->tdmi_adapter->tda_rootpath);
|
||||
if(dm->dm_network_name != NULL)
|
||||
si->si_network = strdup(dm->dm_network_name);
|
||||
|
||||
si->si_adapter = strdup(tdmi->tdmi_adapter->tda_displayname);
|
||||
|
||||
if(tdmi->tdmi_mux->dm_network_name != NULL)
|
||||
si->si_network = strdup(tdmi->tdmi_mux->dm_network_name);
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
dvb_mux_nicename(buf, sizeof(buf), dm);
|
||||
si->si_mux = strdup(buf);
|
||||
|
||||
if(t->s_provider != NULL)
|
||||
|
@ -335,36 +314,37 @@ dvb_grace_period(service_t *t)
|
|||
return 10;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Find transport based on the DVB identification
|
||||
*/
|
||||
service_t *
|
||||
dvb_service_find3
|
||||
(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi,
|
||||
const char *netname, uint16_t onid, uint16_t tsid, uint16_t sid,
|
||||
int enabled, int epgprimary)
|
||||
dvb_service_find3(dvb_network_t *dn, dvb_mux_t *dm,
|
||||
const char *netname, uint16_t onid, uint16_t tsid,
|
||||
uint16_t sid, int enabled, int epgprimary)
|
||||
{
|
||||
service_t *svc;
|
||||
if (tdmi) {
|
||||
LIST_FOREACH(svc, &tdmi->tdmi_mux->dm_services, s_group_link) {
|
||||
if (dm != NULL) {
|
||||
LIST_FOREACH(svc, &dm->dm_services, s_group_link) {
|
||||
if (enabled && !svc->s_enabled) continue;
|
||||
if (epgprimary && !service_is_primary_epg(svc)) continue;
|
||||
if (sid == svc->s_dvb_service_id) return svc;
|
||||
}
|
||||
} else if (tda) {
|
||||
LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) {
|
||||
if (enabled && !tdmi->tdmi_enabled) continue;
|
||||
if (onid && onid != tdmi->tdmi_mux->dm_network_id) continue;
|
||||
if (tsid && tsid != tdmi->tdmi_mux->dm_transport_stream_id) continue;
|
||||
if (netname && strcmp(netname, tdmi->tdmi_mux->dm_network_name ?: "")) continue;
|
||||
if ((svc = dvb_service_find3(tda, tdmi, NULL, 0, 0, sid,
|
||||
enabled, epgprimary)))
|
||||
} else if (dn) {
|
||||
LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) {
|
||||
if (enabled && !dm->dm_enabled) continue;
|
||||
if (onid && onid != dm->dm_network_id) continue;
|
||||
if (tsid && tsid != dm->dm_transport_stream_id) continue;
|
||||
if (netname && strcmp(netname, dm->dm_network_name ?: "")) continue;
|
||||
if ((svc = dvb_service_find3(dn, dm, NULL, 0, 0, sid,
|
||||
enabled, epgprimary)))
|
||||
return svc;
|
||||
}
|
||||
} else {
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link)
|
||||
if ((svc = dvb_service_find3(tda, NULL, netname, onid, tsid,
|
||||
sid, enabled, epgprimary)))
|
||||
LIST_FOREACH(dn, &dvb_networks, dn_global_link)
|
||||
if ((svc = dvb_service_find3(dn, NULL, netname, onid, tsid,
|
||||
sid, enabled, epgprimary)))
|
||||
return svc;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -377,39 +357,36 @@ dvb_service_find3
|
|||
* If it cannot be found we create it if 'pmt_pid' is also set
|
||||
*/
|
||||
service_t *
|
||||
dvb_service_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid,
|
||||
const char *identifier)
|
||||
dvb_service_find(dvb_mux_t *dm, uint16_t sid, int pmt_pid, const char *uuid)
|
||||
{
|
||||
return dvb_service_find2(tdmi, sid, pmt_pid, identifier, NULL);
|
||||
return dvb_service_find2(dm, sid, pmt_pid, uuid, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
service_t *
|
||||
dvb_service_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid,
|
||||
const char *identifier, int *save)
|
||||
dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid,
|
||||
const char *uuid, int *save)
|
||||
{
|
||||
service_t *t;
|
||||
char tmp[200];
|
||||
char buf[200];
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) {
|
||||
LIST_FOREACH(t, &dm->dm_services, s_group_link) {
|
||||
if(t->s_dvb_service_id == sid)
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
if(pmt_pid == 0)
|
||||
return NULL;
|
||||
|
||||
if(identifier == NULL) {
|
||||
snprintf(tmp, sizeof(tmp), "%s_%04x", tdmi->tdmi_identifier, sid);
|
||||
identifier = tmp;
|
||||
}
|
||||
dvb_mux_nicename(buf, sizeof(buf), dm);
|
||||
tvhlog(LOG_DEBUG, "dvb", "Add service \"0x%x\" on \"%s\"", sid, buf);
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
tvhlog(LOG_DEBUG, "dvb", "Add service \"%s\" on \"%s\"", identifier, buf);
|
||||
|
||||
t = service_create(identifier, SERVICE_TYPE_DVB, S_MPEG_TS);
|
||||
t = service_create(uuid, S_MPEG_TS);
|
||||
if (save) *save = 1;
|
||||
|
||||
t->s_dvb_service_id = sid;
|
||||
|
@ -420,17 +397,14 @@ dvb_service_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid,
|
|||
t->s_stop_feed = dvb_service_stop;
|
||||
t->s_config_save = dvb_service_save;
|
||||
t->s_setsourceinfo = dvb_service_setsourceinfo;
|
||||
t->s_quality_index = dvb_service_quality;
|
||||
t->s_grace_period = dvb_grace_period;
|
||||
|
||||
t->s_dvb_mux_instance = tdmi;
|
||||
LIST_INSERT_HEAD(&tdmi->tdmi_mux->dm_services, t, s_group_link);
|
||||
t->s_dvb_mux = dm;
|
||||
LIST_INSERT_HEAD(&dm->dm_services, t, s_group_link);
|
||||
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
service_make_nicename(t);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
||||
dvb_adapter_notify(tdmi->tdmi_adapter);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -441,11 +415,11 @@ dvb_service_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid,
|
|||
htsmsg_t *
|
||||
dvb_service_build_msg(service_t *t)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance;
|
||||
dvb_mux_t *dm = t->s_dvb_mux;
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
char buf[100];
|
||||
|
||||
htsmsg_add_str(m, "id", t->s_identifier);
|
||||
htsmsg_add_str(m, "uuid", t->s_uuid);
|
||||
htsmsg_add_u32(m, "enabled", t->s_enabled);
|
||||
htsmsg_add_u32(m, "channel", t->s_channel_number);
|
||||
|
||||
|
@ -458,9 +432,9 @@ dvb_service_build_msg(service_t *t)
|
|||
htsmsg_add_str(m, "svcname", t->s_svcname ?: "");
|
||||
htsmsg_add_str(m, "provider", t->s_provider ?: "");
|
||||
|
||||
htsmsg_add_str(m, "network", tdmi->tdmi_mux->dm_network_name ?: "");
|
||||
htsmsg_add_str(m, "network", dm->dm_network_name ?: "");
|
||||
|
||||
dvb_mux_nicefreq(buf, sizeof(buf), tdmi->tdmi_mux);
|
||||
dvb_mux_nicefreq(buf, sizeof(buf), dm);
|
||||
htsmsg_add_str(m, "mux", buf);
|
||||
|
||||
if(t->s_ch != NULL)
|
||||
|
@ -486,16 +460,3 @@ dvb_service_notify_by_adapter(th_dvb_adapter_t *tda)
|
|||
notify_by_msg("dvbService", m);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvb_service_notify(service_t *t)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance;
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
|
||||
htsmsg_add_str(m, "adapterId", tdmi->tdmi_adapter->tda_identifier);
|
||||
notify_by_msg("dvbService", m);
|
||||
}
|
||||
|
|
|
@ -485,13 +485,12 @@ dvb_mux_nicefreq(char *buf, size_t size, const dvb_mux_t *dm)
|
|||
*
|
||||
*/
|
||||
void
|
||||
dvb_mux_nicename(char *buf, size_t size, th_dvb_mux_instance_t *tdmi)
|
||||
dvb_mux_nicename(char *buf, size_t size, dvb_mux_t *dm)
|
||||
{
|
||||
char freq[50];
|
||||
const dvb_mux_t *dm = tdmi->tdmi_mux;
|
||||
const char *n = dm->dm_network_name;
|
||||
|
||||
if(tdmi->tdmi_adapter->tda_fe_type == FE_QPSK) {
|
||||
if(dm->dm_dn->dn_fe_type == FE_QPSK) {
|
||||
nicenum(freq, sizeof(freq), dm->dm_conf.dmc_fe_params.frequency);
|
||||
snprintf(buf, size, "%s%s%s kHz %s",
|
||||
n?:"", n ? ": ":"", freq,
|
||||
|
|
|
@ -79,7 +79,7 @@ const char *dvb_polarisation_to_str(int pol);
|
|||
const char *dvb_polarisation_to_str_long(int pol);
|
||||
th_dvb_adapter_t *dvb_adapter_find_by_identifier(const char *identifier);
|
||||
th_dvb_mux_instance_t *dvb_mux_find_by_identifier(const char *identifier);
|
||||
void dvb_mux_nicename(char *buf, size_t size, th_dvb_mux_instance_t *tdmi);
|
||||
void dvb_mux_nicename(char *buf, size_t size, dvb_mux_t *tdmi);
|
||||
int dvb_mux_badness(th_dvb_mux_instance_t *tdmi);
|
||||
const char *dvb_mux_status(th_dvb_mux_instance_t *tdmi);
|
||||
void dvb_mux_nicefreq(char *buf, size_t size, const dvb_mux_t *dm);
|
||||
|
|
|
@ -64,10 +64,10 @@ dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi)
|
|||
|
||||
dm->dm_table_initial = 0;
|
||||
dn->dn_initial_num_mux--;
|
||||
dvb_mux_save(tdmi);
|
||||
dvb_mux_save(dm);
|
||||
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
dvb_mux_nicename(buf, sizeof(buf), dm);
|
||||
tvhlog(LOG_DEBUG, "dvb", "\"%s\" initial scan completed for \"%s\"",
|
||||
tda->tda_rootpath, buf);
|
||||
dvb_network_mux_scanner(dn);
|
||||
|
@ -164,7 +164,8 @@ tdt_add(dvb_mux_t *dm, int tableid, int mask,
|
|||
const char *name, int flags, int pid)
|
||||
{
|
||||
th_dvb_table_t *t;
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi;
|
||||
assert(tdmi != NULL);
|
||||
|
||||
// Allow multiple entries per PID, but only one per callback/opaque instance
|
||||
// TODO: this could mean reading the same data multiple times, and not
|
||||
|
@ -298,7 +299,7 @@ dvb_bat_callback(dvb_mux_t *dm, uint8_t *buf, int len,
|
|||
save = 1;
|
||||
}
|
||||
if (save)
|
||||
dvb_mux_save(dm->dm_tdmi);
|
||||
dvb_mux_save(dm);
|
||||
}
|
||||
|
||||
i += tdlen;
|
||||
|
@ -377,7 +378,7 @@ dvb_sdt_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
if(dllen > len)
|
||||
break;
|
||||
|
||||
if (!(t = dvb_service_find(dm->dm_tdmi, service_id, 0, NULL))) {
|
||||
if (!(t = dvb_service_find(dm, service_id, 0, NULL))) {
|
||||
len -= dllen;
|
||||
ptr += dllen;
|
||||
continue;
|
||||
|
@ -519,8 +520,8 @@ dvb_pat_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
|
||||
if(service != 0 && pmt != 0) {
|
||||
int save = 0;
|
||||
dvb_service_find2(dm->dm_tdmi, service, pmt, NULL, &save);
|
||||
if (save || ! dm->dm_tdmi->tdmi_adapter->tda_disable_pmt_monitor)
|
||||
dvb_service_find2(dm, service, pmt, NULL, &save);
|
||||
if (save || ! dm->dm_dn->dn_disable_pmt_monitor)
|
||||
dvb_table_add_pmt(dm, pmt);
|
||||
}
|
||||
ptr += 4;
|
||||
|
@ -623,7 +624,7 @@ dvb_table_cable_delivery(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
struct dvb_mux_conf dmc;
|
||||
int freq, symrate;
|
||||
|
||||
if(!dm->dm_tdmi->tdmi_adapter->tda_autodiscovery)
|
||||
if(!dm->dm_dn->dn_autodiscovery)
|
||||
return -1;
|
||||
|
||||
if(len < 11)
|
||||
|
@ -655,7 +656,7 @@ dvb_table_cable_delivery(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
|
||||
dmc.dmc_fe_params.u.qam.fec_inner = fec_tab[ptr[10] & 0x07];
|
||||
|
||||
dvb_mux_create(dm->dm_tdmi->tdmi_adapter, &dmc, onid, tsid, NULL,
|
||||
dvb_mux_create(dm->dm_dn, &dmc, onid, tsid, NULL,
|
||||
"automatic mux discovery", 1, 1, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
@ -671,7 +672,7 @@ dvb_table_sat_delivery(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
// uint16_t orbital_pos;
|
||||
struct dvb_mux_conf dmc;
|
||||
|
||||
if(!dm->dm_tdmi->tdmi_adapter->tda_autodiscovery)
|
||||
if(!dm->dm_dn->dn_autodiscovery)
|
||||
return -1;
|
||||
|
||||
if(len < 11)
|
||||
|
@ -738,7 +739,7 @@ dvb_table_sat_delivery(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
}
|
||||
|
||||
#endif
|
||||
dvb_mux_create(dm->dm_tdmi->tdmi_adapter, &dmc, onid, tsid, NULL,
|
||||
dvb_mux_create(dm->dm_dn, &dmc, onid, tsid, NULL,
|
||||
"automatic mux discovery", 1, 1, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
@ -767,7 +768,7 @@ dvb_table_local_channel(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
chan = ((ptr[2] & 3) << 8) | ptr[3];
|
||||
|
||||
if(chan != 0) {
|
||||
t = dvb_service_find(dm->dm_tdmi, sid, 0, NULL);
|
||||
t = dvb_service_find(dm, sid, 0, NULL);
|
||||
if(t != NULL) {
|
||||
|
||||
if(t->s_channel_number != chan) {
|
||||
|
@ -797,11 +798,11 @@ dvb_nit_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
uint16_t tsid, onid;
|
||||
uint16_t network_id = (ptr[0] << 8) | ptr[1];
|
||||
|
||||
if(dm->dm_tdmi->tdmi_adapter->tda_nitoid) {
|
||||
if(dm->dm_dn->dn_nitoid) {
|
||||
if(tableid != 0x41)
|
||||
return -1;
|
||||
|
||||
if(network_id != dm->dm_tdmi->tdmi_adapter->tda_nitoid)
|
||||
if(network_id != dm->dm_dn->dn_nitoid)
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
|
@ -943,7 +944,7 @@ atsc_vct_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
continue;
|
||||
|
||||
service_id = (ptr[24] << 8) | ptr[25];
|
||||
if((t = dvb_service_find(dm->dm_tdmi, service_id, 0, NULL)) == NULL)
|
||||
if((t = dvb_service_find(dm, service_id, 0, NULL)) == NULL)
|
||||
continue;
|
||||
|
||||
atsc_stype = ptr[27] & 0x3f;
|
||||
|
@ -987,18 +988,18 @@ dvb_pmt_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
int active = 0;
|
||||
service_t *t;
|
||||
th_dvb_table_t *tdt = opaque;
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
|
||||
LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) {
|
||||
LIST_FOREACH(t, &dm->dm_services, s_group_link) {
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
psi_parse_pmt(t, ptr, len, 1, 1);
|
||||
if (t->s_pmt_pid == tdt->tdt_pid && t->s_status == SERVICE_RUNNING)
|
||||
active = 1;
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
}
|
||||
|
||||
if (tdmi->tdmi_adapter->tda_disable_pmt_monitor && !active)
|
||||
dvb_tdt_destroy(tdmi->tdmi_adapter, tdmi, tdt);
|
||||
|
||||
if (dm->dm_dn->dn_disable_pmt_monitor && !active)
|
||||
dvb_tdt_destroy(dm->dm_current_tdmi->tdmi_adapter,
|
||||
dm->dm_current_tdmi, tdt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1014,7 +1015,7 @@ dvb_table_add_default_dvb(dvb_mux_t *dm)
|
|||
|
||||
int table;
|
||||
|
||||
if(dm->dm_tdmi->tdmi_adapter->tda_nitoid) {
|
||||
if(dm->dm_dn->dn_nitoid) {
|
||||
table = 0x41;
|
||||
} else {
|
||||
table = 0x40;
|
||||
|
@ -1095,7 +1096,7 @@ dvb_table_add_pmt(dvb_mux_t *dm, int pmt_pid)
|
|||
void
|
||||
dvb_table_rem_pmt(dvb_mux_t *dm, int pmt_pid)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_tdmi;
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
th_dvb_table_t *tdt = NULL;
|
||||
LIST_FOREACH(tdt, &dm->dm_tables, tdt_link)
|
||||
|
@ -1112,10 +1113,10 @@ dvb_table_rem_pmt(dvb_mux_t *dm, int pmt_pid)
|
|||
void
|
||||
dvb_table_flush_all(dvb_mux_t *dm)
|
||||
{
|
||||
th_dvb_adapter_t *tda = dm->dm_tdmi->tdmi_adapter;
|
||||
th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
th_dvb_table_t *tdt;
|
||||
|
||||
while((tdt = LIST_FIRST(&dm->dm_tables)) != NULL)
|
||||
dvb_tdt_destroy(tda, dm->dm_tdmi, tdt);
|
||||
|
||||
dvb_tdt_destroy(tda, tdmi, tdt);
|
||||
}
|
||||
|
|
|
@ -475,7 +475,7 @@ static int _eit_desc_crid
|
|||
} else {
|
||||
char *defauth = svc->s_default_authority;
|
||||
if (!defauth)
|
||||
defauth = svc->s_dvb_mux_instance->tdmi_mux->dm_default_authority;
|
||||
defauth = svc->s_dvb_mux->dm_default_authority;
|
||||
if (defauth)
|
||||
snprintf(crid, clen, "crid://%s%s", defauth, buf);
|
||||
}
|
||||
|
@ -544,8 +544,8 @@ static int _eit_process_event
|
|||
/* Override */
|
||||
if (!ev.default_charset) {
|
||||
ev.default_charset
|
||||
= dvb_charset_find(svc->s_dvb_mux_instance->tdmi_mux->dm_network_id,
|
||||
svc->s_dvb_mux_instance->tdmi_mux->dm_transport_stream_id,
|
||||
= dvb_charset_find(svc->s_dvb_mux->dm_network_id,
|
||||
svc->s_dvb_mux->dm_transport_stream_id,
|
||||
svc->s_dvb_service_id);
|
||||
}
|
||||
|
||||
|
@ -660,7 +660,6 @@ _eit_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
{
|
||||
epggrab_module_t *mod = opaque;
|
||||
epggrab_ota_mux_t *ota;
|
||||
th_dvb_adapter_t *tda;
|
||||
service_t *svc;
|
||||
eit_status_t *sta;
|
||||
eit_table_status_t *tsta;
|
||||
|
@ -713,9 +712,7 @@ _eit_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
// Note: tableid=0x4f,0x60-0x6f is other TS
|
||||
// so must find the tdmi
|
||||
if(tableid == 0x4f || tableid >= 0x60) {
|
||||
tda = dm->dm_tdmi->tdmi_adapter;
|
||||
th_dvb_mux_instance_t *tdmi = dvb_mux_find(tda, NULL, onid, tsid, 1);
|
||||
dm = tdmi->tdmi_mux;
|
||||
dm = dvb_mux_find(dm->dm_dn, NULL, onid, tsid, 1);
|
||||
|
||||
} else {
|
||||
if (dm->dm_transport_stream_id != tsid ||
|
||||
|
@ -732,7 +729,7 @@ _eit_callback(dvb_mux_t *dm, uint8_t *ptr, int len,
|
|||
if(!dm) goto done;
|
||||
|
||||
/* Get service */
|
||||
svc = dvb_service_find3(NULL, dm->dm_tdmi, NULL, 0, 0, sid, 1, 1);
|
||||
svc = dvb_service_find3(NULL, dm, NULL, 0, 0, sid, 1, 1);
|
||||
if (!svc || !svc->s_ch) goto done;
|
||||
|
||||
/* Register as interesting */
|
||||
|
|
|
@ -254,12 +254,11 @@ void epggrab_ota_create_and_register_by_id
|
|||
( epggrab_module_ota_t *mod, int onid, int tsid, int period, int interval,
|
||||
const char *networkname )
|
||||
{
|
||||
th_dvb_adapter_t *tda;
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
dvb_network_t *dn;
|
||||
dvb_mux_t *dm;
|
||||
epggrab_ota_mux_t *ota;
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) {
|
||||
LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) {
|
||||
dvb_mux_t *dm = tdmi->tdmi_mux;
|
||||
LIST_FOREACH(dn, &dvb_networks, dn_global_link) {
|
||||
LIST_FOREACH(dm, &dn->dn_muxes, dm_network_link) {
|
||||
if (dm->dm_transport_stream_id != tsid) continue;
|
||||
if (onid && dm->dm_network_id != onid) continue;
|
||||
if (networkname && (!dm->dm_network_name ||
|
||||
|
|
|
@ -227,7 +227,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
fd = tvh_socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
}
|
||||
if(fd == -1) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->s_identifier);
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->s_uuid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
if(ioctl(fd, SIOCGIFINDEX, &ifr)) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s",
|
||||
t->s_identifier, t->s_iptv_iface);
|
||||
t->s_uuid, t->s_iptv_iface);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &m, sizeof(struct ip_mreqn));
|
||||
if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot bind %s:%d -- %s",
|
||||
t->s_identifier, inet_ntoa(sin.sin_addr), t->s_iptv_port,
|
||||
t->s_uuid, inet_ntoa(sin.sin_addr), t->s_iptv_port,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
|
@ -265,7 +265,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
if(setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m,
|
||||
sizeof(struct ip_mreqn)) == -1) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot join %s -- %s",
|
||||
t->s_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno));
|
||||
t->s_uuid, inet_ntoa(m.imr_multiaddr), strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
if(bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) == -1) {
|
||||
inet_ntop(AF_INET6, &sin6.sin6_addr, straddr, sizeof(straddr));
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot bind %s:%d -- %s",
|
||||
t->s_identifier, straddr, t->s_iptv_port,
|
||||
t->s_uuid, straddr, t->s_iptv_port,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
|
@ -294,7 +294,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
inet_ntop(AF_INET6, m6.ipv6mr_multiaddr.s6_addr,
|
||||
straddr, sizeof(straddr));
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot join %s -- %s",
|
||||
t->s_identifier, straddr, strerror(errno));
|
||||
t->s_uuid, straddr, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ iptv_service_start(service_t *t, unsigned int weight, int force_start)
|
|||
ev.data.fd = fd;
|
||||
if(epoll_ctl(iptv_epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot add to epoll set -- %s",
|
||||
t->s_identifier, strerror(errno));
|
||||
t->s_uuid, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ iptv_service_stop(service_t *t)
|
|||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
if(ioctl(t->s_iptv_fd, SIOCGIFINDEX, &ifr)) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s",
|
||||
t->s_identifier, t->s_iptv_iface);
|
||||
t->s_uuid, t->s_iptv_iface);
|
||||
}
|
||||
|
||||
if(t->s_iptv_group.s_addr != 0) {
|
||||
|
@ -371,7 +371,7 @@ iptv_service_stop(service_t *t)
|
|||
if(setsockopt(t->s_iptv_fd, SOL_IP, IP_DROP_MEMBERSHIP, &m,
|
||||
sizeof(struct ip_mreqn)) == -1) {
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s",
|
||||
t->s_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno));
|
||||
t->s_uuid, inet_ntoa(m.imr_multiaddr), strerror(errno));
|
||||
}
|
||||
} else {
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
|
@ -388,7 +388,7 @@ iptv_service_stop(service_t *t)
|
|||
straddr, sizeof(straddr));
|
||||
|
||||
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s",
|
||||
t->s_identifier, straddr, strerror(errno));
|
||||
t->s_uuid, straddr, strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
|
@ -441,27 +441,12 @@ iptv_service_save(service_t *t)
|
|||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
||||
hts_settings_save(m, "iptvservices/%s",
|
||||
t->s_identifier);
|
||||
t->s_uuid);
|
||||
|
||||
htsmsg_destroy(m);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
iptv_service_quality(service_t *t)
|
||||
{
|
||||
if(t->s_iptv_iface == NULL ||
|
||||
(t->s_iptv_group.s_addr == 0 && t->s_iptv_group6.s6_addr == 0) ||
|
||||
t->s_iptv_port == 0)
|
||||
return 0;
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a descriptive name for the source
|
||||
*/
|
||||
|
@ -499,7 +484,7 @@ iptv_grace_period(service_t *t)
|
|||
static void
|
||||
iptv_service_dtor(service_t *t)
|
||||
{
|
||||
hts_settings_remove("iptvservices/%s", t->s_identifier);
|
||||
hts_settings_remove("iptvservices/%s", t->s_uuid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -519,7 +504,7 @@ iptv_service_find(const char *id, int create)
|
|||
return NULL;
|
||||
|
||||
LIST_FOREACH(t, &iptv_all_services, s_group_link)
|
||||
if(!strcmp(t->s_identifier, id))
|
||||
if(!strcmp(t->s_uuid, id))
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -534,7 +519,7 @@ iptv_service_find(const char *id, int create)
|
|||
tally = MAX(atoi(id + 5), tally);
|
||||
}
|
||||
|
||||
t = service_create(id, SERVICE_TYPE_IPTV, S_MPEG_TS);
|
||||
t = service_create(id, S_MPEG_TS);
|
||||
|
||||
t->s_servicetype = ST_SDTV;
|
||||
t->s_start_feed = iptv_service_start;
|
||||
|
@ -542,7 +527,6 @@ iptv_service_find(const char *id, int create)
|
|||
t->s_stop_feed = iptv_service_stop;
|
||||
t->s_config_save = iptv_service_save;
|
||||
t->s_setsourceinfo = iptv_service_setsourceinfo;
|
||||
t->s_quality_index = iptv_service_quality;
|
||||
t->s_grace_period = iptv_grace_period;
|
||||
t->s_dtor = iptv_service_dtor;
|
||||
t->s_iptv_fd = -1;
|
||||
|
|
|
@ -83,17 +83,6 @@ rawts_service_save(service_t *t)
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
rawts_service_quality(service_t *t)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a descriptive name for the source
|
||||
*/
|
||||
|
@ -123,7 +112,7 @@ rawts_service_add(rawts_t *rt, uint16_t sid, int pmt_pid)
|
|||
|
||||
snprintf(tmp, sizeof(tmp), "%s_%04x", rt->rt_identifier, sid);
|
||||
|
||||
t = service_create(tmp, SERVICE_TYPE_DVB, S_MPEG_TS);
|
||||
t = service_create(tmp, S_MPEG_TS);
|
||||
t->s_flags |= S_DEBUG;
|
||||
|
||||
t->s_dvb_service_id = sid;
|
||||
|
@ -133,7 +122,6 @@ rawts_service_add(rawts_t *rt, uint16_t sid, int pmt_pid)
|
|||
t->s_stop_feed = rawts_service_stop;
|
||||
t->s_config_save = rawts_service_save;
|
||||
t->s_setsourceinfo = rawts_service_setsourceinfo;
|
||||
t->s_quality_index = rawts_service_quality;
|
||||
|
||||
t->s_svcname = strdup(tmp);
|
||||
|
||||
|
|
164
src/service.c
164
src/service.c
|
@ -231,86 +231,6 @@ service_start(service_t *t, unsigned int weight, int force_start)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
dvb_extra_prio(th_dvb_adapter_t *tda)
|
||||
{
|
||||
return tda->tda_extrapriority + tda->tda_hostconnection * 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return prio for the given service
|
||||
*/
|
||||
static int
|
||||
service_get_prio(service_t *t)
|
||||
{
|
||||
switch(t->s_type) {
|
||||
case SERVICE_TYPE_DVB:
|
||||
return (t->s_scrambled ? 300 : 100) +
|
||||
dvb_extra_prio(t->s_dvb_mux_instance->tdmi_adapter);
|
||||
|
||||
case SERVICE_TYPE_IPTV:
|
||||
return 200;
|
||||
|
||||
case SERVICE_TYPE_V4L:
|
||||
return 400;
|
||||
|
||||
default:
|
||||
return 500;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return quality index for given service
|
||||
*
|
||||
* We invert the result (providers say that negative numbers are worse)
|
||||
*
|
||||
* But for sorting, we want low numbers first
|
||||
*
|
||||
* Also, we bias and trim with an offset of two to avoid counting any
|
||||
* transient errors.
|
||||
*/
|
||||
|
||||
static int
|
||||
service_get_quality(service_t *t)
|
||||
{
|
||||
return t->s_quality_index ? -MIN(t->s_quality_index(t) + 2, 0) : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* a - b -> lowest number first
|
||||
*/
|
||||
static int
|
||||
servicecmp(const void *A, const void *B)
|
||||
{
|
||||
service_t *a = *(service_t **)A;
|
||||
service_t *b = *(service_t **)B;
|
||||
|
||||
/* only check quality if both adapters have the same prio
|
||||
*
|
||||
* there needs to be a much more sophisticated algorithm to take priority and quality into account
|
||||
* additional, it may be problematic, since a higher priority value lowers the ranking
|
||||
*
|
||||
*/
|
||||
int prio_a = service_get_prio(a);
|
||||
int prio_b = service_get_prio(b);
|
||||
if (prio_a == prio_b) {
|
||||
|
||||
int q = service_get_quality(a) - service_get_quality(b);
|
||||
|
||||
if(q != 0)
|
||||
return q; /* Quality precedes priority */
|
||||
}
|
||||
|
||||
return prio_a - prio_b;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -351,7 +271,7 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo,
|
|||
/* Sort services, lower priority should come come earlier in the vector
|
||||
(i.e. it will be more favoured when selecting a service */
|
||||
|
||||
qsort(vec, cnt, sizeof(service_t *), servicecmp);
|
||||
// qsort(vec, cnt, sizeof(service_t *), servicecmp);
|
||||
|
||||
// Skip up to the service that the caller didn't want
|
||||
// If the sorting above is not stable that might mess up things
|
||||
|
@ -371,15 +291,6 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo,
|
|||
t = vec[i];
|
||||
if(t->s_status == SERVICE_RUNNING)
|
||||
return t;
|
||||
if(t->s_quality_index(t) < 10) {
|
||||
if(loginfo != NULL) {
|
||||
tvhlog(LOG_NOTICE, "Service",
|
||||
"%s: Skipping \"%s\" -- Quality below 10%%",
|
||||
loginfo, service_nicename(t));
|
||||
err = SM_CODE_BAD_SIGNAL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
tvhlog(LOG_DEBUG, "Service", "%s: Probing adapter \"%s\" without stealing for service \"%s\"",
|
||||
loginfo, service_adapter_nicename(t), service_nicename(t));
|
||||
if((r = service_start(t, 0, 0)) == 0)
|
||||
|
@ -487,7 +398,7 @@ service_destroy(service_t *t)
|
|||
|
||||
t->s_status = SERVICE_ZOMBIE;
|
||||
|
||||
free(t->s_identifier);
|
||||
free(t->s_uuid);
|
||||
free(t->s_svcname);
|
||||
free(t->s_provider);
|
||||
free(t->s_dvb_charset);
|
||||
|
@ -516,17 +427,16 @@ service_destroy(service_t *t)
|
|||
* Create and initialize a new service struct
|
||||
*/
|
||||
service_t *
|
||||
service_create(const char *identifier, int type, int source_type)
|
||||
service_create(const char *uuid, int source_type)
|
||||
{
|
||||
unsigned int hash = tvh_strhash(identifier, SERVICE_HASH_WIDTH);
|
||||
unsigned int hash = tvh_strhash(uuid, SERVICE_HASH_WIDTH);
|
||||
service_t *t = calloc(1, sizeof(service_t));
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
pthread_mutex_init(&t->s_stream_mutex, NULL);
|
||||
pthread_cond_init(&t->s_tss_cond, NULL);
|
||||
t->s_identifier = strdup(identifier);
|
||||
t->s_type = type;
|
||||
t->s_uuid = strdup(uuid);
|
||||
t->s_source_type = source_type;
|
||||
t->s_refcount = 1;
|
||||
t->s_enabled = 1;
|
||||
|
@ -555,7 +465,7 @@ service_find_by_identifier(const char *identifier)
|
|||
lock_assert(&global_lock);
|
||||
|
||||
LIST_FOREACH(t, &servicehash[hash], s_hash_link)
|
||||
if(!strcmp(t->s_identifier, identifier))
|
||||
if(!strcmp(t->s_uuid, identifier))
|
||||
break;
|
||||
return t;
|
||||
}
|
||||
|
@ -1061,25 +971,7 @@ service_component_nicename(elementary_stream_t *st)
|
|||
const char *
|
||||
service_adapter_nicename(service_t *t)
|
||||
{
|
||||
switch(t->s_type) {
|
||||
case SERVICE_TYPE_DVB:
|
||||
if(t->s_dvb_mux_instance)
|
||||
return t->s_dvb_mux_instance->tdmi_identifier;
|
||||
else
|
||||
return "Unknown adapter";
|
||||
|
||||
case SERVICE_TYPE_IPTV:
|
||||
return t->s_iptv_iface;
|
||||
|
||||
case SERVICE_TYPE_V4L:
|
||||
if(t->s_v4l_adapter)
|
||||
return t->s_v4l_adapter->va_displayname;
|
||||
else
|
||||
return "Unknown adapter";
|
||||
|
||||
default:
|
||||
return "Unknown adapter";
|
||||
}
|
||||
return "Adapter";
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -1140,6 +1032,45 @@ service_refresh_channel(service_t *t)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
ssc_cmp(const service_start_cand_t *a,
|
||||
const service_start_cand_t *b)
|
||||
{
|
||||
return a->ssc_prio - b->ssc_prio;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
service_start_cand_t *
|
||||
service_find_cand(struct service_start_cand_list *sscl,
|
||||
struct service *s, int instance, int prio)
|
||||
{
|
||||
service_start_cand_t *ssc;
|
||||
LIST_FOREACH(ssc, sscl, ssc_link) {
|
||||
if(ssc->ssc_s == s && ssc->ssc_instance == instance)
|
||||
break;
|
||||
}
|
||||
|
||||
if(ssc != NULL) {
|
||||
ssc = calloc(1, sizeof(service_start_cand_t));
|
||||
ssc->ssc_s = s;
|
||||
service_ref(s);
|
||||
ssc->ssc_instance = instance;
|
||||
} else {
|
||||
if(ssc->ssc_prio == prio)
|
||||
return ssc;
|
||||
LIST_REMOVE(ssc, ssc_link);
|
||||
}
|
||||
ssc->ssc_prio = prio;
|
||||
LIST_INSERT_SORTED(sscl, ssc, ssc_link, ssc_cmp);
|
||||
return ssc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the encryption CAID from a service
|
||||
* only the first CA stream in a service is returned
|
||||
|
@ -1174,9 +1105,8 @@ service_is_primary_epg(service_t *svc)
|
|||
service_t *ret = NULL, *t;
|
||||
if (!svc || !svc->s_ch) return 0;
|
||||
LIST_FOREACH(t, &svc->s_ch->ch_services, s_ch_link) {
|
||||
if (!t->s_dvb_mux_instance) continue;
|
||||
if (!t->s_enabled || !t->s_dvb_eit_enable) continue;
|
||||
if (!ret || service_get_prio(t) < service_get_prio(ret))
|
||||
if (!ret)
|
||||
ret = t;
|
||||
}
|
||||
return !ret ? 0 : (ret->s_dvb_service_id == svc->s_dvb_service_id);
|
||||
|
|
|
@ -167,6 +167,36 @@ typedef struct elementary_stream {
|
|||
} elementary_stream_t;
|
||||
|
||||
|
||||
LIST_HEAD(service_start_cand_list, service_start_cand);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef struct service_start_cand {
|
||||
|
||||
LIST_ENTRY(service_start_cand) ssc_link;
|
||||
|
||||
int ssc_prio;
|
||||
|
||||
struct service *ssc_s; // A reference is held
|
||||
int ssc_instance; // Discriminator when having multiple adapters, etc
|
||||
|
||||
int ssc_error_code; // Set if we deem this cand to be broken
|
||||
time_t ssc_err_time; // Time we detected it was broken
|
||||
|
||||
int ssc_weight; // Highest weight that holds this cand
|
||||
|
||||
} service_start_cand_t;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
service_start_cand_t *service_find_cand(struct service_start_cand_list *sscl,
|
||||
struct service *s,
|
||||
int instance,
|
||||
int prio);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -174,12 +204,6 @@ typedef struct service {
|
|||
|
||||
LIST_ENTRY(service) s_hash_link;
|
||||
|
||||
enum {
|
||||
SERVICE_TYPE_DVB,
|
||||
SERVICE_TYPE_IPTV,
|
||||
SERVICE_TYPE_V4L,
|
||||
} s_type;
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Transport is idle.
|
||||
|
@ -262,6 +286,10 @@ typedef struct service {
|
|||
|
||||
LIST_HEAD(, th_subscription) s_subscriptions;
|
||||
|
||||
void (*s_enlist)(struct service *s,
|
||||
struct service_start_cand_list *sscl);
|
||||
|
||||
|
||||
int (*s_start_feed)(struct service *t, unsigned int weight,
|
||||
int force_start);
|
||||
|
||||
|
@ -273,8 +301,6 @@ typedef struct service {
|
|||
|
||||
void (*s_setsourceinfo)(struct service *t, struct source_info *si);
|
||||
|
||||
int (*s_quality_index)(struct service *t);
|
||||
|
||||
int (*s_grace_period)(struct service *t);
|
||||
|
||||
void (*s_dtor)(struct service *t);
|
||||
|
@ -282,12 +308,12 @@ typedef struct service {
|
|||
/*
|
||||
* Per source type structs
|
||||
*/
|
||||
struct th_dvb_mux_instance *s_dvb_mux_instance;
|
||||
struct dvb_mux *s_dvb_mux;
|
||||
|
||||
/**
|
||||
* Unique identifer (used for storing on disk, etc)
|
||||
* Unique identifer
|
||||
*/
|
||||
char *s_identifier;
|
||||
char *s_uuid;
|
||||
|
||||
/**
|
||||
* Name usable for displaying to user
|
||||
|
@ -520,8 +546,7 @@ unsigned int service_compute_weight(struct service_list *head);
|
|||
|
||||
int service_start(service_t *t, unsigned int weight, int force_start);
|
||||
|
||||
service_t *service_create(const char *identifier, int type,
|
||||
int source_type);
|
||||
service_t *service_create(const char *uuid, int source_type);
|
||||
|
||||
void service_unref(service_t *t);
|
||||
|
||||
|
|
|
@ -108,7 +108,8 @@ serviceprobe_thread(void *aux)
|
|||
was_doing_work = 1;
|
||||
}
|
||||
|
||||
checksubscr = !t->s_dvb_mux_instance->tdmi_adapter->tda_skip_checksubscr;
|
||||
// XXX(dvbreorg)
|
||||
checksubscr = 1; // !t->s_dvb_mux->tdmi_adapter->tda_skip_checksubscr;
|
||||
|
||||
if (checksubscr) {
|
||||
tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...",
|
||||
|
@ -176,10 +177,10 @@ serviceprobe_thread(void *aux)
|
|||
} else if(t->s_ch == NULL) {
|
||||
int channum = t->s_channel_number;
|
||||
const char *str;
|
||||
|
||||
#if 0 // XXX(dvbreorg)
|
||||
if (!channum && t->s_dvb_mux_instance->tdmi_adapter->tda_sidtochan)
|
||||
channum = t->s_dvb_service_id;
|
||||
|
||||
#endif
|
||||
ch = channel_find_by_name(t->s_svcname, 1, channum);
|
||||
service_map_channel(t, ch, 1);
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ hts_settings_load_one(const char *filename)
|
|||
*
|
||||
*/
|
||||
static htsmsg_t *
|
||||
_hts_settings_load(const char *fullpath)
|
||||
hts_settings_load_path(const char *fullpath, int depth)
|
||||
{
|
||||
char child[256];
|
||||
struct filebundle_stat st;
|
||||
|
@ -237,9 +237,16 @@ _hts_settings_load(const char *fullpath)
|
|||
for(i = 0; i < n; i++) {
|
||||
d = namelist[i];
|
||||
if(d->name[0] != '.') {
|
||||
snprintf(child, sizeof(child), "%s/%s", fullpath, d->name);
|
||||
if ((c = hts_settings_load_one(child)))
|
||||
|
||||
snprintf(child, sizeof(child), "%s/%s", fullpath, d->name);
|
||||
if(d->type == FB_DIR && depth > 0) {
|
||||
c = hts_settings_load_path(child, depth - 1);
|
||||
} else {
|
||||
c = hts_settings_load_one(child);
|
||||
}
|
||||
if(c != NULL)
|
||||
htsmsg_add_msg(r, d->name, c);
|
||||
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
|
@ -256,32 +263,56 @@ _hts_settings_load(const char *fullpath)
|
|||
/**
|
||||
*
|
||||
*/
|
||||
htsmsg_t *
|
||||
hts_settings_load(const char *pathfmt, ...)
|
||||
static htsmsg_t *
|
||||
hts_settings_vload(const char *pathfmt, va_list ap, int depth)
|
||||
{
|
||||
htsmsg_t *ret = NULL;
|
||||
char fullpath[256];
|
||||
va_list ap;
|
||||
va_list ap2;
|
||||
va_copy(ap2, ap);
|
||||
|
||||
/* Try normal path */
|
||||
va_start(ap, pathfmt);
|
||||
hts_settings_buildpath(fullpath, sizeof(fullpath),
|
||||
hts_settings_buildpath(fullpath, sizeof(fullpath),
|
||||
pathfmt, ap, settingspath);
|
||||
va_end(ap);
|
||||
ret = _hts_settings_load(fullpath);
|
||||
ret = hts_settings_load_path(fullpath, depth);
|
||||
|
||||
/* Try bundle path */
|
||||
if (!ret && *pathfmt != '/') {
|
||||
va_start(ap, pathfmt);
|
||||
hts_settings_buildpath(fullpath, sizeof(fullpath),
|
||||
pathfmt, ap, "data/conf");
|
||||
va_end(ap);
|
||||
ret = _hts_settings_load(fullpath);
|
||||
pathfmt, ap2, "data/conf");
|
||||
ret = hts_settings_load_path(fullpath, depth);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
htsmsg_t *
|
||||
hts_settings_load(const char *pathfmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, pathfmt);
|
||||
htsmsg_t *r = hts_settings_vload(pathfmt, ap, 0);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
htsmsg_t *
|
||||
hts_settings_load_r(int depth, const char *pathfmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, pathfmt);
|
||||
htsmsg_t *r = hts_settings_vload(pathfmt, ap, depth);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -28,6 +28,8 @@ void hts_settings_save(htsmsg_t *record, const char *pathfmt, ...);
|
|||
|
||||
htsmsg_t *hts_settings_load(const char *pathfmt, ...);
|
||||
|
||||
htsmsg_t *hts_settings_load_r(int depth, const char *pathfmt, ...);
|
||||
|
||||
void hts_settings_remove(const char *pathfmt, ...);
|
||||
|
||||
const char *hts_settings_get_root(void);
|
||||
|
|
|
@ -385,14 +385,13 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight,
|
|||
tvhlog(LOG_INFO, "subscription",
|
||||
"\"%s\" subscribing on \"%s\", weight: %d, adapter: \"%s\", "
|
||||
"network: \"%s\", mux: \"%s\", provider: \"%s\", "
|
||||
"service: \"%s\", quality: %d",
|
||||
"service: \"%s\"",
|
||||
s->ths_title, ch->ch_name, weight,
|
||||
si.si_adapter ?: "<N/A>",
|
||||
si.si_network ?: "<N/A>",
|
||||
si.si_mux ?: "<N/A>",
|
||||
si.si_provider ?: "<N/A>",
|
||||
si.si_service ?: "<N/A>",
|
||||
s->ths_service->s_quality_index(s->ths_service));
|
||||
si.si_service ?: "<N/A>");
|
||||
|
||||
service_source_info_free(&si);
|
||||
}
|
||||
|
@ -432,14 +431,13 @@ subscription_create_from_service(service_t *t, const char *name,
|
|||
tvhlog(LOG_INFO, "subscription",
|
||||
"\"%s\" direct subscription to adapter: \"%s\", "
|
||||
"network: \"%s\", mux: \"%s\", provider: \"%s\", "
|
||||
"service: \"%s\", quality: %d",
|
||||
"service: \"%s\"",
|
||||
s->ths_title,
|
||||
si.si_adapter ?: "<N/A>",
|
||||
si.si_network ?: "<N/A>",
|
||||
si.si_mux ?: "<N/A>",
|
||||
si.si_provider ?: "<N/A>",
|
||||
si.si_service ?: "<N/A>",
|
||||
t->s_quality_index(t));
|
||||
si.si_service ?: "<N/A>");
|
||||
service_source_info_free(&si);
|
||||
|
||||
subscription_link_service(s, t);
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct source_info {
|
|||
int si_type;
|
||||
} source_info_t;
|
||||
|
||||
|
||||
static inline void
|
||||
lock_assert0(pthread_mutex_t *l, const char *file, int line)
|
||||
{
|
||||
|
|
|
@ -289,7 +289,7 @@ v4l_service_save(service_t *t)
|
|||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
||||
hts_settings_save(m, "v4lservices/%s/%s",
|
||||
va->va_identifier, t->s_identifier);
|
||||
va->va_identifier, t->s_uuid);
|
||||
|
||||
htsmsg_destroy(m);
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ v4l_service_find(v4l_adapter_t *va, const char *id, int create)
|
|||
return NULL;
|
||||
|
||||
LIST_FOREACH(t, &va->va_services, s_group_link)
|
||||
if(!strcmp(t->s_identifier, id))
|
||||
if(!strcmp(t->s_uuid, id))
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -364,7 +364,7 @@ v4l_service_find(v4l_adapter_t *va, const char *id, int create)
|
|||
va->va_tally = MAX(atoi(id + vaidlen + 1), va->va_tally);
|
||||
}
|
||||
|
||||
t = service_create(id, SERVICE_TYPE_V4L, 0);
|
||||
t = service_create(id, 0);
|
||||
|
||||
t->s_start_feed = v4l_service_start;
|
||||
t->s_refresh_feed = v4l_service_refresh;
|
||||
|
|
|
@ -1669,7 +1669,7 @@ build_record_iptv(service_t *t)
|
|||
htsmsg_t *r = htsmsg_create_map();
|
||||
char abuf[INET_ADDRSTRLEN];
|
||||
char abuf6[INET6_ADDRSTRLEN];
|
||||
htsmsg_add_str(r, "id", t->s_identifier);
|
||||
htsmsg_add_str(r, "id", t->s_uuid);
|
||||
|
||||
htsmsg_add_str(r, "channelname", t->s_ch ? t->s_ch->ch_name : "");
|
||||
htsmsg_add_str(r, "interface", t->s_iptv_iface ?: "");
|
||||
|
@ -1828,7 +1828,7 @@ extjs_tvadapter(http_connection_t *hc, const char *remain, void *opaque)
|
|||
array = htsmsg_create_list();
|
||||
|
||||
#if ENABLE_LINUXDVB
|
||||
extjs_list_dvb_adapters(array);
|
||||
// extjs_list_dvb_adapters(array);
|
||||
#endif
|
||||
|
||||
#if ENABLE_V4L
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
#include "dvb/dvb_preconf.h"
|
||||
#include "dvr/dvr.h"
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -685,6 +689,7 @@ extjs_list_dvb_adapters(htsmsg_t *array)
|
|||
htsmsg_add_msg(array, NULL, dvb_adapter_build_msg(tda));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -741,11 +746,12 @@ extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque)
|
|||
void
|
||||
extjs_start_dvb(void)
|
||||
{
|
||||
http_path_add("/dvb/networks",
|
||||
NULL, extjs_dvbnetworks, ACCESS_WEB_INTERFACE);
|
||||
#if 0
|
||||
http_path_add("/dvb/locations",
|
||||
NULL, extjs_dvblocations, ACCESS_WEB_INTERFACE);
|
||||
|
||||
http_path_add("/dvb/networks",
|
||||
NULL, extjs_dvbnetworks, ACCESS_WEB_INTERFACE);
|
||||
|
||||
http_path_add("/dvb/adapter",
|
||||
NULL, extjs_dvbadapter, ACCESS_ADMIN);
|
||||
|
@ -767,7 +773,6 @@ extjs_start_dvb(void)
|
|||
|
||||
http_path_add("/dvb/addmux",
|
||||
NULL, extjs_dvb_addmux, ACCESS_ADMIN);
|
||||
#if 0 // XXX(dvbreorg)
|
||||
http_path_add("/dvb/copymux",
|
||||
NULL, extjs_dvb_copymux, ACCESS_ADMIN);
|
||||
#endif
|
||||
|
|
|
@ -76,6 +76,7 @@ dumpchannels(htsbuf_queue_t *hq)
|
|||
}
|
||||
|
||||
#if ENABLE_LINUXDVB
|
||||
#if 0
|
||||
static void
|
||||
dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent)
|
||||
{
|
||||
|
@ -119,6 +120,7 @@ dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent)
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -126,23 +128,11 @@ static void
|
|||
dumpdvbadapters(htsbuf_queue_t *hq)
|
||||
{
|
||||
th_dvb_adapter_t *tda;
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
|
||||
outputtitle(hq, 0, "DVB Adapters");
|
||||
|
||||
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) {
|
||||
htsbuf_qprintf(hq, "%s (%s)\n", tda->tda_displayname, tda->tda_identifier);
|
||||
|
||||
outputtitle(hq, 4, "Multiplexes");
|
||||
LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) {
|
||||
char tdminame[64];
|
||||
dvb_mux_nicename(tdminame, sizeof(tdminame), tdmi);
|
||||
htsbuf_qprintf(hq, " %s (%s)\n",
|
||||
tdminame, tdmi->tdmi_identifier);
|
||||
|
||||
htsbuf_qprintf(hq, "\n");
|
||||
dumptransports(hq, &tdmi->tdmi_mux->dm_services, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -606,7 +606,7 @@ http_stream_tdmi(http_connection_t *hc, th_dvb_mux_instance_t *tdmi)
|
|||
streaming_queue_init(&sq, SMT_PACKET);
|
||||
|
||||
s = dvb_subscription_create_from_tdmi(tdmi, "HTTP", &sq.sq_st);
|
||||
name = strdupa(tdmi->tdmi_identifier);
|
||||
name = strdupa(tdmi->tdmi_mux->dm_uuid);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
http_stream_run(hc, &sq, name, MC_PASS);
|
||||
pthread_mutex_lock(&global_lock);
|
||||
|
@ -723,7 +723,7 @@ http_stream(http_connection_t *hc, const char *remain, void *opaque)
|
|||
} else if(!strcmp(components[0], "service")) {
|
||||
service = service_find_by_identifier(components[1]);
|
||||
} else if(!strcmp(components[0], "mux")) {
|
||||
tdmi = dvb_mux_find_by_identifier(components[1]);
|
||||
tdmi = NULL; // dvb_mux_find_by_identifier(components[1]);
|
||||
}
|
||||
|
||||
if(ch != NULL) {
|
||||
|
|
Loading…
Add table
Reference in a new issue