From dc7f65b51dae293e81fd31b3f79edd082a760b33 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 23 Apr 2014 12:50:18 +0200 Subject: [PATCH] Optimize the PIDs filtering - only used CA PIDs are opened - all PMT PIDs are opened only at the initial scan The SAT>IP boxes have limited count of PIDs filters (and probably some linuxdvb hardware too), so try to use these resources better. --- src/descrambler/capmt.c | 2 ++ src/descrambler/cwc.c | 2 ++ src/input/mpegts.h | 14 +++++--- src/input/mpegts/dvb_psi.c | 5 +-- src/input/mpegts/mpegts_input.c | 2 +- src/input/mpegts/mpegts_table.c | 57 +++++++++++++++++++++++++++++---- 6 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 779981a4..e7027262 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -1074,6 +1074,8 @@ capmt_service_start(service_t *s) tvhlog(LOG_DEBUG, "capmt", "New caid 0x%04X for service \"%s\"", c->caid, t->s_dvb_svcname); + mpegts_table_register_caid(((mpegts_service_t *)s)->s_dvb_mux, c->caid); + /* add it to list */ cce = calloc(1, sizeof(capmt_caid_ecm_t)); cce->cce_caid = c->caid; diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 2d838f3b..63e3bb5d 100755 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -2031,6 +2031,8 @@ cwc_service_start(service_t *t) if (ct) continue; + mpegts_table_register_caid(((mpegts_service_t *)t)->s_dvb_mux, pcard->cwc_caid); + ct = calloc(1, sizeof(cwc_service_t)); tvhcsa_init(&ct->cs_csa); ct->cs_cwc = cwc; diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 80a5a0a5..24068b98 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -140,10 +140,12 @@ struct mpegts_table */ int mt_flags; -#define MT_CRC 0x1 -#define MT_FULL 0x2 -#define MT_QUICKREQ 0x4 -#define MT_RECORD 0x8 +#define MT_CRC 0x01 +#define MT_FULL 0x02 +#define MT_QUICKREQ 0x04 +#define MT_RECORD 0x08 +#define MT_SKIPSUBS 0x10 +#define MT_SCANSUBS 0x20 /** * Cycle queue @@ -169,6 +171,7 @@ struct mpegts_table int mt_complete; int mt_incomplete; int mt_finished; + int mt_subscribed; int mt_count; @@ -696,6 +699,8 @@ void mpegts_input_close_pid void mpegts_table_dispatch (const uint8_t *sec, size_t r, void *mt); +static inline void mpegts_table_grab + (mpegts_table_t *mt) { mt->mt_refcount++; } void mpegts_table_release_ (mpegts_table_t *mt); static inline void mpegts_table_release @@ -710,6 +715,7 @@ mpegts_table_t *mpegts_table_add void mpegts_table_flush_all (mpegts_mux_t *mm); void mpegts_table_destroy ( mpegts_table_t *mt ); +void mpegts_table_register_caid ( mpegts_mux_t *mm, uint16_t caid ); mpegts_service_t *mpegts_service_create0 ( mpegts_service_t *ms, const idclass_t *class, const char *uuid, diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index f4ce6b11..b912a0fd 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -592,7 +592,8 @@ dvb_pat_callback int save = 0; if ((s = mpegts_service_find(mm, sid, pid, 1, &save))) { mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK, dvb_pmt_callback, - NULL, "pmt", MT_CRC | MT_QUICKREQ, pid); + NULL, "pmt", MT_CRC | MT_QUICKREQ | MT_SCANSUBS, + pid); if (save) service_request_save((service_t*)s, 1); @@ -660,7 +661,7 @@ dvb_cat_callback (uint16_t)caid, (uint16_t)caid, pid, pid); if(pid != 0) mpegts_table_add(mm, 0, 0, dvb_ca_callback, - (void*)caid, "ca", MT_FULL, pid); + (void*)caid, "ca", MT_FULL | MT_SKIPSUBS, pid); break; default: break; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index fa9bbc35..2b3cd990 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -678,8 +678,8 @@ mpegts_input_table_dispatch ( mpegts_mux_t *mm, mpegts_table_feed_t *mtf ) /* Collate - tables may be removed during callbacks */ LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + mpegts_table_grab(mt); vec[i++] = mt; - mt->mt_refcount++; } assert(i == len); diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index b3eb8094..f0be04ad 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -105,7 +105,8 @@ mpegts_table_destroy ( mpegts_table_t *mt ) LIST_REMOVE(mt, mt_link); mt->mt_destroyed = 1; mt->mt_mux->mm_num_tables--; - mt->mt_mux->mm_close_table(mt->mt_mux, mt); + if (mt->mt_subscribed) + mt->mt_mux->mm_close_table(mt->mt_mux, mt); while ((st = RB_FIRST(&mt->mt_state))) { RB_REMOVE(&mt->mt_state, st, link); free(st); @@ -126,13 +127,34 @@ mpegts_table_add const char *name, int flags, int pid ) { mpegts_table_t *mt; + int subscribe = 1; /* Check for existing */ LIST_FOREACH(mt, &mm->mm_tables, mt_link) { - if ( mt->mt_pid == pid && - mt->mt_callback == callback && - mt->mt_opaque == opaque ) - return mt; + if (mt->mt_opaque != opaque) + continue; + if (mt->mt_pid < 0) { + if (strcmp(mt->mt_name, name)) + continue; + mt->mt_callback = callback; + mt->mt_pid = pid; + mt->mt_table = tableid; + mt->mt_subscribed = 1; + mm->mm_open_table(mm, mt); + } else if (pid >= 0) { + if (mt->mt_pid != pid) + continue; + if (mt->mt_callback != callback) + continue; + } else { + if (strcmp(mt->mt_name, name)) + continue; + if (!(flags & MT_SKIPSUBS) && !mt->mt_subscribed) { + mt->mt_subscribed = 1; + mm->mm_open_table(mm, mt); + } + } + return mt; } tvhtrace("mpegts", "add %s table %02X/%02X (%d) pid %04X (%d)", @@ -145,7 +167,7 @@ mpegts_table_add mt->mt_callback = callback; mt->mt_opaque = opaque; mt->mt_pid = pid; - mt->mt_flags = flags; + mt->mt_flags = flags & ~(MT_SKIPSUBS|MT_SCANSUBS); mt->mt_table = tableid; mt->mt_mask = mask; mt->mt_mux = mm; @@ -154,7 +176,18 @@ mpegts_table_add mm->mm_num_tables++; /* Open table */ - mm->mm_open_table(mm, mt); + if (pid < 0) { + subscribe = 0; + } else if (flags & MT_SKIPSUBS) { + subscribe = 0; + } else if (flags & MT_SCANSUBS) { + if (mm->mm_initial_scan_status == MM_SCAN_DONE) + subscribe = 0; + } + if (subscribe) { + mt->mt_subscribed = 1; + mm->mm_open_table(mm, mt); + } return mt; } @@ -169,6 +202,16 @@ mpegts_table_flush_all ( mpegts_mux_t *mm ) mpegts_table_destroy(mt); } +/** + * Register wanted CAID + */ +void +mpegts_table_register_caid ( mpegts_mux_t *mm, uint16_t caid ) +{ + uintptr_t ca = caid; + mpegts_table_add(mm, 0, 0, NULL, (void *)ca, "ca", MT_FULL, -1); +} + /* * Section assembly */