]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dca.c
Merge remote branch 'qatar/master'
[ffmpeg] / libavcodec / dca.c
index 64a81d577ce6c0f2e4a31db48d34d247f8e7ff41..1e26eedc3cc486581b251b528e7ffb2b6b195c82 100644 (file)
@@ -29,7 +29,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intmath.h"
 #include "libavutil/intreadwrite.h"
-#include "libavcore/audioconvert.h"
+#include "libavutil/audioconvert.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "fft.h"
@@ -40,6 +40,7 @@
 #include "dca.h"
 #include "synth_filter.h"
 #include "dcadsp.h"
+#include "fmtconvert.h"
 
 //#define TRACE
 
@@ -98,6 +99,21 @@ enum DCAExtensionMask {
     DCA_EXT_EXSS_XLL   = 0x200, ///< lossless extension in ExSS
 };
 
+/* -1 are reserved or unknown */
+static const int dca_ext_audio_descr_mask[] = {
+    DCA_EXT_XCH,
+    -1,
+    DCA_EXT_X96,
+    DCA_EXT_XCH | DCA_EXT_X96,
+    -1,
+    -1,
+    DCA_EXT_XXCH,
+    -1,
+};
+
+/* extensions that reside in core substream */
+#define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96)
+
 /* Tables for mapping dts channel configurations to libavcodec multichannel api.
  * Some compromises have been made for special configurations. Most configurations
  * are never used so complete accuracy is not needed.
@@ -105,7 +121,7 @@ enum DCAExtensionMask {
  * L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead.
  * S  -> side, when both rear and back are configured move one of them to the side channel
  * OV -> center back
- * All 2 channel configurations -> CH_LAYOUT_STEREO
+ * All 2 channel configurations -> AV_CH_LAYOUT_STEREO
  */
 
 static const int64_t dca_core_channel_layout[] = {
@@ -116,7 +132,7 @@ static const int64_t dca_core_channel_layout[] = {
     AV_CH_LAYOUT_STEREO,                                                     ///< 2, LT +RT (left and right total)
     AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER,                                  ///< 3, C+L+R
     AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER,                                   ///< 3, L+R+S
-    AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER|CH_BACK_CENTER,                   ///< 4, C + L + R+ S
+    AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER,                ///< 4, C + L + R+ S
     AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,                    ///< 4, L + R +SL+ SR
     AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, ///< 5, C + L + R+ SL+SR
     AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER,                    ///< 6, CL + CR + L + R + SL + SR
@@ -305,17 +321,16 @@ typedef struct {
 
     /* Subband samples history (for ADPCM) */
     float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
-    DECLARE_ALIGNED(16, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
-    DECLARE_ALIGNED(16, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32];
+    DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
+    DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32];
     int hist_index[DCA_PRIM_CHANNELS_MAX];
-    DECLARE_ALIGNED(16, float, raXin)[32];
+    DECLARE_ALIGNED(32, float, raXin)[32];
 
     int output;                 ///< type of output
-    float add_bias;             ///< output bias
     float scale_bias;           ///< output scale
 
-    DECLARE_ALIGNED(16, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
-    DECLARE_ALIGNED(16, float, samples)[(DCA_PRIM_CHANNELS_MAX+1)*256];
+    DECLARE_ALIGNED(32, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
+    DECLARE_ALIGNED(32, float, samples)[(DCA_PRIM_CHANNELS_MAX+1)*256];
     const float *samples_chanptr[DCA_PRIM_CHANNELS_MAX+1];
 
     uint8_t dca_buffer[DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_SIZE];
@@ -327,14 +342,12 @@ typedef struct {
     int current_subframe;
     int current_subsubframe;
 
+    int core_ext_mask;          ///< present extensions in the core substream
+
     /* XCh extension information */
-    int xch_present;
+    int xch_present;            ///< XCh extension present and valid
     int xch_base_channel;       ///< index of first (only) channel containing XCH data
 
-    /* Other detected extensions in the core substream */
-    int xxch_present;
-    int x96_present;
-
     /* ExSS header parser */
     int static_fields;          ///< static fields present
     int mix_metadata;           ///< mixing metadata present
@@ -348,6 +361,7 @@ typedef struct {
     FFTContext imdct;
     SynthFilterContext synth;
     DCADSPContext dcadsp;
+    FmtConvertContext fmt_conv;
 } DCAContext;
 
 static const uint16_t dca_vlc_offs[] = {
@@ -868,7 +882,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
 
 static void qmf_32_subbands(DCAContext * s, int chans,
                             float samples_in[32][8], float *samples_out,
-                            float scale, float bias)
+                            float scale)
 {
     const float *prCoeff;
     int i;
@@ -897,7 +911,7 @@ static void qmf_32_subbands(DCAContext * s, int chans,
         s->synth.synth_filter_float(&s->imdct,
                               s->subband_fir_hist[chans], &s->hist_index[chans],
                               s->subband_fir_noidea[chans], prCoeff,
-                              samples_out, s->raXin, scale, bias);
+                              samples_out, s->raXin, scale);
         samples_out+= 32;
 
     }
@@ -905,8 +919,7 @@ static void qmf_32_subbands(DCAContext * s, int chans,
 
 static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
                                   int num_deci_sample, float *samples_in,
-                                  float *samples_out, float scale,
-                                  float bias)
+                                  float *samples_out, float scale)
 {
     /* samples_in: An array holding decimated samples.
      *   Samples in current subframe starts from samples_in[0],
@@ -931,7 +944,7 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
     /* Interpolation */
     for (deciindex = 0; deciindex < num_deci_sample; deciindex++) {
         s->dcadsp.lfe_fir(samples_out, samples_in, prCoeff, decifactor,
-                          scale, bias);
+                          scale);
         samples_in++;
         samples_out += 2 * decifactor;
     }
@@ -939,19 +952,19 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
 
 /* downmixing routines */
 #define MIX_REAR1(samples, si1, rs, coef) \
-     samples[i]     += (samples[si1] - add_bias) * coef[rs][0];  \
-     samples[i+256] += (samples[si1] - add_bias) * coef[rs][1];
+     samples[i]     += samples[si1] * coef[rs][0];  \
+     samples[i+256] += samples[si1] * coef[rs][1];
 
 #define MIX_REAR2(samples, si1, si2, rs, coef) \
-     samples[i]     += (samples[si1] - add_bias) * coef[rs][0] + (samples[si2] - add_bias) * coef[rs+1][0]; \
-     samples[i+256] += (samples[si1] - add_bias) * coef[rs][1] + (samples[si2] - add_bias) * coef[rs+1][1];
+     samples[i]     += samples[si1] * coef[rs][0] + samples[si2] * coef[rs+1][0]; \
+     samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs+1][1];
 
 #define MIX_FRONT3(samples, coef) \
-    t = samples[i+c] - add_bias; \
-    u = samples[i+l] - add_bias; \
-    v = samples[i+r] - add_bias; \
-    samples[i]     = t * coef[0][0] + u * coef[1][0] + v * coef[2][0] + add_bias; \
-    samples[i+256] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1] + add_bias;
+    t = samples[i+c]; \
+    u = samples[i+l]; \
+    v = samples[i+r]; \
+    samples[i]     = t * coef[0][0] + u * coef[1][0] + v * coef[2][0]; \
+    samples[i+256] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1];
 
 #define DOWNMIX_TO_STEREO(op1, op2) \
     for (i = 0; i < 256; i++){ \
@@ -961,7 +974,7 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
 
 static void dca_downmix(float *samples, int srcfmt,
                         int downmix_coef[DCA_PRIM_CHANNELS_MAX][2],
-                        const int8_t *channel_mapping, float add_bias)
+                        const int8_t *channel_mapping)
 {
     int c,l,r,sl,sr,s;
     int i;
@@ -1117,7 +1130,7 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
                         block[m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel);
                 }
 
-                s->dsp.int32_to_float_fmul_scalar(subband_samples[k][l],
+                s->fmt_conv.int32_to_float_fmul_scalar(subband_samples[k][l],
                                                   block, rscale, 8);
             }
 
@@ -1193,13 +1206,12 @@ static int dca_filter_channels(DCAContext * s, int block_index)
 /*        static float pcm_to_double[8] =
             {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/
          qmf_32_subbands(s, k, subband_samples[k], &s->samples[256 * s->channel_order_tab[k]],
-                            M_SQRT1_2*s->scale_bias /*pcm_to_double[s->source_pcm_res] */ ,
-                            s->add_bias );
+                         M_SQRT1_2*s->scale_bias /*pcm_to_double[s->source_pcm_res] */ );
     }
 
     /* Down mixing */
     if (s->avctx->request_channels == 2 && s->prim_channels > 2) {
-        dca_downmix(s->samples, s->amode, s->downmix_coef, s->channel_order_tab, s->add_bias);
+        dca_downmix(s->samples, s->amode, s->downmix_coef, s->channel_order_tab);
     }
 
     /* Generate LFE samples for this subsubframe FIXME!!! */
@@ -1207,7 +1219,7 @@ static int dca_filter_channels(DCAContext * s, int block_index)
         lfe_interpolation_fir(s, s->lfe, 2 * s->lfe,
                               s->lfe_data + 2 * s->lfe * (block_index + 4),
                               &s->samples[256 * dca_lfe_index[s->amode]],
-                              (1.0/256.0)*s->scale_bias,  s->add_bias);
+                              (1.0/256.0)*s->scale_bias);
         /* Outputs 20bits pcm samples */
     }
 
@@ -1357,7 +1369,9 @@ static int dca_exss_mask2count(int mask)
  */
 static void dca_exss_skip_mix_coeffs(GetBitContext *gb, int channels, int out_ch)
 {
-    for (int i = 0; i < channels; i++) {
+    int i;
+
+    for (i = 0; i < channels; i++) {
         int mix_map_mask = get_bits(gb, out_ch);
         int num_coeffs = av_popcount(mix_map_mask);
         skip_bits_long(gb, num_coeffs * 6);
@@ -1507,12 +1521,9 @@ static int dca_exss_parse_asset_header(DCAContext *s)
 
     if (!(extensions_mask & DCA_EXT_CORE))
         av_log(s->avctx, AV_LOG_WARNING, "DTS core detection mismatch.\n");
-    if (!!(extensions_mask & DCA_EXT_XCH) != s->xch_present)
-        av_log(s->avctx, AV_LOG_WARNING, "DTS XCh detection mismatch.\n");
-    if (!!(extensions_mask & DCA_EXT_XXCH) != s->xxch_present)
-        av_log(s->avctx, AV_LOG_WARNING, "DTS XXCh detection mismatch.\n");
-    if (!!(extensions_mask & DCA_EXT_X96) != s->x96_present)
-        av_log(s->avctx, AV_LOG_WARNING, "DTS X96 detection mismatch.\n");
+    if ((extensions_mask & DCA_CORE_EXTS) != s->core_ext_mask)
+        av_log(s->avctx, AV_LOG_WARNING, "DTS extensions detection mismatch (%d, %d)\n",
+               extensions_mask & DCA_CORE_EXTS, s->core_ext_mask);
 
     return 0;
 }
@@ -1615,6 +1626,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
     int lfe_samples;
     int num_core_channels = 0;
     int i;
+    float *samples_flt = data;
     int16_t *samples = data;
     DCAContext *s = avctx->priv_data;
     int channels;
@@ -1622,8 +1634,6 @@ static int dca_decode_frame(AVCodecContext * avctx,
 
 
     s->xch_present = 0;
-    s->x96_present = 0;
-    s->xxch_present = 0;
 
     s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer,
                                                DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
@@ -1651,11 +1661,24 @@ static int dca_decode_frame(AVCodecContext * avctx,
     /* record number of core channels incase less than max channels are requested */
     num_core_channels = s->prim_channels;
 
-    /* extensions start at 32-bit boundaries into bitstream */
-    skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
+    if (s->ext_coding)
+        s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];
+    else
+        s->core_ext_mask = 0;
 
     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) {
+
+        /* 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);
 
@@ -1674,7 +1697,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
             /* skip length-to-end-of-frame field for the moment */
             skip_bits(&s->gb, 10);
 
-            s->profile = FFMAX(s->profile, FF_PROFILE_DTS_ES);
+            s->core_ext_mask |= DCA_EXT_XCH;
 
             /* extension amode should == 1, number of channels in extension */
             /* AFAIK XCh is not used for more channels */
@@ -1698,8 +1721,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
             /* 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->xxch_present = 1;
-            s->profile = FFMAX(s->profile, FF_PROFILE_DTS_ES);
+            s->core_ext_mask |= DCA_EXT_XXCH;
             break;
 
         case 0x1d95f262: {
@@ -1712,8 +1734,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
             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->x96_present = 1;
-            s->profile = FFMAX(s->profile, FF_PROFILE_DTS_96_24);
+            s->core_ext_mask |= DCA_EXT_X96;
             break;
         }
         }
@@ -1721,6 +1742,16 @@ static int dca_decode_frame(AVCodecContext * avctx,
         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_HD_MARKER)
@@ -1782,9 +1813,10 @@ static int dca_decode_frame(AVCodecContext * avctx,
         return -1;
     }
 
-    if (*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels)
+    /* ffdshow custom code */
+    if (*data_size < (s->sample_blocks / 8) * 256 * sizeof(samples[0]) * channels)
         return -1;
-    *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels;
+    *data_size = 256 / 8 * s->sample_blocks * sizeof(samples[0]) * channels;
 
     /* filter to get final output */
     for (i = 0; i < (s->sample_blocks / 8); i++) {
@@ -1798,13 +1830,19 @@ static int dca_decode_frame(AVCodecContext * avctx,
             float* rt_chan   = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
             int j;
             for(j = 0; j < 256; ++j) {
-                lt_chan[j] -= (back_chan[j] - s->add_bias) * M_SQRT1_2;
-                rt_chan[j] -= (back_chan[j] - s->add_bias) * M_SQRT1_2;
+                lt_chan[j] -= back_chan[j] * M_SQRT1_2;
+                rt_chan[j] -= back_chan[j] * M_SQRT1_2;
             }
         }
 
-        s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);
-        samples += 256 * channels;
+        /* interleave samples */
+        if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+            float_interleave(samples_flt, s->samples_chanptr, 256, channels);
+            samples_flt += 256 * channels;
+        } else {
+            s->fmt_conv.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);
+            samples += 256 * channels;
+        }
     }
 
     /* update lfe history */
@@ -1836,26 +1874,21 @@ static av_cold int dca_decode_init(AVCodecContext * avctx)
     ff_mdct_init(&s->imdct, 6, 1, 1.0);
     ff_synth_filter_init(&s->synth);
     ff_dcadsp_init(&s->dcadsp);
+    ff_fmt_convert_init(&s->fmt_conv, avctx);
 
     for (i = 0; i < DCA_PRIM_CHANNELS_MAX+1; i++)
         s->samples_chanptr[i] = s->samples + i * 256;
-    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+    avctx->sample_fmt = avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT ?
+                        AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16;
 
-    if (s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
-        s->add_bias = 385.0f;
-        s->scale_bias = 1.0 / 32768.0;
-    } else {
-        s->add_bias = 0.0f;
-        s->scale_bias = 1.0;
+    s->scale_bias = 1.0;
 
-        /* allow downmixing to stereo */
-        if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
-                avctx->request_channels == 2) {
-            avctx->channels = avctx->request_channels;
-        }
+    /* allow downmixing to stereo */
+    if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
+        avctx->request_channels == 2) {
+        avctx->channels = avctx->request_channels;
     }
 
-
     return 0;
 }
 
@@ -1866,7 +1899,16 @@ static av_cold int dca_decode_end(AVCodecContext * avctx)
     return 0;
 }
 
-AVCodec dca_decoder = {
+static const AVProfile profiles[] = {
+    { FF_PROFILE_DTS,        "DTS"        },
+    { FF_PROFILE_DTS_ES,     "DTS-ES"     },
+    { FF_PROFILE_DTS_96_24,  "DTS 96/24"  },
+    { FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" },
+    { FF_PROFILE_DTS_HD_MA,  "DTS-HD MA"  },
+    { FF_PROFILE_UNKNOWN },
+};
+
+AVCodec ff_dca_decoder = {
     .name = "dca",
     .type = AVMEDIA_TYPE_AUDIO,
     .id = CODEC_ID_DTS,
@@ -1876,4 +1918,5 @@ AVCodec dca_decoder = {
     .close = dca_decode_end,
     .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
     .capabilities = CODEC_CAP_CHANNEL_CONF,
+    .profiles = NULL_IF_CONFIG_SMALL(profiles),
 };