mpegts linuxdvb: loads of tidying up of network/mux code

This commit is contained in:
Adam Sutton 2013-06-01 13:40:29 +01:00
parent 896345228c
commit 400e8c61ea
8 changed files with 327 additions and 220 deletions

View file

@ -411,10 +411,10 @@ mpegts_input_t *mpegts_input_create0
mpegts_network_t *mpegts_network_create0
( mpegts_network_t *mn, const idclass_t *idc, const char *uuid,
const char *name );
const char *name, htsmsg_t *conf );
#define mpegts_network_create(t, u, n)\
(struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n)
#define mpegts_network_create(t, u, n, c)\
(struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n, c)
void mpegts_network_schedule_initial_scan
( mpegts_network_t *mm );
@ -439,7 +439,7 @@ mpegts_mux_t *mpegts_mux_create0
void mpegts_mux_initial_scan_done ( mpegts_mux_t *mm );
void mpegts_mux_load_one ( mpegts_mux_t *mm, htsmsg_t *c );
void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c );
mpegts_mux_instance_t *mpegts_mux_instance_create0
( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid,

View file

@ -30,10 +30,12 @@
#include <dirent.h>
#include <fcntl.h>
/*
/* **************************************************************************
* Class definition
*/
* *************************************************************************/
extern const idclass_t mpegts_mux_class;
const idclass_t linuxdvb_mux_class =
{
.ic_super = &mpegts_mux_class,
@ -84,9 +86,9 @@ const idclass_t linuxdvb_mux_atsc_class =
}
};
/*
* Mux Objects
*/
/* **************************************************************************
* Class methods
* *************************************************************************/
static void
linuxdvb_mux_config_save ( mpegts_mux_t *mm )
@ -94,7 +96,7 @@ linuxdvb_mux_config_save ( mpegts_mux_t *mm )
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
htsmsg_t *c = htsmsg_create_map();
idnode_save(&mm->mm_id, c);
mpegts_mux_save(mm, c);
dvb_mux_conf_save(ln->ln_type, &lm->lm_tuning, c);
hts_settings_save(c, "input/linuxdvb/networks/%s/muxes/%s/config",
idnode_uuid_as_str(&mm->mm_network->mn_id),
@ -143,6 +145,10 @@ linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
}
#endif
/* **************************************************************************
* Creation/Config
* *************************************************************************/
linuxdvb_mux_t *
linuxdvb_mux_create0
( linuxdvb_network_t *ln,
@ -150,10 +156,12 @@ linuxdvb_mux_create0
const char *uuid, htsmsg_t *conf )
{
const idclass_t *idc;
const char *str;
mpegts_mux_t *mm;
linuxdvb_mux_t *lm;
/* Search for existing */
dvb_mux_conf_t dmc0;
htsmsg_t *c, *e;
htsmsg_field_t *f;
/* Class */
if (ln->ln_type == FE_QPSK)
@ -165,7 +173,20 @@ linuxdvb_mux_create0
else if (ln->ln_type == FE_ATSC)
idc = &linuxdvb_mux_atsc_class;
else {
tvhlog(LOG_ERR, "linuxdvb", "unknown FE type %d", ln->ln_type);
tvherror("linuxdvb", "unknown FE type %d", ln->ln_type);
return NULL;
}
/* Load mux config */
if (conf && !dmc) {
dmc = &dmc0;
if ((str = dvb_mux_conf_load(ln->ln_type, &dmc0, conf))) {
tvherror( "linuxdvb", "failed to load mux config [%s]", str);
return NULL;
}
}
if (!dmc) {
tvherror("linuxdvb", "no mux configuration provided");
return NULL;
}
@ -174,49 +195,23 @@ linuxdvb_mux_create0
(mpegts_network_t*)ln, onid, tsid, conf)))
return NULL;
lm = (linuxdvb_mux_t*)mm;
/* Tuning */
memcpy(&lm->lm_tuning, dmc, sizeof(dvb_mux_conf_t));
/* Callbacks */
lm->mm_display_name = linuxdvb_mux_display_name;
lm->mm_config_save = linuxdvb_mux_config_save;
lm->mm_create_instances = linuxdvb_mux_create_instances;
return (linuxdvb_mux_t*)mm;
}
linuxdvb_mux_t *
linuxdvb_mux_create1
( linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf )
{
const char *str;
htsmsg_t *c, *e;
htsmsg_field_t *f;
linuxdvb_mux_t *lm;
dvb_mux_conf_t dmc;
/* Check tuning */
memset(&dmc, 0, sizeof(dmc));
if (conf) {
if ((str = dvb_mux_conf_load(ln->ln_type, &dmc, conf))) {
tvhlog(LOG_ERR, "linuxdvb", "failed to load mux config [%s]", str);
return NULL;
}
}
lm = linuxdvb_mux_create0(ln, MPEGTS_ONID_NONE,
MPEGTS_TSID_NONE, &dmc, uuid, conf);
if (!lm) return NULL;
/* No config */
if (!conf)
return lm;
/* Config */
memcpy(&lm->lm_tuning, &dmc, sizeof(dmc));
if (!conf) return lm;
/* Services */
if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes/%s/services",
"TODO", uuid))) {
c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes/%s/services",
idnode_uuid_as_str(&ln->mn_id),
idnode_uuid_as_str(&mm->mm_id));
if (c) {
HTSMSG_FOREACH(f, c) {
if (!(e = htsmsg_get_map_by_field(f))) continue;
if (!(e = htsmsg_get_map(e, "config"))) continue;

View file

@ -30,16 +30,22 @@
#include <dirent.h>
#include <fcntl.h>
/* ****************************************************************************
* Class definition
* ***************************************************************************/
extern const idclass_t mpegts_network_class;
static const char *
ln_type_getstr ( void *ptr )
mpegts_network_class_get_lntype
( void * ptr )
{
return dvb_type2str(((linuxdvb_network_t*)ptr)->ln_type);
}
static void
ln_type_setstr ( void *ptr, const char *str )
static void
mpegts_network_class_set_lntype
( void *ptr, const char *str )
{
((linuxdvb_network_t*)ptr)->ln_type = dvb_str2type(str);
}
@ -52,21 +58,15 @@ const idclass_t linuxdvb_network_class =
.ic_properties = (const property_t[]){
{ PROPDEF2("type", "Network Type",
PT_STR, linuxdvb_network_t, ln_type, 1),
.str_get = ln_type_getstr,
.str_set = ln_type_setstr },
.str_get = mpegts_network_class_get_lntype,
.str_set = mpegts_network_class_set_lntype },
{}
}
};
static void
linuxdvb_network_config_save ( mpegts_network_t *mn )
{
htsmsg_t *c = htsmsg_create_map();
idnode_save(&mn->mn_id, c);
hts_settings_save(c, "input/linuxdvb/networks/%s/config",
idnode_uuid_as_str(&mn->mn_id));
htsmsg_destroy(c);
}
/* ****************************************************************************
* Class methods
* ***************************************************************************/
static mpegts_mux_t *
linuxdvb_network_find_mux
@ -84,10 +84,21 @@ linuxdvb_network_find_mux
return mm;
}
static void
linuxdvb_network_config_save ( mpegts_network_t *mn )
{
htsmsg_t *c = htsmsg_create_map();
idnode_save(&mn->mn_id, c);
hts_settings_save(c, "input/linuxdvb/networks/%s/config",
idnode_uuid_as_str(&mn->mn_id));
htsmsg_destroy(c);
}
static mpegts_mux_t *
linuxdvb_network_create_mux
( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid, dvb_mux_conf_t *dmc )
{
// TODO: should we have a mux_find wrapper?
linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
mm = linuxdvb_network_find_mux(ln, dmc);
if (!mm) {
@ -102,9 +113,14 @@ static mpegts_service_t *
linuxdvb_network_create_service
( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid )
{
return linuxdvb_service_create0((linuxdvb_mux_t*)mm, sid, pmt_pid, NULL, NULL);
return linuxdvb_service_create0((linuxdvb_mux_t*)mm, sid,
pmt_pid, NULL, NULL);
}
/* ****************************************************************************
* Creation/Config
* ***************************************************************************/
static linuxdvb_network_t *
linuxdvb_network_create0
( const char *uuid, htsmsg_t *conf )
@ -114,7 +130,7 @@ linuxdvb_network_create0
htsmsg_field_t *f;
/* Create */
if (!(ln = mpegts_network_create(linuxdvb_network, uuid, NULL)))
if (!(ln = mpegts_network_create(linuxdvb_network, uuid, NULL, conf)))
return NULL;
/* Callbacks */
@ -126,9 +142,6 @@ linuxdvb_network_create0
if (!conf)
return ln;
/* Load configuration */
idnode_load(&ln->mn_id, conf);
/* Load muxes */
if ((c = hts_settings_load_r(1, "input/linuxdvb/networks/%s/muxes", uuid))) {
HTSMSG_FOREACH(f, c) {
@ -138,18 +151,9 @@ linuxdvb_network_create0
}
}
linuxdvb_network_config_save((mpegts_network_t*)ln);
return ln;
}
linuxdvb_network_t*
linuxdvb_network_find_by_uuid(const char *uuid)
{
idnode_t *in = idnode_find(uuid, &linuxdvb_network_class);
return (linuxdvb_network_t*)in;
}
void linuxdvb_network_init ( void )
{
htsmsg_t *c, *e;
@ -165,3 +169,20 @@ void linuxdvb_network_init ( void )
}
htsmsg_destroy(c);
}
/* ****************************************************************************
* Search
* ***************************************************************************/
linuxdvb_network_t*
linuxdvb_network_find_by_uuid(const char *uuid)
{
idnode_t *in = idnode_find(uuid, &linuxdvb_network_class);
return (linuxdvb_network_t*)in;
}
/******************************************************************************
* Editor Configuration
*
* vim:sts=2:ts=2:sw=2:et
*****************************************************************************/

View file

@ -186,8 +186,10 @@ struct linuxdvb_mux
linuxdvb_mux_t *linuxdvb_mux_create0
(linuxdvb_network_t *ln, uint16_t onid, uint16_t tsid,
const dvb_mux_conf_t *dmc, const char *uuid, htsmsg_t *conf);
linuxdvb_mux_t *linuxdvb_mux_create1
(linuxdvb_network_t *ln, const char *uuid, htsmsg_t *conf);
#define linuxdvb_mux_create1(n, u, c)\
linuxdvb_mux_create0(n, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE,\
NULL, u, c)
/*
* Service

View file

@ -109,9 +109,9 @@ mpegts_input_recv_packets
/* Re-sync */
} else {
// TODO: set flag (to avoid spam)
tvhlog(LOG_DEBUG, "tsdemux", "%s ts sync lost", "TODO");
tvhdebug("tsdemux", "%s ts sync lost", "TODO");
if (ts_resync(tsb, &len, &i)) break;
tvhlog(LOG_DEBUG, "tsdemux", "%s ts sync found", "TODO");
tvhdebug("tsdemux", "%s ts sync found", "TODO");
}
}

View file

@ -23,6 +23,13 @@
#include <assert.h>
static void
mpegts_mux_initial_scan_timeout ( void *aux );
/* ****************************************************************************
* Mux instance (input linkage)
* ***************************************************************************/
const idclass_t mpegts_mux_instance_class =
{
.ic_class = "mpegts_mux_instance",
@ -37,16 +44,21 @@ mpegts_mux_instance_create0
mpegts_input_t *mi, mpegts_mux_t *mm )
{
idnode_insert(&mmi->mmi_id, uuid, class);
// TODO: does this need to be an idnode?
/* Setup links */
mmi->mmi_mux = mm;
mmi->mmi_input = mi; // TODO: is this required?
mmi->mmi_input = mi;
LIST_INSERT_HEAD(&mm->mm_instances, mmi, mmi_mux_link);
return mmi;
}
/* ****************************************************************************
* Class definition
* ***************************************************************************/
static void
mpegts_mux_class_save ( idnode_t *self )
{
@ -74,6 +86,10 @@ const idclass_t mpegts_mux_class =
}
};
/* ****************************************************************************
* Class methods
* ***************************************************************************/
static void
mpegts_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
{
@ -92,124 +108,34 @@ mpegts_mux_is_enabled ( mpegts_mux_t *mm )
return mm->mm_enabled;
}
int
mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid )
{
char buf[256];
if (onid == mm->mm_onid)
return 0;
mm->mm_onid = onid;
mm->mm_display_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s onid set to %d", buf, onid);
return 1;
}
int
mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid )
{
char buf[256];
if (tsid == mm->mm_tsid)
return 0;
mm->mm_tsid = tsid;
mm->mm_display_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s tsid set to %d", buf, tsid);
return 1;
}
int
mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth )
{
char buf[256];
if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: ""))
return 0;
tvh_str_update(&mm->mm_crid_authority, defauth);
mm->mm_display_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s crid authority set to %s", buf, defauth);
return 1;
}
static void
mpegts_mux_initial_scan_link ( mpegts_mux_t *mm )
mpegts_mux_create_instances ( mpegts_mux_t *mm )
{
mpegts_network_t *mn = mm->mm_network;
assert(mn != NULL);
assert(mm->mm_initial_scan_status == MM_SCAN_DONE);
mm->mm_initial_scan_status = MM_SCAN_PENDING;
TAILQ_INSERT_TAIL(&mn->mn_initial_scan_pending_queue, mm,
mm_initial_scan_link);
mn->mn_initial_scan_num++;
tvhtrace("mpegts", "added mm %p to initial scan for mn %p pending %d",
mm, mn, mn->mn_initial_scan_num);
mpegts_network_schedule_initial_scan(mn);
}
static void
mpegts_mux_initial_scan_timeout ( void *aux )
{
mpegts_mux_t *mm = aux;
tvhlog(LOG_DEBUG, "mpegts", "initial scan timed out for mm %p", mm);
mpegts_mux_initial_scan_done(mm);
}
static int
mpegts_mux_has_subscribers ( mpegts_mux_t *mm )
{
service_t *t;
mpegts_mux_instance_t *mmi = mm->mm_active;
if (mmi) {
LIST_FOREACH(t, &mmi->mmi_input->mi_transports, s_active_link)
if (((mpegts_service_t*)t)->s_dvb_mux == mm)
return 1;
}
return 0;
}
void
mpegts_mux_initial_scan_done ( mpegts_mux_t *mm )
{
mpegts_network_t *mn = mm->mm_network;
tvhlog(LOG_DEBUG, "mpegts", "initial scan complete for mm %p", mm);
gtimer_disarm(&mm->mm_initial_scan_timeout);
assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT);
mn->mn_initial_scan_num--;
mm->mm_initial_scan_status = MM_SCAN_DONE;
TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link);
mpegts_network_schedule_initial_scan(mn);
/* Stop */
if (!mpegts_mux_has_subscribers(mm))
mm->mm_stop(mm);
/* Save */
mm->mm_initial_scan_done = 1;
mm->mm_config_save(mm);
}
static int
mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
{
char buf[128];
char buf[256], buf2[256];
mpegts_network_t *mn = mm->mm_network;
mpegts_mux_instance_t *mmi;
tvhtrace("mpegts", "mm %p starting for '%s' (weight %d)",
mm, reason, weight);
mm->mm_display_name(mm, buf, sizeof(buf));
tvhinfo("mpegts", "%s - starting for '%s' (weight %d)",
buf, reason, weight);
/* Already tuned */
if (mm->mm_active) {
tvhtrace("mpegts", "mm %p already active", mm);
tvhtrace("mpegts", "%s - already active", buf);
return 0;
}
/* Create mux instances (where needed) */
mm->mm_create_instances(mm);
if (!LIST_FIRST(&mm->mm_instances))
tvhtrace("mpegts", "mm %p has no instances", mm);
if (!LIST_FIRST(&mm->mm_instances)) {
tvhtrace("mpegts", "%s - has no instances", buf);
return SM_CODE_NO_FREE_ADAPTER;
}
/* Find */
// TODO: don't like this is unbounded, if for some reason mi_start_mux()
@ -224,13 +150,12 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
break;
}
if (mmi)
tvhtrace("mpegts", "found free mmi %p", mmi);
tvhtrace("mpegts", "%s - found free mmi %p", buf, mmi);
else
tvhtrace("mpegts", "no input is free");
tvhtrace("mpegts", "%s - no input is free", buf);
/* Try and remove a lesser instance */
if (!mmi) {
#if 0
LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) {
/* Bad - skip */
@ -243,30 +168,30 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
}
if (mmi)
tvhtrace("mpegts", "found mmi %p to boot", mmi);
#endif
tvhtrace("mpegts", "%s - found mmi %p to boot", buf, mmi);
/* No free input */
if (!mmi) {
tvhlog(LOG_DEBUG, "mpegts", "no input available");
else {
tvhdebug("mpegts", "%s - no input available", buf);
return SM_CODE_NO_FREE_ADAPTER;
}
}
/* Tune */
mm->mm_display_name(mm, buf, sizeof(buf));
tvhlog(LOG_INFO, "mpegts", "tuning %s", buf);
mmi->mmi_input->mi_display_name(mmi->mmi_input, buf2, sizeof(buf2));
tvhinfo("mpegts", "%s - tuning on %s", buf, buf2);
if (!mmi->mmi_input->mi_start_mux(mmi->mmi_input, mmi)) {
tvhdebug("mpegts", "%s - started", buf);
LIST_INSERT_HEAD(&mmi->mmi_input->mi_mux_active, mmi, mmi_active_link);
mm->mm_active = mmi;
break;
}
tvhtrace("mpegts", "failed to run mmi %p", mmi);
tvhwarn("mpegts", "%s - failed to start, try another", buf);
}
/* Initial scanning */
if (mm->mm_initial_scan_status == MM_SCAN_PENDING) {
tvhtrace("mpegts", "adding mm %p to current scan Q", mm);
tvhtrace("mpegts", "%s - adding to current scan Q", buf);
TAILQ_REMOVE(&mn->mn_initial_scan_pending_queue, mm, mm_initial_scan_link);
mm->mm_initial_scan_status = MM_SCAN_CURRENT;
TAILQ_INSERT_TAIL(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link);
@ -279,20 +204,22 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
static void
mpegts_mux_stop ( mpegts_mux_t *mm )
{
char buf[256];
service_t *s, *t;
mpegts_mux_instance_t *mmi = mm->mm_active;
mpegts_input_t *mi;
tvhtrace("mpegts", "stopping mux %p", mm);
mm->mm_display_name(mm, buf, sizeof(buf));
tvhdebug("mpegts", "%s - stopping mux", buf);
if (mmi) {
mi = mmi->mmi_input;
mi->mi_stop_mux(mi, mmi);
mm->mm_active = NULL;
LIST_REMOVE(mmi, mmi_active_link);
tvhtrace("mpegts", "active first = %p", LIST_FIRST(&mi->mi_mux_active));
/* Flush all subscribers */
tvhtrace("mpegts", "%s - flush subscribers", buf);
s = LIST_FIRST(&mi->mi_transports);
while (s) {
t = s;
@ -304,6 +231,7 @@ mpegts_mux_stop ( mpegts_mux_t *mm )
}
/* Flush all tables */
tvhtrace("mpegts", "%s - flush tables", buf);
mpegts_table_flush_all(mm);
/* Alert listeners */
@ -311,6 +239,7 @@ mpegts_mux_stop ( mpegts_mux_t *mm )
/* Scanning */
if (mm->mm_initial_scan_status == MM_SCAN_CURRENT) {
tvhtrace("mpegts", "%s - add to pending scan Q", buf);
mpegts_network_t *mn = mm->mm_network;
TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link);
mm->mm_initial_scan_status = MM_SCAN_PENDING;
@ -322,51 +251,114 @@ mpegts_mux_stop ( mpegts_mux_t *mm )
mm->mm_active = NULL;
}
static void
mpegts_mux_create_instances ( mpegts_mux_t *mm )
{
}
static void
mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
char buf[256];
if (mt->mt_pid >= 0x2000)
return;
mm->mm_display_name(mm, buf, sizeof(buf));
if (!mm->mm_table_filter[mt->mt_pid])
tvhtrace("mpegts", "mm %p opened table pid %04X (%d)",
mm, mt->mt_pid, mt->mt_pid);
tvhtrace("mpegts", "%s - opened table %s pid %04X (%d)",
buf, mt->mt_name, mt->mt_pid, mt->mt_pid);
mm->mm_table_filter[mt->mt_pid] = 1;
}
static void
mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
{
char buf[256];
if (mt->mt_pid >= 0x2000)
return;
tvhtrace("mpegts", "mm %p closed table pid %04X (%d)",
mm, mt->mt_pid, mt->mt_pid);
mm->mm_display_name(mm, buf, sizeof(buf));
tvhtrace("mpegts", "%s - closed table %s pid %04X (%d)",
buf, mt->mt_name, mt->mt_pid, mt->mt_pid);
mm->mm_table_filter[mt->mt_pid] = 0;
}
void
mpegts_mux_load_one ( mpegts_mux_t *mm, htsmsg_t *c )
{
uint32_t u32;
/* ONID */
if (!htsmsg_get_u32(c, "onid", &u32))
mm->mm_onid = u32;
/* **************************************************************************
* Scanning
* *************************************************************************/
/* TSID */
if (!htsmsg_get_u32(c, "tsid", &u32))
mm->mm_tsid = u32;
static int
mpegts_mux_has_subscribers ( mpegts_mux_t *mm )
{
service_t *t;
mpegts_mux_instance_t *mmi = mm->mm_active;
if (mmi) {
LIST_FOREACH(t, &mmi->mmi_input->mi_transports, s_active_link)
if (((mpegts_service_t*)t)->s_dvb_mux == mm)
return 1;
}
return 0;
}
static void
mpegts_mux_initial_scan_link ( mpegts_mux_t *mm )
{
char buf1[256], buf2[256];
mpegts_network_t *mn = mm->mm_network;
assert(mn != NULL);
assert(mm->mm_initial_scan_status == MM_SCAN_DONE);
mm->mm_initial_scan_status = MM_SCAN_PENDING;
TAILQ_INSERT_TAIL(&mn->mn_initial_scan_pending_queue, mm,
mm_initial_scan_link);
mn->mn_initial_scan_num++;
mn->mn_display_name(mn, buf1, sizeof(buf1));
mm->mm_display_name(mm, buf2, sizeof(buf2));
tvhdebug("mpegts", "%s - added %s to scan pending q",
buf1, buf2);
mpegts_network_schedule_initial_scan(mn);
}
static void
mpegts_mux_initial_scan_timeout ( void *aux )
{
char buf[256];
mpegts_mux_t *mm = aux;
mm->mm_display_name(mm, buf, sizeof(buf));
tvhdebug("mpegts", "%s - initial scan timed", buf);
mpegts_mux_initial_scan_done(mm);
}
void
mpegts_mux_initial_scan_done ( mpegts_mux_t *mm )
{
char buf[256];
mpegts_network_t *mn = mm->mm_network;
mm->mm_display_name(mm, buf, sizeof(buf));
tvhinfo("mpegts", "%s - initial scan complete", buf);
gtimer_disarm(&mm->mm_initial_scan_timeout);
assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT);
mn->mn_initial_scan_num--;
mm->mm_initial_scan_status = MM_SCAN_DONE;
TAILQ_REMOVE(&mn->mn_initial_scan_current_queue, mm, mm_initial_scan_link);
mpegts_network_schedule_initial_scan(mn);
/* Stop */
if (!mpegts_mux_has_subscribers(mm)) {
tvhtrace("mpegts", "%s - no active subscribers, stop", buf);
mm->mm_stop(mm);
}
/* Save */
mm->mm_initial_scan_done = 1;
mm->mm_config_save(mm);
}
/* **************************************************************************
* Creation / Config
* *************************************************************************/
mpegts_mux_t *
mpegts_mux_create0
( mpegts_mux_t *mm, const idclass_t *class, const char *uuid,
mpegts_network_t *mn, uint16_t onid, uint16_t tsid, htsmsg_t *conf )
{
char buf[256];
idnode_insert(&mm->mm_id, uuid, class);
/* Enabled by default */
@ -403,9 +395,56 @@ mpegts_mux_create0
if (!mm->mm_initial_scan_done || !mn->mn_skipinitscan)
mpegts_mux_initial_scan_link(mm);
mm->mm_display_name(mm, buf, sizeof(buf));
tvhtrace("mpegts", "%s - created", buf);
return mm;
}
void
mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c )
{
idnode_save(&mm->mm_id, c);
}
int
mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid )
{
char buf[256];
if (onid == mm->mm_onid)
return 0;
mm->mm_onid = onid;
mm->mm_display_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s - set onid %04X (%d)", buf, onid, onid);
return 1;
}
int
mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid )
{
char buf[256];
if (tsid == mm->mm_tsid)
return 0;
mm->mm_tsid = tsid;
mm->mm_display_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s - set tsid %04X (%d)", buf, tsid, tsid);
return 1;
}
int
mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth )
{
char buf[256];
if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: ""))
return 0;
tvh_str_update(&mm->mm_crid_authority, defauth);
mm->mm_display_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s - set crid authority %s", buf, defauth);
return 1;
}
/******************************************************************************
* Editor Configuration

View file

@ -20,10 +20,23 @@
#include <assert.h>
/* ****************************************************************************
* Class definition
* ***************************************************************************/
static void
mpegts_network_class_save
( idnode_t *in )
{
mpegts_network_t *mn = (mpegts_network_t*)in;
mn->mn_config_save(mn);
}
const idclass_t mpegts_network_class =
{
.ic_class = "mpegts_network",
.ic_caption = "MPEGTS Network",
.ic_save = mpegts_network_class_save,
.ic_properties = (const property_t[]){
{ PROPDEF1("networkname", "Network Name",
PT_STR, mpegts_network_t, mn_network_name) },
@ -37,6 +50,10 @@ const idclass_t mpegts_network_class =
}
};
/* ****************************************************************************
* Class methods
* ***************************************************************************/
static void
mpegts_network_display_name
( mpegts_network_t *mn, char *buf, size_t len )
@ -65,6 +82,10 @@ mpegts_network_create_service
return NULL;
}
/* ****************************************************************************
* Scanning
* ***************************************************************************/
static void
mpegts_network_initial_scan(void *aux)
{
@ -87,36 +108,61 @@ mpegts_network_schedule_initial_scan ( mpegts_network_t *mn )
gtimer_arm(&mn->mn_initial_scan_timer, mpegts_network_initial_scan, mn, 0);
}
void
mpegts_network_add_input ( mpegts_network_t *mn, mpegts_input_t *mi )
{
mi->mi_network = mn;
LIST_INSERT_HEAD(&mn->mn_inputs, mi, mi_network_link);
}
/* ****************************************************************************
* Creation/Config
* ***************************************************************************/
mpegts_network_t *
mpegts_network_create0
( mpegts_network_t *mn, const idclass_t *idc, const char *uuid,
const char *netname )
const char *netname, htsmsg_t *conf )
{
char buf[256];
/* Setup idnode */
idnode_insert(&mn->mn_id, uuid, idc);
if (conf)
idnode_load(&mn->mn_id, conf);
/* Default callbacks */
mn->mn_display_name = mpegts_network_display_name;
mn->mn_config_save = mpegts_network_config_save;
mn->mn_create_mux = mpegts_network_create_mux;
mn->mn_create_service = mpegts_network_create_service;
/* Network name */
if (netname) mn->mn_network_name = strdup(netname);
/* Init Qs */
TAILQ_INIT(&mn->mn_initial_scan_pending_queue);
TAILQ_INIT(&mn->mn_initial_scan_current_queue);
mn->mn_display_name(mn, buf, sizeof(buf));
tvhtrace("mpegts", "created network %s", buf);
return mn;
}
void
mpegts_network_add_input ( mpegts_network_t *mn, mpegts_input_t *mi )
{
char buf1[256], buf2[265];
mi->mi_network = mn;
LIST_INSERT_HEAD(&mn->mn_inputs, mi, mi_network_link);
mn->mn_display_name(mn, buf1, sizeof(buf1));
mi->mi_display_name(mi, buf2, sizeof(buf2));
tvhdebug("mpegts", "%s - added input %s", buf1, buf2);
}
int
mpegts_network_set_nid
( mpegts_network_t *mn, uint16_t nid )
{
char buf[256];
if (mn->mn_nid == nid)
return 0;
mn->mn_nid = nid;
mn->mn_display_name(mn, buf, sizeof(buf));
tvhdebug("mpegts", "%s - set nid %04X (%d)", buf, nid, nid);
return 1;
}
@ -124,9 +170,12 @@ int
mpegts_network_set_network_name
( mpegts_network_t *mn, const char *name )
{
char buf[256];
if (!name || !strcmp(name, mn->mn_network_name ?: ""))
return 0;
tvh_str_update(&mn->mn_network_name, name);
mn->mn_display_name(mn, buf, sizeof(buf));
tvhdebug("mpegts", "%s - set name %s", buf, name);
return 1;
}

View file

@ -82,8 +82,9 @@ void _tvhlog_hexdump ( const char *file, int line,
#define tvhlog_hexdump(...) (void)0
#endif
#define tvhdebug(...) tvhlog(LOG_DEBUG, ##__VA_ARGS__)
#define tvhdebug(...) tvhlog(LOG_DEBUG, ##__VA_ARGS__)
#define tvhinfo(...) tvhlog(LOG_INFO, ##__VA_ARGS__)
#define tvhwarn(...) tvhlog(LOG_WARNING, ##__VA_ARGS__)
#define tvherror(...) tvhlog(LOG_ERR, ##__VA_ARGS__)
#endif /* __TVH_LOGGING_H__ */