]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
pass muxer: add more rewrites, fix NIT rewrite, fix teletext subs, fixes #5062, fixes...
authorJaroslav Kysela <perex@perex.cz>
Fri, 20 Apr 2018 09:12:20 +0000 (11:12 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 20 Apr 2018 09:15:29 +0000 (11:15 +0200)
src/esstream.h
src/input/mpegts/mpegts_service.c
src/muxer/muxer_pass.c
src/service.c
src/service.h
src/streaming.h
src/subscriptions.c

index 31b0886cded6113ea19cc3c9b8da27c949cf85b7..41b704d6c996810005e60a8ddb72de669d491b8d 100644 (file)
@@ -107,6 +107,10 @@ struct elementary_info {
 
   uint16_t es_composition_id;
   uint16_t es_ancillary_id;
+
+  uint16_t es_parent_pid;    /* For subtitle streams originating from
+                               a teletext stream. this is the pid
+                               of the teletext stream */
 };
 
 /**
@@ -123,9 +127,6 @@ struct elementary_stream {
   char *es_nicename;
 
   /* PID related */
-  uint16_t es_parent_pid;    /* For subtitle streams originating from
-                               a teletext stream. this is the pid
-                               of the teletext stream */
   int8_t es_pid_opened;      /* PID is opened */
   int8_t es_cc;              /* Last CC */
   int8_t es_delete_me;       /* Temporary flag for deleting streams */
index 2112f3c54513e60e93fbc1197f1ba9207326a790..afef1d58cac39ad79b1d748773c8f13bb4a5ed91 100644 (file)
@@ -500,6 +500,9 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si)
     si->si_satpos = strdup(buf);
   }
 #endif
+
+  si->si_tsid = m->mm_tsid;
+  si->si_onid = m->mm_onid;
 }
 
 /*
index b3c96b211b7578001da8e097a063af565cb93a1a..628da6b31a41d1c012f5c446b72d86e11289d2e3 100644 (file)
@@ -55,6 +55,10 @@ typedef struct pass_muxer {
   uint16_t pm_pmt_pid;
   uint16_t pm_src_sid;
   uint16_t pm_dst_sid;
+  uint16_t pm_src_tsid;
+  uint16_t pm_dst_tsid;
+  uint16_t pm_src_onid;
+  uint16_t pm_dst_onid;
 
   mpegts_psi_table_t pm_pat;
   mpegts_psi_table_t pm_pmt;
@@ -87,10 +91,12 @@ pass_muxer_pat_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
 
   out[1] = 0x80;
   out[2] = 13; /* section_length (number of bytes after this field, including CRC) */
+  out[3] = pm->pm_dst_tsid >> 8;
+  out[4] = pm->pm_dst_tsid;
   out[7] = 0;
 
-  out[8] = (pm->pm_dst_sid & 0xff00) >> 8;
-  out[9] = pm->pm_dst_sid & 0x00ff;
+  out[8] = pm->pm_dst_sid >> 8;
+  out[9] = pm->pm_dst_sid;
   out[10] = 0xe0 | ((pm->pm_pmt_pid & 0x1f00) >> 8);
   out[11] = pm->pm_pmt_pid & 0x00ff;
 
@@ -198,6 +204,12 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
   memcpy(out, buf, ol);
   buf += ol;
   len -= ol;
+
+  out[3] = pm->pm_dst_tsid >> 8;
+  out[4] = pm->pm_dst_tsid;
+  out[8] = pm->pm_dst_onid >> 8;
+  out[9] = pm->pm_dst_onid;
+
   while (len >= 5) {
     sid = (buf[0] << 8) | buf[1];
     l = (buf[3] & 0x0f) << 8 | buf[4];
@@ -240,8 +252,8 @@ 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;
+  uint8_t out[4096], *ob, dtag;
+  int l, ol, lptr, dlen;
 
   /* filter out the other networks */
   if (buf[0] != 0x40)
@@ -251,18 +263,66 @@ pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
     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;
+  memcpy(out, buf, ol = 10);
+  l = (buf[8] & 0x0f) << 8 | buf[9];
+  buf += 10;
+  len -= 10;
+
+  if (pm->m_config.u.pass.m_rewrite_sid > 0) {
+    out[3] = 0;
+    out[4] = 1;
+  }
+
+  while (l > 1 && len > 1) {
+    dtag = buf[0];
+    dlen = buf[1];
+    if (dtag == DVB_DESC_PRIVATE_DATA) {
+      if (sizeof(out) - 32 < ol) {
+        tvherror(LS_PASS, "NIT entry too long (%i)", ol);
+        return;
+      }
+      memcpy(out, buf, dlen + 2);
+      ol += dlen + 2;
+    }
+    dlen += 2;
+    buf += dlen;
+    len -= dlen;
+      l -= dlen;
+  }
+  out[8] &= 0xf0;
+  out[8] |= ((ol - 10) >> 8) & 0x0f;
+  out[9] = ol - 10;
 
-  if (sizeof(out) < ol) {
+  if (sizeof(out) - 32 < ol) {
     tvherror(LS_PASS, "NIT entry too long (%i)", ol);
     return;
   }
 
-  memcpy(out, buf, ol);
+  /* mux info length */
+  lptr = ol;
+  out[ol++] = 0xf0;
+  out[ol++] = 0x00;
+
+  /* mux info */
+  out[ol++] = pm->pm_dst_tsid >> 8;
+  out[ol++] = pm->pm_dst_tsid;
+  out[ol++] = pm->pm_dst_onid >> 8;
+  out[ol++] = pm->pm_dst_onid;
+  /* mux tags */
+  out[ol++] = 0xf0;
+  out[ol++] = 5;
+  out[ol++] = DVB_DESC_SERVICE_LIST;
+  out[ol++] = 3;
+  out[ol++] = pm->pm_dst_sid >> 8;
+  out[ol++] = pm->pm_dst_sid;
+  out[ol++] = 0x11;
+  out[lptr] = (ol - lptr - 2) >> 8;
+  out[lptr+1] = ol - lptr - 2;
+
+  /* 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));
 
@@ -297,7 +357,7 @@ pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
   sbuf = malloc(len + 4);
   memcpy(sbuf, buf, len);
   sbuf[3] = pm->pm_dst_sid >> 8;
-  sbuf[4] = pm->pm_dst_sid & 0xff;
+  sbuf[4] = pm->pm_dst_sid;
 
   len = dvb_table_append_crc32(sbuf, len, len + 4);
   if (len > 0 && (olen = dvb_table_remux(mt, sbuf, len, &out)) > 0) {
@@ -365,10 +425,17 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss)
   int i;
 
   pm->pm_src_sid     = ss->ss_service_id;
-  if (pm->m_config.u.pass.m_rewrite_sid > 0)
+  pm->pm_src_tsid    = ss->ss_si.si_tsid;
+  pm->pm_src_onid    = ss->ss_si.si_onid;
+  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_dst_tsid  = 1;
+    pm->pm_dst_onid  = 1;
+  } else {
+    pm->pm_dst_sid   = pm->pm_src_sid;
+    pm->pm_dst_tsid  = pm->pm_src_tsid;
+    pm->pm_dst_onid  = pm->pm_src_onid;
+  }
   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;
index 286bbd48c9e469176b3b9ed4d9d434be5142505d..b3999d7c18011342ee7fb319eb32a9873a989ac9 100644 (file)
@@ -974,6 +974,18 @@ service_set_streaming_status_flags_(service_t *t, int set)
   service_send_streaming_status(t);
 }
 
+/**
+ *
+ */
+streaming_start_t *
+service_build_streaming_start(service_t *t)
+{
+  streaming_start_t *ss;
+  ss = elementary_stream_build_start(&t->s_components);
+  t->s_setsourceinfo(t, &ss->ss_si);
+  return ss;
+}
+
 /**
  * Restart output on a service (streams only).
  * Happens if the stream composition changes.
@@ -994,8 +1006,7 @@ service_restart_streams(service_t *t)
       sm = streaming_msg_create_code(SMT_STOP, SM_CODE_SOURCE_RECONFIGURED);
       streaming_service_deliver(t, sm);
     }
-    ss = elementary_stream_build_start(&t->s_components);
-    t->s_setsourceinfo(t, &ss->ss_si);
+    ss = service_build_streaming_start(t);
     sm = streaming_msg_create_data(SMT_START, ss);
     streaming_pad_deliver(&t->s_streaming_pad, sm);
     t->s_running = 1;
index 925abf0b285d3017bc1c20eb9931742244c6e2b1..d5f439194f6151ca413ac76da183e126e4379002 100644 (file)
@@ -469,6 +469,8 @@ service_reset_streaming_status_flags(service_t *t, int flag)
     service_set_streaming_status_flags_(t, n & ~flag);
 }
 
+streaming_start_t *service_build_streaming_start(service_t *t);
+
 void service_restart(service_t *t);
 
 void service_restart_streams(service_t *t);
index 3c66304abf219965ecfc6c3c9bd83a5518c5dbf7..64a0e8fab93929f5c4f63c59679c8ac44553a91b 100644 (file)
@@ -382,6 +382,8 @@ struct source_info {
   char *si_provider;
   char *si_service;
   int   si_type;
+  uint16_t si_tsid;
+  uint16_t si_onid;
 };
 
 /**
index 607d9d300f48fb5c33156eac53ea6f0ccc1e1e9b..b5af604d5467f51b2b49c532d43458d055e3c5fc 100644 (file)
@@ -107,8 +107,7 @@ subscription_link_service(th_subscription_t *s, service_t *t)
 
   if(elementary_set_has_streams(&t->s_components, 1) || t->s_type != STYPE_STD) {
     streaming_msg_free(s->ths_start_message);
-    ss = elementary_stream_build_start(&t->s_components);
-    t->s_setsourceinfo(t, &ss->ss_si);
+    ss = service_build_streaming_start(t);
     s->ths_start_message = streaming_msg_create_data(SMT_START, ss);
   }