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;
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;
*/
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
int mt_complete;
int mt_incomplete;
int mt_finished;
+ int mt_subscribed;
int mt_count;
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
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,
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);
(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;
/* 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);
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);
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)",
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;
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;
}
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
*/