Commit 217e4ff4 authored by Niels Möller's avatar Niels Möller Committed by Diego Biurrun

dca: Support for XLL (lossless extension)

Cleanup and integration by Diego Biurrun.
Signed-off-by: default avatarDiego Biurrun <diego@biurrun.de>
parent 4da5aacc
......@@ -23,6 +23,7 @@ version <next>:
- RTP depacketization of T.140 text (RFC 4103)
- VP9 RTP payload format (draft 0) experimental depacketizer
- TDSC decoder
- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
version 11:
......
......@@ -828,6 +828,7 @@ following image formats are supported:
@item COOK @tab @tab X
@tab All versions except 5.1 are supported.
@item DCA (DTS Coherent Acoustics) @tab @tab X
@tab supported extensions: XCh, XLL (partially)
@item DPCM id RoQ @tab X @tab X
@tab Used in Quake III, Jedi Knight 2, other computer games.
@item DPCM Interplay @tab @tab X
......
......@@ -161,7 +161,7 @@ OBJS-$(CONFIG_CSCD_DECODER) += cscd.o
OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadsp.o \
dcadata.o dca_exss.o \
synth_filter.o
dca_xll.o synth_filter.o
OBJS-$(CONFIG_DFA_DECODER) += dfa.o
OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o
OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o
......
......@@ -42,6 +42,21 @@
#define DCA_BLOCKS_MAX (16)
#define DCA_LFE_MAX (3)
#define DCA_PRIM_CHANNELS_MAX (7)
#define DCA_ABITS_MAX (32) /* Should be 28 */
#define DCA_SUBSUBFRAMES_MAX (4)
#define DCA_SUBFRAMES_MAX (16)
#define DCA_BLOCKS_MAX (16)
#define DCA_LFE_MAX (3)
#define DCA_XLL_FBANDS_MAX (4)
#define DCA_XLL_SEGMENTS_MAX (16)
#define DCA_XLL_CHSETS_MAX (16)
#define DCA_XLL_CHANNELS_MAX (16)
#define DCA_XLL_AORDER_MAX (15)
/* Arbitrary limit; not sure what the maximum really is, but much larger. */
#define DCA_XLL_DMIX_NCOEFFS_MAX (18)
#define DCA_MAX_FRAME_SIZE 16384
#define DCA_MAX_EXSS_HEADER_SIZE 4096
......@@ -60,6 +75,61 @@ enum DCAExtensionMask {
DCA_EXT_EXSS_XLL = 0x200, ///< lossless extension in ExSS
};
typedef struct XllChSetSubHeader {
int channels; ///< number of channels in channel set, at most 16
int residual_encode; ///< residual channel encoding
int bit_resolution; ///< input sample bit-width
int bit_width; ///< original input sample bit-width
int sampling_frequency; ///< sampling frequency
int samp_freq_interp; ///< sampling frequency interpolation multiplier
int replacement_set; ///< replacement channel set group
int active_replace_set; ///< current channel set is active channel set
int primary_ch_set;
int downmix_coeff_code_embedded;
int downmix_embedded;
int downmix_type;
int hier_chset; ///< hierarchical channel set
int downmix_ncoeffs;
int downmix_coeffs[DCA_XLL_DMIX_NCOEFFS_MAX];
int ch_mask_enabled;
int ch_mask;
int mapping_coeffs_present;
int num_freq_bands;
/* m_nOrigChanOrder */
uint8_t orig_chan_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
uint8_t orig_chan_order_inv[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
/* Coefficients for channel pairs (at most 8), m_anPWChPairsCoeffs */
int8_t pw_ch_pairs_coeffs[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX/2];
/* m_nCurrHighestLPCOrder */
uint8_t adapt_order_max[DCA_XLL_FBANDS_MAX];
/* m_pnAdaptPredOrder */
uint8_t adapt_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
/* m_pnFixedPredOrder */
uint8_t fixed_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
/* m_pnLPCReflCoeffsQInd, unsigned version */
uint8_t lpc_refl_coeffs_q_ind[DCA_XLL_FBANDS_MAX]
[DCA_XLL_CHANNELS_MAX][DCA_XLL_AORDER_MAX];
int lsb_fsize[DCA_XLL_FBANDS_MAX];
int8_t scalable_lsbs[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
int8_t bit_width_adj_per_ch[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
} XllChSetSubHeader;
typedef struct XllNavi {
GetBitContext gb; // Context for parsing the data segments
unsigned band_size[DCA_XLL_FBANDS_MAX];
unsigned segment_size[DCA_XLL_FBANDS_MAX][DCA_XLL_SEGMENTS_MAX];
unsigned chset_size[DCA_XLL_FBANDS_MAX][DCA_XLL_SEGMENTS_MAX][DCA_XLL_CHSETS_MAX];
} XllNavi;
typedef struct QMF64_table {
float dct4_coeff[32][32];
float dct2_coeff[32][32];
float rcos[32];
float rsin[32];
} QMF64_table;
typedef struct DCAContext {
AVClass *class; ///< class for AVOptions
AVCodecContext *avctx;
......@@ -132,8 +202,10 @@ typedef struct DCAContext {
/* Subband samples history (for ADPCM) */
DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32];
/* Half size is sufficient for core decoding, but for 96 kHz data
* we need QMF with 64 subbands and 1024 samples. */
DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][1024];
DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][64];
int hist_index[DCA_PRIM_CHANNELS_MAX];
DECLARE_ALIGNED(32, float, raXin)[32];
......@@ -155,12 +227,31 @@ typedef struct DCAContext {
int current_subsubframe;
int core_ext_mask; ///< present extensions in the core substream
int exss_ext_mask; ///< Non-core extensions
/* XCh extension information */
int xch_present; ///< XCh extension present and valid
int xch_base_channel; ///< index of first (only) channel containing XCH data
int xch_disable; ///< whether the XCh extension should be decoded or not
/* XLL extension information */
int xll_disable;
int xll_nch_sets; ///< number of channel sets per frame
int xll_channels; ///< total number of channels (in all channel sets)
int xll_residual_channels; ///< number of residual channels
int xll_segments; ///< number of segments per frame
int xll_log_smpl_in_seg; ///< supposedly this is "nBits4SamplLoci"
int xll_smpl_in_seg; ///< samples in segment per one frequency band for the first channel set
int xll_bits4seg_size; ///< number of bits used to read segment size
int xll_banddata_crc; ///< presence of CRC16 within each frequency band
int xll_scalable_lsb;
int xll_bits4ch_mask; ///< channel position mask
int xll_fixed_lsb_width;
XllChSetSubHeader xll_chsets[DCA_XLL_CHSETS_MAX];
XllNavi xll_navi;
int *xll_sample_buf;
unsigned int xll_sample_buf_size;
/* ExSS header parser */
int static_fields; ///< static fields present
int mix_metadata; ///< mixing metadata present
......@@ -168,12 +259,14 @@ typedef struct DCAContext {
int mix_config_num_ch[4]; ///< number of channels in each mix out configuration
int profile;
int one2one_map_chtospkr;
int debug_flag; ///< used for suppressing repeated error messages output
AVFloatDSPContext fdsp;
FFTContext imdct;
SynthFilterContext synth;
DCADSPContext dcadsp;
QMF64_table *qmf64_table;
FmtConvertContext fmt_conv;
} DCAContext;
......@@ -187,4 +280,8 @@ int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
void ff_dca_exss_parse_header(DCAContext *s);
int ff_dca_xll_decode_header(DCAContext *s);
int ff_dca_xll_decode_navi(DCAContext *s, int asset_end);
int ff_dca_xll_decode_audio(DCAContext *s, AVFrame *frame);
#endif /* AVCODEC_DCA_H */
......@@ -22,6 +22,7 @@
#include "libavutil/log.h"
#include "dca.h"
#include "dca_syncwords.h"
#include "get_bits.h"
/* extensions that reside in core substream */
......@@ -121,7 +122,8 @@ static int dca_exss_parse_asset_header(DCAContext *s)
skip_bits(&s->gb, 4); // max sample rate code
channels = get_bits(&s->gb, 8) + 1;
if (get_bits1(&s->gb)) { // 1-to-1 channels to speakers
s->one2one_map_chtospkr = get_bits1(&s->gb);
if (s->one2one_map_chtospkr) {
int spkr_remap_sets;
int spkr_mask_size = 16;
int num_spkrs[7];
......@@ -242,21 +244,27 @@ static int dca_exss_parse_asset_header(DCAContext *s)
*/
void ff_dca_exss_parse_header(DCAContext *s)
{
int asset_size[8];
int ss_index;
int blownup;
int num_audiop = 1;
int num_assets = 1;
int active_ss_mask[8];
int i, j;
int start_pos;
int hdrsize;
uint32_t mkr;
if (get_bits_left(&s->gb) < 52)
return;
start_pos = get_bits_count(&s->gb) - 32;
skip_bits(&s->gb, 8); // user data
ss_index = get_bits(&s->gb, 2);
blownup = get_bits1(&s->gb);
skip_bits(&s->gb, 8 + 4 * blownup); // header_size
hdrsize = get_bits(&s->gb, 8 + 4 * blownup) + 1; // header_size
skip_bits(&s->gb, 16 + 4 * blownup); // hd_size
s->static_fields = get_bits1(&s->gb);
......@@ -309,13 +317,52 @@ void ff_dca_exss_parse_header(DCAContext *s)
}
for (i = 0; i < num_assets; i++)
skip_bits_long(&s->gb, 16 + 4 * blownup); // asset size
asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup) + 1;
for (i = 0; i < num_assets; i++) {
if (dca_exss_parse_asset_header(s))
return;
}
/* not parsed further, we were only interested in the extensions mask
* from the asset header */
if (num_assets > 0) {
j = get_bits_count(&s->gb);
if (start_pos + hdrsize * 8 > j)
skip_bits_long(&s->gb, start_pos + hdrsize * 8 - j);
for (i = 0; i < num_assets; i++) {
int end_pos;
start_pos = get_bits_count(&s->gb);
end_pos = start_pos + asset_size[i] * 8;
mkr = get_bits_long(&s->gb, 32);
/* parse extensions that we know about */
switch (mkr) {
case DCA_SYNCWORD_XLL:
if (s->xll_disable) {
av_log(s->avctx, AV_LOG_DEBUG,
"DTS-XLL: ignoring XLL extension\n");
break;
}
av_log(s->avctx, AV_LOG_DEBUG,
"DTS-XLL: decoding XLL extension\n");
if (ff_dca_xll_decode_header(s) == 0 &&
ff_dca_xll_decode_navi(s, end_pos) == 0)
s->exss_ext_mask |= DCA_EXT_EXSS_XLL;
break;
case DCA_SYNCWORD_XBR:
case DCA_SYNCWORD_XXCH:
default:
av_log(s->avctx, AV_LOG_VERBOSE,
"DTS-ExSS: unknown marker = 0x%08"PRIx32"\n", mkr);
}
/* skip to end of block */
j = get_bits_count(&s->gb);
if (j > end_pos)
av_log(s->avctx, AV_LOG_ERROR,
"DTS-ExSS: Processed asset too long.\n");
if (j < end_pos)
skip_bits_long(&s->gb, end_pos - j);
}
}
}
This diff is collapsed.
This diff is collapsed.
......@@ -47,11 +47,19 @@ extern const float ff_dca_fir_32bands_nonperfect[512];
extern const float ff_dca_lfe_fir_64[256];
extern const float ff_dca_lfe_fir_128[256];
extern const float ff_dca_lfe_xll_fir_64[256];
extern const float ff_dca_fir_64bands[1024];
extern const uint16_t ff_dca_dmixtable[242];
#define FF_DCA_DMIXTABLE_SIZE 242
#define FF_DCA_INV_DMIXTABLE_SIZE 201
extern const uint16_t ff_dca_dmixtable[FF_DCA_DMIXTABLE_SIZE];
extern const uint32_t ff_dca_inv_dmixtable[FF_DCA_INV_DMIXTABLE_SIZE];
extern const float ff_dca_default_coeffs[10][6][2];
extern const int32_t ff_dca_sampling_freqs[16];
extern const int8_t ff_dca_lfe_index[16];
extern const int8_t ff_dca_channel_reorder_lfe[16][9];
......
......@@ -4,6 +4,8 @@
* Copyright (C) 2004 Benjamin Zores
* Copyright (C) 2006 Benjamin Larsson
* Copyright (C) 2007 Konstantin Shishkov
* Copyright (C) 2012 Paul B Mahol
* Copyright (C) 2014 Niels Möller
*
* This file is part of Libav.
*
......@@ -26,6 +28,7 @@
#include <stddef.h>
#include <stdio.h>
#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
......@@ -555,8 +558,83 @@ static void qmf_32_subbands(DCAContext *s, int chans,
samples_out, s->raXin, scale);
}
static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
int num_deci_sample, float *samples_in,
static QMF64_table *qmf64_precompute(void)
{
unsigned i, j;
QMF64_table *table = av_malloc(sizeof(*table));
if (!table)
return NULL;
for (i = 0; i < 32; i++)
for (j = 0; j < 32; j++)
table->dct4_coeff[i][j] = cos((2 * i + 1) * (2 * j + 1) * M_PI / 128);
for (i = 0; i < 32; i++)
for (j = 0; j < 32; j++)
table->dct2_coeff[i][j] = cos((2 * i + 1) * j * M_PI / 64);
/* FIXME: Is the factor 0.125 = 1/8 right? */
for (i = 0; i < 32; i++)
table->rcos[i] = 0.125 / cos((2 * i + 1) * M_PI / 256);
for (i = 0; i < 32; i++)
table->rsin[i] = -0.125 / sin((2 * i + 1) * M_PI / 256);
return table;
}
/* FIXME: Totally unoptimized. Based on the reference code and
* http://multimedia.cx/mirror/dca-transform.pdf, with guessed tweaks
* for doubling the size. */
static void qmf_64_subbands(DCAContext *s, int chans, float samples_in[64][8],
float *samples_out, float scale)
{
float raXin[64];
float A[32], B[32];
float *raX = s->subband_fir_hist[chans];
float *raZ = s->subband_fir_noidea[chans];
unsigned i, j, k, subindex;
for (i = s->subband_activity[chans]; i < 64; i++)
raXin[i] = 0.0;
for (subindex = 0; subindex < 8; subindex++) {
for (i = 0; i < s->subband_activity[chans]; i++)
raXin[i] = samples_in[i][subindex];
for (k = 0; k < 32; k++) {
A[k] = 0.0;
for (i = 0; i < 32; i++)
A[k] += (raXin[2 * i] + raXin[2 * i + 1]) * s->qmf64_table->dct4_coeff[k][i];
}
for (k = 0; k < 32; k++) {
B[k] = raXin[0] * s->qmf64_table->dct2_coeff[k][0];
for (i = 1; i < 32; i++)
B[k] += (raXin[2 * i] + raXin[2 * i - 1]) * s->qmf64_table->dct2_coeff[k][i];
}
for (k = 0; k < 32; k++) {
raX[k] = s->qmf64_table->rcos[k] * (A[k] + B[k]);
raX[63 - k] = s->qmf64_table->rsin[k] * (A[k] - B[k]);
}
for (i = 0; i < 64; i++) {
float out = raZ[i];
for (j = 0; j < 1024; j += 128)
out += ff_dca_fir_64bands[j + i] * (raX[j + i] - raX[j + 63 - i]);
*samples_out++ = out * scale;
}
for (i = 0; i < 64; i++) {
float hist = 0.0;
for (j = 0; j < 1024; j += 128)
hist += ff_dca_fir_64bands[64 + j + i] * (-raX[i + j] - raX[j + 63 - i]);
raZ[i] = hist;
}
/* FIXME: Make buffer circular, to avoid this move. */
memmove(raX + 64, raX, (1024 - 64) * sizeof(*raX));
}
}
static void lfe_interpolation_fir(DCAContext *s, const float *samples_in,
float *samples_out)
{
/* samples_in: An array holding decimated samples.
......@@ -572,15 +650,18 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
int deciindex;
/* Select decimation filter */
if (decimation_select == 1) {
if (s->lfe == 1) {
idx = 1;
prCoeff = ff_dca_lfe_fir_128;
} else {
idx = 0;
prCoeff = ff_dca_lfe_fir_64;
idx = 0;
if (s->exss_ext_mask & DCA_EXT_EXSS_XLL)
prCoeff = ff_dca_lfe_xll_fir_64;
else
prCoeff = ff_dca_lfe_fir_64;
}
/* Interpolation */
for (deciindex = 0; deciindex < num_deci_sample; deciindex++) {
for (deciindex = 0; deciindex < 2 * s->lfe; deciindex++) {
s->dcadsp.lfe_fir[idx](samples_out, samples_in, prCoeff);
samples_in++;
samples_out += 2 * 32 * (1 + idx);
......@@ -849,27 +930,56 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
return 0;
}
static int dca_filter_channels(DCAContext *s, int block_index)
static int dca_filter_channels(DCAContext *s, int block_index, int upsample)
{
float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index];
int k;
/* 32 subbands QMF */
for (k = 0; k < s->prim_channels; k++) {
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);
if (upsample) {
if (!s->qmf64_table) {
s->qmf64_table = qmf64_precompute();
if (!s->qmf64_table)
return AVERROR(ENOMEM);
}
/* 64 subbands QMF */
for (k = 0; k < s->prim_channels; k++) {
if (s->channel_order_tab[k] >= 0)
qmf_64_subbands(s, k, subband_samples[k],
s->samples_chanptr[s->channel_order_tab[k]],
/* Upsampling needs a factor 2 here. */
M_SQRT2 / 32768.0);
}
} else {
/* 32 subbands QMF */
for (k = 0; k < s->prim_channels; k++) {
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);
}
}
/* Generate LFE samples for this subsubframe FIXME!!! */
if (s->lfe) {
lfe_interpolation_fir(s, s->lfe, 2 * s->lfe,
float *samples = s->samples_chanptr[ff_dca_lfe_index[s->amode]];
lfe_interpolation_fir(s,
s->lfe_data + 2 * s->lfe * (block_index + 4),
s->samples_chanptr[ff_dca_lfe_index[s->amode]]);
/* Outputs 20bits pcm samples */
samples);
if (upsample) {
unsigned i;
/* Should apply the filter in Table 6-11 when upsampling. For
* now, just duplicate. */
for (i = 511; i > 0; i--) {
samples[2 * i] =
samples[2 * i + 1] = samples[i];
}
samples[1] = samples[0];
}
}
/* FIXME: This downmixing is probably broken with upsample.
* Probably totally broken also with XLL in general. */
/* Downmixing to Stereo */
if (s->prim_channels + !!s->lfe > 2 &&
s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
......@@ -1050,8 +1160,10 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
DCAContext *s = avctx->priv_data;
int channels, full_channels;
int core_ss_end;
int upsample = 0;
s->xch_present = 0;
s->exss_ext_mask = 0;
s->xch_present = 0;
s->dca_buffer_size = ff_dca_convert_bitstream(buf, buf_size, s->dca_buffer,
DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
......@@ -1279,6 +1391,43 @@ FF_ENABLE_DEPRECATION_WARNINGS
/* get output buffer */
frame->nb_samples = 256 * (s->sample_blocks / 8);
if (s->exss_ext_mask & DCA_EXT_EXSS_XLL) {
int xll_nb_samples = s->xll_segments * s->xll_smpl_in_seg;
/* Check for invalid/unsupported conditions first */
if (s->xll_residual_channels > channels) {
av_log(s->avctx, AV_LOG_WARNING,
"DCA: too many residual channels (%d, core channels %d). Disabling XLL\n",
s->xll_residual_channels, channels);
s->exss_ext_mask &= ~DCA_EXT_EXSS_XLL;
} else if (xll_nb_samples != frame->nb_samples &&
2 * frame->nb_samples != xll_nb_samples) {
av_log(s->avctx, AV_LOG_WARNING,
"DCA: unsupported upsampling (%d XLL samples, %d core samples). Disabling XLL\n",
xll_nb_samples, frame->nb_samples);
s->exss_ext_mask &= ~DCA_EXT_EXSS_XLL;
} else {
if (2 * frame->nb_samples == xll_nb_samples) {
av_log(s->avctx, AV_LOG_INFO,
"XLL: upsampling core channels by a factor of 2\n");
upsample = 1;
frame->nb_samples = xll_nb_samples;
// FIXME: Is it good enough to copy from the first channel set?
avctx->sample_rate = s->xll_chsets[0].sampling_frequency;
}
/* If downmixing to stereo, don't decode additional channels.
* FIXME: Using the xch_disable flag for this doesn't seem right. */
if (!s->xch_disable)
avctx->channels += s->xll_channels - s->xll_residual_channels;
}
}
/* FIXME: This is an ugly hack, to just revert to the default
* layout if we have additional channels. Need to convert the XLL
* channel masks to libav channel_layout mask. */
if (av_get_channel_layout_nb_channels(avctx->channel_layout) != avctx->channels)
avctx->channel_layout = 0;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
......@@ -1309,13 +1458,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
/* filter to get final output */
for (i = 0; i < (s->sample_blocks / 8); i++) {
int ch;
unsigned block = upsample ? 512 : 256;
for (ch = 0; ch < channels; ch++)
s->samples_chanptr[ch] = samples_flt[ch] + i * 256;
s->samples_chanptr[ch] = samples_flt[ch] + i * block;
for (; ch < full_channels; ch++)
s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256;
s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * block;
dca_filter_channels(s, i);
dca_filter_channels(s, i, upsample);
/* If this was marked as a DTS-ES stream we need to subtract back- */
/* channel from SL & SR to remove matrixed back-channel signal */
......@@ -1333,6 +1482,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
for (i = 0; i < 2 * s->lfe * 4; i++)
s->lfe_data[i] = s->lfe_data[i + lfe_samples];
if (s->exss_ext_mask & DCA_EXT_EXSS_XLL) {
ret = ff_dca_xll_decode_audio(s, frame);
if (ret < 0)
return ret;
}
/* AVMatrixEncoding
*
* DCA_STEREO_TOTAL (Lt/Rt) is equivalent to Dolby Surround */
......@@ -1387,6 +1541,8 @@ 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);
av_freep(&s->xll_sample_buf);
av_freep(&s->qmf64_table);
return 0;
}
......@@ -1401,6 +1557,7 @@ static const AVProfile profiles[] = {
static const AVOption options[] = {
{ "disable_xch", "disable decoding of the XCh extension", offsetof(DCAContext, xch_disable), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
{ "disable_xll", "disable decoding of the XLL extension", offsetof(DCAContext, xll_disable), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
{ NULL },
};
......
......@@ -29,7 +29,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56
#define LIBAVCODEC_VERSION_MINOR 18
#define LIBAVCODEC_VERSION_MINOR 19
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment