Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
SAT>IP client: override tuners with lower weight for master/slave config
  • Loading branch information
perexg committed Mar 21, 2016
1 parent 54b57cf commit 60157d0
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/input/mpegts.h
Expand Up @@ -924,6 +924,7 @@ void mpegts_input_recv_packets
int mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags );
int mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags );
int mpegts_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm );
int mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi );

void mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *c );

Expand Down
2 changes: 1 addition & 1 deletion src/input/mpegts/mpegts_input.c
Expand Up @@ -405,7 +405,7 @@ mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
return mi->mi_priority;
}

static int
int
mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
{
mpegts_mux_instance_t *cur;
Expand Down
80 changes: 60 additions & 20 deletions src/input/mpegts/satip/satip_frontend.c
Expand Up @@ -451,22 +451,48 @@ satip_frontend_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm )
}

static int
satip_frontend_match_satcfg ( satip_frontend_t *lfe2, mpegts_mux_t *mm2 )
satip_frontend_get_max_weight ( satip_frontend_t *lfe, mpegts_mux_t *mm, int flags )
{
satip_frontend_t *lfe2;
int w = 0, w2;

TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) {
if (!lfe2->sf_running) continue;
if (lfe2->sf_type != DVB_TYPE_S) continue;
if (lfe2 != lfe) continue;
if (lfe->sf_master != lfe2->sf_number &&
lfe2->sf_master != lfe->sf_number) continue;
w2 = lfe2->mi_get_weight((mpegts_input_t *)lfe2, mm, flags);
if (w2 > w)
w = w2;
}
return w;
}

int
satip_frontend_match_satcfg
( satip_frontend_t *lfe2, mpegts_mux_t *mm2, int flags, int weight )
{
satip_frontend_t *lfe_master;
mpegts_mux_t *mm1 = NULL;
dvb_mux_conf_t *mc1, *mc2;
int position, high1, high2;
int position, weight2, high1, high2;

if (lfe2->sf_req == NULL || lfe2->sf_req->sf_mmi == NULL)
if (!lfe2->sf_running)
return 0;

lfe_master = lfe2;
if (lfe2->sf_master)
lfe_master = satip_frontend_find_by_number(lfe2->sf_device, lfe2->sf_master) ?: lfe2;

if (weight > 0) {
weight2 = satip_frontend_get_max_weight(lfe2, mm2, flags);
if (weight2 > 0 && weight2 < weight)
return 1;
}

mm1 = lfe2->sf_req->sf_mmi->mmi_mux;
position = satip_satconf_get_position(lfe2, mm2, NULL, 0);
position = satip_satconf_get_position(lfe2, mm2, NULL, 0, 0, -1);
if (position <= 0 || lfe_master->sf_position != position)
return 0;
mc1 = &((dvb_mux_t *)mm1)->lm_tuning;
Expand All @@ -479,7 +505,9 @@ satip_frontend_match_satcfg ( satip_frontend_t *lfe2, mpegts_mux_t *mm2 )
high2 = mc2->dmc_fe_freq > 11700000;
if (high1 != high2)
return 0;
return 1;

/* return unique hash for the active satcfg greater than zero */
return 1 | (high1 ? 2 : 0) | ((int)mc1->u.dmc_fe_qpsk.polarisation << 8) | (position << 16);
}

static int
Expand All @@ -497,18 +525,18 @@ satip_frontend_is_enabled
if (lfe->sf_type != DVB_TYPE_S) return 1;
/* try to reuse any input for limited networks if allowed */
if (lfe->sf_device->sd_all_tuners) {
position = satip_satconf_get_position(lfe, mm, &netlimit, 0);
position = satip_satconf_get_position(lfe, mm, &netlimit, 0, 0, -1);
if (position <= 0) return 0;
if (netlimit <= 0) goto cont;
/* try to reuse any tuner input as slave */
TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) {
if (lfe2 == lfe) continue;
if (satip_frontend_match_satcfg(lfe2, mm))
if (satip_frontend_match_satcfg(lfe2, mm, flags, weight))
return 1;
}
}
/* check if the position is enabled */
position = satip_satconf_get_position(lfe, mm, NULL, 1);
position = satip_satconf_get_position(lfe, mm, NULL, 1, flags, weight);
if (position <= 0)
return 0;
/* check if any "blocking" tuner is running */
Expand All @@ -519,13 +547,10 @@ satip_frontend_is_enabled
if (lfe->sf_master == lfe2->sf_number) {
if (!lfe2->sf_running)
return 0; /* master must be running */
return satip_frontend_match_satcfg(lfe2, mm);
}
if (lfe2->sf_master == lfe->sf_number && lfe2->sf_running) {
if (lfe2->sf_req == NULL || lfe2->sf_req->sf_mmi == NULL)
return 0;
return satip_frontend_match_satcfg(lfe2, mm);
return satip_frontend_match_satcfg(lfe2, mm, flags, weight);
}
if (lfe2->sf_master == lfe->sf_number && lfe2->sf_running)
return satip_frontend_match_satcfg(lfe2, mm, flags, weight);
}
return 1;
}
Expand Down Expand Up @@ -560,20 +585,34 @@ satip_frontend_stop_mux
}

static int
satip_frontend_start_mux
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight )
satip_frontend_warm_mux
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
{
satip_frontend_t *lfe = (satip_frontend_t*)mi;
dvb_mux_t *lm = (dvb_mux_t *)mmi->mmi_mux;
satip_tune_req_t *tr;
char buf1[256], buf2[256];
int r;

r = mpegts_input_warm_mux(mi, mmi);
if (r)
return r;

if (lfe->sf_positions > 0) {
lfe->sf_position = satip_satconf_get_position(lfe, mmi->mmi_mux, NULL, 0);
lfe->sf_position = satip_satconf_get_position(lfe, mmi->mmi_mux, NULL, 2, 0, -1);
if (lfe->sf_position <= 0)
return SM_CODE_TUNING_FAILED;
}

return 0;
}

static int
satip_frontend_start_mux
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight )
{
satip_frontend_t *lfe = (satip_frontend_t*)mi;
dvb_mux_t *lm = (dvb_mux_t *)mmi->mmi_mux;
satip_tune_req_t *tr;
char buf1[256], buf2[256];

lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1));
mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2));
tvhdebug("satip", "%s - starting %s", buf1, buf2);
Expand Down Expand Up @@ -1956,6 +1995,7 @@ satip_frontend_create
lfe->ti_wizard_get = satip_frontend_wizard_get;
lfe->ti_wizard_set = satip_frontend_wizard_set;
lfe->mi_is_enabled = satip_frontend_is_enabled;
lfe->mi_warm_mux = satip_frontend_warm_mux;
lfe->mi_start_mux = satip_frontend_start_mux;
lfe->mi_stop_mux = satip_frontend_stop_mux;
lfe->mi_network_list = satip_frontend_network_list;
Expand Down
5 changes: 4 additions & 1 deletion src/input/mpegts/satip/satip_private.h
Expand Up @@ -209,6 +209,9 @@ void satip_device_destroy_later( satip_device_t *sd, int after_ms );

char *satip_device_nicename ( satip_device_t *sd, char *buf, int len );

int satip_frontend_match_satcfg
( satip_frontend_t *lfe2, mpegts_mux_t *mm2, int flags, int weight );

satip_frontend_t *
satip_frontend_create
( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int v2, int num );
Expand Down Expand Up @@ -237,7 +240,7 @@ int satip_satconf_get_grace
( satip_frontend_t *lfe, mpegts_mux_t *mm );

int satip_satconf_get_position
( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check );
( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check, int flags, int weight );

/*
* RTSP part
Expand Down
114 changes: 97 additions & 17 deletions src/input/mpegts/satip/satip_satconf.c
Expand Up @@ -66,41 +66,121 @@ satip_satconf_get_grace
}

static int
satip_satconf_check_network_limit
( satip_frontend_t *lfe, satip_satconf_t *sfc, idnode_t *mn )
satip_satconf_master_or_slave
( satip_frontend_t *lfe1, satip_frontend_t *lfe2 )
{
return lfe1->sf_number == lfe2->sf_master ||
lfe2->sf_number == lfe1->sf_master;
}

static int
satip_satconf_in_network_group
( satip_frontend_t *lfe, int network_group, idnode_t *mn )
{
satip_frontend_t *lfe2;
satip_satconf_t *sfc2;
int count;

count = 0;
TAILQ_FOREACH(sfc2, &lfe->sf_satconf, sfc_link) {
if (network_group > 0 &&
sfc2->sfc_network_group > 0 &&
sfc2->sfc_network_group == network_group)
break;
else if (idnode_set_exists(sfc2->sfc_networks, mn))
break;
}
return sfc2 != NULL;
}

static int
satip_satconf_check_limits
( satip_frontend_t *lfe, satip_satconf_t *sfc, mpegts_mux_t *mm,
int flags, int weight, int manage )
{
satip_frontend_t *lfe2, *lowest_lfe;
mpegts_mux_t *mm2;
mpegts_input_t *mi2;
idnode_t *mn = &mm->mm_network->mn_id;
int count, size, lowest, w2, r, i, limit, *hashes;

size = 0;
TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link)
TAILQ_FOREACH(sfc2, &lfe2->sf_satconf, sfc_link) {
if (!lfe2->sf_running) continue;
if (sfc->sfc_network_group > 0 &&
sfc2->sfc_network_group > 0 &&
sfc2->sfc_network_group == sfc->sfc_network_group)
count++;
else if (idnode_set_exists(sfc2->sfc_networks, mn))
size++;
hashes = alloca(size * sizeof(int));

limit = sfc->sfc_network_limit > 0 ? sfc->sfc_network_limit : 1;

retry:
memset(hashes, 0, size * sizeof(int));
count = 1;
lowest = INT_MAX;
lowest_lfe = NULL;
TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) {
if (lfe == lfe2 || !lfe2->sf_running || lfe2->sf_type != DVB_TYPE_S)
continue;
if (sfc->sfc_network_limit) {
if (!satip_satconf_in_network_group(lfe2, sfc->sfc_network_group, mn))
continue;
} else {
if (!satip_satconf_master_or_slave(lfe, lfe2))
continue;
}
mi2 = (mpegts_input_t *)lfe2;
mm2 = lfe2->sf_req->sf_mmi->mmi_mux;
if (weight > 0) {
w2 = lfe2->mi_get_weight(mi2, mm2, flags);
if (w2 < weight)
continue;
} else {
w2 = -1;
}
r = satip_frontend_match_satcfg(lfe2, mm, 0, -1);
if (r && manage) {
w2 = lfe2->mi_get_weight(mi2, mm2, flags);;
if (w2 < lowest) {
lowest = w2;
lowest_lfe = lfe2;
}
}
for (i = 0; i < size; i++) {
if (hashes[i] == r)
break;
if (!hashes[i]) {
hashes[i] = r;
count++;
break;
}
}

return count <= sfc->sfc_network_limit;
}
if (count <= limit)
return 1;
if (manage) {
/* free tuner with lowest weight */
mm2 = lowest_lfe->sf_req->sf_mmi->mmi_mux;
mm2->mm_stop(mm2, 1, SM_CODE_SUBSCRIPTION_OVERRIDDEN);
goto retry;
}
return 0;
}

int
satip_satconf_get_position
( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check )
( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check, int flags, int weight )
{
satip_satconf_t *sfc;
sfc = satip_satconf_find_ele(lfe, mm);
if (sfc && sfc->sfc_enabled) {
if (netlimit)
*netlimit = sfc->sfc_network_limit;
if (!check || sfc->sfc_network_limit <= 0)
if (!check)
return sfc->sfc_position;
if (satip_satconf_check_network_limit(lfe, sfc, &mm->mm_network->mn_id))
if (check > 1) {
satip_satconf_check_limits(lfe, sfc, mm, flags, weight, 1);
return sfc->sfc_position;
} else {
if (sfc->sfc_network_limit <= 0)
return sfc->sfc_position;
if (satip_satconf_check_limits(lfe, sfc, mm, flags, weight, 0))
return sfc->sfc_position;
}
} else {
if (netlimit)
*netlimit = 0;
Expand Down

0 comments on commit 60157d0

Please sign in to comment.