static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 };
static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 };
static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
+ int hdr_pos = 0, hdr_size = 0;
+ float sign, mag, scale_factor;
+ int this_chans, acc_mask;
+ int embedded_downmix;
+ int nchans, mask[8];
+ int coeff, ichan;
+
+ /* xxch has arbitrary sized audio coding headers */
+ if (xxch) {
+ hdr_pos = get_bits_count(&s->gb);
+ hdr_size = get_bits(&s->gb, 7) + 1;
+ }
- s->total_channels = get_bits(&s->gb, 3) + 1 + base_channel;
+ nchans = get_bits(&s->gb, 3) + 1;
+ s->total_channels = nchans + base_channel;
s->prim_channels = s->total_channels;
- 1.0f / dca_downmix_scale_factors[(get_bits(&s->gb, 6) - 1) << 2];
+ /* obtain speaker layout mask & downmix coefficients for XXCH */
+ if (xxch) {
+ acc_mask = s->xxch_core_spkmask;
+
+ this_chans = get_bits(&s->gb, s->xxch_nbits_spk_mask - 6) << 6;
+ s->xxch_spk_masks[s->xxch_chset] = this_chans;
+ s->xxch_chset_nch[s->xxch_chset] = nchans;
+
+ for (i = 0; i <= s->xxch_chset; i++)
+ acc_mask |= s->xxch_spk_masks[i];
+
+ /* check for downmixing information */
+ if (get_bits1(&s->gb)) {
+ embedded_downmix = get_bits1(&s->gb);
+ scale_factor =
- mag = dca_downmix_scale_factors[((coeff & 63) - 1) << 2];
++ 1.0f / dca_dmixtable[(get_bits(&s->gb, 6) - 1) << 2];
+
+ s->xxch_dmix_sf[s->xxch_chset] = scale_factor;
+
+ for (i = base_channel; i < s->prim_channels; i++) {
+ mask[i] = get_bits(&s->gb, s->xxch_nbits_spk_mask);
+ }
+
+ for (j = base_channel; j < s->prim_channels; j++) {
+ memset(s->xxch_dmix_coeff[j], 0, sizeof(s->xxch_dmix_coeff[0]));
+ s->xxch_dmix_embedded |= (embedded_downmix << j);
+ for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
+ if (mask[j] & (1 << i)) {
+ if ((1 << i) == DCA_XXCH_LFE1) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "DCA-XXCH: dmix to LFE1 not supported.\n");
+ continue;
+ }
+
+ coeff = get_bits(&s->gb, 7);
+ sign = (coeff & 64) ? 1.0 : -1.0;
++ mag = dca_dmixtable[((coeff & 63) - 1) << 2];
+ ichan = dca_xxch2index(s, 1 << i);
+ s->xxch_dmix_coeff[j][ichan] = sign * mag;
+ }
+ }
+ }
+ }
+ }
+
if (s->prim_channels > DCA_PRIM_CHANNELS_MAX)
s->prim_channels = DCA_PRIM_CHANNELS_MAX;
/* record number of core channels incase less than max channels are requested */
num_core_channels = s->prim_channels;
++ if (s->prim_channels > 2 &&
++ avctx->request_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");
++ }
++
if (s->ext_coding)
s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];
else