diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index e4103524..f69e2d07 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -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"); } diff --git a/src/input/mpegts.h b/src/input/mpegts.h index ef01a3e2..5445c0f2 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -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 diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index a7200c3e..90f79ba5 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -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); } } diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 768cba7a..42407fca 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -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); } /* ************************************************************************** diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index a164b8a5..6e83bb0e 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -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 diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 1831f8bf..1546be43 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -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; diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 3d74c6f8..7aeef8c7 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -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); } diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index c373d2f7..7cb078d1 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -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; } diff --git a/src/input/mpegts/tsdemux.h b/src/input/mpegts/tsdemux.h index 19d430df..756f9acb 100644 --- a/src/input/mpegts/tsdemux.h +++ b/src/input/mpegts/tsdemux.h @@ -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); diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index 8fb7ec35..95f2a24d 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -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);