profile, transcode: move transcode config to profiles, add new profile type
This commit is contained in:
parent
24818812ff
commit
811191c862
9 changed files with 381 additions and 153 deletions
|
@ -34,9 +34,6 @@
|
|||
#if ENABLE_TIMESHIFT
|
||||
#include "timeshift.h"
|
||||
#endif
|
||||
#if ENABLE_LIBAV
|
||||
#include "plumbing/transcoding.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
@ -193,9 +190,8 @@ typedef struct htsp_subscription {
|
|||
streaming_target_t *hs_tshift;
|
||||
#endif
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
streaming_target_t *hs_transcoder;
|
||||
#endif
|
||||
streaming_target_t *hs_work;
|
||||
void (*hs_work_destroy)(streaming_target_t *);
|
||||
|
||||
htsp_msg_q_t hs_q;
|
||||
|
||||
|
@ -340,10 +336,8 @@ htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs)
|
|||
if(hs->hs_tsfix != NULL)
|
||||
tsfix_destroy(hs->hs_tsfix);
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
if(hs->hs_transcoder != NULL)
|
||||
transcoder_destroy(hs->hs_transcoder);
|
||||
#endif
|
||||
if(hs->hs_work != NULL)
|
||||
hs->hs_work_destroy(hs->hs_work);
|
||||
|
||||
#if ENABLE_TIMESHIFT
|
||||
if(hs->hs_tshift)
|
||||
|
@ -1763,27 +1757,13 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
#endif
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
if (transcoding_enabled) {
|
||||
transcoder_props_t props;
|
||||
const char *profile_id = htsmsg_get_str(in, "profile");
|
||||
profile_t *pro = profile_find_by_uuid(profile_id) ?: profile_find_by_name(profile_id);
|
||||
|
||||
props.tp_vcodec = streaming_component_txt2type(htsmsg_get_str(in, "videoCodec"));
|
||||
props.tp_acodec = streaming_component_txt2type(htsmsg_get_str(in, "audioCodec"));
|
||||
props.tp_scodec = streaming_component_txt2type(htsmsg_get_str(in, "subtitleCodec"));
|
||||
|
||||
props.tp_resolution = htsmsg_get_u32_or_default(in, "maxResolution", 0);
|
||||
props.tp_channels = htsmsg_get_u32_or_default(in, "channels", 0);
|
||||
props.tp_bandwidth = htsmsg_get_u32_or_default(in, "bandwidth", 0);
|
||||
|
||||
if ((str = htsmsg_get_str(in, "language")))
|
||||
strncpy(props.tp_language, str, 3);
|
||||
|
||||
if(props.tp_vcodec != SCT_UNKNOWN ||
|
||||
props.tp_acodec != SCT_UNKNOWN ||
|
||||
props.tp_scodec != SCT_UNKNOWN) {
|
||||
st = hs->hs_transcoder = transcoder_create(st);
|
||||
transcoder_set_properties(st, &props);
|
||||
normts = 1;
|
||||
}
|
||||
hs->hs_work = profile_work(pro, st, &hs->hs_work_destroy);
|
||||
if (hs->hs_work) {
|
||||
st = hs->hs_work;
|
||||
normts = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2142,27 +2122,23 @@ htsp_method_file_seek(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
return rep;
|
||||
}
|
||||
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static htsmsg_t *
|
||||
htsp_method_getCodecs(htsp_connection_t *htsp, htsmsg_t *in)
|
||||
htsp_method_getProfiles(htsp_connection_t *htsp, htsmsg_t *in)
|
||||
{
|
||||
htsmsg_t *out, *l;
|
||||
|
||||
l = htsmsg_create_list();
|
||||
transcoder_get_capabilities(l);
|
||||
profile_get_htsp_list(l);
|
||||
|
||||
out = htsmsg_create_map();
|
||||
|
||||
htsmsg_add_msg(out, "encoders", l);
|
||||
htsmsg_add_msg(out, "profiles", l);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* HTSP methods
|
||||
|
@ -2198,9 +2174,7 @@ struct {
|
|||
{ "subscriptionSpeed", htsp_method_speed, ACCESS_STREAMING},
|
||||
{ "subscriptionLive", htsp_method_live, ACCESS_STREAMING},
|
||||
{ "subscriptionFilterStream", htsp_method_filter_stream, ACCESS_STREAMING},
|
||||
#if ENABLE_LIBAV
|
||||
{ "getCodecs", htsp_method_getCodecs, ACCESS_STREAMING},
|
||||
#endif
|
||||
{ "getProfiles", htsp_method_getProfiles, ACCESS_STREAMING},
|
||||
{ "fileOpen", htsp_method_file_open, ACCESS_RECORDER},
|
||||
{ "fileRead", htsp_method_file_read, ACCESS_RECORDER},
|
||||
{ "fileClose", htsp_method_file_close, ACCESS_RECORDER},
|
||||
|
|
|
@ -147,9 +147,6 @@ const tvh_caps_t tvheadend_capabilities[] = {
|
|||
#if ENABLE_SATIP_CLIENT
|
||||
{ "satip_client", NULL },
|
||||
#endif
|
||||
#if ENABLE_LIBAV
|
||||
{ "transcoding", &transcoding_enabled },
|
||||
#endif
|
||||
#if ENABLE_IMAGECACHE
|
||||
{ "imagecache", (uint32_t*)&imagecache_conf.enabled },
|
||||
#endif
|
||||
|
|
|
@ -1321,12 +1321,12 @@ transcoder_destroy(streaming_target_t *st)
|
|||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
transcoder_get_capabilities(htsmsg_t *array)
|
||||
htsmsg_t *
|
||||
transcoder_get_capabilities(void)
|
||||
{
|
||||
AVCodec *p = NULL;
|
||||
const char *name;
|
||||
streaming_component_type_t sct;
|
||||
htsmsg_t *array = htsmsg_create_list();
|
||||
|
||||
while ((p = av_codec_next(p))) {
|
||||
|
||||
|
@ -1340,9 +1340,9 @@ transcoder_get_capabilities(htsmsg_t *array)
|
|||
if (sct == SCT_NONE)
|
||||
continue;
|
||||
|
||||
name = streaming_component_type2txt(sct);
|
||||
htsmsg_add_str(array, NULL, name);
|
||||
htsmsg_add_s32(array, NULL, sct);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ extern uint32_t transcoding_enabled;
|
|||
streaming_target_t *transcoder_create (streaming_target_t *output);
|
||||
void transcoder_destroy(streaming_target_t *tr);
|
||||
|
||||
void transcoder_get_capabilities(htsmsg_t *array);
|
||||
htsmsg_t *transcoder_get_capabilities(void);
|
||||
void transcoder_set_properties (streaming_target_t *tr,
|
||||
transcoder_props_t *prop);
|
||||
|
||||
|
|
344
src/profile.c
344
src/profile.c
|
@ -22,6 +22,10 @@
|
|||
#include "streaming.h"
|
||||
#include "plumbing/tsfix.h"
|
||||
#include "plumbing/globalheaders.h"
|
||||
#if ENABLE_LIBAV
|
||||
#include "lang_codes.h"
|
||||
#include "plumbing/transcoding.h"
|
||||
#endif
|
||||
#include "dvr/dvr.h"
|
||||
|
||||
profile_builders_queue profile_builders;
|
||||
|
@ -300,6 +304,26 @@ profile_class_get_list(void *o)
|
|||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void
|
||||
profile_get_htsp_list(htsmsg_t *array)
|
||||
{
|
||||
profile_t *pro;
|
||||
htsmsg_t *m;
|
||||
|
||||
TAILQ_FOREACH(pro, &profiles, pro_link) {
|
||||
if (pro->pro_work) {
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&pro->pro_id));
|
||||
htsmsg_add_str(m, "name", pro->pro_name ?: "");
|
||||
htsmsg_add_str(m, "comment", pro->pro_comment ?: "");
|
||||
htsmsg_add_msg(array, NULL, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -328,6 +352,10 @@ profile_chain_close(profile_chain_t *prch)
|
|||
tsfix_destroy(prch->prch_tsfix);
|
||||
if (prch->prch_gh)
|
||||
globalheaders_destroy(prch->prch_gh);
|
||||
#if ENABLE_LIBAV
|
||||
if (prch->prch_transcoder != NULL)
|
||||
transcoder_destroy(prch->prch_transcoder);
|
||||
#endif
|
||||
if (prch->prch_muxer)
|
||||
muxer_destroy(prch->prch_muxer);
|
||||
streaming_queue_deinit(&prch->prch_sq);
|
||||
|
@ -473,6 +501,319 @@ profile_matroska_builder(void)
|
|||
return (profile_t *)pro;
|
||||
}
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
|
||||
/*
|
||||
* Transcoding + packet-like muxers
|
||||
*/
|
||||
typedef struct profile_transcode {
|
||||
profile_t;
|
||||
int pro_mc;
|
||||
uint32_t pro_resolution;
|
||||
uint32_t pro_channels;
|
||||
uint32_t pro_bandwidth;
|
||||
char *pro_language;
|
||||
int pro_vcodec;
|
||||
int pro_acodec;
|
||||
int pro_scodec;
|
||||
} profile_transcode_t;
|
||||
|
||||
static htsmsg_t *
|
||||
profile_class_mc_list ( void *o )
|
||||
{
|
||||
static const struct strtab tab[] = {
|
||||
{ "Not set", MC_UNKNOWN },
|
||||
{ "Matroska (mkv)", MC_MATROSKA, },
|
||||
{ "WEBM", MC_WEBM, },
|
||||
{ "MPEG-TS", MC_MPEGTS },
|
||||
{ "MPEG-PS (DVD)", MC_MPEGPS },
|
||||
};
|
||||
return strtab2htsmsg(tab);
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
profile_class_channels_list ( void *o )
|
||||
{
|
||||
static const struct strtab tab[] = {
|
||||
{ "Copy layout", 0 },
|
||||
{ "Mono", 1 },
|
||||
{ "Stereo", 2 },
|
||||
{ "Surround (2 Front, Rear Mono)", 3 },
|
||||
{ "Quad (4.0)", 4 },
|
||||
{ "5.0", 5 },
|
||||
{ "5.1", 6 },
|
||||
{ "6.1", 7 },
|
||||
{ "7.1", 8 }
|
||||
};
|
||||
return strtab2htsmsg(tab);
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
profile_class_language_list(void *o)
|
||||
{
|
||||
htsmsg_t *l = htsmsg_create_list();
|
||||
const lang_code_t *lc = lang_codes;
|
||||
char buf[128];
|
||||
|
||||
while (lc->code2b) {
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
if (!strcmp(lc->code2b, "und")) {
|
||||
htsmsg_add_str(e, "key", "");
|
||||
htsmsg_add_str(e, "val", "Use original");
|
||||
} else {
|
||||
htsmsg_add_str(e, "key", lc->code2b);
|
||||
snprintf(buf, sizeof(buf), "%s (%s)", lc->desc, lc->code2b);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
htsmsg_add_str(e, "val", buf);
|
||||
}
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
lc++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline int
|
||||
profile_class_check_sct(htsmsg_t *c, int sct)
|
||||
{
|
||||
htsmsg_field_t *f;
|
||||
int64_t x;
|
||||
HTSMSG_FOREACH(f, c)
|
||||
if (!htsmsg_field_get_s64(f, &x))
|
||||
if (x == sct)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
profile_class_vcodec_list(void *o)
|
||||
{
|
||||
htsmsg_t *l = htsmsg_create_list(), *e, *c;
|
||||
int i;
|
||||
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", -1);
|
||||
htsmsg_add_str(e, "val", "Do not use");
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", 0);
|
||||
htsmsg_add_str(e, "val", "Copy codec type");
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
c = transcoder_get_capabilities();
|
||||
for (i = 0; i <= SCT_LAST; i++) {
|
||||
if (!SCT_ISVIDEO(i))
|
||||
continue;
|
||||
if (!profile_class_check_sct(c, i))
|
||||
continue;
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_u32(e, "key", i);
|
||||
htsmsg_add_str(e, "val", streaming_component_type2txt(i));
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
}
|
||||
htsmsg_destroy(c);
|
||||
return l;
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
profile_class_acodec_list(void *o)
|
||||
{
|
||||
htsmsg_t *l = htsmsg_create_list(), *e, *c;
|
||||
int i;
|
||||
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", -1);
|
||||
htsmsg_add_str(e, "val", "Do not use");
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", 0);
|
||||
htsmsg_add_str(e, "val", "Copy codec type");
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
c = transcoder_get_capabilities();
|
||||
for (i = 0; i <= SCT_LAST; i++) {
|
||||
if (!SCT_ISAUDIO(i))
|
||||
continue;
|
||||
if (!profile_class_check_sct(c, i))
|
||||
continue;
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", i);
|
||||
htsmsg_add_str(e, "val", streaming_component_type2txt(i));
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
}
|
||||
htsmsg_destroy(c);
|
||||
return l;
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
profile_class_scodec_list(void *o)
|
||||
{
|
||||
htsmsg_t *l = htsmsg_create_list(), *e, *c;
|
||||
int i;
|
||||
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", -1);
|
||||
htsmsg_add_str(e, "val", "Do not use");
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", 0);
|
||||
htsmsg_add_str(e, "val", "Copy codec type");
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
c = transcoder_get_capabilities();
|
||||
for (i = 0; i <= SCT_LAST; i++) {
|
||||
if (!SCT_ISSUBTITLE(i))
|
||||
continue;
|
||||
if (!profile_class_check_sct(c, i))
|
||||
continue;
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_s32(e, "key", i);
|
||||
htsmsg_add_str(e, "val", streaming_component_type2txt(i));
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
}
|
||||
htsmsg_destroy(c);
|
||||
return l;
|
||||
}
|
||||
|
||||
const idclass_t profile_transcode_class =
|
||||
{
|
||||
.ic_super = &profile_class,
|
||||
.ic_class = "profile-transcode",
|
||||
.ic_caption = "Transcode",
|
||||
.ic_properties = (const property_t[]){
|
||||
{
|
||||
.type = PT_INT,
|
||||
.id = "container",
|
||||
.name = "Container",
|
||||
.off = offsetof(profile_transcode_t, pro_mc),
|
||||
.def.i = MC_MATROSKA,
|
||||
.list = profile_class_mc_list,
|
||||
},
|
||||
{
|
||||
.type = PT_U32,
|
||||
.id = "resolution",
|
||||
.name = "Resolution",
|
||||
.off = offsetof(profile_transcode_t, pro_resolution),
|
||||
.def.u32 = 384,
|
||||
},
|
||||
{
|
||||
.type = PT_U32,
|
||||
.id = "channels",
|
||||
.name = "Channels",
|
||||
.off = offsetof(profile_transcode_t, pro_channels),
|
||||
.def.u32 = 2,
|
||||
.list = profile_class_channels_list,
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "language",
|
||||
.name = "Language",
|
||||
.off = offsetof(profile_transcode_t, pro_language),
|
||||
.list = profile_class_language_list,
|
||||
},
|
||||
{
|
||||
.type = PT_INT,
|
||||
.id = "vcodec",
|
||||
.name = "Video Codec",
|
||||
.off = offsetof(profile_transcode_t, pro_vcodec),
|
||||
.def.i = SCT_H264,
|
||||
.list = profile_class_vcodec_list,
|
||||
},
|
||||
{
|
||||
.type = PT_INT,
|
||||
.id = "acodec",
|
||||
.name = "Audio Codec",
|
||||
.off = offsetof(profile_transcode_t, pro_acodec),
|
||||
.def.i = SCT_VORBIS,
|
||||
.list = profile_class_acodec_list,
|
||||
},
|
||||
{
|
||||
.type = PT_INT,
|
||||
.id = "scodec",
|
||||
.name = "Subtitles Codec",
|
||||
.off = offsetof(profile_transcode_t, pro_scodec),
|
||||
.def.i = SCT_NONE,
|
||||
.list = profile_class_scodec_list,
|
||||
},
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
profile_transcode_work_destroy(streaming_target_t *st)
|
||||
{
|
||||
if (st)
|
||||
transcoder_destroy(st);
|
||||
}
|
||||
|
||||
static streaming_target_t *
|
||||
profile_transcode_work(profile_t *_pro, streaming_target_t *src,
|
||||
void (**destroy)(streaming_target_t *st))
|
||||
{
|
||||
profile_transcode_t *pro = (profile_transcode_t *)_pro;
|
||||
transcoder_props_t props;
|
||||
|
||||
memset(&props, 0, sizeof(props));
|
||||
props.tp_vcodec = pro->pro_vcodec;
|
||||
props.tp_acodec = pro->pro_acodec;
|
||||
props.tp_scodec = pro->pro_scodec;
|
||||
props.tp_resolution = pro->pro_resolution >= 240 ? pro->pro_resolution : 240;
|
||||
props.tp_channels = pro->pro_channels;
|
||||
props.tp_bandwidth = pro->pro_bandwidth >= 64 ? pro->pro_bandwidth : 64;
|
||||
strncpy(props.tp_language, pro->pro_language ?: "", 3);
|
||||
|
||||
if (destroy)
|
||||
*destroy = profile_transcode_work_destroy;
|
||||
|
||||
return transcoder_create(src);
|
||||
}
|
||||
|
||||
static int
|
||||
profile_transcode_open(profile_t *_pro, profile_chain_t *prch,
|
||||
muxer_config_t *m_cfg, int flags, size_t qsize)
|
||||
{
|
||||
muxer_config_t c;
|
||||
|
||||
if (m_cfg)
|
||||
c = *m_cfg; /* do not alter the original parameter */
|
||||
else
|
||||
memset(&c, 0, sizeof(c));
|
||||
switch (c.m_type) {
|
||||
case MC_MATROSKA:
|
||||
case MC_WEBM:
|
||||
case MC_MPEGTS:
|
||||
case MC_MPEGPS:
|
||||
break;
|
||||
default:
|
||||
c.m_type = MC_MATROSKA;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(prch, 0, sizeof(*prch));
|
||||
streaming_queue_init(&prch->prch_sq, 0, qsize);
|
||||
prch->prch_transcoder = profile_transcode_work(_pro, &prch->prch_sq.sq_st, NULL);
|
||||
prch->prch_gh = globalheaders_create(prch->prch_transcoder);
|
||||
prch->prch_tsfix = tsfix_create(prch->prch_gh);
|
||||
prch->prch_muxer = muxer_create(&c);
|
||||
prch->prch_st = prch->prch_transcoder;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static muxer_container_type_t
|
||||
profile_transcode_get_mc(profile_t *_pro)
|
||||
{
|
||||
profile_transcode_t *pro = (profile_transcode_t *)_pro;
|
||||
return pro->pro_mc;
|
||||
}
|
||||
|
||||
static profile_t *
|
||||
profile_transcode_builder(void)
|
||||
{
|
||||
profile_transcode_t *pro = calloc(1, sizeof(*pro));
|
||||
pro->pro_work = profile_transcode_work;
|
||||
pro->pro_open = profile_transcode_open;
|
||||
pro->pro_get_mc = profile_transcode_get_mc;
|
||||
return (profile_t *)pro;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_TRANSCODE */
|
||||
|
||||
/*
|
||||
* Initialize
|
||||
*/
|
||||
|
@ -487,6 +828,9 @@ profile_init(void)
|
|||
|
||||
profile_register(&profile_mpegts_pass_class, profile_mpegts_pass_builder);
|
||||
profile_register(&profile_matroska_class, profile_matroska_builder);
|
||||
#if ENABLE_LIBAV
|
||||
profile_register(&profile_transcode_class, profile_transcode_builder);
|
||||
#endif
|
||||
|
||||
if ((c = hts_settings_load("profile")) != NULL) {
|
||||
HTSMSG_FOREACH(f, c) {
|
||||
|
|
|
@ -31,8 +31,6 @@ extern const idclass_t profile_class;
|
|||
extern const idclass_t profile_mpegts_pass_class;
|
||||
extern const idclass_t profile_matroska_class;
|
||||
|
||||
#define PROFILE_TIMESHIFT (1<<0)
|
||||
|
||||
TAILQ_HEAD(profile_entry_queue, profile);
|
||||
|
||||
extern struct profile_entry_queue profiles;
|
||||
|
@ -56,6 +54,9 @@ typedef struct profile_chain {
|
|||
struct muxer *prch_muxer;
|
||||
struct streaming_target *prch_gh;
|
||||
struct streaming_target *prch_tsfix;
|
||||
#if ENABLE_LIBAV
|
||||
struct streaming_target *prch_transcoder;
|
||||
#endif
|
||||
} profile_chain_t;
|
||||
|
||||
typedef struct profile {
|
||||
|
@ -73,6 +74,9 @@ typedef struct profile {
|
|||
void (*pro_conf_changed)(struct profile *pro);
|
||||
muxer_container_type_t (*pro_get_mc)(struct profile *pro);
|
||||
|
||||
struct streaming_target *(*pro_work)(struct profile *pro,
|
||||
struct streaming_target *src,
|
||||
void (**destroy)(struct streaming_target *));
|
||||
int (*pro_open)(struct profile *pro, profile_chain_t *prch,
|
||||
muxer_config_t *m_cfg, int flags, size_t qsize);
|
||||
} profile_t;
|
||||
|
@ -82,6 +86,12 @@ void profile_register(const idclass_t *clazz, profile_builder_t builder);
|
|||
profile_t *profile_create
|
||||
(const char *uuid, htsmsg_t *conf, int save);
|
||||
|
||||
static inline struct streaming_target *
|
||||
profile_work(profile_t *pro, struct streaming_target *src,
|
||||
void (**destroy)(struct streaming_target *st))
|
||||
{ return pro && pro->pro_work ? pro->pro_work(pro, src, destroy) : NULL; }
|
||||
|
||||
|
||||
static inline int
|
||||
profile_chain_open(profile_t *pro, profile_chain_t *prch,
|
||||
muxer_config_t *m_cfg, int flags, size_t qsize)
|
||||
|
@ -102,6 +112,8 @@ const char *profile_get_name(profile_t *pro);
|
|||
static inline muxer_container_type_t profile_get_mc(profile_t *pro)
|
||||
{ return pro->pro_get_mc(pro); }
|
||||
|
||||
void profile_get_htsp_list(htsmsg_t *array);
|
||||
|
||||
void profile_init(void);
|
||||
void profile_done(void);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ tvheadend.miscconf = function(panel, index) {
|
|||
[
|
||||
'muxconfpath', 'language',
|
||||
'tvhtime_update_enabled', 'tvhtime_ntp_enabled',
|
||||
'tvhtime_tolerance', 'transcoding_enabled',
|
||||
'tvhtime_tolerance',
|
||||
'piconpath'
|
||||
]);
|
||||
|
||||
|
@ -203,28 +203,6 @@ tvheadend.miscconf = function(panel, index) {
|
|||
var imagecache_form = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transcoding
|
||||
*/
|
||||
|
||||
var transcodingEnabled = new Ext.form.Checkbox({
|
||||
name: 'transcoding_enabled',
|
||||
fieldLabel: 'Enabled'
|
||||
});
|
||||
|
||||
var transcodingPanel = new Ext.form.FieldSet({
|
||||
title: 'Transcoding',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
animCollapse: true,
|
||||
items: [transcodingEnabled]
|
||||
});
|
||||
|
||||
if (tvheadend.capabilities.indexOf('transcoding') === -1)
|
||||
transcodingPanel.hide();
|
||||
|
||||
|
||||
/* ****************************************************************
|
||||
* Form
|
||||
* ***************************************************************/
|
||||
|
@ -252,7 +230,7 @@ tvheadend.miscconf = function(panel, index) {
|
|||
layout: 'form',
|
||||
defaultType: 'textfield',
|
||||
autoHeight: true,
|
||||
items: [languageWrap, dvbscanWrap, tvhtimePanel, transcodingPanel, piconPanel]
|
||||
items: [languageWrap, dvbscanWrap, tvhtimePanel, piconPanel]
|
||||
});
|
||||
|
||||
var _items = [confpanel];
|
||||
|
|
|
@ -17,6 +17,7 @@ tvheadend.esfilter_tab = function(panel)
|
|||
clazz: 'profile',
|
||||
comet: 'profile',
|
||||
titleS: 'Stream Profile',
|
||||
titleP: 'Stream Profiles',
|
||||
titleC: 'Stream Profile Name',
|
||||
iconCls: 'stream_profile',
|
||||
add: {
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "dvr/dvr.h"
|
||||
#include "filebundle.h"
|
||||
#include "streaming.h"
|
||||
#include "plumbing/transcoding.h"
|
||||
#include "profile.h"
|
||||
#include "epg.h"
|
||||
#include "muxer.h"
|
||||
|
@ -82,63 +81,6 @@ is_client_simple(http_connection_t *hc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
static int
|
||||
http_get_transcoder_properties(struct http_arg_list *args,
|
||||
transcoder_props_t *props)
|
||||
{
|
||||
int transcode;
|
||||
const char *s;
|
||||
|
||||
memset(props, 0, sizeof(transcoder_props_t));
|
||||
|
||||
if ((s = http_arg_get(args, "transcode")))
|
||||
transcode = atoi(s);
|
||||
else
|
||||
transcode = 0;
|
||||
|
||||
if ((s = http_arg_get(args, "resolution")))
|
||||
props->tp_resolution = atoi(s);
|
||||
else
|
||||
props->tp_resolution = 384;
|
||||
|
||||
if ((s = http_arg_get(args, "channels")))
|
||||
props->tp_channels = atoi(s);
|
||||
else
|
||||
props->tp_channels = 0; //same as source
|
||||
|
||||
if ((s = http_arg_get(args, "bandwidth")))
|
||||
props->tp_bandwidth = atoi(s);
|
||||
else
|
||||
props->tp_bandwidth = 0; //same as source
|
||||
|
||||
if ((s = http_arg_get(args, "language")))
|
||||
strncpy(props->tp_language, s, 3);
|
||||
else
|
||||
strncpy(props->tp_language, config_get_language() ?: "", 3);
|
||||
|
||||
if ((s = http_arg_get(args, "vcodec")))
|
||||
props->tp_vcodec = streaming_component_txt2type(s);
|
||||
else
|
||||
props->tp_vcodec = SCT_UNKNOWN;
|
||||
|
||||
if ((s = http_arg_get(args, "acodec")))
|
||||
props->tp_acodec = streaming_component_txt2type(s);
|
||||
else
|
||||
props->tp_acodec = SCT_UNKNOWN;
|
||||
|
||||
if ((s = http_arg_get(args, "scodec")))
|
||||
props->tp_scodec = streaming_component_txt2type(s);
|
||||
else
|
||||
props->tp_scodec = SCT_UNKNOWN;
|
||||
|
||||
return transcode && transcoding_enabled;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Root page, we direct the client to different pages depending
|
||||
* on if it is a full blown browser or just some mobile app
|
||||
|
@ -449,26 +391,6 @@ http_channel_playlist(http_connection_t *hc, channel_t *channel)
|
|||
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
|
||||
access_ticket_create(buf, hc->hc_access));
|
||||
|
||||
#if ENABLE_LIBAV
|
||||
transcoder_props_t props;
|
||||
if(http_get_transcoder_properties(&hc->hc_req_args, &props)) {
|
||||
htsbuf_qprintf(hq, "&transcode=1");
|
||||
if(props.tp_resolution)
|
||||
htsbuf_qprintf(hq, "&resolution=%d", props.tp_resolution);
|
||||
if(props.tp_channels)
|
||||
htsbuf_qprintf(hq, "&channels=%d", props.tp_channels);
|
||||
if(props.tp_bandwidth)
|
||||
htsbuf_qprintf(hq, "&bandwidth=%d", props.tp_bandwidth);
|
||||
if(props.tp_language[0])
|
||||
htsbuf_qprintf(hq, "&language=%s", props.tp_language);
|
||||
if(props.tp_vcodec)
|
||||
htsbuf_qprintf(hq, "&vcodec=%s", streaming_component_type2txt(props.tp_vcodec));
|
||||
if(props.tp_acodec)
|
||||
htsbuf_qprintf(hq, "&acodec=%s", streaming_component_type2txt(props.tp_acodec));
|
||||
if(props.tp_scodec)
|
||||
htsbuf_qprintf(hq, "&scodec=%s", streaming_component_type2txt(props.tp_scodec));
|
||||
}
|
||||
#endif
|
||||
htsbuf_qprintf(hq, "&profile=%s\n", profile);
|
||||
|
||||
http_output_content(hc, "audio/x-mpegurl");
|
||||
|
|
Loading…
Add table
Reference in a new issue