]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
profile: add priority settings, fixes #2783
authorJaroslav Kysela <perex@perex.cz>
Fri, 24 Apr 2015 10:56:38 +0000 (12:56 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 24 Apr 2015 10:57:04 +0000 (12:57 +0200)
src/config.c
src/dvr/dvr_rec.c
src/htsp_server.c
src/profile.c
src/profile.h
src/subscriptions.c
src/webui/webui.c

index bb98b140ed0279087c31f14947175f6e772c9649..a56ca7c4da6f54cbd6d4e7b278b5344848e5dcdc 100644 (file)
@@ -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
 };
 
 /*
index a8377f0872d3d25e33355a389b8e976a81ce05a5..708a708aeae46d1576b194ef022fb6c2140c7921 100644 (file)
@@ -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;
index b19d34ef96b9942a9f084eb47a4d3379fe5ca789..af234b38723215d11404c42a211e4503ff9ef9fc 100644 (file)
@@ -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");
index 594f177a24c0b0d1d796c0e548efff0d32edc3c3..870bff22473802d0a456b5582098bf1d35bd45f9 100644 (file)
@@ -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);
index e499642298d5b9466ef10044f54048ff2f56ec14..b0d4270a337a0eb67641b8e80b04f57dd94bf39a 100644 (file)
 #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); }
index c3a83dcdcc9b5b3f59b89d15c36875b47f746711..56415a561aaaf54a0569d44fe914363322e4761f 100644 (file)
@@ -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;
 
index 80a8eb65dfc1d012690fd3d59f2cc38f8fba74ae..4c4bbed622b9069166142ce2f45012f3b086f41b 100644 (file)
@@ -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"),