Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
subscription: add TABLES subscription type handling, fix some memory …
…leaks
  • Loading branch information
perexg committed Mar 11, 2015
1 parent ffa0639 commit cd99597
Show file tree
Hide file tree
Showing 15 changed files with 122 additions and 59 deletions.
7 changes: 5 additions & 2 deletions src/epggrab/otamux.c
Expand Up @@ -546,8 +546,11 @@ epggrab_ota_kick_cb ( void *p )

/* 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)
Expand Down
10 changes: 7 additions & 3 deletions src/input/mpegts.h
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -502,6 +504,8 @@ struct mpegts_service
{
service_t; // Parent

int s_dvb_subscription_flags;

/*
* Fields defined by DVB standard EN 300 468
*/
Expand Down Expand Up @@ -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*);
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions src/input/mpegts/linuxdvb/linuxdvb_frontend.c
Expand Up @@ -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;
Expand Down
53 changes: 29 additions & 24 deletions src/input/mpegts/mpegts_input.c
Expand Up @@ -408,35 +408,28 @@ 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 )
{
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) +
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}


Expand Down Expand Up @@ -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);
}
Expand Down
16 changes: 12 additions & 4 deletions src/input/mpegts/mpegts_mux.c
Expand Up @@ -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));
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/input/mpegts/mpegts_network_scan.c
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/input/mpegts/mpegts_pid.c
Expand Up @@ -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;
Expand Down
17 changes: 10 additions & 7 deletions src/input/mpegts/mpegts_service.c
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

/*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/input/mpegts/satip/satip_frontend.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit cd99597

Please sign in to comment.