From: Jaroslav Kysela Date: Mon, 27 Apr 2015 17:31:49 +0000 (+0200) Subject: mpegts: implemented weighted PID subscriptions (sequential PMT scan) X-Git-Tag: v4.1~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2623cc52d9b42b5e2b421d9afa26b4489da5acb0;p=thirdparty%2Ftvheadend.git mpegts: implemented weighted PID subscriptions (sequential PMT scan) --- diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 474551e84..f81f0f777 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -37,7 +37,7 @@ #define MPEGTS_PID_NONE 0xFFFF /* Types */ -typedef int16_t mpegts_apid_t; +typedef struct mpegts_apid mpegts_apid_t; typedef struct mpegts_apids mpegts_apids_t; typedef struct mpegts_table mpegts_table_t; typedef struct mpegts_network mpegts_network_t; @@ -78,11 +78,17 @@ void mpegts_done ( void ); * PIDs * *************************************************************************/ +struct mpegts_apid { + uint16_t pid; + uint16_t weight; +}; + struct mpegts_apids { mpegts_apid_t *pids; int alloc; int count; int all; + int sorted; }; int mpegts_pid_init ( mpegts_apids_t *pids ); @@ -90,17 +96,21 @@ void mpegts_pid_done ( mpegts_apids_t *pids ); mpegts_apids_t *mpegts_pid_alloc ( void ); void mpegts_pid_destroy ( mpegts_apids_t **pids ); void mpegts_pid_reset ( mpegts_apids_t *pids ); -int mpegts_pid_add ( mpegts_apids_t *pids, mpegts_apid_t pid ); +int mpegts_pid_add ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ); int mpegts_pid_add_group ( mpegts_apids_t *pids, mpegts_apids_t *vals ); -int mpegts_pid_del ( mpegts_apids_t *pids, mpegts_apid_t pid ); +int mpegts_pid_del ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ); int mpegts_pid_del_group ( mpegts_apids_t *pids, mpegts_apids_t *vals ); -int mpegts_pid_find_index ( mpegts_apids_t *pids, mpegts_apid_t pid ); -static inline int mpegts_pid_exists ( mpegts_apids_t *pids, mpegts_apid_t pid ) - { return pids->all || mpegts_pid_find_index(pids, pid) >= 0; } +int mpegts_pid_find_windex ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ); +int mpegts_pid_find_rindex ( mpegts_apids_t *pids, uint16_t pid ); +static inline int mpegts_pid_wexists ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ) + { return pids->all || mpegts_pid_find_windex(pids, pid, weight) >= 0; } +static inline int mpegts_pid_rexists ( mpegts_apids_t *pids, uint16_t pid ) + { return pids->all || mpegts_pid_find_rindex(pids, pid) >= 0; } int mpegts_pid_copy ( mpegts_apids_t *dst, mpegts_apids_t *src ); int mpegts_pid_compare ( mpegts_apids_t *dst, mpegts_apids_t *src, mpegts_apids_t *add, mpegts_apids_t *del ); -int mpegts_pid_dump ( mpegts_apids_t *pids, char *buf, int len ); +int mpegts_pid_weighted( mpegts_apids_t *dst, mpegts_apids_t *src, int limit ); +int mpegts_pid_dump ( mpegts_apids_t *pids, char *buf, int len, int wflag, int raw ); /* ************************************************************************** * Data / SI processing @@ -453,6 +463,7 @@ struct mpegts_mux int (*mm_is_enabled) (mpegts_mux_t *mm); void (*mm_stop) (mpegts_mux_t *mm, int force, int reason); void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*,int subscribe); + void (*mm_unsubscribe_table)(mpegts_mux_t*,mpegts_table_t*); void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*); void (*mm_create_instances) (mpegts_mux_t*); int (*mm_is_epg) (mpegts_mux_t*); @@ -826,6 +837,7 @@ int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid ); int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ); void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ); +void mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt ); void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ); void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int reason); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 46db8d6a1..2baa3f1ce 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -548,6 +548,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, mpegts_mux_t *mm = s->s_dvb_mux; elementary_stream_t *st; mpegts_apids_t *pids; + mpegts_apid_t *p; mpegts_service_t *s2; int i; @@ -566,8 +567,8 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, mi->mi_open_pid(mi, mm, s->s_pmt_pid, MPS_SERVICE, MPS_WEIGHT_PMT, s); mi->mi_open_pid(mi, mm, s->s_pcr_pid, MPS_SERVICE, MPS_WEIGHT_PCR, s); - mpegts_pid_add(pids, s->s_pmt_pid); - mpegts_pid_add(pids, s->s_pcr_pid); + mpegts_pid_add(pids, s->s_pmt_pid, MPS_WEIGHT_PMT); + mpegts_pid_add(pids, s->s_pcr_pid, MPS_WEIGHT_PCR); /* Open only filtered components here */ TAILQ_FOREACH(st, &s->s_filt_components, es_filt_link) if (st->es_type != SCT_CA) { @@ -578,7 +579,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, /* Ensure that filtered PIDs are not send in ts_recv_raw */ TAILQ_FOREACH(st, &s->s_filt_components, es_filt_link) if (st->es_type != SCT_CA && st->es_pid >= 0 && st->es_pid < 8192) - mpegts_pid_add(pids, st->es_pid); + mpegts_pid_add(pids, st->es_pid, mps_weight(st)); LIST_FOREACH(s2, &s->s_masters, s_masters_link) { pthread_mutex_lock(&s2->s_stream_mutex); @@ -593,8 +594,10 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, if (pids->all) { mi->mi_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW | MPS_ALL, MPS_WEIGHT_RAW, s); } else { - for (i = 0; i < pids->count; i++) - mi->mi_open_pid(mi, mm, pids->pids[i], MPS_RAW, MPS_WEIGHT_RAW, s); + for (i = 0; i < pids->count; i++) { + p = &pids->pids[i]; + mi->mi_open_pid(mi, mm, p->pid, MPS_RAW, p->weight, s); + } } } else if (flags & SUBSCRIPTION_TABLES) { mi->mi_open_pid(mi, mm, MPEGTS_TABLES_PID, MPS_RAW | MPS_TABLES, MPS_WEIGHT_PAT, s); @@ -643,8 +646,8 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) mi->mi_close_pid(mi, mm, s->s_pmt_pid, MPS_SERVICE, MPS_WEIGHT_PMT, s); mi->mi_close_pid(mi, mm, s->s_pcr_pid, MPS_SERVICE, MPS_WEIGHT_PCR, s); - mpegts_pid_del(pids, s->s_pmt_pid); - mpegts_pid_del(pids, s->s_pcr_pid); + mpegts_pid_del(pids, s->s_pmt_pid, MPS_WEIGHT_PMT); + mpegts_pid_del(pids, s->s_pcr_pid, MPS_WEIGHT_PCR); /* Close all opened PIDs (the component filter may be changed at runtime) */ TAILQ_FOREACH(st, &s->s_components, es_link) { if (st->es_pid_opened) { @@ -652,7 +655,7 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) mi->mi_close_pid(mi, mm, st->es_pid, MPS_SERVICE, mps_weight(st), s); } if (st->es_pid >= 0 && st->es_pid < 8192) - mpegts_pid_del(pids, st->es_pid); + mpegts_pid_del(pids, st->es_pid, mps_weight(st)); } LIST_FOREACH(s2, &s->s_masters, s_masters_link) { diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index fb0db5a69..b6bc532d4 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -818,12 +818,35 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ) } void -mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) +mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) { mpegts_input_t *mi; lock_assert(&mm->mm_tables_lock); + mi = mm->mm_active->mmi_input; + if (mt->mt_subscribed) { + mpegts_table_grab(mt); + mt->mt_subscribed = 0; + pthread_mutex_unlock(&mm->mm_tables_lock); + pthread_mutex_lock(&mi->mi_output_lock); + mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt); + pthread_mutex_unlock(&mi->mi_output_lock); + pthread_mutex_lock(&mm->mm_tables_lock); + mpegts_table_release(mt); + } + if ((mt->mt_flags & MT_DEFER) && mt->mt_defer_cmd == MT_DEFER_OPEN_PID) { + TAILQ_REMOVE(&mm->mm_defer_tables, mt, mt_defer_link); + mt->mt_defer_cmd = 0; + mpegts_table_release(mt); + } +} + +void +mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) +{ + lock_assert(&mm->mm_tables_lock); + if (!mm->mm_active || !mm->mm_active->mmi_input) { if (mt->mt_defer_cmd) { TAILQ_REMOVE(&mm->mm_defer_tables, mt, mt_defer_link); @@ -852,19 +875,9 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) TAILQ_INSERT_TAIL(&mm->mm_defer_tables, mt, mt_defer_link); return; } - mi = mm->mm_active->mmi_input; LIST_REMOVE(mt, mt_link); mm->mm_num_tables--; - if (mt->mt_subscribed) { - mpegts_table_grab(mt); - mt->mt_subscribed = 0; - pthread_mutex_unlock(&mm->mm_tables_lock); - pthread_mutex_lock(&mi->mi_output_lock); - mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt); - pthread_mutex_unlock(&mi->mi_output_lock); - pthread_mutex_lock(&mm->mm_tables_lock); - mpegts_table_release(mt); - } + mm->mm_unsubscribe_table(mm, mt); } /* ************************************************************************** @@ -1030,6 +1043,7 @@ mpegts_mux_create0 /* Table processing */ mm->mm_open_table = mpegts_mux_open_table; + mm->mm_unsubscribe_table = mpegts_mux_unsubscribe_table; mm->mm_close_table = mpegts_mux_close_table; pthread_mutex_init(&mm->mm_tables_lock, NULL); TAILQ_INIT(&mm->mm_table_queue); diff --git a/src/input/mpegts/mpegts_pid.c b/src/input/mpegts/mpegts_pid.c index 9d4e8bc37..5a94b3446 100644 --- a/src/input/mpegts/mpegts_pid.c +++ b/src/input/mpegts/mpegts_pid.c @@ -19,11 +19,43 @@ #include "tvheadend.h" #include "input.h" +static int +pid_cmp(uint16_t pid, uint16_t weight, mpegts_apid_t *p2) +{ + if (pid < p2->pid) + return 1; + if (pid > p2->pid) + return -1; + if (weight < p2->weight) + return 1; + if (weight > p2->weight) + return -1; + return 0; +} + +static int +pid_wcmp(const void *_p1, const void *_p2) +{ + const mpegts_apid_t *p1 = _p1; + const mpegts_apid_t *p2 = _p2; + if (p1->weight < p2->weight) + return 1; + if (p1->weight > p2->weight) + return -1; + /* note: prefer lower PIDs - they usually contain more important streams */ + if (p1->pid > p2->pid) + return 1; + if (p1->pid < p2->pid) + return -1; + return 0; +} + int mpegts_pid_init(mpegts_apids_t *pids) { assert(pids); memset(pids, 0, sizeof(*pids)); + pids->sorted = 1; return 0; } @@ -40,7 +72,10 @@ mpegts_pid_done(mpegts_apids_t *pids) mpegts_apids_t * mpegts_pid_alloc(void) { - return calloc(1, sizeof(mpegts_apids_t)); + mpegts_apids_t *r = calloc(1, sizeof(mpegts_apids_t)); + if (r) + r->sorted = 1; + return r; } void @@ -60,12 +95,12 @@ mpegts_pid_reset(mpegts_apids_t *pids) } int -mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid) +mpegts_pid_add(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) { mpegts_apid_t *p; int i; - if (mpegts_pid_exists(pids, pid)) + if (mpegts_pid_wexists(pids, pid, weight)) return 0; assert(pids); assert(pid >= 0 && pid <= 8191); @@ -78,9 +113,15 @@ mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid) pids->alloc = i; } p = pids->pids; - for (i = pids->count++; i > 0 && p[i - 1] > pid; i--) - p[i] = p[i - 1]; - p[i] = pid; + if (pids->sorted) { + for (i = pids->count++; i > 0 && pid_cmp(pid, weight, &p[i - 1]) > 0; i--) + p[i] = p[i - 1]; + p[i].pid = pid; + p[i].weight = weight; + } else { + p[pids->count].pid = pid; + p[pids->count++].weight = weight; + } return 0; } @@ -88,9 +129,11 @@ int mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals) { int i, r; + mpegts_apid_t *p; for (i = 0; i < vals->count; i++) { - r = mpegts_pid_add(pids, vals->pids[i]); + p = &vals->pids[i]; + r = mpegts_pid_add(pids, p->pid, p->weight); if (r) return r; } @@ -98,29 +141,64 @@ mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals) } int -mpegts_pid_find_index(mpegts_apids_t *pids, mpegts_apid_t pid) +mpegts_pid_find_windex(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) +{ + mpegts_apid_t *p = pids->pids; + int first, last, i, cmp; + + if (pids->sorted) { + first = 0; + last = pids->count - 1; + for (i = last / 2; first <= last; i = (first + last) / 2) { + cmp = pid_cmp(pid, weight, &p[i]); + if (cmp < 0) + first = i + 1; + else if (cmp == 0) + return i; + else + last = i - 1; + } + } else { + for (i = 0; i < pids->count; i++) + if (pid_cmp(pid, weight, &p[i]) == 0) + return i; + } + return -1; +} + +int +mpegts_pid_find_rindex(mpegts_apids_t *pids, uint16_t pid) { mpegts_apid_t *p = pids->pids; - int first = 0, last = pids->count - 1, i; - for (i = last / 2; first <= last; i = (first + last) / 2) { - if (p[i] < pid) - first = i + 1; - else if (p[i] == pid) - return i; - else - last = i - 1; + int i, first, last; + + if (pids->sorted) { + first = 0; + last = pids->count - 1; + for (i = last / 2; first <= last; i = (first + last) / 2) { + if (pid > p[i].pid) + first = i + 1; + else if (pid == p[i].pid) + return i; + else + last = i - 1; + } + } else { + for (i = 0; i < pids->count; i++) + if (pids->pids[i].pid == pid) + return i; } return -1; } int -mpegts_pid_del(mpegts_apids_t *pids, mpegts_apid_t pid) +mpegts_pid_del(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) { int i; assert(pids); assert(pid >= 0 && pid <= 8191); - if ((i = mpegts_pid_find_index(pids, pid)) >= 0) { + if ((i = mpegts_pid_find_windex(pids, pid, weight)) >= 0) { memmove(&pids->pids[i], &pids->pids[i+1], (pids->count - i - 1) * sizeof(mpegts_apid_t)); pids->count--; @@ -133,10 +211,12 @@ mpegts_pid_del(mpegts_apids_t *pids, mpegts_apid_t pid) int mpegts_pid_del_group(mpegts_apids_t *pids, mpegts_apids_t *vals) { + mpegts_apid_t *p; int i, r; for (i = 0; i < vals->count; i++) { - r = mpegts_pid_del(pids, vals->pids[i]); + p = &vals->pids[i]; + r = mpegts_pid_del(pids, p->pid, p->weight); if (r) return r; } @@ -159,6 +239,7 @@ mpegts_pid_copy(mpegts_apids_t *dst, mpegts_apids_t *src) } dst->count = src->count; dst->all = src->all; + dst->sorted = src->sorted; memcpy(dst->pids, src->pids, src->count * sizeof(mpegts_apid_t)); return 0; } @@ -167,6 +248,7 @@ int mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src, mpegts_apids_t *add, mpegts_apids_t *del) { + mpegts_apid_t *p; int i; assert(dst); @@ -178,28 +260,65 @@ mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src, mpegts_pid_copy(add, dst); return add->count > 0; } - for (i = 0; i < src->count; i++) - if (mpegts_pid_find_index(dst, src->pids[i]) < 0) - mpegts_pid_add(del, src->pids[i]); - for (i = 0; i < dst->count; i++) - if (mpegts_pid_find_index(src, dst->pids[i]) < 0) - mpegts_pid_add(add, dst->pids[i]); + for (i = 0; i < src->count; i++) { + p = &src->pids[i]; + if (mpegts_pid_find_windex(dst, p->pid, p->weight) < 0) + mpegts_pid_add(del, p->pid, p->weight); + } + for (i = 0; i < dst->count; i++) { + p = &dst->pids[i]; + if (mpegts_pid_find_windex(src, p->pid, p->weight) < 0) + mpegts_pid_add(add, p->pid, p->weight); + } return add->count || del->count; } int -mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len) +mpegts_pid_weighted(mpegts_apids_t *dst, mpegts_apids_t *pids, int limit) { + int i, j; + mpegts_pid_init(dst); + mpegts_pid_copy(dst, pids); + qsort(dst->pids, dst->count, sizeof(mpegts_apid_t), pid_wcmp); + for (i = j = 0; i < dst->count; i++) + if (j == 0 || (dst->pids[j-1].pid != dst->pids[i].pid)) { + if (j < limit || dst->pids[i].weight > MPS_WEIGHT_PMT_SCAN) { + dst->pids[j].weight = 0; + dst->pids[j++].pid = dst->pids[i].pid; + } + } + dst->count = j; + dst->sorted = 0; + return 0; +} + +int +mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len, int wflag, int raw) +{ + mpegts_apids_t spids; + mpegts_apid_t *p; int i, l = 0; - if (len < 1) { - if (len) - *buf = '\0'; + if (len < 1) return len; - } if (pids->all) return snprintf(buf, len, "all"); - for (i = 0; i < pids->count && l + 1 < len; i++) - tvh_strlcatf(buf, len, l, "%s%i", i > 0 ? "," : "", pids->pids[i]); + if (!raw) + mpegts_pid_weighted(&spids, pids, len / 2); + else { + mpegts_pid_init(&spids); + mpegts_pid_copy(&spids, pids); + } + *buf = '\0'; + if (wflag) { + for (i = 0; i < spids.count && l + 1 < len; i++) { + p = &spids.pids[i]; + tvh_strlcatf(buf, len, l, "%s%i(%i)", i > 0 ? "," : "", p->pid, p->weight); + } + } else { + for (i = 0; i < spids.count && l + 1 < len; i++) + tvh_strlcatf(buf, len, l, "%s%i", i > 0 ? "," : "", spids.pids[i].pid); + } + mpegts_pid_done(&spids); return l; } diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index c781ff078..7b3215e95 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -735,6 +735,7 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) mpegts_mux_t *mm = t->s_dvb_mux; mpegts_apids_t *p, *x; mpegts_apids_t add, del; + mpegts_apid_t *pi; int i; lock_assert(&global_lock); @@ -752,18 +753,24 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) if (!pids->all && x && x->all) { mi->mi_close_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, MPS_WEIGHT_RAW, t); mpegts_input_close_pids(mi, mm, t, 1); - for (i = 0; i < x->count; i++) - mi->mi_open_pid(mi, mm, x->pids[i], MPS_RAW, MPS_WEIGHT_RAW, t); + for (i = 0; i < x->count; i++) { + pi = &x->pids[i]; + mi->mi_open_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t); + } } else { if (pids->all) { mpegts_input_close_pids(mi, mm, t, 1); mi->mi_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, MPS_WEIGHT_RAW, t); } else { mpegts_pid_compare(p, x, &add, &del); - for (i = 0; i < del.count; i++) - mi->mi_close_pid(mi, mm, del.pids[i], MPS_RAW, MPS_WEIGHT_RAW, t); - for (i = 0; i < add.count; i++) - mi->mi_open_pid(mi, mm, add.pids[i], MPS_RAW, MPS_WEIGHT_RAW, t); + for (i = 0; i < del.count; i++) { + pi = &x->pids[i]; + mi->mi_close_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t); + } + for (i = 0; i < add.count; i++) { + pi = &x->pids[i]; + mi->mi_open_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t); + } mpegts_pid_done(&add); mpegts_pid_done(&del); } diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index beac5649a..67526d2a7 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -49,10 +49,16 @@ mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm ) assert(mm == mtm->mt_mux); - if(mm->mm_scan_state != MM_SCAN_STATE_ACTIVE) + pthread_mutex_lock(&mm->mm_tables_lock); + + if ((mtm->mt_flags & MT_ONESHOT) && (mtm->mt_complete && !mtm->mt_working)) + mm->mm_unsubscribe_table(mm, mtm); + + if (mm->mm_scan_state != MM_SCAN_STATE_ACTIVE) { + pthread_mutex_unlock(&mm->mm_tables_lock); return; + } - pthread_mutex_lock(&mm->mm_tables_lock); LIST_FOREACH(mt, &mm->mm_tables, mt_link) { if (!(mt->mt_flags & MT_QUICKREQ) && !mt->mt_working) continue; @@ -61,8 +67,7 @@ mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm ) return; } } - if (mtm->mt_flags & MT_ONESHOT) - mm->mm_close_table(mm, mtm); + pthread_mutex_unlock(&mm->mm_tables_lock); mpegts_mux_nice_name(mm, buf, sizeof(buf)); diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 48fda65eb..a60f6c0c5 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -530,7 +530,7 @@ satip_frontend_start_mux } static int -satip_frontend_add_pid( satip_frontend_t *lfe, int pid) +satip_frontend_add_pid( satip_frontend_t *lfe, int pid, int weight) { satip_tune_req_t *tr; @@ -539,7 +539,7 @@ satip_frontend_add_pid( satip_frontend_t *lfe, int pid) tr = lfe->sf_req; if (tr) { - mpegts_pid_add(&tr->sf_pids, pid); + mpegts_pid_add(&tr->sf_pids, pid, weight); return 1; } @@ -571,14 +571,14 @@ satip_frontend_open_pid mpegts_service_t *s; elementary_stream_t *st; LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) { - change |= satip_frontend_add_pid(lfe, s->s_pmt_pid); - change |= satip_frontend_add_pid(lfe, s->s_pcr_pid); + change |= satip_frontend_add_pid(lfe, s->s_pmt_pid, weight); + change |= satip_frontend_add_pid(lfe, s->s_pcr_pid, weight); TAILQ_FOREACH(st, &s->s_components, es_link) - change |= satip_frontend_add_pid(lfe, st->es_pid); + change |= satip_frontend_add_pid(lfe, st->es_pid, weight); } } } else { - change |= satip_frontend_add_pid(lfe, mp->mp_pid); + change |= satip_frontend_add_pid(lfe, mp->mp_pid, weight); } if (change) tvh_write(lfe->sf_dvr_pipe.wr, "c", 1); @@ -614,7 +614,7 @@ satip_frontend_close_pid } } } else { - change = mpegts_pid_del(&tr->sf_pids, pid) >= 0; + change = mpegts_pid_del(&tr->sf_pids, pid, weight) >= 0; } if (change) tvh_write(lfe->sf_dvr_pipe.wr, "c", 1); @@ -794,10 +794,10 @@ satip_frontend_pid_changed( http_client_t *rtsp, { satip_tune_req_t *tr; char *add, *del; - int i, j, r, any; + int i, j, r; int max_pids_len = lfe->sf_device->sd_pids_len; int max_pids_count = lfe->sf_device->sd_pids_max; - mpegts_apids_t padd, pdel; + mpegts_apids_t wpid, padd, pdel; pthread_mutex_lock(&lfe->sf_dvr_lock); @@ -808,15 +808,12 @@ satip_frontend_pid_changed( http_client_t *rtsp, return 0; } - any = tr->sf_pids.all; - - if (tr->sf_pids.count > max_pids_count) - any = lfe->sf_device->sd_fullmux_ok ? 1 : 0; - - if (any) { + if (tr->sf_pids.all) { +all: i = tr->sf_pids_tuned.all; - mpegts_pid_copy(&tr->sf_pids_tuned, &tr->sf_pids); + mpegts_pid_done(&tr->sf_pids_tuned); + tr->sf_pids_tuned.all = 1; pthread_mutex_unlock(&lfe->sf_dvr_lock); if (i) return 0; @@ -828,17 +825,16 @@ satip_frontend_pid_changed( http_client_t *rtsp, tr->sf_pids_tuned.all || tr->sf_pids.count == 0) { - j = tr->sf_pids.count; - if (j > lfe->sf_device->sd_pids_max) - j = lfe->sf_device->sd_pids_max; + mpegts_pid_weighted(&wpid, &tr->sf_pids, lfe->sf_device->sd_pids_max); + j = MIN(wpid.count, lfe->sf_device->sd_pids_max); add = alloca(1 + j * 5); add[0] = '\0'; - /* prioritize higher PIDs (tables are low prio) */ - for (i = tr->sf_pids.count - j; i < tr->sf_pids.count; i++) - sprintf(add + strlen(add), ",%i", tr->sf_pids.pids[i]); - mpegts_pid_copy(&tr->sf_pids_tuned, &tr->sf_pids); + for (i = 0; i < j; i++) + sprintf(add + strlen(add), ",%i", wpid.pids[i].pid); + mpegts_pid_copy(&tr->sf_pids_tuned, &wpid); tr->sf_pids_tuned.all = 0; pthread_mutex_unlock(&lfe->sf_dvr_lock); + mpegts_pid_done(&wpid); if (!j || add[0] == '\0') return 0; @@ -848,27 +844,35 @@ satip_frontend_pid_changed( http_client_t *rtsp, } else { - mpegts_pid_compare(&tr->sf_pids, &tr->sf_pids_tuned, &padd, &pdel); + mpegts_pid_weighted(&wpid, &tr->sf_pids, lfe->sf_device->sd_pids_max); + + if (wpid.count > max_pids_count) { + if (lfe->sf_device->sd_fullmux_ok) { + mpegts_pid_done(&wpid); + goto all; + } + } + + mpegts_pid_compare(&wpid, &tr->sf_pids_tuned, &padd, &pdel); add = alloca(1 + padd.count * 5); del = alloca(1 + pdel.count * 5); add[0] = del[0] = '\0'; for (i = 0; i < pdel.count; i++) { - sprintf(del + strlen(del), ",%i", pdel.pids[i]); - mpegts_pid_del(&tr->sf_pids_tuned, pdel.pids[i]); + sprintf(del + strlen(del), ",%i", pdel.pids[i].pid); + mpegts_pid_del(&tr->sf_pids_tuned, pdel.pids[i].pid, pdel.pids[i].weight); } - j = padd.count; - if (padd.count + tr->sf_pids_tuned.count > max_pids_count) - j = max_pids_count - tr->sf_pids_tuned.count; - /* prioritize higher PIDs (tables are low prio) */ - for (i = padd.count - j; i < padd.count; i++) - sprintf(add + strlen(add), ",%i", padd.pids[i]); + j = MIN(padd.count, lfe->sf_device->sd_pids_max); + for (i = 0; i < j; i++) + sprintf(add + strlen(add), ",%i", padd.pids[i].pid); - mpegts_pid_copy(&tr->sf_pids_tuned, &tr->sf_pids); + mpegts_pid_copy(&tr->sf_pids_tuned, &wpid); + tr->sf_pids_tuned.all = 0; pthread_mutex_unlock(&lfe->sf_dvr_lock); + mpegts_pid_done(&wpid); mpegts_pid_done(&padd); mpegts_pid_done(&pdel); diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index 44750bd9b..79269b7d4 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -239,7 +239,7 @@ ts_recv_raw(mpegts_service_t *t, const uint8_t *tsb, int len) * deliver this PID (decrambling) */ pid = (tsb[1] & 0x1f) << 8 | tsb[2]; - parent = mpegts_pid_exists(t->s_slaves_pids, pid); + parent = mpegts_pid_rexists(t->s_slaves_pids, pid); service_set_streaming_status_flags((service_t*)t, TSS_PACKETS); t->s_streaming_live |= TSS_LIVE; } diff --git a/src/satip/rtp.c b/src/satip/rtp.c index 92a911da7..cfee3c041 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -121,7 +121,7 @@ satip_rtp_loop(satip_rtp_session_t *rtp, uint8_t *data, int len) pid = ((data[1] & 0x1f) << 8) | data[2]; if (pid != last_pid && !rtp->pids.all) { for (i = 0; i < rtp->pids.count; i++) { - j = pids[i]; + j = pids[i].pid; if (pid < j) break; if (j == pid) goto found; } @@ -399,7 +399,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len) break; } - mpegts_pid_dump(&rtp->pids, pids, sizeof(pids)); + mpegts_pid_dump(&rtp->pids, pids, sizeof(pids), 0, 0); switch (rtp->dmc.dmc_fe_delsys) { case DVB_SYS_DVBS: diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index c33ba862a..cc3e5c225 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -391,7 +391,7 @@ rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids) if (st->es_type == SCT_CA) enc = 1; if (st->es_pid > 0) - if (pids == NULL || mpegts_pid_exists(pids, st->es_pid)) + if (pids == NULL || mpegts_pid_wexists(pids, st->es_pid, MPS_WEIGHT_RAW)) if ((SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type))) av = 1; } @@ -425,7 +425,7 @@ rtsp_manage_descramble(session_t *rs) idnode_set_add(found, &s->s_id, NULL); } else { for (i = 0; i < rs->pids.count; i++) { - s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i]); + s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i].pid); if (s != NULL && rtsp_validate_service(s, &rs->pids)) if (!idnode_set_exists(found, &s->s_id)) idnode_set_add(found, &s->s_id, NULL); @@ -522,7 +522,7 @@ rtsp_start if (!rs->subs) goto endclean; if (!rs->pids.all && rs->pids.count == 0) - mpegts_pid_add(&rs->pids, 0); + mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW); /* retrigger play when new setup arrived */ if (oldstate) { setup = 0; @@ -533,7 +533,7 @@ pids: if (!rs->subs) goto endclean; if (!rs->pids.all && rs->pids.count == 0) - mpegts_pid_add(&rs->pids, 0); + mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW); svc = (mpegts_service_t *)rs->subs->ths_raw_service; svc->s_update_pids(svc, &rs->pids); satip_rtp_update_pids((void *)(intptr_t)rs->stream, &rs->pids); @@ -548,7 +548,7 @@ pids: rs->frontend, rs->findex, &rs->mux->lm_tuning, &rs->pids); if (!rs->pids.all && rs->pids.count == 0) - mpegts_pid_add(&rs->pids, 0); + mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW); svc = (mpegts_service_t *)rs->subs->ths_raw_service; svc->s_update_pids(svc, &rs->pids); rs->state = STATE_PLAY; @@ -750,7 +750,7 @@ parse_pids(char *p, mpegts_apids_t *pids) pid = atoi(x); if (pid < 0 || pid > 8191) return -1; - mpegts_pid_add(pids, pid); + mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW); } x = strtok_r(NULL, ",", &saveptr); i++; @@ -1048,7 +1048,7 @@ play: dvb_mux_conf_str(dmc, buf, sizeof(buf)); r = strlen(buf); tvh_strlcatf(buf, sizeof(buf), r, " pids "); - if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r) == 0) + if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r, 0, 0) == 0) tvh_strlcatf(buf, sizeof(buf), r, ""); tvhdebug("satips", "%i/%s/%d: %s from %s:%d %s", diff --git a/src/webui/webui.c b/src/webui/webui.c index 4c4bbed62..e397925cf 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -831,7 +831,7 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight) if (i == 8192) pids.all = 1; else - mpegts_pid_add(&pids, i); + mpegts_pid_add(&pids, i, MPS_WEIGHT_RAW); } p = strtok_r(NULL, ",", &saveptr); }