Streaming - add special streaming priority for all inputs (including IPTV)

This commit is contained in:
Jaroslav Kysela 2014-08-11 13:45:28 +02:00
parent eb46c63532
commit 7d8470ba98
20 changed files with 95 additions and 43 deletions

View file

@ -55,5 +55,8 @@
<dt>Priority
<dd>IPTV : The mux priority value (higher value = higher priority to use services from this mux). Value 0 means use the IPTV network priority value.
<dt>Streaming Priority
<dd>IPTV : The mux priority value for streamed channels through HTTP or HTSP (higher value = higher priority to use services from this mux). Value 0 means use the standard streaming network priority value.
</dl>
</div>

View file

@ -49,5 +49,9 @@
<dt>Priority
<dd>IPTV : The network priority value (higher value = higher priority to use muxes/services from this network).
<dt>Streaming Priority
<dd>IPTV : The network priority value for streamed channels through HTTP or HTSP (higher value = higher priority to use muxes/services from this
network). If not set, the standard network priority value is used.
</dl>
</div>

View file

@ -26,6 +26,11 @@
<dd>The tuner priority value (higher value = higher priority to use this
tuner).</dd>
<dt>Streaming Priority</dt>
<dd>The tuner priority value for streamed channels through HTTP or HTSP
(higher value = higher priority to use this tuner). If not set (zero),
the standard priority value is used.</dd>
</dl>
</p>

View file

@ -244,7 +244,7 @@ api_mpegts_service_grid
LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) {
if (hide && !mm->mm_is_enabled(mm)) continue;
LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) {
if (hide == 2 && !ms->s_is_enabled((service_t*)ms)) continue;
if (hide == 2 && !ms->s_is_enabled((service_t*)ms, 0)) continue;
idnode_set_add(ins, (idnode_t*)ms, &conf->filter);
}
}

View file

@ -1545,7 +1545,8 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
tvhdebug("htsp", "%s - subscribe to %s\n", htsp->htsp_logname, ch->ch_name ?: "");
hs->hs_s = subscription_create_from_channel(ch, weight,
htsp->htsp_logname,
st, 0,
st,
SUBSCRIPTION_STREAMING,
htsp->htsp_peername,
htsp->htsp_username,
htsp->htsp_clientname);

View file

@ -395,7 +395,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 (*mm_start) (mpegts_mux_t *mm, 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*);
@ -520,6 +520,7 @@ struct mpegts_input
char *mi_name;
int mi_priority;
int mi_streaming_priority;
int mi_ota_epg;
@ -576,8 +577,8 @@ struct mpegts_input
void (*mi_enabled_updated)(mpegts_input_t*);
void (*mi_display_name) (mpegts_input_t*, char *buf, size_t len);
int (*mi_is_free) (mpegts_input_t*);
int (*mi_get_weight) (mpegts_input_t*);
int (*mi_get_priority) (mpegts_input_t*, mpegts_mux_t *mm);
int (*mi_get_weight) (mpegts_input_t*, int flags);
int (*mi_get_priority) (mpegts_input_t*, mpegts_mux_t *mm, int flags);
int (*mi_get_grace) (mpegts_input_t*, mpegts_mux_t *mm);
int (*mi_start_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
void (*mi_stop_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
@ -752,8 +753,8 @@ void mpegts_input_recv_packets
int mpegts_input_is_free ( mpegts_input_t *mi );
int mpegts_input_get_weight ( mpegts_input_t *mi );
int mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm );
int mpegts_input_get_weight ( mpegts_input_t *mi, int flags );
int mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags );
int mpegts_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm );
void mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *c );

View file

@ -127,7 +127,7 @@ iptv_input_is_free ( mpegts_input_t *mi )
}
static int
iptv_input_get_weight ( mpegts_input_t *mi )
iptv_input_get_weight ( mpegts_input_t *mi, int flags )
{
int c = 0, w = 0;
const th_subscription_t *ths;
@ -170,10 +170,16 @@ iptv_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm )
}
static int
iptv_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm )
iptv_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
{
iptv_mux_t *im = (iptv_mux_t *)mm;
iptv_network_t *in = (iptv_network_t *)im->mm_network;
if (flags & SUBSCRIPTION_STREAMING) {
if (im->mm_iptv_streaming_priority > 0)
return im->mm_iptv_streaming_priority;
if (in->in_streaming_priority > 0)
return in->in_streaming_priority;
}
return im->mm_iptv_priority > 0 ? im->mm_iptv_priority : in->in_priority;
}
@ -412,6 +418,14 @@ const idclass_t iptv_network_class = {
.def.i = 1,
.opts = PO_ADVANCED
},
{
.type = PT_INT,
.id = "spriority",
.name = "Streaming Priority",
.off = offsetof(iptv_network_t, in_streaming_priority),
.def.i = 1,
.opts = PO_ADVANCED
},
{
.type = PT_U32,
.id = "max_streams",
@ -478,6 +492,7 @@ iptv_network_create0
/* Init Network */
in->in_priority = 1;
in->in_streaming_priority = 1;
if (!mpegts_network_create0((mpegts_network_t *)in,
&iptv_network_class,
uuid, NULL, conf)) {

View file

@ -88,6 +88,14 @@ const idclass_t iptv_mux_class =
.def.i = 0,
.opts = PO_ADVANCED
},
{
.type = PT_INT,
.id = "spriority",
.name = "Streaming Priority",
.off = offsetof(iptv_mux_t, mm_iptv_streaming_priority),
.def.i = 0,
.opts = PO_ADVANCED
},
{
.type = PT_STR,
.id = "iptv_url",

View file

@ -65,6 +65,7 @@ struct iptv_network
int in_bw_limited;
int in_priority;
int in_streaming_priority;
uint32_t in_max_streams;
uint32_t in_max_bandwidth;
@ -78,6 +79,7 @@ struct iptv_mux
mpegts_mux_t;
int mm_iptv_priority;
int mm_iptv_streaming_priority;
int mm_iptv_fd;
udp_connection_t *mm_iptv_connection;
char *mm_iptv_url;

View file

@ -223,21 +223,21 @@ linuxdvb_frontend_is_free ( mpegts_input_t *mi )
}
static int
linuxdvb_frontend_get_weight ( mpegts_input_t *mi )
linuxdvb_frontend_get_weight ( mpegts_input_t *mi, int flags )
{
int weight = 0;
linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)mi)->lfe_adapter;
linuxdvb_frontend_t *lfe;
LIST_FOREACH(lfe, &la->la_frontends, lfe_link)
weight = MAX(weight, mpegts_input_get_weight((mpegts_input_t*)lfe));
weight = MAX(weight, mpegts_input_get_weight((mpegts_input_t*)lfe, flags));
return weight;
}
static int
linuxdvb_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm )
linuxdvb_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
int r = mpegts_input_get_priority(mi, mm);
int r = mpegts_input_get_priority(mi, mm, flags);
if (lfe->lfe_satconf)
r += linuxdvb_satconf_get_priority(lfe->lfe_satconf, mm);
return r;

View file

@ -160,6 +160,14 @@ const idclass_t mpegts_input_class =
.def.i = 1,
.opts = PO_ADVANCED
},
{
.type = PT_INT,
.id = "spriority",
.name = "Streaming Priority",
.off = offsetof(mpegts_input_t, mi_streaming_priority),
.def.i = 1,
.opts = PO_ADVANCED
},
{
.type = PT_STR,
.id = "displayname",
@ -221,7 +229,7 @@ mpegts_input_is_free ( mpegts_input_t *mi )
}
int
mpegts_input_get_weight ( mpegts_input_t *mi )
mpegts_input_get_weight ( mpegts_input_t *mi, int flags )
{
const mpegts_mux_instance_t *mmi;
const service_t *s;
@ -249,8 +257,12 @@ mpegts_input_get_weight ( mpegts_input_t *mi )
}
int
mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm )
mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
{
if (flags & SUBSCRIPTION_STREAMING) {
if (mi->mi_streaming_priority > 0)
return mi->mi_streaming_priority;
}
return mi->mi_priority;
}

View file

@ -492,7 +492,7 @@ mpegts_mux_start1( mpegts_mux_instance_t *mmi )
static int
mpegts_mux_start
( mpegts_mux_t *mm, const char *reason, int weight )
( mpegts_mux_t *mm, const char *reason, int weight, int flags )
{
int havefree = 0, enabled = 0, index, index2, weight2, count, size = 0;
char buf[256];
@ -549,8 +549,8 @@ mpegts_mux_start
tvhtrace("mpegts", "%s - found mmi %p", buf, mmi);
aweight = ((int64_t )mmi->mmi_input->mi_get_priority(mmi->mmi_input,
mmi->mmi_mux) << 32) |
mmi->mmi_input->mi_get_weight(mmi->mmi_input);
mmi->mmi_mux, flags) << 32) |
mmi->mmi_input->mi_get_weight(mmi->mmi_input, flags);
for (index = 0; index < count; index++) {
if (allw[index] >= aweight)
break;

View file

@ -164,7 +164,7 @@ const idclass_t mpegts_service_class =
* Check the service is enabled
*/
static int
mpegts_service_is_enabled(service_t *t)
mpegts_service_is_enabled(service_t *t, int flags)
{
mpegts_service_t *s = (mpegts_service_t*)t;
mpegts_mux_t *mm = s->s_dvb_mux;
@ -191,7 +191,7 @@ mpegts_service_config_save ( service_t *t )
* Service instance list
*/
static void
mpegts_service_enlist(service_t *t, struct service_instance_list *sil)
mpegts_service_enlist(service_t *t, struct service_instance_list *sil, int flags)
{
int p = 0, w;
mpegts_service_t *s = (mpegts_service_t*)t;
@ -215,8 +215,8 @@ mpegts_service_enlist(service_t *t, struct service_instance_list *sil)
w = -1;
p = -1;
} else {
w = mmi->mmi_input->mi_get_weight(mmi->mmi_input);
p = mmi->mmi_input->mi_get_priority(mmi->mmi_input, mmi->mmi_mux);
w = mmi->mmi_input->mi_get_weight(mmi->mmi_input, flags);
p = mmi->mmi_input->mi_get_priority(mmi->mmi_input, mmi->mmi_mux, flags);
}
service_instance_add(sil, t, mmi->mmi_input->mi_instance, p, w);

View file

@ -314,16 +314,16 @@ satip_frontend_is_free ( mpegts_input_t *mi )
}
static int
satip_frontend_get_weight ( mpegts_input_t *mi )
satip_frontend_get_weight ( mpegts_input_t *mi, int flags )
{
return mpegts_input_get_weight(mi);
return mpegts_input_get_weight(mi, flags);
}
static int
satip_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm )
satip_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
{
satip_frontend_t *lfe = (satip_frontend_t*)mi;
int r = mpegts_input_get_priority(mi, mm);
int r = mpegts_input_get_priority(mi, mm, flags);
if (lfe->sf_positions)
r += satip_satconf_get_priority(lfe, mm);
return r;

View file

@ -611,7 +611,7 @@ service_start(service_t *t, int instance, int postpone)
service_instance_t *
service_find_instance
(service_t *s, channel_t *ch, service_instance_list_t *sil,
int *error, int weight, int postpone)
int *error, int weight, int flags, int postpone)
{
channel_service_mapping_t *csm;
service_instance_t *si, *next;
@ -626,11 +626,11 @@ service_find_instance
if (ch) {
LIST_FOREACH(csm, &ch->ch_services, csm_chn_link) {
s = csm->csm_svc;
if (s->s_is_enabled(s))
s->s_enlist(s, sil);
if (s->s_is_enabled(s, flags))
s->s_enlist(s, sil, flags);
}
} else {
s->s_enlist(s, sil);
s->s_enlist(s, sil, flags);
}
/* Clean */

View file

@ -271,9 +271,9 @@ typedef struct service {
LIST_HEAD(, th_subscription) s_subscriptions;
int (*s_is_enabled)(struct service *t);
int (*s_is_enabled)(struct service *t, int flags);
void (*s_enlist)(struct service *s, service_instance_list_t *sil);
void (*s_enlist)(struct service *s, service_instance_list_t *sil, int flags);
int (*s_start_feed)(struct service *s, int instance);
@ -469,8 +469,8 @@ service_t *service_find(const char *identifier);
service_instance_t *service_find_instance(struct service *s,
struct channel *ch,
service_instance_list_t *sil,
int *error,
int weight, int postpone);
int *error, int weight,
int flags, int postpone);
elementary_stream_t *service_stream_find_(service_t *t, int pid);

View file

@ -107,7 +107,7 @@ service_mapper_start ( const service_mapper_conf_t *conf, htsmsg_t *uuids )
service_mapper_stat.ignore++;
/* Disabled */
if (!s->s_is_enabled(s)) continue;
if (!s->s_is_enabled(s, 0)) continue;
tvhtrace("service_mapper", " enabled");
/* Get service info */

View file

@ -308,6 +308,7 @@ subscription_reschedule(void)
s->ths_service->s_nicename, s->ths_weight);
si = service_find_instance(s->ths_service, s->ths_channel,
&s->ths_instances, &error, s->ths_weight,
s->ths_flags,
dispatch_clock > s->ths_postpone_end ?
0 : s->ths_postpone_end - dispatch_clock);
s->ths_current_instance = si;
@ -716,7 +717,7 @@ subscription_create_from_mux
int r;
/* Tune */
r = mm->mm_start(mm, name, weight);
r = mm->mm_start(mm, name, weight, flags);
if (r) {
if (err) *err = r;
return NULL;

View file

@ -26,6 +26,7 @@ extern struct th_subscription_list subscriptions;
#define SUBSCRIPTION_RAW_MPEGTS 0x1
#define SUBSCRIPTION_NONE 0x2
#define SUBSCRIPTION_FULLMUX 0x4
#define SUBSCRIPTION_STREAMING 0x8
/* Some internal prioties */
#define SUBSCRIPTION_PRIO_SCAN_IDLE 1 ///< Idle scanning

View file

@ -715,7 +715,7 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight)
streaming_target_t *st;
dvr_config_t *cfg;
muxer_container_type_t mc;
int flags;
int flags = SUBSCRIPTION_STREAMING;
const char *str;
size_t qsize;
const char *name;
@ -739,13 +739,12 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight)
gh = NULL;
tsfix = NULL;
st = &sq.sq_st;
flags = SUBSCRIPTION_RAW_MPEGTS;
flags |= SUBSCRIPTION_RAW_MPEGTS;
} else {
streaming_queue_init2(&sq, 0, qsize);
gh = globalheaders_create(&sq.sq_st);
tsfix = tsfix_create(gh);
st = tsfix;
flags = 0;
}
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrbuf, 50);
@ -794,7 +793,8 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight)
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrbuf, 50);
s = subscription_create_from_mux(mm, weight ?: 10, "HTTP", &sq.sq_st,
SUBSCRIPTION_RAW_MPEGTS |
SUBSCRIPTION_FULLMUX,
SUBSCRIPTION_FULLMUX |
SUBSCRIPTION_STREAMING,
addrbuf, hc->hc_username,
http_arg_get(&hc->hc_args, "User-Agent"), NULL);
if (!s)
@ -826,7 +826,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
streaming_target_t *tr = NULL;
#endif
dvr_config_t *cfg;
int flags;
int flags = SUBSCRIPTION_STREAMING;
muxer_container_type_t mc;
char *str;
size_t qsize;
@ -851,7 +851,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
gh = NULL;
tsfix = NULL;
st = &sq.sq_st;
flags = SUBSCRIPTION_RAW_MPEGTS;
flags |= SUBSCRIPTION_RAW_MPEGTS;
} else {
streaming_queue_init2(&sq, 0, qsize);
gh = globalheaders_create(&sq.sq_st);
@ -865,7 +865,6 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
#endif
tsfix = tsfix_create(gh);
st = tsfix;
flags = 0;
}
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrbuf, 50);