FS-11189 refactor to support any possible codec specific private options
This commit is contained in:
parent
18bcc4ddff
commit
12e3b7177c
|
@ -123,14 +123,15 @@ enum AVColorRange {
|
||||||
-->
|
-->
|
||||||
<param name="color-range" value="2"/>
|
<param name="color-range" value="2"/>
|
||||||
|
|
||||||
<!-- x264 private -->
|
<!-- x264 private options-->
|
||||||
<param name="x264-preset" value="veryfast"/>
|
<options>
|
||||||
<param name="x264-intra-refresh" value="1"/>
|
<option name="preset" value="veryfast"/>
|
||||||
<param name="x264-tune" value="animation+zerolatency"/>
|
<option name="intra_refresh" value="1"/>
|
||||||
<!-- <param name="x264-sc-threshold" value="40"/> -->
|
<option name="tune" value="animation+zerolatency"/>
|
||||||
<!-- <param name="x264-b-strategy" value="1"/> -->
|
<option name="sc_threshold" value="40"/>
|
||||||
<!-- <param name="x264-crf" value="18"/> -->
|
<option name="b_strategy" value="1"/>
|
||||||
|
<option name="crf" value="18"/>
|
||||||
|
</options>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
<profile name="H265">
|
<profile name="H265">
|
||||||
|
|
|
@ -46,6 +46,7 @@ int SLICE_SIZE = SWITCH_DEFAULT_VIDEO_SIZE;
|
||||||
#define KEY_FRAME_MIN_FREQ 250000
|
#define KEY_FRAME_MIN_FREQ 250000
|
||||||
|
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
||||||
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avcodec_shutdown);
|
||||||
|
|
||||||
/* ff_avc_find_startcode is not exposed in the ffmpeg lib but you can use it
|
/* ff_avc_find_startcode is not exposed in the ffmpeg lib but you can use it
|
||||||
Either include the avc.h which available in the ffmpeg source, or
|
Either include the avc.h which available in the ffmpeg source, or
|
||||||
|
@ -202,14 +203,7 @@ typedef struct avcodec_profile_s {
|
||||||
char name[20];
|
char name[20];
|
||||||
int decoder_thread_count;
|
int decoder_thread_count;
|
||||||
AVCodecContext ctx;
|
AVCodecContext ctx;
|
||||||
struct {
|
switch_event_t *options;
|
||||||
char preset[20];
|
|
||||||
char tune[64];
|
|
||||||
int intra_refresh;
|
|
||||||
int sc_threshold;
|
|
||||||
int b_strategy;
|
|
||||||
int crf;
|
|
||||||
} x264;
|
|
||||||
} avcodec_profile_t;
|
} avcodec_profile_t;
|
||||||
|
|
||||||
struct avcodec_globals {
|
struct avcodec_globals {
|
||||||
|
@ -1010,18 +1004,18 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
av_opt_set(context->encoder_ctx->priv_data, "preset", "llhp", 0);
|
av_opt_set(context->encoder_ctx->priv_data, "preset", "llhp", 0);
|
||||||
av_opt_set_int(context->encoder_ctx->priv_data, "2pass", 1, 0);
|
av_opt_set_int(context->encoder_ctx->priv_data, "2pass", 1, 0);
|
||||||
} else {
|
} else {
|
||||||
av_opt_set_int(context->encoder_ctx->priv_data, "intra-refresh", profile->x264.intra_refresh, 0);
|
if (profile->options) {
|
||||||
av_opt_set(context->encoder_ctx->priv_data, "preset", profile->x264.preset, 0);
|
switch_event_header_t *hp;
|
||||||
av_opt_set(context->encoder_ctx->priv_data, "tune", profile->x264.tune, 0);
|
|
||||||
av_opt_set_int(context->encoder_ctx->priv_data, "slice-max-size", SLICE_SIZE, 0);
|
for (hp = profile->options->headers; hp; hp = hp->next) {
|
||||||
|
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: %s\n", hp->name, hp->value);
|
||||||
|
av_opt_set(context->encoder_ctx->priv_data, hp->name, hp->value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context->encoder_ctx->colorspace = profile->ctx.colorspace;
|
context->encoder_ctx->colorspace = profile->ctx.colorspace;
|
||||||
context->encoder_ctx->color_range = profile->ctx.color_range;
|
context->encoder_ctx->color_range = profile->ctx.color_range;
|
||||||
|
|
||||||
if (profile->x264.sc_threshold > 0) av_opt_set_int(context->encoder_ctx->priv_data, "sc_threshold", profile->x264.sc_threshold, 0);
|
|
||||||
if (profile->x264.b_strategy > 0)av_opt_set_int(context->encoder_ctx->priv_data, "b_strategy", profile->x264.b_strategy, 0);
|
|
||||||
if (profile->x264.crf > 0)av_opt_set_int(context->encoder_ctx->priv_data, "crf", profile->x264.crf, 0);
|
|
||||||
|
|
||||||
context->encoder_ctx->flags |= profile->ctx.flags; // CODEC_FLAG_LOOP_FILTER; // flags=+loop
|
context->encoder_ctx->flags |= profile->ctx.flags; // CODEC_FLAG_LOOP_FILTER; // flags=+loop
|
||||||
if (profile->ctx.me_cmp >= 0) context->encoder_ctx->me_cmp = profile->ctx.me_cmp; // cmp=+chroma, where CHROMA = 1
|
if (profile->ctx.me_cmp >= 0) context->encoder_ctx->me_cmp = profile->ctx.me_cmp; // cmp=+chroma, where CHROMA = 1
|
||||||
if (profile->ctx.me_range >= 0) context->encoder_ctx->me_range = profile->ctx.me_range;
|
if (profile->ctx.me_range >= 0) context->encoder_ctx->me_range = profile->ctx.me_range;
|
||||||
|
@ -1647,10 +1641,6 @@ static void load_config()
|
||||||
profile->ctx.qmax = -1;
|
profile->ctx.qmax = -1;
|
||||||
profile->ctx.max_qdiff = -1;
|
profile->ctx.max_qdiff = -1;
|
||||||
|
|
||||||
profile->x264.sc_threshold = 0;
|
|
||||||
profile->x264.b_strategy = 0;
|
|
||||||
profile->x264.crf = 0;
|
|
||||||
|
|
||||||
if (!strcasecmp(CODEC_MAPS[i], "H264")) {
|
if (!strcasecmp(CODEC_MAPS[i], "H264")) {
|
||||||
profile->ctx.profile = FF_PROFILE_H264_BASELINE;
|
profile->ctx.profile = FF_PROFILE_H264_BASELINE;
|
||||||
profile->ctx.level = 41;
|
profile->ctx.level = 41;
|
||||||
|
@ -1713,6 +1703,7 @@ static void load_config()
|
||||||
switch_xml_t profile = switch_xml_child(profiles, "profile");
|
switch_xml_t profile = switch_xml_child(profiles, "profile");
|
||||||
|
|
||||||
for (; profile; profile = profile->next) {
|
for (; profile; profile = profile->next) {
|
||||||
|
switch_xml_t options = switch_xml_child(profile, "options");
|
||||||
switch_xml_t param = NULL;
|
switch_xml_t param = NULL;
|
||||||
const char *profile_name = switch_xml_attr(profile, "name");
|
const char *profile_name = switch_xml_attr(profile, "name");
|
||||||
avcodec_profile_t *aprofile = NULL;
|
avcodec_profile_t *aprofile = NULL;
|
||||||
|
@ -1778,8 +1769,6 @@ static void load_config()
|
||||||
ctx->time_base.num = num;
|
ctx->time_base.num = num;
|
||||||
ctx->time_base.den = den;
|
ctx->time_base.den = den;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(name, "preset")) {
|
|
||||||
switch_set_string(aprofile->x264.preset, value);
|
|
||||||
} else if (!strcmp(name, "flags")) {
|
} else if (!strcmp(name, "flags")) {
|
||||||
char *s = strdup(value);
|
char *s = strdup(value);
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
@ -1872,18 +1861,30 @@ static void load_config()
|
||||||
if (ctx->color_range > AVCOL_RANGE_NB) {
|
if (ctx->color_range > AVCOL_RANGE_NB) {
|
||||||
ctx->color_range = 0;
|
ctx->color_range = 0;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(name, "x264-preset")) {
|
|
||||||
switch_set_string(aprofile->x264.preset, value);
|
|
||||||
} else if (!strcmp(name, "x264-tune")) {
|
|
||||||
switch_set_string(aprofile->x264.tune, value);
|
|
||||||
} else if (!strcmp(name, "x264-sc-threshold")) {
|
|
||||||
aprofile->x264.sc_threshold = UINTVAL(val);
|
|
||||||
} else if (!strcmp(name, "x264-b-strategy")) {
|
|
||||||
aprofile->x264.b_strategy = UINTVAL(val);
|
|
||||||
} else if (!strcmp(name, "x264-crf")) {
|
|
||||||
aprofile->x264.crf = UINTVAL(val);
|
|
||||||
}
|
}
|
||||||
} // for param
|
} // for param
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
switch_xml_t option = switch_xml_child(options, "option");
|
||||||
|
|
||||||
|
if (aprofile->options) {
|
||||||
|
switch_event_destroy(&aprofile->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_event_create(&aprofile->options, SWITCH_EVENT_CLONE);
|
||||||
|
aprofile->options->flags |= EF_UNIQ_HEADERS;
|
||||||
|
|
||||||
|
for (; option; option = option->next) {
|
||||||
|
const char *name = switch_xml_attr(option, "name");
|
||||||
|
const char *value = switch_xml_attr(option, "value");
|
||||||
|
|
||||||
|
if (zstr(name) || zstr(value)) continue;
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: %s\n", name, value);
|
||||||
|
|
||||||
|
switch_event_add_header_string(aprofile->options, SWITCH_STACK_BOTTOM, name, value);
|
||||||
|
}
|
||||||
|
} // for options
|
||||||
} // for profile
|
} // for profile
|
||||||
} // profiles
|
} // profiles
|
||||||
|
|
||||||
|
@ -1928,6 +1929,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load)
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avcodec_shutdown)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CODECS; i++) {
|
||||||
|
avcodec_profile_t *profile = &avcodec_globals.profiles[i];
|
||||||
|
|
||||||
|
if (profile->options) {
|
||||||
|
switch_event_destroy(&profile->options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* For Emacs:
|
/* For Emacs:
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* mode:c
|
* mode:c
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_av_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_av_load);
|
||||||
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avcodec_shutdown);
|
||||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown);
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown);
|
||||||
SWITCH_MODULE_DEFINITION(mod_av, mod_av_load, mod_av_shutdown, NULL);
|
SWITCH_MODULE_DEFINITION(mod_av, mod_av_load, mod_av_shutdown, NULL);
|
||||||
|
|
||||||
|
@ -124,6 +125,7 @@ static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
|
||||||
|
|
||||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown)
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown)
|
||||||
{
|
{
|
||||||
|
mod_avcodec_shutdown();
|
||||||
avformat_network_deinit();
|
avformat_network_deinit();
|
||||||
av_log_set_callback(NULL);
|
av_log_set_callback(NULL);
|
||||||
av_lockmgr_register(NULL);
|
av_lockmgr_register(NULL);
|
||||||
|
|
Loading…
Reference in New Issue