From: Jaroslav Kysela Date: Tue, 23 May 2017 09:37:37 +0000 (+0200) Subject: pass muxer: add possibility to rewrite SID, fixes #3774 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f3c671d54089b5657ad55146c751ee23c9e02719;p=thirdparty%2Ftvheadend.git pass muxer: add possibility to rewrite SID, fixes #3774 --- diff --git a/src/muxer.h b/src/muxer.h index 209f6696a..8604a4154 100644 --- a/src/muxer.h +++ b/src/muxer.h @@ -67,6 +67,7 @@ typedef struct muxer_config { */ union { struct { + int m_rewrite_sid; int m_rewrite_pat; int m_rewrite_pmt; int m_rewrite_sdt; diff --git a/src/muxer/muxer_pass.c b/src/muxer/muxer_pass.c index 74008ffa7..852d7d302 100644 --- a/src/muxer/muxer_pass.c +++ b/src/muxer/muxer_pass.c @@ -50,7 +50,8 @@ typedef struct pass_muxer { uint8_t pm_rewrite_eit; uint16_t pm_pmt_pid; - uint16_t pm_service_id; + uint16_t pm_src_sid; + uint16_t pm_dst_sid; mpegts_psi_table_t pm_pat; mpegts_psi_table_t pm_pmt; @@ -85,8 +86,8 @@ pass_muxer_pat_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) out[2] = 13; /* section_length (number of bytes after this field, including CRC) */ out[7] = 0; - out[8] = (pm->pm_service_id & 0xff00) >> 8; - out[9] = pm->pm_service_id & 0x00ff; + out[8] = (pm->pm_dst_sid & 0xff00) >> 8; + out[9] = pm->pm_dst_sid & 0x00ff; out[10] = 0xe0 | ((pm->pm_pmt_pid & 0x1f00) >> 8); out[11] = pm->pm_pmt_pid & 0x00ff; @@ -121,10 +122,12 @@ pass_muxer_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) return; pm = (pass_muxer_t*)mt->mt_opaque; - if (sid != pm->pm_service_id) + if (sid != pm->pm_src_sid) return; - memcpy(out + ol, buf, 9); + out[ol + 0] = pm->pm_dst_sid >> 8; + out[ol + 1] = pm->pm_dst_sid & 0xff; + memcpy(out + ol + 2, buf + 2, 7); ol += 9; /* skip common descriptors */ buf += 9 + l; @@ -195,7 +198,7 @@ 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 (sid != pm->pm_service_id) { + if (sid != pm->pm_src_sid) { buf += l + 5; len -= l + 5; continue; @@ -204,7 +207,9 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) tvherror(LS_PASS, "SDT entry too long (%i)", l); return; } - memcpy(out + ol, buf, l + 5); + out[ol + 0] = pm->pm_dst_sid >> 8; + out[ol + 1] = pm->pm_dst_sid & 0xff; + memcpy(out + ol + 2, buf + 2, l + 3); /* set free CA */ out[ol + 3] = out[ol + 3] & ~0x10; ol += l + 5; @@ -231,7 +236,7 @@ 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; + uint8_t *sbuf, *out; int olen; /* filter out the other transponders */ @@ -240,17 +245,23 @@ pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) pm = (pass_muxer_t*)mt->mt_opaque; sid = (buf[3] << 8) | buf[4]; - if (sid != pm->pm_service_id) + if (sid != pm->pm_src_sid) return; /* TODO: set free_CA_mode bit to zero */ - len = dvb_table_append_crc32((uint8_t *)buf, len, len + 4); + sbuf = malloc(len + 4); + memcpy(sbuf, buf, len); + sbuf[3] = pm->pm_dst_sid >> 8; + sbuf[4] = pm->pm_dst_sid & 0xff; - if (len > 0 && (olen = dvb_table_remux(mt, buf, len, &out)) > 0) { + len = dvb_table_append_crc32(sbuf, len, len + 4); + if (len > 0 && (olen = dvb_table_remux(mt, sbuf, len, &out)) > 0) { pass_muxer_write((muxer_t *)pm, out, olen); free(out); } + + free(sbuf); } /** @@ -305,8 +316,12 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) const streaming_start_component_t *ssc; int i; - pm->pm_service_id = ss->ss_service_id; - pm->pm_pmt_pid = ss->ss_pmt_pid; + pm->pm_src_sid = ss->ss_service_id; + if (pm->m_config.u.pass.m_rewrite_sid > 0) + pm->pm_dst_sid = pm->m_config.u.pass.m_rewrite_sid; + else + 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_eit = !!pm->m_config.u.pass.m_rewrite_eit; diff --git a/src/profile.c b/src/profile.c index 364167275..182c7105f 100644 --- a/src/profile.c +++ b/src/profile.c @@ -1094,17 +1094,32 @@ profile_htsp_builder(void) */ typedef struct profile_mpegts { profile_t; + uint16_t pro_rewrite_sid; int pro_rewrite_pmt; int pro_rewrite_pat; int pro_rewrite_sdt; int pro_rewrite_eit; } profile_mpegts_t; +static htsmsg_t * +profile_class_pass_save ( idnode_t *in, char *filename, size_t fsize ) +{ + profile_mpegts_t *pro = (profile_mpegts_t *)in; + if (pro->pro_rewrite_sid > 0) { + pro->pro_rewrite_pmt = + pro->pro_rewrite_pat = + pro->pro_rewrite_sdt = + pro->pro_rewrite_eit = 1; + } + return profile_class_save(in, filename, fsize); +} + const idclass_t profile_mpegts_pass_class = { .ic_super = &profile_class, .ic_class = "profile-mpegts", .ic_caption = N_("MPEG-TS Pass-thru/built-in"), + .ic_save = profile_class_pass_save, .ic_groups = (const property_group_t[]) { { .name = N_("Configuration"), @@ -1117,6 +1132,17 @@ const idclass_t profile_mpegts_pass_class = {} }, .ic_properties = (const property_t[]){ + { + .type = PT_U16, + .id = "sid", + .name = N_("Rewrite Service ID"), + .desc = N_("Rewrite service identificator (SID) using the specified " + "value (usually 1)."), + .off = offsetof(profile_mpegts_t, pro_rewrite_sid), + .opts = PO_EXPERT, + .def.i = 1, + .group = 2 + }, { .type = PT_BOOL, .id = "rewrite_pmt", @@ -1182,6 +1208,7 @@ profile_mpegts_pass_reopen(profile_chain_t *prch, memset(&c, 0, sizeof(c)); if (c.m_type != MC_RAW) c.m_type = MC_PASS; + c.u.pass.m_rewrite_sid = pro->pro_rewrite_sid; 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; @@ -1221,6 +1248,11 @@ profile_mpegts_pass_builder(void) pro->pro_reopen = profile_mpegts_pass_reopen; pro->pro_open = profile_mpegts_pass_open; pro->pro_get_mc = profile_mpegts_pass_get_mc; + pro->pro_rewrite_sid = 1; + pro->pro_rewrite_pat = 1; + pro->pro_rewrite_pmt = 1; + pro->pro_rewrite_sdt = 1; + pro->pro_rewrite_eit = 1; return (profile_t *)pro; } @@ -1230,6 +1262,7 @@ profile_mpegts_pass_builder(void) typedef struct profile_matroska { profile_t; int pro_webm; + int pro_dvbsub_reorder; } profile_matroska_t; const idclass_t profile_matroska_class = diff --git a/src/profile.h b/src/profile.h index 1e03d230d..cd518c52e 100644 --- a/src/profile.h +++ b/src/profile.h @@ -134,7 +134,6 @@ typedef struct profile { int pro_ca_timeout; int pro_swservice; int pro_svfilter; - int pro_dvbsub_reorder; void (*pro_free)(struct profile *pro); void (*pro_conf_changed)(struct profile *pro);