From 7e9b78aa2438983f98cc4dae97860b290358e393 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sat, 27 Apr 2013 23:32:44 +0100 Subject: [PATCH] mpegts: Now creates services from tsfile input Another baby step, PAT is processed to add PMT listeners and PMT will result in the creation of services. Although atm I think this does not properly handle things as it won't necessarily create the correct service type as its created from the generic code with no creation callback. --- src/input/mpegts.h | 13 +++-- src/input/mpegts/mpegts_mux.c | 18 +++++++ src/input/mpegts/mpegts_service.c | 86 ++++++++++++++++++++++++++++--- src/input/mpegts/psi.c | 17 +++--- src/service.c | 10 ++-- src/service.h | 8 +-- 6 files changed, 123 insertions(+), 29 deletions(-) diff --git a/src/input/mpegts.h b/src/input/mpegts.h index c410710b..4e49ad10 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -171,7 +171,7 @@ struct mpegts_mux * Services */ - struct service_list mm_services; + LIST_HEAD(,mpegts_service) mm_services; /* * Scanning @@ -271,8 +271,9 @@ struct mpegts_service * Link to carrying multiplex and active adapter */ - mpegts_mux_t *s_dvb_mux; - mpegts_input_t *s_dvb_active_input; + LIST_ENTRY(mpegts_service) s_dvb_mux_link; + mpegts_mux_t *s_dvb_mux; + mpegts_input_t *s_dvb_active_input; /* * Streaming elements @@ -406,6 +407,10 @@ mpegts_mux_instance_t *mpegts_mux_instance_create0 void mpegts_mux_initial_scan_done ( mpegts_mux_t *mm ); +void mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force ); + +void mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid, int force ); + size_t mpegts_input_recv_packets (mpegts_input_t *mi, mpegts_mux_instance_t *mmi, uint8_t *tsb, size_t len, int64_t *pcr, uint16_t *pcr_pid); @@ -428,6 +433,8 @@ void mpegts_table_flush_all (mpegts_mux_t *mm); void mpegts_table_destroy ( mpegts_table_t *mt ); +mpegts_service_t *mpegts_service_find ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, const char *uuid, int *save ); + /****************************************************************************** * Editor Configuration diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index a5d3a4bd..f1c170d3 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -58,6 +58,24 @@ const idclass_t mpegts_mux_class = } }; +void mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid, int force ) +{ + if (onid == mm->mm_onid) + return; + if (!force && mm->mm_onid != MM_ONID_NONE) + return; + mm->mm_onid = onid; +} + +void mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force ) +{ + if (tsid == mm->mm_tsid) + return; + if (!force && mm->mm_tsid != MM_ONID_NONE) + return; + mm->mm_tsid = tsid; +} + static void mpegts_mux_initial_scan_link ( mpegts_mux_t *mm ) { diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 18c0c9c9..385b5484 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -22,18 +22,37 @@ #include "service.h" #include "input/mpegts.h" -int mpegts_service_enabled (service_t *); -void mpegts_service_enlist (service_t *, struct service_instance_list*); -int mpegts_service_start (service_t *, int); -void mpegts_service_stop (service_t *); -void mpegts_service_refresh (service_t *); +const idclass_t mpegts_service_class = +{ + .ic_class = "mpegts_service", + .ic_caption = "MPEGTS Service", + .ic_properties = (const property_t[]){ + } +}; + +// TODO: why not static? +int mpegts_service_is_enabled (service_t *); +void mpegts_service_enlist (service_t *, struct service_instance_list*); +int mpegts_service_start (service_t *, int); +void mpegts_service_stop (service_t *); +void mpegts_service_refresh (service_t *); void mpegts_service_setsourceinfo (service_t *, source_info_t *); +void mpegts_service_config_save (service_t *); + +/* + * Save + */ +void +mpegts_service_config_save ( service_t *t ) +{ + //TODO +} /* * Check the service is enabled */ int -mpegts_service_enabled(service_t *t) +mpegts_service_is_enabled(service_t *t) { mpegts_service_t *s = (mpegts_service_t*)t; #if 0 @@ -183,3 +202,58 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si) if(s->s_dvb_svcname != NULL) si->si_service = strdup(s->s_dvb_svcname); } + +/* + * Find service + */ +mpegts_service_t * +mpegts_service_find + ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, const char *uuid, int *save ) +{ + mpegts_service_t *s; + + /* Validate */ + lock_assert(&global_lock); + + /* Find existing service */ + LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + if (s->s_dvb_service_id == sid) { + if (pmt_pid && pmt_pid != s->s_pmt_pid) { + s->s_pmt_pid = pmt_pid; + if (save) *save = 1; + } + return s; + } + + /* Ignore */ + if (!pmt_pid) + return NULL; + + /* Create */ + tvhlog(LOG_DEBUG, "mpegts", "Add service %04X on %s", sid, "TODO"); + s = service_create(mpegts_service, uuid, S_MPEG_TS); + + sbuf_init(&s->s_tsbuf); + + s->s_dvb_service_id = sid; + s->s_pmt_pid = pmt_pid; + s->s_dvb_mux = mm; + LIST_INSERT_HEAD(&mm->mm_services, s, s_dvb_mux_link); + + s->s_is_enabled = mpegts_service_is_enabled; + s->s_enlist = mpegts_service_enlist; + s->s_start_feed = mpegts_service_start; + s->s_stop_feed = mpegts_service_stop; + s->s_refresh_feed = mpegts_service_refresh; + s->s_setsourceinfo = mpegts_service_setsourceinfo; + s->s_config_save = mpegts_service_config_save; +#if 0 + s->s_grace_period = mpegts_service_grace_period; +#endif + + pthread_mutex_lock(&s->s_stream_mutex); + // TODO: nice name + pthread_mutex_unlock(&s->s_stream_mutex); + + return s; +} diff --git a/src/input/mpegts/psi.c b/src/input/mpegts/psi.c index 3a1153b1..0aaa257b 100644 --- a/src/input/mpegts/psi.c +++ b/src/input/mpegts/psi.c @@ -57,11 +57,9 @@ psi_pat_callback /* Multiplex */ tsid = (ptr[0] << 8) | ptr[1]; tvhtrace("pat", "tsid %04X (%d)", tsid, tsid); -#if 0 // TODO: process this mpegts_mux_set_tsid(mm, tsid, 0); if (mm->mm_tsid != tsid) return -1; -#endif /* Process each programme */ ptr += 5; @@ -81,13 +79,11 @@ psi_pat_callback /* Service */ } else if (pid) { - tvhtrace("pat", "SID %04X (%d) on PID %04X (%d)", sid, sid, pid, pid); -#if 0 int save = 0; + tvhtrace("pat", "SID %04X (%d) on PID %04X (%d)", sid, sid, pid, pid); mpegts_service_find(mm, sid, pid, NULL, &save); // TODO: option to disable PMT monitor - if (save) -#endif + //if (save) psi_table_add_pmt(mm, pid); } @@ -107,19 +103,18 @@ psi_pmt_callback (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) { mpegts_mux_t *mm = mt->mt_mux; - service_t *t; + mpegts_service_t *s; tvhtrace("pmt", "tableid %d len %d", tableid, len); tvhlog_hexdump("pmt", ptr, len); - LIST_FOREACH(t, &mm->mm_services, s_group_link) { - mpegts_service_t *s = (mpegts_service_t*)t; - pthread_mutex_lock(&t->s_stream_mutex); + 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 0 if (s->s_pmt_pid == mt->mt_pid && t->s_status == SERVICE_RUNNING) active = 1; #endif - pthread_mutex_unlock(&t->s_stream_mutex); + pthread_mutex_unlock(&s->s_stream_mutex); } mpegts_table_destroy(mt); #if 0 diff --git a/src/service.c b/src/service.c index 28c0ac85..02529952 100644 --- a/src/service.c +++ b/src/service.c @@ -440,7 +440,9 @@ service_destroy(service_t *t) LIST_REMOVE(t, s_ch_link); } +#ifdef TODO_MOVE_TO_MPEGTS LIST_REMOVE(t, s_group_link); +#endif idnode_unlink(&t->s_id); @@ -479,9 +481,9 @@ service_destroy(service_t *t) * Create and initialize a new service struct */ service_t * -service_create(const char *uuid, int source_type, const idclass_t *idc) +service_create0(size_t alloc, const char *uuid, const idclass_t *idc, int source_type) { - service_t *t = calloc(1, sizeof(service_t)); + service_t *t = calloc(1, alloc); lock_assert(&global_lock); @@ -492,10 +494,6 @@ service_create(const char *uuid, int source_type, const idclass_t *idc) t->s_enabled = 1; #ifdef MOVE_TO_TODO t->s_pcr_last = PTS_UNSET; -#endif -#ifdef MOVE_TO_MPEGTS - t->s_dvb_charset = NULL; - t->s_dvb_eit_enable = 1; #endif TAILQ_INIT(&t->s_components); diff --git a/src/service.h b/src/service.h index f4371fca..a7e3e657 100644 --- a/src/service.h +++ b/src/service.h @@ -244,8 +244,6 @@ typedef struct service { int64_t s_pcr_last_realtime; #endif - LIST_ENTRY(service) s_group_link; - LIST_ENTRY(service) s_active_link; LIST_HEAD(, th_subscription) s_subscriptions; @@ -435,7 +433,11 @@ void service_init(void); int service_start(service_t *t, int instance); -service_t *service_create(const char *uuid, int source_type, const idclass_t *idc); +service_t *service_create0(size_t alloc, const char *uuid, const idclass_t *idc, int source_type); + +#define service_create(t, u, s)\ + (struct t*)service_create0(sizeof(struct t), u, &t##_class, s) + void service_unref(service_t *t);