mpegts: rework of the PID handling code

This should overcome the current issues with EPG grabbers stealing data
but also, IMO, is a better approach.

However it did require some reworking of lock semantics.
This commit is contained in:
Adam Sutton 2013-09-24 13:40:36 +01:00
parent 67e221300c
commit 859f08aa5d
12 changed files with 276 additions and 172 deletions

View file

@ -87,6 +87,25 @@ typedef struct mpegts_table_state
RB_ENTRY(mpegts_table_state) link;
} mpegts_table_state_t;
typedef struct mpegts_pid_sub
{
RB_ENTRY(mpegts_pid_sub) mps_link;
enum {
MPS_NONE,
MPS_STREAM,
MPS_TABLE
} mps_type;
void *mps_owner;
} mpegts_pid_sub_t;
typedef struct mpegts_pid
{
int mp_pid;
int mp_fd; // linuxdvb demux fd
RB_HEAD(,mpegts_pid_sub) mp_subs; // subscribers to pid
RB_ENTRY(mpegts_pid) mp_link;
} mpegts_pid_t;
struct mpegts_table
{
/**
@ -110,7 +129,6 @@ struct mpegts_table
/**
* File descriptor for filter
*/
int mt_fd;
LIST_ENTRY(mpegts_table) mt_link;
mpegts_mux_t *mt_mux;
@ -260,13 +278,14 @@ struct mpegts_mux
mpegts_mux_instance_t *mm_active;
/*
* Table processing
* Data processing
*/
RB_HEAD(, mpegts_pid) mm_pids;
int mm_num_tables;
LIST_HEAD(, mpegts_table) mm_tables;
TAILQ_HEAD(, mpegts_table) mm_table_queue;
uint8_t mm_table_filter[8192];
/*
* Functions
@ -442,6 +461,8 @@ 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 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*);
void (*mi_create_mux_instance) (mpegts_input_t*,mpegts_mux_t*);
void (*mi_started_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
void (*mi_stopped_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
@ -574,6 +595,8 @@ void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int re
int mpegts_mux_subscribe(mpegts_mux_t *mm, const char *name, int weight);
void mpegts_mux_unsubscribe_by_name(mpegts_mux_t *mm, const char *name);
mpegts_pid_t *mpegts_mux_find_pid(mpegts_mux_t *mm, int pid, int create);
size_t mpegts_input_recv_packets
(mpegts_input_t *mi, mpegts_mux_instance_t *mmi, uint8_t *tsb, size_t len,
int64_t *pcr, uint16_t *pcr_pid, const char *name);
@ -588,6 +611,12 @@ void mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *c );
void mpegts_input_flush_mux ( mpegts_input_t *mi, mpegts_mux_t *mm );
mpegts_pid_t * mpegts_input_open_pid
( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner );
void mpegts_input_close_pid
( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner );
void mpegts_table_dispatch
(const uint8_t *sec, size_t r, void *mt);
void mpegts_table_release

View file

@ -675,7 +675,7 @@ int
dvb_pmt_callback
(mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
{
int r, sect, last, ver;
int r, sect, last, ver, had_components;
uint16_t sid;
mpegts_mux_t *mm = mt->mt_mux;
mpegts_service_t *s;
@ -694,8 +694,11 @@ dvb_pmt_callback
/* Process */
tvhdebug("pmt", "sid %04X (%d)", sid, sid);
pthread_mutex_lock(&s->s_stream_mutex);
psi_parse_pmt(s, ptr, len);
had_components = !!TAILQ_FIRST(&s->s_components);
r = psi_parse_pmt(s, ptr, len);
pthread_mutex_unlock(&s->s_stream_mutex);
if (r)
service_restart((service_t*)s, had_components);
/* Finish */
return dvb_table_end(mt, st, sect);
@ -1170,10 +1173,11 @@ psi_desc_teletext(mpegts_service_t *t, const uint8_t *ptr, int size,
/**
* PMT parser, from ISO 13818-1 and ETSI EN 300 468
*/
int
static int
psi_parse_pmt
(mpegts_service_t *t, const uint8_t *ptr, int len)
{
int ret = 0;
uint16_t pcr_pid, pid;
uint8_t estype;
int dllen;
@ -1181,7 +1185,6 @@ psi_parse_pmt
streaming_component_type_t hts_stream_type;
elementary_stream_t *st, *next;
int update = 0;
int had_components;
int composition_id;
int ancillary_id;
int version;
@ -1194,8 +1197,6 @@ psi_parse_pmt
lock_assert(&t->s_stream_mutex);
had_components = !!TAILQ_FIRST(&t->s_components);
version = ptr[2] >> 1 & 0x1f;
pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6];
dllen = (ptr[7] & 0xf) << 8 | ptr[8];
@ -1441,8 +1442,8 @@ psi_parse_pmt
PMT_UPDATE_CA_PROVIDER_CHANGE |
PMT_UPDATE_CAID_DELETED)) {
if(t->s_status == SERVICE_RUNNING)
service_restart((service_t*)t, had_components);
ret = 1;
}
}
return 0;
return ret;
}

View file

@ -289,32 +289,37 @@ linuxdvb_frontend_start_mux
return linuxdvb_frontend_tune1((linuxdvb_frontend_t*)mi, mmi, -1);
}
static int
linuxdvb_frontend_open_pid
( linuxdvb_frontend_t *lfe, int pid, const char *name )
static void
linuxdvb_frontend_open_pid0
( linuxdvb_frontend_t *lfe, mpegts_pid_t *mp )
{
char buf[256];
char name[256];
struct dmx_pes_filter_params dmx_param;
int fd = -1;
int fd;
/* Already opened */
if (mp->mp_fd != -1)
return;
/* Not locked OR full mux mode */
if (!lfe->lfe_locked || lfe->lfe_fullmux)
return -1;
return;
if (!name) {
lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf));
name = buf;
}
lfe->mi_display_name((mpegts_input_t*)lfe, name, sizeof(name));
/* Open DMX */
fd = tvh_open(lfe->lfe_dmx_path, O_RDWR, 0);
if(fd == -1) {
tvherror("linuxdvb", "%s - failed to open dmx for pid %d [e=%s]",
name, pid, strerror(errno));
return -1;
name, mp->mp_pid, strerror(errno));
return;
}
tvhtrace("linuxdvb", "%s - open PID %04X (%d) fd %d", name, pid, pid, fd);
/* Install filter */
tvhtrace("linuxdvb", "%s - open PID %04X (%d) fd %d",
name, mp->mp_pid, mp->mp_pid, fd);
memset(&dmx_param, 0, sizeof(dmx_param));
dmx_param.pid = pid;
dmx_param.pid = mp->mp_pid;
dmx_param.input = DMX_IN_FRONTEND;
dmx_param.output = DMX_OUT_TS_TAP;
dmx_param.pes_type = DMX_PES_OTHER;
@ -322,54 +327,30 @@ linuxdvb_frontend_open_pid
if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) {
tvherror("linuxdvb", "%s - failed to config dmx for pid %d [e=%s]",
name, pid, strerror(errno));
name, mp->mp_pid, strerror(errno));
close(fd);
return -1;
return;
}
return fd;
/* Store */
mp->mp_fd = fd;
return;
}
static void
linuxdvb_frontend_open_service
( mpegts_input_t *mi, mpegts_service_t *s, int init )
static mpegts_pid_t *
linuxdvb_frontend_open_pid
( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner )
{
char buf[256];
elementary_stream_t *st;
mpegts_pid_t *mp;
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
/* Ignore in full rx mode OR if not yet locked */
if (!lfe->lfe_locked || lfe->lfe_fullmux) goto exit;
mi->mi_display_name(mi, buf, sizeof(buf));
/* Install PES filters */
TAILQ_FOREACH(st, &s->s_components, es_link) {
if(st->es_pid >= 0x2000)
continue;
if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, owner)))
return NULL;
if(st->es_demuxer_fd != -1)
continue;
linuxdvb_frontend_open_pid0(lfe, mp);
st->es_cc_valid = 0;
st->es_demuxer_fd
= linuxdvb_frontend_open_pid((linuxdvb_frontend_t*)mi, st->es_pid, buf);
}
exit:
mpegts_input_open_service(mi, s, init);
}
static void
linuxdvb_frontend_close_service
( mpegts_input_t *mi, mpegts_service_t *s )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
/* Ignore in full rx mode OR if not yet locked */
if (!lfe->lfe_locked || lfe->lfe_fullmux) goto exit;
exit:
mpegts_input_close_service(mi, s);
return mp;
}
static idnode_set_t *
@ -443,22 +424,6 @@ linuxdvb_frontend_default_tables
}
}
static void
linuxdvb_frontend_open_all
( linuxdvb_frontend_t *lfe, mpegts_mux_t *mm )
{
mpegts_table_t *mt;
service_t *s;
LIST_FOREACH(s, &lfe->mi_transports, s_active_link) {
lfe->mi_open_service((mpegts_input_t*)lfe,
(mpegts_service_t*)s, 0);
}
LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
if (mt->mt_fd == -1)
mt->mt_fd = lfe->lfe_open_pid(lfe, mt->mt_pid, NULL);
}
}
static void
linuxdvb_frontend_monitor ( void *aux )
{
@ -468,6 +433,7 @@ linuxdvb_frontend_monitor ( void *aux )
linuxdvb_frontend_t *lfe = aux;
mpegts_mux_instance_t *mmi = LIST_FIRST(&lfe->mi_mux_active);
mpegts_mux_t *mm;
mpegts_pid_t *mp;
fe_status_t fe_status;
signal_state_t status;
@ -533,8 +499,11 @@ linuxdvb_frontend_monitor ( void *aux )
/* Table handlers */
linuxdvb_frontend_default_tables(lfe, (linuxdvb_mux_t*)mm);
/* Services */
linuxdvb_frontend_open_all(lfe, mm);
/* Locked - ensure everything is open */
pthread_mutex_lock(&lfe->mi_delivery_mutex);
RB_FOREACH(mp, &mm->mm_pids, mp_link)
linuxdvb_frontend_open_pid0(lfe, mp);
pthread_mutex_unlock(&lfe->mi_delivery_mutex);
/* Re-arm (quick) */
} else {
@ -853,10 +822,8 @@ linuxdvb_frontend_create0
lfe->mi_is_enabled = linuxdvb_frontend_is_enabled;
lfe->mi_start_mux = linuxdvb_frontend_start_mux;
lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
lfe->mi_open_service = linuxdvb_frontend_open_service;
lfe->mi_close_service = linuxdvb_frontend_close_service;
lfe->mi_network_list = linuxdvb_frontend_network_list;
lfe->lfe_open_pid = linuxdvb_frontend_open_pid;
lfe->mi_open_pid = linuxdvb_frontend_open_pid;
/* Adapter link */
lfe->lh_parent = (linuxdvb_hardware_t*)la;

View file

@ -499,30 +499,6 @@ linuxdvb_mux_create_instances ( mpegts_mux_t *mm )
mi->mi_create_mux_instance(mi, mm);
}
static void
linuxdvb_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
linuxdvb_frontend_t *lfe;
mpegts_mux_open_table(mm, mt);
/* Open DMX */
if (mm->mm_active) {
lfe = (linuxdvb_frontend_t*)mm->mm_active->mmi_input;
mt->mt_fd = lfe->lfe_open_pid(lfe, mt->mt_pid, NULL);
} else {
mt->mt_fd = -1;
}
}
static void
linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
mpegts_mux_close_table(mm, mt);
if (mt->mt_fd != -1)
close(mt->mt_fd);
}
static void
linuxdvb_mux_delete ( mpegts_mux_t *mm )
{
@ -580,8 +556,6 @@ linuxdvb_mux_create0
lm->mm_display_name = linuxdvb_mux_display_name;
lm->mm_config_save = linuxdvb_mux_config_save;
lm->mm_create_instances = linuxdvb_mux_create_instances;
lm->mm_open_table = linuxdvb_mux_open_table;
lm->mm_close_table = linuxdvb_mux_close_table;
/* No config */
if (!conf) return lm;

View file

@ -128,25 +128,110 @@ mpegts_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
{
}
static int
mps_cmp ( mpegts_pid_sub_t *a, mpegts_pid_sub_t *b )
{
if (a->mps_type != b->mps_type)
return a->mps_type - b->mps_type;
if (a->mps_owner < b->mps_owner) return -1;
if (a->mps_owner > b->mps_owner) return 1;
return 0;
}
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_mux_find_pid(mm, pid, 1);
assert(owner != NULL);
if (mp) {
static mpegts_pid_sub_t *skel = NULL;
if (!skel)
skel = calloc(1, sizeof(mpegts_pid_sub_t));
skel->mps_type = type;
skel->mps_owner = owner;
if (!RB_INSERT_SORTED(&mp->mp_subs, skel, mps_link, mps_cmp)) {
mm->mm_display_name(mm, buf, sizeof(buf));
tvhdebug("mpegts", "%s - open PID %04X (%d) [%d/%p]",
buf, mp->mp_pid, mp->mp_pid, type, owner);
skel = NULL;
}
}
return mp;
}
void
mpegts_input_close_pid
( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner )
{
char buf[512];
mpegts_pid_sub_t *mps, skel;
mpegts_pid_t *mp = mpegts_mux_find_pid(mm, pid, 1);
assert(owner != NULL);
skel.mps_type = type;
skel.mps_owner = owner;
mps = RB_FIND(&mp->mp_subs, &skel, mps_link, mps_cmp);
if (mps) {
RB_REMOVE(&mp->mp_subs, mps, mps_link);
free(mps);
if (!RB_FIRST(&mp->mp_subs)) {
RB_REMOVE(&mm->mm_pids, mp, mp_link);
if (mp->mp_fd != -1) {
mm->mm_display_name(mm, buf, sizeof(buf));
tvhdebug("mpegts", "%s - close PID %04X (%d) [%d/%p]",
buf, mp->mp_pid, mp->mp_pid, type, owner);
close(mp->mp_fd);
}
free(mp);
}
}
}
void
mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init )
{
if (!init) return;
elementary_stream_t *st;
/* Add to list */
pthread_mutex_lock(&mi->mi_delivery_mutex);
LIST_INSERT_HEAD(&mi->mi_transports, ((service_t*)s), s_active_link);
s->s_dvb_active_input = mi;
if (!s->s_dvb_active_input) {
LIST_INSERT_HEAD(&mi->mi_transports, ((service_t*)s), s_active_link);
s->s_dvb_active_input = mi;
}
/* Register PIDs */
pthread_mutex_lock(&s->s_stream_mutex);
TAILQ_FOREACH(st, &s->s_components, es_link)
mi->mi_open_pid(mi, s->s_dvb_mux, st->es_pid, MPS_STREAM, s);
pthread_mutex_unlock(&s->s_stream_mutex);
pthread_mutex_unlock(&mi->mi_delivery_mutex);
}
void
mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s )
{
elementary_stream_t *st;
/* Remove from list */
pthread_mutex_lock(&mi->mi_delivery_mutex);
if (s->s_dvb_active_input != NULL) {
LIST_REMOVE(((service_t*)s), s_active_link);
s->s_dvb_active_input = NULL;
}
/* Close PID */
pthread_mutex_lock(&s->s_stream_mutex);
TAILQ_FOREACH(st, &s->s_components, es_link)
mi->mi_close_pid(mi, s->s_dvb_mux, st->es_pid, MPS_STREAM, s);
pthread_mutex_unlock(&s->s_stream_mutex);
pthread_mutex_unlock(&mi->mi_delivery_mutex);
/* Stop mux? */
s->s_dvb_mux->mm_stop(s->s_dvb_mux, 0);
}
@ -259,32 +344,44 @@ mpegts_input_recv_packets
/* Sync */
if ( tsb[i] == 0x47 ) {
int pid = ((tsb[i+1] & 0x1f) << 8) | tsb[i+2];
mpegts_pid_t *mp;
mpegts_pid_sub_t *mps;
service_t *s;
int pid = ((tsb[i+1] & 0x1f) << 8) | tsb[i+2];
int64_t *ppcr = (pcr_pid && *pcr_pid == pid) ? pcr : NULL;
tvhtrace("tsdemux", "%s - recv_packet for pid %04X (%d)", name, pid, pid);
/* SI data */
if (mm->mm_table_filter[pid]) {
if (!(tsb[i+1] & 0x80)) {
mpegts_table_feed_t *mtf = malloc(sizeof(mpegts_table_feed_t));
memcpy(mtf->mtf_tsb, tsb+i, 188);
mtf->mtf_mux = mm;
TAILQ_INSERT_TAIL(&mi->mi_table_feed, mtf, mtf_link);
table_wakeup = 1;
/* Find PID */
if ((mp = mpegts_mux_find_pid(mm, pid, 0))) {
/* Stream takes pref. */
RB_FOREACH(mps, &mp->mp_subs, mps_link)
if (mps->mps_type == MPS_STREAM)
break;
/* Stream data */
if (mps) {
LIST_FOREACH(s, &mi->mi_transports, s_active_link)
ts_recv_packet1((mpegts_service_t*)s, tsb+i, ppcr);
/* Table data */
} else {
tvhdebug("tsdemux", "%s - SI packet had errors", name);
if (!(tsb[i+1] & 0x80)) {
mpegts_table_feed_t *mtf = malloc(sizeof(mpegts_table_feed_t));
memcpy(mtf->mtf_tsb, tsb+i, 188);
mtf->mtf_mux = mm;
TAILQ_INSERT_TAIL(&mi->mi_table_feed, mtf, mtf_link);
table_wakeup = 1;
} else {
tvhdebug("tsdemux", "%s - SI packet had errors", name);
}
}
/* Other */
} else {
service_t *s;
int64_t *ppcr = (pcr_pid && *pcr_pid == pid) ? pcr : NULL;
LIST_FOREACH(s, &mi->mi_transports, s_active_link) {
ts_recv_packet1((mpegts_service_t*)s, tsb+i, ppcr);
}
if (ppcr && *ppcr == PTS_UNSET)
ts_recv_packet1(NULL, tsb+i, ppcr);
}
/* Force PCR extraction for tsfile */
if (ppcr && *ppcr == PTS_UNSET)
ts_recv_packet1(NULL, tsb+i, ppcr);
i += 188;
len -= 188;
@ -489,6 +586,8 @@ 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_create_mux_instance = mpegts_input_create_mux_instance;
mi->mi_started_mux = mpegts_input_started_mux;
mi->mi_stopped_mux = mpegts_input_stopped_mux;

View file

@ -400,6 +400,8 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force )
mpegts_mux_instance_t *mmi = mm->mm_active;
mpegts_input_t *mi = NULL;
th_subscription_t *sub;
mpegts_pid_t *mp;
mpegts_pid_sub_t *mps;
if (!force && mpegts_mux_has_subscribers(mm))
return;
@ -423,8 +425,19 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force )
if (mi)
mpegts_input_flush_mux(mi, mm);
/* Alert listeners */
// TODO
/* Ensure PIDs are cleared */
while ((mp = RB_FIRST(&mm->mm_pids))) {
while ((mps = RB_FIRST(&mp->mp_subs))) {
RB_REMOVE(&mp->mp_subs, mps, mps_link);
free(mps);
}
RB_REMOVE(&mm->mm_pids, mp, mp_link);
if (mp->mp_fd) {
tvhdebug("mpegts", "%s - close PID %04X (%d)", buf, mp->mp_pid, mp->mp_pid);
close(mp->mp_fd);
}
free(mp);
}
/* Scanning */
if (mm->mm_initial_scan_status == MM_SCAN_CURRENT) {
@ -446,26 +459,23 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force )
void
mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
char buf[256];
if (mt->mt_pid >= 0x2000)
return;
mm->mm_display_name(mm, buf, sizeof(buf));
if (!mm->mm_table_filter[mt->mt_pid])
tvhtrace("mpegts", "%s - opened table %s pid %04X (%d)",
buf, mt->mt_name, mt->mt_pid, mt->mt_pid);
mm->mm_table_filter[mt->mt_pid] = 1;
mpegts_input_t *mi;
if (!mm->mm_active || !mm->mm_active->mmi_input) return;
mi = mm->mm_active->mmi_input;
pthread_mutex_lock(&mi->mi_delivery_mutex);
mi->mi_open_pid(mi, mm, mt->mt_pid, MPS_TABLE, mt);
pthread_mutex_unlock(&mi->mi_delivery_mutex);
}
void
mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
char buf[256];
if (mt->mt_pid >= 0x2000)
return;
mm->mm_display_name(mm, buf, sizeof(buf));
tvhtrace("mpegts", "%s - closed table %s pid %04X (%d)",
buf, mt->mt_name, mt->mt_pid, mt->mt_pid);
mm->mm_table_filter[mt->mt_pid] = 0;
mpegts_input_t *mi;
if (!mm->mm_active || !mm->mm_active->mmi_input) return;
mi = mm->mm_active->mmi_input;
pthread_mutex_lock(&mi->mi_delivery_mutex);
mi->mi_close_pid(mi, mm, mt->mt_pid, MPS_TABLE, mt);
pthread_mutex_unlock(&mi->mi_delivery_mutex);
}
/* **************************************************************************
@ -702,6 +712,37 @@ mpegts_mux_find_service ( mpegts_mux_t *mm, uint16_t sid)
return ms;
}
static int mp_cmp ( mpegts_pid_t *a, mpegts_pid_t *b )
{
return a->mp_pid - b->mp_pid;
};
mpegts_pid_t *
mpegts_mux_find_pid ( mpegts_mux_t *mm, int pid, int create )
{
mpegts_pid_t *mp;
if (pid > 0x2000) return NULL;
if (!create) {
mpegts_pid_t skel;
skel.mp_pid = pid;
mp = RB_FIND(&mm->mm_pids, &skel, mp_link, mp_cmp);
} else {
static mpegts_pid_t *skel = NULL;
if (!skel)
skel = calloc(1, sizeof(mpegts_pid_t));
skel->mp_pid = pid;
mp = RB_INSERT_SORTED(&mm->mm_pids, skel, mp_link, mp_cmp);
if (!mp) {
mp = skel;
skel = NULL;
mp->mp_fd = -1;
}
}
return mp;
}
/******************************************************************************
* Editor Configuration
*

View file

@ -154,7 +154,6 @@ mpegts_table_add
mt->mt_table = tableid;
mt->mt_mask = mask;
mt->mt_mux = mm;
mt->mt_fd = -1;
mt->mt_cc = -1;
LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link);
mm->mm_num_tables++;

View file

@ -165,7 +165,7 @@ ts_process_pcr(mpegts_service_t *t, elementary_stream_t *st, int64_t pcr)
/**
* Process service stream packets, extract PCR and optionally descramble
*/
void
int
ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
{
elementary_stream_t *st;
@ -194,11 +194,11 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
}
/* Nothing - special case for tsfile to get PCR */
if (!t) return;
if (!t) return 0;
/* Service inactive - ignore */
if(t->s_status != SERVICE_RUNNING)
return;
return 0;
pthread_mutex_lock(&t->s_stream_mutex);
@ -220,7 +220,7 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
if(st == NULL) {
pthread_mutex_unlock(&t->s_stream_mutex);
return;
return 0;
}
if(!error)
@ -246,7 +246,7 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
r = td->td_descramble(td, (service_t*)t, st, tsb);
if(r == 0) {
pthread_mutex_unlock(&t->s_stream_mutex);
return;
return 1;
}
if(r == 1)
@ -265,6 +265,7 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
ts_recv_packet0(t, st, tsb);
}
pthread_mutex_unlock(&t->s_stream_mutex);
return 1;
}

View file

@ -21,7 +21,7 @@
int ts_resync ( const uint8_t *tsb, int *len, int *idx );
void ts_recv_packet1(struct mpegts_service *t, const uint8_t *tsb, int64_t *pcrp);
int ts_recv_packet1(struct mpegts_service *t, const uint8_t *tsb, int64_t *pcrp);
void ts_recv_packet2(struct mpegts_service *t, const uint8_t *tsb);

View file

@ -240,6 +240,8 @@ tsfile_input_create ( int idx )
mi->mi_start_mux = tsfile_input_start_mux;
mi->mi_stop_mux = tsfile_input_stop_mux;
LIST_INSERT_HEAD(&tsfile_inputs, mi, mi_global_link);
if (!mi->mi_displayname)
mi->mi_displayname = strdup("TSFile");
/* Start table thread */
tvhthread_create(&tid, NULL, mpegts_input_table_thread, mi);

View file

@ -205,12 +205,6 @@ stream_init(elementary_stream_t *st)
static void
stream_clean(elementary_stream_t *st)
{
if(st->es_demuxer_fd != -1) {
// XXX: Should be in DVB-code perhaps
close(st->es_demuxer_fd);
st->es_demuxer_fd = -1;
}
free(st->es_priv);
st->es_priv = NULL;
@ -629,7 +623,6 @@ service_stream_create(service_t *t, int pid,
st->es_service = t;
st->es_pid = pid;
st->es_demuxer_fd = -1;
avgstat_init(&st->es_rate, 10);
avgstat_init(&st->es_cc_errors, 10);
@ -792,7 +785,7 @@ void
service_restart(service_t *t, int had_components)
{
streaming_message_t *sm;
lock_assert(&t->s_stream_mutex);
pthread_mutex_lock(&t->s_stream_mutex);
if(had_components) {
sm = streaming_msg_create_code(SMT_STOP, SM_CODE_SOURCE_RECONFIGURED);
@ -800,18 +793,19 @@ service_restart(service_t *t, int had_components)
streaming_msg_free(sm);
}
if(t->s_refresh_feed != NULL)
t->s_refresh_feed(t);
descrambler_service_start(t);
if(TAILQ_FIRST(&t->s_components) != NULL) {
sm = streaming_msg_create_data(SMT_START,
service_build_stream_start(t));
streaming_pad_deliver(&t->s_streaming_pad, sm);
streaming_msg_free(sm);
}
pthread_mutex_unlock(&t->s_stream_mutex);
if(t->s_refresh_feed != NULL)
t->s_refresh_feed(t);
}
@ -948,9 +942,7 @@ service_saver(void *aux)
if(t->s_status != SERVICE_ZOMBIE)
t->s_config_save(t);
if(t->s_status == SERVICE_RUNNING && restart) {
pthread_mutex_lock(&t->s_stream_mutex);
service_restart(t, 1);
pthread_mutex_unlock(&t->s_stream_mutex);
}
service_unref(t);

View file

@ -61,7 +61,6 @@ typedef struct elementary_stream {
avgstat_t es_cc_errors;
avgstat_t es_rate;
int es_demuxer_fd;
int es_peak_presentation_delay; /* Max seen diff. of DTS and PTS */
/* PCR recovery */