mpegts: make the mapping of network<->input N<->N
I've rejected doing this for ages, however there are real limitations with not being able to do this. And I've specifically come across one while thinking about how some IPTV changes would be handled. This will probably result in a break to peoples config, I will try and mitigate this.
This commit is contained in:
parent
a3d2062c01
commit
1298adb956
3 changed files with 169 additions and 29 deletions
|
@ -40,12 +40,14 @@ typedef struct mpegts_mux_instance mpegts_mux_instance_t;
|
|||
typedef struct mpegts_mux_sub mpegts_mux_sub_t;
|
||||
typedef struct mpegts_input mpegts_input_t;
|
||||
typedef struct mpegts_table_feed mpegts_table_feed_t;
|
||||
typedef struct mpegts_network_link mpegts_network_link_t;
|
||||
|
||||
/* Lists */
|
||||
typedef LIST_HEAD (,mpegts_network) mpegts_network_list_t;
|
||||
typedef LIST_HEAD (mpegts_input_list,mpegts_input) mpegts_input_list_t;
|
||||
typedef TAILQ_HEAD(mpegts_mux_queue,mpegts_mux) mpegts_mux_queue_t;
|
||||
typedef LIST_HEAD (mpegts_mux_list,mpegts_mux) mpegts_mux_list_t;
|
||||
typedef LIST_HEAD (,mpegts_network) mpegts_network_list_t;
|
||||
typedef LIST_HEAD (,mpegts_input) mpegts_input_list_t;
|
||||
typedef TAILQ_HEAD(mpegts_mux_queue,mpegts_mux) mpegts_mux_queue_t;
|
||||
typedef LIST_HEAD (,mpegts_mux) mpegts_mux_list_t;
|
||||
typedef LIST_HEAD (,mpegts_network_link) mpegts_network_link_list_t;
|
||||
TAILQ_HEAD(mpegts_table_feed_queue, mpegts_table_feed);
|
||||
|
||||
/* Classes */
|
||||
|
@ -190,6 +192,16 @@ void mpegts_psi_section_reassemble
|
|||
* Logical network
|
||||
* *************************************************************************/
|
||||
|
||||
/* Network/Input linkage */
|
||||
struct mpegts_network_link
|
||||
{
|
||||
int mnl_mark;
|
||||
mpegts_input_t *mnl_input;
|
||||
mpegts_network_t *mnl_network;
|
||||
LIST_ENTRY(mpegts_network_link) mnl_mn_link;
|
||||
LIST_ENTRY(mpegts_network_link) mnl_mi_link;
|
||||
};
|
||||
|
||||
/* Network */
|
||||
struct mpegts_network
|
||||
{
|
||||
|
@ -212,7 +224,7 @@ struct mpegts_network
|
|||
/*
|
||||
* Inputs
|
||||
*/
|
||||
mpegts_input_list_t mn_inputs;
|
||||
mpegts_network_link_list_t mn_inputs;
|
||||
|
||||
/*
|
||||
* Multiplexes
|
||||
|
@ -419,8 +431,7 @@ struct mpegts_input
|
|||
|
||||
LIST_ENTRY(mpegts_input) mi_global_link;
|
||||
|
||||
mpegts_network_t *mi_network;
|
||||
LIST_ENTRY(mpegts_input) mi_network_link;
|
||||
mpegts_network_link_list_t mi_networks;
|
||||
|
||||
LIST_HEAD(,mpegts_mux_instance) mi_mux_active;
|
||||
|
||||
|
@ -509,13 +520,21 @@ void mpegts_input_delete ( mpegts_input_t *mi, int delconf );
|
|||
|
||||
#define mpegts_input_find(u) idnode_find(u, &mpegts_input_class);
|
||||
|
||||
void mpegts_input_set_network ( mpegts_input_t *mi, mpegts_network_t *mn );
|
||||
int mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg );
|
||||
|
||||
int mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn );
|
||||
|
||||
void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init );
|
||||
void mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s );
|
||||
|
||||
void mpegts_input_status_timer ( void *p );
|
||||
|
||||
/* TODO: exposing these class methods here is a bit of a hack */
|
||||
const void *mpegts_input_class_network_get ( void *o );
|
||||
int mpegts_input_class_network_set ( void *o, const void *p );
|
||||
htsmsg_t *mpegts_input_class_network_enum ( void *o );
|
||||
char *mpegts_input_class_network_rend ( void *o );
|
||||
|
||||
void mpegts_network_register_builder
|
||||
( const idclass_t *idc,
|
||||
mpegts_network_t *(*build)(const idclass_t *idc, htsmsg_t *conf) );
|
||||
|
|
|
@ -23,12 +23,15 @@
|
|||
#include "subscriptions.h"
|
||||
#include "atomic.h"
|
||||
#include "notify.h"
|
||||
#include "idnode.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
SKEL_DECLARE(mpegts_pid_sub_skel, mpegts_pid_sub_t);
|
||||
|
||||
static void
|
||||
mpegts_input_del_network ( mpegts_network_link_t *mnl );
|
||||
|
||||
/* **************************************************************************
|
||||
* Class definition
|
||||
|
@ -43,6 +46,59 @@ mpegts_input_class_get_title ( idnode_t *in )
|
|||
return buf;
|
||||
}
|
||||
|
||||
const void *
|
||||
mpegts_input_class_network_get ( void *obj )
|
||||
{
|
||||
mpegts_network_link_t *mnl;
|
||||
mpegts_input_t *mi = obj;
|
||||
htsmsg_t *l = htsmsg_create_list();
|
||||
|
||||
LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link)
|
||||
htsmsg_add_str(l, NULL, idnode_uuid_as_str(&mnl->mnl_network->mn_id));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
mpegts_input_class_network_set ( void *obj, const void *p )
|
||||
{
|
||||
return mpegts_input_set_networks(obj, (htsmsg_t*)p);
|
||||
}
|
||||
|
||||
htsmsg_t *
|
||||
mpegts_input_class_network_enum ( void *obj )
|
||||
{
|
||||
htsmsg_t *p, *m;
|
||||
|
||||
p = htsmsg_create_map();
|
||||
htsmsg_add_str (p, "uuid", idnode_uuid_as_str((idnode_t*)obj));
|
||||
htsmsg_add_bool(p, "enum", 1);
|
||||
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_add_str (m, "type", "api");
|
||||
htsmsg_add_str (m, "uri", "mpegts/input/network_list");
|
||||
htsmsg_add_str (m, "event", "mpegts_network");
|
||||
htsmsg_add_msg (m, "params", p);
|
||||
return m;
|
||||
}
|
||||
|
||||
char *
|
||||
mpegts_input_class_network_rend ( void *obj )
|
||||
{
|
||||
char *str;
|
||||
mpegts_network_link_t *mnl;
|
||||
mpegts_input_t *mi = obj;
|
||||
htsmsg_t *l = htsmsg_create_list();
|
||||
|
||||
LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link)
|
||||
htsmsg_add_str(l, NULL, idnode_get_title(&mnl->mnl_network->mn_id));
|
||||
|
||||
str = htsmsg_list_2_csv(l);
|
||||
htsmsg_destroy(l);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
const idclass_t mpegts_input_class =
|
||||
{
|
||||
.ic_class = "mpegts_input",
|
||||
|
@ -71,6 +127,16 @@ const idclass_t mpegts_input_class =
|
|||
.off = offsetof(mpegts_input_t, mi_name),
|
||||
.notify = idnode_notify_title_changed,
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "networks",
|
||||
.name = "Networks",
|
||||
.islist = 1,
|
||||
.set = mpegts_input_class_network_set,
|
||||
.get = mpegts_input_class_network_get,
|
||||
.list = mpegts_input_class_network_enum,
|
||||
.rend = mpegts_input_class_network_rend,
|
||||
},
|
||||
{}
|
||||
}
|
||||
};
|
||||
|
@ -711,7 +777,9 @@ mpegts_input_create0
|
|||
void
|
||||
mpegts_input_delete ( mpegts_input_t *mi, int delconf )
|
||||
{
|
||||
mpegts_input_set_network(mi, NULL);
|
||||
mpegts_network_link_t *mnl;
|
||||
while ((mnl = LIST_FIRST(&mi->mi_networks)))
|
||||
mpegts_input_del_network(mnl);
|
||||
idnode_unlink(&mi->ti_id);
|
||||
pthread_mutex_destroy(&mi->mi_delivery_mutex);
|
||||
pthread_cond_destroy(&mi->mi_table_feed_cond);
|
||||
|
@ -728,27 +796,71 @@ mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *m )
|
|||
idnode_save(&mi->ti_id, m);
|
||||
}
|
||||
|
||||
void
|
||||
mpegts_input_set_network ( mpegts_input_t *mi, mpegts_network_t *mn )
|
||||
int
|
||||
mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn )
|
||||
{
|
||||
char buf1[256], buf2[265];
|
||||
if (mi->mi_network == mn) return;
|
||||
*buf1 = *buf2 = 0;
|
||||
if (mi->mi_display_name) {
|
||||
mi->mi_display_name(mi, buf1, sizeof(buf1));
|
||||
mpegts_network_link_t *mnl;
|
||||
|
||||
/* Find existing */
|
||||
LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link)
|
||||
if (mnl->mnl_network == mn)
|
||||
break;
|
||||
|
||||
/* Clear mark */
|
||||
if (mnl) {
|
||||
mnl->mnl_mark = 0;
|
||||
return 0;
|
||||
}
|
||||
if (mi->mi_network) {
|
||||
mi->mi_network->mn_display_name(mi->mi_network, buf2, sizeof(buf2));
|
||||
LIST_REMOVE(mi, mi_network_link);
|
||||
tvhdebug("mpegts", "%s - remove network %s", buf1, buf2);
|
||||
mi->mi_network = NULL;
|
||||
|
||||
/* Create new */
|
||||
mnl = calloc(1, sizeof(mpegts_network_link_t));
|
||||
mnl->mnl_input = mi;
|
||||
mnl->mnl_network = mn;
|
||||
LIST_INSERT_HEAD(&mi->mi_networks, mnl, mnl_mi_link);
|
||||
LIST_INSERT_HEAD(&mn->mn_inputs, mnl, mnl_mn_link);
|
||||
idnode_notify_simple(&mnl->mnl_network->mn_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_input_del_network ( mpegts_network_link_t *mnl )
|
||||
{
|
||||
idnode_notify_simple(&mnl->mnl_network->mn_id);
|
||||
LIST_REMOVE(mnl, mnl_mn_link);
|
||||
LIST_REMOVE(mnl, mnl_mi_link);
|
||||
free(mnl);
|
||||
}
|
||||
|
||||
int
|
||||
mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg )
|
||||
{
|
||||
int save = 0;
|
||||
const char *str;
|
||||
htsmsg_field_t *f;
|
||||
mpegts_network_t *mn;
|
||||
mpegts_network_link_t *mnl, *nxt;
|
||||
|
||||
/* Mark for deletion */
|
||||
LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link)
|
||||
mnl->mnl_mark = 1;
|
||||
|
||||
/* Link */
|
||||
HTSMSG_FOREACH(f, msg) {
|
||||
if (!(str = htsmsg_field_get_str(f))) continue;
|
||||
if (!(mn = mpegts_network_find(str))) continue;
|
||||
save |= mpegts_input_add_network(mi, mn);
|
||||
}
|
||||
if (mn) {
|
||||
mn->mn_display_name(mn, buf2, sizeof(buf2));
|
||||
mi->mi_network = mn;
|
||||
LIST_INSERT_HEAD(&mn->mn_inputs, mi, mi_network_link);
|
||||
tvhdebug("mpegts", "%s - added network %s", buf1, buf2);
|
||||
|
||||
/* Unlink */
|
||||
for (mnl = LIST_FIRST(&mi->mi_networks); mnl != NULL; mnl = nxt) {
|
||||
nxt = LIST_NEXT(mnl, mnl_mi_link);
|
||||
if (mnl->mnl_mark) {
|
||||
mpegts_input_del_network(mnl);
|
||||
save = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -208,12 +208,21 @@ mpegts_network_mux_create2
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_network_link_delete ( mpegts_network_link_t *mnl )
|
||||
{
|
||||
idnode_notify_simple(&mnl->mnl_input->ti_id);
|
||||
LIST_REMOVE(mnl, mnl_mn_link);
|
||||
LIST_REMOVE(mnl, mnl_mi_link);
|
||||
free(mnl);
|
||||
}
|
||||
|
||||
void
|
||||
mpegts_network_delete
|
||||
( mpegts_network_t *mn, int delconf )
|
||||
{
|
||||
mpegts_input_t *mi;
|
||||
mpegts_mux_t *mm;
|
||||
mpegts_network_link_t *mnl;
|
||||
|
||||
/* Remove from global list */
|
||||
LIST_REMOVE(mn, mn_global_link);
|
||||
|
@ -231,8 +240,8 @@ mpegts_network_delete
|
|||
gtimer_disarm(&mn->mn_initial_scan_timer);
|
||||
|
||||
/* Remove from input */
|
||||
while ((mi = LIST_FIRST(&mn->mn_inputs)))
|
||||
mpegts_input_set_network(mi, NULL);
|
||||
while ((mnl = LIST_FIRST(&mn->mn_inputs)))
|
||||
mpegts_network_link_delete(mnl);
|
||||
|
||||
/* Free memory */
|
||||
idnode_unlink(&mn->mn_id);
|
||||
|
|
Loading…
Add table
Reference in a new issue