diff options
-rw-r--r-- | libavfilter/af_hdcd.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 8e27d8aee8..0752c39555 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -933,6 +933,45 @@ static void hdcd_update_info(hdcd_state_t *state) state->max_gain = FFMAX(state->max_gain, (state->control & 15)); } +typedef enum { + HDCD_CODE_NONE=0, + HDCD_CODE_A, + HDCD_CODE_A_ALMOST, + HDCD_CODE_B, + HDCD_CODE_B_CHECKFAIL, + HDCD_CODE_EXPECT_A, + HDCD_CODE_EXPECT_B, +} hdcd_code_result_t; + +static hdcd_code_result_t hdcd_code(const uint32_t bits, unsigned char *code) +{ + if ((bits & 0x0fa00500) == 0x0fa00500) { + /* A: 8-bit code 0x7e0fa005[..] */ + if ((bits & 0xc8) == 0) { + /* [..pt gggg] + * 0x0fa005[..] -> 0b[00.. 0...], gain part doubled */ + *code = (bits & 255) + (bits & 7); + return HDCD_CODE_A; + } else + return HDCD_CODE_A_ALMOST; /* one of bits 3, 6, or 7 was not 0 */ + } else if ((bits & 0xa0060000) == 0xa0060000) { + /* B: 8-bit code, 8-bit XOR check, 0x7e0fa006[....] */ + if (((bits ^ (~bits >> 8 & 255)) & 0xffff00ff) == 0xa0060000) { + /* check: [..pt gggg ~(..pt gggg)] + * 0xa006[....] -> 0b[.... .... .... .... ] */ + *code = bits >> 8 & 255; + return HDCD_CODE_B; + } else + return HDCD_CODE_B_CHECKFAIL; /* XOR check failed */ + } + if (bits == 0x7e0fa005) + return HDCD_CODE_EXPECT_A; + else if (bits == 0x7e0fa006) + return HDCD_CODE_EXPECT_B; + + return HDCD_CODE_NONE; +} + static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t *state, int *flag, const int32_t *samples, int count, int stride) { uint32_t bits = 0; @@ -953,44 +992,39 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state_t *state, int *flag, cons bits = (state->window ^ state->window >> 5 ^ state->window >> 23); if (state->arg) { - if ((bits & 0x0fa00500) == 0x0fa00500) { - /* A: 8-bit code */ - if ((bits & 0xc8) == 0) { - /* [..pt gggg] - * 0x0fa005[..] -> 0b[00.. 0...], gain part doubled */ - state->control = (bits & 255) + (bits & 7); + switch (hdcd_code(bits, &state->control)) { + case HDCD_CODE_A: *flag = 1; state->code_counterA++; - } else { - /* one of bits 3, 6, or 7 was not 0 */ + break; + case HDCD_CODE_B: + *flag = 1; + state->code_counterB++; + break; + case HDCD_CODE_A_ALMOST: state->code_counterA_almost++; av_log(ctx->fctx, AV_LOG_VERBOSE, "hdcd error: Control A almost: 0x%02x near %d\n", bits & 0xff, ctx->sample_count); - } - } else if ((bits & 0xa0060000) == 0xa0060000) { - /* B: 8-bit code, 8-bit XOR check */ - if (((bits ^ (~bits >> 8 & 255)) & 0xffff00ff) == 0xa0060000) { - /* check: [..pt gggg ~(..pt gggg)] - * 0xa006[....] -> 0b[.... .... .... .... ] */ - state->control = bits >> 8 & 255; - *flag = 1; - state->code_counterB++; - } else { - /* XOR check failed */ + break; + case HDCD_CODE_B_CHECKFAIL: state->code_counterB_checkfails++; av_log(ctx->fctx, AV_LOG_VERBOSE, - "hdcd error: Control B check failed: 0x%04x (0x%02x vs 0x%02x) near %d\n", bits & 0xffff, (bits & 0xff00) >> 8, ~bits & 0xff, ctx->sample_count); - } - } else { - /* told to look for a code, but didn't match one */ - state->code_counterC_unmatched++; - av_log(ctx->fctx, AV_LOG_VERBOSE, - "hdcd error: Unmatched code: 0x%08x near %d\n", bits, ctx->sample_count); + "hdcd error: Control B check failed: 0x%04x (0x%02x vs 0x%02x) near %d\n", bits & 0xffff, (bits & 0xff00) >> 8, ~bits & 0xff, ctx->sample_count); + break; + case HDCD_CODE_NONE: + state->code_counterC_unmatched++; + av_log(ctx->fctx, AV_LOG_VERBOSE, + "hdcd error: Unmatched code: 0x%08x near %d\n", bits, ctx->sample_count); + default: + av_log(ctx->fctx, AV_LOG_INFO, + "hdcd error: Unexpected return value from hdcd_code()\n"); + av_assert0(0); /* die */ } if (*flag) hdcd_update_info(state); state->arg = 0; } if (bits == 0x7e0fa005 || bits == 0x7e0fa006) { + /* 0x7e0fa00[.]-> [0b0101 or 0b0110] */ state->readahead = (bits & 3) * 8; state->arg = 1; state->code_counterC++; |