Commit 6c44696b authored by foo86's avatar foo86 Committed by James Almer

avcodec/dca: add DTS Express (LBR) decoder

Signed-off-by: 's avatarJames Almer <jamrial@gmail.com>
parent fce75131
......@@ -31,6 +31,7 @@ version <next>:
- Duck TrueMotion 2.0 Real Time decoder
- Wideband Single-bit Data (WSD) demuxer
- VAAPI-accelerated H.264/HEVC/MJPEG encoding
- DTS Express (LBR) decoder
version 3.0:
- Common Encryption (CENC) MP4 encoding and decoding support
......
......@@ -232,7 +232,7 @@ 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 dcahuff.o \
dca_core.o dca_exss.o dca_xll.o \
dca_core.o dca_exss.o dca_xll.o dca_lbr.o \
dcadsp.o dcadct.o synth_filter.o
OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o
OBJS-$(CONFIG_DDS_DECODER) += dds.o
......
This diff is collapsed.
/*
* 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_LBR_H
#define AVCODEC_DCA_LBR_H
#include "libavutil/common.h"
#include "libavutil/float_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 "fft.h"
#define DCA_LBR_CHANNELS 6
#define DCA_LBR_CHANNELS_TOTAL 32
#define DCA_LBR_SUBBANDS 32
#define DCA_LBR_TONES 512
#define DCA_LBR_TIME_SAMPLES 128
#define DCA_LBR_TIME_HISTORY 8
typedef struct DCALbrTone {
uint8_t x_freq; ///< Spectral line offset
uint8_t f_delt; ///< Difference between original and center frequency
uint8_t ph_rot; ///< Phase rotation
uint8_t pad; ///< Padding field
uint8_t amp[DCA_LBR_CHANNELS]; ///< Per-channel amplitude
uint8_t phs[DCA_LBR_CHANNELS]; ///< Per-channel phase
} DCALbrTone;
typedef struct DCALbrDecoder {
AVCodecContext *avctx;
GetBitContext gb;
int sample_rate; ///< Sample rate of LBR audio
int ch_mask; ///< LBR speaker mask
int flags; ///< Flags for LBR decoder initialization
int bit_rate_orig; ///< Original bit rate
int bit_rate_scaled; ///< Scaled bit rate
int nchannels; ///< Number of fullband channels to decode
int nchannels_total; ///< Total number of fullband channels
int freq_range; ///< Frequency range of LBR audio
int band_limit; ///< Band limit factor
int limited_rate; ///< Band limited sample rate
int limited_range; ///< Band limited frequency range
int res_profile; ///< Resolution profile
int nsubbands; ///< Number of encoded subbands
int g3_avg_only_start_sb; ///< Subband index where grid 3 scale factors end
int min_mono_subband; ///< Subband index where mono encoding starts
int max_mono_subband; ///< Subband index where mono encoding ends
int framenum; ///< Lower 5 bits of current frame number
int lbr_rand; ///< Seed for subband randomization
int warned; ///< Flags for warning suppression
uint8_t quant_levels[DCA_LBR_CHANNELS / 2][DCA_LBR_SUBBANDS]; ///< Quantization levels
uint8_t sb_indices[DCA_LBR_SUBBANDS]; ///< Subband reordering indices
uint8_t sec_ch_sbms[DCA_LBR_CHANNELS / 2][DCA_LBR_SUBBANDS]; ///< Right channel inversion or mid/side decoding flags
uint8_t sec_ch_lrms[DCA_LBR_CHANNELS / 2][DCA_LBR_SUBBANDS]; ///< Flags indicating if left/right channel are swapped
uint32_t ch_pres[DCA_LBR_CHANNELS]; ///< Subband allocation flags
uint8_t grid_1_scf[DCA_LBR_CHANNELS][12][8]; ///< Grid 1 scale factors
uint8_t grid_2_scf[DCA_LBR_CHANNELS][3][64]; ///< Grid 2 scale factors
int8_t grid_3_avg[DCA_LBR_CHANNELS][DCA_LBR_SUBBANDS - 4]; ///< Grid 3 average values
int8_t grid_3_scf[DCA_LBR_CHANNELS][DCA_LBR_SUBBANDS - 4][8]; ///< Grid 3 scale factors
uint32_t grid_3_pres[DCA_LBR_CHANNELS]; ///< Grid 3 scale factors presence flags
uint8_t high_res_scf[DCA_LBR_CHANNELS][DCA_LBR_SUBBANDS][8]; ///< High-frequency resolution scale factors
uint8_t part_stereo[DCA_LBR_CHANNELS][DCA_LBR_SUBBANDS / 4][5]; ///< Partial stereo coefficients
uint8_t part_stereo_pres; ///< Partial stereo coefficients presence flags
float lpc_coeff[2][DCA_LBR_CHANNELS][3][2][8]; ///< Predictor coefficients
float sb_scf[DCA_LBR_SUBBANDS]; ///< Subband randomization scale factors
float *time_samples[DCA_LBR_CHANNELS][DCA_LBR_SUBBANDS]; ///< Time samples
float *ts_buffer; ///< Time sample buffer base
unsigned int ts_size; ///< Time sample buffer size
DECLARE_ALIGNED(32, float, history)[DCA_LBR_CHANNELS][DCA_LBR_SUBBANDS * 4]; ///< IMDCT history
DECLARE_ALIGNED(32, float, window)[DCA_LBR_SUBBANDS * 4]; ///< Long window for IMDCT
DECLARE_ALIGNED(32, float, lfe_data)[64]; ///< Decimated LFE samples
DECLARE_ALIGNED(32, float, lfe_history)[5][2]; ///< LFE IIR filter history
float lfe_scale; ///< Scale factor of LFE samples before IIR filter
uint8_t tonal_scf[6]; ///< Tonal scale factors
uint16_t tonal_bounds[5][32][2]; ///< Per-group per-subframe start/end positions of tones
DCALbrTone tones[DCA_LBR_TONES]; ///< Circular buffer of tones
int ntones; ///< Circular buffer head position
FFTContext imdct;
AVFloatDSPContext *fdsp;
DCADSPContext *dcadsp;
} DCALbrDecoder;
int ff_dca_lbr_parse(DCALbrDecoder *s, uint8_t *data, DCAExssAsset *asset);
int ff_dca_lbr_filter_frame(DCALbrDecoder *s, AVFrame *frame);
av_cold void ff_dca_lbr_flush(DCALbrDecoder *s);
av_cold int ff_dca_lbr_init(DCALbrDecoder *s);
av_cold void ff_dca_lbr_close(DCALbrDecoder *s);
#endif
This diff is collapsed.
......@@ -73,4 +73,51 @@ extern const int32_t ff_dca_xll_band_coeff[20];
extern const int32_t ff_dca_sampling_freqs[16];
extern const uint16_t ff_dca_avg_g3_freqs[3];
extern const uint16_t ff_dca_fst_amp[44];
extern const uint8_t ff_dca_freq_to_sb[32];
extern const int8_t ff_dca_ph0_shift[8];
extern const uint8_t ff_dca_grid_1_to_scf[11];
extern const uint8_t ff_dca_grid_2_to_scf[3];
extern const uint8_t ff_dca_scf_to_grid_1[32];
extern const uint8_t ff_dca_scf_to_grid_2[32];
extern const uint8_t ff_dca_grid_1_weights[12][32];
extern const uint8_t ff_dca_sb_reorder[8][8];
extern const int8_t ff_dca_lfe_delta_index_16[8];
extern const int8_t ff_dca_lfe_delta_index_24[32];
extern const uint16_t ff_dca_rsd_pack_5_in_8[256];
extern const uint8_t ff_dca_rsd_pack_3_in_7[128][3];
extern const float ff_dca_rsd_level_2a[2];
extern const float ff_dca_rsd_level_2b[2];
extern const float ff_dca_rsd_level_3[3];
extern const float ff_dca_rsd_level_5[5];
extern const float ff_dca_rsd_level_8[8];
extern const float ff_dca_rsd_level_16[16];
extern const float ff_dca_synth_env[32];
extern const float ff_dca_corr_cf[32][11];
extern const float ff_dca_quant_amp[57];
extern const float ff_dca_st_coeff[34];
extern const float ff_dca_long_window[128];
extern const float ff_dca_lfe_step_size_16[101];
extern const float ff_dca_lfe_step_size_24[144];
extern const float ff_dca_bank_coeff[10];
extern const float ff_dca_lfe_iir[5][4];
#endif /* AVCODEC_DCADATA_H */
......@@ -235,6 +235,16 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
}
}
// Parse LBR component in EXSS
if (asset && (asset->extension_mask & DCA_EXSS_LBR)) {
if ((ret = ff_dca_lbr_parse(&s->lbr, input, asset)) < 0) {
if (ret == AVERROR(ENOMEM) || (avctx->err_recognition & AV_EF_EXPLODE))
return ret;
} else {
s->packet |= DCA_PACKET_LBR;
}
}
// 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)
......@@ -242,7 +252,10 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
}
// Filter the frame
if (s->packet & DCA_PACKET_XLL) {
if (s->packet & DCA_PACKET_LBR) {
if ((ret = ff_dca_lbr_filter_frame(&s->lbr, frame)) < 0)
return ret;
} else if (s->packet & DCA_PACKET_XLL) {
if (s->packet & DCA_PACKET_CORE) {
int x96_synth = -1;
......@@ -297,6 +310,7 @@ static av_cold void dcadec_flush(AVCodecContext *avctx)
ff_dca_core_flush(&s->core);
ff_dca_xll_flush(&s->xll);
ff_dca_lbr_flush(&s->lbr);
s->core_residual_valid = 0;
}
......@@ -307,6 +321,7 @@ static av_cold int dcadec_close(AVCodecContext *avctx)
ff_dca_core_close(&s->core);
ff_dca_xll_close(&s->xll);
ff_dca_lbr_close(&s->lbr);
av_freep(&s->buffer);
s->buffer_size = 0;
......@@ -322,15 +337,20 @@ static av_cold int dcadec_init(AVCodecContext *avctx)
s->core.avctx = avctx;
s->exss.avctx = avctx;
s->xll.avctx = avctx;
s->lbr.avctx = avctx;
ff_dca_init_vlcs();
if (ff_dca_core_init(&s->core) < 0)
return AVERROR(ENOMEM);
if (ff_dca_lbr_init(&s->lbr) < 0)
return AVERROR(ENOMEM);
ff_dcadsp_init(&s->dcadsp);
s->core.dcadsp = &s->dcadsp;
s->xll.dcadsp = &s->dcadsp;
s->lbr.dcadsp = &s->dcadsp;
s->crctab = av_crc_get_table(AV_CRC_16_CCITT);
......
......@@ -32,13 +32,15 @@
#include "dca_core.h"
#include "dca_exss.h"
#include "dca_xll.h"
#include "dca_lbr.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
#define DCA_PACKET_LBR 0x08
#define DCA_PACKET_RECOVERY 0x10
typedef struct DCAContext {
const AVClass *class; ///< class for AVOptions
......@@ -47,6 +49,7 @@ typedef struct DCAContext {
DCACoreDecoder core; ///< Core decoder context
DCAExssParser exss; ///< EXSS parser context
DCAXllDecoder xll; ///< XLL decoder context
DCALbrDecoder lbr; ///< LBR decoder context
DCADSPContext dcadsp;
......
......@@ -385,6 +385,77 @@ static void assemble_freq_bands_c(int32_t *dst, int32_t *src0, int32_t *src1,
}
}
static void lbr_bank_c(float output[32][4], float **input,
const float *coeff, ptrdiff_t ofs, ptrdiff_t len)
{
float SW0 = coeff[0];
float SW1 = coeff[1];
float SW2 = coeff[2];
float SW3 = coeff[3];
float C1 = coeff[4];
float C2 = coeff[5];
float C3 = coeff[6];
float C4 = coeff[7];
float AL1 = coeff[8];
float AL2 = coeff[9];
int i;
// Short window and 8 point forward MDCT
for (i = 0; i < len; i++) {
float *src = input[i] + ofs;
float a = src[-4] * SW0 - src[-1] * SW3;
float b = src[-3] * SW1 - src[-2] * SW2;
float c = src[ 2] * SW1 + src[ 1] * SW2;
float d = src[ 3] * SW0 + src[ 0] * SW3;
output[i][0] = C1 * b - C2 * c + C4 * a - C3 * d;
output[i][1] = C1 * d - C2 * a - C4 * b - C3 * c;
output[i][2] = C3 * b + C2 * d - C4 * c + C1 * a;
output[i][3] = C3 * a - C2 * b + C4 * d - C1 * c;
}
// Aliasing cancellation for high frequencies
for (i = 12; i < len - 1; i++) {
float a = output[i ][3] * AL1;
float b = output[i+1][0] * AL1;
output[i ][3] += b - a;
output[i+1][0] -= b + a;
a = output[i ][2] * AL2;
b = output[i+1][1] * AL2;
output[i ][2] += b - a;
output[i+1][1] -= b + a;
}
}
static void lfe_iir_c(float *output, const float *input,
const float iir[5][4], float hist[5][2],
ptrdiff_t factor)
{
float res, tmp;
int i, j, k;
for (i = 0; i < 64; i++) {
res = *input++;
for (j = 0; j < factor; j++) {
for (k = 0; k < 5; k++) {
tmp = hist[k][0] * iir[k][0] + hist[k][1] * iir[k][1] + res;
res = hist[k][0] * iir[k][2] + hist[k][1] * iir[k][3] + tmp;
hist[k][0] = hist[k][1];
hist[k][1] = tmp;
}
*output++ = res;
res = 0;
}
}
}
av_cold void ff_dcadsp_init(DCADSPContext *s)
{
s->decode_hf = decode_hf_c;
......@@ -411,6 +482,9 @@ av_cold void ff_dcadsp_init(DCADSPContext *s)
s->assemble_freq_bands = assemble_freq_bands_c;
s->lbr_bank = lbr_bank_c;
s->lfe_iir = lfe_iir_c;
if (ARCH_X86)
ff_dcadsp_init_x86(s);
}
......@@ -84,6 +84,13 @@ typedef struct DCADSPContext {
void (*assemble_freq_bands)(int32_t *dst, int32_t *src0, int32_t *src1,
const int32_t *coeff, ptrdiff_t len);
void (*lbr_bank)(float output[32][4], float **input,
const float *coeff, ptrdiff_t ofs, ptrdiff_t len);
void (*lfe_iir)(float *output, const float *input,
const float iir[5][4], float hist[5][2],
ptrdiff_t factor);
} DCADSPContext;
av_cold void ff_dcadsp_init(DCADSPContext *s);
......
This diff is collapsed.
......@@ -41,6 +41,19 @@ extern DCAVLC ff_dca_vlc_transition_mode;
extern DCAVLC ff_dca_vlc_scale_factor;
extern DCAVLC ff_dca_vlc_quant_index[DCA_CODE_BOOKS];
extern VLC ff_dca_vlc_tnl_grp[5];
extern VLC ff_dca_vlc_tnl_scf;
extern VLC ff_dca_vlc_damp;
extern VLC ff_dca_vlc_dph;
extern VLC ff_dca_vlc_fst_rsd_amp;
extern VLC ff_dca_vlc_rsd_apprx;
extern VLC ff_dca_vlc_rsd_amp;
extern VLC ff_dca_vlc_avg_g3;
extern VLC ff_dca_vlc_st_grid;
extern VLC ff_dca_vlc_grid_2;
extern VLC ff_dca_vlc_grid_3;
extern VLC ff_dca_vlc_rsd;
av_cold void ff_dca_init_vlcs(void);
#endif /* AVCODEC_DCAHUFF_H */
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