HDCD is only "detected" if a valid code is active in both channels simultaneously, as described here: https://hydrogenaud.io/index.php/topic,79427.msg900371.html#msg900371
Signed-off-by: Burt P <pbu...@gmail.com> --- libavfilter/af_hdcd.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 6f0db71..4b48967 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -818,15 +818,25 @@ static const int32_t gaintab[] = { typedef struct { uint64_t window; - unsigned char readahead, arg, control; - int running_gain; - unsigned sustain, sustain_reset; - int code_counterA; - int code_counterA_almost; /* looks like an A code, but a bit expected to be 0 is 1 */ - int code_counterB; + unsigned char readahead; + + /* arg is set when a packet prefix is found. + * control is the active control code, where + * bit 0-3: target_gain, 4-bit (3.1) fixed-point value + * bit 4 : peak_extend + * bit 5 : transient_filter + * bit 6,7: always zero */ + unsigned char arg, control; + unsigned sustain, sustain_reset; /* code detect timer */ + + int running_gain; /* 11-bit (3.8) fixed point, extended from target_gain */ + + int code_counterA; /* 8-bit format packet */ + int code_counterA_almost; /* looks like an A code, but a bit expected to be 0 is 1 */ + int code_counterB; /* 16-bit format packet, 8-bit code, 8-bit XOR of code */ int code_counterB_checkfails; /* looks like a B code, but doesn't pass the XOR check */ - int code_counterC; - int code_counterC_unmatched; /* told to look for a code, but didn't find one */ + int code_counterC; /* packet prefix was found, expect a code */ + int code_counterC_unmatched; /* told to look for a code, but didn't find one */ /* For user information/stats, pulled up into HDCDContext * by filter_frame() */ @@ -1096,7 +1106,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out; const int16_t *in_data; int32_t *out_data; - int n, c; + int n, c, detect; out = ff_get_audio_buffer(outlink, in->nb_samples); if (!out) { @@ -1112,6 +1122,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out_data[n] = in_data[n]; } + detect = 0; s->det_errors = 0; for (c = 0; c < inlink->channels; c++) { hdcd_state_t *state = &s->state[c]; @@ -1120,11 +1131,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) s->uses_peak_extend |= !!state->count_peak_extend; s->uses_transient_filter |= !!state->count_transient_filter; s->max_gain_adjustment = FFMIN(s->max_gain_adjustment, GAINTOFLOAT(state->max_gain)); - s->hdcd_detected |= state->code_counterB || state->code_counterA; + if (state->sustain) detect++; s->det_errors += state->code_counterA_almost + state->code_counterB_checkfails + state->code_counterC_unmatched; } + /* HDCD is detected if a valid packet is active in all (both) + * channels at the same time. */ + if (detect == inlink->channels) s->hdcd_detected = 1; av_frame_free(&in); return ff_filter_frame(outlink, out); -- 2.7.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel