From: Jaroslav Kysela Date: Sun, 3 May 2015 19:35:58 +0000 (+0200) Subject: mpegts: simplify pid subscriptions for input drivers X-Git-Tag: v4.1~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9dcfd08d846cd353540da2b60eb6e4a60354b96d;p=thirdparty%2Ftvheadend.git mpegts: simplify pid subscriptions for input drivers --- diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 9c5e15808..1204526f0 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -684,8 +684,7 @@ struct mpegts_input 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*); @@ -970,10 +969,8 @@ int dvb_tot_callback 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, diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index 89fe4c114..dce993fb1 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -340,6 +340,9 @@ typedef enum dvb_fe_delivery_system { 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 { diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 343ecd3ce..2b4ed6f2b 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -2419,7 +2419,7 @@ dvb_tot_callback * 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, @@ -2444,7 +2444,7 @@ psi_tables_dvb_fastscan( void *aux, bouquet_t *bq, const char *name, int pid ) } #endif -void +static void psi_tables_dvb ( mpegts_mux_t *mm ) { mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback, @@ -2473,7 +2473,7 @@ psi_tables_dvb ( mpegts_mux_t *mm ) #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, @@ -2481,10 +2481,61 @@ psi_tables_atsc_c ( mpegts_mux_t *mm ) 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); +} diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 407c92cf9..af7667026 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -416,12 +416,9 @@ iptv_input_mux_started ( iptv_mux_t *im ) /* 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); } /* ************************************************************************** diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index d1afb90e0..312a95e92 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -362,63 +362,27 @@ linuxdvb_frontend_start_mux 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 * @@ -448,27 +412,6 @@ linuxdvb_frontend_network_list ( mpegts_input_t *mi ) * 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 ) { @@ -597,7 +540,8 @@ linuxdvb_frontend_monitor ( void *aux ) 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 { @@ -1620,8 +1564,7 @@ linuxdvb_frontend_create 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 */ diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index e2e9ad6d3..4a6b634c3 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -409,17 +409,18 @@ mpegts_input_close_pids 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 ) @@ -528,6 +529,13 @@ mpegts_input_close_pid 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)) @@ -563,15 +571,15 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, 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 */ @@ -590,17 +598,17 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, } 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); } } @@ -614,6 +622,10 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, 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 @@ -642,15 +654,15 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) 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)); @@ -668,10 +680,11 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) 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); } @@ -966,6 +979,7 @@ static void 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; @@ -978,7 +992,8 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) 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); } @@ -987,7 +1002,8 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) 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); } @@ -999,6 +1015,8 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) } mpegts_table_consistency_check(mm); pthread_mutex_unlock(&mm->mm_tables_lock); + if (update) + mi->mi_update_pids(mi, mm); } #if ENABLE_TSDEBUG @@ -1474,8 +1492,7 @@ mpegts_input_create0 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; diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index b4fc44fe7..8204a63df 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -808,7 +808,8 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ) 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); @@ -828,7 +829,8 @@ mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *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); diff --git a/src/input/mpegts/mpegts_pid.c b/src/input/mpegts/mpegts_pid.c index 5a94b3446..b643eb899 100644 --- a/src/input/mpegts/mpegts_pid.c +++ b/src/input/mpegts/mpegts_pid.c @@ -289,6 +289,7 @@ mpegts_pid_weighted(mpegts_apids_t *dst, mpegts_apids_t *pids, int limit) } dst->count = j; dst->sorted = 0; + dst->all = pids->all; return 0; } diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 7b3215e95..ee8627b41 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -751,31 +751,32 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) 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); diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index a18db7ef3..6b61bba9a 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -64,15 +64,8 @@ satip_frontend_signal_cb( void *aux ) 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); @@ -529,107 +522,47 @@ satip_frontend_start_mux 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 * @@ -1687,8 +1620,7 @@ satip_frontend_create 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; diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index f44337294..29dc6cd72 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -235,10 +235,7 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) 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; } diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index 2780ca38a..0ee67c933 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -23,10 +23,6 @@ #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 ) { @@ -214,30 +210,12 @@ tvhdhomerun_frontend_input_thread ( void *aux ) 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; @@ -281,12 +259,9 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) 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); } @@ -317,15 +292,15 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) } } -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 */ @@ -340,11 +315,11 @@ static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, mpegts_pid_ 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); @@ -353,7 +328,7 @@ static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, mpegts_pid_ 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; } } @@ -469,32 +444,32 @@ tvhdhomerun_frontend_stop_mux 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 * @@ -673,8 +648,7 @@ tvhdhomerun_frontend_create(tvhdhomerun_device_t *hd, struct hdhomerun_discover_ 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;