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.
This commit is contained in:
Adam Sutton 2013-04-27 23:32:44 +01:00
parent f8c00d3c2a
commit 7e9b78aa24
6 changed files with 123 additions and 29 deletions

View file

@ -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

View file

@ -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 )
{

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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);