Merge commit '971177f751a6e2931232accceab438bce277bde8'
authorHendrik Leppkes <h.leppkes@gmail.com>
Thu, 17 Sep 2015 09:08:22 +0000 (11:08 +0200)
committerHendrik Leppkes <h.leppkes@gmail.com>
Thu, 17 Sep 2015 09:08:22 +0000 (11:08 +0200)
* commit '971177f751a6e2931232accceab438bce277bde8':
  dcadec: scan for extensions in a separate function

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
1  2 
libavcodec/dcadec.c

@@@ -1450,9 -1139,111 +1450,117 @@@ static float dca_dmix_code(unsigned cod
  {
      int sign = (code >> 8) - 1;
      code &= 0xff;
 -    return ((ff_dca_dmixtable[code] ^ sign) - sign) * (1.0 / (1U << 15));
 +    return ((ff_dca_dmixtable[code] ^ sign) - sign) * (1.0 / (1 << 15));
  }
  
 -    if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) {
+ static int scan_for_extensions(AVCodecContext *avctx)
+ {
+     DCAContext *s = avctx->priv_data;
+     int core_ss_end, ret;
+     core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8;
+     /* only scan for extensions if ext_descr was unknown or indicated a
+      * supported XCh extension */
 -                dca_parse_audio_coding_header(s, s->xch_base_channel);
++    if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
+         /* if ext_descr was unknown, clear s->core_ext_mask so that the
+          * extensions scan can fill it up */
+         s->core_ext_mask = FFMAX(s->core_ext_mask, 0);
+         /* extensions start at 32-bit boundaries into bitstream */
+         skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
+         while (core_ss_end - get_bits_count(&s->gb) >= 32) {
+             uint32_t bits = get_bits_long(&s->gb, 32);
+             int i;
+             switch (bits) {
+             case DCA_SYNCWORD_XCH: {
+                 int ext_amode, xch_fsize;
+                 s->xch_base_channel = s->prim_channels;
+                 /* validate sync word using XCHFSIZE field */
+                 xch_fsize = show_bits(&s->gb, 10);
+                 if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize) &&
+                     (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize + 1))
+                     continue;
+                 /* skip length-to-end-of-frame field for the moment */
+                 skip_bits(&s->gb, 10);
+                 s->core_ext_mask |= DCA_EXT_XCH;
+                 /* extension amode(number of channels in extension) should be 1 */
+                 /* AFAIK XCh is not used for more channels */
+                 if ((ext_amode = get_bits(&s->gb, 4)) != 1) {
+                     av_log(avctx, AV_LOG_ERROR,
+                            "XCh extension amode %d not supported!\n",
+                            ext_amode);
+                     continue;
+                 }
++                if (s->xch_base_channel < 2) {
++                    avpriv_request_sample(avctx, "XCh with fewer than 2 base channels");
++                    continue;
++                }
++
+                 /* much like core primary audio coding header */
++                dca_parse_audio_coding_header(s, s->xch_base_channel, 0);
+                 for (i = 0; i < (s->sample_blocks / 8); i++)
+                     if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
+                         av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");
+                         continue;
+                     }
+                 s->xch_present = 1;
+                 break;
+             }
+             case DCA_SYNCWORD_XXCH:
+                 /* XXCh: extended channels */
+                 /* usually found either in core or HD part in DTS-HD HRA streams,
+                  * but not in DTS-ES which contains XCh extensions instead */
+                 s->core_ext_mask |= DCA_EXT_XXCH;
++                ff_dca_xxch_decode_frame(s);
+                 break;
+             case 0x1d95f262: {
+                 int fsize96 = show_bits(&s->gb, 12) + 1;
+                 if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + fsize96)
+                     continue;
+                 av_log(avctx, AV_LOG_DEBUG, "X96 extension found at %d bits\n",
+                        get_bits_count(&s->gb));
+                 skip_bits(&s->gb, 12);
+                 av_log(avctx, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", fsize96);
+                 av_log(avctx, AV_LOG_DEBUG, "REVNO = %d\n", get_bits(&s->gb, 4));
+                 s->core_ext_mask |= DCA_EXT_X96;
+                 break;
+             }
+             }
+             skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
+         }
+     } else {
+         /* no supported extensions, skip the rest of the core substream */
+         skip_bits_long(&s->gb, core_ss_end - get_bits_count(&s->gb));
+     }
+     if (s->core_ext_mask & DCA_EXT_X96)
+         s->profile = FF_PROFILE_DTS_96_24;
+     else if (s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH))
+         s->profile = FF_PROFILE_DTS_ES;
+     /* check for ExSS (HD part) */
+     if (s->dca_buffer_size - s->frame_size > 32 &&
+         get_bits_long(&s->gb, 32) == DCA_SYNCWORD_SUBSTREAM)
+         ff_dca_exss_parse_header(s);
+     return ret;
+ }
  /**
   * Main frame decoding function
   * FIXME add arguments
@@@ -1468,20 -1258,9 +1576,19 @@@ static int dca_decode_frame(AVCodecCont
      int lfe_samples;
      int num_core_channels = 0;
      int i, ret;
 -    float  **samples_flt;
 +    float **samples_flt;
 +    float *src_chan;
 +    float *dst_chan;
      DCAContext *s = avctx->priv_data;
-     int core_ss_end;
      int channels, full_channels;
 +    float scale;
 +    int achan;
 +    int chset;
 +    int mask;
 +    int lavc;
 +    int posn;
 +    int j, k;
 +    int endch;
      int upsample = 0;
  
      s->exss_ext_mask = 0;
                          s->downmix_coef[i][1]);
              }
              ff_dlog(s->avctx, "\n");
-     core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8;
-     /* only scan for extensions if ext_descr was unknown or indicated a
-      * supported XCh extension */
-     if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
-         /* if ext_descr was unknown, clear s->core_ext_mask so that the
-          * extensions scan can fill it up */
-         s->core_ext_mask = FFMAX(s->core_ext_mask, 0);
-         /* extensions start at 32-bit boundaries into bitstream */
-         skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
-         while (core_ss_end - get_bits_count(&s->gb) >= 32) {
-             uint32_t bits = get_bits_long(&s->gb, 32);
-             switch (bits) {
-             case DCA_SYNCWORD_XCH: {
-                 int ext_amode, xch_fsize;
-                 s->xch_base_channel = s->prim_channels;
-                 /* validate sync word using XCHFSIZE field */
-                 xch_fsize = show_bits(&s->gb, 10);
-                 if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize) &&
-                     (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize + 1))
-                     continue;
-                 /* skip length-to-end-of-frame field for the moment */
-                 skip_bits(&s->gb, 10);
-                 s->core_ext_mask |= DCA_EXT_XCH;
-                 /* extension amode(number of channels in extension) should be 1 */
-                 /* AFAIK XCh is not used for more channels */
-                 if ((ext_amode = get_bits(&s->gb, 4)) != 1) {
-                     av_log(avctx, AV_LOG_ERROR,
-                            "XCh extension amode %d not supported!\n",
-                            ext_amode);
-                     continue;
-                 }
-                 if (s->xch_base_channel < 2) {
-                     avpriv_request_sample(avctx, "XCh with fewer than 2 base channels");
-                     continue;
-                 }
-                 /* much like core primary audio coding header */
-                 dca_parse_audio_coding_header(s, s->xch_base_channel, 0);
-                 for (i = 0; i < (s->sample_blocks / 8); i++)
-                     if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
-                         av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");
-                         continue;
-                     }
-                 s->xch_present = 1;
-                 break;
-             }
-             case DCA_SYNCWORD_XXCH:
-                 /* XXCh: extended channels */
-                 /* usually found either in core or HD part in DTS-HD HRA streams,
-                  * but not in DTS-ES which contains XCh extensions instead */
-                 s->core_ext_mask |= DCA_EXT_XXCH;
-                 ff_dca_xxch_decode_frame(s);
-                 break;
-             case 0x1d95f262: {
-                 int fsize96 = show_bits(&s->gb, 12) + 1;
-                 if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + fsize96)
-                     continue;
-                 av_log(avctx, AV_LOG_DEBUG, "X96 extension found at %d bits\n",
-                        get_bits_count(&s->gb));
-                 skip_bits(&s->gb, 12);
-                 av_log(avctx, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", fsize96);
-                 av_log(avctx, AV_LOG_DEBUG, "REVNO = %d\n", get_bits(&s->gb, 4));
-                 s->core_ext_mask |= DCA_EXT_X96;
-                 break;
-             }
-             }
-             skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
-         }
-     } else {
-         /* no supported extensions, skip the rest of the core substream */
-         skip_bits_long(&s->gb, core_ss_end - get_bits_count(&s->gb));
-     }
-     if (s->core_ext_mask & DCA_EXT_X96)
-         s->profile = FF_PROFILE_DTS_96_24;
-     else if (s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH))
-         s->profile = FF_PROFILE_DTS_ES;
-     /* check for ExSS (HD part) */
-     if (s->dca_buffer_size - s->frame_size > 32 &&
-         get_bits_long(&s->gb, 32) == DCA_SYNCWORD_SUBSTREAM)
-         ff_dca_exss_parse_header(s);
 +    }
 +
 +    if (s->ext_coding)
 +        s->core_ext_mask = ff_dca_ext_audio_descr_mask[s->ext_descr];
 +    else
 +        s->core_ext_mask = 0;
 +
++    ret = scan_for_extensions(avctx);
 +
 +    avctx->profile = s->profile;
 +
 +    full_channels = channels = s->prim_channels + !!s->lfe;
 +
 +    /* If we have XXCH then the channel layout is managed differently */
 +    /* note that XLL will also have another way to do things */
 +    if (!(s->core_ext_mask & DCA_EXT_XXCH)) {
 +        /* xxx should also do MA extensions */
 +        if (s->amode < 16) {
 +            avctx->channel_layout = ff_dca_core_channel_layout[s->amode];
 +
 +            if (s->prim_channels + !!s->lfe > 2 &&
 +                avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
 +                /*
 +                 * Neither the core's auxiliary data nor our default tables contain
 +                 * downmix coefficients for the additional channel coded in the XCh
 +                 * extension, so when we're doing a Stereo downmix, don't decode it.
 +                 */
 +                s->xch_disable = 1;
 +            }
 +
 +            if (s->xch_present && !s->xch_disable) {
 +                if (avctx->channel_layout & AV_CH_BACK_CENTER) {
 +                    avpriv_request_sample(avctx, "XCh with Back center channel");
 +                    return AVERROR_INVALIDDATA;
 +                }
 +                avctx->channel_layout |= AV_CH_BACK_CENTER;
 +                if (s->lfe) {
 +                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 +                    s->channel_order_tab = ff_dca_channel_reorder_lfe_xch[s->amode];
 +                } else {
 +                    s->channel_order_tab = ff_dca_channel_reorder_nolfe_xch[s->amode];
 +                }
 +                if (s->channel_order_tab[s->xch_base_channel] < 0)
 +                    return AVERROR_INVALIDDATA;
 +            } else {
 +                channels       = num_core_channels + !!s->lfe;
 +                s->xch_present = 0; /* disable further xch processing */
 +                if (s->lfe) {
 +                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 +                    s->channel_order_tab = ff_dca_channel_reorder_lfe[s->amode];
 +                } else
 +                    s->channel_order_tab = ff_dca_channel_reorder_nolfe[s->amode];
 +            }
 +
 +            if (channels > !!s->lfe &&
 +                s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
 +                return AVERROR_INVALIDDATA;
 +
 +            if (av_get_channel_layout_nb_channels(avctx->channel_layout) != channels) {
 +                av_log(avctx, AV_LOG_ERROR, "Number of channels %d mismatches layout %d\n", channels, av_get_channel_layout_nb_channels(avctx->channel_layout));
 +                return AVERROR_INVALIDDATA;
 +            }
 +
 +            if (num_core_channels + !!s->lfe > 2 &&
 +                avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
 +                channels              = 2;
 +                s->output             = s->prim_channels == 2 ? s->amode : DCA_STEREO;
 +                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
 +            }
 +            else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {
 +                static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
 +                s->channel_order_tab = dca_channel_order_native;
 +            }
 +            s->lfe_index = ff_dca_lfe_index[s->amode];
 +        } else {
 +            av_log(avctx, AV_LOG_ERROR,
 +                   "Non standard configuration %d !\n", s->amode);
 +            return AVERROR_INVALIDDATA;
          }
 +
 +        s->xxch_dmix_embedded = 0;
      } else {
 -        av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);
 -        return AVERROR_INVALIDDATA;
 +        /* we only get here if an XXCH channel set can be added to the mix */
 +        channel_mask = s->xxch_core_spkmask;
 +
 +        {
 +            channels = s->prim_channels + !!s->lfe;
 +            for (i = 0; i < s->xxch_chset; i++) {
 +                channel_mask |= s->xxch_spk_masks[i];
 +            }
 +        }
 +
 +        /* Given the DTS spec'ed channel mask, generate an avcodec version */
 +        channel_layout = 0;
 +        for (i = 0; i < s->xxch_nbits_spk_mask; ++i) {
 +            if (channel_mask & (1 << i)) {
 +                channel_layout |= ff_dca_map_xxch_to_native[i];
 +            }
 +        }
 +
 +        /* make sure that we have managed to get equivalent dts/avcodec channel
 +         * masks in some sense -- unfortunately some channels could overlap */
 +        if (av_popcount(channel_mask) != av_popcount(channel_layout)) {
 +            av_log(avctx, AV_LOG_DEBUG,
 +                   "DTS-XXCH: Inconsistent avcodec/dts channel layouts\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +
 +        avctx->channel_layout = channel_layout;
 +
 +        if (!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) {
 +            /* Estimate DTS --> avcodec ordering table */
 +            for (chset = -1, j = 0; chset < s->xxch_chset; ++chset) {
 +                mask = chset >= 0 ? s->xxch_spk_masks[chset]
 +                                  : s->xxch_core_spkmask;
 +                for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
 +                    if (mask & ~(DCA_XXCH_LFE1 | DCA_XXCH_LFE2) & (1 << i)) {
 +                        lavc = ff_dca_map_xxch_to_native[i];
 +                        posn = av_popcount(channel_layout & (lavc - 1));
 +                        s->xxch_order_tab[j++] = posn;
 +                    }
 +                }
 +
 +            }
 +
 +            s->lfe_index = av_popcount(channel_layout & (AV_CH_LOW_FREQUENCY-1));
 +        } else { /* native ordering */
 +            for (i = 0; i < channels; i++)
 +                s->xxch_order_tab[i] = i;
 +
 +            s->lfe_index = channels - 1;
 +        }
 +
 +        s->channel_order_tab = s->xxch_order_tab;
      }
 -    avctx->channels = channels;
  
      /* get output buffer */
      frame->nb_samples = 256 * (s->sample_blocks / 8);