aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/dca_lbr.h
blob: e6856a2cf7c5b06e966569206f52f95cdd043194 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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_internal.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

enum DCALBRHeader {
    DCA_LBR_HEADER_SYNC_ONLY    = 1,
    DCA_LBR_HEADER_DECODER_INIT = 2
};

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