FS-11189 refactor to support any possible codec specific private options

This commit is contained in:
Seven Du 2018-06-20 21:22:06 +08:00 committed by Muteesa Fred
parent 18bcc4ddff
commit 12e3b7177c
3 changed files with 59 additions and 40 deletions

View File

@ -123,14 +123,15 @@ enum AVColorRange {
-->
<param name="color-range" value="2"/>
<!-- x264 private -->
<param name="x264-preset" value="veryfast"/>
<param name="x264-intra-refresh" value="1"/>
<param name="x264-tune" value="animation+zerolatency"/>
<!-- <param name="x264-sc-threshold" value="40"/> -->
<!-- <param name="x264-b-strategy" value="1"/> -->
<!-- <param name="x264-crf" value="18"/> -->
<!-- x264 private options-->
<options>
<option name="preset" value="veryfast"/>
<option name="intra_refresh" value="1"/>
<option name="tune" value="animation+zerolatency"/>
<option name="sc_threshold" value="40"/>
<option name="b_strategy" value="1"/>
<option name="crf" value="18"/>
</options>
</profile>
<profile name="H265">

View File

@ -46,6 +46,7 @@ int SLICE_SIZE = SWITCH_DEFAULT_VIDEO_SIZE;
#define KEY_FRAME_MIN_FREQ 250000
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
Either include the avc.h which available in the ffmpeg source, or
@ -202,14 +203,7 @@ typedef struct avcodec_profile_s {
char name[20];
int decoder_thread_count;
AVCodecContext ctx;
struct {
char preset[20];
char tune[64];
int intra_refresh;
int sc_threshold;
int b_strategy;
int crf;
} x264;
switch_event_t *options;
} avcodec_profile_t;
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_int(context->encoder_ctx->priv_data, "2pass", 1, 0);
} else {
av_opt_set_int(context->encoder_ctx->priv_data, "intra-refresh", profile->x264.intra_refresh, 0);
av_opt_set(context->encoder_ctx->priv_data, "preset", profile->x264.preset, 0);
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);
if (profile->options) {
switch_event_header_t *hp;
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->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
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;
@ -1647,10 +1641,6 @@ static void load_config()
profile->ctx.qmax = -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")) {
profile->ctx.profile = FF_PROFILE_H264_BASELINE;
profile->ctx.level = 41;
@ -1713,6 +1703,7 @@ static void load_config()
switch_xml_t profile = switch_xml_child(profiles, "profile");
for (; profile; profile = profile->next) {
switch_xml_t options = switch_xml_child(profile, "options");
switch_xml_t param = NULL;
const char *profile_name = switch_xml_attr(profile, "name");
avcodec_profile_t *aprofile = NULL;
@ -1778,8 +1769,6 @@ static void load_config()
ctx->time_base.num = num;
ctx->time_base.den = den;
}
} else if (!strcmp(name, "preset")) {
switch_set_string(aprofile->x264.preset, value);
} else if (!strcmp(name, "flags")) {
char *s = strdup(value);
int flags = 0;
@ -1872,18 +1861,30 @@ static void load_config()
if (ctx->color_range > AVCOL_RANGE_NB) {
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
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
} // profiles
@ -1928,6 +1929,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load)
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:
* Local Variables:
* mode:c

View File

@ -38,6 +38,7 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
SWITCH_MODULE_LOAD_FUNCTION(mod_av_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avcodec_shutdown);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown);
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)
{
mod_avcodec_shutdown();
avformat_network_deinit();
av_log_set_callback(NULL);
av_lockmgr_register(NULL);