#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;
* 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 );
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
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*);
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);
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;
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) {
/* 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);
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);
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) {
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) {
}
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);
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);
}
/* **************************************************************************
/* 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);
#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;
}
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
}
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);
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;
}
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;
}
}
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--;
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;
}
}
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;
}
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);
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;
}
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);
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);
}
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;
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));
}
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;
tr = lfe->sf_req;
if (tr) {
- mpegts_pid_add(&tr->sf_pids, pid);
+ mpegts_pid_add(&tr->sf_pids, pid, weight);
return 1;
}
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);
}
}
} 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);
{
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);
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;
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;
} 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);
* 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;
}
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;
}
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:
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;
}
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);
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;
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);
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;
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++;
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, "<none>");
tvhdebug("satips", "%i/%s/%d: %s from %s:%d %s",
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);
}