Fix duplicate mux issues by pushing all mux freq to 1KHz boundary. Fixes #1310.

This is really considered a hack, it will be replaced with a better internal
DVB structure in 3.4.
(cherry picked from commit afd468ef83)
This commit is contained in:
Adam Sutton 2012-10-09 15:09:38 +01:00
parent c4ec5aae9e
commit 274dd64c2c
3 changed files with 97 additions and 52 deletions

View file

@ -395,7 +395,7 @@ void dvb_mux_add_to_scan_queue (th_dvb_mux_instance_t *tdmi);
/**
* DVB Transport (aka DVB service)
*/
void dvb_transport_load(th_dvb_mux_instance_t *tdmi);
void dvb_transport_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier);
struct service *dvb_transport_find(th_dvb_mux_instance_t *tdmi,
uint16_t sid, int pmt_pid,

View file

@ -157,9 +157,23 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
th_dvb_mux_instance_t *tdmi, *c;
unsigned int hash;
char buf[200];
struct dvb_mux_conf _dmc;
const char *oldid = NULL;
lock_assert(&global_lock);
/* HACK - move frequency to nominal based on 1KHz spacing
* temporary workaround to duplicate mux issues
*/
memcpy(&_dmc, dmc, sizeof(_dmc));
_dmc.dmc_fe_params.frequency
= ((dmc->dmc_fe_params.frequency + 499) / 1000) * 1000;
if (_dmc.dmc_fe_params.frequency != dmc->dmc_fe_params.frequency) {
oldid = identifier;
identifier = NULL;
}
dmc = &_dmc;
hash = (dmc->dmc_fe_params.frequency +
dmc->dmc_polarisation) % TDA_MUX_HASH_WIDTH;
@ -197,11 +211,19 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
save = 1;
}
if(tdmi->tdmi_transport_stream_id != tsid) {
if(tdmi->tdmi_transport_stream_id != tsid && tsid != (uint16_t)-1) {
tdmi->tdmi_transport_stream_id = tsid;
save = 1;
}
/* HACK - load old transports and remove old mux config */
if(oldid) {
save = 1;
dvb_transport_load(tdmi, oldid);
hts_settings_remove("dvbmuxes/%s/%s",
tda->tda_identifier, oldid);
}
if(save) {
dvb_mux_save(tdmi);
dvb_mux_nicename(buf, sizeof(buf), tdmi);
@ -279,7 +301,7 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
dvb_adapter_notify(tda);
}
dvb_transport_load(tdmi);
dvb_transport_load(tdmi, oldid ?: identifier);
dvb_mux_notify(tdmi);
if(enabled && initialscan) {
@ -290,6 +312,10 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
dvb_mux_add_to_scan_queue(tdmi);
}
/* HACK - remove old config */
if(oldid)
hts_settings_remove("dvbmuxes/%s/%s", tda->tda_identifier, oldid);
return tdmi;
}

View file

@ -186,12 +186,59 @@ dvb_transport_refresh(service_t *t)
}
/**
*
*/
static void
dvb_transport_save(service_t *t)
{
htsmsg_t *m = htsmsg_create_map();
lock_assert(&global_lock);
htsmsg_add_u32(m, "service_id", t->s_dvb_service_id);
htsmsg_add_u32(m, "pmt", t->s_pmt_pid);
htsmsg_add_u32(m, "stype", t->s_servicetype);
htsmsg_add_u32(m, "scrambled", t->s_scrambled);
htsmsg_add_u32(m, "channel", t->s_channel_number);
if(t->s_provider != NULL)
htsmsg_add_str(m, "provider", t->s_provider);
if(t->s_svcname != NULL)
htsmsg_add_str(m, "servicename", t->s_svcname);
if(t->s_ch != NULL) {
htsmsg_add_str(m, "channelname", t->s_ch->ch_name);
htsmsg_add_u32(m, "mapped", 1);
}
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)
htsmsg_add_str(m, "default_authority", t->s_default_authority);
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);
htsmsg_destroy(m);
dvb_transport_notify(t);
}
/**
* Load config for the given mux
*/
void
dvb_transport_load(th_dvb_mux_instance_t *tdmi)
dvb_transport_load(th_dvb_mux_instance_t *tdmi, const char *tdmi_identifier)
{
htsmsg_t *l, *c;
htsmsg_field_t *f;
@ -199,10 +246,17 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi)
const char *s;
unsigned int u32;
service_t *t;
int old;
lock_assert(&global_lock);
if((l = hts_settings_load("dvbtransports/%s", tdmi->tdmi_identifier)) == NULL)
/* 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)
return;
HTSMSG_FOREACH(f, l) {
@ -254,57 +308,22 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi)
if(s && u32)
service_map_channel(t, channel_find_by_name(s, 1, 0), 0);
/* HACK - force save for old config */
if(old)
dvb_transport_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);
}
/**
*
*/
static void
dvb_transport_save(service_t *t)
{
htsmsg_t *m = htsmsg_create_map();
lock_assert(&global_lock);
htsmsg_add_u32(m, "service_id", t->s_dvb_service_id);
htsmsg_add_u32(m, "pmt", t->s_pmt_pid);
htsmsg_add_u32(m, "stype", t->s_servicetype);
htsmsg_add_u32(m, "scrambled", t->s_scrambled);
htsmsg_add_u32(m, "channel", t->s_channel_number);
if(t->s_provider != NULL)
htsmsg_add_str(m, "provider", t->s_provider);
if(t->s_svcname != NULL)
htsmsg_add_str(m, "servicename", t->s_svcname);
if(t->s_ch != NULL) {
htsmsg_add_str(m, "channelname", t->s_ch->ch_name);
htsmsg_add_u32(m, "mapped", 1);
}
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)
htsmsg_add_str(m, "default_authority", t->s_default_authority);
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);
htsmsg_destroy(m);
dvb_transport_notify(t);
}
/**
* Called to get quality for the given transport