mpegts: add the concept of a mux level subscription
This is necessary so that things like EPG grabbing can make subscriptions that take precedence over initial scan but not over standard subscriptions. Will also be used for the debug mux dump from UI feature. (cherry picked from commit 35a58bdf85008b819504e86e26f1072f79e79af3)
This commit is contained in:
parent
e5140a9c75
commit
3a1cbb9f53
6 changed files with 88 additions and 30 deletions
|
@ -34,6 +34,7 @@ typedef struct mpegts_network mpegts_network_t;
|
|||
typedef struct mpegts_mux mpegts_mux_t;
|
||||
typedef struct mpegts_service mpegts_service_t;
|
||||
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;
|
||||
|
||||
|
@ -251,8 +252,9 @@ 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);
|
||||
void (*mm_stop) (mpegts_mux_t *mm);
|
||||
int (*mm_start) (mpegts_mux_t *mm,
|
||||
void *src, const char *r, int w);
|
||||
void (*mm_stop) (mpegts_mux_t *mm, void *src, int force);
|
||||
void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*);
|
||||
void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*);
|
||||
void (*mm_create_instances) (mpegts_mux_t*);
|
||||
|
@ -349,12 +351,21 @@ struct mpegts_mux_instance
|
|||
mpegts_mux_t *mmi_mux;
|
||||
mpegts_input_t *mmi_input;
|
||||
|
||||
RB_HEAD(,mpegts_mux_sub) mmi_subs;
|
||||
|
||||
// TODO: remove this
|
||||
int mmi_tune_failed; // this is really DVB
|
||||
|
||||
void (*mmi_delete) (mpegts_mux_instance_t *mmi);
|
||||
};
|
||||
|
||||
struct mpegts_mux_sub
|
||||
{
|
||||
RB_ENTRY(mpegts_mux_sub) mms_link;
|
||||
void *mms_src;
|
||||
int mms_weight;
|
||||
};
|
||||
|
||||
/* Input source */
|
||||
struct mpegts_input
|
||||
{
|
||||
|
@ -512,7 +523,8 @@ mpegts_mux_instance_t *mpegts_mux_instance_create0
|
|||
(struct type*)mpegts_mux_instance_create0(calloc(1, sizeof(struct type)),\
|
||||
&type##_class, uuid,\
|
||||
mi, mm);
|
||||
int mpegts_mux_instance_start ( mpegts_mux_instance_t **mmiptr );
|
||||
int mpegts_mux_instance_start
|
||||
( mpegts_mux_instance_t **mmiptr, void *src, int weight );
|
||||
|
||||
int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid );
|
||||
int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
|
||||
|
|
|
@ -673,7 +673,7 @@ linuxdvb_frontend_tune0
|
|||
return 0;
|
||||
|
||||
/* Stop current */
|
||||
cur->mmi_mux->mm_stop(cur->mmi_mux);
|
||||
cur->mmi_mux->mm_stop(cur->mmi_mux, NULL, 1);
|
||||
}
|
||||
assert(LIST_FIRST(&lfe->mi_mux_active) == NULL);
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ int
|
|||
mpegts_input_current_weight ( mpegts_input_t *mi )
|
||||
{
|
||||
const mpegts_mux_instance_t *mmi;
|
||||
const mpegts_mux_sub_t *mms;
|
||||
const service_t *s;
|
||||
const th_subscription_t *ths;
|
||||
int w = 0;
|
||||
|
@ -101,10 +102,8 @@ mpegts_input_current_weight ( mpegts_input_t *mi )
|
|||
|
||||
/* Check for scan (weight 1) */
|
||||
LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) {
|
||||
if (mmi->mmi_mux->mm_initial_scan_status == MM_SCAN_CURRENT) {
|
||||
w = 1;
|
||||
break;
|
||||
}
|
||||
RB_FOREACH(mms, &mmi->mmi_subs, mms_link)
|
||||
w = MAX(w, mms->mms_weight);
|
||||
}
|
||||
|
||||
/* Check subscriptions */
|
||||
|
|
|
@ -68,8 +68,17 @@ mpegts_mux_instance_create0
|
|||
return mmi;
|
||||
}
|
||||
|
||||
static int
|
||||
mms_cmp ( mpegts_mux_sub_t *a, mpegts_mux_sub_t *b )
|
||||
{
|
||||
if (a->mms_src < b->mms_src) return -1;
|
||||
if (a->mms_src > b->mms_src) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mpegts_mux_instance_start ( mpegts_mux_instance_t **mmiptr )
|
||||
mpegts_mux_instance_start
|
||||
( mpegts_mux_instance_t **mmiptr, void *src, int weight )
|
||||
{
|
||||
int r;
|
||||
char buf[256], buf2[256];;
|
||||
|
@ -91,6 +100,21 @@ mpegts_mux_instance_start ( mpegts_mux_instance_t **mmiptr )
|
|||
r = mmi->mmi_input->mi_start_mux(mmi->mmi_input, mmi);
|
||||
if (r) return r;
|
||||
|
||||
/* Add sub */
|
||||
if (src) {
|
||||
mpegts_mux_sub_t *sub;
|
||||
static mpegts_mux_sub_t *skel = NULL;
|
||||
if (!skel)
|
||||
skel = calloc(1, sizeof(mpegts_mux_sub_t));
|
||||
skel->mms_src = src;
|
||||
sub = RB_INSERT_SORTED(&mmi->mmi_subs, skel, mms_link, mms_cmp);
|
||||
if (!sub) {
|
||||
sub = skel;
|
||||
skel = NULL;
|
||||
sub->mms_weight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start */
|
||||
tvhdebug("mpegts", "%s - started", buf);
|
||||
mmi->mmi_input->mi_started_mux(mmi->mmi_input, mmi);
|
||||
|
@ -251,7 +275,7 @@ mpegts_mux_delete ( mpegts_mux_t *mm )
|
|||
tvhinfo("mpegts", "%s - deleting", buf);
|
||||
|
||||
/* Stop */
|
||||
mm->mm_stop(mm);
|
||||
mm->mm_stop(mm, NULL, 1);
|
||||
|
||||
/* Remove from lists */
|
||||
LIST_REMOVE(mm, mm_network_link);
|
||||
|
@ -290,7 +314,8 @@ mpegts_mux_create_instances ( mpegts_mux_t *mm )
|
|||
}
|
||||
|
||||
static int
|
||||
mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
|
||||
mpegts_mux_start
|
||||
( mpegts_mux_t *mm, void *src, const char *reason, int weight )
|
||||
{
|
||||
int pass, fail;
|
||||
char buf[256];
|
||||
|
@ -353,7 +378,7 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
|
|||
if (tune) {
|
||||
tvhinfo("mpegts", "%s - starting for '%s' (weight %d)",
|
||||
buf, reason, weight);
|
||||
if (!(fail = mpegts_mux_instance_start(&tune))) break;
|
||||
if (!(fail = mpegts_mux_instance_start(&tune, src, weight))) break;
|
||||
tune = NULL;
|
||||
tvhwarn("mpegts", "%s - failed to start, try another", buf);
|
||||
}
|
||||
|
@ -371,12 +396,44 @@ mpegts_mux_start ( mpegts_mux_t *mm, const char *reason, int weight )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpegts_mux_has_subscribers ( mpegts_mux_t *mm )
|
||||
{
|
||||
mpegts_mux_instance_t *mmi = mm->mm_active;
|
||||
if (mmi) {
|
||||
if (RB_FIRST(&mmi->mmi_subs))
|
||||
return 1;
|
||||
return mmi->mmi_input->mi_has_subscription(mmi->mmi_input, mm);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_mux_stop ( mpegts_mux_t *mm )
|
||||
mpegts_mux_stop ( mpegts_mux_t *mm, void *src, int force )
|
||||
{
|
||||
char buf[256];
|
||||
mpegts_mux_instance_t *mmi = mm->mm_active;
|
||||
mpegts_input_t *mi = NULL;
|
||||
mpegts_mux_sub_t *sub, skel;
|
||||
|
||||
/* Remove subs */
|
||||
if (mmi) {
|
||||
if (force) {
|
||||
while ((sub = RB_FIRST(&mmi->mmi_subs))) {
|
||||
RB_REMOVE(&mmi->mmi_subs, sub, mms_link);
|
||||
free(sub);
|
||||
}
|
||||
} else if (src) {
|
||||
skel.mms_src = src;
|
||||
if ((sub = RB_FIND(&mmi->mmi_subs, &skel, mms_link, mms_cmp))) {
|
||||
RB_REMOVE(&mmi->mmi_subs, sub, mms_link);
|
||||
free(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mpegts_mux_has_subscribers(mm))
|
||||
return;
|
||||
|
||||
mm->mm_display_name(mm, buf, sizeof(buf));
|
||||
tvhdebug("mpegts", "%s - stopping mux", buf);
|
||||
|
@ -442,15 +499,6 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
|
|||
* Scanning
|
||||
* *************************************************************************/
|
||||
|
||||
static int
|
||||
mpegts_mux_has_subscribers ( mpegts_mux_t *mm )
|
||||
{
|
||||
mpegts_mux_instance_t *mmi = mm->mm_active;
|
||||
if (mmi)
|
||||
return mmi->mmi_input->mi_has_subscription(mmi->mmi_input, mm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_mux_initial_scan_link ( mpegts_mux_t *mm )
|
||||
{
|
||||
|
@ -497,10 +545,7 @@ mpegts_mux_initial_scan_done ( mpegts_mux_t *mm )
|
|||
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);
|
||||
}
|
||||
mm->mm_stop(mm, mn, 0);
|
||||
|
||||
/* Save */
|
||||
mm->mm_initial_scan_done = 1;
|
||||
|
|
|
@ -241,7 +241,7 @@ mpegts_network_initial_scan(void *aux)
|
|||
tvhtrace("mpegts", "setup initial scan for %p", mn);
|
||||
while((mm = TAILQ_FIRST(&mn->mn_initial_scan_pending_queue)) != NULL) {
|
||||
assert(mm->mm_initial_scan_status == MM_SCAN_PENDING);
|
||||
if (mm->mm_start(mm, "initial scan", 1))
|
||||
if (mm->mm_start(mm, mn, "initial scan", 1))
|
||||
break;
|
||||
assert(mm->mm_initial_scan_status == MM_SCAN_CURRENT);
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ mpegts_service_start(service_t *t, int instance)
|
|||
return SM_CODE_UNDEFINED_ERROR;
|
||||
|
||||
/* Start Mux */
|
||||
r = mpegts_mux_instance_start(&mmi);
|
||||
r = mpegts_mux_instance_start(&mmi, NULL, 0);
|
||||
|
||||
/* Start */
|
||||
if (!r) {
|
||||
|
@ -200,8 +200,9 @@ mpegts_service_start(service_t *t, int instance)
|
|||
static void
|
||||
mpegts_service_stop(service_t *t)
|
||||
{
|
||||
mpegts_service_t *s = (mpegts_service_t*)t;
|
||||
mpegts_input_t *i = s->s_dvb_active_input;
|
||||
mpegts_service_t *s = (mpegts_service_t*)t;
|
||||
mpegts_mux_t *mm = (mpegts_mux_t*)s->s_dvb_mux;
|
||||
mpegts_input_t *i = s->s_dvb_active_input;
|
||||
|
||||
/* Validate */
|
||||
assert(s->s_source_type == S_MPEG_TS);
|
||||
|
@ -209,6 +210,7 @@ mpegts_service_stop(service_t *t)
|
|||
lock_assert(&global_lock);
|
||||
|
||||
/* Stop */
|
||||
mm->mm_stop(mm, NULL, 0);
|
||||
i->mi_close_service(i, s);
|
||||
s->s_status = SERVICE_IDLE;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue