diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index e4fb7e90..5b505230 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -1585,7 +1585,8 @@ capmt_caid_change(th_descrambler_t *td) /* search ecmpid in list */ LIST_FOREACH(cce, &ct->ct_caid_ecm, cce_link) if (c->use && cce->cce_caid == c->caid && cce->cce_providerid == c->providerid) - break; + if (!t->s_dvb_forcecaid || t->s_dvb_forcecaid == cce->cce_caid) + break; if (cce) continue; tvhlog(LOG_DEBUG, "capmt", @@ -1867,6 +1868,8 @@ capmt_service_start(caclient_t *cac, service_t *s) LIST_FOREACH(c, &st->es_caids, link) { if(c == NULL || c->use == 0) continue; + if (t->s_dvb_forcecaid && t->s_dvb_forcecaid != c->caid) + continue; tvhlog(LOG_DEBUG, "capmt", "%s: New caid 0x%04X for service \"%s\"", capmt_name(capmt), c->caid, t->s_dvb_svcname); diff --git a/src/descrambler/constcw.c b/src/descrambler/constcw.c index 6ac6e0df..731751a5 100644 --- a/src/descrambler/constcw.c +++ b/src/descrambler/constcw.c @@ -110,6 +110,9 @@ constcw_service_start(caclient_t *cac, service_t *t) return; mt = (mpegts_service_t *)t; + if (mt->s_dvb_forcecaid && mt->s_dvb_forcecaid != ccw->ccw_caid) + return; + if (mt->s_dvb_service_id != ccw->ccw_sid) return; @@ -122,18 +125,20 @@ constcw_service_start(caclient_t *cac, service_t *t) if (ct) return; - pthread_mutex_lock(&t->s_stream_mutex); - TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) { - LIST_FOREACH(c, &st->es_caids, link) { - if (c->use && c->caid == ccw->ccw_caid && - c->providerid == ccw->ccw_providerid) - break; + if (!mt->s_dvb_forcecaid) { + pthread_mutex_lock(&t->s_stream_mutex); + TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) { + LIST_FOREACH(c, &st->es_caids, link) { + if (c->use && c->caid == ccw->ccw_caid && + c->providerid == ccw->ccw_providerid) + break; + } + if (c) break; } - if (c) break; + pthread_mutex_unlock(&t->s_stream_mutex); + if (st == NULL) + return; } - pthread_mutex_unlock(&t->s_stream_mutex); - if (st == NULL) - return; ct = calloc(1, sizeof(constcw_service_t)); td = (th_descrambler_t *)ct; diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 0dc61502..cf26c11a 100755 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -2008,7 +2008,9 @@ cwc_service_start(caclient_t *cac, service_t *t) continue; LIST_FOREACH(c, &st->es_caids, link) { if (c->use && c->caid == pcard->cwc_caid) - break; + if (!((mpegts_service_t *)t)->s_dvb_forcecaid || + ((mpegts_service_t *)t)->s_dvb_forcecaid == c->caid) + break; } if (c) break; } diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 330ffdc4..225b74b5 100755 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -102,13 +102,17 @@ descrambler_service_start ( service_t *t ) th_descrambler_runtime_t *dr; elementary_stream_t *st; - TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) - if (LIST_FIRST(&st->es_caids)) - break; + if (!((mpegts_service_t *)t)->s_dvb_forcecaid) { - /* Do not run descrambler on FTA channels */ - if (!st) - return; + TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) + if (LIST_FIRST(&st->es_caids)) + break; + + /* Do not run descrambler on FTA channels */ + if (!st) + return; + + } ((mpegts_service_t *)t)->s_dvb_mux->mm_descrambler_flush = 0; if (t->s_descramble == NULL) { diff --git a/src/input/mpegts.h b/src/input/mpegts.h index addb8f9a..acbf49db 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -435,6 +435,7 @@ struct mpegts_service char *s_dvb_charset; uint16_t s_dvb_prefcapid; int s_dvb_prefcapid_lock; + uint16_t s_dvb_forcecaid; /* * EIT/EPG control diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 0e29edc1..321268da 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -168,6 +168,13 @@ const idclass_t mpegts_service_class = .opts = PO_ADVANCED, .list = mpegts_service_pref_capid_lock_list, }, + { + .type = PT_U16, + .id = "force_caid", + .name = "Force CA ID (e.g. 0x2600)", + .off = offsetof(mpegts_service_t, s_dvb_forcecaid), + .opts = PO_ADVANCED | PO_HEXA, + }, {}, } };