Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
mpegts: add linked tuner feature
The DvbSky S952 drivers have numerous tuning bugs and one of it is
that if two tuners are not used together, streaming from one tuner
can "hang".

This change implements a workaround which makes the second (linked)
tuner alive (tuning is joined with these two linked tuners).
  • Loading branch information
perexg committed Jan 17, 2015
1 parent 37eb9d2 commit 273835f
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 46 deletions.
2 changes: 1 addition & 1 deletion src/epggrab/otamux.c
Expand Up @@ -540,7 +540,7 @@ epggrab_ota_kick_cb ( void *p )

/* Subscribe to the mux */
om->om_requeue = 1;
if ((r = mpegts_mux_subscribe(mm, "epggrab", SUBSCRIPTION_PRIO_EPG,
if ((r = mpegts_mux_subscribe(mm, NULL, "epggrab", SUBSCRIPTION_PRIO_EPG,
SUBSCRIPTION_EPG))) {
TAILQ_INSERT_TAIL(&epggrab_ota_pending, om, om_q_link);
om->om_q_type = EPGGRAB_OTA_MUX_PENDING;
Expand Down
9 changes: 7 additions & 2 deletions src/input/mpegts.h
Expand Up @@ -413,7 +413,7 @@ struct mpegts_mux
void (*mm_config_save) (mpegts_mux_t *mm);
void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len);
int (*mm_is_enabled) (mpegts_mux_t *mm);
int (*mm_start) (mpegts_mux_t *mm, const char *r, int w, int flags);
int (*mm_start) (mpegts_mux_t *mm, mpegts_input_t *mi, const char *r, int w, int flags);
void (*mm_stop) (mpegts_mux_t *mm, int force);
void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*,int subscribe);
void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*);
Expand Down Expand Up @@ -564,6 +564,8 @@ struct mpegts_input
int mi_initscan;
int mi_idlescan;

char *mi_linked;

LIST_ENTRY(mpegts_input) mi_global_link;

mpegts_network_link_list_t mi_networks;
Expand Down Expand Up @@ -779,9 +781,12 @@ void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe
void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt );

void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int reason);
int mpegts_mux_subscribe(mpegts_mux_t *mm, const char *name, int weight, int flags);
int mpegts_mux_subscribe(mpegts_mux_t *mm, mpegts_input_t *mi,
const char *name, int weight, int flags);
void mpegts_mux_unsubscribe_by_name(mpegts_mux_t *mm, const char *name);

void mpegts_mux_unsubscribe_linked(mpegts_input_t *mi);

void mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res );

void mpegts_mux_bouquet_rescan ( const char *src, const char *extra );
Expand Down
89 changes: 85 additions & 4 deletions src/input/mpegts/mpegts_input.c
Expand Up @@ -140,6 +140,75 @@ mpegts_input_enabled_notify ( void *p )
mi->mi_enabled_updated(mi);
}

static int
mpegts_input_class_linked_set ( void *self, const void *val )
{
mpegts_input_t *mi = self, *mi2;

if (strcmp(val ?: "", mi->mi_linked ?: "")) {
mi2 = mpegts_input_find(mi->mi_linked);
free(mi->mi_linked);
mi->mi_linked = NULL;
if (mi2) {
free(mi2->mi_linked);
mi2->mi_linked = NULL;
mpegts_mux_unsubscribe_linked(mi2);
}
mpegts_mux_unsubscribe_linked(mi);
if (val) {
mi->mi_linked = strdup((char *)val);
mi2 = mpegts_input_find((char *)val);
if (mi2) {
free(mi2->mi_linked);
mi2->mi_linked = strdup(idnode_uuid_as_str(&mi->ti_id));
idnode_changed(&mi2->ti_id);
}
}
return 1;
}
return 0;
}

static const void *
mpegts_input_class_linked_get ( void *self )
{
static const char *ptr;
mpegts_input_t *mi = self;
ptr = "";
if (mi->mi_linked) {
mi = mpegts_input_find(mi->mi_linked);
if (mi)
ptr = idnode_uuid_as_str(&mi->ti_id);
}
return &ptr;
}

static void
mpegts_input_add_keyval(htsmsg_t *l, const char *key, const char *val)
{
htsmsg_t *e = htsmsg_create_map();
htsmsg_add_str(e, "key", key);
htsmsg_add_str(e, "val", val);
htsmsg_add_msg(l, NULL, e);
}

static htsmsg_t *
mpegts_input_class_linked_enum( void * self )
{
mpegts_input_t *mi = self, *mi2;
tvh_input_t *ti;
htsmsg_t *m = htsmsg_create_list();
mpegts_input_add_keyval(m, "", "Not Linked");
TVH_INPUT_FOREACH(ti)
if (idnode_is_instance(&ti->ti_id, &mpegts_input_class)) {
mi2 = (mpegts_input_t *)ti;
if (mi2 != mi)
mpegts_input_add_keyval(m, idnode_uuid_as_str(&ti->ti_id),
idnode_get_title(&mi2->ti_id));
}
return m;
}

const idclass_t mpegts_input_class =
{
.ic_class = "mpegts_input",
Expand Down Expand Up @@ -212,6 +281,14 @@ const idclass_t mpegts_input_class =
.list = mpegts_input_class_network_enum,
.rend = mpegts_input_class_network_rend,
},
{
.type = PT_STR,
.id = "linked",
.name = "Linked Input",
.set = mpegts_input_class_linked_set,
.get = mpegts_input_class_linked_get,
.list = mpegts_input_class_linked_enum
},
{}
}
};
Expand All @@ -235,19 +312,22 @@ mpegts_input_is_enabled ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
static void
mpegts_input_display_name ( mpegts_input_t *mi, char *buf, size_t len )
{
if (mi->mi_name)
strncpy(buf, mi->mi_name, len);
else
if (mi->mi_name) {
strncpy(buf, mi->mi_name, len - 1);
buf[len - 1] = '\0';
} else
*buf = 0;
}

int
mpegts_input_is_free ( mpegts_input_t *mi )
{
char buf[256];
mpegts_mux_instance_t *mmi = LIST_FIRST(&mi->mi_mux_active);
#if ENABLE_TRACE
char buf[256];
mi->mi_display_name(mi, buf, sizeof(buf));
tvhtrace("mpegts", "%s - is free? %d", buf, mmi == NULL);
#endif
return mmi ? 0 : 1;
}

Expand Down Expand Up @@ -1345,6 +1425,7 @@ mpegts_input_delete ( mpegts_input_t *mi, int delconf )
pthread_mutex_destroy(&mi->mi_output_lock);
pthread_cond_destroy(&mi->mi_table_cond);
free(mi->mi_name);
free(mi->mi_linked);
free(mi);
}

Expand Down

3 comments on commit 273835f

@ksooo
Copy link
Contributor

@ksooo ksooo commented on 273835f Jan 19, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@perexg: I have a DvbSky S952. and never noticed the problems you mentioned above. But after this commit I experience "hangs". Formerly working channels sporadically(?) cannot be subscribed now. Will my DvbSky S952 now only work if I enable "Linked"?

@adamsutton
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must admit, I really don't like this commit. Although we do have some fixes in place to cope with broken drivers, I think this is really a step too far. It's adding a significant level of complexity to fix someone else's broken code, potentially at the expense of our own code base.

@ksooo
Copy link
Contributor

@ksooo ksooo commented on 273835f Jan 19, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fully backing @adamsutton. I think driver problems should be fixed in the causing driver(s). Especially if the workaround is so complex like in this case.

Please sign in to comment.