X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fdcadec.c;h=efd07055ecd0bb8d37a4f07df8754b4309ba5daf;hb=76b19a3984359b3be44d4f7e4e69b7b86729a622;hp=a0a5ea948d50c733390275ce8f042269ee36d493;hpb=1218777ffd152287244349d4ff9e1cbc84fa2c54;p=ffmpeg diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index a0a5ea948d5..efd07055ecd 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -26,14 +26,14 @@ #include #include +#include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/float_dsp.h" -#include "libavutil/intmath.h" +#include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" -#include "libavutil/audioconvert.h" +#include "libavutil/samplefmt.h" #include "avcodec.h" -#include "dsputil.h" #include "fft.h" #include "get_bits.h" #include "put_bits.h" @@ -41,9 +41,11 @@ #include "dcahuff.h" #include "dca.h" #include "dca_parser.h" +#include "mathops.h" #include "synth_filter.h" #include "dcadsp.h" #include "fmtconvert.h" +#include "internal.h" #if ARCH_ARM # include "arm/dca.h" @@ -283,7 +285,6 @@ static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, typedef struct { AVCodecContext *avctx; - AVFrame frame; /* Frame header */ int frame_type; ///< type of the current frame int samples_deficit; ///< deficit sample count @@ -316,7 +317,6 @@ typedef struct { /* Primary audio coding header */ int subframes; ///< number of subframes - int is_channels_set; ///< check for if the channel number is already set int total_channels; ///< number of channels including extensions int prim_channels; ///< number of primary audio channels int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count @@ -354,11 +354,12 @@ typedef struct { DECLARE_ALIGNED(32, float, raXin)[32]; 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, samples)[(DCA_PRIM_CHANNELS_MAX + 1) * 256]; - const float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1]; + float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1]; + float *extra_channels[DCA_PRIM_CHANNELS_MAX + 1]; + uint8_t *extra_channels_buffer; + unsigned int extra_channels_buffer_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 @@ -1007,20 +1008,20 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select, } /* downmixing routines */ -#define MIX_REAR1(samples, si1, rs, coef) \ - samples[i] += samples[si1] * coef[rs][0]; \ - samples[i+256] += samples[si1] * coef[rs][1]; +#define MIX_REAR1(samples, s1, rs, coef) \ + samples[0][i] += samples[s1][i] * coef[rs][0]; \ + samples[1][i] += samples[s1][i] * coef[rs][1]; -#define MIX_REAR2(samples, si1, si2, rs, coef) \ - samples[i] += samples[si1] * coef[rs][0] + samples[si2] * coef[rs + 1][0]; \ - samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs + 1][1]; +#define MIX_REAR2(samples, s1, s2, rs, coef) \ + samples[0][i] += samples[s1][i] * coef[rs][0] + samples[s2][i] * coef[rs + 1][0]; \ + samples[1][i] += samples[s1][i] * coef[rs][1] + samples[s2][i] * coef[rs + 1][1]; #define MIX_FRONT3(samples, coef) \ - t = samples[i + c]; \ - u = samples[i + l]; \ - v = samples[i + r]; \ - samples[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]; + t = samples[c][i]; \ + u = samples[l][i]; \ + v = samples[r][i]; \ + samples[0][i] = t * coef[0][0] + u * coef[1][0] + v * coef[2][0]; \ + samples[1][i] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1]; #define DOWNMIX_TO_STEREO(op1, op2) \ for (i = 0; i < 256; i++) { \ @@ -1028,7 +1029,7 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select, 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], const int8_t *channel_mapping) { @@ -1053,36 +1054,36 @@ static void dca_downmix(float *samples, int srcfmt, case DCA_STEREO: break; case DCA_3F: - c = channel_mapping[0] * 256; - l = channel_mapping[1] * 256; - r = channel_mapping[2] * 256; + c = channel_mapping[0]; + l = channel_mapping[1]; + r = channel_mapping[2]; DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), ); break; case DCA_2F1R: - s = channel_mapping[2] * 256; - DOWNMIX_TO_STEREO(MIX_REAR1(samples, i + s, 2, coef), ); + s = channel_mapping[2]; + DOWNMIX_TO_STEREO(MIX_REAR1(samples, s, 2, coef), ); break; case DCA_3F1R: - c = channel_mapping[0] * 256; - l = channel_mapping[1] * 256; - r = channel_mapping[2] * 256; - s = channel_mapping[3] * 256; + c = channel_mapping[0]; + l = channel_mapping[1]; + r = channel_mapping[2]; + s = channel_mapping[3]; DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), - MIX_REAR1(samples, i + s, 3, coef)); + MIX_REAR1(samples, s, 3, coef)); break; case DCA_2F2R: - sl = channel_mapping[2] * 256; - sr = channel_mapping[3] * 256; - DOWNMIX_TO_STEREO(MIX_REAR2(samples, i + sl, i + sr, 2, coef), ); + sl = channel_mapping[2]; + sr = channel_mapping[3]; + DOWNMIX_TO_STEREO(MIX_REAR2(samples, sl, sr, 2, coef), ); break; case DCA_3F2R: - c = channel_mapping[0] * 256; - l = channel_mapping[1] * 256; - r = channel_mapping[2] * 256; - sl = channel_mapping[3] * 256; - sr = channel_mapping[4] * 256; + c = channel_mapping[0]; + l = channel_mapping[1]; + r = channel_mapping[2]; + sl = channel_mapping[3]; + sr = channel_mapping[4]; DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), - MIX_REAR2(samples, i + sl, i + sr, 3, coef)); + MIX_REAR2(samples, sl, sr, 3, coef)); break; } } @@ -1278,22 +1279,23 @@ static int dca_filter_channels(DCAContext *s, int block_index) for (k = 0; k < s->prim_channels; k++) { /* static float pcm_to_double[8] = { 32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0 };*/ - qmf_32_subbands(s, k, subband_samples[k], - &s->samples[256 * s->channel_order_tab[k]], - M_SQRT1_2 * s->scale_bias /* pcm_to_double[s->source_pcm_res] */); + if (s->channel_order_tab[k] >= 0) + qmf_32_subbands(s, k, subband_samples[k], + s->samples_chanptr[s->channel_order_tab[k]], + M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */); } /* Down mixing */ 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!!! */ if (s->output & DCA_LFE) { lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, s->lfe_data + 2 * s->lfe * (block_index + 4), - &s->samples[256 * dca_lfe_index[s->amode]], - (1.0 / 256.0) * s->scale_bias); + s->samples_chanptr[dca_lfe_index[s->amode]], + 1.0 / (256.0 * 32768.0)); /* Outputs 20bits pcm samples */ } @@ -1650,16 +1652,16 @@ static void dca_exss_parse_header(DCAContext *s) static int dca_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int lfe_samples; int num_core_channels = 0; int i, ret; - float *samples_flt; - int16_t *samples_s16; + float **samples_flt; DCAContext *s = avctx->priv_data; - int channels; + int channels, full_channels; int core_ss_end; @@ -1793,7 +1795,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, avctx->profile = s->profile; - channels = s->prim_channels + !!s->lfe; + full_channels = channels = s->prim_channels + !!s->lfe; if (s->amode < 16) { avctx->channel_layout = dca_core_channel_layout[s->amode]; @@ -1830,56 +1832,57 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); return AVERROR_INVALIDDATA; } - - - /* There is nothing that prevents a dts frame to change channel configuration - but Libav doesn't support that so only set the channels if it is previously - unset. Ideally during the first probe for channels the crc should be checked - and only set avctx->channels when the crc is ok. Right now the decoder could - set the channels based on a broken first frame.*/ - if (s->is_channels_set == 0) { - s->is_channels_set = 1; - avctx->channels = channels; - } - if (avctx->channels != channels) { - av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of " - "channels changing in stream. Skipping frame.\n"); - return AVERROR_PATCHWELCOME; - } + avctx->channels = channels; /* get output buffer */ - s->frame.nb_samples = 256 * (s->sample_blocks / 8); - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + frame->nb_samples = 256 * (s->sample_blocks / 8); + if ((ret = ff_get_buffer(avctx, frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - samples_flt = (float *) s->frame.data[0]; - samples_s16 = (int16_t *) s->frame.data[0]; + samples_flt = (float **)frame->extended_data; + + /* allocate buffer for extra channels if downmixing */ + if (avctx->channels < full_channels) { + ret = av_samples_get_buffer_size(NULL, full_channels - channels, + frame->nb_samples, + avctx->sample_fmt, 0); + if (ret < 0) + return ret; + + av_fast_malloc(&s->extra_channels_buffer, + &s->extra_channels_buffer_size, ret); + if (!s->extra_channels_buffer) + return AVERROR(ENOMEM); + + ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL, + s->extra_channels_buffer, + full_channels - channels, + frame->nb_samples, avctx->sample_fmt, 0); + if (ret < 0) + return ret; + } /* filter to get final output */ 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; + for (; ch < full_channels; ch++) + s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256; + dca_filter_channels(s, i); /* If this was marked as a DTS-ES stream we need to subtract back- */ /* channel from SL & SR to remove matrixed back-channel signal */ if ((s->source_pcm_res & 1) && s->xch_present) { - float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256; - float *lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256; - float *rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256; + float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]]; + float *lt_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]]; + 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(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 */ @@ -1887,8 +1890,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < 2 * s->lfe * 4; i++) s->lfe_data[i] = s->lfe_data[i + lfe_samples]; - *got_frame_ptr = 1; - *(AVFrame *) data = s->frame; + *got_frame_ptr = 1; return buf_size; } @@ -1904,7 +1906,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, static av_cold int dca_decode_init(AVCodecContext *avctx) { DCAContext *s = avctx->priv_data; - int i; s->avctx = avctx; dca_init_vlcs(); @@ -1915,16 +1916,7 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) ff_dcadsp_init(&s->dcadsp); ff_fmt_convert_init(&s->fmt_conv, avctx); - for (i = 0; i < DCA_PRIM_CHANNELS_MAX + 1; i++) - 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; - } + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo */ if (avctx->channels > 0 && avctx->request_channels < avctx->channels && @@ -1932,9 +1924,6 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) avctx->channels = avctx->request_channels; } - avcodec_get_frame_defaults(&s->frame); - avctx->coded_frame = &s->frame; - return 0; } @@ -1942,6 +1931,7 @@ static av_cold int dca_decode_end(AVCodecContext *avctx) { DCAContext *s = avctx->priv_data; ff_mdct_end(&s->imdct); + av_freep(&s->extra_channels_buffer); return 0; } @@ -1964,8 +1954,7 @@ AVCodec ff_dca_decoder = { .close = dca_decode_end, .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_S16, + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .profiles = NULL_IF_CONFIG_SMALL(profiles), };