return 0;
}
-static int dca_filter_channels(DCAContext *s, int block_index, int upsample)
+static int dca_filter_channels(DCAContext *s, int block_index, int upsample, int downmix)
{
int k;
/* 64 subbands QMF */
for (k = 0; k < s->audio_header.prim_channels; k++) {
+ int channel = s->channel_order_tab[k];
int32_t (*subband_samples)[SAMPLES_PER_SUBBAND] =
s->dca_chan[k].subband_samples[block_index];
s->fmt_conv.int32_to_float(samples[0], subband_samples[0],
DCA_SUBBANDS_X96K * SAMPLES_PER_SUBBAND);
- if (s->channel_order_tab[k] >= 0)
+ if (channel >= 0)
qmf_64_subbands(s, k, samples,
- s->samples_chanptr[s->channel_order_tab[k]],
+ s->samples_chanptr[channel],
/* Upsampling needs a factor 2 here. */
M_SQRT2 / 32768.0);
}
LOCAL_ALIGNED(32, float, samples, [DCA_SUBBANDS], [SAMPLES_PER_SUBBAND]);
for (k = 0; k < s->audio_header.prim_channels; k++) {
+ int channel = s->channel_order_tab[k];
int32_t (*subband_samples)[SAMPLES_PER_SUBBAND] =
s->dca_chan[k].subband_samples[block_index];
s->fmt_conv.int32_to_float(samples[0], subband_samples[0],
DCA_SUBBANDS * SAMPLES_PER_SUBBAND);
- if (s->channel_order_tab[k] >= 0)
+ if (channel >= 0)
qmf_32_subbands(s, k, samples,
- s->samples_chanptr[s->channel_order_tab[k]],
+ s->samples_chanptr[channel],
M_SQRT1_2 / 32768.0);
}
}
/* FIXME: This downmixing is probably broken with upsample.
* Probably totally broken also with XLL in general. */
/* Downmixing to Stereo */
- if (s->audio_header.prim_channels + !!s->lfe > 2 &&
- s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ if (downmix) {
dca_downmix(s->samples_chanptr, s->amode, !!s->lfe, s->downmix_coef,
s->channel_order_tab);
}
return ret;
}
-static int set_channel_layout(AVCodecContext *avctx, int channels, int num_core_channels)
+static int set_channel_layout(AVCodecContext *avctx, int channels)
{
DCAContext *s = avctx->priv_data;
+ int num_core_channels = s->audio_header.prim_channels;
int i;
if (s->amode < 16) {
s->channel_order_tab = ff_dca_channel_reorder_nolfe[s->amode];
}
+ if (channels < ff_dca_channels[s->amode] + !!s->lfe)
+ return AVERROR_INVALIDDATA;
+
if (channels > !!s->lfe &&
s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
return AVERROR_INVALIDDATA;
ff_dlog(s->avctx, "\n");
}
} else {
- av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);
+ av_log(avctx, AV_LOG_ERROR, "Nonstandard configuration %d !\n", s->amode);
return AVERROR_INVALIDDATA;
}
int buf_size = avpkt->size;
int lfe_samples;
- int num_core_channels = 0;
int i, ret;
float **samples_flt;
DCAContext *s = avctx->priv_data;
int channels, full_channels;
int upsample = 0;
+ int downmix;
s->exss_ext_mask = 0;
s->xch_present = 0;
}
}
- /* record number of core channels incase less than max channels are requested */
- num_core_channels = s->audio_header.prim_channels;
-
if (s->ext_coding)
s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];
else
full_channels = channels = s->audio_header.prim_channels + !!s->lfe;
- ret = set_channel_layout(avctx, channels, num_core_channels);
+ ret = set_channel_layout(avctx, channels);
if (ret < 0)
return ret;
avctx->channels = channels;
return ret;
}
+ downmix = s->audio_header.prim_channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO;
+
/* filter to get final output */
for (i = 0; i < (s->sample_blocks / SAMPLES_PER_SUBBAND); i++) {
int ch;
for (; ch < full_channels; ch++)
s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * block;
- dca_filter_channels(s, i, upsample);
+ dca_filter_channels(s, i, upsample, downmix);
/* If this was marked as a DTS-ES stream we need to subtract back- */
/* channel from SL & SR to remove matrixed back-channel signal */