As per ETSI TS 102 114 V1.4.1 specification. Signed-off-by: Anton Khirnov <anton@khirnov.net>tags/n2.2-rc1
| @@ -7505,6 +7505,52 @@ DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] = | |||
| 0.01724460535, 0.47964480519, 0.48503074050, 0.01805862412, | |||
| }; | |||
| /* | |||
| * D.11 Look-up Table for Downmix Scale Factors | |||
| * | |||
| * Note that the range of the entries in DmixTable[] is between -60 dB and 0 dB | |||
| * with addition of -inf (|DMixCoeff| = 0), which is coded with a DmixCode = 0. | |||
| * Furthermore, the range [-60 to 0] is subdivided into 3 regions, each with a | |||
| * different grid resolution: | |||
| * | |||
| * 1) [-60.000 to -30] with resolution of 0.500 dB | |||
| * 2) [-29.750 to -15] with resolution of 0.250 dB | |||
| * 3) [-14.875 to 0] with resolution of 0.125 dB | |||
| */ | |||
| static const float dca_dmixtable[241] = { | |||
| 0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496, | |||
| 0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371, | |||
| 0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758, | |||
| 0.003981, 0.004217, 0.004467, 0.004732, 0.005012, 0.005309, 0.005623, 0.005957, | |||
| 0.006310, 0.006683, 0.007079, 0.007499, 0.007943, 0.008414, 0.008913, 0.009441, | |||
| 0.010000, 0.010593, 0.011220, 0.011885, 0.012589, 0.013335, 0.014125, 0.014962, | |||
| 0.015849, 0.016788, 0.017783, 0.018836, 0.019953, 0.021135, 0.022387, 0.023714, | |||
| 0.025119, 0.026607, 0.028184, 0.029854, 0.031623, 0.032546, 0.033497, 0.034475, | |||
| 0.035481, 0.036517, 0.037584, 0.038681, 0.039811, 0.040973, 0.042170, 0.043401, | |||
| 0.044668, 0.045973, 0.047315, 0.048697, 0.050119, 0.051582, 0.053088, 0.054639, | |||
| 0.056234, 0.057876, 0.059566, 0.061306, 0.063096, 0.064938, 0.066834, 0.068786, | |||
| 0.070795, 0.072862, 0.074989, 0.077179, 0.079433, 0.081752, 0.084140, 0.086596, | |||
| 0.089125, 0.091728, 0.094406, 0.097163, 0.100000, 0.102920, 0.105925, 0.109018, | |||
| 0.112202, 0.115478, 0.118850, 0.122321, 0.125893, 0.129569, 0.133352, 0.137246, | |||
| 0.141254, 0.145378, 0.149624, 0.153993, 0.158489, 0.163117, 0.167880, 0.172783, | |||
| 0.177828, 0.180406, 0.183021, 0.185674, 0.188365, 0.191095, 0.193865, 0.196675, | |||
| 0.199526, 0.202418, 0.205353, 0.208329, 0.211349, 0.214412, 0.217520, 0.220673, | |||
| 0.223872, 0.227117, 0.230409, 0.233749, 0.237137, 0.240575, 0.244062, 0.247600, | |||
| 0.251189, 0.254830, 0.258523, 0.262271, 0.266073, 0.269929, 0.273842, 0.277811, | |||
| 0.281838, 0.285924, 0.290068, 0.294273, 0.298538, 0.302866, 0.307256, 0.311709, | |||
| 0.316228, 0.320812, 0.325462, 0.330179, 0.334965, 0.339821, 0.344747, 0.349744, | |||
| 0.354813, 0.359956, 0.365174, 0.370467, 0.375837, 0.381285, 0.386812, 0.392419, | |||
| 0.398107, 0.403878, 0.409732, 0.415671, 0.421697, 0.427809, 0.434010, 0.440301, | |||
| 0.446684, 0.453158, 0.459727, 0.466391, 0.473151, 0.480010, 0.486968, 0.494026, | |||
| 0.501187, 0.508452, 0.515822, 0.523299, 0.530884, 0.538580, 0.546387, 0.554307, | |||
| 0.562341, 0.570493, 0.578762, 0.587151, 0.595662, 0.604296, 0.613056, 0.621942, | |||
| 0.630957, 0.640103, 0.649382, 0.658795, 0.668344, 0.678032, 0.687860, 0.697831, | |||
| 0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979, | |||
| 0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517, | |||
| 0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712, | |||
| 1.000000, | |||
| }; | |||
| static const float dca_default_coeffs[10][5][2] = { | |||
| { { 0.707946, 0.707946 }, }, // A | |||
| { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, }, // A + B (dual mono) | |||
| @@ -339,6 +339,13 @@ typedef struct { | |||
| float downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients | |||
| int dynrange_coef; ///< dynamic range coefficient | |||
| /* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1) | |||
| * Input: primary audio channels (incl. LFE if present) | |||
| * Output: downmix audio channels (up to 4, no LFE) */ | |||
| uint8_t core_downmix; ///< embedded downmix coefficients available | |||
| uint8_t core_downmix_amode; ///< audio channel arrangement of embedded downmix | |||
| uint16_t core_downmix_codes[DCA_PRIM_CHANNELS_MAX + 1][4]; ///< embedded downmix coefficients (9-bit codes) | |||
| int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands | |||
| float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data | |||
| @@ -796,25 +803,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) | |||
| } | |||
| } | |||
| /* Stereo downmix coefficients */ | |||
| if (!base_channel && s->prim_channels > 2) { | |||
| int am = s->amode & DCA_CHANNEL_MASK; | |||
| if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { | |||
| av_log(s->avctx, AV_LOG_ERROR, | |||
| "Invalid channel mode %d\n", am); | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) { | |||
| avpriv_request_sample(s->avctx, "Downmixing %d channels", | |||
| s->prim_channels); | |||
| return AVERROR_PATCHWELCOME; | |||
| } | |||
| for (j = base_channel; j < s->prim_channels; j++) { | |||
| s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; | |||
| s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; | |||
| } | |||
| } | |||
| /* Dynamic range coefficient */ | |||
| if (!base_channel && s->dynrange) | |||
| s->dynrange_coef = get_bits(&s->gb, 8); | |||
| @@ -909,16 +897,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) | |||
| av_log(s->avctx, AV_LOG_DEBUG, "\n"); | |||
| } | |||
| } | |||
| if (!base_channel && s->prim_channels > 2) { | |||
| av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n"); | |||
| for (j = 0; j < s->prim_channels; j++) { | |||
| av_log(s->avctx, AV_LOG_DEBUG, "Channel 0, %d = %f\n", j, | |||
| s->downmix_coef[j][0]); | |||
| av_log(s->avctx, AV_LOG_DEBUG, "Channel 1, %d = %f\n", j, | |||
| s->downmix_coef[j][1]); | |||
| } | |||
| av_log(s->avctx, AV_LOG_DEBUG, "\n"); | |||
| } | |||
| for (j = base_channel; j < s->prim_channels; j++) | |||
| for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) | |||
| av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); | |||
| @@ -1292,7 +1270,7 @@ static int dca_filter_channels(DCAContext *s, int block_index) | |||
| static int dca_subframe_footer(DCAContext *s, int base_channel) | |||
| { | |||
| int aux_data_count = 0, i; | |||
| int in, out, aux_data_count, aux_data_end, reserved; | |||
| /* | |||
| * Unpack optional information | |||
| @@ -1303,11 +1281,74 @@ static int dca_subframe_footer(DCAContext *s, int base_channel) | |||
| if (s->timestamp) | |||
| skip_bits_long(&s->gb, 32); | |||
| if (s->aux_data) | |||
| if (s->aux_data) { | |||
| aux_data_count = get_bits(&s->gb, 6); | |||
| for (i = 0; i < aux_data_count; i++) | |||
| get_bits(&s->gb, 8); | |||
| // align (32-bit) | |||
| skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); | |||
| aux_data_end = 8 * aux_data_count + get_bits_count(&s->gb); | |||
| if (get_bits_long(&s->gb, 32) != 0x9A1105A0) // nSYNCAUX | |||
| return AVERROR_INVALIDDATA; | |||
| if (get_bits1(&s->gb)) { // bAUXTimeStampFlag | |||
| avpriv_request_sample(s->avctx, | |||
| "Auxiliary Decode Time Stamp Flag"); | |||
| // align (4-bit) | |||
| skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 4); | |||
| // 44 bits: nMSByte (8), nMarker (4), nLSByte (28), nMarker (4) | |||
| skip_bits_long(&s->gb, 44); | |||
| } | |||
| if ((s->core_downmix = get_bits1(&s->gb))) { | |||
| switch (get_bits(&s->gb, 3)) { | |||
| case 0: | |||
| s->core_downmix_amode = DCA_MONO; | |||
| break; | |||
| case 1: | |||
| s->core_downmix_amode = DCA_STEREO; | |||
| break; | |||
| case 2: | |||
| s->core_downmix_amode = DCA_STEREO_TOTAL; | |||
| break; | |||
| case 3: | |||
| s->core_downmix_amode = DCA_3F; | |||
| break; | |||
| case 4: | |||
| s->core_downmix_amode = DCA_2F1R; | |||
| break; | |||
| case 5: | |||
| s->core_downmix_amode = DCA_2F2R; | |||
| break; | |||
| case 6: | |||
| s->core_downmix_amode = DCA_3F1R; | |||
| break; | |||
| default: | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| for (out = 0; out < dca_channels[s->core_downmix_amode]; out++) { | |||
| for (in = 0; in < s->prim_channels + !!s->lfe; in++) { | |||
| uint16_t tmp = get_bits(&s->gb, 9); | |||
| if ((tmp & 0xFF) > 241) | |||
| return AVERROR_INVALIDDATA; | |||
| s->core_downmix_codes[in][out] = tmp; | |||
| } | |||
| } | |||
| } | |||
| align_get_bits(&s->gb); // byte align | |||
| skip_bits(&s->gb, 16); // nAUXCRC16 | |||
| // additional data (reserved, cf. ETSI TS 102 114 V1.4.1) | |||
| if ((reserved = (aux_data_end - get_bits_count(&s->gb))) < 0) | |||
| return AVERROR_INVALIDDATA; | |||
| else if (reserved) { | |||
| avpriv_request_sample(s->avctx, | |||
| "Core auxiliary data reserved content"); | |||
| skip_bits_long(&s->gb, reserved); | |||
| } | |||
| } | |||
| if (s->crc_present && s->dynrange) | |||
| get_bits(&s->gb, 16); | |||
| @@ -1822,6 +1863,51 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||
| channels = 2; | |||
| s->output = DCA_STEREO; | |||
| avctx->channel_layout = AV_CH_LAYOUT_STEREO; | |||
| /* Stereo downmix coefficients | |||
| * | |||
| * The decoder can only downmix to 2-channel, so we need to ensure | |||
| * embedded downmix coefficients are actually targeting 2-channel. | |||
| * | |||
| * Coefficients for the LFE channel are ignored (not supported) */ | |||
| if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO || | |||
| s->core_downmix_amode == DCA_STEREO_TOTAL)) { | |||
| int sign, code; | |||
| for (i = 0; i < s->prim_channels; i++) { | |||
| sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1; | |||
| code = s->core_downmix_codes[i][0] & 0x0FF; | |||
| s->downmix_coef[i][0] = (!code ? 0.0f : | |||
| sign * dca_dmixtable[code - 1]); | |||
| sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1; | |||
| code = s->core_downmix_codes[i][1] & 0x0FF; | |||
| s->downmix_coef[i][1] = (!code ? 0.0f : | |||
| sign * dca_dmixtable[code - 1]); | |||
| } | |||
| } else { | |||
| int am = s->amode & DCA_CHANNEL_MASK; | |||
| if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { | |||
| av_log(s->avctx, AV_LOG_ERROR, | |||
| "Invalid channel mode %d\n", am); | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) { | |||
| avpriv_request_sample(s->avctx, "Downmixing %d channels", | |||
| s->prim_channels); | |||
| return AVERROR_PATCHWELCOME; | |||
| } | |||
| for (i = 0; i < s->prim_channels; i++) { | |||
| s->downmix_coef[i][0] = dca_default_coeffs[am][i][0]; | |||
| s->downmix_coef[i][1] = dca_default_coeffs[am][i][1]; | |||
| } | |||
| } | |||
| av_dlog(s->avctx, "Stereo downmix coeffs:\n"); | |||
| for (i = 0; i < s->prim_channels; i++) { | |||
| av_dlog(s->avctx, "L, input channel %d = %f\n", i, | |||
| s->downmix_coef[i][0]); | |||
| av_dlog(s->avctx, "R, input channel %d = %f\n", i, | |||
| s->downmix_coef[i][1]); | |||
| } | |||
| av_dlog(s->avctx, "\n"); | |||
| } | |||
| } else { | |||
| av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); | |||