mpegts: pass certain PIDs through to the TS muxer

Note: this will probably break the muxer atm, as its not expecting
those packets and will still mux in its own. But its just a start.
This commit is contained in:
Adam Sutton 2013-11-27 22:39:22 +00:00
parent d1eabea12d
commit d61c93afb7
10 changed files with 58 additions and 35 deletions

View file

@ -642,7 +642,7 @@ done:
static void _eit_start
( epggrab_module_ota_t *m, mpegts_mux_t *dm )
{
int pid;
int pid, opts = 0;
/* Disabled */
if (!m->enabled) return;
@ -665,9 +665,11 @@ static void _eit_start
/* Standard (0x12) */
} else {
pid = 0x12;
pid = 0x12;
opts = MT_RECORD;
}
mpegts_table_add(dm, 0, 0, _eit_callback, m, m->id, MT_CRC, pid);
mpegts_table_add(dm, 0, 0, _eit_callback, m, m->id, MT_CRC | opts, pid);
// TODO: might want to limit recording to EITpf only
tvhlog(LOG_DEBUG, m->id, "installed table handlers");
}

View file

@ -91,11 +91,10 @@ typedef struct mpegts_table_state
typedef struct mpegts_pid_sub
{
RB_ENTRY(mpegts_pid_sub) mps_link;
enum {
MPS_NONE,
MPS_STREAM,
MPS_TABLE
} mps_type;
#define MPS_NONE 0x0
#define MPS_STREAM 0x1
#define MPS_TABLE 0x2
int mps_type;
void *mps_owner;
} mpegts_pid_sub_t;
@ -118,6 +117,7 @@ struct mpegts_table
#define MT_CRC 0x1
#define MT_FULL 0x2
#define MT_QUICKREQ 0x4
#define MT_RECORD 0x8
/**
* Cycle queue

View file

@ -608,7 +608,7 @@ dvb_pat_callback
int save = 0;
if (mpegts_service_find(mm, sid, pid, 1, &save)) {
mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK, dvb_pmt_callback,
NULL, "pmt", MT_CRC | MT_QUICKREQ, pid);
NULL, "pmt", MT_CRC | MT_QUICKREQ | MT_RECORD, pid);
}
}

View file

@ -348,10 +348,10 @@ iptv_input_mux_started ( iptv_mux_t *im )
// TODO: not currently installing ATSC handler
mpegts_table_add((mpegts_mux_t*)im, DVB_SDT_BASE, DVB_SDT_MASK,
dvb_sdt_callback, NULL, "sdt",
MT_QUICKREQ | MT_CRC, DVB_SDT_PID);
MT_QUICKREQ | MT_CRC | MT_RECORD, DVB_SDT_PID);
mpegts_table_add((mpegts_mux_t*)im, DVB_PAT_BASE, DVB_PAT_MASK,
dvb_pat_callback, NULL, "pat",
MT_QUICKREQ | MT_CRC, DVB_PAT_PID);
MT_QUICKREQ | MT_CRC | MT_RECORD, DVB_PAT_PID);
}
/* **************************************************************************

View file

@ -406,7 +406,8 @@ linuxdvb_frontend_default_tables
/* Common */
mpegts_table_add(mm, DVB_PAT_BASE, DVB_PAT_MASK, dvb_pat_callback,
NULL, "pat", MT_QUICKREQ | MT_CRC, DVB_PAT_PID);
NULL, "pat", MT_QUICKREQ | MT_CRC | MT_RECORD,
DVB_PAT_PID);
#if 0
mpegts_table_add(mm, DVB_CAT_BASE, DVB_CAT_MASK, dvb_cat_callback,
NULL, "cat", MT_CRC, DVB_CAT_PID);
@ -420,7 +421,8 @@ linuxdvb_frontend_default_tables
else
tableid = DVB_VCT_C_BASE;
mpegts_table_add(mm, tableid, DVB_VCT_MASK, atsc_vct_callback,
NULL, "vct", MT_QUICKREQ | MT_CRC, DVB_VCT_PID);
NULL, "vct", MT_QUICKREQ | MT_CRC | MT_RECORD,
DVB_VCT_PID);
/* DVB */
} else {
@ -429,7 +431,8 @@ linuxdvb_frontend_default_tables
mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
NULL, "nit", MT_QUICKREQ | MT_CRC, DVB_NIT_PID);
mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback,
NULL, "sdt", MT_QUICKREQ | MT_CRC, DVB_SDT_PID);
NULL, "sdt", MT_QUICKREQ | MT_CRC | MT_RECORD,
DVB_SDT_PID);
mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback,
NULL, "bat", MT_CRC, DVB_BAT_PID);
#if 0

View file

@ -147,8 +147,12 @@ 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_type != b->mps_type) {
if (a->mps_type & MPS_STREAM)
return 1;
else
return -1;
}
if (a->mps_owner < b->mps_owner) return -1;
if (a->mps_owner > b->mps_owner) return 1;
return 0;
@ -360,19 +364,26 @@ mpegts_input_recv_packets
/* Find PID */
if ((mp = mpegts_mux_find_pid(mm, pid, 0))) {
int stream = 0;
int table = 0;
/* Stream takes pref. */
RB_FOREACH(mps, &mp->mp_subs, mps_link)
if (mps->mps_type == MPS_STREAM)
break;
RB_FOREACH(mps, &mp->mp_subs, mps_link) {
if (mps->mps_type & MPS_STREAM)
stream = 1;
if (mps->mps_type & MPS_TABLE)
table = 1;
}
printf("pid = %04X, stream = %d, table = %d\n", pid, stream, table);
/* Stream data */
if (mps) {
if (stream) {
LIST_FOREACH(s, &mi->mi_transports, s_active_link)
ts_recv_packet1((mpegts_service_t*)s, tsb+i, ppcr);
ts_recv_packet1((mpegts_service_t*)s, tsb+i, ppcr, table);
}
/* Table data */
} else {
if (table) {
if (!(tsb[i+1] & 0x80)) {
mpegts_table_feed_t *mtf = malloc(sizeof(mpegts_table_feed_t));
memcpy(mtf->mtf_tsb, tsb+i, 188);
@ -383,11 +394,12 @@ mpegts_input_recv_packets
tvhdebug("tsdemux", "%s - SI packet had errors", name);
}
}
}
/* Force PCR extraction for tsfile */
if (ppcr && *ppcr == PTS_UNSET)
ts_recv_packet1(NULL, tsb+i, ppcr);
} else {
if (ppcr && *ppcr == PTS_UNSET)
ts_recv_packet1(NULL, tsb+i, ppcr, 0);
}
i += 188;
len -= 188;

View file

@ -524,11 +524,13 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force )
void
mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
int type = MPS_TABLE;
if (mt->mt_flags & MT_RECORD) type |= MPS_STREAM;
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);
mi->mi_open_pid(mi, mm, mt->mt_pid, type, mt);
pthread_mutex_unlock(&mi->mi_delivery_mutex);
}
@ -536,10 +538,12 @@ void
mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
mpegts_input_t *mi;
int type = MPS_TABLE;
if (mt->mt_flags & MT_RECORD) type |= MPS_STREAM;
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);
mi->mi_close_pid(mi, mm, mt->mt_pid, type, mt);
pthread_mutex_unlock(&mi->mi_delivery_mutex);
}

View file

@ -92,7 +92,7 @@ ts_recv_packet0
// Mark as error if this is not the first packet of a payload
if(!pusi)
error |= 0x2;
error |= 0x2;
}
st->es_cc_valid = 1;
st->es_cc = (cc + 1) & 0xf;
@ -169,7 +169,8 @@ ts_process_pcr(mpegts_service_t *t, elementary_stream_t *st, int64_t pcr)
* Process service stream packets, extract PCR and optionally descramble
*/
int
ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
ts_recv_packet1
(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp, int table)
{
elementary_stream_t *st;
int pid, n, m, r;
@ -221,7 +222,7 @@ ts_recv_packet1(mpegts_service_t *t, const uint8_t *tsb, int64_t *pcrp)
if (pcr != PTS_UNSET)
ts_process_pcr(t, st, pcr);
if((st == NULL) && (pid != t->s_pcr_pid)) {
if((st == NULL) && (pid != t->s_pcr_pid) && !table) {
pthread_mutex_unlock(&t->s_stream_mutex);
return 0;
}

View file

@ -21,7 +21,8 @@
int ts_resync ( const uint8_t *tsb, int *len, int *idx );
int 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, int table);
void ts_recv_packet2(struct mpegts_service *t, const uint8_t *tsb);

View file

@ -215,15 +215,15 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t )
/* Install table handlers */
mpegts_table_add(mm, DVB_PAT_BASE, DVB_PAT_MASK, dvb_pat_callback,
NULL, "pat", MT_QUICKREQ | MT_CRC, DVB_PAT_PID);
NULL, "pat", MT_QUICKREQ | MT_CRC | MT_RECORD, DVB_PAT_PID);
mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback,
NULL, "sdt", MT_QUICKREQ | MT_CRC, DVB_SDT_PID);
NULL, "sdt", MT_QUICKREQ | MT_CRC | MT_RECORD, DVB_SDT_PID);
mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback,
NULL, "bat", MT_CRC, DVB_BAT_PID);
mpegts_table_add(mm, DVB_VCT_T_BASE, DVB_VCT_MASK, atsc_vct_callback,
NULL, "vct", MT_CRC, DVB_VCT_PID);
NULL, "vct", MT_QUICKREQ | MT_CRC | MT_RECORD, DVB_VCT_PID);
mpegts_table_add(mm, DVB_VCT_C_BASE, DVB_VCT_MASK, atsc_vct_callback,
NULL, "vct", MT_CRC, DVB_VCT_PID);
NULL, "vct", MT_QUICKREQ | MT_CRC | MT_RECORD, DVB_VCT_PID);
#if 0
mpegts_table_add(mm, 0x1, 0xff, dvb_cat_callback, NULL, "cat",
MT_CRC, 1);