diff options
Diffstat (limited to 'libavcodec/dca_core.h')
-rw-r--r-- | libavcodec/dca_core.h | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/libavcodec/dca_core.h b/libavcodec/dca_core.h new file mode 100644 index 0000000000..10128d1e32 --- /dev/null +++ b/libavcodec/dca_core.h @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2016 foo86 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DCA_CORE_H +#define AVCODEC_DCA_CORE_H + +#include "libavutil/common.h" +#include "libavutil/float_dsp.h" +#include "libavutil/fixed_dsp.h" +#include "libavutil/mem.h" + +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "dca.h" +#include "dca_exss.h" +#include "dcadsp.h" +#include "dcadct.h" +#include "dcamath.h" +#include "dcahuff.h" +#include "fft.h" +#include "synth_filter.h" + +#define DCA_CHANNELS 7 +#define DCA_SUBBANDS 32 +#define DCA_SUBBANDS_X96 64 +#define DCA_SUBFRAMES 16 +#define DCA_SUBBAND_SAMPLES 8 +#define DCA_PCMBLOCK_SAMPLES 32 +#define DCA_LFE_HISTORY 8 +#define DCA_ABITS_MAX 26 + +#define DCA_CORE_CHANNELS_MAX 6 +#define DCA_DMIX_CHANNELS_MAX 4 +#define DCA_XXCH_CHANNELS_MAX 2 +#define DCA_EXSS_CHANNELS_MAX 8 +#define DCA_EXSS_CHSETS_MAX 4 + +#define DCA_FILTER_MODE_X96 0x01 +#define DCA_FILTER_MODE_FIXED 0x02 + +enum DCACoreAudioMode { + DCA_AMODE_MONO, // Mode 0: A (mono) + DCA_AMODE_MONO_DUAL, // Mode 1: A + B (dual mono) + DCA_AMODE_STEREO, // Mode 2: L + R (stereo) + DCA_AMODE_STEREO_SUMDIFF, // Mode 3: (L+R) + (L-R) (sum-diff) + DCA_AMODE_STEREO_TOTAL, // Mode 4: LT + RT (left and right total) + DCA_AMODE_3F, // Mode 5: C + L + R + DCA_AMODE_2F1R, // Mode 6: L + R + S + DCA_AMODE_3F1R, // Mode 7: C + L + R + S + DCA_AMODE_2F2R, // Mode 8: L + R + SL + SR + DCA_AMODE_3F2R, // Mode 9: C + L + R + SL + SR + + DCA_AMODE_COUNT +}; + +enum DCACoreExtAudioType { + DCA_EXT_AUDIO_XCH = 0, + DCA_EXT_AUDIO_X96 = 2, + DCA_EXT_AUDIO_XXCH = 6 +}; + +enum DCACoreLFEFlag { + DCA_LFE_FLAG_NONE, + DCA_LFE_FLAG_128, + DCA_LFE_FLAG_64, + DCA_LFE_FLAG_INVALID +}; + +typedef struct DCADSPData { + union { + struct { + DECLARE_ALIGNED(32, float, hist1)[1024]; + DECLARE_ALIGNED(32, float, hist2)[64]; + } flt; + struct { + DECLARE_ALIGNED(32, int32_t, hist1)[1024]; + DECLARE_ALIGNED(32, int32_t, hist2)[64]; + } fix; + } u; + int offset; +} DCADSPData; + +typedef struct DCACoreDecoder { + AVCodecContext *avctx; + GetBitContext gb; + GetBitContext gb_in; + + // Bit stream header + int crc_present; ///< CRC present flag + int npcmblocks; ///< Number of PCM sample blocks + int frame_size; ///< Primary frame byte size + int audio_mode; ///< Audio channel arrangement + int sample_rate; ///< Core audio sampling frequency + int bit_rate; ///< Transmission bit rate + int drc_present; ///< Embedded dynamic range flag + int ts_present; ///< Embedded time stamp flag + int aux_present; ///< Auxiliary data flag + int ext_audio_type; ///< Extension audio descriptor flag + int ext_audio_present; ///< Extended coding flag + int sync_ssf; ///< Audio sync word insertion flag + int lfe_present; ///< Low frequency effects flag + int predictor_history; ///< Predictor history flag switch + int filter_perfect; ///< Multirate interpolator switch + int source_pcm_res; ///< Source PCM resolution + int es_format; ///< Extended surround (ES) mastering flag + int sumdiff_front; ///< Front sum/difference flag + int sumdiff_surround; ///< Surround sum/difference flag + + // Primary audio coding header + int nsubframes; ///< Number of subframes + int nchannels; ///< Number of primary audio channels (incl. extension channels) + int ch_mask; ///< Speaker layout mask (incl. LFE and extension channels) + int8_t nsubbands[DCA_CHANNELS]; ///< Subband activity count + int8_t subband_vq_start[DCA_CHANNELS]; ///< High frequency VQ start subband + int8_t joint_intensity_index[DCA_CHANNELS]; ///< Joint intensity coding index + int8_t transition_mode_sel[DCA_CHANNELS]; ///< Transient mode code book + int8_t scale_factor_sel[DCA_CHANNELS]; ///< Scale factor code book + int8_t bit_allocation_sel[DCA_CHANNELS]; ///< Bit allocation quantizer select + int8_t quant_index_sel[DCA_CHANNELS][DCA_CODE_BOOKS]; ///< Quantization index codebook select + int32_t scale_factor_adj[DCA_CHANNELS][DCA_CODE_BOOKS]; ///< Scale factor adjustment + + // Primary audio coding side information + int8_t nsubsubframes[DCA_SUBFRAMES]; ///< Subsubframe count for each subframe + int8_t prediction_mode[DCA_CHANNELS][DCA_SUBBANDS_X96]; ///< Prediction mode + int16_t prediction_vq_index[DCA_CHANNELS][DCA_SUBBANDS_X96]; ///< Prediction coefficients VQ address + int8_t bit_allocation[DCA_CHANNELS][DCA_SUBBANDS_X96]; ///< Bit allocation index + int8_t transition_mode[DCA_SUBFRAMES][DCA_CHANNELS][DCA_SUBBANDS]; ///< Transition mode + int32_t scale_factors[DCA_CHANNELS][DCA_SUBBANDS][2]; ///< Scale factors (2x for transients and X96) + int8_t joint_scale_sel[DCA_CHANNELS]; ///< Joint subband codebook select + int32_t joint_scale_factors[DCA_CHANNELS][DCA_SUBBANDS_X96]; ///< Scale factors for joint subband coding + + // Auxiliary data + int prim_dmix_embedded; ///< Auxiliary dynamic downmix flag + int prim_dmix_type; ///< Auxiliary primary channel downmix type + int prim_dmix_coeff[DCA_DMIX_CHANNELS_MAX * DCA_CORE_CHANNELS_MAX]; ///< Dynamic downmix code coefficients + + // Core extensions + int ext_audio_mask; ///< Bit mask of fully decoded core extensions + + // XCH extension data + int xch_pos; ///< Bit position of XCH frame in core substream + + // XXCH extension data + int xxch_crc_present; ///< CRC presence flag for XXCH channel set header + int xxch_mask_nbits; ///< Number of bits for loudspeaker mask + int xxch_core_mask; ///< Core loudspeaker activity mask + int xxch_spkr_mask; ///< Loudspeaker layout mask + int xxch_dmix_embedded; ///< Downmix already performed by encoder + int xxch_dmix_scale_inv; ///< Downmix scale factor + int xxch_dmix_mask[DCA_XXCH_CHANNELS_MAX]; ///< Downmix channel mapping mask + int xxch_dmix_coeff[DCA_XXCH_CHANNELS_MAX * DCA_CORE_CHANNELS_MAX]; ///< Downmix coefficients + int xxch_pos; ///< Bit position of XXCH frame in core substream + + // X96 extension data + int x96_rev_no; ///< X96 revision number + int x96_crc_present; ///< CRC presence flag for X96 channel set header + int x96_nchannels; ///< Number of primary channels in X96 extension + int x96_high_res; ///< X96 high resolution flag + int x96_subband_start; ///< First encoded subband in X96 extension + int x96_rand; ///< Random seed for generating samples for unallocated X96 subbands + int x96_pos; ///< Bit position of X96 frame in core substream + + // Sample buffers + unsigned int x96_subband_size; + int32_t *x96_subband_buffer; ///< X96 subband sample buffer base + int32_t *x96_subband_samples[DCA_CHANNELS][DCA_SUBBANDS_X96]; ///< X96 subband samples + + unsigned int subband_size; + int32_t *subband_buffer; ///< Subband sample buffer base + int32_t *subband_samples[DCA_CHANNELS][DCA_SUBBANDS]; ///< Subband samples + int32_t *lfe_samples; ///< Decimated LFE samples + + // DSP contexts + DCADSPData dcadsp_data[DCA_CHANNELS]; ///< FIR history buffers + DCADSPContext *dcadsp; + DCADCTContext dcadct; + FFTContext imdct[2]; + SynthFilterContext synth; + AVFloatDSPContext *float_dsp; + AVFixedDSPContext *fixed_dsp; + + // PCM output data + unsigned int output_size; + void *output_buffer; ///< PCM output buffer base + int32_t *output_samples[DCA_SPEAKER_COUNT]; ///< PCM output for fixed point mode + int32_t output_history_lfe_fixed; ///< LFE PCM history for X96 filter + float output_history_lfe_float; ///< LFE PCM history for X96 filter + + int ch_remap[DCA_SPEAKER_COUNT]; ///< Channel to speaker map + int request_mask; ///< Requested channel layout (for stereo downmix) + + int npcmsamples; ///< Number of PCM samples per channel + int output_rate; ///< Output sample rate (1x or 2x header rate) + + int filter_mode; ///< Previous filtering mode for detecting changes +} DCACoreDecoder; + +static inline int ff_dca_core_map_spkr(DCACoreDecoder *core, int spkr) +{ + if (core->ch_mask & (1U << spkr)) + return spkr; + if (spkr == DCA_SPEAKER_Lss && (core->ch_mask & DCA_SPEAKER_MASK_Ls)) + return DCA_SPEAKER_Ls; + if (spkr == DCA_SPEAKER_Rss && (core->ch_mask & DCA_SPEAKER_MASK_Rs)) + return DCA_SPEAKER_Rs; + return -1; +} + +static inline void ff_dca_core_dequantize(int32_t *output, const int32_t *input, + int32_t step_size, int32_t scale, int residual, int len) +{ + // Account for quantizer step size + int64_t step_scale = (int64_t)step_size * scale; + int n, shift = 0; + + // Limit scale factor resolution to 22 bits + if (step_scale > (1 << 23)) { + shift = av_log2(step_scale >> 23) + 1; + step_scale >>= shift; + } + + // Scale the samples + if (residual) { + for (n = 0; n < len; n++) + output[n] += clip23(norm__(input[n] * step_scale, 22 - shift)); + } else { + for (n = 0; n < len; n++) + output[n] = clip23(norm__(input[n] * step_scale, 22 - shift)); + } +} + +int ff_dca_core_parse(DCACoreDecoder *s, uint8_t *data, int size); +int ff_dca_core_parse_exss(DCACoreDecoder *s, uint8_t *data, DCAExssAsset *asset); +int ff_dca_core_filter_fixed(DCACoreDecoder *s, int x96_synth); +int ff_dca_core_filter_frame(DCACoreDecoder *s, AVFrame *frame); +av_cold void ff_dca_core_flush(DCACoreDecoder *s); +av_cold int ff_dca_core_init(DCACoreDecoder *s); +av_cold void ff_dca_core_close(DCACoreDecoder *s); + +#endif |