mpegts pass muxer: add possibility to rewrite/filter SDT and EIT tables, fixes #2043
This commit is contained in:
parent
d5c5f67bfe
commit
9ee27b671b
3 changed files with 134 additions and 4 deletions
|
@ -50,6 +50,8 @@ typedef struct muxer_config {
|
|||
|
||||
int m_rewrite_pat;
|
||||
int m_rewrite_pmt;
|
||||
int m_rewrite_sdt;
|
||||
int m_rewrite_eit;
|
||||
int m_cache;
|
||||
|
||||
/*
|
||||
|
|
|
@ -48,9 +48,17 @@ typedef struct pass_muxer {
|
|||
uint8_t *pm_pmt;
|
||||
uint16_t pm_pmt_version;
|
||||
uint16_t pm_service_id;
|
||||
uint32_t pm_streams[256]; /* lookup table identifying which streams to include in the PMT */
|
||||
|
||||
mpegts_psi_table_t pm_sdt;
|
||||
mpegts_psi_table_t pm_eit;
|
||||
|
||||
} pass_muxer_t;
|
||||
|
||||
|
||||
static void
|
||||
pass_muxer_write(muxer_t *m, const void *data, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* Append CRC
|
||||
*/
|
||||
|
@ -275,6 +283,87 @@ pass_muxer_rewrite_pat(pass_muxer_t* pm, unsigned char* tsb)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void
|
||||
pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
|
||||
{
|
||||
pass_muxer_t *pm;
|
||||
uint8_t out[1024], *ob;
|
||||
uint16_t sid;
|
||||
int l, ol;
|
||||
|
||||
/* filter out the other transponders */
|
||||
if (buf[0] != 0x42)
|
||||
return;
|
||||
|
||||
pm = (pass_muxer_t*)mt->mt_opaque;
|
||||
ol = 8 + 3;
|
||||
memcpy(out, buf, ol);
|
||||
buf += ol;
|
||||
len -= ol;
|
||||
while (len >= 5) {
|
||||
sid = (buf[0] << 8) | buf[1];
|
||||
l = (buf[3] & 0x0f) << 8 | buf[4];
|
||||
if (sid != pm->pm_service_id) {
|
||||
buf += l + 5;
|
||||
len -= l + 5;
|
||||
continue;
|
||||
}
|
||||
if (sizeof(out) < ol + l + 5 + 4 /* crc */) {
|
||||
tvherror("pass", "SDT entry too long (%i)", l);
|
||||
return;
|
||||
}
|
||||
memcpy(out + ol, buf, l + 5);
|
||||
/* set free CA */
|
||||
out[ol + 3] = out[ol + 3] & ~0x10;
|
||||
ol += l + 5;
|
||||
break;
|
||||
}
|
||||
|
||||
/* update section length */
|
||||
out[1] = (out[1] & 0xf0) | ((ol + 4 - 3) >> 8);
|
||||
out[2] = (ol + 4 - 3) & 0xff;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void
|
||||
pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
|
||||
{
|
||||
pass_muxer_t *pm;
|
||||
uint16_t sid;
|
||||
uint8_t *out;
|
||||
int olen;
|
||||
|
||||
/* filter out the other transponders */
|
||||
if ((buf[0] < 0x50 && buf[0] != 0x4e) || buf[0] > 0x5f || len < 14)
|
||||
return;
|
||||
|
||||
pm = (pass_muxer_t*)mt->mt_opaque;
|
||||
sid = (buf[3] << 8) | buf[4];
|
||||
if (sid != pm->pm_service_id)
|
||||
return;
|
||||
|
||||
/* TODO: set free_CA_mode bit to zero */
|
||||
|
||||
len = dvb_table_append_crc32((uint8_t *)buf, len, len + 4);
|
||||
|
||||
if (len > 0 && (olen = dvb_table_remux(mt, buf, len, &out)) > 0) {
|
||||
pass_muxer_write((muxer_t *)pm, out, olen);
|
||||
free(out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out the mime-type for the muxed data stream
|
||||
*/
|
||||
|
@ -451,8 +540,10 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb)
|
|||
int pid = (tsb[1] & 0x1f) << 8 | tsb[2];
|
||||
|
||||
/* Process */
|
||||
if ( (pm->m_config.m_rewrite_pat && (pid == 0)) ||
|
||||
(pm->m_config.m_rewrite_pmt && (pid == pm->pm_pmt_pid)) ) {
|
||||
if ( (pm->m_config.m_rewrite_pat && pid == DVB_PAT_PID) ||
|
||||
(pm->m_config.m_rewrite_pmt && pid == pm->pm_pmt_pid) ||
|
||||
(pm->m_config.m_rewrite_sdt && pid == DVB_SDT_PID) ||
|
||||
(pm->m_config.m_rewrite_eit && pid == DVB_EIT_PID) ) {
|
||||
|
||||
/* Flush */
|
||||
if (len)
|
||||
|
@ -463,7 +554,8 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb)
|
|||
len = 0;
|
||||
|
||||
/* PAT */
|
||||
if (pid == 0) {
|
||||
if (pid == DVB_PAT_PID) {
|
||||
|
||||
memcpy(tmp, tsb, sizeof(tmp));
|
||||
e = pass_muxer_rewrite_pat(pm, tmp);
|
||||
if (e < 0) {
|
||||
|
@ -473,11 +565,23 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb)
|
|||
if (e)
|
||||
pass_muxer_write(m, tmp, 188);
|
||||
|
||||
/* SDT */
|
||||
} else if (pid == DVB_SDT_PID) {
|
||||
|
||||
dvb_table_parse(&pm->pm_sdt, tsb, 188, 1, 0, pass_muxer_sdt_cb);
|
||||
|
||||
/* EIT */
|
||||
} else if (pid == DVB_EIT_PID) {
|
||||
|
||||
dvb_table_parse(&pm->pm_eit, tsb, 188, 1, 0, pass_muxer_eit_cb);
|
||||
|
||||
/* PMT */
|
||||
} else if (tsb[1] & 0x40) { /* pusi - the first PMT packet */
|
||||
|
||||
pm->pm_pmt[3] = (pm->pm_pmt[3] & 0xf0) | pm->pm_pmt_cc;
|
||||
pm->pm_pmt_cc = (pm->pm_pmt_cc + 1) & 0xf;
|
||||
pass_muxer_write(m, pm->pm_pmt, 188);
|
||||
|
||||
}
|
||||
|
||||
/* Record */
|
||||
|
@ -565,6 +669,9 @@ pass_muxer_destroy(muxer_t *m)
|
|||
if(pm->pm_pmt)
|
||||
free(pm->pm_pmt);
|
||||
|
||||
dvb_table_parse_done(&pm->pm_sdt);
|
||||
dvb_table_parse_done(&pm->pm_eit);
|
||||
|
||||
free(pm);
|
||||
}
|
||||
|
||||
|
@ -592,6 +699,9 @@ pass_muxer_create(const muxer_config_t *m_cfg)
|
|||
pm->m_destroy = pass_muxer_destroy;
|
||||
pm->pm_fd = -1;
|
||||
|
||||
dvb_table_parse_init(&pm->pm_sdt, "pass-sdt", DVB_SDT_PID, pm);
|
||||
dvb_table_parse_init(&pm->pm_eit, "pass-eit", DVB_EIT_PID, pm);
|
||||
|
||||
return (muxer_t *)pm;
|
||||
}
|
||||
|
||||
|
|
|
@ -865,6 +865,8 @@ typedef struct profile_mpegts {
|
|||
profile_t;
|
||||
int pro_rewrite_pmt;
|
||||
int pro_rewrite_pat;
|
||||
int pro_rewrite_sdt;
|
||||
int pro_rewrite_eit;
|
||||
} profile_mpegts_t;
|
||||
|
||||
const idclass_t profile_mpegts_pass_class =
|
||||
|
@ -887,6 +889,20 @@ const idclass_t profile_mpegts_pass_class =
|
|||
.off = offsetof(profile_mpegts_t, pro_rewrite_pat),
|
||||
.def.i = 1,
|
||||
},
|
||||
{
|
||||
.type = PT_BOOL,
|
||||
.id = "rewrite_sdt",
|
||||
.name = "Rewrite SDT",
|
||||
.off = offsetof(profile_mpegts_t, pro_rewrite_sdt),
|
||||
.def.i = 1,
|
||||
},
|
||||
{
|
||||
.type = PT_BOOL,
|
||||
.id = "rewrite_eit",
|
||||
.name = "Rewrite EIT",
|
||||
.off = offsetof(profile_mpegts_t, pro_rewrite_eit),
|
||||
.def.i = 1,
|
||||
},
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
@ -906,6 +922,8 @@ profile_mpegts_pass_reopen(profile_chain_t *prch,
|
|||
c.m_type = MC_PASS;
|
||||
c.m_rewrite_pat = pro->pro_rewrite_pat;
|
||||
c.m_rewrite_pmt = pro->pro_rewrite_pmt;
|
||||
c.m_rewrite_sdt = pro->pro_rewrite_sdt;
|
||||
c.m_rewrite_eit = pro->pro_rewrite_eit;
|
||||
|
||||
assert(!prch->prch_muxer);
|
||||
prch->prch_muxer = muxer_create(&c);
|
||||
|
|
Loading…
Add table
Reference in a new issue