mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
dcadec: use float planar sample format
This commit is contained in:
parent
cbf6ee7823
commit
64c312aa29
@ -354,11 +354,9 @@ typedef struct {
|
|||||||
DECLARE_ALIGNED(32, float, raXin)[32];
|
DECLARE_ALIGNED(32, float, raXin)[32];
|
||||||
|
|
||||||
int output; ///< type of output
|
int output; ///< type of output
|
||||||
float scale_bias; ///< output scale
|
|
||||||
|
|
||||||
DECLARE_ALIGNED(32, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
|
DECLARE_ALIGNED(32, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
|
||||||
DECLARE_ALIGNED(32, float, samples)[(DCA_PRIM_CHANNELS_MAX + 1) * 256];
|
float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1];
|
||||||
const float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1];
|
|
||||||
|
|
||||||
uint8_t dca_buffer[DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_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 dca_buffer_size; ///< how much data is in the dca_buffer
|
||||||
@ -1007,20 +1005,20 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* downmixing routines */
|
/* downmixing routines */
|
||||||
#define MIX_REAR1(samples, si1, rs, coef) \
|
#define MIX_REAR1(samples, s1, rs, coef) \
|
||||||
samples[i] += samples[si1] * coef[rs][0]; \
|
samples[0][i] += samples[s1][i] * coef[rs][0]; \
|
||||||
samples[i+256] += samples[si1] * coef[rs][1];
|
samples[1][i] += samples[s1][i] * coef[rs][1];
|
||||||
|
|
||||||
#define MIX_REAR2(samples, si1, si2, rs, coef) \
|
#define MIX_REAR2(samples, s1, s2, rs, coef) \
|
||||||
samples[i] += samples[si1] * coef[rs][0] + samples[si2] * coef[rs + 1][0]; \
|
samples[0][i] += samples[s1][i] * coef[rs][0] + samples[s2][i] * coef[rs + 1][0]; \
|
||||||
samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs + 1][1];
|
samples[1][i] += samples[s1][i] * coef[rs][1] + samples[s2][i] * coef[rs + 1][1];
|
||||||
|
|
||||||
#define MIX_FRONT3(samples, coef) \
|
#define MIX_FRONT3(samples, coef) \
|
||||||
t = samples[i + c]; \
|
t = samples[c][i]; \
|
||||||
u = samples[i + l]; \
|
u = samples[l][i]; \
|
||||||
v = samples[i + r]; \
|
v = samples[r][i]; \
|
||||||
samples[i] = t * coef[0][0] + u * coef[1][0] + v * coef[2][0]; \
|
samples[0][i] = t * coef[0][0] + u * coef[1][0] + v * coef[2][0]; \
|
||||||
samples[i+256] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1];
|
samples[1][i] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1];
|
||||||
|
|
||||||
#define DOWNMIX_TO_STEREO(op1, op2) \
|
#define DOWNMIX_TO_STEREO(op1, op2) \
|
||||||
for (i = 0; i < 256; i++) { \
|
for (i = 0; i < 256; i++) { \
|
||||||
@ -1028,7 +1026,7 @@ 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 downmix_coef[DCA_PRIM_CHANNELS_MAX][2],
|
int downmix_coef[DCA_PRIM_CHANNELS_MAX][2],
|
||||||
const int8_t *channel_mapping)
|
const int8_t *channel_mapping)
|
||||||
{
|
{
|
||||||
@ -1053,36 +1051,36 @@ static void dca_downmix(float *samples, int srcfmt,
|
|||||||
case DCA_STEREO:
|
case DCA_STEREO:
|
||||||
break;
|
break;
|
||||||
case DCA_3F:
|
case DCA_3F:
|
||||||
c = channel_mapping[0] * 256;
|
c = channel_mapping[0];
|
||||||
l = channel_mapping[1] * 256;
|
l = channel_mapping[1];
|
||||||
r = channel_mapping[2] * 256;
|
r = channel_mapping[2];
|
||||||
DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), );
|
DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), );
|
||||||
break;
|
break;
|
||||||
case DCA_2F1R:
|
case DCA_2F1R:
|
||||||
s = channel_mapping[2] * 256;
|
s = channel_mapping[2];
|
||||||
DOWNMIX_TO_STEREO(MIX_REAR1(samples, i + s, 2, coef), );
|
DOWNMIX_TO_STEREO(MIX_REAR1(samples, s, 2, coef), );
|
||||||
break;
|
break;
|
||||||
case DCA_3F1R:
|
case DCA_3F1R:
|
||||||
c = channel_mapping[0] * 256;
|
c = channel_mapping[0];
|
||||||
l = channel_mapping[1] * 256;
|
l = channel_mapping[1];
|
||||||
r = channel_mapping[2] * 256;
|
r = channel_mapping[2];
|
||||||
s = channel_mapping[3] * 256;
|
s = channel_mapping[3];
|
||||||
DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),
|
DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),
|
||||||
MIX_REAR1(samples, i + s, 3, coef));
|
MIX_REAR1(samples, s, 3, coef));
|
||||||
break;
|
break;
|
||||||
case DCA_2F2R:
|
case DCA_2F2R:
|
||||||
sl = channel_mapping[2] * 256;
|
sl = channel_mapping[2];
|
||||||
sr = channel_mapping[3] * 256;
|
sr = channel_mapping[3];
|
||||||
DOWNMIX_TO_STEREO(MIX_REAR2(samples, i + sl, i + sr, 2, coef), );
|
DOWNMIX_TO_STEREO(MIX_REAR2(samples, sl, sr, 2, coef), );
|
||||||
break;
|
break;
|
||||||
case DCA_3F2R:
|
case DCA_3F2R:
|
||||||
c = channel_mapping[0] * 256;
|
c = channel_mapping[0];
|
||||||
l = channel_mapping[1] * 256;
|
l = channel_mapping[1];
|
||||||
r = channel_mapping[2] * 256;
|
r = channel_mapping[2];
|
||||||
sl = channel_mapping[3] * 256;
|
sl = channel_mapping[3];
|
||||||
sr = channel_mapping[4] * 256;
|
sr = channel_mapping[4];
|
||||||
DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),
|
DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),
|
||||||
MIX_REAR2(samples, i + sl, i + sr, 3, coef));
|
MIX_REAR2(samples, sl, sr, 3, coef));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1279,21 +1277,21 @@ static int dca_filter_channels(DCAContext *s, int block_index)
|
|||||||
/* static float pcm_to_double[8] = { 32768.0, 32768.0, 524288.0, 524288.0,
|
/* static float pcm_to_double[8] = { 32768.0, 32768.0, 524288.0, 524288.0,
|
||||||
0, 8388608.0, 8388608.0 };*/
|
0, 8388608.0, 8388608.0 };*/
|
||||||
qmf_32_subbands(s, k, subband_samples[k],
|
qmf_32_subbands(s, k, subband_samples[k],
|
||||||
&s->samples[256 * s->channel_order_tab[k]],
|
s->samples_chanptr[s->channel_order_tab[k]],
|
||||||
M_SQRT1_2 * s->scale_bias /* pcm_to_double[s->source_pcm_res] */);
|
M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Down mixing */
|
/* Down mixing */
|
||||||
if (s->avctx->request_channels == 2 && s->prim_channels > 2) {
|
if (s->avctx->request_channels == 2 && s->prim_channels > 2) {
|
||||||
dca_downmix(s->samples, s->amode, s->downmix_coef, s->channel_order_tab);
|
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,
|
||||||
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_chanptr[dca_lfe_index[s->amode]],
|
||||||
(1.0 / 256.0) * s->scale_bias);
|
1.0 / (256.0 * 32768.0));
|
||||||
/* Outputs 20bits pcm samples */
|
/* Outputs 20bits pcm samples */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1656,8 +1654,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
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;
|
||||||
int16_t *samples_s16;
|
|
||||||
DCAContext *s = avctx->priv_data;
|
DCAContext *s = avctx->priv_data;
|
||||||
int channels;
|
int channels;
|
||||||
int core_ss_end;
|
int core_ss_end;
|
||||||
@ -1853,33 +1850,26 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
samples_flt = (float *) s->frame.data[0];
|
samples_flt = (float **) s->frame.extended_data;
|
||||||
samples_s16 = (int16_t *) s->frame.data[0];
|
|
||||||
|
|
||||||
/* filter to get final output */
|
/* filter to get final output */
|
||||||
for (i = 0; i < (s->sample_blocks / 8); i++) {
|
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;
|
||||||
|
|
||||||
dca_filter_channels(s, i);
|
dca_filter_channels(s, i);
|
||||||
|
|
||||||
/* If this was marked as a DTS-ES stream we need to subtract back- */
|
/* If this was marked as a DTS-ES stream we need to subtract back- */
|
||||||
/* channel from SL & SR to remove matrixed back-channel signal */
|
/* channel from SL & SR to remove matrixed back-channel signal */
|
||||||
if ((s->source_pcm_res & 1) && s->xch_present) {
|
if ((s->source_pcm_res & 1) && s->xch_present) {
|
||||||
float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256;
|
float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]];
|
||||||
float *lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256;
|
float *lt_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]];
|
||||||
float *rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
|
float *rt_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]];
|
||||||
s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
|
s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
|
||||||
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 (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
|
|
||||||
s->fmt_conv.float_interleave(samples_flt, s->samples_chanptr, 256,
|
|
||||||
channels);
|
|
||||||
samples_flt += 256 * channels;
|
|
||||||
} else {
|
|
||||||
s->fmt_conv.float_to_int16_interleave(samples_s16,
|
|
||||||
s->samples_chanptr, 256,
|
|
||||||
channels);
|
|
||||||
samples_s16 += 256 * channels;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update lfe history */
|
/* update lfe history */
|
||||||
@ -1904,7 +1894,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
static av_cold int dca_decode_init(AVCodecContext *avctx)
|
static av_cold int dca_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
DCAContext *s = avctx->priv_data;
|
DCAContext *s = avctx->priv_data;
|
||||||
int i;
|
|
||||||
|
|
||||||
s->avctx = avctx;
|
s->avctx = avctx;
|
||||||
dca_init_vlcs();
|
dca_init_vlcs();
|
||||||
@ -1915,16 +1904,7 @@ static av_cold int dca_decode_init(AVCodecContext *avctx)
|
|||||||
ff_dcadsp_init(&s->dcadsp);
|
ff_dcadsp_init(&s->dcadsp);
|
||||||
ff_fmt_convert_init(&s->fmt_conv, avctx);
|
ff_fmt_convert_init(&s->fmt_conv, avctx);
|
||||||
|
|
||||||
for (i = 0; i < DCA_PRIM_CHANNELS_MAX + 1; i++)
|
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||||
s->samples_chanptr[i] = s->samples + i * 256;
|
|
||||||
|
|
||||||
if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
|
|
||||||
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
|
|
||||||
s->scale_bias = 1.0 / 32768.0;
|
|
||||||
} else {
|
|
||||||
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
|
|
||||||
s->scale_bias = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allow downmixing to stereo */
|
/* allow downmixing to stereo */
|
||||||
if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
|
if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
|
||||||
@ -1964,8 +1944,7 @@ AVCodec ff_dca_decoder = {
|
|||||||
.close = dca_decode_end,
|
.close = dca_decode_end,
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
|
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
|
||||||
.capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
|
.capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
|
||||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
|
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||||
AV_SAMPLE_FMT_S16,
|
|
||||||
AV_SAMPLE_FMT_NONE },
|
AV_SAMPLE_FMT_NONE },
|
||||||
.profiles = NULL_IF_CONFIG_SMALL(profiles),
|
.profiles = NULL_IF_CONFIG_SMALL(profiles),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user