#include <stddef.h>
#include <stdio.h>
+#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/intmath.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
-#include "libavutil/audioconvert.h"
+#include "libavutil/samplefmt.h"
#include "avcodec.h"
#include "dsputil.h"
#include "fft.h"
DECLARE_ALIGNED(32, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1];
+ float *extra_channels[DCA_PRIM_CHANNELS_MAX + 1];
+ uint8_t *extra_channels_buffer;
+ unsigned int extra_channels_buffer_size;
uint8_t dca_buffer[DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_SIZE];
int dca_buffer_size; ///< how much data is in the dca_buffer
int xxch_chset_nch[4];
float xxch_dmix_sf[DCA_CHSETS_MAX];
- uint32_t xxch_downmix; /* downmix enabled per channel set */
uint32_t xxch_dmix_embedded; /* lower layer has mix pre-embedded, per chset */
float xxch_dmix_coeff[DCA_PRIM_CHANNELS_MAX][32]; /* worst case sizing */
s->xxch_dmix_sf[s->xxch_chset] = scale_factor;
for (i = base_channel; i < s->prim_channels; i++) {
- s->xxch_downmix |= (1 << i);
mask[i] = get_bits(&s->gb, s->xxch_nbits_spk_mask);
}
for (k = 0; k < s->prim_channels; k++) {
/* static float pcm_to_double[8] = { 32768.0, 32768.0, 524288.0, 524288.0,
0, 8388608.0, 8388608.0 };*/
+ if(s->channel_order_tab[k] >= 0)
qmf_32_subbands(s, k, subband_samples[k],
s->samples_chanptr[s->channel_order_tab[k]],
M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
core_spk = get_bits(&s->gb, spkmsk_bits);
s->xxch_core_spkmask = core_spk;
s->xxch_nbits_spk_mask = spkmsk_bits;
- s->xxch_downmix = 0;
s->xxch_dmix_embedded = 0;
/* skip to the end of the header */
float *dst_chan;
DCAContext *s = avctx->priv_data;
int core_ss_end;
- int channels;
+ int channels, full_channels;
float scale;
int achan;
int chset;
avctx->profile = s->profile;
- channels = s->prim_channels + !!s->lfe;
+ 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 */
return AVERROR_INVALIDDATA;
}
- s->xxch_downmix = 0;
+ s->xxch_dmix_embedded = 0;
} else {
/* we only get here if an XXCH channel set can be added to the mix */
channel_mask = s->xxch_core_spkmask;
}
samples_flt = (float **) s->frame.extended_data;
+ /* allocate buffer for extra channels if downmixing */
+ if (avctx->channels < full_channels) {
+ ret = av_samples_get_buffer_size(NULL, full_channels - channels,
+ s->frame.nb_samples,
+ avctx->sample_fmt, 0);
+ if (ret < 0)
+ return ret;
+
+ av_fast_malloc(&s->extra_channels_buffer,
+ &s->extra_channels_buffer_size, ret);
+ if (!s->extra_channels_buffer)
+ return AVERROR(ENOMEM);
+
+ ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,
+ s->extra_channels_buffer,
+ full_channels - channels,
+ s->frame.nb_samples, avctx->sample_fmt, 0);
+ if (ret < 0)
+ return ret;
+ }
+
/* filter to get final output */
for (i = 0; i < (s->sample_blocks / 8); i++) {
int ch;
for (ch = 0; ch < channels; ch++)
s->samples_chanptr[ch] = samples_flt[ch] + i * 256;
+ for (; ch < full_channels; ch++)
+ s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256;
dca_filter_channels(s, i);
{
DCAContext *s = avctx->priv_data;
ff_mdct_end(&s->imdct);
+ av_freep(&s->extra_channels_buffer);
return 0;
}