mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-28 12:32:17 +02:00
Merge commit 'aaa44d0299338e3bc90128816c21dbfab06cdb48'
* commit 'aaa44d0299338e3bc90128816c21dbfab06cdb48': dca: support mixing LFE in dca_downmix. Conflicts: libavcodec/dcadec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
97468463a2
@ -7551,17 +7551,17 @@ static const float dca_dmixtable[241] = {
|
|||||||
1.000000,
|
1.000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const float dca_default_coeffs[10][5][2] = {
|
static const float dca_default_coeffs[10][6][2] = {
|
||||||
{ { 0.707107, 0.707107 }, }, // A
|
{ { 0.707107, 0.707107 }, { 0.000000, 0.000000 }, }, // A [LFE]
|
||||||
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, }, // A + B (dual mono)
|
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // A + B (dual mono) [LFE]
|
||||||
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, }, // L + R (stereo)
|
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // L + R (stereo) [LFE]
|
||||||
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, }, // (L+R) + (L-R) (sum-difference)
|
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // (L+R) + (L-R) (sum-difference) [LFE]
|
||||||
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, }, // LT + RT (left and right total)
|
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // LT + RT (left and right total) [LFE]
|
||||||
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, }, // C + L + R
|
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.000000, 0.000000 }, }, // C + L + R [LFE]
|
||||||
{ { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, }, // L + R + S
|
{ { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + S [LFE]
|
||||||
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, }, // C + L + R + S
|
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + S [LFE]
|
||||||
{ { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, }, // L + R + SL + SR
|
{ { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + SL + SR [LFE]
|
||||||
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, }, // C + L + R + SL + SR
|
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE]
|
||||||
};
|
};
|
||||||
|
|
||||||
/* downmix coeffs
|
/* downmix coeffs
|
||||||
|
@ -399,7 +399,7 @@ typedef struct {
|
|||||||
int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient)
|
int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient)
|
||||||
int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook
|
int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook
|
||||||
int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors
|
int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors
|
||||||
float downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients
|
float downmix_coef[DCA_PRIM_CHANNELS_MAX + 1][2]; ///< stereo downmix coefficients
|
||||||
int dynrange_coef; ///< dynamic range coefficient
|
int dynrange_coef; ///< dynamic range coefficient
|
||||||
|
|
||||||
/* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1)
|
/* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1)
|
||||||
@ -1152,8 +1152,8 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
|
|||||||
op2 \
|
op2 \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dca_downmix(float **samples, int srcfmt,
|
static void dca_downmix(float **samples, int srcfmt, int lfe_present,
|
||||||
float coef[DCA_PRIM_CHANNELS_MAX][2],
|
float coef[DCA_PRIM_CHANNELS_MAX + 1][2],
|
||||||
const int8_t *channel_mapping)
|
const int8_t *channel_mapping)
|
||||||
{
|
{
|
||||||
int c, l, r, sl, sr, s;
|
int c, l, r, sl, sr, s;
|
||||||
@ -1203,6 +1203,14 @@ static void dca_downmix(float **samples, int srcfmt,
|
|||||||
MIX_REAR2(samples, sl, sr, 3, coef));
|
MIX_REAR2(samples, sl, sr, 3, coef));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (lfe_present) {
|
||||||
|
int lf_buf = dca_lfe_index[srcfmt];
|
||||||
|
int lf_idx = dca_channels [srcfmt];
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
samples[0][i] += samples[lf_buf][i] * coef[lf_idx][0];
|
||||||
|
samples[1][i] += samples[lf_buf][i] * coef[lf_idx][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1410,12 +1418,6 @@ static int dca_filter_channels(DCAContext *s, int block_index)
|
|||||||
M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
|
M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Down mixing */
|
|
||||||
if (s->prim_channels > 2 &&
|
|
||||||
s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
|
|
||||||
dca_downmix(s->samples_chanptr, s->amode, s->downmix_coef, s->channel_order_tab);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate LFE samples for this subsubframe FIXME!!! */
|
/* Generate LFE samples for this subsubframe FIXME!!! */
|
||||||
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,
|
||||||
@ -1425,6 +1427,13 @@ static int dca_filter_channels(DCAContext *s, int block_index)
|
|||||||
/* Outputs 20bits pcm samples */
|
/* Outputs 20bits pcm samples */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Downmixing to Stereo */
|
||||||
|
if (s->prim_channels + !!s->lfe > 2 &&
|
||||||
|
s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
|
||||||
|
dca_downmix(s->samples_chanptr, s->amode, !!s->lfe, s->downmix_coef,
|
||||||
|
s->channel_order_tab);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2145,53 +2154,52 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
/* record number of core channels incase less than max channels are requested */
|
/* record number of core channels incase less than max channels are requested */
|
||||||
num_core_channels = s->prim_channels;
|
num_core_channels = s->prim_channels;
|
||||||
|
|
||||||
if (s->prim_channels > 2 &&
|
if (s->prim_channels + !!s->lfe > 2 &&
|
||||||
avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
|
avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
|
||||||
/* Stereo downmix coefficients
|
/* Stereo downmix coefficients
|
||||||
*
|
*
|
||||||
* The decoder can only downmix to 2-channel, so we need to ensure
|
* The decoder can only downmix to 2-channel, so we need to ensure
|
||||||
* embedded downmix coefficients are actually targeting 2-channel.
|
* embedded downmix coefficients are actually targeting 2-channel.
|
||||||
*
|
*/
|
||||||
* Coefficients for the LFE channel are ignored (not supported) */
|
if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
|
||||||
if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
|
s->core_downmix_amode == DCA_STEREO_TOTAL)) {
|
||||||
s->core_downmix_amode == DCA_STEREO_TOTAL)) {
|
int sign, code;
|
||||||
int sign, code;
|
for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
|
||||||
for (i = 0; i < s->prim_channels; i++) {
|
sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;
|
||||||
sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;
|
code = s->core_downmix_codes[i][0] & 0x0FF;
|
||||||
code = s->core_downmix_codes[i][0] & 0x0FF;
|
s->downmix_coef[i][0] = (!code ? 0.0f :
|
||||||
s->downmix_coef[i][0] = (!code ? 0.0f :
|
sign * dca_dmixtable[code - 1]);
|
||||||
sign * dca_dmixtable[code - 1]);
|
sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;
|
||||||
sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;
|
code = s->core_downmix_codes[i][1] & 0x0FF;
|
||||||
code = s->core_downmix_codes[i][1] & 0x0FF;
|
s->downmix_coef[i][1] = (!code ? 0.0f :
|
||||||
s->downmix_coef[i][1] = (!code ? 0.0f :
|
sign * dca_dmixtable[code - 1]);
|
||||||
sign * dca_dmixtable[code - 1]);
|
}
|
||||||
|
} else {
|
||||||
|
int am = s->amode & DCA_CHANNEL_MASK;
|
||||||
|
if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {
|
||||||
|
av_log(s->avctx, AV_LOG_ERROR,
|
||||||
|
"Invalid channel mode %d\n", am);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
if (s->prim_channels + !!s->lfe >
|
||||||
|
FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
|
||||||
|
avpriv_request_sample(s->avctx, "Downmixing %d channels",
|
||||||
|
s->prim_channels + !!s->lfe);
|
||||||
|
return AVERROR_PATCHWELCOME;
|
||||||
|
}
|
||||||
|
for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
|
||||||
|
s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];
|
||||||
|
s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
av_dlog(s->avctx, "Stereo downmix coeffs:\n");
|
||||||
int am = s->amode & DCA_CHANNEL_MASK;
|
for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
|
||||||
if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {
|
av_dlog(s->avctx, "L, input channel %d = %f\n", i,
|
||||||
av_log(s->avctx, AV_LOG_ERROR,
|
s->downmix_coef[i][0]);
|
||||||
"Invalid channel mode %d\n", am);
|
av_dlog(s->avctx, "R, input channel %d = %f\n", i,
|
||||||
return AVERROR_INVALIDDATA;
|
s->downmix_coef[i][1]);
|
||||||
}
|
}
|
||||||
|
av_dlog(s->avctx, "\n");
|
||||||
if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
|
|
||||||
avpriv_request_sample(s->avctx, "Downmixing %d channels",
|
|
||||||
s->prim_channels);
|
|
||||||
return AVERROR_PATCHWELCOME;
|
|
||||||
}
|
|
||||||
for (i = 0; i < s->prim_channels; i++) {
|
|
||||||
s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];
|
|
||||||
s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
av_dlog(s->avctx, "Stereo downmix coeffs:\n");
|
|
||||||
for (i = 0; i < s->prim_channels; i++) {
|
|
||||||
av_dlog(s->avctx, "L, input channel %d = %f\n", i,
|
|
||||||
s->downmix_coef[i][0]);
|
|
||||||
av_dlog(s->avctx, "R, input channel %d = %f\n", i,
|
|
||||||
s->downmix_coef[i][1]);
|
|
||||||
}
|
|
||||||
av_dlog(s->avctx, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->ext_coding)
|
if (s->ext_coding)
|
||||||
@ -2348,7 +2356,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->prim_channels > 2 &&
|
if (s->prim_channels + !!s->lfe > 2 &&
|
||||||
avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
|
avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
|
||||||
channels = 2;
|
channels = 2;
|
||||||
s->output = DCA_STEREO;
|
s->output = DCA_STEREO;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user