From d5a86bf8e93e27fd669bc4d6838f093aebea7533 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Thu, 30 May 2013 22:30:16 +0100 Subject: [PATCH] linuxdvb: started to add service saving (very rough) --- src/input/mpegts/dvb_psi.c | 14 ++-- src/input/mpegts/linuxdvb/linuxdvb_network.c | 21 +++++- src/input/mpegts/mpegts_service.c | 2 +- src/service.c | 72 ++++++++++++++++++-- src/service.h | 4 +- 5 files changed, 99 insertions(+), 14 deletions(-) diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index d7a3c464..f733d933 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -328,12 +328,17 @@ dvb_desc_service_list { uint16_t stype, sid; int i; + mpegts_service_t *s; for (i = 0; i < len; i += 3) { sid = (ptr[i] << 8) | ptr[i+1]; stype = ptr[i+2]; tvhtrace(dstr, " service %04X (%d) type %d", sid, sid, stype); - if (mm) - mm->mm_network->mn_create_service(mm, sid, 0); + if (mm) { + int save = 0; + s = mpegts_service_find(mm, sid, 0, NULL, &save); + if (save) + s->s_config_save((service_t*)s); + } } return 0; } @@ -1038,11 +1043,6 @@ psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len, int chksvcid, sid = ptr[0] << 8 | ptr[1]; version = ptr[2] >> 1 & 0x1f; - if((ptr[2] & 1) == 0) { - /* current_next_indicator == next, skip this */ - return -1; - } - pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6]; dllen = (ptr[7] & 0xf) << 8 | ptr[8]; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_network.c b/src/input/mpegts/linuxdvb/linuxdvb_network.c index 0c63487e..caaa55bd 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_network.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_network.c @@ -98,11 +98,30 @@ linuxdvb_network_create_mux return mm; } +static void +linuxdvb_service_config_save ( service_t *t ) +{ + mpegts_service_t *s = (mpegts_service_t*)t; + htsmsg_t *c = htsmsg_create_map(); + idnode_save(&s->s_id, c); + service_save(t, 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 ) { - return NULL; + extern const idclass_t mpegts_service_class; + mpegts_service_t *s = mpegts_service_create1(NULL, mm, sid, pmt_pid); + if (s) + s->s_config_save = linuxdvb_service_config_save; + // TODO: do we need any DVB specific fields? + return s; } static linuxdvb_network_t * diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index a4ccb8fd..5e9d92c8 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -214,7 +214,7 @@ mpegts_service_load_one const char *str; /* Load core */ - service_load_one((service_t*)ms, c); + service_load((service_t*)ms, c); /* Load local */ if (!htsmsg_get_u32(c, "pcr_pid", &u32)) diff --git a/src/service.c b/src/service.c index 514b679e..c340aa14 100644 --- a/src/service.c +++ b/src/service.c @@ -46,12 +46,12 @@ static void service_data_timeout(void *aux); static const char *service_channel_get(void *obj); static void service_channel_set(void *obj, const char *str); -static void service_save(struct idnode *self); +static void service_class_save(struct idnode *self); const idclass_t service_class = { .ic_class = "service", .ic_caption = "Service", - .ic_save = service_save, + .ic_save = service_class_save, .ic_properties = (const property_t[]){ { "channel", "Channel", PT_STR, @@ -975,7 +975,7 @@ service_request_save(service_t *t, int restart) * */ static void -service_save(struct idnode *self) +service_class_save(struct idnode *self) { service_t *s = (service_t *)self; s->s_config_save(s); @@ -1273,6 +1273,70 @@ htsmsg_t *servicetype_list ( void ) return ret; } -void service_load_one ( service_t *s, htsmsg_t *c ) +void service_save ( service_t *t, htsmsg_t *m ) +{ + elementary_stream_t *st; + htsmsg_t *list, *sub; + + htsmsg_add_u32(m, "pcr", t->s_pcr_pid); + + htsmsg_add_u32(m, "disabled", !t->s_enabled); + + lock_assert(&t->s_stream_mutex); + + list = htsmsg_create_list(); + TAILQ_FOREACH(st, &t->s_components, es_link) { + sub = htsmsg_create_map(); + + htsmsg_add_u32(sub, "pid", st->es_pid); + htsmsg_add_str(sub, "type", streaming_component_type2txt(st->es_type)); + htsmsg_add_u32(sub, "position", st->es_position); + + if(st->es_lang[0]) + htsmsg_add_str(sub, "language", st->es_lang); + +#if TODO // Where did this go? + if (SCT_ISAUDIO(st->es_type)) + htsmsg_add_u32(sub, "audio_type", st->es_audio_type); +#endif + + if(st->es_type == SCT_CA) { + caid_t *c; + htsmsg_t *v = htsmsg_create_list(); + LIST_FOREACH(c, &st->es_caids, link) { + htsmsg_t *caid = htsmsg_create_map(); + + htsmsg_add_u32(caid, "caid", c->caid); + if(c->providerid) + htsmsg_add_u32(caid, "providerid", c->providerid); + htsmsg_add_msg(v, NULL, caid); + } + + htsmsg_add_msg(sub, "caidlist", v); + } + + if(st->es_type == SCT_DVBSUB) { + htsmsg_add_u32(sub, "compositionid", st->es_composition_id); + htsmsg_add_u32(sub, "ancillartyid", st->es_ancillary_id); + } + + if(st->es_type == SCT_TEXTSUB) + htsmsg_add_u32(sub, "parentpid", st->es_parent_pid); + + if(st->es_type == SCT_MPEG2VIDEO || st->es_type == SCT_H264) { + if(st->es_width && st->es_height) { + htsmsg_add_u32(sub, "width", st->es_width); + htsmsg_add_u32(sub, "height", st->es_height); + } + if(st->es_frame_duration) + htsmsg_add_u32(sub, "duration", st->es_frame_duration); + } + + htsmsg_add_msg(list, NULL, sub); + } + htsmsg_add_msg(m, "stream", list); +} + +void service_load ( service_t *s, htsmsg_t *c ) { } diff --git a/src/service.h b/src/service.h index 36761789..012e82a0 100644 --- a/src/service.h +++ b/src/service.h @@ -513,6 +513,8 @@ int service_is_primary_epg (service_t *t); htsmsg_t *servicetype_list (void); -void service_load_one ( service_t *s, htsmsg_t *c ); +void service_load ( service_t *s, htsmsg_t *c ); + +void service_save ( service_t *s, htsmsg_t *c ); #endif // SERVICE_H__