Commit cd8bef96 authored by Nick Brereton's avatar Nick Brereton Committed by Michael Niedermayer

Generate channel layout, reordering for DTS-XXCH extension and, undo embedded downmixes

Reviewed-by: 's avatarBenjamin Larsson <benjamin@southpole.se>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 16f6c16a
...@@ -95,6 +95,68 @@ enum DCAExSSSpeakerMask { ...@@ -95,6 +95,68 @@ enum DCAExSSSpeakerMask {
DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000, DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000,
}; };
enum DCAXxchSpeakerMask {
DCA_XXCH_FRONT_CENTER = 0x0000001,
DCA_XXCH_FRONT_LEFT = 0x0000002,
DCA_XXCH_FRONT_RIGHT = 0x0000004,
DCA_XXCH_SIDE_REAR_LEFT = 0x0000008,
DCA_XXCH_SIDE_REAR_RIGHT = 0x0000010,
DCA_XXCH_LFE1 = 0x0000020,
DCA_XXCH_REAR_CENTER = 0x0000040,
DCA_XXCH_SURROUND_REAR_LEFT = 0x0000080,
DCA_XXCH_SURROUND_REAR_RIGHT = 0x0000100,
DCA_XXCH_SIDE_SURROUND_LEFT = 0x0000200,
DCA_XXCH_SIDE_SURROUND_RIGHT = 0x0000400,
DCA_XXCH_FRONT_CENTER_LEFT = 0x0000800,
DCA_XXCH_FRONT_CENTER_RIGHT = 0x0001000,
DCA_XXCH_FRONT_HIGH_LEFT = 0x0002000,
DCA_XXCH_FRONT_HIGH_CENTER = 0x0004000,
DCA_XXCH_FRONT_HIGH_RIGHT = 0x0008000,
DCA_XXCH_LFE2 = 0x0010000,
DCA_XXCH_SIDE_FRONT_LEFT = 0x0020000,
DCA_XXCH_SIDE_FRONT_RIGHT = 0x0040000,
DCA_XXCH_OVERHEAD = 0x0080000,
DCA_XXCH_SIDE_HIGH_LEFT = 0x0100000,
DCA_XXCH_SIDE_HIGH_RIGHT = 0x0200000,
DCA_XXCH_REAR_HIGH_CENTER = 0x0400000,
DCA_XXCH_REAR_HIGH_LEFT = 0x0800000,
DCA_XXCH_REAR_HIGH_RIGHT = 0x1000000,
DCA_XXCH_REAR_LOW_CENTER = 0x2000000,
DCA_XXCH_REAR_LOW_LEFT = 0x4000000,
DCA_XXCH_REAR_LOW_RIGHT = 0x8000000,
};
static const uint32_t map_xxch_to_libav[28] = {
AV_CH_FRONT_CENTER,
AV_CH_FRONT_LEFT,
AV_CH_FRONT_RIGHT,
AV_CH_SIDE_LEFT,
AV_CH_SIDE_RIGHT,
AV_CH_LOW_FREQUENCY,
AV_CH_BACK_CENTER,
AV_CH_BACK_LEFT,
AV_CH_BACK_RIGHT,
AV_CH_BACK_LEFT, /* side surround left -- dup sur rear L */
AV_CH_BACK_RIGHT, /* side surround right -- dup sur rear R */
AV_CH_FRONT_LEFT_OF_CENTER,
AV_CH_FRONT_RIGHT_OF_CENTER,
AV_CH_TOP_FRONT_LEFT,
AV_CH_TOP_FRONT_CENTER,
AV_CH_TOP_FRONT_RIGHT,
AV_CH_LOW_FREQUENCY, /* lfe2 -- duplicate lfe1 position */
AV_CH_FRONT_LEFT_OF_CENTER, /* side front left -- dup front cntr L */
AV_CH_FRONT_RIGHT_OF_CENTER,/* side front right -- dup front cntr R */
AV_CH_TOP_CENTER, /* overhead */
AV_CH_TOP_FRONT_LEFT, /* side high left -- dup */
AV_CH_TOP_FRONT_RIGHT, /* side high right -- dup */
AV_CH_TOP_BACK_CENTER,
AV_CH_TOP_BACK_LEFT,
AV_CH_TOP_BACK_RIGHT,
AV_CH_BACK_CENTER, /* rear low center -- dup */
AV_CH_BACK_LEFT, /* rear low left -- dup */
AV_CH_BACK_RIGHT /* read low right -- dup */
};
enum DCAExtensionMask { enum DCAExtensionMask {
DCA_EXT_CORE = 0x001, ///< core in core substream DCA_EXT_CORE = 0x001, ///< core in core substream
DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream
...@@ -377,8 +439,20 @@ typedef struct { ...@@ -377,8 +439,20 @@ typedef struct {
int xch_base_channel; ///< index of first (only) channel containing XCH data int xch_base_channel; ///< index of first (only) channel containing XCH data
/* XXCH extension information */ /* XXCH extension information */
int xxch_spk_layout; int xxch_chset;
int xxch_nbits_spk_mask; int xxch_nbits_spk_mask;
int xxch_num_chsets; /* number of channel sets */
uint32_t xxch_core_spkmask;
int xxch_num_chans[4]; /* num in channel set */
uint32_t xxch_spk_masks[4]; /* speaker masks, last element is core mask */
int xxch_chset_nch[4];
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 */
int8_t xxch_order_tab[32];
int8_t lfe_index;
/* ExSS header parser */ /* ExSS header parser */
int static_fields; ///< static fields present int static_fields; ///< static fields present
...@@ -474,7 +548,11 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, ...@@ -474,7 +548,11 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel,
static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; 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 }; static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
int hdr_pos = 0, hdr_size = 0; int hdr_pos = 0, hdr_size = 0;
int mask[8]; 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 */ /* xxch has arbitrary sized audio coding headers */
if (xxch) { if (xxch) {
...@@ -482,22 +560,44 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, ...@@ -482,22 +560,44 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel,
hdr_size = get_bits(&s->gb, 7) + 1; 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; s->prim_channels = s->total_channels;
/* obtain speaker layout mask & mixdown coefficients if applicable */ /* obtain speaker layout mask & downmix coefficients for XXCH */
if (xxch) { if (xxch) {
s->xxch_spk_layout |= get_bits(&s->gb, s->xxch_nbits_spk_mask - 6); 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)) { if (get_bits1(&s->gb)) {
get_bits1(&s->gb); embedded_downmix = get_bits1(&s->gb);
skip_bits(&s->gb, 6); scale_factor =
1.0f / dca_downmix_scale_factors[get_bits(&s->gb, 6) << 2];
for (i = base_channel; i < s->prim_channels; i++) { 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); mask[i] = get_bits(&s->gb, s->xxch_nbits_spk_mask);
} }
for (j = base_channel; j < s->prim_channels; j++) { for (j = base_channel; j < s->prim_channels; j++) {
memset(s->xxch_dmix_coeff[j], 0, sizeof(s->xxch_dmix_coeff[0]));
if (mask[j])
s->xxch_dmix_embedded |= (embedded_downmix << j);
for (i = 0; i < s->xxch_nbits_spk_mask; i++) { for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
if (mask[j] & (1 << i)) { if (mask[j] & (1 << i)) {
int coeff = get_bits(&s->gb, 7); coeff = get_bits(&s->gb, 7);
sign = (coeff & 64) ? 1.0 : -1.0;
mag = dca_downmix_scale_factors[(coeff & 63) << 2];
ichan = av_popcount((acc_mask & ~DCA_XXCH_LFE1)
& ((1 << i) - 1));
s->xxch_dmix_coeff[j][ichan] = sign * mag * scale_factor;
} }
} }
} }
...@@ -609,7 +709,7 @@ static int dca_parse_frame_header(DCAContext *s) ...@@ -609,7 +709,7 @@ static int dca_parse_frame_header(DCAContext *s)
if (!s->bit_rate) if (!s->bit_rate)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
s->downmix = get_bits(&s->gb, 1); s->downmix = get_bits(&s->gb, 1); /* note: this is FixedBit == 0 */
s->dynrange = get_bits(&s->gb, 1); s->dynrange = get_bits(&s->gb, 1);
s->timestamp = get_bits(&s->gb, 1); s->timestamp = get_bits(&s->gb, 1);
s->aux_data = get_bits(&s->gb, 1); s->aux_data = get_bits(&s->gb, 1);
...@@ -1337,7 +1437,7 @@ static int dca_filter_channels(DCAContext *s, int block_index) ...@@ -1337,7 +1437,7 @@ static int dca_filter_channels(DCAContext *s, int block_index)
if (s->output & DCA_LFE) { if (s->output & DCA_LFE) {
lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, lfe_interpolation_fir(s, s->lfe, 2 * s->lfe,
s->lfe_data + 2 * s->lfe * (block_index + 4), s->lfe_data + 2 * s->lfe * (block_index + 4),
&s->samples[256 * dca_lfe_index[s->amode]], &s->samples[256 * s->lfe_index],
(1.0 / 256.0) * s->scale_bias); (1.0 / 256.0) * s->scale_bias);
/* Outputs 20bits pcm samples */ /* Outputs 20bits pcm samples */
} }
...@@ -1782,10 +1882,11 @@ static int dca_xxch_decode_frame(DCAContext *s) ...@@ -1782,10 +1882,11 @@ static int dca_xxch_decode_frame(DCAContext *s)
for (i = 0; i < num_chsets; i++) for (i = 0; i < num_chsets; i++)
fsize[i] = get_bits(&s->gb, 14) + 1; fsize[i] = get_bits(&s->gb, 14) + 1;
core_spk = get_bits(&s->gb, spkmsk_bits); core_spk = get_bits(&s->gb, spkmsk_bits);
s->xxch_core_spkmask = core_spk;
s->xxch_spk_layout = core_spk;
s->xxch_nbits_spk_mask = spkmsk_bits; s->xxch_nbits_spk_mask = spkmsk_bits;
s->xxch_downmix = 0;
s->xxch_dmix_embedded = 0;
/* skip to the end of the header */ /* skip to the end of the header */
i = get_bits_count(&s->gb); i = get_bits_count(&s->gb);
...@@ -1793,8 +1894,9 @@ static int dca_xxch_decode_frame(DCAContext *s) ...@@ -1793,8 +1894,9 @@ static int dca_xxch_decode_frame(DCAContext *s)
skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i); skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i);
for (chset = 0; chset < num_chsets; chset++) { for (chset = 0; chset < num_chsets; chset++) {
chstart = get_bits_count(&s->gb); chstart = get_bits_count(&s->gb);
base_channel = s->prim_channels; base_channel = s->prim_channels;
s->xxch_chset = chset;
/* XXCH and Core headers differ, see 6.4.2 "XXCH Channel Set Header" vs. /* XXCH and Core headers differ, see 6.4.2 "XXCH Channel Set Header" vs.
5.3.2 "Primary Audio Coding Header", DTS Spec 1.3.1 */ 5.3.2 "Primary Audio Coding Header", DTS Spec 1.3.1 */
...@@ -1814,6 +1916,7 @@ static int dca_xxch_decode_frame(DCAContext *s) ...@@ -1814,6 +1916,7 @@ static int dca_xxch_decode_frame(DCAContext *s)
if (chstart + fsize[chset] * 8 > i) if (chstart + fsize[chset] * 8 > i)
skip_bits_long(&s->gb, chstart + fsize[chset] * 8 - i); skip_bits_long(&s->gb, chstart + fsize[chset] * 8 - i);
} }
s->xxch_chset = num_chsets;
return 0; return 0;
} }
...@@ -1823,6 +1926,7 @@ static int dca_xxch_decode_frame(DCAContext *s) ...@@ -1823,6 +1926,7 @@ static int dca_xxch_decode_frame(DCAContext *s)
*/ */
static void dca_exss_parse_header(DCAContext *s) static void dca_exss_parse_header(DCAContext *s)
{ {
int asset_size[8];
int ss_index; int ss_index;
int blownup; int blownup;
int num_audiop = 1; int num_audiop = 1;
...@@ -1894,7 +1998,7 @@ static void dca_exss_parse_header(DCAContext *s) ...@@ -1894,7 +1998,7 @@ static void dca_exss_parse_header(DCAContext *s)
} }
for (i = 0; i < num_assets; i++) for (i = 0; i < num_assets; i++)
skip_bits_long(&s->gb, 16 + 4 * blownup); // asset size asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup);
for (i = 0; i < num_assets; i++) { for (i = 0; i < num_assets; i++) {
if (dca_exss_parse_asset_header(s)) if (dca_exss_parse_asset_header(s))
...@@ -1904,18 +2008,31 @@ static void dca_exss_parse_header(DCAContext *s) ...@@ -1904,18 +2008,31 @@ static void dca_exss_parse_header(DCAContext *s)
/* not parsed further, we were only interested in the extensions mask /* not parsed further, we were only interested in the extensions mask
* from the asset header */ * from the asset header */
if(num_assets > 0) { if (num_assets > 0) {
j = get_bits_count(&s->gb); j = get_bits_count(&s->gb);
if(start_posn + hdrsize * 8 > j) if (start_posn + hdrsize * 8 > j)
skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j); skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j);
/* check first asset for XBR -- should also check extension mask! */ for (i = 0; i < num_assets; i++) {
mkr = get_bits_long(&s->gb, 32); start_posn = get_bits_count(&s->gb);
mkr = get_bits_long(&s->gb, 32);
if(mkr == 0x655e315e) /* parse extensions that we know about */
dca_xbr_parse_frame(s); if (mkr == 0x655e315e) {
else dca_xbr_parse_frame(s);
av_log(s->avctx, AV_LOG_DEBUG, "DTS-MA: unknown marker = 0x%08x\n", mkr); } else if (mkr == 0x47004a03) {
dca_xxch_decode_frame(s);
s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */
} else {
av_log(s->avctx, AV_LOG_DEBUG,
"DTS-ExSS: unknown marker = 0x%08x\n", mkr);
}
/* skip to end of block */
j = get_bits_count(&s->gb);
if (start_posn + asset_size[i] * 8 > j)
skip_bits_long(&s->gb, start_posn + asset_size[i] * 8 - j);
}
} }
} }
...@@ -1928,16 +2045,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, ...@@ -1928,16 +2045,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
{ {
const uint8_t *buf = avpkt->data; const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size; int buf_size = avpkt->size;
int channel_mask;
int channel_layout;
int lfe_samples; int lfe_samples;
int num_core_channels = 0; int num_core_channels = 0;
int i, ret; int i, ret;
float *samples_flt; float *samples_flt;
float *src_chan;
float *dst_chan;
int16_t *samples_s16; int16_t *samples_s16;
DCAContext *s = avctx->priv_data; DCAContext *s = avctx->priv_data;
int channels;
int core_ss_end; int core_ss_end;
int channels;
float scale;
int achan;
int chset;
int mask;
int lavc;
int posn;
int j, k;
s->xch_present = 0; s->xch_present = 0;
...@@ -2072,44 +2198,117 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, ...@@ -2072,44 +2198,117 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
channels = s->prim_channels + !!s->lfe; channels = s->prim_channels + !!s->lfe;
if (s->amode < 16) { /* If we have XXCH then the channel layout is managed differently */
avctx->channel_layout = dca_core_channel_layout[s->amode]; /* note that XLL will also have another way to do things */
if (!(s->core_ext_mask & DCA_EXT_XXCH)
if (s->xch_present && (!avctx->request_channels || || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0
avctx->request_channels > num_core_channels + !!s->lfe)) { && avctx->request_channels
avctx->channel_layout |= AV_CH_BACK_CENTER; < num_core_channels + !!s->lfe + s->xxch_chset_nch[0]))
if (s->lfe) { { /* xxx should also do MA extensions */
avctx->channel_layout |= AV_CH_LOW_FREQUENCY; if (s->amode < 16) {
s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode]; avctx->channel_layout = dca_core_channel_layout[s->amode];
if (s->xch_present && (!avctx->request_channels ||
avctx->request_channels
> num_core_channels + !!s->lfe)) {
avctx->channel_layout |= AV_CH_BACK_CENTER;
if (s->lfe) {
avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];
} else {
s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];
}
} else { } else {
s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode]; 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 = dca_channel_reorder_lfe[s->amode];
} else
s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];
}
if (channels > !!s->lfe &&
s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
return AVERROR_INVALIDDATA;
if (avctx->request_channels == 2 && s->prim_channels > 2) {
channels = 2;
s->output = 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 = dca_lfe_index[s->amode];
} else { } else {
av_log(avctx, AV_LOG_ERROR,
"Non standard configuration %d !\n", s->amode);
return AVERROR_INVALIDDATA;
}
s->xxch_downmix = 0;
} else {
/* we only get here if an XXCH channel set can be added to the mix */
channel_mask = s->xxch_core_spkmask;
if (avctx->request_channels > 0
&& avctx->request_channels < s->prim_channels) {
channels = num_core_channels + !!s->lfe; channels = num_core_channels + !!s->lfe;
s->xch_present = 0; /* disable further xch processing */ for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i]
if (s->lfe) { <= avctx->request_channels; i++) {
avctx->channel_layout |= AV_CH_LOW_FREQUENCY; channels += s->xxch_chset_nch[i];
s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; channel_mask |= s->xxch_spk_masks[i];
} else }
s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; } else {
channels = s->prim_channels + !!s->lfe;
for (i = 0; i < s->xxch_chset; i++) {
channel_mask |= s->xxch_spk_masks[i];
}
} }
if (channels > !!s->lfe && /* Given the DTS spec'ed channel mask, generate an avcodec version */
s->channel_order_tab[channels - 1 - !!s->lfe] < 0) channel_layout = 0;
return AVERROR_INVALIDDATA; for (i = 0; i < s->xxch_nbits_spk_mask; ++i) {
if (channel_mask & (1 << i)) {
channel_layout |= map_xxch_to_libav[i];
}
}
if (avctx->request_channels == 2 && s->prim_channels > 2) { /* make sure that we have managed to get equivelant dts/avcodec channel
channels = 2; * masks in some sense -- unfortunately some channels could overlap */
s->output = DCA_STEREO; if (av_popcount(channel_mask) != av_popcount(channel_layout)) {
avctx->channel_layout = AV_CH_LAYOUT_STEREO; av_log(avctx, AV_LOG_DEBUG,
"DTS-XXCH: Inconsistant avcodec/dts channel layouts\n");
return AVERROR_INVALIDDATA;
} }
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 }; avctx->channel_layout = channel_layout;
s->channel_order_tab = dca_channel_order_native;
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 = map_xxch_to_libav[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;
} }
} else {
av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); s->channel_order_tab = s->xxch_order_tab;
return AVERROR_INVALIDDATA;
} }
if (avctx->channels != channels) { if (avctx->channels != channels) {
...@@ -2141,6 +2340,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, ...@@ -2141,6 +2340,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256); s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
} }
/* If stream contains XXCH, we might need to undo an embedded downmix */
if (s->xxch_downmix & s->xxch_dmix_embedded) {
mask = s->xxch_downmix & s->xxch_dmix_embedded;
for (j = 0; j < channels; j++) {
if (mask & (1 << j)) { /* this channel has been mixed-out */
src_chan = s->samples + s->channel_order_tab[j] * 256;
for (k = 0; k < channels - !!s->lfe; k++) {
achan = s->channel_order_tab[k];
scale = s->xxch_dmix_coeff[j][k];
if (scale != 0.0) {
dst_chan = s->samples + achan * 256;
s->fdsp.vector_fmac_scalar(dst_chan, src_chan,
-scale, 256);
}
}
}
}
}
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
s->fmt_conv.float_interleave(samples_flt, s->samples_chanptr, 256, s->fmt_conv.float_interleave(samples_flt, s->samples_chanptr, 256,
channels); channels);
......
...@@ -7528,6 +7528,40 @@ static const float dca_downmix_coeffs[65] = { ...@@ -7528,6 +7528,40 @@ static const float dca_downmix_coeffs[65] = {
0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000,
}; };
static const float dca_downmix_scale_factors[241] = {
0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496,
0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371,
0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758,
0.003981, 0.004217, 0.004467, 0.004732, 0.005012, 0.005309, 0.005623, 0.005957,
0.006310, 0.006683, 0.007079, 0.007499, 0.007943, 0.008414, 0.008913, 0.009441,
0.010000, 0.010593, 0.011220, 0.011885, 0.012589, 0.013335, 0.014125, 0.014962,
0.015849, 0.016788, 0.017783, 0.018836, 0.019953, 0.021135, 0.022387, 0.023714,
0.025119, 0.026607, 0.028184, 0.029854, 0.031623, 0.032546, 0.033497, 0.034475,
0.035481, 0.036517, 0.037584, 0.038681, 0.039811, 0.040973, 0.042170, 0.043401,
0.044668, 0.045973, 0.047315, 0.048697, 0.050119, 0.051582, 0.053088, 0.054639,
0.056234, 0.057876, 0.059566, 0.061306, 0.063096, 0.064938, 0.066834, 0.068786,
0.070795, 0.072862, 0.074989, 0.077179, 0.079433, 0.081752, 0.084140, 0.086596,
0.089125, 0.091728, 0.094406, 0.097163, 0.100000, 0.102920, 0.105925, 0.109018,
0.112202, 0.115478, 0.118850, 0.122321, 0.125893, 0.129569, 0.133352, 0.137246,
0.141254, 0.145378, 0.149624, 0.153993, 0.158489, 0.163117, 0.167880, 0.172783,
0.177828, 0.180406, 0.183021, 0.185674, 0.188365, 0.191095, 0.193865, 0.196675,
0.199526, 0.202418, 0.205353, 0.208329, 0.211349, 0.214412, 0.217520, 0.220673,
0.223872, 0.227117, 0.230409, 0.233749, 0.237137, 0.240575, 0.244062, 0.247600,
0.251189, 0.254830, 0.258523, 0.262271, 0.266073, 0.269929, 0.273842, 0.277811,
0.281838, 0.285924, 0.290068, 0.294273, 0.298538, 0.302866, 0.307256, 0.311709,
0.316228, 0.320812, 0.325462, 0.330179, 0.334965, 0.339821, 0.344747, 0.349744,
0.354813, 0.359956, 0.365174, 0.370467, 0.375837, 0.381285, 0.386812, 0.392419,
0.398107, 0.403878, 0.409732, 0.415671, 0.421697, 0.427809, 0.434010, 0.440301,
0.446684, 0.453158, 0.459727, 0.466391, 0.473151, 0.480010, 0.486968, 0.494026,
0.501187, 0.508452, 0.515822, 0.523299, 0.530884, 0.538580, 0.546387, 0.554307,
0.562341, 0.570493, 0.578762, 0.587151, 0.595662, 0.604296, 0.613056, 0.621942,
0.630957, 0.640103, 0.649382, 0.658795, 0.668344, 0.678032, 0.687860, 0.697831,
0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979,
0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517,
0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712,
1.000000
};
static const uint8_t dca_default_coeffs[10][5][2] = { static const uint8_t dca_default_coeffs[10][5][2] = {
{ { 13, 13 }, }, { { 13, 13 }, },
{ { 0, 64 }, { 64, 0 }, }, { { 0, 64 }, { 64, 0 }, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment