psi_tables_dvb ( mpegts_mux_t *mm )
{
mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback,
- NULL, "nit", LS_TBL_BASE, MT_QUICKREQ | MT_CRC, DVB_NIT_PID,
- MPS_WEIGHT_NIT);
+ NULL, "nit", LS_TBL_BASE, MT_QUICKREQ | MT_CRC | MT_RECORD,
+ DVB_NIT_PID, MPS_WEIGHT_NIT);
mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback,
NULL, "sdt", LS_TBL_BASE, MT_QUICKREQ | MT_CRC | MT_RECORD,
DVB_SDT_PID, MPS_WEIGHT_SDT);
/* TS muxing */
uint8_t pm_rewrite_sdt;
+ uint8_t pm_rewrite_nit;
uint8_t pm_rewrite_eit;
uint16_t pm_pmt_pid;
mpegts_psi_table_t pm_pat;
mpegts_psi_table_t pm_pmt;
mpegts_psi_table_t pm_sdt;
+ mpegts_psi_table_t pm_nit;
mpegts_psi_table_t pm_eit;
} pass_muxer_t;
while (len >= 5) {
sid = (buf[0] << 8) | buf[1];
l = (buf[3] & 0x0f) << 8 | buf[4];
+ if (l > len - 5)
+ return;
if (sid != pm->pm_src_sid) {
buf += l + 5;
len -= l + 5;
}
}
+/*
+ *
+ */
+static void
+pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
+{
+ pass_muxer_t *pm;
+ uint8_t out[4096], *ob;
+ int l, ol;
+
+ /* filter out the other networks */
+ if (buf[0] != 0x40)
+ return;
+
+ if (len < 10)
+ return;
+
+ pm = (pass_muxer_t*)mt->mt_opaque;
+ l = (buf[8] & 0x0f) << 8 | buf[9];
+ ol = 2 + 3 + 2 + 3 + l;
+
+ if (ol > len)
+ return;
+
+ if (sizeof(out) < ol) {
+ tvherror(LS_PASS, "NIT entry too long (%i)", ol);
+ return;
+ }
+
+ memcpy(out, buf, ol);
+
+ ol = dvb_table_append_crc32(out, ol, sizeof(out));
+
+ if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) {
+ pass_muxer_write((muxer_t *)pm, ob, l);
+ free(ob);
+ }
+}
+
/*
*
*/
pm->pm_dst_sid = ss->ss_service_id;
pm->pm_pmt_pid = ss->ss_pmt_pid;
pm->pm_rewrite_sdt = !!pm->m_config.u.pass.m_rewrite_sdt;
+ pm->pm_rewrite_nit = !!pm->m_config.u.pass.m_rewrite_nit;
pm->pm_rewrite_eit = !!pm->m_config.u.pass.m_rewrite_eit;
for(i=0; i < ss->ss_num_components; i++) {
tvhwarn(LS_PASS, "SDT PID shared with A/V, rewrite disabled");
pm->pm_rewrite_sdt = 0;
}
+ if (ssc->es_pid == DVB_NIT_PID && pm->pm_rewrite_nit) {
+ tvhwarn(LS_PASS, "NIT PID shared with A/V, rewrite disabled");
+ pm->pm_rewrite_nit = 0;
+ }
if (ssc->es_pid == DVB_EIT_PID && pm->pm_rewrite_eit) {
tvhwarn(LS_PASS, "EIT PID shared with A/V, rewrite disabled");
pm->pm_rewrite_eit = 0;
/* Rewrite PAT/PMT in operation */
if (pm->m_config.u.pass.m_rewrite_pat || pm->m_config.u.pass.m_rewrite_pmt ||
- pm->pm_rewrite_sdt || pm->pm_rewrite_eit) {
+ pm->pm_rewrite_sdt || pm->pm_rewrite_nit || pm->pm_rewrite_eit) {
for (tsb = pktbuf_ptr(pb), len2 = pktbuf_len(pb), len = 0;
len2 > 0; tsb += l, len2 -= l) {
if ( (pm->m_config.u.pass.m_rewrite_pat && pid == DVB_PAT_PID) ||
(pm->m_config.u.pass.m_rewrite_pmt && pid == pm->pm_pmt_pid) ||
(pm->pm_rewrite_sdt && pid == DVB_SDT_PID) ||
+ (pm->pm_rewrite_nit && pid == DVB_NIT_PID) ||
(pm->pm_rewrite_eit && pid == DVB_EIT_PID) ) {
/* Flush */
dvb_table_parse(&pm->pm_sdt, "-", tsb, l, 1, 0, pass_muxer_sdt_cb);
+ /* NIT */
+ } else if (pid == DVB_NIT_PID) {
+
+ dvb_table_parse(&pm->pm_nit, "-", tsb, l, 1, 0, pass_muxer_nit_cb);
+
/* EIT */
} else if (pid == DVB_EIT_PID) {
dvb_table_parse_done(&pm->pm_pat);
dvb_table_parse_done(&pm->pm_pmt);
dvb_table_parse_done(&pm->pm_sdt);
+ dvb_table_parse_done(&pm->pm_nit);
dvb_table_parse_done(&pm->pm_eit);
muxer_config_free(&pm->m_config);
DVB_PMT_BASE, DVB_PMT_MASK, pm);
dvb_table_parse_init(&pm->pm_sdt, "pass-sdt", LS_TBL_PASS, DVB_SDT_PID,
DVB_SDT_BASE, DVB_SDT_MASK, pm);
+ dvb_table_parse_init(&pm->pm_nit, "pass-nit", LS_TBL_PASS, DVB_NIT_PID,
+ DVB_NIT_BASE, DVB_NIT_MASK, pm);
dvb_table_parse_init(&pm->pm_eit, "pass-eit", LS_TBL_PASS, DVB_EIT_PID,
0, 0, pm);
int pro_rewrite_pmt;
int pro_rewrite_pat;
int pro_rewrite_sdt;
+ int pro_rewrite_nit;
int pro_rewrite_eit;
} profile_mpegts_t;
pro->pro_rewrite_pmt =
pro->pro_rewrite_pat =
pro->pro_rewrite_sdt =
+ pro->pro_rewrite_nit =
pro->pro_rewrite_eit = 1;
}
pro->pro_rewrite_sid = *val;
return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_sdt);
}
+static int
+profile_pass_rewrite_nit_set (void *in, const void *v)
+{
+ return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_nit);
+}
+
static int
profile_pass_rewrite_eit_set (void *in, const void *v)
{
.def.i = 1,
.group = 2
},
+ {
+ .type = PT_BOOL,
+ .id = "rewrite_nit",
+ .name = N_("Rewrite NIT"),
+ .desc = N_("Rewrite NIT (Network Information Table) packets "
+ "to only include information about the currently-"
+ "streamed service."),
+ .off = offsetof(profile_mpegts_t, pro_rewrite_nit),
+ .set = profile_pass_rewrite_nit_set,
+ .opts = PO_EXPERT,
+ .def.i = 1,
+ .group = 2
+ },
{
.type = PT_BOOL,
.id = "rewrite_eit",
c.u.pass.m_rewrite_pat = pro->pro_rewrite_pat;
c.u.pass.m_rewrite_pmt = pro->pro_rewrite_pmt;
c.u.pass.m_rewrite_sdt = pro->pro_rewrite_sdt;
+ c.u.pass.m_rewrite_nit = pro->pro_rewrite_nit;
c.u.pass.m_rewrite_eit = pro->pro_rewrite_eit;
assert(!prch->prch_muxer);
pro->pro_rewrite_pat = 1;
pro->pro_rewrite_pmt = 1;
pro->pro_rewrite_sdt = 1;
+ pro->pro_rewrite_nit = 1;
pro->pro_rewrite_eit = 1;
return (profile_t *)pro;
}
c.u.pass.m_rewrite_pat = 1;
c.u.pass.m_rewrite_pmt = 1;
c.u.pass.m_rewrite_sdt = 1;
+ c.u.pass.m_rewrite_nit = 1;
c.u.pass.m_rewrite_eit = 1;
mystrset(&c.u.pass.m_cmdline, pro->pro_cmdline);
mystrset(&c.u.pass.m_mime, pro->pro_mime);