td->td_nicename,
dr->dr_key_const ? " (const)" : "");
td->td_keystate = DS_IDLE;
- if (td->td_ecm_idle)
+ if (td->td_ecm_idle) {
+ pthread_mutex_unlock(&t->s_stream_mutex);
td->td_ecm_idle(td);
+ pthread_mutex_lock(&t->s_stream_mutex);
+ }
goto fin;
}
while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
LIST_REMOVE(des, link);
free(des->last_data);
- free(des);
+ if (atomic_dec(&des->refcnt, 1) == 0)
+ free(des);
}
}
pthread_mutex_unlock(&mux->mm_descrambler_lock);
descrambler_section_t *ds;
descrambler_ecmsec_t *des;
th_descrambler_runtime_t *dr;
+ LIST_HEAD(,descrambler_ecmsec) sections;
int emm = (mt->mt_flags & MT_FAST) == 0;
if (len < 6)
return 0;
+ LIST_INIT(§ions);
pthread_mutex_lock(&mt->mt_mux->mm_descrambler_lock);
TAILQ_FOREACH(ds, &dt->sections, link) {
if (!emm) {
} else {
des->last_data_len = 0;
}
- ds->callback(ds->opaque, mt->mt_pid, ptr, len, emm);
+ des->changed = 2;
+ } else {
+ des->changed = des->last_data != NULL ? 1 : 0;
+ }
+ atomic_add(&des->refcnt, 1);
+ des->callback = ds->callback;
+ des->opaque = ds->opaque;
+ LIST_INSERT_HEAD(§ions, des, active_link);
+ }
+ pthread_mutex_unlock(&mt->mt_mux->mm_descrambler_lock);
+
+ LIST_FOREACH(des, §ions, active_link) {
+ if (des->changed == 2) {
+ des->callback(des->opaque, mt->mt_pid, ptr, len, emm);
if (!emm) { /* ECM */
mpegts_service_t *t = mt->mt_service;
if (t) {
+ pthread_mutex_lock(&t->s_stream_mutex);
/* The keys are requested from this moment */
dr = t->s_descramble;
if (dr) {
- if (!dr->dr_quick_ecm && !ds->quick_ecm_called) {
- ds->quick_ecm_called = 1;
+ if (!dr->dr_quick_ecm && !des->quick_ecm_called) {
+ des->quick_ecm_called = 1;
dr->dr_quick_ecm = descrambler_quick_ecm(mt->mt_service, mt->mt_pid);
if (dr->dr_quick_ecm)
tvhdebug(LS_DESCRAMBLER, "quick ECM enabled for service '%s'",
tvhtrace(LS_DESCRAMBLER, "ECM message %02x (section %d, len %d, pid %d) for service \"%s\"",
ptr[0], des->number, len, mt->mt_pid, t->s_dvb_svcname);
}
+ pthread_mutex_unlock(&t->s_stream_mutex);
} else
tvhtrace(LS_DESCRAMBLER, "Unknown fast table message %02x (section %d, len %d, pid %d)",
ptr[0], des->number, len, mt->mt_pid);
}
}
}
- pthread_mutex_unlock(&mt->mt_mux->mm_descrambler_lock);
+
+ while ((des = LIST_FIRST(§ions)) != NULL) {
+ LIST_REMOVE(des, active_link);
+ if (atomic_dec(&des->refcnt, 1) == 0)
+ free(des);
+ }
return 0;
}
while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
LIST_REMOVE(des, link);
free(des->last_data);
- free(des);
+ if (atomic_dec(&des->refcnt, 1) == 0)
+ free(des);
}
if (TAILQ_FIRST(&dt->sections) == NULL) {
TAILQ_REMOVE(&mux->mm_descrambler_tables, dt, link);
while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
LIST_REMOVE(des, link);
free(des->last_data);
- free(des);
+ if (atomic_dec(&des->refcnt, 1) == 0)
+ free(des);
}
free(ds);
}