diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 320a0900..31a08ce7 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -546,8 +546,11 @@ next_one: /* Subscribe to the mux */ om->om_requeue = 1; - if ((r = mpegts_mux_subscribe(mm, NULL, "epggrab", SUBSCRIPTION_PRIO_EPG, - SUBSCRIPTION_EPG | SUBSCRIPTION_ONESHOT))) { + if ((r = mpegts_mux_subscribe(mm, NULL, "epggrab", + SUBSCRIPTION_PRIO_EPG, + SUBSCRIPTION_EPG | + SUBSCRIPTION_ONESHOT | + SUBSCRIPTION_TABLES))) { TAILQ_INSERT_TAIL(&epggrab_ota_pending, om, om_q_link); om->om_q_type = EPGGRAB_OTA_MUX_PENDING; if (r == SM_CODE_NO_FREE_ADAPTER) diff --git a/src/input/mpegts.h b/src/input/mpegts.h index a1d1223e..92394c09 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -34,6 +34,7 @@ #define MPEGTS_TSID_NONE 0xFFFF #define MPEGTS_PSI_SECTION_SIZE 5000 #define MPEGTS_FULLMUX_PID 0x2000 +#define MPEGTS_TABLES_PID 0x2001 #define MPEGTS_PID_NONE 0xFFFF /* Types */ @@ -155,6 +156,7 @@ typedef struct mpegts_pid_sub #define MPS_SERVICE 0x08 #define MPS_TABLE 0x10 #define MPS_FTABLE 0x20 +#define MPS_TABLES 0x40 int mps_type; void *mps_owner; } mpegts_pid_sub_t; @@ -502,6 +504,8 @@ struct mpegts_service { service_t; // Parent + int s_dvb_subscription_flags; + /* * Fields defined by DVB standard EN 300 468 */ @@ -680,7 +684,7 @@ struct mpegts_input int (*mi_warm_mux) (mpegts_input_t*,mpegts_mux_instance_t*); int (*mi_start_mux) (mpegts_input_t*,mpegts_mux_instance_t*); void (*mi_stop_mux) (mpegts_input_t*,mpegts_mux_instance_t*); - void (*mi_open_service) (mpegts_input_t*,mpegts_service_t*,int first); + 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,void*); void (*mi_close_pid) (mpegts_input_t*,mpegts_mux_t*,int,int,void*); @@ -737,7 +741,7 @@ int mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg ); int mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn ); -void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init ); +void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init ); void mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ); void mpegts_input_status_timer ( void *p ); @@ -887,7 +891,7 @@ void mpegts_input_close_pid ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner ); void mpegts_input_close_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm, int type, void *owner ); + ( mpegts_input_t *mi, mpegts_mux_t *mm, void *owner ); static inline void tsdebug_write(mpegts_mux_t *mm, uint8_t *buf, size_t len) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 2eb71205..b58d617c 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -366,6 +366,10 @@ linuxdvb_frontend_open_pid0 struct dmx_pes_filter_params dmx_param; int fd; + /* Do not open internal PIDs */ + if (mp->mp_pid > MPEGTS_FULLMUX_PID) + return; + /* Already opened */ if (mp->mp_fd != -1) return; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 89012021..f6533d2f 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -408,28 +408,20 @@ mpegts_mps_cmp ( mpegts_pid_sub_t *a, mpegts_pid_sub_t *b ) void mpegts_input_close_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm, int type, void *owner ) + ( mpegts_input_t *mi, mpegts_mux_t *mm, void *owner ) { mpegts_pid_t *mp, *mp_next; mpegts_pid_sub_t *mps, *mps_next; for (mp = RB_FIRST(&mm->mm_pids); mp; mp = mp_next) { mp_next = RB_NEXT(mp, mp_link); - if ((mp->mp_type & MPS_RAW) == 0) continue; for (mps = RB_FIRST(&mp->mp_subs); mps; mps = mps_next) { mps_next = RB_NEXT(mps, mps_link); if (mps->mps_owner != owner) continue; - LIST_REMOVE(mps, mps_svcraw_link); - RB_REMOVE(&mp->mp_subs, mps, mps_link); - free(mps); - if (!RB_FIRST(&mp->mp_subs)) { - RB_REMOVE(&mm->mm_pids, mp, mp_link); - free(mp); - } + mi->mi_close_pid(mi, mm, mp->mp_pid, mps->mps_type, mps->mps_owner); } } } - mpegts_pid_t * mpegts_input_open_pid ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner ) @@ -437,6 +429,7 @@ mpegts_input_open_pid char buf[512]; mpegts_pid_t *mp; mpegts_pid_sub_t *mps, *mps2; + assert(owner != NULL); assert((type & (MPS_STREAM|MPS_SERVICE|MPS_RAW)) == 0 || (((type & MPS_STREAM) ? 1 : 0) + @@ -445,21 +438,21 @@ mpegts_input_open_pid lock_assert(&mi->mi_output_lock); if (pid == MPEGTS_FULLMUX_PID) - mpegts_input_close_pids(mi, mm, MPS_RAW, owner); + mpegts_input_close_pids(mi, mm, owner); if ((mp = mpegts_mux_find_pid(mm, pid, 1))) { mps = calloc(1, sizeof(*mps)); mps->mps_type = type; mps->mps_owner = owner; - if (pid == MPEGTS_FULLMUX_PID) { - mp->mp_type |= type | MPS_ALL; + if (pid == MPEGTS_FULLMUX_PID || pid == MPEGTS_TABLES_PID) { + mp->mp_type |= type; LIST_FOREACH(mps2, &mm->mm_all_subs, mps_svcraw_link) if (mps2->mps_owner == owner) break; if (mps2 == NULL) { LIST_INSERT_HEAD(&mm->mm_all_subs, mps, mps_svcraw_link); mpegts_mux_nice_name(mm, buf, sizeof(buf)); - tvhdebug("mpegts", "%s - open PID fullmux subscription [%d/%p]", - buf, type, owner); + tvhdebug("mpegts", "%s - open PID %s subscription [%04x/%p]", + buf, (type & MPS_TABLES) ? "tables" : "fullmux", type, owner); } } else if (!RB_INSERT_SORTED(&mp->mp_subs, mps, mps_link, mpegts_mps_cmp)) { mp->mp_type |= type; @@ -483,20 +476,27 @@ mpegts_input_close_pid char buf[512]; mpegts_pid_sub_t *mps, skel; mpegts_pid_t *mp; + int mask; assert(owner != NULL); lock_assert(&mi->mi_output_lock); if (!(mp = mpegts_mux_find_pid(mm, pid, 0))) return; - if (pid == MPEGTS_FULLMUX_PID) { + if (pid == MPEGTS_FULLMUX_PID || pid == MPEGTS_TABLES_PID) { mpegts_mux_nice_name(mm, buf, sizeof(buf)); - tvhdebug("mpegts", "%s - close PID fullmux subscription [%d/%p]", - buf, type, owner); - mpegts_input_close_pids(mi, mm, MPS_RAW, owner); LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) if (mps->mps_owner == owner) break; if (mps == NULL) return; + tvhdebug("mpegts", "%s - close PID %s subscription [%04x/%p]", + buf, pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", + type, owner); + if (pid == MPEGTS_FULLMUX_PID) + mpegts_input_close_pids(mi, mm, owner); LIST_REMOVE(mps, mps_svcraw_link); free(mps); + mask = pid == MPEGTS_FULLMUX_PID ? MPS_ALL : MPS_TABLES; + LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) + if (mps->mps_type & mask) break; + if (mps) return; } else { skel.mps_type = type; skel.mps_owner = owner; @@ -529,7 +529,7 @@ mpegts_input_close_pid } void -mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init ) +mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init ) { elementary_stream_t *st; mpegts_apids_t *pids; @@ -557,11 +557,13 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init ) } else { if ((pids = s->s_pids) != NULL) { if (pids->all) { - mi->mi_open_pid(mi, s->s_dvb_mux, MPEGTS_FULLMUX_PID, MPS_RAW, s); + mi->mi_open_pid(mi, s->s_dvb_mux, MPEGTS_FULLMUX_PID, MPS_RAW | MPS_ALL, s); } else { for (i = 0; i < pids->count; i++) mi->mi_open_pid(mi, s->s_dvb_mux, pids->pids[i], MPS_RAW, s); } + } else if (flags & SUBSCRIPTION_TABLES) { + mi->mi_open_pid(mi, s->s_dvb_mux, MPEGTS_TABLES_PID, MPS_RAW | MPS_TABLES, s); } } @@ -607,7 +609,7 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) } } } else { - mpegts_input_close_pids(mi, s->s_dvb_mux, MPS_RAW, s); + mpegts_input_close_pids(mi, s->s_dvb_mux, s); } @@ -1058,10 +1060,13 @@ mpegts_input_process type = mp->mp_type; + /* Stream all PIDs */ + LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) + if ((mps->mps_type & MPS_ALL) || (type & (MPS_TABLE|MPS_FTABLE))) + ts_recv_raw((mpegts_service_t *)mps->mps_owner, tsb); + /* Stream raw PIDs */ if (type & MPS_RAW) { - LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) - ts_recv_raw((mpegts_service_t *)mps->mps_owner, tsb); LIST_FOREACH(mps, &mp->mp_svc_subs, mps_svcraw_link) ts_recv_raw((mpegts_service_t *)mps->mps_owner, tsb); } diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 8cb62335..738a1c43 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -585,6 +585,7 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ) { mpegts_mux_instance_t *mmi; mpegts_service_t *s; + th_subscription_t *ths; char buf[256]; mpegts_mux_nice_name(mm, buf, sizeof(buf)); @@ -604,6 +605,11 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ) mmi->mmi_delete(mmi); } + /* Remove raw subscribers */ + while ((ths = LIST_FIRST(&mm->mm_raw_subs))) { + subscription_unsubscribe(ths, 0); + } + /* Delete services */ while ((s = LIST_FIRST(&mm->mm_services))) { service_destroy((service_t*)s, delconf); @@ -712,10 +718,12 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason ) mm->mm_last_mp = NULL; while ((mp = RB_FIRST(&mm->mm_pids))) { assert(mi); - if (mp->mp_pid == MPEGTS_FULLMUX_PID) { + if (mp->mp_pid == MPEGTS_FULLMUX_PID || + mp->mp_pid == MPEGTS_TABLES_PID) { while ((mps = LIST_FIRST(&mm->mm_all_subs))) { - tvhdebug("mpegts", "%s - close PID fullmux subscription [%d/%p]", - buf, mps->mps_type, mps->mps_owner); + tvhdebug("mpegts", "%s - close PID %s subscription [%d/%p]", + buf, mp->mp_pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", + mps->mps_type, mps->mps_owner); LIST_REMOVE(mps, mps_svcraw_link); free(mps); } @@ -1205,7 +1213,7 @@ mpegts_mux_find_pid_ ( mpegts_mux_t *mm, int pid, int create ) { mpegts_pid_t skel, *mp; - if (pid > 0x2000) return NULL; + if (pid < 0 || pid > MPEGTS_TABLES_PID) return NULL; skel.mp_pid = pid; mp = RB_FIND(&mm->mm_pids, &skel, mp_link, mp_cmp); diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index fb3bc140..442de7eb 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -54,7 +54,9 @@ mpegts_network_scan_timer_cb ( void *p ) /* Attempt to tune */ r = mpegts_mux_subscribe(mm, NULL, "scan", mm->mm_scan_weight, - mm->mm_scan_flags | SUBSCRIPTION_ONESHOT); + mm->mm_scan_flags | + SUBSCRIPTION_ONESHOT | + SUBSCRIPTION_TABLES); /* Started */ if (!r) { diff --git a/src/input/mpegts/mpegts_pid.c b/src/input/mpegts/mpegts_pid.c index 8bbea603..9e3a9263 100644 --- a/src/input/mpegts/mpegts_pid.c +++ b/src/input/mpegts/mpegts_pid.c @@ -41,6 +41,8 @@ mpegts_pid_init(mpegts_apids_t *pids, mpegts_apid_t *vals, int count) void mpegts_pid_done(mpegts_apids_t *pids) { + if (pids == NULL) + return; free(pids->pids); pids->pids = NULL; pids->alloc = pids->count = 0; diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 48e52de7..8dc27ee5 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -279,7 +279,7 @@ mpegts_service_enlist(service_t *t, tvh_input_t *ti, * Start service */ static int -mpegts_service_start(service_t *t, int instance) +mpegts_service_start(service_t *t, int instance, int flags) { int r; mpegts_service_t *s = (mpegts_service_t*)t; @@ -306,7 +306,8 @@ mpegts_service_start(service_t *t, int instance) if (!r) { /* Open service */ - mmi->mmi_input->mi_open_service(mmi->mmi_input, s, 1); + s->s_dvb_subscription_flags = flags; + mmi->mmi_input->mi_open_service(mmi->mmi_input, s, flags, 1); } return r; @@ -348,7 +349,7 @@ mpegts_service_refresh(service_t *t) lock_assert(&global_lock); /* Re-open */ - i->mi_open_service(i, s, 0); + i->mi_open_service(i, s, s->s_dvb_subscription_flags, 0); } /* @@ -510,7 +511,8 @@ mpegts_service_delete ( service_t *t, int delconf ) free(ms->s_dvb_provider); free(ms->s_dvb_cridauth); free(ms->s_dvb_charset); - LIST_REMOVE(ms, s_dvb_mux_link); + if (t->s_type == STYPE_STD) + LIST_REMOVE(ms, s_dvb_mux_link); sbuf_free(&ms->s_tsbuf); // Note: the ultimate deletion and removal from the idnode list @@ -552,6 +554,7 @@ mpegts_service_create0 s->s_delete = mpegts_service_delete; s->s_is_enabled = mpegts_service_is_enabled; + s->s_config_save = mpegts_service_config_save; s->s_enlist = mpegts_service_enlist; s->s_start_feed = mpegts_service_start; s->s_stop_feed = mpegts_service_stop; @@ -640,7 +643,7 @@ mpegts_service_raw_setsourceinfo(service_t *t, source_info_t *si) mpegts_service_setsourceinfo(t, si); free(si->si_service); - si->si_service = strdup("Raw Service"); + si->si_service = strdup("Raw PID Subscription"); } static int @@ -667,12 +670,12 @@ mpegts_service_raw_update_pids(service_t *t, mpegts_apids_t *pids) t->s_pids = p; if (!pids->all && x && x->all) { mi->mi_close_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, t); - mpegts_input_close_pids(mi, mm, MPS_RAW, t); + mpegts_input_close_pids(mi, mm, t); for (i = 0; i < x->count; i++) mi->mi_open_pid(mi, mm, x->pids[i], MPS_RAW, t); } else { if (pids->all) { - mpegts_input_close_pids(mi, mm, MPS_RAW, t); + mpegts_input_close_pids(mi, mm, t); mi->mi_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, t); } else { mpegts_pid_compare(p, x, &add, &del); diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index d5b50a3d..c5e7d124 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -604,6 +604,9 @@ satip_frontend_open_pid if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, owner))) return NULL; + if (mp->mp_pid > MPEGTS_FULLMUX_PID) + return mp; + if (pid == MPEGTS_FULLMUX_PID) { pthread_mutex_lock(&lfe->sf_dvr_lock); tr = lfe->sf_req; @@ -649,6 +652,10 @@ satip_frontend_close_pid int change = 0; int mid, div, cnt; + /* Skip internal PIDs */ + if (pid > MPEGTS_FULLMUX_PID) + goto finish; + /* remove PID */ if (pid == MPEGTS_FULLMUX_PID) { pthread_mutex_lock(&lfe->sf_dvr_lock); diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index 9c8be7e3..fbc47580 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -224,6 +224,7 @@ ts_recv_raw(mpegts_service_t *t, const uint8_t *tsb) int pid; pthread_mutex_lock(&t->s_stream_mutex); + service_set_streaming_status_flags((service_t*)t, TSS_MUX_PACKETS); if (t->s_parent) { /* If PID is owned by parent, let parent service to * deliver this PID (decrambling) @@ -231,9 +232,15 @@ ts_recv_raw(mpegts_service_t *t, const uint8_t *tsb) pid = (tsb[1] & 0x1f) << 8 | tsb[2]; st = service_stream_find(t->s_parent, pid); } - if(st == NULL) + if(st == NULL) { if (streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) ts_remux(t, tsb, 0); + else { + /* No subscriber - set OK markers */ + service_set_streaming_status_flags((service_t*)t, TSS_PACKETS); + t->s_streaming_live |= TSS_LIVE; + } + } pthread_mutex_unlock(&t->s_stream_mutex); } diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index 8a75dcbd..4de9fd7b 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -330,6 +330,10 @@ static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, mpegts_pid_ //tvhdebug("tvhdhomerun", "adding PID 0x%x to pfilter", mp->mp_pid); + /* Skip internal PIDs */ + if (mp->mp_pid > MPEGTS_FULLMUX_PID) + return; + /* get the current filter */ pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex); res = hdhomerun_device_get_tuner_filter(hfe->hf_hdhomerun_tuner, &pfilter); diff --git a/src/service.c b/src/service.c index bf2b0e4b..38e3c513 100644 --- a/src/service.c +++ b/src/service.c @@ -370,6 +370,12 @@ service_stop(service_t *t) t->s_status = SERVICE_IDLE; tvhlog_limit_reset(&t->s_tei_log); +#if ENABLE_MPEGTS + mpegts_pid_done(t->s_pids); + free(t->s_pids); + t->s_pids = NULL; +#endif + pthread_mutex_unlock(&t->s_stream_mutex); } @@ -639,7 +645,7 @@ ignore: * */ int -service_start(service_t *t, int instance, int timeout, int postpone) +service_start(service_t *t, int instance, int flags, int timeout, int postpone) { elementary_stream_t *st; int r, stimeout = 10; @@ -659,7 +665,7 @@ service_start(service_t *t, int instance, int timeout, int postpone) descrambler_caid_changed(t); pthread_mutex_unlock(&t->s_stream_mutex); - if((r = t->s_start_feed(t, instance))) + if((r = t->s_start_feed(t, instance, flags))) return r; descrambler_service_start(t); @@ -778,7 +784,7 @@ service_find_instance /* Start */ tvhtrace("service", "will start new instance %d", si->si_instance); - if (service_start(si->si_s, si->si_instance, timeout, postpone)) { + if (service_start(si->si_s, si->si_instance, flags, timeout, postpone)) { tvhtrace("service", "tuning failed"); si->si_error = SM_CODE_TUNING_FAILED; if (*error < SM_CODE_TUNING_FAILED) diff --git a/src/service.h b/src/service.h index e9e1b525..0d17b84c 100644 --- a/src/service.h +++ b/src/service.h @@ -297,7 +297,7 @@ typedef struct service { void (*s_enlist)(struct service *s, struct tvh_input *ti, service_instance_list_t *sil, int flags); - int (*s_start_feed)(struct service *s, int instance); + int (*s_start_feed)(struct service *s, int instance, int flags); void (*s_refresh_feed)(struct service *t); @@ -486,7 +486,7 @@ typedef struct service { void service_init(void); void service_done(void); -int service_start(service_t *t, int instance, int timeout, int postpone); +int service_start(service_t *t, int instance, int flags, int timeout, int postpone); void service_stop(service_t *t); void service_build_filter(service_t *t); diff --git a/src/subscriptions.c b/src/subscriptions.c index 28fe69db..233d2da6 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -262,6 +262,7 @@ subscription_reschedule(void) LIST_FOREACH(s, &subscriptions, ths_global_link) { if (!s->ths_service && !s->ths_channel) continue; + if (s->ths_flags & SUBSCRIPTION_ONESHOT) continue; /* Postpone the tuner decision */ /* Leave some time to wakeup tuners through DBus or so */ @@ -533,12 +534,15 @@ subscription_unsubscribe(th_subscription_t *s, int quiet) if (t) { service_remove_subscriber(t, s, SM_CODE_OK); -#if ENABLE_MPEGTS - if (t->s_type == STYPE_RAW) - LIST_REMOVE(s, ths_mux_link); -#endif } +#if ENABLE_MPEGTS + if (s->ths_raw_service) { + LIST_REMOVE(s, ths_mux_link); + service_destroy(s->ths_raw_service, 0); + } +#endif + streaming_msg_free(s->ths_start_message); if(s->ths_output->st_cb == subscription_input_null) @@ -637,6 +641,7 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, service_t *service) { th_subscription_t *s; + service_instance_t *si; channel_t *ch = NULL; assert(prch); @@ -668,15 +673,18 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, #if ENABLE_MPEGTS if (service && service->s_type == STYPE_RAW) { mpegts_mux_t *mm = prch->prch_id; + s->ths_raw_service = service; LIST_INSERT_HEAD(&mm->mm_raw_subs, s, ths_mux_link); } #endif if (flags & SUBSCRIPTION_ONESHOT) { - if (subscription_start_instance(s, error) == NULL) { + if ((si = subscription_start_instance(s, error)) == NULL) { subscription_unsubscribe(s, 1); return NULL; } + subscription_link_service(s, si->si_s); + subscription_show_info(s); } else { subscription_reschedule(); } @@ -859,11 +867,7 @@ subscription_init(void) void subscription_done(void) { - th_subscription_t *s; - pthread_mutex_lock(&global_lock); - LIST_FOREACH(s, &subscriptions, ths_global_link) - subscription_unsubscribe(s, 0); /* clear remaining subscriptions */ subscription_reschedule(); pthread_mutex_unlock(&global_lock); diff --git a/src/subscriptions.h b/src/subscriptions.h index 7221f21f..e760a2d2 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -30,10 +30,11 @@ extern struct th_subscription_list subscriptions; #define SUBSCRIPTION_STREAMING 0x004 #define SUBSCRIPTION_RESTART 0x008 #define SUBSCRIPTION_ONESHOT 0x010 -#define SUBSCRIPTION_INITSCAN 0x020 ///< for mux subscriptions -#define SUBSCRIPTION_IDLESCAN 0x040 ///< for mux subscriptions -#define SUBSCRIPTION_USERSCAN 0x080 ///< for mux subscriptions -#define SUBSCRIPTION_EPG 0x100 ///< for mux subscriptions +#define SUBSCRIPTION_TABLES 0x020 +#define SUBSCRIPTION_INITSCAN 0x040 ///< for mux subscriptions +#define SUBSCRIPTION_IDLESCAN 0x080 ///< for mux subscriptions +#define SUBSCRIPTION_USERSCAN 0x100 ///< for mux subscriptions +#define SUBSCRIPTION_EPG 0x200 ///< for mux subscriptions /* Some internal priorities */ #define SUBSCRIPTION_PRIO_KEEP 1 ///< Keep input rolling @@ -115,7 +116,10 @@ typedef struct th_subscription { /* * MPEG-TS mux chain */ +#if ENABLE_MPEGTS + service_t *ths_raw_service; LIST_ENTRY(th_subscription) ths_mux_link; +#endif } th_subscription_t;