OSDN Git Service

Merge commit '44b17d794aa508ae21f438ae80bfe8aaf4b426e1'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 29 Nov 2013 00:53:58 +0000 (01:53 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 29 Nov 2013 02:28:15 +0000 (03:28 +0100)
* commit '44b17d794aa508ae21f438ae80bfe8aaf4b426e1':
  dca: extract core substream's embedded downmix coeffcient codes, if present.

Conflicts:
libavcodec/dcadata.h
libavcodec/dcadec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/dcadata.h
libavcodec/dcadec.c

Simple merge
@@@ -556,68 -473,10 +563,68 @@@ static int dca_parse_audio_coding_heade
      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;
  
@@@ -2101,6 -1724,6 +2142,55 @@@ static int dca_decode_frame(AVCodecCont
      /* 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