} th_descrambler_runtime_t;
typedef void (*descrambler_section_callback_t)
- (void *opaque, int pid, const uint8_t *section, int section_len);
+ (void *opaque, int pid, const uint8_t *section, int section_len, int emm);
/**
* Track required PIDs
static void capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force);
static void capmt_send_request(capmt_service_t *ct, int lm);
static void capmt_table_input(void *opaque, int pid,
- const uint8_t *data, int len);
+ const uint8_t *data, int len, int emm);
static void capmt_send_client_info(capmt_t *capmt);
/**
mux = mmi ? mmi->mmi_mux : NULL;
o->pid = -1; /* block for new registrations */
o->pid_refs = 0;
+ if (o->ecm)
+ pid = DESCRAMBLER_ECM_PID(pid);
o->ecm = -1;
if (mux) {
pthread_mutex_unlock(&capmt->capmt_mutex);
*
*/
static void
-capmt_table_input(void *opaque, int pid, const uint8_t *data, int len)
+capmt_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm)
{
capmt_opaque_t *o = opaque;
capmt_t *capmt = o->capmt;
int i, demux_index, filter_index;
+ capmt_dmx_t *df;
capmt_filters_t *cf;
dmx_filter_t *f;
+ int flags = emm ? 0 : CAPMT_MSG_FAST;
/* Validate */
if (data == NULL || len > 4096) return;
cf = &capmt->capmt_demuxes.filters[demux_index];
if (cf->adapter != o->adapter)
continue;
- for (filter_index = 0; filter_index < cf->max; filter_index++)
- if (cf->dmx[filter_index].pid == pid) {
+ for (filter_index = 0; filter_index < cf->max; filter_index++) {
+ df = &cf->dmx[filter_index];
+ if (df->pid == pid && (df->flags & CAPMT_MSG_FAST) == flags) {
f = &cf->dmx[filter_index].filter;
if (f->mode[0] != 0)
continue;
filter_index, data, len,
cf->dmx[filter_index].flags);
}
+ }
}
pthread_mutex_unlock(&capmt->capmt_mutex);
*
*/
static void
-cwc_emm(void *opaque, int pid, const uint8_t *data, int len)
+cwc_emm(void *opaque, int pid, const uint8_t *data, int len, int emm)
{
struct cs_card_data *pcard = opaque;
cwc_t *cwc;
* t->s_streaming_mutex is held
*/
static void
-cwc_table_input(void *opaque, int pid, const uint8_t *data, int len)
+cwc_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm)
{
cwc_service_t *ct = opaque;
elementary_stream_t *st;
for (i = 0; i < CWC_ES_PIDS; i++)
if (ct->cs_epids[i])
- descrambler_close_pid(ct->cs_mux, ct, ct->cs_epids[i]);
+ descrambler_close_pid(ct->cs_mux, ct,
+ DESCRAMBLER_ECM_PID(ct->cs_epids[i]));
cwc_service_pid_free(ct);
} else {
des->last_data_len = 0;
}
- ds->callback(ds->opaque, mt->mt_pid, ptr, len);
+ ds->callback(ds->opaque, mt->mt_pid, ptr, len, emm);
if (!emm) { /* ECM */
mpegts_service_t *t = mt->mt_service;
if (t) {
return 0;
if (mux->mm_descrambler_flush)
return 0;
- flags = pid >> 16;
+ flags = (pid >> 16) & MT_FAST;
pid &= 0x1fff;
TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
- if (dt->table->mt_pid != pid)
+ if (dt->table->mt_pid != pid && (dt->table->mt_flags & MT_FAST) != flags)
continue;
TAILQ_FOREACH(ds, &dt->sections, link) {
if (ds->opaque == opaque)
dt = calloc(1, sizeof(*dt));
TAILQ_INIT(&dt->sections);
dt->table = mpegts_table_add(mux, 0, 0, descrambler_table_callback,
- dt, "descrambler",
+ dt, (flags & MT_FAST) ? "ecm" : "emm",
MT_FULL | MT_DEFER | flags, pid,
MPS_WEIGHT_CA);
if (dt->table)
descrambler_table_t *dt;
descrambler_section_t *ds;
descrambler_ecmsec_t *des;
+ int flags;
if (mux == NULL)
return 0;
- pid &= 0x1fff;
+ flags = (pid >> 16) & MT_FAST;
+ pid &= 0x1fff;
TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
- if (dt->table->mt_pid != pid)
+ if (dt->table->mt_pid != pid || (dt->table->mt_flags & MT_FAST) != flags)
continue;
TAILQ_FOREACH(ds, &dt->sections, link) {
if (ds->opaque == opaque) {
TAILQ_REMOVE(&dt->sections, ds, link);
- ds->callback(ds->opaque, -1, NULL, 0);
+ ds->callback(ds->opaque, -1, NULL, 0, (flags & MT_FAST) == 0);
while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
LIST_REMOVE(des, link);
free(des->last_data);
free(dt);
}
free(ds);
- tvhtrace("descrambler", "mux %p close pid %04X (%i) for %p", mux, pid, pid, opaque);
+ tvhtrace("descrambler", "mux %p close pid %04X (%i) (flags 0x%04x) for %p", mux, pid, pid, flags, opaque);
return 1;
}
}
while ((dt = TAILQ_FIRST(&mux->mm_descrambler_tables)) != NULL) {
while ((ds = TAILQ_FIRST(&dt->sections)) != NULL) {
TAILQ_REMOVE(&dt->sections, ds, link);
- ds->callback(ds->opaque, -1, NULL, 0);
+ ds->callback(ds->opaque, -1, NULL, 0, (dt->table->mt_flags & MT_FAST) ? 0 : 1);
while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
LIST_REMOVE(des, link);
free(des->last_data);