const char *logprefix, int enabled,
int initialscan, const char *uuid);
+int dvb_mux_tune(dvb_mux_t *dm, const char *reason, int weight);
+
void dvb_mux_set_networkname(dvb_mux_t *dm, const char *name);
void dvb_mux_set_tsid(dvb_mux_t *dm, uint16_t tsid);
void dvb_mux_initial_scan_done(dvb_mux_t *dm);
-/**
- * DVB Transport (aka DVB service)
- */
-void dvb_tdmi_destroy(th_dvb_mux_instance_t *tdmi);
+int dvb_fe_tune_tdmi(th_dvb_mux_instance_t *tdmi);
+
/**
* DVB Transport (aka DVB service)
/**
* DVB Frontend
*/
-int dvb_fe_tune(dvb_mux_t *dm, const char *reason, int weight);
//void dvb_fe_stop(th_dvb_adapter_t *tda, int retune);
fe_status_t fe_status;
int status, v, vv, i, fec, q;
th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi;
- char buf[50];
signal_status_t sigstat;
streaming_message_t sm;
struct service *t;
if(status != tdmi->tdmi_fe_status) {
tdmi->tdmi_fe_status = status;
- 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));
+ dvb_mux_nicename(tdmi->tdmi_mux), tda->tda_displayname,
+ dvb_mux_status(tdmi));
notify = 1;
}
#endif
-/**
- * These are created on the fly
- */
-static void
-dvb_create_tdmis(dvb_mux_t *dm)
-{
- th_dvb_mux_instance_t *tdmi;
- dvb_network_t *dn = dm->dm_dn;
- th_dvb_adapter_t *tda;
-
- LIST_FOREACH(tda, &dn->dn_adapters, tda_network_link) {
-
- LIST_FOREACH(tdmi, &dm->dm_tdmis, tdmi_mux_link) {
- if(tdmi->tdmi_adapter != NULL)
- break;
- }
-
- if(tdmi == NULL) {
- tdmi = calloc(1, sizeof(th_dvb_mux_instance_t));
- tdmi->tdmi_adapter = tda;
- tdmi->tdmi_mux = dm;
- LIST_INSERT_HEAD(&tda->tda_tdmis, tdmi, tdmi_adapter_link);
- LIST_INSERT_HEAD(&dm->dm_tdmis, tdmi, tdmi_mux_link);
- }
- }
-}
-
-
-/**
- *
- */
-static void
-dvb_mux_stop(th_dvb_mux_instance_t *tdmi)
+int
+dvb_fe_tune_tdmi(th_dvb_mux_instance_t *tdmi)
{
- dvb_mux_t *dm = tdmi->tdmi_mux;
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
- assert(dm->dm_current_tdmi == tdmi);
- assert(tda->tda_current_tdmi == tdmi);
-
- dvb_table_flush_all(dm);
- epggrab_mux_stop(dm, 0);
-
- assert(dm->dm_scan_status == DM_SCAN_DONE);
-
- dm->dm_current_tdmi = NULL;
- tda->tda_current_tdmi = NULL;
-
- printf("NEED TO TAKE CARE OF SERVICES in dvb_mux_stop\n");
-}
-
-
-/**
- *
- */
-static int
-tdmi_compute_weight(const th_dvb_mux_instance_t *tdmi)
-{
const dvb_mux_t *dm = tdmi->tdmi_mux;
- if(dm->dm_scan_status == DM_SCAN_CURRENT)
- return 1;
- return 0;
-}
-
-
-/**
- *
- */
-static void
-dvb_mux_initial_scan_timeout(void *aux)
-{
- dvb_mux_t *dm = aux;
- char buf[100];
-
- dvb_mux_nicename(buf, sizeof(buf), dm);
- tvhlog(LOG_DEBUG, "dvb", "Initial scan timed out for \"%s\"", buf);
-
- dvb_mux_initial_scan_done(dm);
-}
-
-
-/**
- *
- */
-int
-dvb_fe_tune(dvb_mux_t *dm, const char *reason, int weight)
-{
- dvb_network_t *dn = dm->dm_dn;
-
// copy dmc, cause frequency may be change with FE_QPSK
dvb_mux_conf_t dmc = dm->dm_conf;
dvb_frontend_parameters_t* p = &dmc.dmc_fe_params;
- th_dvb_mux_instance_t *tdmi;
-
- char buf[256];
int r;
-
- assert(dm->dm_current_tdmi == NULL);
-
- lock_assert(&global_lock);
-
- dvb_create_tdmis(dm);
-
- retry:
- // Figure which adapter to use
- LIST_FOREACH(tdmi, &dm->dm_tdmis, tdmi_mux_link)
- if(!tdmi->tdmi_tune_failed && tdmi->tdmi_adapter->tda_current_tdmi == NULL)
- break;
-
- if(tdmi == NULL) {
- // None available, need to strike one out
- LIST_FOREACH(tdmi, &dm->dm_tdmis, tdmi_mux_link) {
- if(tdmi->tdmi_tune_failed)
- continue;
-
- th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
- th_dvb_mux_instance_t *t2 = tda->tda_current_tdmi;
- assert(t2 != NULL);
- assert(t2 != tdmi);
-
- if(tdmi_compute_weight(t2) < weight) {
- dvb_mux_stop(t2);
- break;
- }
- }
-
- if(tdmi == NULL)
- return SM_CODE_NO_FREE_ADAPTER;
-
- }
-
- th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+ char buf[256];
dvb_adapter_start(tda);
assert(tda->tda_current_tdmi == NULL);
- free(tda->tda_tune_reason);
- tda->tda_tune_reason = strdup(reason);
- tdmi->tdmi_weight = weight;
if(tda->tda_fe_type == FE_QPSK) {
tvhlog(LOG_ERR, "dvb", "diseqc setup failed %d\n", r);
}
- dvb_mux_nicename(buf, sizeof(buf), tdmi->tdmi_mux);
-
tda->tda_fe_monitor_hold = 4;
-
#if DVB_API_VERSION >= 5
if (tda->tda_fe_type == FE_QPSK) {
tvhlog(LOG_DEBUG, "dvb", "\"%s\" tuning via s2api to \"%s\" (%d, %d Baud, "
- "%s, %s, %s) for %s", tda->tda_rootpath, buf, p->frequency, p->u.qpsk.symbol_rate,
- dvb_mux_fec2str(p->u.qpsk.fec_inner), dvb_mux_delsys2str(dmc.dmc_fe_delsys),
- dvb_mux_qam2str(dmc.dmc_fe_modulation), reason);
-
+ "%s, %s, %s)", tda->tda_rootpath, buf, p->frequency, p->u.qpsk.symbol_rate,
+ dvb_mux_fec2str(p->u.qpsk.fec_inner), dvb_mux_delsys2str(dmc.dmc_fe_delsys),
+ dvb_mux_qam2str(dmc.dmc_fe_modulation));
r = dvb_fe_tune_s2(tda, &dmc);
} else
#endif
{
- tvhlog(LOG_DEBUG, "dvb", "\"%s\" tuning to \"%s\" (%s) fd:%d", tda->tda_rootpath, buf, reason, tda->tda_fe_fd);
+ tvhlog(LOG_DEBUG, "dvb", "\"%s\" tuning to \"%s\"",
+ tda->tda_rootpath, dvb_mux_nicename(dm));
r = ioctl(tda->tda_fe_fd, FE_SET_FRONTEND, p);
}
- if(r != 0) {
- tvhlog(LOG_ERR, "dvb", "\"%s\" tuning to \"%s\""
- " -- Front configuration failed -- %s, frequency: %u",
- tda->tda_rootpath, buf, strerror(errno), p->frequency);
-
- /* Mark as bad */
- tdmi->tdmi_tune_failed = 1;
- goto retry;
- }
-
- tda->tda_current_tdmi = tdmi;
- dm->dm_current_tdmi = tdmi;
- if(dm->dm_scan_status == DM_SCAN_PENDING) {
- TAILQ_REMOVE(&dn->dn_initial_scan_pending_queue, dm, dm_scan_link);
- dm->dm_scan_status = DM_SCAN_CURRENT;
- TAILQ_INSERT_TAIL(&dn->dn_initial_scan_current_queue, dm, dm_scan_link);
-
- gtimer_arm(&dm->dm_initial_scan_timeout, dvb_mux_initial_scan_timeout, dm, 10);
- }
+ if(!r)
+ gtimer_arm(&tda->tda_fe_monitor_timer, dvb_fe_monitor, tda, 1);
- gtimer_arm(&tda->tda_fe_monitor_timer, dvb_fe_monitor, tda, 1);
-
- dvb_table_add_default(dm);
- epggrab_mux_start(dm);
-
- dvb_adapter_notify(tda);
- return 0;
+ return r;
}
}
if(save) {
- 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);
+ tvhlog(LOG_DEBUG, "dvb",
+ "Configuration for mux \"%s\" updated by %s%s",
+ dvb_mux_nicename(dm), source, buf2);
dvb_mux_notify(dm);
}
memcpy(&dm->dm_conf, dmc, sizeof(struct dvb_mux_conf));
if(source != NULL) {
- char buf[128];
- dvb_mux_nicename(buf, sizeof(buf), dm);
- tvhlog(LOG_NOTICE, "dvb", "New mux \"%s\" created by %s", buf, source);
+ tvhlog(LOG_NOTICE, "dvb", "New mux \"%s\" created by %s",
+ dvb_mux_nicename(dm), source);
dvb_mux_save(dm);
}
/**
*
*/
-void
+static void
dvb_tdmi_destroy(th_dvb_mux_instance_t *tdmi)
{
LIST_REMOVE(tdmi, tdmi_mux_link);
htsmsg_add_u32(m, "enabled", dm->dm_enabled);
htsmsg_add_str(m, "network", dm->dm_network_name ?: "");
- dvb_mux_nicefreq(buf, sizeof(buf), dm);
- htsmsg_add_str(m, "freq", buf);
+ htsmsg_add_str(m, "freq", dvb_mux_nicefreq(dm));
dvb_mux_modulation(buf, sizeof(buf), dm);
htsmsg_add_str(m, "mod", buf);
s->ths_tdmi = tdmi;
LIST_INSERT_HEAD(&tdmi->tdmi_subscriptions, s, ths_tdmi_link);
- dvb_fe_tune(tdmi->tdmi_mux, "Full mux subscription", 99999);
+ dvb_mux_tune(tdmi->tdmi_mux, "Full mux subscription", 99999);
abort();
pthread_mutex_lock(&tda->tda_delivery_mutex);
streaming_target_connect(&tda->tda_streaming_pad, &s->ths_input);
dvb_mux_t *dm = (dvb_mux_t *)self;
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_str(m, "id", idnode_uuid_as_str(&dm->dm_id));
-
- char buf[256];
- dvb_mux_nicename(buf, sizeof(buf), dm);
-
- htsmsg_add_str(m, "text", buf);
+ htsmsg_add_str(m, "text", dvb_mux_nicename(dm));
return m;
}
v[cnt] = NULL;
return v;
}
+
+
+
+/**
+ * These are created on the fly
+ */
+static void
+dvb_create_tdmis(dvb_mux_t *dm)
+{
+ th_dvb_mux_instance_t *tdmi;
+ dvb_network_t *dn = dm->dm_dn;
+ th_dvb_adapter_t *tda;
+
+ LIST_FOREACH(tda, &dn->dn_adapters, tda_network_link) {
+
+ LIST_FOREACH(tdmi, &dm->dm_tdmis, tdmi_mux_link) {
+ if(tdmi->tdmi_adapter != NULL)
+ break;
+ }
+
+ if(tdmi == NULL) {
+ tdmi = calloc(1, sizeof(th_dvb_mux_instance_t));
+ tdmi->tdmi_adapter = tda;
+ tdmi->tdmi_mux = dm;
+ LIST_INSERT_HEAD(&tda->tda_tdmis, tdmi, tdmi_adapter_link);
+ LIST_INSERT_HEAD(&dm->dm_tdmis, tdmi, tdmi_mux_link);
+ }
+ }
+}
+
+
+
+/**
+ *
+ */
+static void
+dvb_mux_stop(th_dvb_mux_instance_t *tdmi)
+{
+ dvb_mux_t *dm = tdmi->tdmi_mux;
+ th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+ assert(dm->dm_current_tdmi == tdmi);
+ assert(tda->tda_current_tdmi == tdmi);
+
+ dvb_table_flush_all(dm);
+ epggrab_mux_stop(dm, 0);
+
+ assert(dm->dm_scan_status == DM_SCAN_DONE);
+
+ dm->dm_current_tdmi = NULL;
+ tda->tda_current_tdmi = NULL;
+
+ printf("NEED TO TAKE CARE OF SERVICES in dvb_mux_stop\n");
+}
+
+
+/**
+ *
+ */
+static int
+tdmi_compute_weight(const th_dvb_mux_instance_t *tdmi)
+{
+ const dvb_mux_t *dm = tdmi->tdmi_mux;
+ if(dm->dm_scan_status == DM_SCAN_CURRENT)
+ return 1;
+ return 0;
+}
+
+
+/**
+ *
+ */
+static void
+dvb_mux_initial_scan_timeout(void *aux)
+{
+ dvb_mux_t *dm = aux;
+ tvhlog(LOG_DEBUG, "dvb", "Initial scan timed out for \"%s\"",
+ dvb_mux_nicename(dm));
+
+ dvb_mux_initial_scan_done(dm);
+}
+
+
+/**
+ *
+ */
+int
+dvb_mux_tune(dvb_mux_t *dm, const char *reason, int weight)
+{
+ dvb_network_t *dn = dm->dm_dn;
+ th_dvb_mux_instance_t *tdmi;
+ int r;
+
+ assert(dm->dm_current_tdmi == NULL);
+
+ lock_assert(&global_lock);
+
+ dvb_create_tdmis(dm);
+
+ retry:
+ // Figure which adapter to use
+ LIST_FOREACH(tdmi, &dm->dm_tdmis, tdmi_mux_link)
+ if(!tdmi->tdmi_tune_failed && tdmi->tdmi_adapter->tda_current_tdmi == NULL)
+ break;
+
+ if(tdmi == NULL) {
+ // None available, need to strike one out
+ LIST_FOREACH(tdmi, &dm->dm_tdmis, tdmi_mux_link) {
+ if(tdmi->tdmi_tune_failed)
+ continue;
+
+ th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+ th_dvb_mux_instance_t *t2 = tda->tda_current_tdmi;
+ assert(t2 != NULL);
+ assert(t2 != tdmi);
+
+ if(tdmi_compute_weight(t2) < weight) {
+ dvb_mux_stop(t2);
+ break;
+ }
+ }
+
+ if(tdmi == NULL)
+ return SM_CODE_NO_FREE_ADAPTER;
+
+ }
+
+ tdmi->tdmi_weight = weight;
+
+ th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+
+ free(tda->tda_tune_reason);
+ tda->tda_tune_reason = strdup(reason);
+
+ r = dvb_fe_tune_tdmi(tdmi);
+
+ if(r != 0) {
+ tvhlog(LOG_ERR, "dvb", "\"%s\" tuning to \"%s\""
+ " -- Front configuration failed -- %s",
+ tda->tda_rootpath, dvb_mux_nicename(dm), strerror(errno));
+
+ /* Mark as bad */
+ tdmi->tdmi_tune_failed = 1;
+ goto retry;
+ }
+
+ tda->tda_current_tdmi = tdmi;
+ dm->dm_current_tdmi = tdmi;
+ if(dm->dm_scan_status == DM_SCAN_PENDING) {
+ TAILQ_REMOVE(&dn->dn_initial_scan_pending_queue, dm, dm_scan_link);
+ dm->dm_scan_status = DM_SCAN_CURRENT;
+ TAILQ_INSERT_TAIL(&dn->dn_initial_scan_current_queue, dm, dm_scan_link);
+
+ gtimer_arm(&dm->dm_initial_scan_timeout, dvb_mux_initial_scan_timeout, dm, 10);
+ }
+
+ dvb_table_add_default(dm);
+ epggrab_mux_start(dm);
+
+ dvb_adapter_notify(tda);
+ return 0;
+}
while((dm = TAILQ_FIRST(&dn->dn_initial_scan_pending_queue)) != NULL) {
assert(dm->dm_scan_status == DM_SCAN_PENDING);
- if(dvb_fe_tune(dm, "initial scan", 1))
+ if(dvb_mux_tune(dm, "initial scan", 1))
break;
assert(dm->dm_scan_status == DM_SCAN_CURRENT);
}
dvb_service_setsourceinfo(service_t *t, struct source_info *si)
{
dvb_mux_t *dm = t->s_dvb_mux;
- char buf[100];
memset(si, 0, sizeof(struct source_info));
if(dm->dm_network_name != NULL)
si->si_network = strdup(dm->dm_network_name);
- dvb_mux_nicename(buf, sizeof(buf), dm);
- si->si_mux = strdup(buf);
+ si->si_mux = strdup(dvb_mux_nicename(dm));
if(t->s_provider != NULL)
si->si_provider = strdup(t->s_provider);
const char *uuid, int *save)
{
service_t *t;
- char buf[200];
lock_assert(&global_lock);
if(pmt_pid == 0)
return NULL;
- dvb_mux_nicename(buf, sizeof(buf), dm);
- tvhlog(LOG_DEBUG, "dvb", "Add service \"0x%x\" on \"%s\"", sid, buf);
+ tvhlog(LOG_DEBUG, "dvb", "Add service \"0x%x\" on \"%s\"", sid,
+ dvb_mux_nicename(dm));
t = service_create(uuid, S_MPEG_TS);
if (save) *save = 1;
t->s_dvb_mux = dm;
LIST_INSERT_HEAD(&dm->dm_services, t, s_group_link);
- pthread_mutex_lock(&t->s_stream_mutex);
+ pthread_mutex_lock(&t->s_stream_mutex);
service_make_nicename(t);
- pthread_mutex_unlock(&t->s_stream_mutex);
+ pthread_mutex_unlock(&t->s_stream_mutex);
return t;
}
htsmsg_add_str(m, "network", dm->dm_network_name ?: "");
- dvb_mux_nicefreq(buf, sizeof(buf), dm);
- htsmsg_add_str(m, "mux", buf);
+ htsmsg_add_str(m, "mux", dvb_mux_nicefreq(dm));
if(s->s_ch != NULL)
htsmsg_add_str(m, "channelname", s->s_ch->ch_name);
/**
*
*/
-static const char *
-nicenum(char *x, size_t siz, unsigned int v)
+static void
+nicenum(char *x, size_t siz, unsigned int v, const char *postfix)
{
if(v < 1000)
- snprintf(x, siz, "%d", v);
+ snprintf(x, siz, "%d%s", v, postfix);
else if(v < 1000000)
- snprintf(x, siz, "%d,%03d", v / 1000, v % 1000);
+ snprintf(x, siz, "%d,%03d%s", v / 1000, v % 1000, postfix);
else if(v < 1000000000)
- snprintf(x, siz, "%d,%03d,%03d",
- v / 1000000, (v % 1000000) / 1000, v % 1000);
- else
- snprintf(x, siz, "%d,%03d,%03d,%03d",
+ snprintf(x, siz, "%d,%03d,%03d%s",
+ v / 1000000, (v % 1000000) / 1000, v % 1000, postfix);
+ else
+ snprintf(x, siz, "%d,%03d,%03d,%03d%s",
v / 1000000000, (v % 1000000000) / 1000000,
- (v % 1000000) / 1000, v % 1000);
- return x;
+ (v % 1000000) / 1000, v % 1000, postfix);
}
/**
- *
+ *
*/
-void
-dvb_mux_nicefreq(char *buf, size_t size, const dvb_mux_t *dm)
+const char *
+dvb_mux_nicefreq(const dvb_mux_t *dm)
{
- char freq[50];
-
- if(dm->dm_dn->dn_fe_type == FE_QPSK) {
- nicenum(freq, sizeof(freq), dm->dm_conf.dmc_fe_params.frequency);
- snprintf(buf, size, "%s kHz", freq);
- } else {
- nicenum(freq, sizeof(freq),
- dm->dm_conf.dmc_fe_params.frequency / 1000);
- snprintf(buf, size, "%s kHz", freq);
- }
+ static char ret[100];
+ int f = dm->dm_conf.dmc_fe_params.frequency;
+ nicenum(ret, sizeof(ret), dm->dm_dn->dn_fe_type == FE_QPSK ? f : f / 1000,
+ " kHz");
+ return ret;
}
/**
- *
+ *
*/
-void
-dvb_mux_nicename(char *buf, size_t size, dvb_mux_t *dm)
+const char *
+dvb_mux_nicename(const dvb_mux_t *dm)
{
- char freq[50];
+ static char ret[100];
const char *n = dm->dm_network_name;
- 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,
- dvb_polarisation_to_str_long(dm->dm_conf.dmc_polarisation));
-
- } else {
- nicenum(freq, sizeof(freq), dm->dm_conf.dmc_fe_params.frequency / 1000);
- snprintf(buf, size, "%s%s%s kHz", n?:"", n ? ": ":"", freq);
- }
+ snprintf(ret, sizeof(ret), "%s%s%s%s%s",
+ n ?: "",
+ n ? ": " : "",
+ dvb_mux_nicefreq(dm),
+ dm->dm_dn->dn_fe_type == FE_QPSK ? " " : "",
+ dm->dm_dn->dn_fe_type == FE_QPSK ?
+ dvb_polarisation_to_str_long(dm->dm_conf.dmc_polarisation) :
+ "");
+ return ret;
}
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, 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);
+
+const char *dvb_mux_nicefreq(const dvb_mux_t *dm);
+const char *dvb_mux_nicename(const dvb_mux_t *dm);
void atsc_utf16_to_utf8(uint8_t *src, int len, char *buf, int buflen);
pthread_mutex_unlock(&t->s_stream_mutex);
hts_settings_save(m, "v4lservices/%s/%s",
- va->va_identifier, t->s_uuid);
+ va->va_identifier, idnode_uuid_as_str(&t->s_id));
htsmsg_destroy(m);
}
-/**
- *
- */
-static int
-v4l_service_quality(service_t *t)
-{
- return 100;
-}
-
-
/**
*
*/
return NULL;
LIST_FOREACH(t, &va->va_services, s_group_link)
- if(!strcmp(t->s_uuid, id))
+ if(!strcmp(idnode_uuid_as_str(&t->s_id), id))
return t;
}
t->s_stop_feed = v4l_service_stop;
t->s_config_save = v4l_service_save;
t->s_setsourceinfo = v4l_service_setsourceinfo;
- t->s_quality_index = v4l_service_quality;
t->s_grace_period = v4l_grace_period;
t->s_iptv_fd = -1;
t->s_v4l_adapter = va;
{
htsmsg_t *r = htsmsg_create_map();
- htsmsg_add_str(r, "id", t->s_identifier);
+ // htsmsg_add_str(r, "id", t->s_identifier); // XXX(dvbreorg)
htsmsg_add_str(r, "channelname", t->s_ch ? t->s_ch->ch_name : "");
htsmsg_add_u32(r, "frequency", t->s_v4l_frequency);