]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
WEBUI: add "Video codec preset:" menu in Transcoding-Parameters-Stream Profiles trans...
authorSangWoo Kim <saroun74@gmail.com>
Sat, 26 Dec 2015 03:52:30 +0000 (12:52 +0900)
committerJaroslav Kysela <perex@perex.cz>
Sat, 26 Dec 2015 15:54:29 +0000 (16:54 +0100)
src/hts_strtab.h
src/plumbing/transcoding.c
src/plumbing/transcoding.h
src/profile.c

index 93619950664716acaebf22ac16c41d165365b2da..3dcdd80dd95b2e75ffee09ef675548bb91a001c9 100644 (file)
@@ -34,6 +34,11 @@ struct strtab_u32 {
   uint32_t val;
 };
 
+struct strtab_str {
+  const char *str;
+  const char *val;
+};
+
 static int str2val0(const char *str, const struct strtab tab[], int l)
      __attribute((unused));
 
@@ -117,4 +122,20 @@ strtab2htsmsg0_u32(const struct strtab_u32 tab[], uint32_t n, int i18n, const ch
 
 #define strtab2htsmsg_u32(tab,i18n,lang) strtab2htsmsg0_u32(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang)
 
+static inline htsmsg_t *
+strtab2htsmsg0_str(const struct strtab_str tab[], uint32_t n, int i18n, const char *lang)
+{
+  uint32_t i;
+  htsmsg_t *e, *l = htsmsg_create_list();
+  for (i = 0; i < n; i++) {
+    e = htsmsg_create_map();
+    htsmsg_add_str(e, "key", tab[i].val);
+    htsmsg_add_str(e, "val", i18n ? tvh_gettext_lang(lang, tab[i].str) : tab[i].str);
+    htsmsg_add_msg(l, NULL, e);
+  }
+  return l;
+}
+
+#define strtab2htsmsg_str(tab,i18n,lang) strtab2htsmsg0_str(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang)
+
 #endif /* STRTAB_H_ */
index a3f1ece651124052f1ff0f0563627f5845aa607e..568f908b1a51f15b22188c69c7ea0578c164a103 100644 (file)
@@ -1331,12 +1331,9 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt)
       octx->flags         |= CODEC_FLAG_GLOBAL_HEADER;
 
       // Default = "medium". We gain more encoding speed compared to the loss of quality when lowering it _slightly_.
-      if (!strcmp(ocodec->name, "nvenc"))
-         av_dict_set(&opts, "preset",  "hq", 0);
-      else if (!strcmp(ocodec->name, "h264_qsv"))
-         av_dict_set(&opts, "preset",  "medium", 0);
-      else
-         av_dict_set(&opts, "preset",  "faster", 0);
+      // select preset according to system performance and codec type
+      av_dict_set(&opts, "preset",  t->t_props.tp_vcodec_preset, 0);
+      tvhinfo("transcode", "%04X: Using preset %s", shortid(t), t->t_props.tp_vcodec_preset);
 
       // All modern devices should support "high" profile
       av_dict_set(&opts, "profile", "high", 0);
@@ -1365,7 +1362,10 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt)
       octx->flags         |= CODEC_FLAG_GLOBAL_HEADER;
 
       // on all hardware ultrafast (or maybe superfast) should be safe
-      av_dict_set(&opts, "preset", "ultrafast",  0);
+      // select preset according to system performance
+      av_dict_set(&opts, "preset",  t->t_props.tp_vcodec_preset, 0);
+      tvhinfo("transcode", "%04X: Using preset %s", shortid(t), t->t_props.tp_vcodec_preset);
+
       // disables encoder features which tend to be bottlenecks for the decoder/player
       av_dict_set(&opts, "tune",   "fastdecode", 0);
 
@@ -2065,6 +2065,7 @@ transcoder_set_properties(streaming_target_t *st,
   transcoder_props_t *tp = &t->t_props;
 
   strncpy(tp->tp_vcodec, props->tp_vcodec, sizeof(tp->tp_vcodec)-1);
+  strncpy(tp->tp_vcodec_preset, props->tp_vcodec_preset, sizeof(tp->tp_vcodec_preset)-1);
   strncpy(tp->tp_acodec, props->tp_acodec, sizeof(tp->tp_acodec)-1);
   strncpy(tp->tp_scodec, props->tp_scodec, sizeof(tp->tp_scodec)-1);
   tp->tp_channels   = props->tp_channels;
index 10591a91fa1f5590f6101344bb5607c9cc4c4ea4..9b2871ca7b686ccbd6c7aab580772fe2087094ab 100644 (file)
@@ -22,6 +22,7 @@
 
 typedef struct transcoder_prop {
   char     tp_vcodec[32];
+  char     tp_vcodec_preset[32];
   char     tp_acodec[32];
   char     tp_scodec[32];
 
index 4d3423316c3983a3d64771dc44a9d0f9be99c92f..47483c45dcf2a405c51b9a102903c1943f1d8cd2 100644 (file)
@@ -1414,6 +1414,7 @@ typedef struct profile_transcode {
   uint32_t pro_abitrate;
   char    *pro_language;
   char    *pro_vcodec;
+  char    *pro_vcodec_preset;
   char    *pro_acodec;
   char    *pro_scodec;
 } profile_transcode_t;
@@ -1539,6 +1540,31 @@ profile_class_vcodec_list(void *o, const char *lang)
   return profile_class_codec_list(profile_class_vcodec_sct_check, lang);
 }
 
+static htsmsg_t *
+profile_class_vcodec_preset_list(void *o, const char *lang)
+{
+  static const struct strtab_str tab[] = {
+    {N_("ultrafast: h264 / h265")           , "ultrafast" },
+    {N_("superfast: h264 / h265")           , "superfast" },
+    {N_("veryfast: h264 / h265 / qsv(h264)")        , "veryfast"  },
+    {N_("faster: h264 / h265 / qsv(h264)")          , "faster"    },
+    {N_("fast: h264 / h265 / qsv(h264 / h265)")             , "fast"      },
+    {N_("medium: h264 / h265 / qsv(h264 / h265)")           , "medium"    },
+    {N_("slow: h264 / h265 / qsv(h264 / h265)")             , "slow"      },
+    {N_("slower: h264 / h265 / qsv(h264)")          , "slower"    },
+    {N_("veryslow: h264 / h265 / qsv(h264)")        , "veryslow"  },
+    {N_("placebo: h264 / h265")             , "placebo"   },
+    {N_("hq: nvenc(h264 / h265)")           , "hq"        },
+    {N_("hp: nvenc(h264 / h265)")           , "hp"        },
+    {N_("bd: nvenc(h264 / h265)")           , "bd"        },
+    {N_("ll: nvenc(h264 / h265)")           , "ll"        },
+    {N_("llhq: nvenc(h264 / h265)")     , "llhq"      },
+    {N_("llhp: nvenc(h264 / h265)")     , "llhp"      },
+    {N_("default: nvenc(h264 / h265)")  , "default"   }
+  };
+  return strtab2htsmsg_str(tab, 1, lang);
+}
+
 static int
 profile_class_acodec_sct_check(int sct)
 {
@@ -1626,6 +1652,16 @@ const idclass_t profile_transcode_class =
       .opts     = PO_ADVANCED,
       .group    = 2
     },
+    {
+      .type     = PT_STR,
+      .id       = "vcodec_preset",
+      .name     = N_("Video codec preset"),
+      .off      = offsetof(profile_transcode_t, pro_vcodec_preset),
+      .def.s    = "faster",
+      .list     = profile_class_vcodec_preset_list,
+      .opts     = PO_ADVANCED,
+      .group    = 2
+    },
     {
       .type     = PT_U32,
       .id       = "vbitrate",
@@ -1703,6 +1739,8 @@ profile_transcode_can_share(profile_chain_t *prch,
    */
   if (strcmp(pro1->pro_vcodec ?: "", pro2->pro_vcodec ?: ""))
     return 0;
+  if (strcmp(pro1->pro_vcodec_preset ?: "", pro2->pro_vcodec_preset ?: ""))
+    return 0;
   if (strcmp(pro1->pro_acodec ?: "", pro2->pro_acodec ?: ""))
     return 0;
   if (strcmp(pro1->pro_scodec ?: "", pro2->pro_scodec ?: ""))
@@ -1735,6 +1773,7 @@ profile_transcode_work(profile_chain_t *prch,
 
   memset(&props, 0, sizeof(props));
   strncpy(props.tp_vcodec, pro->pro_vcodec ?: "", sizeof(props.tp_vcodec)-1);
+  strncpy(props.tp_vcodec_preset, pro->pro_vcodec_preset ?: "", sizeof(props.tp_vcodec_preset)-1);
   strncpy(props.tp_acodec, pro->pro_acodec ?: "", sizeof(props.tp_acodec)-1);
   strncpy(props.tp_scodec, pro->pro_scodec ?: "", sizeof(props.tp_scodec)-1);
   props.tp_resolution = profile_transcode_resolution(pro);
@@ -1836,6 +1875,7 @@ profile_transcode_free(profile_t *_pro)
 {
   profile_transcode_t *pro = (profile_transcode_t *)_pro;
   free(pro->pro_vcodec);
+  free(pro->pro_vcodec_preset);
   free(pro->pro_acodec);
   free(pro->pro_scodec);
 }
@@ -1960,6 +2000,7 @@ profile_init(void)
     htsmsg_add_u32 (conf, "resolution", 384);
     htsmsg_add_u32 (conf, "channels", 2);
     htsmsg_add_str (conf, "vcodec", "libvpx");
+    htsmsg_add_str (conf, "vcodec_preset", "faster");
     htsmsg_add_str (conf, "acodec", "libvorbis");
     htsmsg_add_bool(conf, "shield", 1);
     (void)profile_create(NULL, conf, 1);
@@ -1980,6 +2021,7 @@ profile_init(void)
     htsmsg_add_u32 (conf, "resolution", 384);
     htsmsg_add_u32 (conf, "channels", 2);
     htsmsg_add_str (conf, "vcodec", "libx264");
+    htsmsg_add_str (conf, "vcodec_preset", "faster");
     htsmsg_add_str (conf, "acodec", "aac");
     htsmsg_add_bool(conf, "shield", 1);
     (void)profile_create(NULL, conf, 1);
@@ -2000,6 +2042,7 @@ profile_init(void)
     htsmsg_add_u32 (conf, "resolution", 384);
     htsmsg_add_u32 (conf, "channels", 2);
     htsmsg_add_str (conf, "vcodec", "libx264");
+    htsmsg_add_str (conf, "vcodec_preset", "faster");
     htsmsg_add_str (conf, "acodec", "aac");
     htsmsg_add_bool(conf, "shield", 1);
     (void)profile_create(NULL, conf, 1);