mpegts input: optimize the PID decoding
This commit is contained in:
parent
787ba1f1d6
commit
29308193bd
3 changed files with 46 additions and 42 deletions
|
@ -146,10 +146,12 @@ typedef struct mpegts_table_state
|
|||
typedef struct mpegts_pid_sub
|
||||
{
|
||||
RB_ENTRY(mpegts_pid_sub) mps_link;
|
||||
#define MPS_NONE 0x0
|
||||
#define MPS_STREAM 0x1
|
||||
#define MPS_TABLE 0x2
|
||||
#define MPS_FTABLE 0x4
|
||||
LIST_ENTRY(mpegts_pid_sub) mps_svc_link;
|
||||
#define MPS_NONE 0x0
|
||||
#define MPS_STREAM 0x1
|
||||
#define MPS_TABLE 0x2
|
||||
#define MPS_FTABLE 0x4
|
||||
#define MPS_SERVICE 0x8
|
||||
int mps_type;
|
||||
void *mps_owner;
|
||||
} mpegts_pid_sub_t;
|
||||
|
@ -157,9 +159,11 @@ typedef struct mpegts_pid_sub
|
|||
typedef struct mpegts_pid
|
||||
{
|
||||
int mp_pid;
|
||||
int mp_type; // mask for all subscribers
|
||||
int mp_fd; // linuxdvb demux fd
|
||||
int8_t mp_cc;
|
||||
RB_HEAD(,mpegts_pid_sub) mp_subs; // subscribers to pid
|
||||
LIST_HEAD(,mpegts_pid_sub) mp_svc_subs;
|
||||
RB_ENTRY(mpegts_pid) mp_link;
|
||||
} mpegts_pid_t;
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ static int
|
|||
mps_cmp ( mpegts_pid_sub_t *a, mpegts_pid_sub_t *b )
|
||||
{
|
||||
if (a->mps_type != b->mps_type) {
|
||||
if (a->mps_type & MPS_STREAM)
|
||||
if (a->mps_type & MPS_SERVICE)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
@ -423,12 +423,17 @@ mpegts_input_open_pid
|
|||
mpegts_pid_t *mp;
|
||||
mpegts_pid_sub_t *mps;
|
||||
assert(owner != NULL);
|
||||
assert((type & (MPS_STREAM|MPS_SERVICE)) == 0 ||
|
||||
((type & MPS_STREAM) ? 1 : 0) != ((type & MPS_SERVICE) ? 1 : 0));
|
||||
lock_assert(&mi->mi_output_lock);
|
||||
if ((mp = mpegts_mux_find_pid(mm, pid, 1))) {
|
||||
mps = calloc(1, sizeof(*mps));
|
||||
mps->mps_type = type;
|
||||
mps->mps_owner = owner;
|
||||
if (!RB_INSERT_SORTED(&mp->mp_subs, mps, mps_link, mps_cmp)) {
|
||||
mp->mp_type |= type;
|
||||
if (type & MPS_SERVICE)
|
||||
LIST_INSERT_HEAD(&mp->mp_svc_subs, mps, mps_svc_link);
|
||||
mpegts_mux_nice_name(mm, buf, sizeof(buf));
|
||||
tvhdebug("mpegts", "%s - open PID %04X (%d) [%d/%p]",
|
||||
buf, mp->mp_pid, mp->mp_pid, type, owner);
|
||||
|
@ -462,6 +467,8 @@ mpegts_input_close_pid
|
|||
mpegts_mux_nice_name(mm, buf, sizeof(buf));
|
||||
tvhdebug("mpegts", "%s - close PID %04X (%d) [%d/%p]",
|
||||
buf, mp->mp_pid, mp->mp_pid, type, owner);
|
||||
if (type & MPS_SERVICE)
|
||||
LIST_REMOVE(mps, mps_svc_link);
|
||||
RB_REMOVE(&mp->mp_subs, mps, mps_link);
|
||||
free(mps);
|
||||
if (!RB_FIRST(&mp->mp_subs)) {
|
||||
|
@ -469,6 +476,11 @@ mpegts_input_close_pid
|
|||
if (mp->mp_fd != -1)
|
||||
linuxdvb_filter_close(mp->mp_fd);
|
||||
free(mp);
|
||||
} else {
|
||||
type = 0;
|
||||
RB_FOREACH(mps, &mp->mp_subs, mps_link)
|
||||
type |= mps->mps_type;
|
||||
mp->mp_type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -487,13 +499,13 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init )
|
|||
|
||||
/* Register PIDs */
|
||||
pthread_mutex_lock(&s->s_stream_mutex);
|
||||
mi->mi_open_pid(mi, s->s_dvb_mux, s->s_pmt_pid, MPS_STREAM, s);
|
||||
mi->mi_open_pid(mi, s->s_dvb_mux, s->s_pcr_pid, MPS_STREAM, s);
|
||||
mi->mi_open_pid(mi, s->s_dvb_mux, s->s_pmt_pid, MPS_SERVICE, s);
|
||||
mi->mi_open_pid(mi, s->s_dvb_mux, s->s_pcr_pid, MPS_SERVICE, s);
|
||||
/* 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, s->s_dvb_mux, st->es_pid, MPS_STREAM, s);
|
||||
mi->mi_open_pid(mi, s->s_dvb_mux, st->es_pid, MPS_SERVICE, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,13 +538,13 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s )
|
|||
|
||||
/* Close PID */
|
||||
pthread_mutex_lock(&s->s_stream_mutex);
|
||||
mi->mi_close_pid(mi, s->s_dvb_mux, s->s_pmt_pid, MPS_STREAM, s);
|
||||
mi->mi_close_pid(mi, s->s_dvb_mux, s->s_pcr_pid, MPS_STREAM, s);
|
||||
mi->mi_close_pid(mi, s->s_dvb_mux, s->s_pmt_pid, MPS_SERVICE, s);
|
||||
mi->mi_close_pid(mi, s->s_dvb_mux, s->s_pcr_pid, MPS_SERVICE, s);
|
||||
/* 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, s->s_dvb_mux, st->es_pid, MPS_STREAM, s);
|
||||
mi->mi_close_pid(mi, s->s_dvb_mux, st->es_pid, MPS_SERVICE, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -920,7 +932,7 @@ mpegts_input_process
|
|||
uint8_t cc;
|
||||
uint8_t *tsb = mpkt->mp_data;
|
||||
int len = mpkt->mp_len;
|
||||
int table = 0, stream = 0, f;
|
||||
int type = 0, f;
|
||||
mpegts_pid_t *mp;
|
||||
mpegts_pid_sub_t *mps;
|
||||
service_t *s;
|
||||
|
@ -928,7 +940,6 @@ mpegts_input_process
|
|||
uint8_t *end = mpkt->mp_data + len;
|
||||
mpegts_mux_t *mm = mpkt->mp_mux;
|
||||
mpegts_mux_instance_t *mmi;
|
||||
mpegts_pid_t *last_mp = NULL;
|
||||
th_subscription_t *ths;
|
||||
#if ENABLE_TSDEBUG
|
||||
off_t tsdebug_pos;
|
||||
|
@ -981,45 +992,32 @@ mpegts_input_process
|
|||
mp->mp_cc = (cc + 1) & 0xF;
|
||||
}
|
||||
|
||||
if (mp != last_mp) {
|
||||
last_mp = mp;
|
||||
if (pid == 0) {
|
||||
stream = MPS_STREAM;
|
||||
table = MPS_TABLE;
|
||||
} else {
|
||||
stream = table = 0;
|
||||
type = mp->mp_type;
|
||||
|
||||
/* Determine PID type */
|
||||
RB_FOREACH(mps, &mp->mp_subs, mps_link) {
|
||||
stream |= mps->mps_type & MPS_STREAM;
|
||||
table |= mps->mps_type & (MPS_TABLE | MPS_FTABLE);
|
||||
if (table == (MPS_TABLE|MPS_FTABLE) && stream) break;
|
||||
}
|
||||
|
||||
/* Special case streams */
|
||||
LIST_FOREACH(s, &mi->mi_transports, s_active_link) {
|
||||
if (((mpegts_service_t*)s)->s_dvb_mux != mm) continue;
|
||||
if (pid == s->s_pmt_pid) stream = MPS_STREAM;
|
||||
else if (pid == s->s_pcr_pid) stream = MPS_STREAM;
|
||||
}
|
||||
/* Stream service data */
|
||||
if (type & MPS_SERVICE) {
|
||||
LIST_FOREACH(mps, &mp->mp_svc_subs, mps_svc_link) {
|
||||
s = mps->mps_owner;
|
||||
f = (type & (MPS_TABLE|MPS_FTABLE)) ||
|
||||
(pid == s->s_pmt_pid) || (pid == s->s_pcr_pid);
|
||||
ts_recv_packet1((mpegts_service_t*)s, tsb, NULL, f);
|
||||
}
|
||||
}
|
||||
|
||||
/* Stream data */
|
||||
if (stream) {
|
||||
} else
|
||||
/* Stream table data */
|
||||
if (type & MPS_STREAM) {
|
||||
LIST_FOREACH(s, &mi->mi_transports, s_active_link) {
|
||||
if (((mpegts_service_t*)s)->s_dvb_mux != mm) continue;
|
||||
f = table || (pid == s->s_pmt_pid) || (pid == s->s_pcr_pid);
|
||||
f = (type & (MPS_TABLE|MPS_FTABLE)) ||
|
||||
(pid == s->s_pmt_pid) || (pid == s->s_pcr_pid);
|
||||
ts_recv_packet1((mpegts_service_t*)s, tsb, NULL, f);
|
||||
}
|
||||
}
|
||||
|
||||
/* Table data */
|
||||
if (table) {
|
||||
if (type & (MPS_TABLE | MPS_FTABLE)) {
|
||||
if (!(tsb[1] & 0x80)) {
|
||||
if (table & MPS_FTABLE)
|
||||
if (type & MPS_FTABLE)
|
||||
mpegts_input_table_dispatch(mm, tsb);
|
||||
if (table & MPS_TABLE) {
|
||||
if (type & MPS_TABLE) {
|
||||
// TODO: might be able to optimise this a bit by having slightly
|
||||
// larger buffering and trying to aggregate data (if we get
|
||||
// same PID multiple times in the loop)
|
||||
|
|
|
@ -889,6 +889,8 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason )
|
|||
tvhdebug("mpegts", "%s - close PID %04X (%d) [%d/%p]", buf,
|
||||
mp->mp_pid, mp->mp_pid, mps->mps_type, mps->mps_owner);
|
||||
RB_REMOVE(&mp->mp_subs, mps, mps_link);
|
||||
if (mps->mps_type & MPS_SERVICE)
|
||||
LIST_REMOVE(mps, mps_svc_link);
|
||||
free(mps);
|
||||
}
|
||||
RB_REMOVE(&mm->mm_pids, mp, mp_link);
|
||||
|
|
Loading…
Add table
Reference in a new issue