Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
WEBUI: add "Video codec preset:" menu in Transcoding-Parameters-Strea…
…m Profiles transcoding: use user selected video codec preset for H264,H265,qsv,nvenc transcoding
  • Loading branch information
saroun74 authored and perexg committed Dec 26, 2015
1 parent fb2d274 commit 4507ae2
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 7 deletions.
21 changes: 21 additions & 0 deletions src/hts_strtab.h
Expand Up @@ -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));

Expand Down Expand Up @@ -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_ */
15 changes: 8 additions & 7 deletions src/plumbing/transcoding.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/plumbing/transcoding.h
Expand Up @@ -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];

Expand Down
43 changes: 43 additions & 0 deletions src/profile.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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 ?: ""))
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 4507ae2

Please sign in to comment.