1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * E-AC-3 decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
4cabdff1aSopenharmony_ci * Copyright (c) 2008 Justin Ruggles
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci/*
24cabdff1aSopenharmony_ci * There are several features of E-AC-3 that this decoder does not yet support.
25cabdff1aSopenharmony_ci *
26cabdff1aSopenharmony_ci * Enhanced Coupling
27cabdff1aSopenharmony_ci *     No known samples exist.  If any ever surface, this feature should not be
28cabdff1aSopenharmony_ci *     too difficult to implement.
29cabdff1aSopenharmony_ci *
30cabdff1aSopenharmony_ci * Reduced Sample Rates
31cabdff1aSopenharmony_ci *     No known samples exist.  The spec also does not give clear information
32cabdff1aSopenharmony_ci *     on how this is to be implemented.
33cabdff1aSopenharmony_ci *
34cabdff1aSopenharmony_ci * Transient Pre-noise Processing
35cabdff1aSopenharmony_ci *     This is side information which a decoder should use to reduce artifacts
36cabdff1aSopenharmony_ci *     caused by transients.  There are samples which are known to have this
37cabdff1aSopenharmony_ci *     information, but this decoder currently ignores it.
38cabdff1aSopenharmony_ci */
39cabdff1aSopenharmony_ci
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_ci#include "avcodec.h"
42cabdff1aSopenharmony_ci#include "aac_ac3_parser.h"
43cabdff1aSopenharmony_ci#include "ac3.h"
44cabdff1aSopenharmony_ci#include "ac3dec.h"
45cabdff1aSopenharmony_ci#include "ac3dec_data.h"
46cabdff1aSopenharmony_ci#include "eac3_data.h"
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci/** gain adaptive quantization mode */
49cabdff1aSopenharmony_citypedef enum {
50cabdff1aSopenharmony_ci    EAC3_GAQ_NO =0,
51cabdff1aSopenharmony_ci    EAC3_GAQ_12,
52cabdff1aSopenharmony_ci    EAC3_GAQ_14,
53cabdff1aSopenharmony_ci    EAC3_GAQ_124
54cabdff1aSopenharmony_ci} EAC3GaqMode;
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci#define EAC3_SR_CODE_REDUCED  3
57cabdff1aSopenharmony_ci
58cabdff1aSopenharmony_cistatic void ff_eac3_apply_spectral_extension(AC3DecodeContext *s)
59cabdff1aSopenharmony_ci{
60cabdff1aSopenharmony_ci    int bin, bnd, ch, i;
61cabdff1aSopenharmony_ci    uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS];
62cabdff1aSopenharmony_ci    float rms_energy[SPX_MAX_BANDS];
63cabdff1aSopenharmony_ci
64cabdff1aSopenharmony_ci    /* Set copy index mapping table. Set wrap flags to apply a notch filter at
65cabdff1aSopenharmony_ci       wrap points later on. */
66cabdff1aSopenharmony_ci    bin = s->spx_dst_start_freq;
67cabdff1aSopenharmony_ci    num_copy_sections = 0;
68cabdff1aSopenharmony_ci    for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
69cabdff1aSopenharmony_ci        int copysize;
70cabdff1aSopenharmony_ci        int bandsize = s->spx_band_sizes[bnd];
71cabdff1aSopenharmony_ci        if (bin + bandsize > s->spx_src_start_freq) {
72cabdff1aSopenharmony_ci            copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
73cabdff1aSopenharmony_ci            bin = s->spx_dst_start_freq;
74cabdff1aSopenharmony_ci            wrapflag[bnd] = 1;
75cabdff1aSopenharmony_ci        }
76cabdff1aSopenharmony_ci        for (i = 0; i < bandsize; i += copysize) {
77cabdff1aSopenharmony_ci            if (bin == s->spx_src_start_freq) {
78cabdff1aSopenharmony_ci                copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
79cabdff1aSopenharmony_ci                bin = s->spx_dst_start_freq;
80cabdff1aSopenharmony_ci            }
81cabdff1aSopenharmony_ci            copysize = FFMIN(bandsize - i, s->spx_src_start_freq - bin);
82cabdff1aSopenharmony_ci            bin += copysize;
83cabdff1aSopenharmony_ci        }
84cabdff1aSopenharmony_ci    }
85cabdff1aSopenharmony_ci    copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
86cabdff1aSopenharmony_ci
87cabdff1aSopenharmony_ci    for (ch = 1; ch <= s->fbw_channels; ch++) {
88cabdff1aSopenharmony_ci        if (!s->channel_uses_spx[ch])
89cabdff1aSopenharmony_ci            continue;
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci        /* Copy coeffs from normal bands to extension bands */
92cabdff1aSopenharmony_ci        bin = s->spx_src_start_freq;
93cabdff1aSopenharmony_ci        for (i = 0; i < num_copy_sections; i++) {
94cabdff1aSopenharmony_ci            memcpy(&s->transform_coeffs[ch][bin],
95cabdff1aSopenharmony_ci                   &s->transform_coeffs[ch][s->spx_dst_start_freq],
96cabdff1aSopenharmony_ci                   copy_sizes[i]*sizeof(INTFLOAT));
97cabdff1aSopenharmony_ci            bin += copy_sizes[i];
98cabdff1aSopenharmony_ci        }
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci        /* Calculate RMS energy for each SPX band. */
101cabdff1aSopenharmony_ci        bin = s->spx_src_start_freq;
102cabdff1aSopenharmony_ci        for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
103cabdff1aSopenharmony_ci            int bandsize = s->spx_band_sizes[bnd];
104cabdff1aSopenharmony_ci            float accum = 0.0f;
105cabdff1aSopenharmony_ci            for (i = 0; i < bandsize; i++) {
106cabdff1aSopenharmony_ci                float coeff = s->transform_coeffs[ch][bin++];
107cabdff1aSopenharmony_ci                accum += coeff * coeff;
108cabdff1aSopenharmony_ci            }
109cabdff1aSopenharmony_ci            rms_energy[bnd] = sqrtf(accum / bandsize);
110cabdff1aSopenharmony_ci        }
111cabdff1aSopenharmony_ci
112cabdff1aSopenharmony_ci        /* Apply a notch filter at transitions between normal and extension
113cabdff1aSopenharmony_ci           bands and at all wrap points. */
114cabdff1aSopenharmony_ci        if (s->spx_atten_code[ch] >= 0) {
115cabdff1aSopenharmony_ci            const float *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]];
116cabdff1aSopenharmony_ci            bin = s->spx_src_start_freq - 2;
117cabdff1aSopenharmony_ci            for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
118cabdff1aSopenharmony_ci                if (wrapflag[bnd]) {
119cabdff1aSopenharmony_ci                    INTFLOAT *coeffs = &s->transform_coeffs[ch][bin];
120cabdff1aSopenharmony_ci                    coeffs[0] *= atten_tab[0];
121cabdff1aSopenharmony_ci                    coeffs[1] *= atten_tab[1];
122cabdff1aSopenharmony_ci                    coeffs[2] *= atten_tab[2];
123cabdff1aSopenharmony_ci                    coeffs[3] *= atten_tab[1];
124cabdff1aSopenharmony_ci                    coeffs[4] *= atten_tab[0];
125cabdff1aSopenharmony_ci                }
126cabdff1aSopenharmony_ci                bin += s->spx_band_sizes[bnd];
127cabdff1aSopenharmony_ci            }
128cabdff1aSopenharmony_ci        }
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_ci        /* Apply noise-blended coefficient scaling based on previously
131cabdff1aSopenharmony_ci           calculated RMS energy, blending factors, and SPX coordinates for
132cabdff1aSopenharmony_ci           each band. */
133cabdff1aSopenharmony_ci        bin = s->spx_src_start_freq;
134cabdff1aSopenharmony_ci        for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
135cabdff1aSopenharmony_ci            float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f / INT32_MIN);
136cabdff1aSopenharmony_ci            float sscale = s->spx_signal_blend[ch][bnd];
137cabdff1aSopenharmony_ci#if USE_FIXED
138cabdff1aSopenharmony_ci            // spx_noise_blend and spx_signal_blend are both FP.23
139cabdff1aSopenharmony_ci            nscale *= 1.0 / (1<<23);
140cabdff1aSopenharmony_ci            sscale *= 1.0 / (1<<23);
141cabdff1aSopenharmony_ci            if (nscale < -1.0)
142cabdff1aSopenharmony_ci                nscale = -1.0;
143cabdff1aSopenharmony_ci#endif
144cabdff1aSopenharmony_ci            for (i = 0; i < s->spx_band_sizes[bnd]; i++) {
145cabdff1aSopenharmony_ci                UINTFLOAT noise = (INTFLOAT)(nscale * (int32_t)av_lfg_get(&s->dith_state));
146cabdff1aSopenharmony_ci                s->transform_coeffs[ch][bin]   *= sscale;
147cabdff1aSopenharmony_ci                s->transform_coeffs[ch][bin++] += noise;
148cabdff1aSopenharmony_ci            }
149cabdff1aSopenharmony_ci        }
150cabdff1aSopenharmony_ci    }
151cabdff1aSopenharmony_ci}
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci/** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */
155cabdff1aSopenharmony_ci#define COEFF_0 10273905LL
156cabdff1aSopenharmony_ci
157cabdff1aSopenharmony_ci/** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */
158cabdff1aSopenharmony_ci#define COEFF_1 11863283LL
159cabdff1aSopenharmony_ci
160cabdff1aSopenharmony_ci/** lrint(M_SQRT2*cos(5*M_PI/12)*(1<<23)) */
161cabdff1aSopenharmony_ci#define COEFF_2  3070444LL
162cabdff1aSopenharmony_ci
163cabdff1aSopenharmony_ci/**
164cabdff1aSopenharmony_ci * Calculate 6-point IDCT of the pre-mantissas.
165cabdff1aSopenharmony_ci * All calculations are 24-bit fixed-point.
166cabdff1aSopenharmony_ci */
167cabdff1aSopenharmony_cistatic void idct6(int pre_mant[6])
168cabdff1aSopenharmony_ci{
169cabdff1aSopenharmony_ci    int tmp;
170cabdff1aSopenharmony_ci    int even0, even1, even2, odd0, odd1, odd2;
171cabdff1aSopenharmony_ci
172cabdff1aSopenharmony_ci    odd1 = pre_mant[1] - pre_mant[3] - pre_mant[5];
173cabdff1aSopenharmony_ci
174cabdff1aSopenharmony_ci    even2 = ( pre_mant[2]                * COEFF_0) >> 23;
175cabdff1aSopenharmony_ci    tmp   = ( pre_mant[4]                * COEFF_1) >> 23;
176cabdff1aSopenharmony_ci    odd0  = ((pre_mant[1] + pre_mant[5]) * COEFF_2) >> 23;
177cabdff1aSopenharmony_ci
178cabdff1aSopenharmony_ci    even0 = pre_mant[0] + (tmp >> 1);
179cabdff1aSopenharmony_ci    even1 = pre_mant[0] - tmp;
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci    tmp = even0;
182cabdff1aSopenharmony_ci    even0 = tmp + even2;
183cabdff1aSopenharmony_ci    even2 = tmp - even2;
184cabdff1aSopenharmony_ci
185cabdff1aSopenharmony_ci    tmp = odd0;
186cabdff1aSopenharmony_ci    odd0 = tmp + pre_mant[1] + pre_mant[3];
187cabdff1aSopenharmony_ci    odd2 = tmp + pre_mant[5] - pre_mant[3];
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ci    pre_mant[0] = even0 + odd0;
190cabdff1aSopenharmony_ci    pre_mant[1] = even1 + odd1;
191cabdff1aSopenharmony_ci    pre_mant[2] = even2 + odd2;
192cabdff1aSopenharmony_ci    pre_mant[3] = even2 - odd2;
193cabdff1aSopenharmony_ci    pre_mant[4] = even1 - odd1;
194cabdff1aSopenharmony_ci    pre_mant[5] = even0 - odd0;
195cabdff1aSopenharmony_ci}
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_cistatic void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch)
198cabdff1aSopenharmony_ci{
199cabdff1aSopenharmony_ci    int bin, blk, gs;
200cabdff1aSopenharmony_ci    int end_bap, gaq_mode;
201cabdff1aSopenharmony_ci    GetBitContext *gbc = &s->gbc;
202cabdff1aSopenharmony_ci    int gaq_gain[AC3_MAX_COEFS];
203cabdff1aSopenharmony_ci
204cabdff1aSopenharmony_ci    gaq_mode = get_bits(gbc, 2);
205cabdff1aSopenharmony_ci    end_bap = (gaq_mode < 2) ? 12 : 17;
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci    /* if GAQ gain is used, decode gain codes for bins with hebap between
208cabdff1aSopenharmony_ci       8 and end_bap */
209cabdff1aSopenharmony_ci    gs = 0;
210cabdff1aSopenharmony_ci    if (gaq_mode == EAC3_GAQ_12 || gaq_mode == EAC3_GAQ_14) {
211cabdff1aSopenharmony_ci        /* read 1-bit GAQ gain codes */
212cabdff1aSopenharmony_ci        for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
213cabdff1aSopenharmony_ci            if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap)
214cabdff1aSopenharmony_ci                gaq_gain[gs++] = get_bits1(gbc) << (gaq_mode-1);
215cabdff1aSopenharmony_ci        }
216cabdff1aSopenharmony_ci    } else if (gaq_mode == EAC3_GAQ_124) {
217cabdff1aSopenharmony_ci        /* read 1.67-bit GAQ gain codes (3 codes in 5 bits) */
218cabdff1aSopenharmony_ci        int gc = 2;
219cabdff1aSopenharmony_ci        for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
220cabdff1aSopenharmony_ci            if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < 17) {
221cabdff1aSopenharmony_ci                if (gc++ == 2) {
222cabdff1aSopenharmony_ci                    int group_code = get_bits(gbc, 5);
223cabdff1aSopenharmony_ci                    if (group_code > 26) {
224cabdff1aSopenharmony_ci                        av_log(s->avctx, AV_LOG_WARNING, "GAQ gain group code out-of-range\n");
225cabdff1aSopenharmony_ci                        group_code = 26;
226cabdff1aSopenharmony_ci                    }
227cabdff1aSopenharmony_ci                    gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][0];
228cabdff1aSopenharmony_ci                    gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][1];
229cabdff1aSopenharmony_ci                    gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][2];
230cabdff1aSopenharmony_ci                    gc = 0;
231cabdff1aSopenharmony_ci                }
232cabdff1aSopenharmony_ci            }
233cabdff1aSopenharmony_ci        }
234cabdff1aSopenharmony_ci    }
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci    gs=0;
237cabdff1aSopenharmony_ci    for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
238cabdff1aSopenharmony_ci        int hebap = s->bap[ch][bin];
239cabdff1aSopenharmony_ci        int bits = ff_eac3_bits_vs_hebap[hebap];
240cabdff1aSopenharmony_ci        if (!hebap) {
241cabdff1aSopenharmony_ci            /* zero-mantissa dithering */
242cabdff1aSopenharmony_ci            for (blk = 0; blk < 6; blk++) {
243cabdff1aSopenharmony_ci                s->pre_mantissa[ch][bin][blk] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
244cabdff1aSopenharmony_ci            }
245cabdff1aSopenharmony_ci        } else if (hebap < 8) {
246cabdff1aSopenharmony_ci            /* Vector Quantization */
247cabdff1aSopenharmony_ci            int v = get_bits(gbc, bits);
248cabdff1aSopenharmony_ci            for (blk = 0; blk < 6; blk++) {
249cabdff1aSopenharmony_ci                s->pre_mantissa[ch][bin][blk] = ff_eac3_mantissa_vq[hebap][v][blk] * (1 << 8);
250cabdff1aSopenharmony_ci            }
251cabdff1aSopenharmony_ci        } else {
252cabdff1aSopenharmony_ci            /* Gain Adaptive Quantization */
253cabdff1aSopenharmony_ci            int gbits, log_gain;
254cabdff1aSopenharmony_ci            if (gaq_mode != EAC3_GAQ_NO && hebap < end_bap) {
255cabdff1aSopenharmony_ci                log_gain = gaq_gain[gs++];
256cabdff1aSopenharmony_ci            } else {
257cabdff1aSopenharmony_ci                log_gain = 0;
258cabdff1aSopenharmony_ci            }
259cabdff1aSopenharmony_ci            gbits = bits - log_gain;
260cabdff1aSopenharmony_ci
261cabdff1aSopenharmony_ci            for (blk = 0; blk < 6; blk++) {
262cabdff1aSopenharmony_ci                int mant = get_sbits(gbc, gbits);
263cabdff1aSopenharmony_ci                if (log_gain && mant == -(1 << (gbits-1))) {
264cabdff1aSopenharmony_ci                    /* large mantissa */
265cabdff1aSopenharmony_ci                    int b;
266cabdff1aSopenharmony_ci                    int mbits = bits - (2 - log_gain);
267cabdff1aSopenharmony_ci                    mant = get_sbits(gbc, mbits);
268cabdff1aSopenharmony_ci                    mant = ((unsigned)mant) << (23 - (mbits - 1));
269cabdff1aSopenharmony_ci                    /* remap mantissa value to correct for asymmetric quantization */
270cabdff1aSopenharmony_ci                    if (mant >= 0)
271cabdff1aSopenharmony_ci                        b = 1 << (23 - log_gain);
272cabdff1aSopenharmony_ci                    else
273cabdff1aSopenharmony_ci                        b = ff_eac3_gaq_remap_2_4_b[hebap-8][log_gain-1] * (1 << 8);
274cabdff1aSopenharmony_ci                    mant += ((ff_eac3_gaq_remap_2_4_a[hebap-8][log_gain-1] * (int64_t)mant) >> 15) + b;
275cabdff1aSopenharmony_ci                } else {
276cabdff1aSopenharmony_ci                    /* small mantissa, no GAQ, or Gk=1 */
277cabdff1aSopenharmony_ci                    mant *= (1 << 24 - bits);
278cabdff1aSopenharmony_ci                    if (!log_gain) {
279cabdff1aSopenharmony_ci                        /* remap mantissa value for no GAQ or Gk=1 */
280cabdff1aSopenharmony_ci                        mant += (ff_eac3_gaq_remap_1[hebap-8] * (int64_t)mant) >> 15;
281cabdff1aSopenharmony_ci                    }
282cabdff1aSopenharmony_ci                }
283cabdff1aSopenharmony_ci                s->pre_mantissa[ch][bin][blk] = mant;
284cabdff1aSopenharmony_ci            }
285cabdff1aSopenharmony_ci        }
286cabdff1aSopenharmony_ci        idct6(s->pre_mantissa[ch][bin]);
287cabdff1aSopenharmony_ci    }
288cabdff1aSopenharmony_ci}
289cabdff1aSopenharmony_ci
290cabdff1aSopenharmony_cistatic int ff_eac3_parse_header(AC3DecodeContext *s)
291cabdff1aSopenharmony_ci{
292cabdff1aSopenharmony_ci    int i, blk, ch;
293cabdff1aSopenharmony_ci    int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data;
294cabdff1aSopenharmony_ci    int parse_transient_proc_info;
295cabdff1aSopenharmony_ci    int num_cpl_blocks;
296cabdff1aSopenharmony_ci    GetBitContext *gbc = &s->gbc;
297cabdff1aSopenharmony_ci
298cabdff1aSopenharmony_ci    /* An E-AC-3 stream can have multiple independent streams which the
299cabdff1aSopenharmony_ci       application can select from. each independent stream can also contain
300cabdff1aSopenharmony_ci       dependent streams which are used to add or replace channels. */
301cabdff1aSopenharmony_ci    if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) {
302cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n");
303cabdff1aSopenharmony_ci        return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
304cabdff1aSopenharmony_ci    }
305cabdff1aSopenharmony_ci
306cabdff1aSopenharmony_ci    /* The substream id indicates which substream this frame belongs to. each
307cabdff1aSopenharmony_ci       independent stream has its own substream id, and the dependent streams
308cabdff1aSopenharmony_ci       associated to an independent stream have matching substream id's. */
309cabdff1aSopenharmony_ci    if (s->substreamid) {
310cabdff1aSopenharmony_ci        /* only decode substream with id=0. skip any additional substreams. */
311cabdff1aSopenharmony_ci        if (!s->eac3_subsbtreamid_found) {
312cabdff1aSopenharmony_ci            s->eac3_subsbtreamid_found = 1;
313cabdff1aSopenharmony_ci            avpriv_request_sample(s->avctx, "Additional substreams");
314cabdff1aSopenharmony_ci        }
315cabdff1aSopenharmony_ci        return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
316cabdff1aSopenharmony_ci    }
317cabdff1aSopenharmony_ci
318cabdff1aSopenharmony_ci    if (s->bit_alloc_params.sr_code == EAC3_SR_CODE_REDUCED) {
319cabdff1aSopenharmony_ci        /* The E-AC-3 specification does not tell how to handle reduced sample
320cabdff1aSopenharmony_ci           rates in bit allocation.  The best assumption would be that it is
321cabdff1aSopenharmony_ci           handled like AC-3 DolbyNet, but we cannot be sure until we have a
322cabdff1aSopenharmony_ci           sample which utilizes this feature. */
323cabdff1aSopenharmony_ci        avpriv_request_sample(s->avctx, "Reduced sampling rate");
324cabdff1aSopenharmony_ci        return AVERROR_PATCHWELCOME;
325cabdff1aSopenharmony_ci    }
326cabdff1aSopenharmony_ci    skip_bits(gbc, 5); // skip bitstream id
327cabdff1aSopenharmony_ci
328cabdff1aSopenharmony_ci    /* volume control params */
329cabdff1aSopenharmony_ci    for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
330cabdff1aSopenharmony_ci        s->dialog_normalization[i] = -get_bits(gbc, 5);
331cabdff1aSopenharmony_ci        if (s->dialog_normalization[i] == 0) {
332cabdff1aSopenharmony_ci            s->dialog_normalization[i] = -31;
333cabdff1aSopenharmony_ci        }
334cabdff1aSopenharmony_ci        if (s->target_level != 0) {
335cabdff1aSopenharmony_ci            s->level_gain[i] = powf(2.0f,
336cabdff1aSopenharmony_ci                (float)(s->target_level - s->dialog_normalization[i])/6.0f);
337cabdff1aSopenharmony_ci        }
338cabdff1aSopenharmony_ci        s->compression_exists[i] = get_bits1(gbc);
339cabdff1aSopenharmony_ci        if (s->compression_exists[i]) {
340cabdff1aSopenharmony_ci            s->heavy_dynamic_range[i] = AC3_HEAVY_RANGE(get_bits(gbc, 8));
341cabdff1aSopenharmony_ci        }
342cabdff1aSopenharmony_ci    }
343cabdff1aSopenharmony_ci
344cabdff1aSopenharmony_ci    /* dependent stream channel map */
345cabdff1aSopenharmony_ci    if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
346cabdff1aSopenharmony_ci        if (get_bits1(gbc)) {
347cabdff1aSopenharmony_ci            int64_t channel_layout = 0;
348cabdff1aSopenharmony_ci            int channel_map = get_bits(gbc, 16);
349cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_DEBUG, "channel_map: %0X\n", channel_map);
350cabdff1aSopenharmony_ci
351cabdff1aSopenharmony_ci            for (i = 0; i < 16; i++)
352cabdff1aSopenharmony_ci                if (channel_map & (1 << (EAC3_MAX_CHANNELS - i - 1)))
353cabdff1aSopenharmony_ci                    channel_layout |= ff_eac3_custom_channel_map_locations[i][1];
354cabdff1aSopenharmony_ci
355cabdff1aSopenharmony_ci            if (av_popcount64(channel_layout) > EAC3_MAX_CHANNELS) {
356cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
357cabdff1aSopenharmony_ci            }
358cabdff1aSopenharmony_ci            s->channel_map = channel_map;
359cabdff1aSopenharmony_ci        }
360cabdff1aSopenharmony_ci    }
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ci    /* mixing metadata */
363cabdff1aSopenharmony_ci    if (get_bits1(gbc)) {
364cabdff1aSopenharmony_ci        /* center and surround mix levels */
365cabdff1aSopenharmony_ci        if (s->channel_mode > AC3_CHMODE_STEREO) {
366cabdff1aSopenharmony_ci            s->preferred_downmix = get_bits(gbc, 2);
367cabdff1aSopenharmony_ci            if (s->channel_mode & 1) {
368cabdff1aSopenharmony_ci                /* if three front channels exist */
369cabdff1aSopenharmony_ci                s->center_mix_level_ltrt = get_bits(gbc, 3);
370cabdff1aSopenharmony_ci                s->center_mix_level      = get_bits(gbc, 3);
371cabdff1aSopenharmony_ci            }
372cabdff1aSopenharmony_ci            if (s->channel_mode & 4) {
373cabdff1aSopenharmony_ci                /* if a surround channel exists */
374cabdff1aSopenharmony_ci                s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7);
375cabdff1aSopenharmony_ci                s->surround_mix_level      = av_clip(get_bits(gbc, 3), 3, 7);
376cabdff1aSopenharmony_ci            }
377cabdff1aSopenharmony_ci        }
378cabdff1aSopenharmony_ci
379cabdff1aSopenharmony_ci        /* lfe mix level */
380cabdff1aSopenharmony_ci        if (s->lfe_on && (s->lfe_mix_level_exists = get_bits1(gbc))) {
381cabdff1aSopenharmony_ci            s->lfe_mix_level = get_bits(gbc, 5);
382cabdff1aSopenharmony_ci        }
383cabdff1aSopenharmony_ci
384cabdff1aSopenharmony_ci        /* info for mixing with other streams and substreams */
385cabdff1aSopenharmony_ci        if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) {
386cabdff1aSopenharmony_ci            for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
387cabdff1aSopenharmony_ci                // TODO: apply program scale factor
388cabdff1aSopenharmony_ci                if (get_bits1(gbc)) {
389cabdff1aSopenharmony_ci                    skip_bits(gbc, 6);  // skip program scale factor
390cabdff1aSopenharmony_ci                }
391cabdff1aSopenharmony_ci            }
392cabdff1aSopenharmony_ci            if (get_bits1(gbc)) {
393cabdff1aSopenharmony_ci                skip_bits(gbc, 6);  // skip external program scale factor
394cabdff1aSopenharmony_ci            }
395cabdff1aSopenharmony_ci            /* skip mixing parameter data */
396cabdff1aSopenharmony_ci            switch(get_bits(gbc, 2)) {
397cabdff1aSopenharmony_ci                case 1: skip_bits(gbc, 5);  break;
398cabdff1aSopenharmony_ci                case 2: skip_bits(gbc, 12); break;
399cabdff1aSopenharmony_ci                case 3: {
400cabdff1aSopenharmony_ci                    int mix_data_size = (get_bits(gbc, 5) + 2) << 3;
401cabdff1aSopenharmony_ci                    skip_bits_long(gbc, mix_data_size);
402cabdff1aSopenharmony_ci                    break;
403cabdff1aSopenharmony_ci                }
404cabdff1aSopenharmony_ci            }
405cabdff1aSopenharmony_ci            /* skip pan information for mono or dual mono source */
406cabdff1aSopenharmony_ci            if (s->channel_mode < AC3_CHMODE_STEREO) {
407cabdff1aSopenharmony_ci                for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
408cabdff1aSopenharmony_ci                    if (get_bits1(gbc)) {
409cabdff1aSopenharmony_ci                        /* note: this is not in the ATSC A/52B specification
410cabdff1aSopenharmony_ci                           reference: ETSI TS 102 366 V1.1.1
411cabdff1aSopenharmony_ci                                      section: E.1.3.1.25 */
412cabdff1aSopenharmony_ci                        skip_bits(gbc, 8);  // skip pan mean direction index
413cabdff1aSopenharmony_ci                        skip_bits(gbc, 6);  // skip reserved paninfo bits
414cabdff1aSopenharmony_ci                    }
415cabdff1aSopenharmony_ci                }
416cabdff1aSopenharmony_ci            }
417cabdff1aSopenharmony_ci            /* skip mixing configuration information */
418cabdff1aSopenharmony_ci            if (get_bits1(gbc)) {
419cabdff1aSopenharmony_ci                for (blk = 0; blk < s->num_blocks; blk++) {
420cabdff1aSopenharmony_ci                    if (s->num_blocks == 1 || get_bits1(gbc)) {
421cabdff1aSopenharmony_ci                        skip_bits(gbc, 5);
422cabdff1aSopenharmony_ci                    }
423cabdff1aSopenharmony_ci                }
424cabdff1aSopenharmony_ci            }
425cabdff1aSopenharmony_ci        }
426cabdff1aSopenharmony_ci    }
427cabdff1aSopenharmony_ci
428cabdff1aSopenharmony_ci    /* informational metadata */
429cabdff1aSopenharmony_ci    if (get_bits1(gbc)) {
430cabdff1aSopenharmony_ci        s->bitstream_mode = get_bits(gbc, 3);
431cabdff1aSopenharmony_ci        skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
432cabdff1aSopenharmony_ci        if (s->channel_mode == AC3_CHMODE_STEREO) {
433cabdff1aSopenharmony_ci            s->dolby_surround_mode  = get_bits(gbc, 2);
434cabdff1aSopenharmony_ci            s->dolby_headphone_mode = get_bits(gbc, 2);
435cabdff1aSopenharmony_ci        }
436cabdff1aSopenharmony_ci        if (s->channel_mode >= AC3_CHMODE_2F2R) {
437cabdff1aSopenharmony_ci            s->dolby_surround_ex_mode = get_bits(gbc, 2);
438cabdff1aSopenharmony_ci        }
439cabdff1aSopenharmony_ci        for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
440cabdff1aSopenharmony_ci            if (get_bits1(gbc)) {
441cabdff1aSopenharmony_ci                skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type
442cabdff1aSopenharmony_ci            }
443cabdff1aSopenharmony_ci        }
444cabdff1aSopenharmony_ci        if (s->bit_alloc_params.sr_code != EAC3_SR_CODE_REDUCED) {
445cabdff1aSopenharmony_ci            skip_bits1(gbc); // skip source sample rate code
446cabdff1aSopenharmony_ci        }
447cabdff1aSopenharmony_ci    }
448cabdff1aSopenharmony_ci
449cabdff1aSopenharmony_ci    /* converter synchronization flag
450cabdff1aSopenharmony_ci       If frames are less than six blocks, this bit should be turned on
451cabdff1aSopenharmony_ci       once every 6 blocks to indicate the start of a frame set.
452cabdff1aSopenharmony_ci       reference: RFC 4598, Section 2.1.3  Frame Sets */
453cabdff1aSopenharmony_ci    if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && s->num_blocks != 6) {
454cabdff1aSopenharmony_ci        skip_bits1(gbc); // skip converter synchronization flag
455cabdff1aSopenharmony_ci    }
456cabdff1aSopenharmony_ci
457cabdff1aSopenharmony_ci    /* original frame size code if this stream was converted from AC-3 */
458cabdff1aSopenharmony_ci    if (s->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT &&
459cabdff1aSopenharmony_ci            (s->num_blocks == 6 || get_bits1(gbc))) {
460cabdff1aSopenharmony_ci        skip_bits(gbc, 6); // skip frame size code
461cabdff1aSopenharmony_ci    }
462cabdff1aSopenharmony_ci
463cabdff1aSopenharmony_ci    /* additional bitstream info */
464cabdff1aSopenharmony_ci    if (get_bits1(gbc)) {
465cabdff1aSopenharmony_ci        int addbsil = get_bits(gbc, 6);
466cabdff1aSopenharmony_ci        for (i = 0; i < addbsil + 1; i++) {
467cabdff1aSopenharmony_ci            skip_bits(gbc, 8); // skip additional bit stream info
468cabdff1aSopenharmony_ci        }
469cabdff1aSopenharmony_ci    }
470cabdff1aSopenharmony_ci
471cabdff1aSopenharmony_ci    /* audio frame syntax flags, strategy data, and per-frame data */
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_ci    if (s->num_blocks == 6) {
474cabdff1aSopenharmony_ci        ac3_exponent_strategy = get_bits1(gbc);
475cabdff1aSopenharmony_ci        parse_aht_info        = get_bits1(gbc);
476cabdff1aSopenharmony_ci    } else {
477cabdff1aSopenharmony_ci        /* less than 6 blocks, so use AC-3-style exponent strategy syntax, and
478cabdff1aSopenharmony_ci           do not use AHT */
479cabdff1aSopenharmony_ci        ac3_exponent_strategy = 1;
480cabdff1aSopenharmony_ci        parse_aht_info = 0;
481cabdff1aSopenharmony_ci    }
482cabdff1aSopenharmony_ci
483cabdff1aSopenharmony_ci    s->snr_offset_strategy    = get_bits(gbc, 2);
484cabdff1aSopenharmony_ci    parse_transient_proc_info = get_bits1(gbc);
485cabdff1aSopenharmony_ci
486cabdff1aSopenharmony_ci    s->block_switch_syntax = get_bits1(gbc);
487cabdff1aSopenharmony_ci    if (!s->block_switch_syntax)
488cabdff1aSopenharmony_ci        memset(s->block_switch, 0, sizeof(s->block_switch));
489cabdff1aSopenharmony_ci
490cabdff1aSopenharmony_ci    s->dither_flag_syntax = get_bits1(gbc);
491cabdff1aSopenharmony_ci    if (!s->dither_flag_syntax) {
492cabdff1aSopenharmony_ci        for (ch = 1; ch <= s->fbw_channels; ch++)
493cabdff1aSopenharmony_ci            s->dither_flag[ch] = 1;
494cabdff1aSopenharmony_ci    }
495cabdff1aSopenharmony_ci    s->dither_flag[CPL_CH] = s->dither_flag[s->lfe_ch] = 0;
496cabdff1aSopenharmony_ci
497cabdff1aSopenharmony_ci    s->bit_allocation_syntax = get_bits1(gbc);
498cabdff1aSopenharmony_ci    if (!s->bit_allocation_syntax) {
499cabdff1aSopenharmony_ci        /* set default bit allocation parameters */
500cabdff1aSopenharmony_ci        s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[2];
501cabdff1aSopenharmony_ci        s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[1];
502cabdff1aSopenharmony_ci        s->bit_alloc_params.slow_gain  = ff_ac3_slow_gain_tab [1];
503cabdff1aSopenharmony_ci        s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[2];
504cabdff1aSopenharmony_ci        s->bit_alloc_params.floor      = ff_ac3_floor_tab     [7];
505cabdff1aSopenharmony_ci    }
506cabdff1aSopenharmony_ci
507cabdff1aSopenharmony_ci    s->fast_gain_syntax  = get_bits1(gbc);
508cabdff1aSopenharmony_ci    s->dba_syntax        = get_bits1(gbc);
509cabdff1aSopenharmony_ci    s->skip_syntax       = get_bits1(gbc);
510cabdff1aSopenharmony_ci    parse_spx_atten_data = get_bits1(gbc);
511cabdff1aSopenharmony_ci
512cabdff1aSopenharmony_ci    /* coupling strategy occurrence and coupling use per block */
513cabdff1aSopenharmony_ci    num_cpl_blocks = 0;
514cabdff1aSopenharmony_ci    if (s->channel_mode > 1) {
515cabdff1aSopenharmony_ci        for (blk = 0; blk < s->num_blocks; blk++) {
516cabdff1aSopenharmony_ci            s->cpl_strategy_exists[blk] = (!blk || get_bits1(gbc));
517cabdff1aSopenharmony_ci            if (s->cpl_strategy_exists[blk]) {
518cabdff1aSopenharmony_ci                s->cpl_in_use[blk] = get_bits1(gbc);
519cabdff1aSopenharmony_ci            } else {
520cabdff1aSopenharmony_ci                s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
521cabdff1aSopenharmony_ci            }
522cabdff1aSopenharmony_ci            num_cpl_blocks += s->cpl_in_use[blk];
523cabdff1aSopenharmony_ci        }
524cabdff1aSopenharmony_ci    } else {
525cabdff1aSopenharmony_ci        memset(s->cpl_in_use, 0, sizeof(s->cpl_in_use));
526cabdff1aSopenharmony_ci    }
527cabdff1aSopenharmony_ci
528cabdff1aSopenharmony_ci    /* exponent strategy data */
529cabdff1aSopenharmony_ci    if (ac3_exponent_strategy) {
530cabdff1aSopenharmony_ci        /* AC-3-style exponent strategy syntax */
531cabdff1aSopenharmony_ci        for (blk = 0; blk < s->num_blocks; blk++) {
532cabdff1aSopenharmony_ci            for (ch = !s->cpl_in_use[blk]; ch <= s->fbw_channels; ch++) {
533cabdff1aSopenharmony_ci                s->exp_strategy[blk][ch] = get_bits(gbc, 2);
534cabdff1aSopenharmony_ci            }
535cabdff1aSopenharmony_ci        }
536cabdff1aSopenharmony_ci    } else {
537cabdff1aSopenharmony_ci        /* LUT-based exponent strategy syntax */
538cabdff1aSopenharmony_ci        for (ch = !((s->channel_mode > 1) && num_cpl_blocks); ch <= s->fbw_channels; ch++) {
539cabdff1aSopenharmony_ci            int frmchexpstr = get_bits(gbc, 5);
540cabdff1aSopenharmony_ci            for (blk = 0; blk < 6; blk++) {
541cabdff1aSopenharmony_ci                s->exp_strategy[blk][ch] = ff_eac3_frm_expstr[frmchexpstr][blk];
542cabdff1aSopenharmony_ci            }
543cabdff1aSopenharmony_ci        }
544cabdff1aSopenharmony_ci    }
545cabdff1aSopenharmony_ci    /* LFE exponent strategy */
546cabdff1aSopenharmony_ci    if (s->lfe_on) {
547cabdff1aSopenharmony_ci        for (blk = 0; blk < s->num_blocks; blk++) {
548cabdff1aSopenharmony_ci            s->exp_strategy[blk][s->lfe_ch] = get_bits1(gbc);
549cabdff1aSopenharmony_ci        }
550cabdff1aSopenharmony_ci    }
551cabdff1aSopenharmony_ci    /* original exponent strategies if this stream was converted from AC-3 */
552cabdff1aSopenharmony_ci    if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT &&
553cabdff1aSopenharmony_ci            (s->num_blocks == 6 || get_bits1(gbc))) {
554cabdff1aSopenharmony_ci        skip_bits(gbc, 5 * s->fbw_channels); // skip converter channel exponent strategy
555cabdff1aSopenharmony_ci    }
556cabdff1aSopenharmony_ci
557cabdff1aSopenharmony_ci    /* determine which channels use AHT */
558cabdff1aSopenharmony_ci    if (parse_aht_info) {
559cabdff1aSopenharmony_ci        /* For AHT to be used, all non-zero blocks must reuse exponents from
560cabdff1aSopenharmony_ci           the first block.  Furthermore, for AHT to be used in the coupling
561cabdff1aSopenharmony_ci           channel, all blocks must use coupling and use the same coupling
562cabdff1aSopenharmony_ci           strategy. */
563cabdff1aSopenharmony_ci        s->channel_uses_aht[CPL_CH]=0;
564cabdff1aSopenharmony_ci        for (ch = (num_cpl_blocks != 6); ch <= s->channels; ch++) {
565cabdff1aSopenharmony_ci            int use_aht = 1;
566cabdff1aSopenharmony_ci            for (blk = 1; blk < 6; blk++) {
567cabdff1aSopenharmony_ci                if ((s->exp_strategy[blk][ch] != EXP_REUSE) ||
568cabdff1aSopenharmony_ci                        (!ch && s->cpl_strategy_exists[blk])) {
569cabdff1aSopenharmony_ci                    use_aht = 0;
570cabdff1aSopenharmony_ci                    break;
571cabdff1aSopenharmony_ci                }
572cabdff1aSopenharmony_ci            }
573cabdff1aSopenharmony_ci            s->channel_uses_aht[ch] = use_aht && get_bits1(gbc);
574cabdff1aSopenharmony_ci        }
575cabdff1aSopenharmony_ci    } else {
576cabdff1aSopenharmony_ci        memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht));
577cabdff1aSopenharmony_ci    }
578cabdff1aSopenharmony_ci
579cabdff1aSopenharmony_ci    /* per-frame SNR offset */
580cabdff1aSopenharmony_ci    if (!s->snr_offset_strategy) {
581cabdff1aSopenharmony_ci        int csnroffst = (get_bits(gbc, 6) - 15) << 4;
582cabdff1aSopenharmony_ci        int snroffst = (csnroffst + get_bits(gbc, 4)) << 2;
583cabdff1aSopenharmony_ci        for (ch = 0; ch <= s->channels; ch++)
584cabdff1aSopenharmony_ci            s->snr_offset[ch] = snroffst;
585cabdff1aSopenharmony_ci    }
586cabdff1aSopenharmony_ci
587cabdff1aSopenharmony_ci    /* transient pre-noise processing data */
588cabdff1aSopenharmony_ci    if (parse_transient_proc_info) {
589cabdff1aSopenharmony_ci        for (ch = 1; ch <= s->fbw_channels; ch++) {
590cabdff1aSopenharmony_ci            if (get_bits1(gbc)) { // channel in transient processing
591cabdff1aSopenharmony_ci                skip_bits(gbc, 10); // skip transient processing location
592cabdff1aSopenharmony_ci                skip_bits(gbc, 8);  // skip transient processing length
593cabdff1aSopenharmony_ci            }
594cabdff1aSopenharmony_ci        }
595cabdff1aSopenharmony_ci    }
596cabdff1aSopenharmony_ci
597cabdff1aSopenharmony_ci    /* spectral extension attenuation data */
598cabdff1aSopenharmony_ci    for (ch = 1; ch <= s->fbw_channels; ch++) {
599cabdff1aSopenharmony_ci        if (parse_spx_atten_data && get_bits1(gbc)) {
600cabdff1aSopenharmony_ci            s->spx_atten_code[ch] = get_bits(gbc, 5);
601cabdff1aSopenharmony_ci        } else {
602cabdff1aSopenharmony_ci            s->spx_atten_code[ch] = -1;
603cabdff1aSopenharmony_ci        }
604cabdff1aSopenharmony_ci    }
605cabdff1aSopenharmony_ci
606cabdff1aSopenharmony_ci    /* block start information */
607cabdff1aSopenharmony_ci    if (s->num_blocks > 1 && get_bits1(gbc)) {
608cabdff1aSopenharmony_ci        /* reference: Section E2.3.2.27
609cabdff1aSopenharmony_ci           nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame)))
610cabdff1aSopenharmony_ci           The spec does not say what this data is or what it's used for.
611cabdff1aSopenharmony_ci           It is likely the offset of each block within the frame. */
612cabdff1aSopenharmony_ci        int block_start_bits = (s->num_blocks-1) * (4 + av_log2(s->frame_size-2));
613cabdff1aSopenharmony_ci        skip_bits_long(gbc, block_start_bits);
614cabdff1aSopenharmony_ci        avpriv_request_sample(s->avctx, "Block start info");
615cabdff1aSopenharmony_ci    }
616cabdff1aSopenharmony_ci
617cabdff1aSopenharmony_ci    /* syntax state initialization */
618cabdff1aSopenharmony_ci    for (ch = 1; ch <= s->fbw_channels; ch++) {
619cabdff1aSopenharmony_ci        s->first_spx_coords[ch] = 1;
620cabdff1aSopenharmony_ci        s->first_cpl_coords[ch] = 1;
621cabdff1aSopenharmony_ci    }
622cabdff1aSopenharmony_ci    s->first_cpl_leak = 1;
623cabdff1aSopenharmony_ci
624cabdff1aSopenharmony_ci    return 0;
625cabdff1aSopenharmony_ci}
626