]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
pass muxer: add possibility to rewrite SID, fixes #3774
authorJaroslav Kysela <perex@perex.cz>
Tue, 23 May 2017 09:37:37 +0000 (11:37 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 23 May 2017 09:37:37 +0000 (11:37 +0200)
src/muxer.h
src/muxer/muxer_pass.c
src/profile.c
src/profile.h

index 209f6696a6a78486daa8c65dc5ced81d823becc3..8604a415476893de22dc2f0e003b155170ea4fe6 100644 (file)
@@ -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;
index 74008ffa73c388a6b85882491aea60ac3bfc50ec..852d7d30269eeb7f3853b04a5c1fa9e4ec61eb02 100644 (file)
@@ -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;
 
index 3641672751de2f6e10d967581450cba6012792b2..182c7105f494c517b588b6599762037d8a9a009d 100644 (file)
@@ -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 =
index 1e03d230d48e87f7050bf0b758579e48c830a015..cd518c52e76948f8da470c98a252bdb34b5a6567 100644 (file)
@@ -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);