From b90d0ab4be3d03400e25db5cc4e03126998a75dd Mon Sep 17 00:00:00 2001 From: Burt P Date: Fri, 29 Jul 2016 12:36:19 -0500 Subject: [PATCH] af_hdcd: add force_pe filter option Used to attempt replication of some results from http://www.audiomisc.co.uk/HFN/HDCD/Examined.html May not be generally useful, defaults to off. Signed-off-by: Burt P Signed-off-by: Michael Niedermayer --- libavfilter/af_hdcd.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 4a4c9c754b..8e27d8aee8 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -867,6 +867,12 @@ typedef struct HDCDContext { const AVClass *class; hdcd_state_t state[2]; + /* always extend peaks above -3dBFS even if PE isn't signaled + * -af hdcd=force_pe=0 for off + * -af hdcd=force_pe=1 for on + * default is off */ + int force_pe; + AVFilterContext *fctx; /* filter context for logging errors */ int sample_count; /* used in error logging */ @@ -878,7 +884,10 @@ typedef struct HDCDContext { float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */ } HDCDContext; +#define OFFSET(x) offsetof(HDCDContext, x) static const AVOption hdcd_options[] = { + { "force_pe", "Always extend peaks above -3dBFS even when PE is not signaled.", + OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, 0 }, {NULL} }; @@ -1093,14 +1102,21 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int gain, int return gain; } +/* extract fields from control code */ +static void hdcd_control(HDCDContext *ctx, hdcd_state_t *state, int *peak_extend, int *target_gain) +{ + *peak_extend = (ctx->force_pe || state->control & 16); + *target_gain = (state->control & 15) << 7; +} + static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t *samples, int count, int stride) { int32_t *samples_end = samples + count * stride; int gain = state->running_gain; - int peak_extend = (state->control & 16); - int target_gain = (state->control & 15) << 7; + int peak_extend, target_gain; int lead = 0; + hdcd_control(ctx, state, &peak_extend, &target_gain); while (count > lead) { int envelope_run; int run; @@ -1115,8 +1131,7 @@ static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t *samples samples += envelope_run * stride; count -= envelope_run; lead = run - envelope_run; - peak_extend = (state->control & 16); - target_gain = (state->control & 15) << 7; + hdcd_control(ctx, state, &peak_extend, &target_gain); } if (lead > 0) { av_assert0(samples + lead * stride <= samples_end); @@ -1285,6 +1300,9 @@ static av_cold int init(AVFilterContext *ctx) hdcd_reset(&s->state[c], 44100); } + av_log(ctx, AV_LOG_VERBOSE, "Force PE: %s\n", + (s->force_pe) ? "on" : "off"); + return 0; }