diff --git a/Makefile b/Makefile index 83a314a5..79cfc911 100644 --- a/Makefile +++ b/Makefile @@ -173,8 +173,7 @@ SRCS-${CONFIG_LINUXDVB} += \ src/input/mpegts/linuxdvb/linuxdvb_frontend.c \ src/input/mpegts/linuxdvb/linuxdvb_network.c \ src/input/mpegts/linuxdvb/linuxdvb_mux.c \ - -# src/input/mpegts/linuxdvb/linuxdvb_service.c \ + src/input/mpegts/linuxdvb/linuxdvb_service.c \ # IPTV SRCS-${CONFIG_IPTV} += \ diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index b506f5d2..39b6327c 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -33,8 +33,7 @@ #include static int -psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, - int delete); +psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len); /* ************************************************************************** * Descriptors @@ -313,16 +312,6 @@ dvb_desc_service return 0; } -static int -dvb_desc_def_authority - ( const uint8_t *ptr, int len, - char *sauth, size_t sauth_len ) -{ - if (dvb_get_string_with_len(sauth, sauth_len, ptr, len, NULL, NULL) < 0) - return -1; - return 0; -} - static int dvb_desc_service_list ( const char *dstr, const uint8_t *ptr, int len, mpegts_mux_t *mm ) @@ -507,28 +496,25 @@ dvb_pmt_callback (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) { int sect, last, ver; + uint16_t sid; mpegts_mux_t *mm = mt->mt_mux; mpegts_service_t *s; /* Start */ - if (dvb_table_begin(mt, ptr, len, tableid, 5, §, &last, &ver)) + if (dvb_table_begin(mt, ptr, len, tableid, 9, §, &last, &ver)) return -1; - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) { - pthread_mutex_lock(&s->s_stream_mutex); - psi_parse_pmt(s, ptr, len, 1, 1); -#if TODO_FIXME - if (s->s_pmt_pid == mt->mt_pid && t->s_status == SERVICE_RUNNING) - active = 1; -#endif - pthread_mutex_unlock(&s->s_stream_mutex); - } - mpegts_table_destroy(mt); -#if TODO_FIXME - if (dm->dm_dn->dn_disable_pmt_monitor && !active) - dvb_tdt_destroy(dm->dm_current_tdmi->tdmi_adapter, - dm->dm_current_tdmi, tdt); -#endif + /* Find service */ + sid = ptr[0] << 8 | ptr[1]; + LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + if (s->s_dvb_service_id == sid) break; + if (!s) return -1; + + /* Process */ + tvhtrace("pmt", "sid %04X (%d)", sid, sid); + pthread_mutex_lock(&s->s_stream_mutex); + psi_parse_pmt(s, ptr, len); + pthread_mutex_unlock(&s->s_stream_mutex); /* Finish */ dvb_table_end(mt, tableid, sect, last, ver); @@ -635,7 +621,7 @@ dvb_nit_callback /* Both */ case DVB_DESC_DEF_AUTHORITY: - if (dvb_desc_def_authority(dptr, dlen, dauth, sizeof(dauth))) + if (dvb_get_string(dauth, sizeof(dauth), dptr, dlen, NULL, NULL)) return -1; tvhtrace(mt->mt_name, " default auth [%s]", dauth); if (mux && *dauth) @@ -714,8 +700,7 @@ dvb_sdt_callback DVB_LOOP_INIT(ptr, len, 3, lptr, llen); /* Find service */ - if (!(s = mm->mm_network->mn_create_service(mm, service_id, 0))) - continue; + s = mpegts_service_find(mm, service_id, 0, 1, &save); /* Descriptor loop */ DVB_DESC_EACH(lptr, llen, dtag, dlen, dptr) { @@ -727,7 +712,7 @@ dvb_sdt_callback return -1; break; case DVB_DESC_DEF_AUTHORITY: - if (dvb_desc_def_authority(dptr, dlen, sauth, sizeof(sauth))) + if (dvb_get_string(sauth, sizeof(sauth), dptr, dlen, NULL, NULL)) return -1; break; } @@ -735,6 +720,7 @@ dvb_sdt_callback tvhtrace("sdt", " type %d name [%s] provider [%s] def_auth [%s]", stype, sname, sprov, sauth); + if (!s) continue; /* Update service type */ if (stype && s->s_dvb_servicetype != stype) { @@ -976,14 +962,13 @@ psi_desc_teletext(mpegts_service_t *t, const uint8_t *ptr, int size, * PMT parser, from ISO 13818-1 and ETSI EN 300 468 */ int -psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, - int delete) +psi_parse_pmt + (mpegts_service_t *t, const uint8_t *ptr, int len) { uint16_t pcr_pid, pid; uint8_t estype; int dllen; uint8_t dtag, dlen; - uint16_t sid; streaming_component_type_t hts_stream_type; elementary_stream_t *st, *next; int update = 0; @@ -997,22 +982,14 @@ psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, caid_t *c, *cn; - if(len < 9) - return -1; - lock_assert(&t->s_stream_mutex); had_components = !!TAILQ_FIRST(&t->s_components); - sid = ptr[0] << 8 | ptr[1]; version = ptr[2] >> 1 & 0x1f; - pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6]; dllen = (ptr[7] & 0xf) << 8 | ptr[8]; - if(chksvcid && sid != t->s_dvb_service_id) - return -1; - if(t->s_pcr_pid != pcr_pid) { t->s_pcr_pid = pcr_pid; update |= PMT_UPDATE_PCR; @@ -1022,17 +999,14 @@ psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, len -= 9; /* Mark all streams for deletion */ - if(delete) { - TAILQ_FOREACH(st, &t->s_components, es_link) { + TAILQ_FOREACH(st, &t->s_components, es_link) { + if(st->es_type == SCT_PMT) + continue; - if(st->es_type == SCT_PMT) - continue; + st->es_delete_me = 1; - st->es_delete_me = 1; - - LIST_FOREACH(c, &st->es_caids, link) + LIST_FOREACH(c, &st->es_caids, link) c->delete_me = 1; - } } // Common descriptors @@ -1055,12 +1029,11 @@ psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, len -= dlen; ptr += dlen; dllen -= dlen; } - - while(len >= 5) { estype = ptr[0]; pid = (ptr[1] & 0x1f) << 8 | ptr[2]; dllen = (ptr[3] & 0xf) << 8 | ptr[4]; + tvhtrace("pmt", " pid %04X estype %d", pid, estype); ptr += 5; len -= 5; @@ -1174,6 +1147,14 @@ psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, st->es_delete_me = 0; + tvhtrace("pmt", " type %s position %d", streaming_component_type2txt(st->es_type), position); + if (lang) + tvhtrace("pmt", " language %s", lang); + if (composition_id != -1) + tvhtrace("pmt", " composition_id %d", composition_id); + if (ancillary_id != -1) + tvhtrace("pmt", " ancillary_id %d", ancillary_id); + if(st->es_position != position) { update |= PMT_REORDERED; st->es_position = position; @@ -1237,6 +1218,10 @@ psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, update&PMT_UPDATE_PARENT_PID ? ", Parent PID changed":"", update&PMT_UPDATE_CAID_DELETED ? ", CAID deleted":"", update&PMT_REORDERED ? ", PIDs reordered":""); + int c = 0; + TAILQ_FOREACH(st, &t->s_components, es_link) + c++; + tvhtrace("pmt", "number of streams %d", c); service_request_save((service_t*)t, 0); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_mux.c b/src/input/mpegts/linuxdvb/linuxdvb_mux.c index 14f55e3a..9315aa42 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_mux.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_mux.c @@ -220,7 +220,7 @@ linuxdvb_mux_create1 HTSMSG_FOREACH(f, c) { if (!(e = htsmsg_get_map_by_field(f))) continue; if (!(e = htsmsg_get_map(e, "config"))) continue; - //(void)linuxdvb_service_create0(lm, f->hmf_name, e); + (void)linuxdvb_service_create0(lm, 0, 0, f->hmf_name, e); } htsmsg_destroy(c); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_network.c b/src/input/mpegts/linuxdvb/linuxdvb_network.c index ab783a8c..d094bff4 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_network.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_network.c @@ -98,29 +98,11 @@ linuxdvb_network_create_mux return mm; } -static void -linuxdvb_service_config_save ( service_t *t ) -{ - htsmsg_t *c = htsmsg_create_map(); - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_service_save(s, c); - hts_settings_save(c, "input/linuxdvb/networks/%s/muxes/%s/services/%s", - idnode_uuid_as_str(&s->s_dvb_mux->mm_network->mn_id), - idnode_uuid_as_str(&s->s_dvb_mux->mm_id), - idnode_uuid_as_str(&s->s_id)); - htsmsg_destroy(c); -} - static mpegts_service_t * linuxdvb_network_create_service ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) { - extern const idclass_t mpegts_service_class; - mpegts_service_t *s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); - if (s) - s->s_config_save = linuxdvb_service_config_save; - // TODO: do we need any DVB specific fields? - return s; + return linuxdvb_service_create0((linuxdvb_mux_t*)mm, sid, pmt_pid, NULL, NULL); } static linuxdvb_network_t * diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 33c9ee09..2744d338 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -189,4 +189,11 @@ linuxdvb_mux_t *linuxdvb_mux_create0 linuxdvb_mux_t *linuxdvb_mux_create1 (linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf); +/* + * Service + */ +mpegts_service_t *linuxdvb_service_create0 + (linuxdvb_mux_t *lm, uint16_t sid, uint16_t pmt_pid, + const char *uuid, htsmsg_t *conf); + #endif /* __TVH_LINUXDVB_PRIVATE_H__ */ diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index f076bebd..617235a1 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -225,10 +225,12 @@ mpegts_service_create0 ( mpegts_service_t *s, const idclass_t *class, const char *uuid, mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, htsmsg_t *conf ) { + char buf[256]; service_create0((service_t*)s, class, uuid, S_MPEG_TS, conf); /* Create */ - tvhlog(LOG_DEBUG, "mpegts", "Add service %04X on %s", sid, "TODO"); + mm->mm_display_name(mm, buf, sizeof(buf)); + tvhlog(LOG_DEBUG, "mpegts", "%s - add service %04X", buf, sid); sbuf_init(&s->s_tsbuf); @@ -294,7 +296,5 @@ mpegts_service_find void mpegts_service_save ( mpegts_service_t *s, htsmsg_t *c ) { - pthread_mutex_lock(&s->s_stream_mutex); service_save((service_t*)s, c); - pthread_mutex_unlock(&s->s_stream_mutex); } diff --git a/src/service.c b/src/service.c index 5bbf55e2..509842e8 100644 --- a/src/service.c +++ b/src/service.c @@ -1281,7 +1281,7 @@ void service_save ( service_t *t, htsmsg_t *m ) htsmsg_add_u32(m, "pcr", t->s_pcr_pid); - lock_assert(&t->s_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); list = htsmsg_create_list(); TAILQ_FOREACH(st, &t->s_components, es_link) { @@ -1333,6 +1333,7 @@ void service_save ( service_t *t, htsmsg_t *m ) htsmsg_add_msg(list, NULL, sub); } + pthread_mutex_unlock(&t->s_stream_mutex); htsmsg_add_msg(m, "stream", list); }