subscription: add TABLES subscription type handling, fix some memory leaks
This commit is contained in:
parent
ffa0639149
commit
cd99597a5c
15 changed files with 123 additions and 60 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue