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:
parent
f8c00d3c2a
commit
7e9b78aa24
6 changed files with 123 additions and 29 deletions
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue