From: Jaroslav Kysela Date: Fri, 13 Apr 2018 18:11:35 +0000 (+0200) Subject: pass muxer: add rewrite NIT, fixes #5062 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f0241da6a008b80317085ec2f389d96269dc688;p=thirdparty%2Ftvheadend.git pass muxer: add rewrite NIT, fixes #5062 --- diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 4b5caa424..0b236946a 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -2225,8 +2225,8 @@ static void 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); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index b7bdf1d53..7c6a3a554 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -1072,7 +1072,7 @@ static void mpegts_input_analyze_table_queue ( mpegts_input_t *mi ) memset(&counters, 0, sizeof(counters)); TAILQ_FOREACH(mtf, &mi->mi_table_queue, mtf_link) { const uint8_t *tsb = mtf->mtf_tsb; - pid = (tsb[1] << 8) | tsb[2]; + pid = ((tsb[1] << 8) & 0x0f) | tsb[2]; sizes[pid] += mtf->mtf_len; counters[pid]++; } diff --git a/src/muxer.h b/src/muxer.h index 9b3ba408c..9801f9b78 100644 --- a/src/muxer.h +++ b/src/muxer.h @@ -72,6 +72,7 @@ typedef struct muxer_config { int m_rewrite_pat; int m_rewrite_pmt; int m_rewrite_sdt; + int m_rewrite_nit; int m_rewrite_eit; char *m_cmdline; char *m_mime; diff --git a/src/muxer/muxer_pass.c b/src/muxer/muxer_pass.c index a6ea51dd1..b3c96b211 100644 --- a/src/muxer/muxer_pass.c +++ b/src/muxer/muxer_pass.c @@ -49,6 +49,7 @@ typedef struct pass_muxer { /* TS muxing */ uint8_t pm_rewrite_sdt; + uint8_t pm_rewrite_nit; uint8_t pm_rewrite_eit; uint16_t pm_pmt_pid; @@ -58,6 +59,7 @@ typedef struct pass_muxer { 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; @@ -199,6 +201,8 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) 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; @@ -229,6 +233,45 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) } } +/* + * + */ +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); + } +} + /* * */ @@ -328,6 +371,7 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) 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++) { @@ -338,6 +382,10 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) 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; @@ -496,7 +544,7 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) /* 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) { @@ -508,6 +556,7 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) 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 */ @@ -528,6 +577,11 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) 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) { @@ -628,6 +682,7 @@ pass_muxer_destroy(muxer_t *m) 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); @@ -668,6 +723,8 @@ pass_muxer_create(const muxer_config_t *m_cfg, 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); diff --git a/src/profile.c b/src/profile.c index 07e25eaf4..7c693789e 100644 --- a/src/profile.c +++ b/src/profile.c @@ -1254,6 +1254,7 @@ typedef struct profile_mpegts { int pro_rewrite_pmt; int pro_rewrite_pat; int pro_rewrite_sdt; + int pro_rewrite_nit; int pro_rewrite_eit; } profile_mpegts_t; @@ -1267,6 +1268,7 @@ profile_pass_rewrite_sid_set (void *in, const void *v) 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; @@ -1306,6 +1308,12 @@ profile_pass_rewrite_sdt_set (void *in, const void *v) 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) { @@ -1380,6 +1388,19 @@ const idclass_t profile_mpegts_pass_class = .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", @@ -1415,6 +1436,7 @@ profile_mpegts_pass_reopen(profile_chain_t *prch, 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); @@ -1449,6 +1471,7 @@ profile_mpegts_pass_builder(void) 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; } @@ -1544,6 +1567,7 @@ profile_mpegts_spawn_reopen(profile_chain_t *prch, 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);