From 55d5cc5aeabcd01672346ad546f7dab46ee4cd2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Mon, 22 Jun 2009 19:51:10 +0000 Subject: [PATCH] Figure out if we need to re-save a transport configuration instead of relying on ''if we've seen it once, it can not change'' --- src/dvb/dvb_adapter.c | 6 ++-- src/psi.c | 75 +++++++++++++++++++++++++++++++------------ src/rawtsinput.c | 9 ++++-- src/transports.c | 33 +++++++++++++++---- src/transports.h | 6 ++-- src/tvhead.h | 8 +---- 6 files changed, 95 insertions(+), 42 deletions(-) diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index b8440fd5..ea45e4bf 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -371,9 +371,9 @@ dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src) LIST_FOREACH(st_src, &t_src->tht_components, st_link) { - st_dst = transport_add_stream(t_dst, - st_src->st_pid, - st_src->st_type); + st_dst = transport_stream_create(t_dst, + st_src->st_pid, + st_src->st_type); st_dst->st_tb = (AVRational){1, 90000}; diff --git a/src/psi.c b/src/psi.c index c6d9066a..9f9ed21b 100644 --- a/src/psi.c +++ b/src/psi.c @@ -92,10 +92,11 @@ psi_parse_pat(th_transport_t *t, uint8_t *ptr, int len, pid = (ptr[2] & 0x1f) << 8 | ptr[3]; if(prognum != 0) { - st = transport_add_stream(t, pid, SCT_PMT); - st->st_section_docrc = 1; - st->st_got_section = pmt_callback; - + if(transport_stream_find(t, pid) == NULL) { + st = transport_stream_create(t, pid, SCT_PMT); + st->st_section_docrc = 1; + st->st_got_section = pmt_callback; + } } ptr += 4; len -= 4; @@ -164,11 +165,32 @@ psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid) +/** + * Parser for CA descriptor + */ +static int +psi_desc_ca(th_transport_t *t, uint8_t *ptr) +{ + uint16_t pid = (ptr[2] & 0x1f) << 8 | ptr[3]; + th_stream_t *st; + int r = 0; + uint16_t caid = (ptr[0] << 8) | ptr[1]; + + if((st = transport_stream_find(t, pid)) == NULL) { + st = transport_stream_create(t, pid, SCT_CA); + r = 1; + } + + if(st->st_caid != caid) { + st->st_caid = caid; + r = 1; + } + return r; +} /** * PMT parser, from ISO 13818-1 and ETSI EN 300 468 */ - int psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid) { @@ -181,6 +203,8 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid) th_stream_t *st; char lang[4]; int frameduration; + int need_save = 0; + if(len < 9) return -1; @@ -190,14 +214,17 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid) pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6]; dllen = (ptr[7] & 0xf) << 8 | ptr[8]; - t->tht_pcr_pid = pcr_pid; + if(chksvcid && sid != t->tht_dvb_service_id) + return -1; + + if(t->tht_pcr_pid != pcr_pid) { + t->tht_pcr_pid = pcr_pid; + need_save = 1; + } ptr += 9; len -= 9; - if(chksvcid && sid != t->tht_dvb_service_id) - return -1; - while(dllen > 1) { dtag = ptr[0]; dlen = ptr[1]; @@ -208,8 +235,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid) switch(dtag) { case DVB_DESC_CA: - st = transport_add_stream(t, (ptr[2] & 0x1f) << 8 | ptr[3], SCT_CA); - st->st_caid = (ptr[0] << 8) | ptr[1]; + need_save |= psi_desc_ca(t, ptr); break; default: @@ -262,8 +288,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid) switch(dtag) { case DVB_DESC_CA: - st = transport_add_stream(t, (ptr[2] & 0x1f) << 8 | ptr[3], SCT_CA); - st->st_caid = (ptr[0] << 8) | ptr[1]; + need_save |= psi_desc_ca(t, ptr); break; case DVB_DESC_VIDEO_STREAM: @@ -296,19 +321,29 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid) } if(hts_stream_type != 0) { - st = transport_add_stream(t, pid, hts_stream_type); - st->st_tb = (AVRational){1, 90000}; - memcpy(st->st_lang, lang, 4); - if(st->st_frame_duration == 0) + if((st = transport_stream_find(t, pid)) == NULL) { + need_save = 1; + st = transport_stream_create(t, pid, hts_stream_type); + } + + st->st_tb = (AVRational){1, 90000}; + + if(memcmp(st->st_lang, lang, 4)) { + need_save = 1; + memcpy(st->st_lang, lang, 4); + } + + if(st->st_frame_duration == 0 && frameduration != 0) { st->st_frame_duration = frameduration; + need_save = 1; + } } } - if(t->tht_pmt_seen == 0) + if(need_save) t->tht_config_change(t); - t->tht_pmt_seen = 1; return 0; } @@ -635,7 +670,7 @@ psi_load_transport_settings(htsmsg_t *m, th_transport_t *t) if(htsmsg_get_u32(c, "pid", &pid)) continue; - st = transport_add_stream(t, pid, type); + st = transport_stream_create(t, pid, type); st->st_tb = (AVRational){1, 90000}; if((v = htsmsg_get_str(c, "language")) != NULL) diff --git a/src/rawtsinput.c b/src/rawtsinput.c index ba99d4d7..f0029888 100644 --- a/src/rawtsinput.c +++ b/src/rawtsinput.c @@ -195,9 +195,12 @@ got_pat(rawts_t *rt) if(t != NULL) { pthread_mutex_lock(&t->tht_stream_mutex); - st = transport_add_stream(t, pid, SCT_PMT); - st->st_section_docrc = 1; - st->st_got_section = got_pmt; + + if(transport_stream_find(t, pid) == NULL) { + st = transport_stream_create(t, pid, SCT_PMT); + st->st_section_docrc = 1; + st->st_got_section = got_pmt; + } pthread_mutex_unlock(&t->tht_stream_mutex); } } diff --git a/src/transports.c b/src/transports.c index 688187f6..853379bf 100644 --- a/src/transports.c +++ b/src/transports.c @@ -471,16 +471,14 @@ transport_find_by_identifier(const char *identifier) /** * Add a new stream to a transport - * - * */ th_stream_t * -transport_add_stream(th_transport_t *t, int pid, - streaming_component_type_t type) +transport_stream_create(th_transport_t *t, int pid, + streaming_component_type_t type) { th_stream_t *st; int i = 0; - + lock_assert(&t->tht_stream_mutex); LIST_FOREACH(st, &t->tht_components, st_link) { @@ -490,8 +488,8 @@ transport_add_stream(th_transport_t *t, int pid, } if(t->tht_flags & THT_DEBUG) - tvhlog(LOG_DEBUG, "transport", "%s: Add stream \"%s\", pid: %d", - t->tht_identifier, streaming_component_type2txt(type), pid); + tvhlog(LOG_DEBUG, "transport", "%s: Add stream \"%s\", pid: %d", + t->tht_identifier, streaming_component_type2txt(type), pid); st = calloc(1, sizeof(th_stream_t)); st->st_index = i; @@ -506,10 +504,31 @@ transport_add_stream(th_transport_t *t, int pid, avgstat_init(&st->st_rate, 10); avgstat_init(&st->st_cc_errors, 10); + return st; } + +/** + * Add a new stream to a transport + */ +th_stream_t * +transport_stream_find(th_transport_t *t, int pid) +{ + th_stream_t *st; + + lock_assert(&t->tht_stream_mutex); + + LIST_FOREACH(st, &t->tht_components, st_link) { + if(st->st_pid == pid) + return st; + } + return NULL; +} + + + /** * */ diff --git a/src/transports.h b/src/transports.h index efac9ecb..1a9d63f5 100644 --- a/src/transports.h +++ b/src/transports.h @@ -42,8 +42,10 @@ void transport_unmap_channel(th_transport_t *t); th_transport_t *transport_find(channel_t *ch, unsigned int weight); -th_stream_t *transport_add_stream(th_transport_t *t, int pid, - streaming_component_type_t type); +th_stream_t *transport_stream_find(th_transport_t *t, int pid); + +th_stream_t *transport_stream_create(th_transport_t *t, int pid, + streaming_component_type_t type); void transport_set_priority(th_transport_t *t, int prio); diff --git a/src/tvhead.h b/src/tvhead.h index 644da8fb..28f490a1 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -578,14 +578,8 @@ typedef struct th_transport { int64_t tht_pcr_drift; /** - * Set if we've seen the PMT. Used to avoid (re)saving the transport - * for everytime we see a PMT. - * XXX: Not very good, should be replaced with more intelligent - * code in psi.c + * List of all components. */ - int tht_pmt_seen; - - struct th_stream_list tht_components;