mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec/dca: add new decoder based on libdcadec
This commit is contained in:
parent
0930b2dd1f
commit
ae5b2c5250
@ -61,6 +61,7 @@ version <next>:
|
||||
- support for dvaudio in wav and avi
|
||||
- libaacplus and libvo-aacenc support removed
|
||||
- Cineform HD decoder
|
||||
- new DCA decoder with full support for DTS-HD extensions
|
||||
|
||||
|
||||
version 2.8:
|
||||
|
1
configure
vendored
1
configure
vendored
@ -2271,6 +2271,7 @@ comfortnoise_encoder_select="lpc"
|
||||
cook_decoder_select="audiodsp mdct sinewin"
|
||||
cscd_decoder_select="lzo"
|
||||
cscd_decoder_suggest="zlib"
|
||||
dca_decoder_select="mdct"
|
||||
dds_decoder_select="texturedsp"
|
||||
dirac_decoder_select="dirac_parse dwt golomb videodsp mpegvideoenc"
|
||||
dnxhd_decoder_select="blockdsp idctdsp"
|
||||
|
@ -222,6 +222,9 @@ OBJS-$(CONFIG_COMFORTNOISE_ENCODER) += cngenc.o
|
||||
OBJS-$(CONFIG_CPIA_DECODER) += cpia.o
|
||||
OBJS-$(CONFIG_CSCD_DECODER) += cscd.o
|
||||
OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadata.o \
|
||||
dca_core.o dca_exss.o dca_xll.o \
|
||||
dcadsp.o dcadct.o synth_filter.o
|
||||
OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o
|
||||
OBJS-$(CONFIG_DDS_DECODER) += dds.o
|
||||
OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o \
|
||||
|
@ -1,4 +1,4 @@
|
||||
#OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_init.o
|
||||
OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_init.o
|
||||
OBJS-$(CONFIG_FFT) += aarch64/fft_init_aarch64.o
|
||||
OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_init.o
|
||||
OBJS-$(CONFIG_H264CHROMA) += aarch64/h264chroma_init_aarch64.o
|
||||
@ -17,7 +17,7 @@ OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o
|
||||
|
||||
ARMV8-OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp.o
|
||||
|
||||
#NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_neon.o
|
||||
NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_neon.o
|
||||
NEON-OBJS-$(CONFIG_FFT) += aarch64/fft_neon.o
|
||||
NEON-OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_neon.o
|
||||
NEON-OBJS-$(CONFIG_H264CHROMA) += aarch64/h264cmc_neon.o
|
||||
|
@ -391,7 +391,7 @@ void avcodec_register_all(void)
|
||||
REGISTER_DECODER(BINKAUDIO_RDFT, binkaudio_rdft);
|
||||
REGISTER_DECODER(BMV_AUDIO, bmv_audio);
|
||||
REGISTER_DECODER(COOK, cook);
|
||||
REGISTER_ENCODER(DCA, dca);
|
||||
REGISTER_ENCDEC (DCA, dca);
|
||||
REGISTER_DECODER(DSD_LSBF, dsd_lsbf);
|
||||
REGISTER_DECODER(DSD_MSBF, dsd_msbf);
|
||||
REGISTER_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar);
|
||||
|
@ -36,7 +36,7 @@ OBJS-$(CONFIG_VP8DSP) += arm/vp8dsp_init_arm.o
|
||||
# decoders/encoders
|
||||
OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_init_arm.o \
|
||||
arm/sbrdsp_init_arm.o
|
||||
#OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_init_arm.o
|
||||
OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_init_arm.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_arm.o
|
||||
OBJS-$(CONFIG_MLP_DECODER) += arm/mlpdsp_init_arm.o
|
||||
OBJS-$(CONFIG_RV40_DECODER) += arm/rv40dsp_init_arm.o
|
||||
@ -87,7 +87,7 @@ VFP-OBJS-$(CONFIG_FMTCONVERT) += arm/fmtconvert_vfp.o
|
||||
VFP-OBJS-$(CONFIG_MDCT) += arm/mdct_vfp.o
|
||||
|
||||
# decoders/encoders
|
||||
#VFP-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_vfp.o
|
||||
VFP-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_vfp.o
|
||||
|
||||
|
||||
# NEON optimizations
|
||||
@ -126,7 +126,7 @@ NEON-OBJS-$(CONFIG_VP8DSP) += arm/vp8dsp_init_neon.o \
|
||||
NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_neon.o \
|
||||
arm/sbrdsp_neon.o
|
||||
NEON-OBJS-$(CONFIG_LLAUDDSP) += arm/lossless_audiodsp_neon.o
|
||||
#NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_neon.o
|
||||
NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_neon.o
|
||||
NEON-OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_neon.o \
|
||||
arm/hevcdsp_deblock_neon.o \
|
||||
arm/hevcdsp_idct_neon.o \
|
||||
|
2603
libavcodec/dca_core.c
Normal file
2603
libavcodec/dca_core.c
Normal file
File diff suppressed because it is too large
Load Diff
206
libavcodec/dca_core.h
Normal file
206
libavcodec/dca_core.h
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 "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_ADPCM_COEFFS 4
|
||||
#define DCA_LFE_HISTORY 8
|
||||
#define DCA_CODE_BOOKS 10
|
||||
#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
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
514
libavcodec/dca_exss.c
Normal file
514
libavcodec/dca_exss.c
Normal file
@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "dcadec.h"
|
||||
#include "dcadata.h"
|
||||
|
||||
static int count_chs_for_mask(int mask)
|
||||
{
|
||||
return av_popcount(mask) + av_popcount(mask & 0xae66);
|
||||
}
|
||||
|
||||
static void parse_xll_parameters(DCAExssParser *s, DCAExssAsset *asset)
|
||||
{
|
||||
// Size of XLL data in extension substream
|
||||
asset->xll_size = get_bits(&s->gb, s->exss_size_nbits) + 1;
|
||||
|
||||
// XLL sync word present flag
|
||||
if (asset->xll_sync_present = get_bits1(&s->gb)) {
|
||||
int xll_delay_nbits;
|
||||
|
||||
// Peak bit rate smoothing buffer size
|
||||
skip_bits(&s->gb, 4);
|
||||
|
||||
// Number of bits for XLL decoding delay
|
||||
xll_delay_nbits = get_bits(&s->gb, 5) + 1;
|
||||
|
||||
// Initial XLL decoding delay in frames
|
||||
asset->xll_delay_nframes = get_bits_long(&s->gb, xll_delay_nbits);
|
||||
|
||||
// Number of bytes offset to XLL sync
|
||||
asset->xll_sync_offset = get_bits(&s->gb, s->exss_size_nbits);
|
||||
} else {
|
||||
asset->xll_delay_nframes = 0;
|
||||
asset->xll_sync_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_lbr_parameters(DCAExssParser *s, DCAExssAsset *asset)
|
||||
{
|
||||
// Size of LBR component in extension substream
|
||||
asset->lbr_size = get_bits(&s->gb, 14) + 1;
|
||||
|
||||
// LBR sync word present flag
|
||||
if (get_bits1(&s->gb))
|
||||
// LBR sync distance
|
||||
skip_bits(&s->gb, 2);
|
||||
}
|
||||
|
||||
static int parse_descriptor(DCAExssParser *s, DCAExssAsset *asset)
|
||||
{
|
||||
int i, j, drc_present, descr_size, descr_pos = get_bits_count(&s->gb);
|
||||
|
||||
// Size of audio asset descriptor in bytes
|
||||
descr_size = get_bits(&s->gb, 9) + 1;
|
||||
|
||||
// Audio asset identifier
|
||||
asset->asset_index = get_bits(&s->gb, 3);
|
||||
|
||||
//
|
||||
// Per stream static metadata
|
||||
//
|
||||
|
||||
if (s->static_fields_present) {
|
||||
// Asset type descriptor presence
|
||||
if (get_bits1(&s->gb))
|
||||
// Asset type descriptor
|
||||
skip_bits(&s->gb, 4);
|
||||
|
||||
// Language descriptor presence
|
||||
if (get_bits1(&s->gb))
|
||||
// Language descriptor
|
||||
skip_bits(&s->gb, 24);
|
||||
|
||||
// Additional textual information presence
|
||||
if (get_bits1(&s->gb)) {
|
||||
// Byte size of additional text info
|
||||
int text_size = get_bits(&s->gb, 10) + 1;
|
||||
|
||||
// Sanity check available size
|
||||
if (get_bits_left(&s->gb) < text_size * 8)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
// Additional textual information string
|
||||
skip_bits_long(&s->gb, text_size * 8);
|
||||
}
|
||||
|
||||
// PCM bit resolution
|
||||
asset->pcm_bit_res = get_bits(&s->gb, 5) + 1;
|
||||
|
||||
// Maximum sample rate
|
||||
asset->max_sample_rate = ff_dca_sampling_freqs[get_bits(&s->gb, 4)];
|
||||
|
||||
// Total number of channels
|
||||
asset->nchannels_total = get_bits(&s->gb, 8) + 1;
|
||||
|
||||
// One to one map channel to speakers
|
||||
if (asset->one_to_one_map_ch_to_spkr = get_bits1(&s->gb)) {
|
||||
int spkr_mask_nbits = 0;
|
||||
int spkr_remap_nsets;
|
||||
int nspeakers[8];
|
||||
|
||||
// Embedded stereo flag
|
||||
if (asset->nchannels_total > 2)
|
||||
asset->embedded_stereo = get_bits1(&s->gb);
|
||||
|
||||
// Embedded 6 channels flag
|
||||
if (asset->nchannels_total > 6)
|
||||
asset->embedded_6ch = get_bits1(&s->gb);
|
||||
|
||||
// Speaker mask enabled flag
|
||||
if (asset->spkr_mask_enabled = get_bits1(&s->gb)) {
|
||||
// Number of bits for speaker activity mask
|
||||
spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2;
|
||||
|
||||
// Loudspeaker activity mask
|
||||
asset->spkr_mask = get_bits(&s->gb, spkr_mask_nbits);
|
||||
}
|
||||
|
||||
// Number of speaker remapping sets
|
||||
if ((spkr_remap_nsets = get_bits(&s->gb, 3)) && !spkr_mask_nbits) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Speaker mask disabled yet there are remapping sets\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
// Standard loudspeaker layout mask
|
||||
for (i = 0; i < spkr_remap_nsets; i++)
|
||||
nspeakers[i] = count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits));
|
||||
|
||||
for (i = 0; i < spkr_remap_nsets; i++) {
|
||||
// Number of channels to be decoded for speaker remapping
|
||||
int nch_for_remaps = get_bits(&s->gb, 5) + 1;
|
||||
|
||||
for (j = 0; j < nspeakers[i]; j++) {
|
||||
// Decoded channels to output speaker mapping mask
|
||||
int remap_ch_mask = get_bits_long(&s->gb, nch_for_remaps);
|
||||
|
||||
// Loudspeaker remapping codes
|
||||
skip_bits_long(&s->gb, av_popcount(remap_ch_mask) * 5);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
asset->embedded_stereo = 0;
|
||||
asset->embedded_6ch = 0;
|
||||
asset->spkr_mask_enabled = 0;
|
||||
asset->spkr_mask = 0;
|
||||
|
||||
// Representation type
|
||||
asset->representation_type = get_bits(&s->gb, 3);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// DRC, DNC and mixing metadata
|
||||
//
|
||||
|
||||
// Dynamic range coefficient presence flag
|
||||
drc_present = get_bits1(&s->gb);
|
||||
|
||||
// Code for dynamic range coefficient
|
||||
if (drc_present)
|
||||
skip_bits(&s->gb, 8);
|
||||
|
||||
// Dialog normalization presence flag
|
||||
if (get_bits1(&s->gb))
|
||||
// Dialog normalization code
|
||||
skip_bits(&s->gb, 5);
|
||||
|
||||
// DRC for stereo downmix
|
||||
if (drc_present && asset->embedded_stereo)
|
||||
skip_bits(&s->gb, 8);
|
||||
|
||||
// Mixing metadata presence flag
|
||||
if (s->mix_metadata_enabled && get_bits1(&s->gb)) {
|
||||
int nchannels_dmix;
|
||||
|
||||
// External mixing flag
|
||||
skip_bits1(&s->gb);
|
||||
|
||||
// Post mixing / replacement gain adjustment
|
||||
skip_bits(&s->gb, 6);
|
||||
|
||||
// DRC prior to mixing
|
||||
if (get_bits(&s->gb, 2) == 3)
|
||||
// Custom code for mixing DRC
|
||||
skip_bits(&s->gb, 8);
|
||||
else
|
||||
// Limit for mixing DRC
|
||||
skip_bits(&s->gb, 3);
|
||||
|
||||
// Scaling type for channels of main audio
|
||||
// Scaling parameters of main audio
|
||||
if (get_bits1(&s->gb))
|
||||
for (i = 0; i < s->nmixoutconfigs; i++)
|
||||
skip_bits_long(&s->gb, 6 * s->nmixoutchs[i]);
|
||||
else
|
||||
skip_bits_long(&s->gb, 6 * s->nmixoutconfigs);
|
||||
|
||||
nchannels_dmix = asset->nchannels_total;
|
||||
if (asset->embedded_6ch)
|
||||
nchannels_dmix += 6;
|
||||
if (asset->embedded_stereo)
|
||||
nchannels_dmix += 2;
|
||||
|
||||
for (i = 0; i < s->nmixoutconfigs; i++) {
|
||||
if (!s->nmixoutchs[i]) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid speaker layout mask for mixing configuration\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
for (j = 0; j < nchannels_dmix; j++) {
|
||||
// Mix output mask
|
||||
int mix_map_mask = get_bits(&s->gb, s->nmixoutchs[i]);
|
||||
|
||||
// Mixing coefficients
|
||||
skip_bits_long(&s->gb, av_popcount(mix_map_mask) * 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Decoder navigation data
|
||||
//
|
||||
|
||||
// Coding mode for the asset
|
||||
asset->coding_mode = get_bits(&s->gb, 2);
|
||||
|
||||
// Coding components used in asset
|
||||
switch (asset->coding_mode) {
|
||||
case 0: // Coding mode that may contain multiple coding components
|
||||
asset->extension_mask = get_bits(&s->gb, 12);
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_CORE) {
|
||||
// Size of core component in extension substream
|
||||
asset->core_size = get_bits(&s->gb, 14) + 1;
|
||||
// Core sync word present flag
|
||||
if (get_bits1(&s->gb))
|
||||
// Core sync distance
|
||||
skip_bits(&s->gb, 2);
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XBR)
|
||||
// Size of XBR extension in extension substream
|
||||
asset->xbr_size = get_bits(&s->gb, 14) + 1;
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XXCH)
|
||||
// Size of XXCH extension in extension substream
|
||||
asset->xxch_size = get_bits(&s->gb, 14) + 1;
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_X96)
|
||||
// Size of X96 extension in extension substream
|
||||
asset->x96_size = get_bits(&s->gb, 12) + 1;
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_LBR)
|
||||
parse_lbr_parameters(s, asset);
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XLL)
|
||||
parse_xll_parameters(s, asset);
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_RSV1)
|
||||
skip_bits(&s->gb, 16);
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_RSV2)
|
||||
skip_bits(&s->gb, 16);
|
||||
break;
|
||||
|
||||
case 1: // Loss-less coding mode without CBR component
|
||||
asset->extension_mask = DCA_EXSS_XLL;
|
||||
parse_xll_parameters(s, asset);
|
||||
break;
|
||||
|
||||
case 2: // Low bit rate mode
|
||||
asset->extension_mask = DCA_EXSS_LBR;
|
||||
parse_lbr_parameters(s, asset);
|
||||
break;
|
||||
|
||||
case 3: // Auxiliary coding mode
|
||||
asset->extension_mask = 0;
|
||||
|
||||
// Size of auxiliary coded data
|
||||
skip_bits(&s->gb, 14);
|
||||
|
||||
// Auxiliary codec identification
|
||||
skip_bits(&s->gb, 8);
|
||||
|
||||
// Aux sync word present flag
|
||||
if (get_bits1(&s->gb))
|
||||
// Aux sync distance
|
||||
skip_bits(&s->gb, 3);
|
||||
break;
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XLL)
|
||||
// DTS-HD stream ID
|
||||
asset->hd_stream_id = get_bits(&s->gb, 3);
|
||||
|
||||
// One to one mixing flag
|
||||
// Per channel main audio scaling flag
|
||||
// Main audio scaling codes
|
||||
// Decode asset in secondary decoder flag
|
||||
// Revision 2 DRC metadata
|
||||
// Reserved
|
||||
// Zero pad
|
||||
if (ff_dca_seek_bits(&s->gb, descr_pos + descr_size * 8)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS asset descriptor\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_exss_offsets(DCAExssAsset *asset)
|
||||
{
|
||||
int offs = asset->asset_offset;
|
||||
int size = asset->asset_size;
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_CORE) {
|
||||
asset->core_offset = offs;
|
||||
if (asset->core_size > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
offs += asset->core_size;
|
||||
size -= asset->core_size;
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XBR) {
|
||||
asset->xbr_offset = offs;
|
||||
if (asset->xbr_size > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
offs += asset->xbr_size;
|
||||
size -= asset->xbr_size;
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XXCH) {
|
||||
asset->xxch_offset = offs;
|
||||
if (asset->xxch_size > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
offs += asset->xxch_size;
|
||||
size -= asset->xxch_size;
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_X96) {
|
||||
asset->x96_offset = offs;
|
||||
if (asset->x96_size > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
offs += asset->x96_size;
|
||||
size -= asset->x96_size;
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_LBR) {
|
||||
asset->lbr_offset = offs;
|
||||
if (asset->lbr_size > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
offs += asset->lbr_size;
|
||||
size -= asset->lbr_size;
|
||||
}
|
||||
|
||||
if (asset->extension_mask & DCA_EXSS_XLL) {
|
||||
asset->xll_offset = offs;
|
||||
if (asset->xll_size > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
offs += asset->xll_size;
|
||||
size -= asset->xll_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size)
|
||||
{
|
||||
int i, ret, offset, wide_hdr, header_size;
|
||||
|
||||
if ((ret = init_get_bits8(&s->gb, data, size)) < 0)
|
||||
return ret;
|
||||
|
||||
// Extension substream sync word
|
||||
skip_bits_long(&s->gb, 32);
|
||||
|
||||
// User defined bits
|
||||
skip_bits(&s->gb, 8);
|
||||
|
||||
// Extension substream index
|
||||
s->exss_index = get_bits(&s->gb, 2);
|
||||
|
||||
// Flag indicating short or long header size
|
||||
wide_hdr = get_bits1(&s->gb);
|
||||
|
||||
// Extension substream header length
|
||||
header_size = get_bits(&s->gb, 8 + 4 * wide_hdr) + 1;
|
||||
|
||||
// Check CRC
|
||||
if ((s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL))
|
||||
&& ff_dca_check_crc(&s->gb, 32 + 8, header_size * 8)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid EXSS header checksum\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
s->exss_size_nbits = 16 + 4 * wide_hdr;
|
||||
|
||||
// Number of bytes of extension substream
|
||||
s->exss_size = get_bits(&s->gb, s->exss_size_nbits) + 1;
|
||||
if (s->exss_size > size) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Packet too short for EXSS frame\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
// Per stream static fields presence flag
|
||||
if (s->static_fields_present = get_bits1(&s->gb)) {
|
||||
int active_exss_mask[8];
|
||||
|
||||
// Reference clock code
|
||||
skip_bits(&s->gb, 2);
|
||||
|
||||
// Extension substream frame duration
|
||||
skip_bits(&s->gb, 3);
|
||||
|
||||
// Timecode presence flag
|
||||
if (get_bits1(&s->gb))
|
||||
// Timecode data
|
||||
skip_bits_long(&s->gb, 36);
|
||||
|
||||
// Number of defined audio presentations
|
||||
s->npresents = get_bits(&s->gb, 3) + 1;
|
||||
if (s->npresents > 1) {
|
||||
avpriv_request_sample(s->avctx, "%d audio presentations", s->npresents);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
|
||||
// Number of audio assets in extension substream
|
||||
s->nassets = get_bits(&s->gb, 3) + 1;
|
||||
if (s->nassets > 1) {
|
||||
avpriv_request_sample(s->avctx, "%d audio assets", s->nassets);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
|
||||
// Active extension substream mask for audio presentation
|
||||
for (i = 0; i < s->npresents; i++)
|
||||
active_exss_mask[i] = get_bits(&s->gb, s->exss_index + 1);
|
||||
|
||||
// Active audio asset mask
|
||||
for (i = 0; i < s->npresents; i++)
|
||||
skip_bits_long(&s->gb, av_popcount(active_exss_mask[i]) * 8);
|
||||
|
||||
// Mixing metadata enable flag
|
||||
if (s->mix_metadata_enabled = get_bits1(&s->gb)) {
|
||||
int spkr_mask_nbits;
|
||||
|
||||
// Mixing metadata adjustment level
|
||||
skip_bits(&s->gb, 2);
|
||||
|
||||
// Number of bits for mixer output speaker activity mask
|
||||
spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2;
|
||||
|
||||
// Number of mixing configurations
|
||||
s->nmixoutconfigs = get_bits(&s->gb, 2) + 1;
|
||||
|
||||
// Speaker layout mask for mixer output channels
|
||||
for (i = 0; i < s->nmixoutconfigs; i++)
|
||||
s->nmixoutchs[i] = count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits));
|
||||
}
|
||||
} else {
|
||||
s->npresents = 1;
|
||||
s->nassets = 1;
|
||||
}
|
||||
|
||||
// Size of encoded asset data in bytes
|
||||
offset = header_size;
|
||||
for (i = 0; i < s->nassets; i++) {
|
||||
s->assets[i].asset_offset = offset;
|
||||
s->assets[i].asset_size = get_bits(&s->gb, s->exss_size_nbits) + 1;
|
||||
offset += s->assets[i].asset_size;
|
||||
if (offset > s->exss_size) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "EXSS asset out of bounds\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
// Audio asset descriptor
|
||||
for (i = 0; i < s->nassets; i++) {
|
||||
if ((ret = parse_descriptor(s, &s->assets[i])) < 0)
|
||||
return ret;
|
||||
if ((ret = set_exss_offsets(&s->assets[i])) < 0) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid extension size in EXSS asset descriptor\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Backward compatible core present
|
||||
// Backward compatible core substream index
|
||||
// Backward compatible core asset index
|
||||
// Reserved
|
||||
// Byte align
|
||||
// CRC16 of extension substream header
|
||||
if (ff_dca_seek_bits(&s->gb, header_size * 8)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS header\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
92
libavcodec/dca_exss.h
Normal file
92
libavcodec/dca_exss.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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_EXSS_H
|
||||
#define AVCODEC_DCA_EXSS_H
|
||||
|
||||
#include "libavutil/common.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
typedef struct DCAExssAsset {
|
||||
int asset_offset; ///< Offset to asset data from start of substream
|
||||
int asset_size; ///< Size of encoded asset data
|
||||
int asset_index; ///< Audio asset identifier
|
||||
|
||||
int pcm_bit_res; ///< PCM bit resolution
|
||||
int max_sample_rate; ///< Maximum sample rate
|
||||
int nchannels_total; ///< Total number of channels
|
||||
int one_to_one_map_ch_to_spkr; ///< One to one channel to speaker mapping flag
|
||||
int embedded_stereo; ///< Embedded stereo flag
|
||||
int embedded_6ch; ///< Embedded 6 channels flag
|
||||
int spkr_mask_enabled; ///< Speaker mask enabled flag
|
||||
int spkr_mask; ///< Loudspeaker activity mask
|
||||
int representation_type; ///< Representation type
|
||||
|
||||
int coding_mode; ///< Coding mode for the asset
|
||||
int extension_mask; ///< Coding components used in asset
|
||||
|
||||
int core_offset; ///< Offset to core component from start of substream
|
||||
int core_size; ///< Size of core component in extension substream
|
||||
|
||||
int xbr_offset; ///< Offset to XBR extension from start of substream
|
||||
int xbr_size; ///< Size of XBR extension in extension substream
|
||||
|
||||
int xxch_offset; ///< Offset to XXCH extension from start of substream
|
||||
int xxch_size; ///< Size of XXCH extension in extension substream
|
||||
|
||||
int x96_offset; ///< Offset to X96 extension from start of substream
|
||||
int x96_size; ///< Size of X96 extension in extension substream
|
||||
|
||||
int lbr_offset; ///< Offset to LBR component from start of substream
|
||||
int lbr_size; ///< Size of LBR component in extension substream
|
||||
|
||||
int xll_offset; ///< Offset to XLL data from start of substream
|
||||
int xll_size; ///< Size of XLL data in extension substream
|
||||
int xll_sync_present; ///< XLL sync word present flag
|
||||
int xll_delay_nframes; ///< Initial XLL decoding delay in frames
|
||||
int xll_sync_offset; ///< Number of bytes offset to XLL sync
|
||||
|
||||
int hd_stream_id; ///< DTS-HD stream ID
|
||||
} DCAExssAsset;
|
||||
|
||||
typedef struct DCAExssParser {
|
||||
AVCodecContext *avctx;
|
||||
GetBitContext gb;
|
||||
|
||||
int exss_index; ///< Extension substream index
|
||||
int exss_size_nbits; ///< Number of bits for extension substream size
|
||||
int exss_size; ///< Number of bytes of extension substream
|
||||
|
||||
int static_fields_present; ///< Per stream static fields presence flag
|
||||
int npresents; ///< Number of defined audio presentations
|
||||
int nassets; ///< Number of audio assets in extension substream
|
||||
|
||||
int mix_metadata_enabled; ///< Mixing metadata enable flag
|
||||
int nmixoutconfigs; ///< Number of mixing configurations
|
||||
int nmixoutchs[4]; ///< Speaker layout mask for mixer output channels
|
||||
|
||||
DCAExssAsset assets[1]; ///< Audio asset descriptors
|
||||
} DCAExssParser;
|
||||
|
||||
int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size);
|
||||
|
||||
#endif
|
1499
libavcodec/dca_xll.c
Normal file
1499
libavcodec/dca_xll.c
Normal file
File diff suppressed because it is too large
Load Diff
149
libavcodec/dca_xll.h
Normal file
149
libavcodec/dca_xll.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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_XLL_H
|
||||
#define AVCODEC_DCA_XLL_H
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "get_bits.h"
|
||||
#include "dca.h"
|
||||
#include "dcadsp.h"
|
||||
#include "dca_exss.h"
|
||||
|
||||
#define DCA_XLL_CHSETS_MAX 3
|
||||
#define DCA_XLL_CHANNELS_MAX 8
|
||||
#define DCA_XLL_BANDS_MAX 2
|
||||
#define DCA_XLL_ADAPT_PRED_ORDER_MAX 16
|
||||
#define DCA_XLL_DECI_HISTORY_MAX 8
|
||||
#define DCA_XLL_DMIX_SCALES_MAX ((DCA_XLL_CHSETS_MAX - 1) * DCA_XLL_CHANNELS_MAX)
|
||||
#define DCA_XLL_DMIX_COEFFS_MAX (DCA_XLL_DMIX_SCALES_MAX * DCA_XLL_CHANNELS_MAX)
|
||||
#define DCA_XLL_PBR_BUFFER_MAX (240 << 10)
|
||||
#define DCA_XLL_SAMPLE_BUFFERS_MAX 3
|
||||
|
||||
typedef struct DCAXllBand {
|
||||
int decor_enabled; ///< Pairwise channel decorrelation flag
|
||||
int orig_order[DCA_XLL_CHANNELS_MAX]; ///< Original channel order
|
||||
int decor_coeff[DCA_XLL_CHANNELS_MAX / 2]; ///< Pairwise channel coefficients
|
||||
|
||||
int adapt_pred_order[DCA_XLL_CHANNELS_MAX]; ///< Adaptive predictor order
|
||||
int highest_pred_order; ///< Highest adaptive predictor order
|
||||
int fixed_pred_order[DCA_XLL_CHANNELS_MAX]; ///< Fixed predictor order
|
||||
int adapt_refl_coeff[DCA_XLL_CHANNELS_MAX][DCA_XLL_ADAPT_PRED_ORDER_MAX]; ///< Adaptive predictor reflection coefficients
|
||||
|
||||
int dmix_embedded; ///< Downmix performed by encoder in frequency band
|
||||
|
||||
int lsb_section_size; ///< Size of LSB section in any segment
|
||||
int nscalablelsbs[DCA_XLL_CHANNELS_MAX]; ///< Number of bits to represent the samples in LSB part
|
||||
int bit_width_adjust[DCA_XLL_CHANNELS_MAX]; ///< Number of bits discarded by authoring
|
||||
|
||||
int32_t *msb_sample_buffer[DCA_XLL_CHANNELS_MAX]; ///< MSB sample buffer pointers
|
||||
int32_t *lsb_sample_buffer[DCA_XLL_CHANNELS_MAX]; ///< LSB sample buffer pointers or NULL
|
||||
} DCAXllBand;
|
||||
|
||||
typedef struct DCAXllChSet {
|
||||
// Channel set header
|
||||
int nchannels; ///< Number of channels in the channel set (N)
|
||||
int residual_encode; ///< Residual encoding mask (0 - residual, 1 - full channel)
|
||||
int pcm_bit_res; ///< PCM bit resolution (variable)
|
||||
int storage_bit_res; ///< Storage bit resolution (16 or 24)
|
||||
int freq; ///< Original sampling frequency (max. 96000 Hz)
|
||||
|
||||
int primary_chset; ///< Primary channel set flag
|
||||
int dmix_coeffs_present; ///< Downmix coefficients present in stream
|
||||
int dmix_embedded; ///< Downmix already performed by encoder
|
||||
int dmix_type; ///< Primary channel set downmix type
|
||||
int hier_chset; ///< Whether the channel set is part of a hierarchy
|
||||
int hier_ofs; ///< Number of preceding channels in a hierarchy (M)
|
||||
int dmix_coeff[DCA_XLL_DMIX_COEFFS_MAX]; ///< Downmixing coefficients
|
||||
int dmix_scale[DCA_XLL_DMIX_SCALES_MAX]; ///< Downmixing scales
|
||||
int dmix_scale_inv[DCA_XLL_DMIX_SCALES_MAX]; ///< Inverse downmixing scales
|
||||
int ch_mask; ///< Channel mask for set
|
||||
int ch_remap[DCA_XLL_CHANNELS_MAX]; ///< Channel to speaker map
|
||||
|
||||
int nfreqbands; ///< Number of frequency bands (1 or 2)
|
||||
int nabits; ///< Number of bits to read bit allocation coding parameter
|
||||
|
||||
DCAXllBand bands[DCA_XLL_BANDS_MAX]; ///< Frequency bands
|
||||
|
||||
// Frequency band coding parameters
|
||||
int seg_common; ///< Segment type
|
||||
int rice_code_flag[DCA_XLL_CHANNELS_MAX]; ///< Rice coding flag
|
||||
int bitalloc_hybrid_linear[DCA_XLL_CHANNELS_MAX]; ///< Binary code length for isolated samples
|
||||
int bitalloc_part_a[DCA_XLL_CHANNELS_MAX]; ///< Coding parameter for part A of segment
|
||||
int bitalloc_part_b[DCA_XLL_CHANNELS_MAX]; ///< Coding parameter for part B of segment
|
||||
int nsamples_part_a[DCA_XLL_CHANNELS_MAX]; ///< Number of samples in part A of segment
|
||||
|
||||
// Decimator history
|
||||
DECLARE_ALIGNED(32, int32_t, deci_history)[DCA_XLL_CHANNELS_MAX][DCA_XLL_DECI_HISTORY_MAX]; ///< Decimator history for frequency band 1
|
||||
|
||||
// Sample buffers
|
||||
unsigned int sample_size[DCA_XLL_SAMPLE_BUFFERS_MAX];
|
||||
int32_t *sample_buffer[DCA_XLL_SAMPLE_BUFFERS_MAX];
|
||||
} DCAXllChSet;
|
||||
|
||||
typedef struct DCAXllDecoder {
|
||||
AVCodecContext *avctx;
|
||||
GetBitContext gb;
|
||||
|
||||
int frame_size; ///< Number of bytes in a lossless frame
|
||||
int nchsets; ///< Number of channels sets per frame
|
||||
int nframesegs; ///< Number of segments per frame
|
||||
int nsegsamples_log2; ///< log2(nsegsamples)
|
||||
int nsegsamples; ///< Samples in segment per one frequency band
|
||||
int nframesamples_log2; ///< log2(nframesamples)
|
||||
int nframesamples; ///< Samples in frame per one frequency band
|
||||
int seg_size_nbits; ///< Number of bits used to read segment size
|
||||
int band_crc_present; ///< Presence of CRC16 within each frequency band
|
||||
int scalable_lsbs; ///< MSB/LSB split flag
|
||||
int ch_mask_nbits; ///< Number of bits used to read channel mask
|
||||
int fixed_lsb_width; ///< Fixed LSB width
|
||||
|
||||
DCAXllChSet chset[DCA_XLL_CHSETS_MAX]; ///< Channel sets
|
||||
|
||||
int *navi; ///< NAVI table
|
||||
unsigned int navi_size;
|
||||
|
||||
int nfreqbands; ///< Highest number of frequency bands
|
||||
int nchannels; ///< Total number of channels in a hierarchy
|
||||
int nreschsets; ///< Number of channel sets that have residual encoded channels
|
||||
int nactivechsets; ///< Number of active channel sets to decode
|
||||
|
||||
int hd_stream_id; ///< Previous DTS-HD stream ID for detecting changes
|
||||
|
||||
uint8_t *pbr_buffer; ///< Peak bit rate (PBR) smoothing buffer
|
||||
int pbr_length; ///< Length in bytes of data currently buffered
|
||||
int pbr_delay; ///< Delay in frames before decoding buffered data
|
||||
|
||||
DCADSPContext *dcadsp;
|
||||
|
||||
int output_mask;
|
||||
int32_t *output_samples[DCA_SPEAKER_COUNT];
|
||||
} DCAXllDecoder;
|
||||
|
||||
int ff_dca_xll_parse(DCAXllDecoder *s, uint8_t *data, DCAExssAsset *asset);
|
||||
int ff_dca_xll_filter_frame(DCAXllDecoder *s, AVFrame *frame);
|
||||
av_cold void ff_dca_xll_flush(DCAXllDecoder *s);
|
||||
av_cold void ff_dca_xll_close(DCAXllDecoder *s);
|
||||
|
||||
#endif
|
417
libavcodec/dcadec.c
Normal file
417
libavcodec/dcadec.c
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
|
||||
#include "dcadec.h"
|
||||
#include "dcamath.h"
|
||||
#include "dca_syncwords.h"
|
||||
#include "profiles.h"
|
||||
|
||||
#define MIN_PACKET_SIZE 16
|
||||
#define MAX_PACKET_SIZE 0x104000
|
||||
|
||||
int ff_dca_set_channel_layout(AVCodecContext *avctx, int *ch_remap, int dca_mask)
|
||||
{
|
||||
static const uint8_t dca2wav_norm[28] = {
|
||||
2, 0, 1, 9, 10, 3, 8, 4, 5, 9, 10, 6, 7, 12,
|
||||
13, 14, 3, 6, 7, 11, 12, 14, 16, 15, 17, 8, 4, 5,
|
||||
};
|
||||
|
||||
static const uint8_t dca2wav_wide[28] = {
|
||||
2, 0, 1, 4, 5, 3, 8, 4, 5, 9, 10, 6, 7, 12,
|
||||
13, 14, 3, 9, 10, 11, 12, 14, 16, 15, 17, 8, 4, 5,
|
||||
};
|
||||
|
||||
int dca_ch, wav_ch, nchannels = 0;
|
||||
|
||||
if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {
|
||||
for (dca_ch = 0; dca_ch < DCA_SPEAKER_COUNT; dca_ch++)
|
||||
if (dca_mask & (1U << dca_ch))
|
||||
ch_remap[nchannels++] = dca_ch;
|
||||
avctx->channel_layout = dca_mask;
|
||||
} else {
|
||||
int wav_mask = 0;
|
||||
int wav_map[18];
|
||||
const uint8_t *dca2wav;
|
||||
if (dca_mask == DCA_SPEAKER_LAYOUT_7POINT0_WIDE ||
|
||||
dca_mask == DCA_SPEAKER_LAYOUT_7POINT1_WIDE)
|
||||
dca2wav = dca2wav_wide;
|
||||
else
|
||||
dca2wav = dca2wav_norm;
|
||||
for (dca_ch = 0; dca_ch < 28; dca_ch++) {
|
||||
if (dca_mask & (1 << dca_ch)) {
|
||||
wav_ch = dca2wav[dca_ch];
|
||||
if (!(wav_mask & (1 << wav_ch))) {
|
||||
wav_map[wav_ch] = dca_ch;
|
||||
wav_mask |= 1 << wav_ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (wav_ch = 0; wav_ch < 18; wav_ch++)
|
||||
if (wav_mask & (1 << wav_ch))
|
||||
ch_remap[nchannels++] = wav_map[wav_ch];
|
||||
avctx->channel_layout = wav_mask;
|
||||
}
|
||||
|
||||
avctx->channels = nchannels;
|
||||
return nchannels;
|
||||
}
|
||||
|
||||
static uint16_t crc16(const uint8_t *data, int size)
|
||||
{
|
||||
static const uint16_t crctab[16] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
};
|
||||
|
||||
uint16_t res = 0xffff;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
res = (res << 4) ^ crctab[(data[i] >> 4) ^ (res >> 12)];
|
||||
res = (res << 4) ^ crctab[(data[i] & 15) ^ (res >> 12)];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int ff_dca_check_crc(GetBitContext *s, int p1, int p2)
|
||||
{
|
||||
if (((p1 | p2) & 7) || p1 < 0 || p2 > s->size_in_bits || p2 - p1 < 16)
|
||||
return -1;
|
||||
if (crc16(s->buffer + p1 / 8, (p2 - p1) / 8))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_dca_downmix_to_stereo_fixed(DCADSPContext *dcadsp, int32_t **samples,
|
||||
int *coeff_l, int nsamples, int ch_mask)
|
||||
{
|
||||
int pos, spkr, max_spkr = av_log2(ch_mask);
|
||||
int *coeff_r = coeff_l + av_popcount(ch_mask);
|
||||
|
||||
av_assert0(DCA_HAS_STEREO(ch_mask));
|
||||
|
||||
// Scale left and right channels
|
||||
pos = (ch_mask & DCA_SPEAKER_MASK_C);
|
||||
dcadsp->dmix_scale(samples[DCA_SPEAKER_L], coeff_l[pos ], nsamples);
|
||||
dcadsp->dmix_scale(samples[DCA_SPEAKER_R], coeff_r[pos + 1], nsamples);
|
||||
|
||||
// Downmix remaining channels
|
||||
for (spkr = 0; spkr <= max_spkr; spkr++) {
|
||||
if (!(ch_mask & (1U << spkr)))
|
||||
continue;
|
||||
|
||||
if (*coeff_l && spkr != DCA_SPEAKER_L)
|
||||
dcadsp->dmix_add(samples[DCA_SPEAKER_L], samples[spkr],
|
||||
*coeff_l, nsamples);
|
||||
|
||||
if (*coeff_r && spkr != DCA_SPEAKER_R)
|
||||
dcadsp->dmix_add(samples[DCA_SPEAKER_R], samples[spkr],
|
||||
*coeff_r, nsamples);
|
||||
|
||||
coeff_l++;
|
||||
coeff_r++;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_dca_downmix_to_stereo_float(AVFloatDSPContext *fdsp, float **samples,
|
||||
int *coeff_l, int nsamples, int ch_mask)
|
||||
{
|
||||
int pos, spkr, max_spkr = av_log2(ch_mask);
|
||||
int *coeff_r = coeff_l + av_popcount(ch_mask);
|
||||
const float scale = 1.0f / (1 << 15);
|
||||
|
||||
av_assert0(DCA_HAS_STEREO(ch_mask));
|
||||
|
||||
// Scale left and right channels
|
||||
pos = (ch_mask & DCA_SPEAKER_MASK_C);
|
||||
fdsp->vector_fmul_scalar(samples[DCA_SPEAKER_L], samples[DCA_SPEAKER_L],
|
||||
coeff_l[pos ] * scale, nsamples);
|
||||
fdsp->vector_fmul_scalar(samples[DCA_SPEAKER_R], samples[DCA_SPEAKER_R],
|
||||
coeff_r[pos + 1] * scale, nsamples);
|
||||
|
||||
// Downmix remaining channels
|
||||
for (spkr = 0; spkr <= max_spkr; spkr++) {
|
||||
if (!(ch_mask & (1U << spkr)))
|
||||
continue;
|
||||
|
||||
if (*coeff_l && spkr != DCA_SPEAKER_L)
|
||||
fdsp->vector_fmac_scalar(samples[DCA_SPEAKER_L], samples[spkr],
|
||||
*coeff_l * scale, nsamples);
|
||||
|
||||
if (*coeff_r && spkr != DCA_SPEAKER_R)
|
||||
fdsp->vector_fmac_scalar(samples[DCA_SPEAKER_R], samples[spkr],
|
||||
*coeff_r * scale, nsamples);
|
||||
|
||||
coeff_l++;
|
||||
coeff_r++;
|
||||
}
|
||||
}
|
||||
|
||||
static int convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, int max_size)
|
||||
{
|
||||
switch (AV_RB32(src)) {
|
||||
case DCA_SYNCWORD_CORE_BE:
|
||||
case DCA_SYNCWORD_SUBSTREAM:
|
||||
memcpy(dst, src, src_size);
|
||||
return src_size;
|
||||
case DCA_SYNCWORD_CORE_LE:
|
||||
case DCA_SYNCWORD_CORE_14B_BE:
|
||||
case DCA_SYNCWORD_CORE_14B_LE:
|
||||
return avpriv_dca_convert_bitstream(src, src_size, dst, max_size);
|
||||
default:
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *got_frame_ptr, AVPacket *avpkt)
|
||||
{
|
||||
DCAContext *s = avctx->priv_data;
|
||||
AVFrame *frame = data;
|
||||
uint8_t *input = avpkt->data;
|
||||
int input_size = avpkt->size;
|
||||
int i, ret, prev_packet = s->packet;
|
||||
|
||||
if (input_size < MIN_PACKET_SIZE || input_size > MAX_PACKET_SIZE) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid packet size\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
av_fast_malloc(&s->buffer, &s->buffer_size,
|
||||
FFALIGN(input_size, 4096) + DCA_BUFFER_PADDING_SIZE);
|
||||
if (!s->buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (i = 0, ret = AVERROR_INVALIDDATA; i < input_size - MIN_PACKET_SIZE + 1 && ret < 0; i++)
|
||||
ret = convert_bitstream(input + i, input_size - i, s->buffer, s->buffer_size);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
input = s->buffer;
|
||||
input_size = ret;
|
||||
|
||||
s->packet = 0;
|
||||
|
||||
// Parse backward compatible core sub-stream
|
||||
if (AV_RB32(input) == DCA_SYNCWORD_CORE_BE) {
|
||||
int frame_size;
|
||||
|
||||
if ((ret = ff_dca_core_parse(&s->core, input, input_size)) < 0) {
|
||||
s->core_residual_valid = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s->packet |= DCA_PACKET_CORE;
|
||||
|
||||
// EXXS data must be aligned on 4-byte boundary
|
||||
frame_size = FFALIGN(s->core.frame_size, 4);
|
||||
if (input_size - 4 > frame_size) {
|
||||
input += frame_size;
|
||||
input_size -= frame_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s->core_only) {
|
||||
DCAExssAsset *asset = NULL;
|
||||
|
||||
// Parse extension sub-stream (EXSS)
|
||||
if (AV_RB32(input) == DCA_SYNCWORD_SUBSTREAM) {
|
||||
if ((ret = ff_dca_exss_parse(&s->exss, input, input_size)) < 0) {
|
||||
if (avctx->err_recognition & AV_EF_EXPLODE)
|
||||
return ret;
|
||||
} else {
|
||||
s->packet |= DCA_PACKET_EXSS;
|
||||
asset = &s->exss.assets[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Parse XLL component in EXSS
|
||||
if (asset && (asset->extension_mask & DCA_EXSS_XLL)) {
|
||||
if ((ret = ff_dca_xll_parse(&s->xll, input, asset)) < 0) {
|
||||
// Conceal XLL synchronization error
|
||||
if (ret == AVERROR(EAGAIN)
|
||||
&& (prev_packet & DCA_PACKET_XLL)
|
||||
&& (s->packet & DCA_PACKET_CORE))
|
||||
s->packet |= DCA_PACKET_XLL | DCA_PACKET_RECOVERY;
|
||||
else if (ret == AVERROR(ENOMEM) || (avctx->err_recognition & AV_EF_EXPLODE))
|
||||
return ret;
|
||||
} else {
|
||||
s->packet |= DCA_PACKET_XLL;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse core extensions in EXSS or backward compatible core sub-stream
|
||||
if ((s->packet & DCA_PACKET_CORE)
|
||||
&& (ret = ff_dca_core_parse_exss(&s->core, input, asset)) < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Filter the frame
|
||||
if (s->packet & DCA_PACKET_XLL) {
|
||||
if (s->packet & DCA_PACKET_CORE) {
|
||||
int x96_synth = -1;
|
||||
|
||||
// Enable X96 synthesis if needed
|
||||
if (s->xll.chset[0].freq == 96000 && s->core.sample_rate == 48000)
|
||||
x96_synth = 1;
|
||||
|
||||
if ((ret = ff_dca_core_filter_fixed(&s->core, x96_synth)) < 0) {
|
||||
s->core_residual_valid = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Force lossy downmixed output on the first core frame filtered.
|
||||
// This prevents audible clicks when seeking and is consistent with
|
||||
// what reference decoder does when there are multiple channel sets.
|
||||
if (!s->core_residual_valid) {
|
||||
if (s->xll.nreschsets > 0 && s->xll.nchsets > 1)
|
||||
s->packet |= DCA_PACKET_RECOVERY;
|
||||
s->core_residual_valid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = ff_dca_xll_filter_frame(&s->xll, frame)) < 0) {
|
||||
// Fall back to core unless hard error
|
||||
if (!(s->packet & DCA_PACKET_CORE))
|
||||
return ret;
|
||||
if (ret != AVERROR_INVALIDDATA || (avctx->err_recognition & AV_EF_EXPLODE))
|
||||
return ret;
|
||||
if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0) {
|
||||
s->core_residual_valid = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else if (s->packet & DCA_PACKET_CORE) {
|
||||
if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0) {
|
||||
s->core_residual_valid = 0;
|
||||
return ret;
|
||||
}
|
||||
s->core_residual_valid = !!(s->core.filter_mode & DCA_FILTER_MODE_FIXED);
|
||||
} else {
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
*got_frame_ptr = 1;
|
||||
|
||||
return avpkt->size;
|
||||
}
|
||||
|
||||
static av_cold void dcadec_flush(AVCodecContext *avctx)
|
||||
{
|
||||
DCAContext *s = avctx->priv_data;
|
||||
|
||||
ff_dca_core_flush(&s->core);
|
||||
ff_dca_xll_flush(&s->xll);
|
||||
|
||||
s->core_residual_valid = 0;
|
||||
}
|
||||
|
||||
static av_cold int dcadec_close(AVCodecContext *avctx)
|
||||
{
|
||||
DCAContext *s = avctx->priv_data;
|
||||
|
||||
ff_dca_core_close(&s->core);
|
||||
ff_dca_xll_close(&s->xll);
|
||||
|
||||
av_freep(&s->buffer);
|
||||
s->buffer_size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int dcadec_init(AVCodecContext *avctx)
|
||||
{
|
||||
DCAContext *s = avctx->priv_data;
|
||||
|
||||
s->avctx = avctx;
|
||||
s->core.avctx = avctx;
|
||||
s->exss.avctx = avctx;
|
||||
s->xll.avctx = avctx;
|
||||
|
||||
if (ff_dca_core_init(&s->core) < 0)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ff_dcadsp_init(&s->dcadsp);
|
||||
s->core.dcadsp = &s->dcadsp;
|
||||
s->xll.dcadsp = &s->dcadsp;
|
||||
|
||||
switch (avctx->request_channel_layout & ~AV_CH_LAYOUT_NATIVE) {
|
||||
case 0:
|
||||
s->request_channel_layout = 0;
|
||||
break;
|
||||
case AV_CH_LAYOUT_STEREO:
|
||||
case AV_CH_LAYOUT_STEREO_DOWNMIX:
|
||||
s->request_channel_layout = DCA_SPEAKER_LAYOUT_STEREO;
|
||||
break;
|
||||
case AV_CH_LAYOUT_5POINT0:
|
||||
s->request_channel_layout = DCA_SPEAKER_LAYOUT_5POINT0;
|
||||
break;
|
||||
case AV_CH_LAYOUT_5POINT1:
|
||||
s->request_channel_layout = DCA_SPEAKER_LAYOUT_5POINT1;
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
|
||||
break;
|
||||
}
|
||||
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
|
||||
avctx->bits_per_raw_sample = 24;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OFFSET(x) offsetof(DCAContext, x)
|
||||
#define PARAM AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
|
||||
|
||||
static const AVOption dcadec_options[] = {
|
||||
{ "core_only", "Decode core only without extensions", OFFSET(core_only), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, PARAM },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const AVClass dcadec_class = {
|
||||
.class_name = "DCA decoder",
|
||||
.item_name = av_default_item_name,
|
||||
.option = dcadec_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.category = AV_CLASS_CATEGORY_DECODER,
|
||||
};
|
||||
|
||||
AVCodec ff_dca_decoder = {
|
||||
.name = "dca",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_DTS,
|
||||
.priv_data_size = sizeof(DCAContext),
|
||||
.init = dcadec_init,
|
||||
.decode = dcadec_decode_frame,
|
||||
.close = dcadec_close,
|
||||
.flush = dcadec_flush,
|
||||
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
|
||||
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE },
|
||||
.priv_class = &dcadec_class,
|
||||
.profiles = NULL_IF_CONFIG_SMALL(ff_dca_profiles),
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
};
|
80
libavcodec/dcadec.h
Normal file
80
libavcodec/dcadec.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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_DCADEC_H
|
||||
#define AVCODEC_DCADEC_H
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/float_dsp.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
#include "dca.h"
|
||||
#include "dcadsp.h"
|
||||
#include "dca_core.h"
|
||||
#include "dca_exss.h"
|
||||
#include "dca_xll.h"
|
||||
|
||||
#define DCA_BUFFER_PADDING_SIZE 1024
|
||||
|
||||
#define DCA_PACKET_CORE 0x01
|
||||
#define DCA_PACKET_EXSS 0x02
|
||||
#define DCA_PACKET_XLL 0x04
|
||||
#define DCA_PACKET_RECOVERY 0x08
|
||||
|
||||
typedef struct DCAContext {
|
||||
const AVClass *class; ///< class for AVOptions
|
||||
AVCodecContext *avctx;
|
||||
|
||||
DCACoreDecoder core; ///< Core decoder context
|
||||
DCAExssParser exss; ///< EXSS parser context
|
||||
DCAXllDecoder xll; ///< XLL decoder context
|
||||
|
||||
DCADSPContext dcadsp;
|
||||
|
||||
uint8_t *buffer; ///< Packet buffer
|
||||
unsigned int buffer_size;
|
||||
|
||||
int packet; ///< Packet flags
|
||||
|
||||
int core_residual_valid; ///< Core valid for residual decoding
|
||||
|
||||
int request_channel_layout; ///< Converted from avctx.request_channel_layout
|
||||
int core_only; ///< Core only decoding flag
|
||||
} DCAContext;
|
||||
|
||||
int ff_dca_set_channel_layout(AVCodecContext *avctx, int *ch_remap, int dca_mask);
|
||||
|
||||
int ff_dca_check_crc(GetBitContext *s, int p1, int p2);
|
||||
|
||||
void ff_dca_downmix_to_stereo_fixed(DCADSPContext *dcadsp, int32_t **samples,
|
||||
int *coeff_l, int nsamples, int ch_mask);
|
||||
void ff_dca_downmix_to_stereo_float(AVFloatDSPContext *fdsp, float **samples,
|
||||
int *coeff_l, int nsamples, int ch_mask);
|
||||
|
||||
static inline int ff_dca_seek_bits(GetBitContext *s, int p)
|
||||
{
|
||||
if (p < s->index || p > s->size_in_bits)
|
||||
return -1;
|
||||
s->index = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
413
libavcodec/dcadsp.c
Normal file
413
libavcodec/dcadsp.c
Normal file
@ -0,0 +1,413 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "dcadsp.h"
|
||||
#include "dcamath.h"
|
||||
|
||||
static void decode_hf_c(int32_t **dst,
|
||||
const int32_t *vq_index,
|
||||
const int8_t hf_vq[1024][32],
|
||||
int32_t scale_factors[32][2],
|
||||
intptr_t sb_start, intptr_t sb_end,
|
||||
intptr_t ofs, intptr_t len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = sb_start; i < sb_end; i++) {
|
||||
const int8_t *coeff = hf_vq[vq_index[i]];
|
||||
int32_t scale = scale_factors[i][0];
|
||||
for (j = 0; j < len; j++)
|
||||
dst[i][j + ofs] = clip23(coeff[j] * scale + (1 << 3) >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_joint_c(int32_t **dst, int32_t **src,
|
||||
const int32_t *scale_factors,
|
||||
intptr_t sb_start, intptr_t sb_end,
|
||||
intptr_t ofs, intptr_t len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = sb_start; i < sb_end; i++) {
|
||||
int32_t scale = scale_factors[i];
|
||||
for (j = 0; j < len; j++)
|
||||
dst[i][j + ofs] = clip23(mul17(src[i][j + ofs], scale));
|
||||
}
|
||||
}
|
||||
|
||||
static void lfe_fir_float_c(float *pcm_samples, int32_t *lfe_samples,
|
||||
const float *filter_coeff, intptr_t npcmblocks,
|
||||
int dec_select)
|
||||
{
|
||||
// Select decimation factor
|
||||
int factor = 64 << dec_select;
|
||||
int ncoeffs = 8 >> dec_select;
|
||||
int nlfesamples = npcmblocks >> (dec_select + 1);
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0; i < nlfesamples; i++) {
|
||||
// One decimated sample generates 64 or 128 interpolated ones
|
||||
for (j = 0; j < factor / 2; j++) {
|
||||
float a = 0;
|
||||
float b = 0;
|
||||
|
||||
for (k = 0; k < ncoeffs; k++) {
|
||||
a += filter_coeff[ j * ncoeffs + k] * lfe_samples[-k];
|
||||
b += filter_coeff[255 - j * ncoeffs - k] * lfe_samples[-k];
|
||||
}
|
||||
|
||||
pcm_samples[ j] = a;
|
||||
pcm_samples[factor / 2 + j] = b;
|
||||
}
|
||||
|
||||
lfe_samples++;
|
||||
pcm_samples += factor;
|
||||
}
|
||||
}
|
||||
|
||||
static void lfe_fir1_float_c(float *pcm_samples, int32_t *lfe_samples,
|
||||
const float *filter_coeff, intptr_t npcmblocks)
|
||||
{
|
||||
lfe_fir_float_c(pcm_samples, lfe_samples, filter_coeff, npcmblocks, 0);
|
||||
}
|
||||
|
||||
static void lfe_fir2_float_c(float *pcm_samples, int32_t *lfe_samples,
|
||||
const float *filter_coeff, intptr_t npcmblocks)
|
||||
{
|
||||
lfe_fir_float_c(pcm_samples, lfe_samples, filter_coeff, npcmblocks, 1);
|
||||
}
|
||||
|
||||
static void lfe_x96_float_c(float *dst, const float *src,
|
||||
float *hist, intptr_t len)
|
||||
{
|
||||
float prev = *hist;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
float a = 0.25f * src[i] + 0.75f * prev;
|
||||
float b = 0.75f * src[i] + 0.25f * prev;
|
||||
prev = src[i];
|
||||
*dst++ = a;
|
||||
*dst++ = b;
|
||||
}
|
||||
|
||||
*hist = prev;
|
||||
}
|
||||
|
||||
static void sub_qmf32_float_c(SynthFilterContext *synth,
|
||||
FFTContext *imdct,
|
||||
float *pcm_samples,
|
||||
int32_t **subband_samples_lo,
|
||||
int32_t **subband_samples_hi,
|
||||
float *hist1, int *offset, float *hist2,
|
||||
const float *filter_coeff, intptr_t npcmblocks,
|
||||
float scale)
|
||||
{
|
||||
LOCAL_ALIGNED(32, float, input, [32]);
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < npcmblocks; j++) {
|
||||
// Load in one sample from each subband
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((i - 1) & 2)
|
||||
input[i] = -subband_samples_lo[i][j];
|
||||
else
|
||||
input[i] = subband_samples_lo[i][j];
|
||||
}
|
||||
|
||||
// One subband sample generates 32 interpolated ones
|
||||
synth->synth_filter_float(imdct, hist1, offset,
|
||||
hist2, filter_coeff,
|
||||
pcm_samples, input, scale);
|
||||
pcm_samples += 32;
|
||||
}
|
||||
}
|
||||
|
||||
static void sub_qmf64_float_c(SynthFilterContext *synth,
|
||||
FFTContext *imdct,
|
||||
float *pcm_samples,
|
||||
int32_t **subband_samples_lo,
|
||||
int32_t **subband_samples_hi,
|
||||
float *hist1, int *offset, float *hist2,
|
||||
const float *filter_coeff, intptr_t npcmblocks,
|
||||
float scale)
|
||||
{
|
||||
LOCAL_ALIGNED(32, float, input, [64]);
|
||||
int i, j;
|
||||
|
||||
if (!subband_samples_hi)
|
||||
memset(&input[32], 0, sizeof(input[0]) * 32);
|
||||
|
||||
for (j = 0; j < npcmblocks; j++) {
|
||||
// Load in one sample from each subband
|
||||
if (subband_samples_hi) {
|
||||
// Full 64 subbands, first 32 are residual coded
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((i - 1) & 2)
|
||||
input[i] = -subband_samples_lo[i][j] - subband_samples_hi[i][j];
|
||||
else
|
||||
input[i] = subband_samples_lo[i][j] + subband_samples_hi[i][j];
|
||||
}
|
||||
for (i = 32; i < 64; i++) {
|
||||
if ((i - 1) & 2)
|
||||
input[i] = -subband_samples_hi[i][j];
|
||||
else
|
||||
input[i] = subband_samples_hi[i][j];
|
||||
}
|
||||
} else {
|
||||
// Only first 32 subbands
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((i - 1) & 2)
|
||||
input[i] = -subband_samples_lo[i][j];
|
||||
else
|
||||
input[i] = subband_samples_lo[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// One subband sample generates 64 interpolated ones
|
||||
synth->synth_filter_float_64(imdct, hist1, offset,
|
||||
hist2, filter_coeff,
|
||||
pcm_samples, input, scale);
|
||||
pcm_samples += 64;
|
||||
}
|
||||
}
|
||||
|
||||
static void lfe_fir_fixed_c(int32_t *pcm_samples, int32_t *lfe_samples,
|
||||
const int32_t *filter_coeff, intptr_t npcmblocks)
|
||||
{
|
||||
// Select decimation factor
|
||||
int nlfesamples = npcmblocks >> 1;
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0; i < nlfesamples; i++) {
|
||||
// One decimated sample generates 64 interpolated ones
|
||||
for (j = 0; j < 32; j++) {
|
||||
int64_t a = 0;
|
||||
int64_t b = 0;
|
||||
|
||||
for (k = 0; k < 8; k++) {
|
||||
a += (int64_t)filter_coeff[ j * 8 + k] * lfe_samples[-k];
|
||||
b += (int64_t)filter_coeff[255 - j * 8 - k] * lfe_samples[-k];
|
||||
}
|
||||
|
||||
pcm_samples[ j] = clip23(norm23(a));
|
||||
pcm_samples[32 + j] = clip23(norm23(b));
|
||||
}
|
||||
|
||||
lfe_samples++;
|
||||
pcm_samples += 64;
|
||||
}
|
||||
}
|
||||
|
||||
static void lfe_x96_fixed_c(int32_t *dst, const int32_t *src,
|
||||
int32_t *hist, intptr_t len)
|
||||
{
|
||||
int32_t prev = *hist;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
int64_t a = INT64_C(2097471) * src[i] + INT64_C(6291137) * prev;
|
||||
int64_t b = INT64_C(6291137) * src[i] + INT64_C(2097471) * prev;
|
||||
prev = src[i];
|
||||
*dst++ = clip23(norm23(a));
|
||||
*dst++ = clip23(norm23(b));
|
||||
}
|
||||
|
||||
*hist = prev;
|
||||
}
|
||||
|
||||
static void sub_qmf32_fixed_c(SynthFilterContext *synth,
|
||||
DCADCTContext *imdct,
|
||||
int32_t *pcm_samples,
|
||||
int32_t **subband_samples_lo,
|
||||
int32_t **subband_samples_hi,
|
||||
int32_t *hist1, int *offset, int32_t *hist2,
|
||||
const int32_t *filter_coeff, intptr_t npcmblocks)
|
||||
{
|
||||
LOCAL_ALIGNED(32, int32_t, input, [32]);
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < npcmblocks; j++) {
|
||||
// Load in one sample from each subband
|
||||
for (i = 0; i < 32; i++)
|
||||
input[i] = subband_samples_lo[i][j];
|
||||
|
||||
// One subband sample generates 32 interpolated ones
|
||||
synth->synth_filter_fixed(imdct, hist1, offset,
|
||||
hist2, filter_coeff,
|
||||
pcm_samples, input);
|
||||
pcm_samples += 32;
|
||||
}
|
||||
}
|
||||
|
||||
static void sub_qmf64_fixed_c(SynthFilterContext *synth,
|
||||
DCADCTContext *imdct,
|
||||
int32_t *pcm_samples,
|
||||
int32_t **subband_samples_lo,
|
||||
int32_t **subband_samples_hi,
|
||||
int32_t *hist1, int *offset, int32_t *hist2,
|
||||
const int32_t *filter_coeff, intptr_t npcmblocks)
|
||||
{
|
||||
LOCAL_ALIGNED(32, int32_t, input, [64]);
|
||||
int i, j;
|
||||
|
||||
if (!subband_samples_hi)
|
||||
memset(&input[32], 0, sizeof(input[0]) * 32);
|
||||
|
||||
for (j = 0; j < npcmblocks; j++) {
|
||||
// Load in one sample from each subband
|
||||
if (subband_samples_hi) {
|
||||
// Full 64 subbands, first 32 are residual coded
|
||||
for (i = 0; i < 32; i++)
|
||||
input[i] = subband_samples_lo[i][j] + subband_samples_hi[i][j];
|
||||
for (i = 32; i < 64; i++)
|
||||
input[i] = subband_samples_hi[i][j];
|
||||
} else {
|
||||
// Only first 32 subbands
|
||||
for (i = 0; i < 32; i++)
|
||||
input[i] = subband_samples_lo[i][j];
|
||||
}
|
||||
|
||||
// One subband sample generates 64 interpolated ones
|
||||
synth->synth_filter_fixed_64(imdct, hist1, offset,
|
||||
hist2, filter_coeff,
|
||||
pcm_samples, input);
|
||||
pcm_samples += 64;
|
||||
}
|
||||
}
|
||||
|
||||
static void decor_c(int32_t *dst, const int32_t *src, intptr_t coeff, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] += src[i] * coeff + (1 << 2) >> 3;
|
||||
}
|
||||
|
||||
static void dmix_sub_xch_c(int32_t *dst1, int32_t *dst2,
|
||||
const int32_t *src, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
int32_t cs = mul23(src[i], 5931520 /* M_SQRT1_2 * (1 << 23) */);
|
||||
dst1[i] -= cs;
|
||||
dst2[i] -= cs;
|
||||
}
|
||||
}
|
||||
|
||||
static void dmix_sub_c(int32_t *dst, const int32_t *src, intptr_t coeff, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] -= mul15(src[i], coeff);
|
||||
}
|
||||
|
||||
static void dmix_add_c(int32_t *dst, const int32_t *src, intptr_t coeff, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] += mul15(src[i], coeff);
|
||||
}
|
||||
|
||||
static void dmix_scale_c(int32_t *dst, intptr_t scale, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] = mul15(dst[i], scale);
|
||||
}
|
||||
|
||||
static void dmix_scale_inv_c(int32_t *dst, intptr_t scale_inv, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] = mul16(dst[i], scale_inv);
|
||||
}
|
||||
|
||||
static void filter0(int32_t *dst, const int32_t *src, int32_t coeff, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] -= mul22(src[i], coeff);
|
||||
}
|
||||
|
||||
static void filter1(int32_t *dst, const int32_t *src, int32_t coeff, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] -= mul23(src[i], coeff);
|
||||
}
|
||||
|
||||
static void assemble_freq_bands_c(int32_t *dst, int32_t *src0, int32_t *src1,
|
||||
const int32_t *coeff, intptr_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
filter0(src0, src1, coeff[0], len);
|
||||
filter0(src1, src0, coeff[1], len);
|
||||
filter0(src0, src1, coeff[2], len);
|
||||
filter0(src1, src0, coeff[3], len);
|
||||
|
||||
for (i = 0; i < 8; i++, src0--) {
|
||||
filter1(src0, src1, coeff[i + 4], len);
|
||||
filter1(src1, src0, coeff[i + 12], len);
|
||||
filter1(src0, src1, coeff[i + 4], len);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
*dst++ = *src1++;
|
||||
*dst++ = *++src0;
|
||||
}
|
||||
}
|
||||
|
||||
av_cold void ff_dcadsp_init(DCADSPContext *s)
|
||||
{
|
||||
s->decode_hf = decode_hf_c;
|
||||
s->decode_joint = decode_joint_c;
|
||||
|
||||
s->lfe_fir_float[0] = lfe_fir1_float_c;
|
||||
s->lfe_fir_float[1] = lfe_fir2_float_c;
|
||||
s->lfe_x96_float = lfe_x96_float_c;
|
||||
s->sub_qmf_float[0] = sub_qmf32_float_c;
|
||||
s->sub_qmf_float[1] = sub_qmf64_float_c;
|
||||
|
||||
s->lfe_fir_fixed = lfe_fir_fixed_c;
|
||||
s->lfe_x96_fixed = lfe_x96_fixed_c;
|
||||
s->sub_qmf_fixed[0] = sub_qmf32_fixed_c;
|
||||
s->sub_qmf_fixed[1] = sub_qmf64_fixed_c;
|
||||
|
||||
s->decor = decor_c;
|
||||
|
||||
s->dmix_sub_xch = dmix_sub_xch_c;
|
||||
s->dmix_sub = dmix_sub_c;
|
||||
s->dmix_add = dmix_add_c;
|
||||
s->dmix_scale = dmix_scale_c;
|
||||
s->dmix_scale_inv = dmix_scale_inv_c;
|
||||
|
||||
s->assemble_freq_bands = assemble_freq_bands_c;
|
||||
}
|
91
libavcodec/dcadsp.h
Normal file
91
libavcodec/dcadsp.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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_DCADSP_H
|
||||
#define AVCODEC_DCADSP_H
|
||||
|
||||
#include "libavutil/common.h"
|
||||
|
||||
#include "fft.h"
|
||||
#include "dcadct.h"
|
||||
#include "synth_filter.h"
|
||||
|
||||
typedef struct DCADSPContext {
|
||||
void (*decode_hf)(int32_t **dst,
|
||||
const int32_t *vq_index,
|
||||
const int8_t hf_vq[1024][32],
|
||||
int32_t scale_factors[32][2],
|
||||
intptr_t sb_start, intptr_t sb_end,
|
||||
intptr_t ofs, intptr_t len);
|
||||
|
||||
void (*decode_joint)(int32_t **dst, int32_t **src,
|
||||
const int32_t *scale_factors,
|
||||
intptr_t sb_start, intptr_t sb_end,
|
||||
intptr_t ofs, intptr_t len);
|
||||
|
||||
void (*lfe_fir_float[2])(float *pcm_samples, int32_t *lfe_samples,
|
||||
const float *filter_coeff, intptr_t npcmblocks);
|
||||
|
||||
void (*lfe_x96_float)(float *dst, const float *src,
|
||||
float *hist, intptr_t len);
|
||||
|
||||
void (*sub_qmf_float[2])(SynthFilterContext *synth,
|
||||
FFTContext *imdct,
|
||||
float *pcm_samples,
|
||||
int32_t **subband_samples_lo,
|
||||
int32_t **subband_samples_hi,
|
||||
float *hist1, int *offset, float *hist2,
|
||||
const float *filter_coeff, intptr_t npcmblocks,
|
||||
float scale);
|
||||
|
||||
void (*lfe_fir_fixed)(int32_t *pcm_samples, int32_t *lfe_samples,
|
||||
const int32_t *filter_coeff, intptr_t npcmblocks);
|
||||
|
||||
void (*lfe_x96_fixed)(int32_t *dst, const int32_t *src,
|
||||
int32_t *hist, intptr_t len);
|
||||
|
||||
void (*sub_qmf_fixed[2])(SynthFilterContext *synth,
|
||||
DCADCTContext *imdct,
|
||||
int32_t *pcm_samples,
|
||||
int32_t **subband_samples_lo,
|
||||
int32_t **subband_samples_hi,
|
||||
int32_t *hist1, int *offset, int32_t *hist2,
|
||||
const int32_t *filter_coeff, intptr_t npcmblocks);
|
||||
|
||||
void (*decor)(int32_t *dst, const int32_t *src, intptr_t coeff, intptr_t len);
|
||||
|
||||
void (*dmix_sub_xch)(int32_t *dst1, int32_t *dst2,
|
||||
const int32_t *src, intptr_t len);
|
||||
|
||||
void (*dmix_sub)(int32_t *dst, const int32_t *src, intptr_t coeff, intptr_t len);
|
||||
|
||||
void (*dmix_add)(int32_t *dst, const int32_t *src, intptr_t coeff, intptr_t len);
|
||||
|
||||
void (*dmix_scale)(int32_t *dst, intptr_t scale, intptr_t len);
|
||||
|
||||
void (*dmix_scale_inv)(int32_t *dst, intptr_t scale_inv, intptr_t len);
|
||||
|
||||
void (*assemble_freq_bands)(int32_t *dst, int32_t *src0, int32_t *src1,
|
||||
const int32_t *coeff, intptr_t len);
|
||||
} DCADSPContext;
|
||||
|
||||
av_cold void ff_dcadsp_init(DCADSPContext *s);
|
||||
|
||||
#endif
|
@ -30,7 +30,7 @@
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 57
|
||||
#define LIBAVCODEC_VERSION_MINOR 24
|
||||
#define LIBAVCODEC_VERSION_MICRO 100
|
||||
#define LIBAVCODEC_VERSION_MICRO 101
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
|
@ -44,7 +44,7 @@ OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp_init.o
|
||||
OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp_init.o
|
||||
OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o
|
||||
OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o
|
||||
#OBJS-$(CONFIG_DCA_DECODER) += x86/synth_filter_init.o
|
||||
OBJS-$(CONFIG_DCA_DECODER) += x86/synth_filter_init.o
|
||||
OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o
|
||||
OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp_init.o
|
||||
@ -132,7 +132,7 @@ YASM-OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp.o
|
||||
YASM-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp.o
|
||||
YASM-OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp.o
|
||||
YASM-OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp.o
|
||||
#YASM-OBJS-$(CONFIG_DCA_DECODER) += x86/synth_filter.o
|
||||
YASM-OBJS-$(CONFIG_DCA_DECODER) += x86/synth_filter.o
|
||||
YASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp_mmx.o x86/diracdsp_yasm.o \
|
||||
x86/dwt_yasm.o
|
||||
YASM-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o
|
||||
|
@ -1,7 +1,7 @@
|
||||
# libavcodec tests
|
||||
AVCODECOBJS-$(CONFIG_ALAC_DECODER) += alacdsp.o
|
||||
AVCODECOBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o
|
||||
#AVCODECOBJS-$(CONFIG_DCA_DECODER) += synth_filter.o
|
||||
AVCODECOBJS-$(CONFIG_DCA_DECODER) += synth_filter.o
|
||||
AVCODECOBJS-$(CONFIG_FLACDSP) += flacdsp.o
|
||||
AVCODECOBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o
|
||||
AVCODECOBJS-$(CONFIG_H264PRED) += h264pred.o
|
||||
|
@ -71,9 +71,9 @@ static const struct {
|
||||
#if CONFIG_BSWAPDSP
|
||||
{ "bswapdsp", checkasm_check_bswapdsp },
|
||||
#endif
|
||||
/* #if CONFIG_DCA_DECODER
|
||||
#if CONFIG_DCA_DECODER
|
||||
{ "synth_filter", checkasm_check_synth_filter },
|
||||
#endif*/
|
||||
#endif
|
||||
#if CONFIG_FLACDSP
|
||||
{ "flacdsp", checkasm_check_flacdsp },
|
||||
#endif
|
||||
|
@ -99,14 +99,14 @@ FATE_ACODEC-$(call ENCDEC, ALAC, MOV) += fate-acodec-alac
|
||||
fate-acodec-alac: FMT = mov
|
||||
fate-acodec-alac: CODEC = alac -compression_level 1
|
||||
|
||||
#FATE_ACODEC-$(call ENCDEC, DCA, DTS) += fate-acodec-dca
|
||||
FATE_ACODEC-$(call ENCDEC, DCA, DTS) += fate-acodec-dca
|
||||
fate-acodec-dca: tests/data/asynth-44100-2.wav
|
||||
fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav
|
||||
fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact
|
||||
fate-acodec-dca: CMP = oneline
|
||||
fate-acodec-dca: REF = 7ffdefdf47069289990755c79387cc90
|
||||
|
||||
#FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2
|
||||
FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2
|
||||
fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact
|
||||
fate-acodec-dca2: REF = $(SRC)
|
||||
fate-acodec-dca2: CMP = stddev
|
||||
|
@ -21,7 +21,7 @@ fate-dca-core: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts.ts
|
||||
fate-dca-core: CMP = oneoff
|
||||
fate-dca-core: REF = $(SAMPLES)/dts/dts.pcm
|
||||
|
||||
#FATE_SAMPLES_AUDIO-$(CONFIG_DCA_DECODER) += $(FATE_DCA-yes)
|
||||
FATE_SAMPLES_AUDIO-$(CONFIG_DCA_DECODER) += $(FATE_DCA-yes)
|
||||
fate-dca: $(FATE_DCA-yes)
|
||||
|
||||
FATE_SAMPLES_AUDIO-$(call DEMDEC, DSICIN, DSICINAUDIO) += fate-delphine-cin-audio
|
||||
@ -31,7 +31,7 @@ FATE_SAMPLES_AUDIO-$(call DEMDEC, DSS, DSS_SP) += fate-dss-lp fate-dss-sp
|
||||
fate-dss-lp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/lp.dss -frames 30
|
||||
fate-dss-sp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/sp.dss -frames 30
|
||||
|
||||
#FATE_SAMPLES_AUDIO-$(call DEMDEC, DTS, DCA) += fate-dts_es
|
||||
FATE_SAMPLES_AUDIO-$(call DEMDEC, DTS, DCA) += fate-dts_es
|
||||
fate-dts_es: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts_es.dts
|
||||
fate-dts_es: CMP = oneoff
|
||||
fate-dts_es: REF = $(SAMPLES)/dts/dts_es_2.pcm
|
||||
|
Loading…
Reference in New Issue
Block a user