Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Adam Sutton
69ac1e378d mpegts: add service and mux cleaning code 2014-11-16 19:53:25 +00:00
5 changed files with 124 additions and 14 deletions

View file

@ -298,6 +298,8 @@ struct mpegts_network
char *mn_charset;
int mn_idlescan;
int mn_ignore_chnum;
int mn_autoclean_svc;
int mn_autoclean_mux;
};
typedef enum mpegts_mux_scan_state
@ -343,6 +345,12 @@ struct mpegts_mux
uint16_t mm_onid;
uint16_t mm_tsid;
/*
* Versioning
*/
int64_t mm_created;
int64_t mm_updated;
/*
* Services
*/
@ -445,6 +453,12 @@ struct mpegts_service
int s_dvb_prefcapid_lock;
uint16_t s_dvb_forcecaid;
/*
* History
*/
int64_t s_dvb_created;
int64_t s_dvb_updated;
/*
* EIT/EPG control
*/

View file

@ -1011,6 +1011,7 @@ dvb_pat_callback
/* Multiplex */
tvhdebug("pat", "tsid %04X (%d)", tsid, tsid);
mpegts_mux_set_tsid(mm, tsid, 1);
mm->mm_updated = dispatch_clock;
/* Process each programme */
ptr += 5;
@ -1031,6 +1032,7 @@ dvb_pat_callback
tvhdebug("pat", " sid %04X (%d) on pid %04X (%d)", sid, sid, pid, pid);
int save = 0;
if ((s = mpegts_service_find(mm, sid, pid, 1, &save))) {
s->s_dvb_updated = dispatch_clock;
mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK, dvb_pmt_callback,
NULL, "pmt", MT_CRC | MT_QUICKREQ | MT_SCANSUBS,
pid);
@ -1121,11 +1123,13 @@ dvb_pmt_callback
sid = ptr[0] << 8 | ptr[1];
r = dvb_table_begin(mt, ptr, len, tableid, sid, 9, &st, &sect, &last, &ver);
if (r != 1) return r;
mm->mm_updated = dispatch_clock;
/* Find service */
LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link)
if (s->s_dvb_service_id == sid) break;
if (!s) return -1;
s->s_dvb_updated = dispatch_clock;
/* Process */
tvhdebug("pmt", "sid %04X (%d)", sid, sid);
@ -1486,6 +1490,10 @@ dvb_nit_callback
#endif
break;
}
/* Update */
if (mux)
mm->mm_updated = dispatch_clock;
}
}
@ -1528,8 +1536,9 @@ dvb_sdt_callback
LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link)
if (mm->mm_onid == onid && mm->mm_tsid == tsid)
break;
goto done;
if (!mm) goto done;
}
mm->mm_updated = dispatch_clock;
/* Service loop */
len -= 8;
@ -1554,6 +1563,9 @@ dvb_sdt_callback
s = mpegts_service_find(mm, service_id, 0, 1, &save);
charset = dvb_charset_find(mn, mm, s);
/* Update time and version */
s->s_dvb_updated = dispatch_clock;
/* Descriptor loop */
DVB_DESC_EACH(lptr, llen, dtag, dlen, dptr) {
tvhtrace("sdt", " dtag %02X dlen %d", dtag, dlen);
@ -1645,7 +1657,8 @@ dvb_sdt_callback
/* Done */
done:
return dvb_table_end(mt, st, sect);
r = dvb_table_end(mt, st, sect);
return r;
}
/*
@ -1677,6 +1690,7 @@ atsc_vct_callback
&st, &sect, &last, &ver);
if (r != 1) return r;
tvhdebug("vct", "tsid %04X (%d)", tsid, tsid);
mm->mm_updated = dispatch_clock;
/* # channels */
count = ptr[6];
@ -1713,6 +1727,7 @@ atsc_vct_callback
/* Find the service */
if (!(s = mpegts_service_find(mm, sid, 0, 1, &save)))
goto next;
s->s_dvb_updated = dispatch_clock;
/* Update */
if (strcmp(s->s_dvb_svcname ?: "", chname)) {

View file

@ -440,7 +440,23 @@ const idclass_t mpegts_mux_class =
.off = offsetof(mpegts_mux_t, mm_pmt_06_ac3),
.opts = PO_ADVANCED,
},
{}
{
.type = PT_S64,
.id = "created",
.name = "Created",
.off = offsetof(mpegts_mux_t, mm_created),
.opts = PO_ADVANCED | PO_RDONLY,
.istime = "%F %T",
},
{
.type = PT_S64,
.id = "updated",
.name = "Updated",
.off = offsetof(mpegts_mux_t, mm_updated),
.opts = PO_ADVANCED | PO_RDONLY,
.istime = "%F %T",
},
{},
}
};
@ -463,7 +479,10 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf )
char buf[256];
mpegts_mux_nice_name(mm, buf, sizeof(buf));
tvhinfo("mpegts", "%s (%p) - deleting", buf, mm);
if (delconf)
tvhinfo("mpegts", "%s (%p) - deleting", buf, mm);
else
tvhtrace("mpegts", "%s (%p) - deleting", buf, mm);
/* Stop */
mm->mm_stop(mm, 1);
@ -831,6 +850,21 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
* Scanning
* *************************************************************************/
#define MPEGTS_AUTOCLEAN_PERIOD (86400L * 7) // 1 week
static void
mpegts_mux_clean_services ( const char *mname, mpegts_mux_t *mm )
{
mpegts_service_t *s, *n;
for (s = LIST_FIRST(&mm->mm_services); s != NULL; s = n) {
n = LIST_NEXT(s, s_dvb_mux_link);
if (dispatch_clock < (s->s_dvb_updated + MPEGTS_AUTOCLEAN_PERIOD))
continue;
tvhinfo("mpegts", "%s - autoclean svc %s", mname, s->s_nicename);
service_destroy((service_t*)s, 1);
}
}
void
mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res )
{
@ -853,6 +887,10 @@ mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res )
}
pthread_mutex_unlock(&mm->mm_tables_lock);
/* Check for out of date services */
if (mm->mm_network->mn_autoclean_svc)
mpegts_mux_clean_services(buf, mm);
if (res)
mpegts_network_scan_mux_done(mm);
else
@ -904,6 +942,15 @@ again:
tvhinfo("mpegts", "%s - scan no data, failed", buf);
mpegts_mux_scan_done(mm, buf, 0);
/* Mark disabled */
if (mm->mm_network->mn_autoclean_mux) {
if (dispatch_clock > (mm->mm_updated + MPEGTS_AUTOCLEAN_PERIOD)) {
tvhinfo("mpegts", "%s - autoclean mux", buf);
mm->mm_delete(mm, 1);
return;
}
}
/* Pending tables (another 20s or 30s - bit arbitrary) */
} else if (q) {
tvhinfo("mpegts", "%s - scan needs more time", buf);
@ -935,6 +982,9 @@ mpegts_mux_create0
return NULL;
}
/* Set time */
mm->mm_created = dispatch_clock;
/* Enabled by default */
mm->mm_enabled = 1;
mm->mm_epg = 1;

View file

@ -154,21 +154,14 @@ const idclass_t mpegts_network_class =
{
.type = PT_BOOL,
.id = "autodiscovery",
.name = "Network Discovery",
.name = "Autodiscover Muxes",
.off = offsetof(mpegts_network_t, mn_autodiscovery),
.def.i = 1
},
{
.type = PT_BOOL,
.id = "skipinitscan",
.name = "Skip Initial Scan",
.off = offsetof(mpegts_network_t, mn_skipinitscan),
.def.i = 1
},
{
.type = PT_BOOL,
.id = "idlescan",
.name = "Idle Scan Muxes",
.name = "Autoscan Muxes",
.off = offsetof(mpegts_network_t, mn_idlescan),
.def.i = 0,
.notify = mpegts_network_class_idlescan_notify,
@ -180,6 +173,27 @@ const idclass_t mpegts_network_class =
.off = offsetof(mpegts_network_t, mn_ignore_chnum),
.def.i = 0,
},
{
.type = PT_BOOL,
.id = "autoclean_svc`",
.name = "Autoclean Services",
.off = offsetof(mpegts_network_t, mn_autoclean_svc),
.def.i = 1,
},
{
.type = PT_BOOL,
.id = "autoclean_mux",
.name = "Autoclean Muxes",
.off = offsetof(mpegts_network_t, mn_autoclean_mux),
.def.i = 1,
},
{
.type = PT_BOOL,
.id = "skipinitscan",
.name = "Skip Initial Scan",
.off = offsetof(mpegts_network_t, mn_skipinitscan),
.def.i = 1
},
{
.type = PT_STR,
.id = "charset",

View file

@ -183,6 +183,22 @@ const idclass_t mpegts_service_class =
.off = offsetof(mpegts_service_t, s_dvb_forcecaid),
.opts = PO_ADVANCED | PO_HEXA,
},
{
.type = PT_S64,
.id = "created",
.name = "Created",
.off = offsetof(mpegts_service_t, s_dvb_created),
.opts = PO_ADVANCED | PO_RDONLY,
.istime = "%F %T",
},
{
.type = PT_S64,
.id = "updated",
.name = "Updated",
.off = offsetof(mpegts_service_t, s_dvb_updated),
.opts = PO_ADVANCED | PO_RDONLY,
.istime = "%F %T",
},
{},
}
};
@ -514,7 +530,8 @@ mpegts_service_create0
if (service_create0((service_t*)s, class, uuid, S_MPEG_TS, conf) == NULL)
return NULL;
s->s_dvb_created = dispatch_clock;
/* Create */
sbuf_init(&s->s_tsbuf);
if (!conf) {