From c649ef2bdfa71a662e2685a385443f3c2cfd46e6 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 24 Apr 2015 12:56:38 +0200 Subject: [PATCH] profile: add priority settings, fixes #2783 --- src/config.c | 25 +++++++++++++- src/dvr/dvr_rec.c | 2 +- src/htsp_server.c | 2 +- src/profile.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ src/profile.h | 17 ++++++++++ src/subscriptions.c | 4 ++- src/webui/webui.c | 4 +-- 7 files changed, 130 insertions(+), 6 deletions(-) diff --git a/src/config.c b/src/config.c index bb98b140e..a56ca7c4d 100644 --- a/src/config.c +++ b/src/config.c @@ -27,6 +27,7 @@ #include "htsbuf.h" #include "spawn.h" #include "lock.h" +#include "profile.h" /* ************************************************************************* * Global data @@ -1163,6 +1164,27 @@ config_migrate_v16 ( void ) } } +static void +config_migrate_v17 ( void ) +{ + htsmsg_t *c, *e; + htsmsg_field_t *f; + int i, p; + + if ((c = hts_settings_load("profile")) != NULL) { + HTSMSG_FOREACH(f, c) { + if (!(e = htsmsg_field_get_map(f))) continue; + if (htsmsg_get_s32(e, "priority", &i)) { + p = PROFILE_SPRIO_NORMAL; + if (strcmp(htsmsg_get_str(e, "name") ?: "", "htsp") == 0) + p = PROFILE_SPRIO_IMPORTANT; + htsmsg_set_s32(e, "priority", p); + hts_settings_save(e, "profile/%s", f->hmf_name); + } + } + } +} + /* * Perform backup */ @@ -1272,7 +1294,8 @@ static const config_migrate_t config_migrate_table[] = { config_migrate_v13, config_migrate_v14, config_migrate_v15, - config_migrate_v16 + config_migrate_v16, + config_migrate_v17 }; /* diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index a8377f087..708a708ae 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -69,7 +69,7 @@ dvr_rec_subscribe(dvr_entry_t *de) assert(de->de_s == NULL); assert(de->de_chain == NULL); - if(de->de_pri < ARRAY_SIZE(prio2weight)) + if(de->de_pri > 0 && de->de_pri < ARRAY_SIZE(prio2weight)) weight = prio2weight[de->de_pri]; else weight = 300; diff --git a/src/htsp_server.c b/src/htsp_server.c index b19d34ef9..af234b387 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -1962,7 +1962,7 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) if (!htsp_user_access_channel(htsp, ch)) return htsp_error("User does not have access"); - weight = htsmsg_get_u32_or_default(in, "weight", 150); + weight = htsmsg_get_u32_or_default(in, "weight", 0); req90khz = htsmsg_get_u32_or_default(in, "90khz", 0); profile_id = htsmsg_get_str(in, "profile"); diff --git a/src/profile.c b/src/profile.c index 594f177a2..870bff224 100644 --- a/src/profile.c +++ b/src/profile.c @@ -32,6 +32,8 @@ #endif #include "dvr/dvr.h" +extern const idclass_t profile_htsp_class; + profile_builders_queue profile_builders; struct profile_entry_queue profiles; @@ -236,6 +238,25 @@ profile_class_name_opts(void *o) return r; } +static htsmsg_t * +profile_class_priority_list ( void *o ) +{ + static const struct strtab tab[] = { + { "Unset (default)", PROFILE_SPRIO_NOTSET }, + { "Important", PROFILE_SPRIO_IMPORTANT }, + { "High", PROFILE_SPRIO_HIGH, }, + { "Normal", PROFILE_SPRIO_NORMAL }, + { "Low", PROFILE_SPRIO_LOW }, + { "Unimportant", PROFILE_SPRIO_UNIMPORTANT }, + { "DVR Override Important", PROFILE_SPRIO_DVR_IMPORTANT }, + { "DVR Override High", PROFILE_SPRIO_DVR_HIGH }, + { "DVR Override Normal", PROFILE_SPRIO_DVR_NORMAL }, + { "DVR Override Low", PROFILE_SPRIO_DVR_LOW }, + { "DVR Override Unimportant", PROFILE_SPRIO_DVR_UNIMPORTANT }, + }; + return strtab2htsmsg(tab); +} + const idclass_t profile_class = { .ic_class = "profile", @@ -282,6 +303,21 @@ const idclass_t profile_class = .name = "Comment", .off = offsetof(profile_t, pro_comment), }, + { + .type = PT_INT, + .id = "priority", + .name = "Default Priority", + .list = profile_class_priority_list, + .off = offsetof(profile_t, pro_prio), + .opts = PO_SORTKEY, + .def.i = PROFILE_SPRIO_NORMAL + }, + { + .type = PT_BOOL, + .id = "fpriority", + .name = "Force Priority", + .off = offsetof(profile_t, pro_fprio), + }, { .type = PT_INT, .id = "timeout", @@ -747,6 +783,44 @@ profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer) return 0; } +/* + * + */ + +const static int prio2weight[] = { + [PROFILE_SPRIO_DVR_IMPORTANT] = 525, + [PROFILE_SPRIO_DVR_HIGH] = 425, + [PROFILE_SPRIO_DVR_NORMAL] = 325, + [PROFILE_SPRIO_DVR_LOW] = 225, + [PROFILE_SPRIO_DVR_UNIMPORTANT] = 175, + [PROFILE_SPRIO_IMPORTANT] = 150, + [PROFILE_SPRIO_HIGH] = 125, + [PROFILE_SPRIO_NORMAL] = 100, + [PROFILE_SPRIO_LOW] = 75, + [PROFILE_SPRIO_UNIMPORTANT] = 50, + [PROFILE_SPRIO_NOTSET] = 0 +}; + +int profile_chain_weight(profile_chain_t *prch, int custom) +{ + int w, w2; + + w = 100; + if (prch->prch_pro) { + if (!prch->prch_pro->pro_fprio && custom > 0) + return custom; + if (idnode_is_instance(&prch->prch_pro->pro_id, &profile_htsp_class)) + w = 150; + w2 = prch->prch_pro->pro_prio; + if (w2 > 0 && w2 < ARRAY_SIZE(prio2weight)) + w = prio2weight[w2]; + } else { + if (custom > 0) + return custom; + } + return w; +} + /* * */ @@ -1673,8 +1747,11 @@ profile_init(void) htsmsg_add_bool(conf, "default", 1); htsmsg_add_str (conf, "name", name); htsmsg_add_str (conf, "comment", "MPEG-TS Pass-through"); + htsmsg_add_s32 (conf, "priority", PROFILE_SPRIO_NORMAL); htsmsg_add_bool(conf, "rewrite_pmt", 1); htsmsg_add_bool(conf, "rewrite_pat", 1); + htsmsg_add_bool(conf, "rewrite_sdt", 1); + htsmsg_add_bool(conf, "rewrite_eit", 1); htsmsg_add_bool(conf, "shield", 1); (void)profile_create(NULL, conf, 1); htsmsg_destroy(conf); @@ -1690,6 +1767,7 @@ profile_init(void) htsmsg_add_bool(conf, "enabled", 1); htsmsg_add_str (conf, "name", name); htsmsg_add_str (conf, "comment", "Matroska"); + htsmsg_add_s32 (conf, "priority", PROFILE_SPRIO_NORMAL); htsmsg_add_bool(conf, "shield", 1); (void)profile_create(NULL, conf, 1); htsmsg_destroy(conf); @@ -1705,6 +1783,7 @@ profile_init(void) htsmsg_add_bool(conf, "enabled", 1); htsmsg_add_str (conf, "name", name); htsmsg_add_str (conf, "comment", "HTSP Default Stream Settings"); + htsmsg_add_s32 (conf, "priority", PROFILE_SPRIO_IMPORTANT); htsmsg_add_bool(conf, "shield", 1); (void)profile_create(NULL, conf, 1); htsmsg_destroy(conf); @@ -1722,6 +1801,7 @@ profile_init(void) htsmsg_add_bool(conf, "enabled", 1); htsmsg_add_str (conf, "name", name); htsmsg_add_str (conf, "comment", "WEBTV profile VP8/Vorbis/WEBM"); + htsmsg_add_s32 (conf, "priority", PROFILE_SPRIO_NORMAL); htsmsg_add_s32 (conf, "container", MC_WEBM); htsmsg_add_u32 (conf, "resolution", 384); htsmsg_add_u32 (conf, "channels", 2); @@ -1741,6 +1821,7 @@ profile_init(void) htsmsg_add_bool(conf, "enabled", 1); htsmsg_add_str (conf, "name", name); htsmsg_add_str (conf, "comment", "WEBTV profile H264/AAC/MPEG-TS"); + htsmsg_add_s32 (conf, "priority", PROFILE_SPRIO_NORMAL); htsmsg_add_s32 (conf, "container", MC_MPEGTS); htsmsg_add_u32 (conf, "resolution", 384); htsmsg_add_u32 (conf, "channels", 2); @@ -1760,6 +1841,7 @@ profile_init(void) htsmsg_add_bool(conf, "enabled", 1); htsmsg_add_str (conf, "name", name); htsmsg_add_str (conf, "comment", "WEBTV profile H264/AAC/Matroska"); + htsmsg_add_s32 (conf, "priority", PROFILE_SPRIO_NORMAL); htsmsg_add_s32 (conf, "container", MC_MATROSKA); htsmsg_add_u32 (conf, "resolution", 384); htsmsg_add_u32 (conf, "channels", 2); diff --git a/src/profile.h b/src/profile.h index e49964229..b0d4270a3 100644 --- a/src/profile.h +++ b/src/profile.h @@ -23,6 +23,20 @@ #include "idnode.h" #include "muxer.h" +typedef enum { + PROFILE_SPRIO_NOTSET = 0, + PROFILE_SPRIO_IMPORTANT, + PROFILE_SPRIO_HIGH, + PROFILE_SPRIO_NORMAL, + PROFILE_SPRIO_LOW, + PROFILE_SPRIO_UNIMPORTANT, + PROFILE_SPRIO_DVR_IMPORTANT, + PROFILE_SPRIO_DVR_HIGH, + PROFILE_SPRIO_DVR_NORMAL, + PROFILE_SPRIO_DVR_LOW, + PROFILE_SPRIO_DVR_UNIMPORTANT +} profile_sprio_t; + struct profile; struct muxer; struct streaming_target; @@ -104,6 +118,8 @@ typedef struct profile { int pro_shield; char *pro_name; char *pro_comment; + int pro_prio; + int pro_fprio; int pro_timeout; int pro_restart; @@ -146,6 +162,7 @@ profile_chain_open(profile_chain_t *prch, void profile_chain_init(profile_chain_t *prch, profile_t *pro, void *id); int profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer); void profile_chain_close(profile_chain_t *prch); +int profile_chain_weight(profile_chain_t *prch, int custom); static inline profile_t *profile_find_by_uuid(const char *uuid) { return (profile_t*)idnode_find(uuid, &profile_class, NULL); } diff --git a/src/subscriptions.c b/src/subscriptions.c index c3a83dcdc..56415a561 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -641,7 +641,6 @@ subscription_create streaming_target_init(&s->ths_input, cb, s, reject); s->ths_prch = prch && prch->prch_st ? prch : NULL; - s->ths_weight = weight; s->ths_title = strdup(name); s->ths_hostname = hostname ? strdup(hostname) : NULL; s->ths_username = username ? strdup(username) : NULL; @@ -653,6 +652,9 @@ subscription_create s->ths_postpone = subscription_postpone; s->ths_postpone_end = dispatch_clock + s->ths_postpone; + if (s->ths_prch) + s->ths_weight = profile_chain_weight(s->ths_prch, weight); + if (pro && pro->pro_restart) s->ths_flags |= SUBSCRIPTION_RESTART; diff --git a/src/webui/webui.c b/src/webui/webui.c index 80a8eb65d..4c4bbed62 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -766,7 +766,7 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight) profile_chain_init(&prch, pro, service); if (!profile_chain_open(&prch, NULL, 0, qsize)) { - s = subscription_create_from_service(&prch, NULL, weight ?: 100, "HTTP", + s = subscription_create_from_service(&prch, NULL, weight, "HTTP", prch.prch_flags | SUBSCRIPTION_STREAMING, hc->hc_peer_ipstr, hc->hc_username, @@ -904,7 +904,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight) if (!profile_chain_open(&prch, NULL, 0, qsize)) { s = subscription_create_from_channel(&prch, - NULL, weight ?: 100, "HTTP", + NULL, weight, "HTTP", prch.prch_flags | SUBSCRIPTION_STREAMING, hc->hc_peer_ipstr, hc->hc_username, http_arg_get(&hc->hc_args, "User-Agent"), -- 2.47.2