Reviewed-by: Benjamin Larsson <benjamin@southpole.se>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -95,6 +95,68 @@ enum DCAExSSSpeakerMask { |
95 | 95 |
DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000, |
96 | 96 |
}; |
97 | 97 |
|
98 |
+enum DCAXxchSpeakerMask { |
|
99 |
+ DCA_XXCH_FRONT_CENTER = 0x0000001, |
|
100 |
+ DCA_XXCH_FRONT_LEFT = 0x0000002, |
|
101 |
+ DCA_XXCH_FRONT_RIGHT = 0x0000004, |
|
102 |
+ DCA_XXCH_SIDE_REAR_LEFT = 0x0000008, |
|
103 |
+ DCA_XXCH_SIDE_REAR_RIGHT = 0x0000010, |
|
104 |
+ DCA_XXCH_LFE1 = 0x0000020, |
|
105 |
+ DCA_XXCH_REAR_CENTER = 0x0000040, |
|
106 |
+ DCA_XXCH_SURROUND_REAR_LEFT = 0x0000080, |
|
107 |
+ DCA_XXCH_SURROUND_REAR_RIGHT = 0x0000100, |
|
108 |
+ DCA_XXCH_SIDE_SURROUND_LEFT = 0x0000200, |
|
109 |
+ DCA_XXCH_SIDE_SURROUND_RIGHT = 0x0000400, |
|
110 |
+ DCA_XXCH_FRONT_CENTER_LEFT = 0x0000800, |
|
111 |
+ DCA_XXCH_FRONT_CENTER_RIGHT = 0x0001000, |
|
112 |
+ DCA_XXCH_FRONT_HIGH_LEFT = 0x0002000, |
|
113 |
+ DCA_XXCH_FRONT_HIGH_CENTER = 0x0004000, |
|
114 |
+ DCA_XXCH_FRONT_HIGH_RIGHT = 0x0008000, |
|
115 |
+ DCA_XXCH_LFE2 = 0x0010000, |
|
116 |
+ DCA_XXCH_SIDE_FRONT_LEFT = 0x0020000, |
|
117 |
+ DCA_XXCH_SIDE_FRONT_RIGHT = 0x0040000, |
|
118 |
+ DCA_XXCH_OVERHEAD = 0x0080000, |
|
119 |
+ DCA_XXCH_SIDE_HIGH_LEFT = 0x0100000, |
|
120 |
+ DCA_XXCH_SIDE_HIGH_RIGHT = 0x0200000, |
|
121 |
+ DCA_XXCH_REAR_HIGH_CENTER = 0x0400000, |
|
122 |
+ DCA_XXCH_REAR_HIGH_LEFT = 0x0800000, |
|
123 |
+ DCA_XXCH_REAR_HIGH_RIGHT = 0x1000000, |
|
124 |
+ DCA_XXCH_REAR_LOW_CENTER = 0x2000000, |
|
125 |
+ DCA_XXCH_REAR_LOW_LEFT = 0x4000000, |
|
126 |
+ DCA_XXCH_REAR_LOW_RIGHT = 0x8000000, |
|
127 |
+}; |
|
128 |
+ |
|
129 |
+static const uint32_t map_xxch_to_libav[28] = { |
|
130 |
+ AV_CH_FRONT_CENTER, |
|
131 |
+ AV_CH_FRONT_LEFT, |
|
132 |
+ AV_CH_FRONT_RIGHT, |
|
133 |
+ AV_CH_SIDE_LEFT, |
|
134 |
+ AV_CH_SIDE_RIGHT, |
|
135 |
+ AV_CH_LOW_FREQUENCY, |
|
136 |
+ AV_CH_BACK_CENTER, |
|
137 |
+ AV_CH_BACK_LEFT, |
|
138 |
+ AV_CH_BACK_RIGHT, |
|
139 |
+ AV_CH_BACK_LEFT, /* side surround left -- dup sur rear L */ |
|
140 |
+ AV_CH_BACK_RIGHT, /* side surround right -- dup sur rear R */ |
|
141 |
+ AV_CH_FRONT_LEFT_OF_CENTER, |
|
142 |
+ AV_CH_FRONT_RIGHT_OF_CENTER, |
|
143 |
+ AV_CH_TOP_FRONT_LEFT, |
|
144 |
+ AV_CH_TOP_FRONT_CENTER, |
|
145 |
+ AV_CH_TOP_FRONT_RIGHT, |
|
146 |
+ AV_CH_LOW_FREQUENCY, /* lfe2 -- duplicate lfe1 position */ |
|
147 |
+ AV_CH_FRONT_LEFT_OF_CENTER, /* side front left -- dup front cntr L */ |
|
148 |
+ AV_CH_FRONT_RIGHT_OF_CENTER,/* side front right -- dup front cntr R */ |
|
149 |
+ AV_CH_TOP_CENTER, /* overhead */ |
|
150 |
+ AV_CH_TOP_FRONT_LEFT, /* side high left -- dup */ |
|
151 |
+ AV_CH_TOP_FRONT_RIGHT, /* side high right -- dup */ |
|
152 |
+ AV_CH_TOP_BACK_CENTER, |
|
153 |
+ AV_CH_TOP_BACK_LEFT, |
|
154 |
+ AV_CH_TOP_BACK_RIGHT, |
|
155 |
+ AV_CH_BACK_CENTER, /* rear low center -- dup */ |
|
156 |
+ AV_CH_BACK_LEFT, /* rear low left -- dup */ |
|
157 |
+ AV_CH_BACK_RIGHT /* read low right -- dup */ |
|
158 |
+}; |
|
159 |
+ |
|
98 | 160 |
enum DCAExtensionMask { |
99 | 161 |
DCA_EXT_CORE = 0x001, ///< core in core substream |
100 | 162 |
DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream |
... | ... |
@@ -377,8 +439,20 @@ typedef struct { |
377 | 377 |
int xch_base_channel; ///< index of first (only) channel containing XCH data |
378 | 378 |
|
379 | 379 |
/* XXCH extension information */ |
380 |
- int xxch_spk_layout; |
|
380 |
+ int xxch_chset; |
|
381 | 381 |
int xxch_nbits_spk_mask; |
382 |
+ int xxch_num_chsets; /* number of channel sets */ |
|
383 |
+ uint32_t xxch_core_spkmask; |
|
384 |
+ int xxch_num_chans[4]; /* num in channel set */ |
|
385 |
+ uint32_t xxch_spk_masks[4]; /* speaker masks, last element is core mask */ |
|
386 |
+ int xxch_chset_nch[4]; |
|
387 |
+ |
|
388 |
+ uint32_t xxch_downmix; /* downmix enabled per channel set */ |
|
389 |
+ uint32_t xxch_dmix_embedded; /* lower layer has mix pre-embedded, per chset */ |
|
390 |
+ float xxch_dmix_coeff[DCA_PRIM_CHANNELS_MAX][32]; /* worst case sizing */ |
|
391 |
+ |
|
392 |
+ int8_t xxch_order_tab[32]; |
|
393 |
+ int8_t lfe_index; |
|
382 | 394 |
|
383 | 395 |
/* ExSS header parser */ |
384 | 396 |
int static_fields; ///< static fields present |
... | ... |
@@ -474,7 +548,11 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, |
474 | 474 |
static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; |
475 | 475 |
static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; |
476 | 476 |
int hdr_pos = 0, hdr_size = 0; |
477 |
- int mask[8]; |
|
477 |
+ float sign, mag, scale_factor; |
|
478 |
+ int this_chans, acc_mask; |
|
479 |
+ int embedded_downmix; |
|
480 |
+ int nchans, mask[8]; |
|
481 |
+ int coeff, ichan; |
|
478 | 482 |
|
479 | 483 |
/* xxch has arbitrary sized audio coding headers */ |
480 | 484 |
if (xxch) { |
... | ... |
@@ -482,22 +560,44 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, |
482 | 482 |
hdr_size = get_bits(&s->gb, 7) + 1; |
483 | 483 |
} |
484 | 484 |
|
485 |
- s->total_channels = get_bits(&s->gb, 3) + 1 + base_channel; |
|
485 |
+ nchans = get_bits(&s->gb, 3) + 1; |
|
486 |
+ s->total_channels = nchans + base_channel; |
|
486 | 487 |
s->prim_channels = s->total_channels; |
487 | 488 |
|
488 |
- /* obtain speaker layout mask & mixdown coefficients if applicable */ |
|
489 |
+ /* obtain speaker layout mask & downmix coefficients for XXCH */ |
|
489 | 490 |
if (xxch) { |
490 |
- s->xxch_spk_layout |= get_bits(&s->gb, s->xxch_nbits_spk_mask - 6); |
|
491 |
+ acc_mask = s->xxch_core_spkmask; |
|
492 |
+ |
|
493 |
+ this_chans = get_bits(&s->gb, s->xxch_nbits_spk_mask - 6) << 6; |
|
494 |
+ s->xxch_spk_masks[s->xxch_chset] = this_chans; |
|
495 |
+ s->xxch_chset_nch[s->xxch_chset] = nchans; |
|
496 |
+ |
|
497 |
+ for (i = 0; i <= s->xxch_chset; i++) |
|
498 |
+ acc_mask |= s->xxch_spk_masks[i]; |
|
499 |
+ |
|
500 |
+ /* check for downmixing information */ |
|
491 | 501 |
if (get_bits1(&s->gb)) { |
492 |
- get_bits1(&s->gb); |
|
493 |
- skip_bits(&s->gb, 6); |
|
502 |
+ embedded_downmix = get_bits1(&s->gb); |
|
503 |
+ scale_factor = |
|
504 |
+ 1.0f / dca_downmix_scale_factors[get_bits(&s->gb, 6) << 2]; |
|
505 |
+ |
|
494 | 506 |
for (i = base_channel; i < s->prim_channels; i++) { |
507 |
+ s->xxch_downmix |= (1 << i); |
|
495 | 508 |
mask[i] = get_bits(&s->gb, s->xxch_nbits_spk_mask); |
496 | 509 |
} |
510 |
+ |
|
497 | 511 |
for (j = base_channel; j < s->prim_channels; j++) { |
512 |
+ memset(s->xxch_dmix_coeff[j], 0, sizeof(s->xxch_dmix_coeff[0])); |
|
513 |
+ if (mask[j]) |
|
514 |
+ s->xxch_dmix_embedded |= (embedded_downmix << j); |
|
498 | 515 |
for (i = 0; i < s->xxch_nbits_spk_mask; i++) { |
499 | 516 |
if (mask[j] & (1 << i)) { |
500 |
- int coeff = get_bits(&s->gb, 7); |
|
517 |
+ coeff = get_bits(&s->gb, 7); |
|
518 |
+ sign = (coeff & 64) ? 1.0 : -1.0; |
|
519 |
+ mag = dca_downmix_scale_factors[(coeff & 63) << 2]; |
|
520 |
+ ichan = av_popcount((acc_mask & ~DCA_XXCH_LFE1) |
|
521 |
+ & ((1 << i) - 1)); |
|
522 |
+ s->xxch_dmix_coeff[j][ichan] = sign * mag * scale_factor; |
|
501 | 523 |
} |
502 | 524 |
} |
503 | 525 |
} |
... | ... |
@@ -609,7 +709,7 @@ static int dca_parse_frame_header(DCAContext *s) |
609 | 609 |
if (!s->bit_rate) |
610 | 610 |
return AVERROR_INVALIDDATA; |
611 | 611 |
|
612 |
- s->downmix = get_bits(&s->gb, 1); |
|
612 |
+ s->downmix = get_bits(&s->gb, 1); /* note: this is FixedBit == 0 */ |
|
613 | 613 |
s->dynrange = get_bits(&s->gb, 1); |
614 | 614 |
s->timestamp = get_bits(&s->gb, 1); |
615 | 615 |
s->aux_data = get_bits(&s->gb, 1); |
... | ... |
@@ -1337,7 +1437,7 @@ static int dca_filter_channels(DCAContext *s, int block_index) |
1337 | 1337 |
if (s->output & DCA_LFE) { |
1338 | 1338 |
lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, |
1339 | 1339 |
s->lfe_data + 2 * s->lfe * (block_index + 4), |
1340 |
- &s->samples[256 * dca_lfe_index[s->amode]], |
|
1340 |
+ &s->samples[256 * s->lfe_index], |
|
1341 | 1341 |
(1.0 / 256.0) * s->scale_bias); |
1342 | 1342 |
/* Outputs 20bits pcm samples */ |
1343 | 1343 |
} |
... | ... |
@@ -1782,10 +1882,11 @@ static int dca_xxch_decode_frame(DCAContext *s) |
1782 | 1782 |
for (i = 0; i < num_chsets; i++) |
1783 | 1783 |
fsize[i] = get_bits(&s->gb, 14) + 1; |
1784 | 1784 |
|
1785 |
- core_spk = get_bits(&s->gb, spkmsk_bits); |
|
1786 |
- |
|
1787 |
- s->xxch_spk_layout = core_spk; |
|
1785 |
+ core_spk = get_bits(&s->gb, spkmsk_bits); |
|
1786 |
+ s->xxch_core_spkmask = core_spk; |
|
1788 | 1787 |
s->xxch_nbits_spk_mask = spkmsk_bits; |
1788 |
+ s->xxch_downmix = 0; |
|
1789 |
+ s->xxch_dmix_embedded = 0; |
|
1789 | 1790 |
|
1790 | 1791 |
/* skip to the end of the header */ |
1791 | 1792 |
i = get_bits_count(&s->gb); |
... | ... |
@@ -1793,8 +1894,9 @@ static int dca_xxch_decode_frame(DCAContext *s) |
1793 | 1793 |
skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i); |
1794 | 1794 |
|
1795 | 1795 |
for (chset = 0; chset < num_chsets; chset++) { |
1796 |
- chstart = get_bits_count(&s->gb); |
|
1797 |
- base_channel = s->prim_channels; |
|
1796 |
+ chstart = get_bits_count(&s->gb); |
|
1797 |
+ base_channel = s->prim_channels; |
|
1798 |
+ s->xxch_chset = chset; |
|
1798 | 1799 |
|
1799 | 1800 |
/* XXCH and Core headers differ, see 6.4.2 "XXCH Channel Set Header" vs. |
1800 | 1801 |
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 | 1814 |
if (chstart + fsize[chset] * 8 > i) |
1815 | 1815 |
skip_bits_long(&s->gb, chstart + fsize[chset] * 8 - i); |
1816 | 1816 |
} |
1817 |
+ s->xxch_chset = num_chsets; |
|
1817 | 1818 |
|
1818 | 1819 |
return 0; |
1819 | 1820 |
} |
... | ... |
@@ -1823,6 +1926,7 @@ static int dca_xxch_decode_frame(DCAContext *s) |
1823 | 1823 |
*/ |
1824 | 1824 |
static void dca_exss_parse_header(DCAContext *s) |
1825 | 1825 |
{ |
1826 |
+ int asset_size[8]; |
|
1826 | 1827 |
int ss_index; |
1827 | 1828 |
int blownup; |
1828 | 1829 |
int num_audiop = 1; |
... | ... |
@@ -1894,7 +1998,7 @@ static void dca_exss_parse_header(DCAContext *s) |
1894 | 1894 |
} |
1895 | 1895 |
|
1896 | 1896 |
for (i = 0; i < num_assets; i++) |
1897 |
- skip_bits_long(&s->gb, 16 + 4 * blownup); // asset size |
|
1897 |
+ asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup); |
|
1898 | 1898 |
|
1899 | 1899 |
for (i = 0; i < num_assets; i++) { |
1900 | 1900 |
if (dca_exss_parse_asset_header(s)) |
... | ... |
@@ -1904,18 +2008,31 @@ static void dca_exss_parse_header(DCAContext *s) |
1904 | 1904 |
/* not parsed further, we were only interested in the extensions mask |
1905 | 1905 |
* from the asset header */ |
1906 | 1906 |
|
1907 |
- if(num_assets > 0) { |
|
1907 |
+ if (num_assets > 0) { |
|
1908 | 1908 |
j = get_bits_count(&s->gb); |
1909 |
- if(start_posn + hdrsize * 8 > j) |
|
1909 |
+ if (start_posn + hdrsize * 8 > j) |
|
1910 | 1910 |
skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j); |
1911 | 1911 |
|
1912 |
- /* check first asset for XBR -- should also check extension mask! */ |
|
1913 |
- mkr = get_bits_long(&s->gb, 32); |
|
1912 |
+ for (i = 0; i < num_assets; i++) { |
|
1913 |
+ start_posn = get_bits_count(&s->gb); |
|
1914 |
+ mkr = get_bits_long(&s->gb, 32); |
|
1914 | 1915 |
|
1915 |
- if(mkr == 0x655e315e) |
|
1916 |
- dca_xbr_parse_frame(s); |
|
1917 |
- else |
|
1918 |
- av_log(s->avctx, AV_LOG_DEBUG, "DTS-MA: unknown marker = 0x%08x\n", mkr); |
|
1916 |
+ /* parse extensions that we know about */ |
|
1917 |
+ if (mkr == 0x655e315e) { |
|
1918 |
+ dca_xbr_parse_frame(s); |
|
1919 |
+ } else if (mkr == 0x47004a03) { |
|
1920 |
+ dca_xxch_decode_frame(s); |
|
1921 |
+ s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */ |
|
1922 |
+ } else { |
|
1923 |
+ av_log(s->avctx, AV_LOG_DEBUG, |
|
1924 |
+ "DTS-ExSS: unknown marker = 0x%08x\n", mkr); |
|
1925 |
+ } |
|
1926 |
+ |
|
1927 |
+ /* skip to end of block */ |
|
1928 |
+ j = get_bits_count(&s->gb); |
|
1929 |
+ if (start_posn + asset_size[i] * 8 > j) |
|
1930 |
+ skip_bits_long(&s->gb, start_posn + asset_size[i] * 8 - j); |
|
1931 |
+ } |
|
1919 | 1932 |
} |
1920 | 1933 |
} |
1921 | 1934 |
|
... | ... |
@@ -1928,16 +2045,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, |
1928 | 1928 |
{ |
1929 | 1929 |
const uint8_t *buf = avpkt->data; |
1930 | 1930 |
int buf_size = avpkt->size; |
1931 |
- |
|
1931 |
+ int channel_mask; |
|
1932 |
+ int channel_layout; |
|
1932 | 1933 |
int lfe_samples; |
1933 | 1934 |
int num_core_channels = 0; |
1934 | 1935 |
int i, ret; |
1935 |
- float *samples_flt; |
|
1936 |
+ float *samples_flt; |
|
1937 |
+ float *src_chan; |
|
1938 |
+ float *dst_chan; |
|
1936 | 1939 |
int16_t *samples_s16; |
1937 | 1940 |
DCAContext *s = avctx->priv_data; |
1938 |
- int channels; |
|
1939 | 1941 |
int core_ss_end; |
1940 |
- |
|
1942 |
+ int channels; |
|
1943 |
+ float scale; |
|
1944 |
+ int achan; |
|
1945 |
+ int chset; |
|
1946 |
+ int mask; |
|
1947 |
+ int lavc; |
|
1948 |
+ int posn; |
|
1949 |
+ int j, k; |
|
1941 | 1950 |
|
1942 | 1951 |
s->xch_present = 0; |
1943 | 1952 |
|
... | ... |
@@ -2072,44 +2198,117 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, |
2072 | 2072 |
|
2073 | 2073 |
channels = s->prim_channels + !!s->lfe; |
2074 | 2074 |
|
2075 |
- if (s->amode < 16) { |
|
2076 |
- avctx->channel_layout = dca_core_channel_layout[s->amode]; |
|
2077 |
- |
|
2078 |
- if (s->xch_present && (!avctx->request_channels || |
|
2079 |
- avctx->request_channels > num_core_channels + !!s->lfe)) { |
|
2080 |
- avctx->channel_layout |= AV_CH_BACK_CENTER; |
|
2081 |
- if (s->lfe) { |
|
2082 |
- avctx->channel_layout |= AV_CH_LOW_FREQUENCY; |
|
2083 |
- s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode]; |
|
2075 |
+ /* If we have XXCH then the channel layout is managed differently */ |
|
2076 |
+ /* note that XLL will also have another way to do things */ |
|
2077 |
+ if (!(s->core_ext_mask & DCA_EXT_XXCH) |
|
2078 |
+ || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0 |
|
2079 |
+ && avctx->request_channels |
|
2080 |
+ < num_core_channels + !!s->lfe + s->xxch_chset_nch[0])) |
|
2081 |
+ { /* xxx should also do MA extensions */ |
|
2082 |
+ if (s->amode < 16) { |
|
2083 |
+ avctx->channel_layout = dca_core_channel_layout[s->amode]; |
|
2084 |
+ |
|
2085 |
+ if (s->xch_present && (!avctx->request_channels || |
|
2086 |
+ avctx->request_channels |
|
2087 |
+ > num_core_channels + !!s->lfe)) { |
|
2088 |
+ avctx->channel_layout |= AV_CH_BACK_CENTER; |
|
2089 |
+ if (s->lfe) { |
|
2090 |
+ avctx->channel_layout |= AV_CH_LOW_FREQUENCY; |
|
2091 |
+ s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode]; |
|
2092 |
+ } else { |
|
2093 |
+ s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode]; |
|
2094 |
+ } |
|
2084 | 2095 |
} else { |
2085 |
- s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode]; |
|
2096 |
+ channels = num_core_channels + !!s->lfe; |
|
2097 |
+ s->xch_present = 0; /* disable further xch processing */ |
|
2098 |
+ if (s->lfe) { |
|
2099 |
+ avctx->channel_layout |= AV_CH_LOW_FREQUENCY; |
|
2100 |
+ s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; |
|
2101 |
+ } else |
|
2102 |
+ s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; |
|
2103 |
+ } |
|
2104 |
+ |
|
2105 |
+ if (channels > !!s->lfe && |
|
2106 |
+ s->channel_order_tab[channels - 1 - !!s->lfe] < 0) |
|
2107 |
+ return AVERROR_INVALIDDATA; |
|
2108 |
+ |
|
2109 |
+ if (avctx->request_channels == 2 && s->prim_channels > 2) { |
|
2110 |
+ channels = 2; |
|
2111 |
+ s->output = DCA_STEREO; |
|
2112 |
+ avctx->channel_layout = AV_CH_LAYOUT_STEREO; |
|
2086 | 2113 |
} |
2114 |
+ else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) { |
|
2115 |
+ static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; |
|
2116 |
+ s->channel_order_tab = dca_channel_order_native; |
|
2117 |
+ } |
|
2118 |
+ s->lfe_index = dca_lfe_index[s->amode]; |
|
2087 | 2119 |
} else { |
2120 |
+ av_log(avctx, AV_LOG_ERROR, |
|
2121 |
+ "Non standard configuration %d !\n", s->amode); |
|
2122 |
+ return AVERROR_INVALIDDATA; |
|
2123 |
+ } |
|
2124 |
+ |
|
2125 |
+ s->xxch_downmix = 0; |
|
2126 |
+ } else { |
|
2127 |
+ /* we only get here if an XXCH channel set can be added to the mix */ |
|
2128 |
+ channel_mask = s->xxch_core_spkmask; |
|
2129 |
+ |
|
2130 |
+ if (avctx->request_channels > 0 |
|
2131 |
+ && avctx->request_channels < s->prim_channels) { |
|
2088 | 2132 |
channels = num_core_channels + !!s->lfe; |
2089 |
- s->xch_present = 0; /* disable further xch processing */ |
|
2090 |
- if (s->lfe) { |
|
2091 |
- avctx->channel_layout |= AV_CH_LOW_FREQUENCY; |
|
2092 |
- s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; |
|
2093 |
- } else |
|
2094 |
- s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; |
|
2133 |
+ for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i] |
|
2134 |
+ <= avctx->request_channels; i++) { |
|
2135 |
+ channels += s->xxch_chset_nch[i]; |
|
2136 |
+ channel_mask |= s->xxch_spk_masks[i]; |
|
2137 |
+ } |
|
2138 |
+ } else { |
|
2139 |
+ channels = s->prim_channels + !!s->lfe; |
|
2140 |
+ for (i = 0; i < s->xxch_chset; i++) { |
|
2141 |
+ channel_mask |= s->xxch_spk_masks[i]; |
|
2142 |
+ } |
|
2095 | 2143 |
} |
2096 | 2144 |
|
2097 |
- if (channels > !!s->lfe && |
|
2098 |
- s->channel_order_tab[channels - 1 - !!s->lfe] < 0) |
|
2099 |
- return AVERROR_INVALIDDATA; |
|
2145 |
+ /* Given the DTS spec'ed channel mask, generate an avcodec version */ |
|
2146 |
+ channel_layout = 0; |
|
2147 |
+ for (i = 0; i < s->xxch_nbits_spk_mask; ++i) { |
|
2148 |
+ if (channel_mask & (1 << i)) { |
|
2149 |
+ channel_layout |= map_xxch_to_libav[i]; |
|
2150 |
+ } |
|
2151 |
+ } |
|
2100 | 2152 |
|
2101 |
- if (avctx->request_channels == 2 && s->prim_channels > 2) { |
|
2102 |
- channels = 2; |
|
2103 |
- s->output = DCA_STEREO; |
|
2104 |
- avctx->channel_layout = AV_CH_LAYOUT_STEREO; |
|
2153 |
+ /* make sure that we have managed to get equivelant dts/avcodec channel |
|
2154 |
+ * masks in some sense -- unfortunately some channels could overlap */ |
|
2155 |
+ if (av_popcount(channel_mask) != av_popcount(channel_layout)) { |
|
2156 |
+ av_log(avctx, AV_LOG_DEBUG, |
|
2157 |
+ "DTS-XXCH: Inconsistant avcodec/dts channel layouts\n"); |
|
2158 |
+ return AVERROR_INVALIDDATA; |
|
2105 | 2159 |
} |
2106 |
- else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) { |
|
2107 |
- static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; |
|
2108 |
- s->channel_order_tab = dca_channel_order_native; |
|
2160 |
+ |
|
2161 |
+ avctx->channel_layout = channel_layout; |
|
2162 |
+ |
|
2163 |
+ if (!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) { |
|
2164 |
+ /* Estimate DTS --> avcodec ordering table */ |
|
2165 |
+ for (chset = -1, j = 0; chset < s->xxch_chset; ++chset) { |
|
2166 |
+ mask = chset >= 0 ? s->xxch_spk_masks[chset] |
|
2167 |
+ : s->xxch_core_spkmask; |
|
2168 |
+ for (i = 0; i < s->xxch_nbits_spk_mask; i++) { |
|
2169 |
+ if (mask & ~(DCA_XXCH_LFE1 | DCA_XXCH_LFE2) & (1 << i)) { |
|
2170 |
+ lavc = map_xxch_to_libav[i]; |
|
2171 |
+ posn = av_popcount(channel_layout & (lavc - 1)); |
|
2172 |
+ s->xxch_order_tab[j++] = posn; |
|
2173 |
+ } |
|
2174 |
+ } |
|
2175 |
+ } |
|
2176 |
+ |
|
2177 |
+ s->lfe_index = av_popcount(channel_layout & (AV_CH_LOW_FREQUENCY-1)); |
|
2178 |
+ } else { /* native ordering */ |
|
2179 |
+ for (i = 0; i < channels; i++) |
|
2180 |
+ s->xxch_order_tab[i] = i; |
|
2181 |
+ |
|
2182 |
+ s->lfe_index = channels - 1; |
|
2109 | 2183 |
} |
2110 |
- } else { |
|
2111 |
- av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); |
|
2112 |
- return AVERROR_INVALIDDATA; |
|
2184 |
+ |
|
2185 |
+ s->channel_order_tab = s->xxch_order_tab; |
|
2113 | 2186 |
} |
2114 | 2187 |
|
2115 | 2188 |
if (avctx->channels != channels) { |
... | ... |
@@ -2141,6 +2340,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, |
2141 | 2141 |
s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256); |
2142 | 2142 |
} |
2143 | 2143 |
|
2144 |
+ /* If stream contains XXCH, we might need to undo an embedded downmix */ |
|
2145 |
+ if (s->xxch_downmix & s->xxch_dmix_embedded) { |
|
2146 |
+ mask = s->xxch_downmix & s->xxch_dmix_embedded; |
|
2147 |
+ for (j = 0; j < channels; j++) { |
|
2148 |
+ if (mask & (1 << j)) { /* this channel has been mixed-out */ |
|
2149 |
+ src_chan = s->samples + s->channel_order_tab[j] * 256; |
|
2150 |
+ for (k = 0; k < channels - !!s->lfe; k++) { |
|
2151 |
+ achan = s->channel_order_tab[k]; |
|
2152 |
+ scale = s->xxch_dmix_coeff[j][k]; |
|
2153 |
+ if (scale != 0.0) { |
|
2154 |
+ dst_chan = s->samples + achan * 256; |
|
2155 |
+ s->fdsp.vector_fmac_scalar(dst_chan, src_chan, |
|
2156 |
+ -scale, 256); |
|
2157 |
+ } |
|
2158 |
+ } |
|
2159 |
+ } |
|
2160 |
+ } |
|
2161 |
+ } |
|
2162 |
+ |
|
2144 | 2163 |
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { |
2145 | 2164 |
s->fmt_conv.float_interleave(samples_flt, s->samples_chanptr, 256, |
2146 | 2165 |
channels); |
... | ... |
@@ -7528,6 +7528,40 @@ static const float dca_downmix_coeffs[65] = { |
7528 | 7528 |
0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, |
7529 | 7529 |
}; |
7530 | 7530 |
|
7531 |
+static const float dca_downmix_scale_factors[241] = { |
|
7532 |
+ 0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496, |
|
7533 |
+ 0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371, |
|
7534 |
+ 0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758, |
|
7535 |
+ 0.003981, 0.004217, 0.004467, 0.004732, 0.005012, 0.005309, 0.005623, 0.005957, |
|
7536 |
+ 0.006310, 0.006683, 0.007079, 0.007499, 0.007943, 0.008414, 0.008913, 0.009441, |
|
7537 |
+ 0.010000, 0.010593, 0.011220, 0.011885, 0.012589, 0.013335, 0.014125, 0.014962, |
|
7538 |
+ 0.015849, 0.016788, 0.017783, 0.018836, 0.019953, 0.021135, 0.022387, 0.023714, |
|
7539 |
+ 0.025119, 0.026607, 0.028184, 0.029854, 0.031623, 0.032546, 0.033497, 0.034475, |
|
7540 |
+ 0.035481, 0.036517, 0.037584, 0.038681, 0.039811, 0.040973, 0.042170, 0.043401, |
|
7541 |
+ 0.044668, 0.045973, 0.047315, 0.048697, 0.050119, 0.051582, 0.053088, 0.054639, |
|
7542 |
+ 0.056234, 0.057876, 0.059566, 0.061306, 0.063096, 0.064938, 0.066834, 0.068786, |
|
7543 |
+ 0.070795, 0.072862, 0.074989, 0.077179, 0.079433, 0.081752, 0.084140, 0.086596, |
|
7544 |
+ 0.089125, 0.091728, 0.094406, 0.097163, 0.100000, 0.102920, 0.105925, 0.109018, |
|
7545 |
+ 0.112202, 0.115478, 0.118850, 0.122321, 0.125893, 0.129569, 0.133352, 0.137246, |
|
7546 |
+ 0.141254, 0.145378, 0.149624, 0.153993, 0.158489, 0.163117, 0.167880, 0.172783, |
|
7547 |
+ 0.177828, 0.180406, 0.183021, 0.185674, 0.188365, 0.191095, 0.193865, 0.196675, |
|
7548 |
+ 0.199526, 0.202418, 0.205353, 0.208329, 0.211349, 0.214412, 0.217520, 0.220673, |
|
7549 |
+ 0.223872, 0.227117, 0.230409, 0.233749, 0.237137, 0.240575, 0.244062, 0.247600, |
|
7550 |
+ 0.251189, 0.254830, 0.258523, 0.262271, 0.266073, 0.269929, 0.273842, 0.277811, |
|
7551 |
+ 0.281838, 0.285924, 0.290068, 0.294273, 0.298538, 0.302866, 0.307256, 0.311709, |
|
7552 |
+ 0.316228, 0.320812, 0.325462, 0.330179, 0.334965, 0.339821, 0.344747, 0.349744, |
|
7553 |
+ 0.354813, 0.359956, 0.365174, 0.370467, 0.375837, 0.381285, 0.386812, 0.392419, |
|
7554 |
+ 0.398107, 0.403878, 0.409732, 0.415671, 0.421697, 0.427809, 0.434010, 0.440301, |
|
7555 |
+ 0.446684, 0.453158, 0.459727, 0.466391, 0.473151, 0.480010, 0.486968, 0.494026, |
|
7556 |
+ 0.501187, 0.508452, 0.515822, 0.523299, 0.530884, 0.538580, 0.546387, 0.554307, |
|
7557 |
+ 0.562341, 0.570493, 0.578762, 0.587151, 0.595662, 0.604296, 0.613056, 0.621942, |
|
7558 |
+ 0.630957, 0.640103, 0.649382, 0.658795, 0.668344, 0.678032, 0.687860, 0.697831, |
|
7559 |
+ 0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979, |
|
7560 |
+ 0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517, |
|
7561 |
+ 0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712, |
|
7562 |
+ 1.000000 |
|
7563 |
+}; |
|
7564 |
+ |
|
7531 | 7565 |
static const uint8_t dca_default_coeffs[10][5][2] = { |
7532 | 7566 |
{ { 13, 13 }, }, |
7533 | 7567 |
{ { 0, 64 }, { 64, 0 }, }, |