[FFmpeg-devel] [PATCH] af_hdcd: Improve HDCD detection
Burt P
pburt0 at gmail.com
Sun Jul 17 20:34:12 EEST 2016
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 <pburt0 at 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
More information about the ffmpeg-devel
mailing list