void (*mi_stop_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
void (*mi_open_service) (mpegts_input_t*,mpegts_service_t*,int flags, int first);
void (*mi_close_service) (mpegts_input_t*,mpegts_service_t*);
- mpegts_pid_t *(*mi_open_pid)(mpegts_input_t*,mpegts_mux_t*,int,int,int,void*);
- int (*mi_close_pid) (mpegts_input_t*,mpegts_mux_t*,int,int,int,void*);
+ void (*mi_update_pids) (mpegts_input_t*,mpegts_mux_t*);
void (*mi_create_mux_instance) (mpegts_input_t*,mpegts_mux_t*);
void (*mi_started_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
void (*mi_stopping_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
int atsc_vct_callback
(struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
-void psi_tables_default ( struct mpegts_mux *mm );
-void psi_tables_dvb ( struct mpegts_mux *mm );
-void psi_tables_atsc_t ( struct mpegts_mux *mm );
-void psi_tables_atsc_c ( struct mpegts_mux *mm );
+void psi_tables_install
+ (mpegts_input_t *mi, mpegts_mux_t *mm, dvb_fe_delivery_system_t delsys);
mpegts_service_t *mpegts_service_create0
( mpegts_service_t *ms, const idclass_t *class, const char *uuid,
DVB_SYS_CMMB = 900,
DVB_SYS_DAB = 1000,
DVB_SYS_TURBO = 1100,
+ /* TVH internal */
+ DVB_SYS_ATSC_ALL = 9998,
+ DVB_SYS_UNKNOWN = 9999
} dvb_fe_delivery_system_t;
typedef enum dvb_fe_spectral_inversion {
* Install default table sets
*/
-void
+static void
psi_tables_default ( mpegts_mux_t *mm )
{
mpegts_table_add(mm, DVB_PAT_BASE, DVB_PAT_MASK, dvb_pat_callback,
}
#endif
-void
+static void
psi_tables_dvb ( mpegts_mux_t *mm )
{
mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
#endif
}
-void
+static void
psi_tables_atsc_c ( mpegts_mux_t *mm )
{
mpegts_table_add(mm, DVB_VCT_C_BASE, DVB_VCT_MASK, atsc_vct_callback,
DVB_VCT_PID, MPS_WEIGHT_VCT);
}
-void
+static void
psi_tables_atsc_t ( mpegts_mux_t *mm )
{
mpegts_table_add(mm, DVB_VCT_T_BASE, DVB_VCT_MASK, atsc_vct_callback,
NULL, "vct", MT_QUICKREQ | MT_CRC | MT_RECORD,
DVB_VCT_PID, MPS_WEIGHT_VCT);
}
+
+void
+psi_tables_install ( mpegts_input_t *mi, mpegts_mux_t *mm,
+ dvb_fe_delivery_system_t delsys)
+{
+ if (mi == NULL || mm == NULL)
+ return;
+
+ psi_tables_default(mm);
+
+ switch (delsys) {
+ case DVB_SYS_DVBC_ANNEX_A:
+ case DVB_SYS_DVBC_ANNEX_C:
+ case DVB_SYS_DVBT:
+ case DVB_SYS_DVBT2:
+ case DVB_SYS_DVBS:
+ case DVB_SYS_DVBS2:
+ case DVB_SYS_ISDBS:
+ psi_tables_dvb(mm);
+ break;
+ case DVB_SYS_TURBO:
+ case DVB_SYS_ATSC:
+ case DVB_SYS_ATSCMH:
+ psi_tables_atsc_t(mm);
+ break;
+ case DVB_SYS_DVBC_ANNEX_B:
+ psi_tables_atsc_c(mm);
+ break;
+ case DVB_SYS_NONE:
+ case DVB_SYS_DVBH:
+ case DVB_SYS_ISDBT:
+ case DVB_SYS_ISDBC:
+ case DVB_SYS_DTMB:
+ case DVB_SYS_CMMB:
+ case DVB_SYS_DSS:
+ case DVB_SYS_DAB:
+ break;
+ case DVB_SYS_ATSC_ALL:
+ psi_tables_atsc_c(mm);
+ psi_tables_atsc_t(mm);
+ break;
+ case DVB_SYS_UNKNOWN:
+ psi_tables_dvb(mm);
+ psi_tables_atsc_c(mm);
+ psi_tables_atsc_t(mm);
+ break;
+ break;
+ }
+
+ mi->mi_update_pids(mi, mm);
+}
/* Install table handlers */
mpegts_mux_t *mm = (mpegts_mux_t*)im;
- psi_tables_default(mm);
- if (im->mm_iptv_atsc) {
- psi_tables_atsc_t(mm);
- psi_tables_atsc_c(mm);
- } else
- psi_tables_dvb(mm);
+ if (mm->mm_active)
+ psi_tables_install(mm->mm_active->mmi_input, mm,
+ im->mm_iptv_atsc ? DVB_SYS_ATSC_ALL : DVB_SYS_DVBT);
}
/* **************************************************************************
return res;
}
-static mpegts_pid_t *
-linuxdvb_frontend_open_pid
- ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
-{
- linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
- mpegts_pid_t *mp;
- int change;
-
- if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, weight, owner)))
- return NULL;
-
- change = 0;
- pthread_mutex_lock(&lfe->lfe_dvr_lock);
- if (pid < MPEGTS_FULLMUX_PID)
- change = mpegts_pid_add(&lfe->lfe_pids, pid, weight) >= 0;
- else if (pid == MPEGTS_FULLMUX_PID) {
- change = lfe->lfe_pids.all == 0;
- lfe->lfe_pids.all = 1;
- }
- pthread_mutex_unlock(&lfe->lfe_dvr_lock);
-
- if (change && lfe->lfe_dvr_pipe.wr > 0)
- tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1);
-
- return mp;
-}
-
-static int
-linuxdvb_frontend_close_pid
- ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
+static void
+linuxdvb_frontend_update_pids
+ ( mpegts_input_t *mi, mpegts_mux_t *mm )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
mpegts_pid_t *mp;
mpegts_pid_sub_t *mps;
- int change, r;
- if ((r = mpegts_input_close_pid(mi, mm, pid, type, weight, owner)) <= 0)
- return r;
-
- change = 0;
pthread_mutex_lock(&lfe->lfe_dvr_lock);
- if (pid == MPEGTS_FULLMUX_PID) {
- change = lfe->lfe_pids.all != 0;
- lfe->lfe_pids.all = 0;
- } else if (pid < MPEGTS_FULLMUX_PID) {
- mpegts_pid_done(&lfe->lfe_pids);
- RB_FOREACH(mp, &mm->mm_pids, mp_link)
+ mpegts_pid_done(&lfe->lfe_pids);
+ RB_FOREACH(mp, &mm->mm_pids, mp_link) {
+ if (mp->mp_pid == MPEGTS_FULLMUX_PID)
+ lfe->lfe_pids.all = 1;
+ else if (mp->mp_pid < MPEGTS_FULLMUX_PID) {
RB_FOREACH(mps, &mp->mp_subs, mps_link)
mpegts_pid_add(&lfe->lfe_pids, mp->mp_pid, mps->mps_weight);
- change = 1;
+ }
}
pthread_mutex_unlock(&lfe->lfe_dvr_lock);
- if (change)
- tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1);
-
- return r;
+ tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1);
}
static idnode_set_t *
* Data processing
* *************************************************************************/
-static void
-linuxdvb_frontend_default_tables
- ( linuxdvb_frontend_t *lfe, dvb_mux_t *lm )
-{
- mpegts_mux_t *mm = (mpegts_mux_t*)lm;
-
- psi_tables_default(mm);
-
- /* ATSC */
- if (lfe->lfe_type == DVB_TYPE_ATSC) {
- if (lm->lm_tuning.dmc_fe_modulation == DVB_MOD_VSB_8)
- psi_tables_atsc_t(mm);
- else
- psi_tables_atsc_c(mm);
-
- /* DVB */
- } else {
- psi_tables_dvb(mm);
- }
-}
-
static inline int
ioctl_check( linuxdvb_frontend_t *lfe, int bit )
{
pthread_mutex_unlock(&lfe->lfe_dvr_lock);
/* Table handlers */
- linuxdvb_frontend_default_tables(lfe, (dvb_mux_t*)mm);
+ psi_tables_install((mpegts_input_t *)lfe, mm,
+ ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_type);
/* Re-arm (quick) */
} else {
lfe->mi_start_mux = linuxdvb_frontend_start_mux;
lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
lfe->mi_network_list = linuxdvb_frontend_network_list;
- lfe->mi_open_pid = linuxdvb_frontend_open_pid;
- lfe->mi_close_pid = linuxdvb_frontend_close_pid;
+ lfe->mi_update_pids = linuxdvb_frontend_update_pids;
lfe->mi_enabled_updated = linuxdvb_frontend_enabled_updated;
/* Adapter link */
if (mps->mps_owner != owner) continue;
pid = MPEGTS_FULLMUX_PID;
if (mps->mps_type & MPS_TABLES) pid = MPEGTS_TABLES_PID;
- mi->mi_close_pid(mi, mm, pid, mps->mps_type, mps->mps_weight, mps->mps_owner);
+ mpegts_input_close_pid(mi, mm, pid, mps->mps_type, mps->mps_weight, mps->mps_owner);
}
for (mp = RB_FIRST(&mm->mm_pids); mp; mp = mp_next) {
mp_next = RB_NEXT(mp, mp_link);
for (mps = RB_FIRST(&mp->mp_subs); mps; mps = mps_next) {
mps_next = RB_NEXT(mps, mps_link);
if (mps->mps_owner != owner) continue;
- mi->mi_close_pid(mi, mm, mp->mp_pid, mps->mps_type, mps->mps_weight, mps->mps_owner);
+ mpegts_input_close_pid(mi, mm, mp->mp_pid, mps->mps_type, mps->mps_weight, mps->mps_owner);
}
}
}
+
mpegts_pid_t *
mpegts_input_open_pid
( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
return 0;
}
+static void
+mpegts_input_update_pids
+ ( mpegts_input_t *mi, mpegts_mux_t *mm )
+{
+ /* nothing - override */
+}
+
static int mps_weight(elementary_stream_t *st)
{
if (SCT_ISVIDEO(st->es_type))
pids = mpegts_pid_alloc();
- 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_input_open_pid(mi, mm, s->s_pmt_pid, MPS_SERVICE, MPS_WEIGHT_PMT, s);
+ mpegts_input_open_pid(mi, mm, s->s_pcr_pid, MPS_SERVICE, MPS_WEIGHT_PCR, s);
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) {
st->es_pid_opened = 1;
- mi->mi_open_pid(mi, mm, st->es_pid, MPS_SERVICE, mps_weight(st), s);
+ mpegts_input_open_pid(mi, mm, st->es_pid, MPS_SERVICE, mps_weight(st), s);
}
/* Ensure that filtered PIDs are not send in ts_recv_raw */
} else {
if ((pids = s->s_pids) != NULL) {
if (pids->all) {
- mi->mi_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW | MPS_ALL, MPS_WEIGHT_RAW, s);
+ mpegts_input_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW | MPS_ALL, MPS_WEIGHT_RAW, s);
} else {
for (i = 0; i < pids->count; i++) {
p = &pids->pids[i];
- mi->mi_open_pid(mi, mm, p->pid, MPS_RAW, p->weight, s);
+ mpegts_input_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);
+ mpegts_input_open_pid(mi, mm, MPEGTS_TABLES_PID, MPS_RAW | MPS_TABLES, MPS_WEIGHT_PAT, s);
} else if (flags & SUBSCRIPTION_MINIMAL) {
- mi->mi_open_pid(mi, mm, DVB_PAT_PID, MPS_RAW, MPS_WEIGHT_PAT, s);
+ mpegts_input_open_pid(mi, mm, DVB_PAT_PID, MPS_RAW, MPS_WEIGHT_PAT, s);
}
}
dvb_pmt_callback, s, "pmt",
MT_CRC, s->s_pmt_pid, MPS_WEIGHT_PMT);
}
+
+ pthread_mutex_lock(&mi->mi_output_lock);
+ mi->mi_update_pids(mi, mm);
+ pthread_mutex_unlock(&mi->mi_output_lock);
}
void
pids = mpegts_pid_alloc();
- 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_input_close_pid(mi, mm, s->s_pmt_pid, MPS_SERVICE, MPS_WEIGHT_PMT, s);
+ mpegts_input_close_pid(mi, mm, s->s_pcr_pid, MPS_SERVICE, MPS_WEIGHT_PCR, s);
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) {
st->es_pid_opened = 0;
- mi->mi_close_pid(mi, mm, st->es_pid, MPS_SERVICE, mps_weight(st), s);
+ mpegts_input_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, mps_weight(st));
mpegts_input_close_pids(mi, mm, s, 1);
}
-
pthread_mutex_unlock(&s->s_stream_mutex);
+ mi->mi_update_pids(mi, mm);
pthread_mutex_unlock(&mi->mi_output_lock);
+
/* Stop mux? */
s->s_dvb_mux->mm_stop(s->s_dvb_mux, 0, SM_CODE_OK);
}
mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
{
mpegts_table_t *mt;
+ int update = 0;
if (!mm || !mm->mm_active)
return;
if (!mt->mt_subscribed) {
mt->mt_subscribed = 1;
pthread_mutex_unlock(&mm->mm_tables_lock);
- mi->mi_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ mpegts_input_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ update = 1;
} else {
pthread_mutex_unlock(&mm->mm_tables_lock);
}
if (mt->mt_subscribed) {
mt->mt_subscribed = 0;
pthread_mutex_unlock(&mm->mm_tables_lock);
- mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ mpegts_input_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ update = 1;
} else {
pthread_mutex_unlock(&mm->mm_tables_lock);
}
}
mpegts_table_consistency_check(mm);
pthread_mutex_unlock(&mm->mm_tables_lock);
+ if (update)
+ mi->mi_update_pids(mi, mm);
}
#if ENABLE_TSDEBUG
mi->mi_stop_mux = mpegts_input_stop_mux;
mi->mi_open_service = mpegts_input_open_service;
mi->mi_close_service = mpegts_input_close_service;
- mi->mi_open_pid = mpegts_input_open_pid;
- mi->mi_close_pid = mpegts_input_close_pid;
+ mi->mi_update_pids = mpegts_input_update_pids;
mi->mi_create_mux_instance = mpegts_input_create_mux_instance;
mi->mi_started_mux = mpegts_input_started_mux;
mi->mi_stopping_mux = mpegts_input_stopping_mux;
mt->mt_subscribed = 1;
pthread_mutex_unlock(&mm->mm_tables_lock);
pthread_mutex_lock(&mi->mi_output_lock);
- mi->mi_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ mpegts_input_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ mi->mi_update_pids(mi, mm);
pthread_mutex_unlock(&mi->mi_output_lock);
pthread_mutex_lock(&mm->mm_tables_lock);
mpegts_table_release(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);
+ mpegts_input_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+ mi->mi_update_pids(mi, mm);
pthread_mutex_unlock(&mi->mi_output_lock);
pthread_mutex_lock(&mm->mm_tables_lock);
mpegts_table_release(mt);
}
dst->count = j;
dst->sorted = 0;
+ dst->all = pids->all;
return 0;
}
x = t->s_pids;
t->s_pids = p;
if (!pids->all && x && x->all) {
- mi->mi_close_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, MPS_WEIGHT_RAW, t);
+ mpegts_input_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++) {
pi = &x->pids[i];
- mi->mi_open_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t);
+ mpegts_input_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);
+ mpegts_input_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++) {
pi = &x->pids[i];
- mi->mi_close_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t);
+ mpegts_input_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_input_open_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t);
}
mpegts_pid_done(&add);
mpegts_pid_done(&del);
}
}
pthread_mutex_unlock(&t->s_stream_mutex);
+ mi->mi_update_pids(mi, mm);
pthread_mutex_unlock(&mi->mi_output_lock);
} else {
pthread_mutex_lock(&t->s_stream_mutex);
if (mmi == NULL)
return;
if (!lfe->sf_tables) {
- psi_tables_default(mmi->mmi_mux);
- if (lfe->sf_type == DVB_TYPE_ATSC) {
- if (lfe->sf_atsc_c)
- psi_tables_atsc_c(mmi->mmi_mux);
- else
- psi_tables_atsc_t(mmi->mmi_mux);
- } else {
- psi_tables_dvb(mmi->mmi_mux);
- }
+ psi_tables_install(mmi->mmi_input, mmi->mmi_mux,
+ ((dvb_mux_t *)mmi->mmi_mux)->lm_tuning.dmc_fe_type);
lfe->sf_tables = 1;
}
sigstat.status_text = signal2str(lfe->sf_status);
return 0;
}
-static int
-satip_frontend_add_pid( satip_frontend_t *lfe, int pid, int weight)
-{
- satip_tune_req_t *tr;
-
- if (pid < 0 || pid >= 8191)
- return 0;
-
- tr = lfe->sf_req;
- if (tr) {
- mpegts_pid_add(&tr->sf_pids, pid, weight);
- return 1;
- }
-
- return 0;
-}
-
-static mpegts_pid_t *
-satip_frontend_open_pid
- ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
-{
- satip_frontend_t *lfe = (satip_frontend_t*)mi;
- satip_tune_req_t *tr;
- mpegts_pid_t *mp;
- int change = 0;
-
- if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, weight, owner)))
- return NULL;
-
- if (mp->mp_pid > MPEGTS_FULLMUX_PID)
- return mp;
-
- pthread_mutex_lock(&lfe->sf_dvr_lock);
- if ((tr = lfe->sf_req) != NULL) {
- if (pid == MPEGTS_FULLMUX_PID) {
- if (lfe->sf_device->sd_fullmux_ok) {
- if (!tr->sf_pids.all)
- tr->sf_pids.all = change = 1;
- } else {
- 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, 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, weight);
- }
- }
- } else {
- change |= satip_frontend_add_pid(lfe, mp->mp_pid, weight);
- }
- if (lfe->sf_device->sd_fritz_quirk)
- change |= satip_frontend_add_pid(lfe, 21, 1);
- }
- pthread_mutex_unlock(&lfe->sf_dvr_lock);
- if (change)
- tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
-
- return mp;
-}
-
-static int
-satip_frontend_close_pid
- ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
+static void
+satip_frontend_update_pids
+ ( mpegts_input_t *mi, mpegts_mux_t *mm )
{
satip_frontend_t *lfe = (satip_frontend_t*)mi;
satip_tune_req_t *tr;
mpegts_pid_t *mp;
mpegts_pid_sub_t *mps;
- int change = 0, r;
-
- if ((r = mpegts_input_close_pid(mi, mm, pid, type, weight, owner)) <= 0)
- return r; /* return here even if change is nonzero - multiple PID subscribers */
-
- /* Skip internal PIDs */
- if (pid > MPEGTS_FULLMUX_PID)
- return r;
pthread_mutex_lock(&lfe->sf_dvr_lock);
- /* remove PID */
if ((tr = lfe->sf_req) != NULL) {
- if (pid == MPEGTS_FULLMUX_PID) {
- if (lfe->sf_device->sd_fullmux_ok) {
- if (tr->sf_pids.all) {
- tr->sf_pids.all = 0;
- change = 1;
+ mpegts_pid_done(&tr->sf_pids);
+ RB_FOREACH(mp, &mm->mm_pids, mp_link) {
+ if (mp->mp_pid == MPEGTS_FULLMUX_PID) {
+ if (lfe->sf_device->sd_fullmux_ok) {
+ if (!tr->sf_pids.all)
+ tr->sf_pids.all = 1;
+ } else {
+ mpegts_service_t *s;
+ elementary_stream_t *st;
+ int w = 0;
+ RB_FOREACH(mps, &mp->mp_subs, mps_link)
+ w = MAX(w, mps->mps_weight);
+ LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) {
+ mpegts_pid_add(&tr->sf_pids, s->s_pmt_pid, w);
+ mpegts_pid_add(&tr->sf_pids, s->s_pcr_pid, w);
+ TAILQ_FOREACH(st, &s->s_components, es_link)
+ mpegts_pid_add(&tr->sf_pids, st->es_pid, w);
+ }
}
- }
- } else {
- mpegts_pid_done(&tr->sf_pids);
- RB_FOREACH(mp, &mm->mm_pids, mp_link)
+ } else if (mp->mp_pid < MPEGTS_FULLMUX_PID) {
RB_FOREACH(mps, &mp->mp_subs, mps_link)
mpegts_pid_add(&tr->sf_pids, mp->mp_pid, mps->mps_weight);
- change = 1;
+ }
}
- if (change)
- tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
+ if (lfe->sf_device->sd_fritz_quirk)
+ mpegts_pid_add(&tr->sf_pids, 21, 1);
}
pthread_mutex_unlock(&lfe->sf_dvr_lock);
- return r;
+ tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
}
static idnode_set_t *
lfe->mi_start_mux = satip_frontend_start_mux;
lfe->mi_stop_mux = satip_frontend_stop_mux;
lfe->mi_network_list = satip_frontend_network_list;
- lfe->mi_open_pid = satip_frontend_open_pid;
- lfe->mi_close_pid = satip_frontend_close_pid;
+ lfe->mi_update_pids = satip_frontend_update_pids;
/* Adapter link */
lfe->sf_device = sd;
mmi->mmi_mux->mm_active = t;
/* Install table handlers */
- psi_tables_default(mm);
- psi_tables_dvb(mm);
- psi_tables_atsc_t(mm);
- psi_tables_atsc_c(mm);
+ psi_tables_install(mi, mm, DVB_SYS_UNKNOWN);
return 0;
}
#include "streaming.h"
#include "tvhdhomerun_private.h"
-static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, mpegts_pid_t *mp);
-
-static mpegts_pid_t * tvhdhomerun_frontend_open_pid( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner );
-
static int
tvhdhomerun_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
{
return NULL;
}
-static void tvhdhomerun_frontend_default_tables( tvhdhomerun_frontend_t *hfe, dvb_mux_t *lm )
-{
- mpegts_mux_t *mm = (mpegts_mux_t*)lm;
-
- psi_tables_default(mm);
-
- if (hfe->hf_type == DVB_TYPE_ATSC) {
- if (lm->lm_tuning.dmc_fe_modulation == DVB_MOD_VSB_8)
- psi_tables_atsc_t(mm);
- else
- psi_tables_atsc_c(mm);
-
- } else {
- psi_tables_dvb(mm);
- }
-}
-
static void
tvhdhomerun_frontend_monitor_cb( void *aux )
{
tvhdhomerun_frontend_t *hfe = aux;
mpegts_mux_instance_t *mmi = LIST_FIRST(&hfe->mi_mux_active);
mpegts_mux_t *mm;
- mpegts_pid_t *mp;
streaming_message_t sm;
signal_status_t sigstat;
service_t *svc;
pthread_mutex_unlock(&hfe->hf_input_thread_mutex);
/* install table handlers */
- tvhdhomerun_frontend_default_tables(hfe, (dvb_mux_t*)mm);
- /* open PIDs */
- pthread_mutex_lock(&hfe->mi_output_lock);
- RB_FOREACH(mp, &mm->mm_pids, mp_link)
- tvhdhomerun_device_open_pid(hfe, mp);
- pthread_mutex_unlock(&hfe->mi_output_lock);
+ psi_tables_install(mmi->mmi_input, mm,
+ ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_type);
+
} else { // quick re-arm the timer to wait for signal lock
gtimer_arm_ms(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, 50);
}
}
}
-static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, mpegts_pid_t *mp) {
+static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, int pid) {
char *pfilter;
char buf[1024];
int res;
- //tvhdebug("tvhdhomerun", "adding PID 0x%x to pfilter", mp->mp_pid);
+ //tvhdebug("tvhdhomerun", "adding PID 0x%x to pfilter", pid);
/* Skip internal PIDs */
- if (mp->mp_pid > MPEGTS_FULLMUX_PID)
+ if (pid > MPEGTS_FULLMUX_PID)
return;
/* get the current filter */
tvhdebug("tvhdhomerun", "current pfilter: %s", pfilter);
memset(buf, 0x00, sizeof(buf));
- snprintf(buf, sizeof(buf), "0x%04x", mp->mp_pid);
+ snprintf(buf, sizeof(buf), "0x%04x", pid);
if(strncmp(pfilter, buf, strlen(buf)) != 0) {
memset(buf, 0x00, sizeof(buf));
- snprintf(buf, sizeof(buf), "%s 0x%04x", pfilter, mp->mp_pid);
+ snprintf(buf, sizeof(buf), "%s 0x%04x", pfilter, pid);
tvhdebug("tvhdhomerun", "setting pfilter to: %s", buf);
pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex);
if(res < 1)
tvhlog(LOG_ERR, "tvhdhomerun", "failed to set_tuner_filter: %d", res);
} else {
- //tvhdebug("tvhdhomerun", "pid 0x%x already present in pfilter", mp->mp_pid);
+ //tvhdebug("tvhdhomerun", "pid 0x%x already present in pfilter", pid);
return;
}
}
gtimer_arm(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, 2);
}
-static mpegts_pid_t *tvhdhomerun_frontend_open_pid( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
+static void tvhdhomerun_frontend_update_pids( mpegts_input_t *mi, mpegts_mux_t *mm )
{
tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)mi;
+ mpegts_apids_t pids, wpids;
mpegts_pid_t *mp;
-
- //tvhdebug("tvhdhomerun", "Open pid 0x%x\n", pid);
-
- if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, weight, owner))) {
- tvhdebug("tvhdhomerun", "Failed to open pid %d", pid);
- return NULL;
+ mpegts_pid_sub_t *mps;
+ int i;
+
+ //tvhdebug("tvhdhomerun", "Update pids\n");
+
+ mpegts_pid_init(&pids);
+ RB_FOREACH(mp, &mm->mm_pids, mp_link) {
+ if (mp->mp_pid == MPEGTS_FULLMUX_PID)
+ pids.all = 1;
+ else if (mp->mp_pid < MPEGTS_FULLMUX_PID) {
+ RB_FOREACH(mps, &mp->mp_subs, mps_link)
+ mpegts_pid_add(&pids, mp->mp_pid, mps->mps_weight);
+ }
}
- tvhdhomerun_device_open_pid(hfe, mp);
-
- return mp;
-}
-
-static int tvhdhomerun_frontend_close_pid( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
-{
- //tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)mi;
-
- tvhdebug("tvhdhomerun", "closing pid 0x%x",pid);
-
- return mpegts_input_close_pid(mi, mm, pid, type, weight, owner);
-
- //tvhdhomerun_device_update_pid_filter(hfe, mm);
+ mpegts_pid_weighted(&wpids, &pids, 128 /* max? */);
+ for (i = 0; i < wpids.count; i++)
+ tvhdhomerun_device_open_pid(hfe, wpids.pids[i].pid);
+ if (wpids.all)
+ tvhdhomerun_device_open_pid(hfe, MPEGTS_FULLMUX_PID);
+ mpegts_pid_done(&wpids);
}
static idnode_set_t *
hfe->mi_start_mux = tvhdhomerun_frontend_start_mux;
hfe->mi_stop_mux = tvhdhomerun_frontend_stop_mux;
hfe->mi_network_list = tvhdhomerun_frontend_network_list;
- hfe->mi_open_pid = tvhdhomerun_frontend_open_pid;
- hfe->mi_close_pid = tvhdhomerun_frontend_close_pid;
+ hfe->mi_update_pids = tvhdhomerun_frontend_update_pids;
/* Adapter link */
hfe->hf_device = hd;