SAT>IP Server: fix the pid subscriptions (stack overflow, duplicate pids)

This commit is contained in:
Jaroslav Kysela 2015-03-23 12:50:05 +01:00
parent 1063fbf472
commit 30f5c44d2c
5 changed files with 27 additions and 21 deletions

View file

@ -565,8 +565,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
/* Ensure that filtered PIDs are not send in ts_recv_raw */
TAILQ_FOREACH(st, &s->s_filt_components, es_filt_link)
if (st->es_type != SCT_CA && st->es_pid >= 0 && st->es_pid < 8192)
if (!mpegts_pid_exists(pids, st->es_pid))
mpegts_pid_add(pids, st->es_pid);
mpegts_pid_add(pids, st->es_pid);
LIST_FOREACH(s2, &s->s_masters, s_masters_link) {
pthread_mutex_lock(&s2->s_stream_mutex);

View file

@ -65,6 +65,8 @@ mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid)
mpegts_apid_t *p;
int i;
if (mpegts_pid_exists(pids, pid))
return 0;
assert(pids);
assert(pid >= 0 && pid <= 8191);
if (pids->alloc == pids->count) {
@ -190,9 +192,14 @@ mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len)
{
int i, l = 0;
if (len < 1) {
if (len)
*buf = '\0';
return len;
}
if (pids->all)
return snprintf(buf, len, "all");
for (i = 0; i < pids->count; i++)
for (i = 0; i < pids->count && l + 1 < len; i++)
l += snprintf(buf + l, len - l, "%s%i",
i > 0 ? "," : "", pids->pids[i]);
return l;

View file

@ -538,7 +538,7 @@ satip_frontend_add_pid( satip_frontend_t *lfe, int pid)
return 0;
tr = lfe->sf_req;
if (tr && !mpegts_pid_exists(&tr->sf_pids, pid)) {
if (tr) {
mpegts_pid_add(&tr->sf_pids, pid);
return 1;
}

View file

@ -373,7 +373,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
char pids[1400];
const char *delsys, *msys, *pilot, *rolloff;
const char *bw, *tmode, *gi, *plp, *t2id, *sm, *c2tft, *ds, *specinv;
int i, j, r, level = 0, lock = 0, quality = 0;
int r, level = 0, lock = 0, quality = 0;
lock = rtp->sig_lock;
switch (rtp->sig.signal_scale) {
@ -399,11 +399,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
break;
}
pids[0] = 0;
for (i = j = 0; i < rtp->pids.count; i++)
j += snprintf(pids + j, sizeof(pids) - j, "%d,", rtp->pids.pids[i]);
if (j && pids[j-1] == ',')
pids[j-1] = '\0';
mpegts_pid_dump(&rtp->pids, pids, sizeof(pids));
switch (rtp->dmc.dmc_fe_delsys) {
case DVB_SYS_DVBS:

View file

@ -377,7 +377,7 @@ rtsp_clean(session_t *rs)
*
*/
static int
rtsp_validate_service(mpegts_service_t *s)
rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids)
{
int av = 0, enc = 0;
elementary_stream_t *st;
@ -390,10 +390,11 @@ rtsp_validate_service(mpegts_service_t *s)
TAILQ_FOREACH(st, &s->s_components, es_link) {
if (st->es_type == SCT_CA)
enc = 1;
if (st->es_pid > 0 &&
(SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
av = 1;
}
if (st->es_pid > 0)
if (pids == NULL || mpegts_pid_exists(pids, st->es_pid))
if ((SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
av = 1;
}
pthread_mutex_unlock(&s->s_stream_mutex);
return enc && av;
}
@ -420,12 +421,12 @@ rtsp_manage_descramble(session_t *rs)
if (rs->pids.all) {
LIST_FOREACH(s, &rs->mux->mm_services, s_dvb_mux_link)
if (rtsp_validate_service(s))
if (rtsp_validate_service(s, NULL))
idnode_set_add(found, &s->s_id, NULL);
} else {
for (i = 0; i < rs->pids.count; i++) {
s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i]);
if (s != NULL && rtsp_validate_service(s))
if (s != NULL && rtsp_validate_service(s, &rs->pids))
if (!idnode_set_exists(found, &s->s_id))
idnode_set_add(found, &s->s_id, NULL);
}
@ -1035,10 +1036,12 @@ play:
mpegts_pid_add_group(&rs->pids, &addpids);
dvb_mux_conf_str(dmc, buf, sizeof(buf));
s = buf + strlen(buf);
s += snprintf(s, sizeof(buf) - (s - buf), " pids ");
if (mpegts_pid_dump(&rs->pids, s, sizeof(buf) - (s - buf)) == 0)
snprintf(s, sizeof(buf) - (s - buf), "<none>");
r = strlen(buf);
if (r + 1 < sizeof(buf))
r += snprintf(buf + r, sizeof(buf) - r, " pids ");
if (r + 1 < sizeof(buf) &&
mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r) == 0)
snprintf(buf + r, sizeof(buf) - r, "<none>");
tvhdebug("satips", "%i/%s/%d: %s from %s:%d %s",
rs->frontend, rs->session, rs->stream,
@ -1451,6 +1454,7 @@ rtsp_close_session(session_t *rs)
udp_close(rs->udp_rtcp);
rs->udp_rtcp = NULL;
pthread_mutex_lock(&global_lock);
mpegts_pid_reset(&rs->pids);
rtsp_clean(rs);
gtimer_disarm(&rs->timer);
pthread_mutex_unlock(&global_lock);