From: Jaroslav Kysela Date: Fri, 20 Apr 2018 09:12:20 +0000 (+0200) Subject: pass muxer: add more rewrites, fix NIT rewrite, fix teletext subs, fixes #5062, fixes... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29140e435098df33676f857bd0f2584f4c98ee78;p=thirdparty%2Ftvheadend.git pass muxer: add more rewrites, fix NIT rewrite, fix teletext subs, fixes #5062, fixes #5075 --- diff --git a/src/esstream.h b/src/esstream.h index 31b0886cd..41b704d6c 100644 --- a/src/esstream.h +++ b/src/esstream.h @@ -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 */ diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 2112f3c54..afef1d58c 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -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; } /* diff --git a/src/muxer/muxer_pass.c b/src/muxer/muxer_pass.c index b3c96b211..628da6b31 100644 --- a/src/muxer/muxer_pass.c +++ b/src/muxer/muxer_pass.c @@ -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; diff --git a/src/service.c b/src/service.c index 286bbd48c..b3999d7c1 100644 --- a/src/service.c +++ b/src/service.c @@ -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; diff --git a/src/service.h b/src/service.h index 925abf0b2..d5f439194 100644 --- a/src/service.h +++ b/src/service.h @@ -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); diff --git a/src/streaming.h b/src/streaming.h index 3c66304ab..64a0e8fab 100644 --- a/src/streaming.h +++ b/src/streaming.h @@ -382,6 +382,8 @@ struct source_info { char *si_provider; char *si_service; int si_type; + uint16_t si_tsid; + uint16_t si_onid; }; /** diff --git a/src/subscriptions.c b/src/subscriptions.c index 607d9d300..b5af604d5 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -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); }