xref: /third_party/ffmpeg/libavcodec/cook.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * COOK compatible decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2003 Sascha Sommer
4cabdff1aSopenharmony_ci * Copyright (c) 2005 Benjamin Larsson
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 * @file
25cabdff1aSopenharmony_ci * Cook compatible decoder. Bastardization of the G.722.1 standard.
26cabdff1aSopenharmony_ci * This decoder handles RealNetworks, RealAudio G2 data.
27cabdff1aSopenharmony_ci * Cook is identified by the codec name cook in RM files.
28cabdff1aSopenharmony_ci *
29cabdff1aSopenharmony_ci * To use this decoder, a calling application must supply the extradata
30cabdff1aSopenharmony_ci * bytes provided from the RM container; 8+ bytes for mono streams and
31cabdff1aSopenharmony_ci * 16+ for stereo streams (maybe more).
32cabdff1aSopenharmony_ci *
33cabdff1aSopenharmony_ci * Codec technicalities (all this assume a buffer length of 1024):
34cabdff1aSopenharmony_ci * Cook works with several different techniques to achieve its compression.
35cabdff1aSopenharmony_ci * In the timedomain the buffer is divided into 8 pieces and quantized. If
36cabdff1aSopenharmony_ci * two neighboring pieces have different quantization index a smooth
37cabdff1aSopenharmony_ci * quantization curve is used to get a smooth overlap between the different
38cabdff1aSopenharmony_ci * pieces.
39cabdff1aSopenharmony_ci * To get to the transformdomain Cook uses a modulated lapped transform.
40cabdff1aSopenharmony_ci * The transform domain has 50 subbands with 20 elements each. This
41cabdff1aSopenharmony_ci * means only a maximum of 50*20=1000 coefficients are used out of the 1024
42cabdff1aSopenharmony_ci * available.
43cabdff1aSopenharmony_ci */
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
46cabdff1aSopenharmony_ci#include "libavutil/lfg.h"
47cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h"
48cabdff1aSopenharmony_ci#include "libavutil/thread.h"
49cabdff1aSopenharmony_ci
50cabdff1aSopenharmony_ci#include "audiodsp.h"
51cabdff1aSopenharmony_ci#include "avcodec.h"
52cabdff1aSopenharmony_ci#include "get_bits.h"
53cabdff1aSopenharmony_ci#include "bytestream.h"
54cabdff1aSopenharmony_ci#include "codec_internal.h"
55cabdff1aSopenharmony_ci#include "fft.h"
56cabdff1aSopenharmony_ci#include "internal.h"
57cabdff1aSopenharmony_ci#include "sinewin.h"
58cabdff1aSopenharmony_ci#include "unary.h"
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci#include "cookdata.h"
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci/* the different Cook versions */
63cabdff1aSopenharmony_ci#define MONO            0x1000001
64cabdff1aSopenharmony_ci#define STEREO          0x1000002
65cabdff1aSopenharmony_ci#define JOINT_STEREO    0x1000003
66cabdff1aSopenharmony_ci#define MC_COOK         0x2000000
67cabdff1aSopenharmony_ci
68cabdff1aSopenharmony_ci#define SUBBAND_SIZE    20
69cabdff1aSopenharmony_ci#define MAX_SUBPACKETS   5
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_ci#define QUANT_VLC_BITS    9
72cabdff1aSopenharmony_ci#define COUPLING_VLC_BITS 6
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_citypedef struct cook_gains {
75cabdff1aSopenharmony_ci    int *now;
76cabdff1aSopenharmony_ci    int *previous;
77cabdff1aSopenharmony_ci} cook_gains;
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_citypedef struct COOKSubpacket {
80cabdff1aSopenharmony_ci    int                 ch_idx;
81cabdff1aSopenharmony_ci    int                 size;
82cabdff1aSopenharmony_ci    int                 num_channels;
83cabdff1aSopenharmony_ci    int                 cookversion;
84cabdff1aSopenharmony_ci    int                 subbands;
85cabdff1aSopenharmony_ci    int                 js_subband_start;
86cabdff1aSopenharmony_ci    int                 js_vlc_bits;
87cabdff1aSopenharmony_ci    int                 samples_per_channel;
88cabdff1aSopenharmony_ci    int                 log2_numvector_size;
89cabdff1aSopenharmony_ci    unsigned int        channel_mask;
90cabdff1aSopenharmony_ci    VLC                 channel_coupling;
91cabdff1aSopenharmony_ci    int                 joint_stereo;
92cabdff1aSopenharmony_ci    int                 bits_per_subpacket;
93cabdff1aSopenharmony_ci    int                 bits_per_subpdiv;
94cabdff1aSopenharmony_ci    int                 total_subbands;
95cabdff1aSopenharmony_ci    int                 numvector_size;       // 1 << log2_numvector_size;
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_ci    float               mono_previous_buffer1[1024];
98cabdff1aSopenharmony_ci    float               mono_previous_buffer2[1024];
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci    cook_gains          gains1;
101cabdff1aSopenharmony_ci    cook_gains          gains2;
102cabdff1aSopenharmony_ci    int                 gain_1[9];
103cabdff1aSopenharmony_ci    int                 gain_2[9];
104cabdff1aSopenharmony_ci    int                 gain_3[9];
105cabdff1aSopenharmony_ci    int                 gain_4[9];
106cabdff1aSopenharmony_ci} COOKSubpacket;
107cabdff1aSopenharmony_ci
108cabdff1aSopenharmony_citypedef struct cook {
109cabdff1aSopenharmony_ci    /*
110cabdff1aSopenharmony_ci     * The following 5 functions provide the lowlevel arithmetic on
111cabdff1aSopenharmony_ci     * the internal audio buffers.
112cabdff1aSopenharmony_ci     */
113cabdff1aSopenharmony_ci    void (*scalar_dequant)(struct cook *q, int index, int quant_index,
114cabdff1aSopenharmony_ci                           int *subband_coef_index, int *subband_coef_sign,
115cabdff1aSopenharmony_ci                           float *mlt_p);
116cabdff1aSopenharmony_ci
117cabdff1aSopenharmony_ci    void (*decouple)(struct cook *q,
118cabdff1aSopenharmony_ci                     COOKSubpacket *p,
119cabdff1aSopenharmony_ci                     int subband,
120cabdff1aSopenharmony_ci                     float f1, float f2,
121cabdff1aSopenharmony_ci                     float *decode_buffer,
122cabdff1aSopenharmony_ci                     float *mlt_buffer1, float *mlt_buffer2);
123cabdff1aSopenharmony_ci
124cabdff1aSopenharmony_ci    void (*imlt_window)(struct cook *q, float *buffer1,
125cabdff1aSopenharmony_ci                        cook_gains *gains_ptr, float *previous_buffer);
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_ci    void (*interpolate)(struct cook *q, float *buffer,
128cabdff1aSopenharmony_ci                        int gain_index, int gain_index_next);
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_ci    void (*saturate_output)(struct cook *q, float *out);
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    AVCodecContext*     avctx;
133cabdff1aSopenharmony_ci    AudioDSPContext     adsp;
134cabdff1aSopenharmony_ci    GetBitContext       gb;
135cabdff1aSopenharmony_ci    /* stream data */
136cabdff1aSopenharmony_ci    int                 num_vectors;
137cabdff1aSopenharmony_ci    int                 samples_per_channel;
138cabdff1aSopenharmony_ci    /* states */
139cabdff1aSopenharmony_ci    AVLFG               random_state;
140cabdff1aSopenharmony_ci    int                 discarded_packets;
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_ci    /* transform data */
143cabdff1aSopenharmony_ci    FFTContext          mdct_ctx;
144cabdff1aSopenharmony_ci    float*              mlt_window;
145cabdff1aSopenharmony_ci
146cabdff1aSopenharmony_ci    /* VLC data */
147cabdff1aSopenharmony_ci    VLC                 envelope_quant_index[13];
148cabdff1aSopenharmony_ci    VLC                 sqvh[7];          // scalar quantization
149cabdff1aSopenharmony_ci
150cabdff1aSopenharmony_ci    /* generate tables and related variables */
151cabdff1aSopenharmony_ci    int                 gain_size_factor;
152cabdff1aSopenharmony_ci    float               gain_table[31];
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci    /* data buffers */
155cabdff1aSopenharmony_ci
156cabdff1aSopenharmony_ci    uint8_t*            decoded_bytes_buffer;
157cabdff1aSopenharmony_ci    DECLARE_ALIGNED(32, float, mono_mdct_output)[2048];
158cabdff1aSopenharmony_ci    float               decode_buffer_1[1024];
159cabdff1aSopenharmony_ci    float               decode_buffer_2[1024];
160cabdff1aSopenharmony_ci    float               decode_buffer_0[1060]; /* static allocation for joint decode */
161cabdff1aSopenharmony_ci
162cabdff1aSopenharmony_ci    const float         *cplscales[5];
163cabdff1aSopenharmony_ci    int                 num_subpackets;
164cabdff1aSopenharmony_ci    COOKSubpacket       subpacket[MAX_SUBPACKETS];
165cabdff1aSopenharmony_ci} COOKContext;
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_cistatic float     pow2tab[127];
168cabdff1aSopenharmony_cistatic float rootpow2tab[127];
169cabdff1aSopenharmony_ci
170cabdff1aSopenharmony_ci/*************** init functions ***************/
171cabdff1aSopenharmony_ci
172cabdff1aSopenharmony_ci/* table generator */
173cabdff1aSopenharmony_cistatic av_cold void init_pow2table(void)
174cabdff1aSopenharmony_ci{
175cabdff1aSopenharmony_ci    /* fast way of computing 2^i and 2^(0.5*i) for -63 <= i < 64 */
176cabdff1aSopenharmony_ci    int i;
177cabdff1aSopenharmony_ci    static const float exp2_tab[2] = {1, M_SQRT2};
178cabdff1aSopenharmony_ci    float exp2_val = powf(2, -63);
179cabdff1aSopenharmony_ci    float root_val = powf(2, -32);
180cabdff1aSopenharmony_ci    for (i = -63; i < 64; i++) {
181cabdff1aSopenharmony_ci        if (!(i & 1))
182cabdff1aSopenharmony_ci            root_val *= 2;
183cabdff1aSopenharmony_ci        pow2tab[63 + i] = exp2_val;
184cabdff1aSopenharmony_ci        rootpow2tab[63 + i] = root_val * exp2_tab[i & 1];
185cabdff1aSopenharmony_ci        exp2_val *= 2;
186cabdff1aSopenharmony_ci    }
187cabdff1aSopenharmony_ci}
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ci/* table generator */
190cabdff1aSopenharmony_cistatic av_cold void init_gain_table(COOKContext *q)
191cabdff1aSopenharmony_ci{
192cabdff1aSopenharmony_ci    int i;
193cabdff1aSopenharmony_ci    q->gain_size_factor = q->samples_per_channel / 8;
194cabdff1aSopenharmony_ci    for (i = 0; i < 31; i++)
195cabdff1aSopenharmony_ci        q->gain_table[i] = pow(pow2tab[i + 48],
196cabdff1aSopenharmony_ci                               (1.0 / (double) q->gain_size_factor));
197cabdff1aSopenharmony_ci}
198cabdff1aSopenharmony_ci
199cabdff1aSopenharmony_cistatic av_cold int build_vlc(VLC *vlc, int nb_bits, const uint8_t counts[16],
200cabdff1aSopenharmony_ci                             const void *syms, int symbol_size, int offset,
201cabdff1aSopenharmony_ci                             void *logctx)
202cabdff1aSopenharmony_ci{
203cabdff1aSopenharmony_ci    uint8_t lens[MAX_COOK_VLC_ENTRIES];
204cabdff1aSopenharmony_ci    unsigned num = 0;
205cabdff1aSopenharmony_ci
206cabdff1aSopenharmony_ci    for (int i = 0; i < 16; i++)
207cabdff1aSopenharmony_ci        for (unsigned count = num + counts[i]; num < count; num++)
208cabdff1aSopenharmony_ci            lens[num] = i + 1;
209cabdff1aSopenharmony_ci
210cabdff1aSopenharmony_ci    return ff_init_vlc_from_lengths(vlc, nb_bits, num, lens, 1,
211cabdff1aSopenharmony_ci                                    syms, symbol_size, symbol_size,
212cabdff1aSopenharmony_ci                                    offset, 0, logctx);
213cabdff1aSopenharmony_ci}
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_cistatic av_cold int init_cook_vlc_tables(COOKContext *q)
216cabdff1aSopenharmony_ci{
217cabdff1aSopenharmony_ci    int i, result;
218cabdff1aSopenharmony_ci
219cabdff1aSopenharmony_ci    result = 0;
220cabdff1aSopenharmony_ci    for (i = 0; i < 13; i++) {
221cabdff1aSopenharmony_ci        result |= build_vlc(&q->envelope_quant_index[i], QUANT_VLC_BITS,
222cabdff1aSopenharmony_ci                            envelope_quant_index_huffcounts[i],
223cabdff1aSopenharmony_ci                            envelope_quant_index_huffsyms[i], 1, -12, q->avctx);
224cabdff1aSopenharmony_ci    }
225cabdff1aSopenharmony_ci    av_log(q->avctx, AV_LOG_DEBUG, "sqvh VLC init\n");
226cabdff1aSopenharmony_ci    for (i = 0; i < 7; i++) {
227cabdff1aSopenharmony_ci        int sym_size = 1 + (i == 3);
228cabdff1aSopenharmony_ci        result |= build_vlc(&q->sqvh[i], vhvlcsize_tab[i],
229cabdff1aSopenharmony_ci                            cvh_huffcounts[i],
230cabdff1aSopenharmony_ci                            cvh_huffsyms[i], sym_size, 0, q->avctx);
231cabdff1aSopenharmony_ci    }
232cabdff1aSopenharmony_ci
233cabdff1aSopenharmony_ci    for (i = 0; i < q->num_subpackets; i++) {
234cabdff1aSopenharmony_ci        if (q->subpacket[i].joint_stereo == 1) {
235cabdff1aSopenharmony_ci            result |= build_vlc(&q->subpacket[i].channel_coupling, COUPLING_VLC_BITS,
236cabdff1aSopenharmony_ci                                ccpl_huffcounts[q->subpacket[i].js_vlc_bits - 2],
237cabdff1aSopenharmony_ci                                ccpl_huffsyms[q->subpacket[i].js_vlc_bits - 2], 1,
238cabdff1aSopenharmony_ci                                0, q->avctx);
239cabdff1aSopenharmony_ci            av_log(q->avctx, AV_LOG_DEBUG, "subpacket %i Joint-stereo VLC used.\n", i);
240cabdff1aSopenharmony_ci        }
241cabdff1aSopenharmony_ci    }
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci    av_log(q->avctx, AV_LOG_DEBUG, "VLC tables initialized.\n");
244cabdff1aSopenharmony_ci    return result;
245cabdff1aSopenharmony_ci}
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_cistatic av_cold int init_cook_mlt(COOKContext *q)
248cabdff1aSopenharmony_ci{
249cabdff1aSopenharmony_ci    int j, ret;
250cabdff1aSopenharmony_ci    int mlt_size = q->samples_per_channel;
251cabdff1aSopenharmony_ci
252cabdff1aSopenharmony_ci    if (!(q->mlt_window = av_malloc_array(mlt_size, sizeof(*q->mlt_window))))
253cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
254cabdff1aSopenharmony_ci
255cabdff1aSopenharmony_ci    /* Initialize the MLT window: simple sine window. */
256cabdff1aSopenharmony_ci    ff_sine_window_init(q->mlt_window, mlt_size);
257cabdff1aSopenharmony_ci    for (j = 0; j < mlt_size; j++)
258cabdff1aSopenharmony_ci        q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel);
259cabdff1aSopenharmony_ci
260cabdff1aSopenharmony_ci    /* Initialize the MDCT. */
261cabdff1aSopenharmony_ci    ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size) + 1, 1, 1.0 / 32768.0);
262cabdff1aSopenharmony_ci    if (ret < 0)
263cabdff1aSopenharmony_ci        return ret;
264cabdff1aSopenharmony_ci    av_log(q->avctx, AV_LOG_DEBUG, "MDCT initialized, order = %d.\n",
265cabdff1aSopenharmony_ci           av_log2(mlt_size) + 1);
266cabdff1aSopenharmony_ci
267cabdff1aSopenharmony_ci    return 0;
268cabdff1aSopenharmony_ci}
269cabdff1aSopenharmony_ci
270cabdff1aSopenharmony_cistatic av_cold void init_cplscales_table(COOKContext *q)
271cabdff1aSopenharmony_ci{
272cabdff1aSopenharmony_ci    int i;
273cabdff1aSopenharmony_ci    for (i = 0; i < 5; i++)
274cabdff1aSopenharmony_ci        q->cplscales[i] = cplscales[i];
275cabdff1aSopenharmony_ci}
276cabdff1aSopenharmony_ci
277cabdff1aSopenharmony_ci/*************** init functions end ***********/
278cabdff1aSopenharmony_ci
279cabdff1aSopenharmony_ci#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes) + 3) % 4)
280cabdff1aSopenharmony_ci#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes)))
281cabdff1aSopenharmony_ci
282cabdff1aSopenharmony_ci/**
283cabdff1aSopenharmony_ci * Cook indata decoding, every 32 bits are XORed with 0x37c511f2.
284cabdff1aSopenharmony_ci * Why? No idea, some checksum/error detection method maybe.
285cabdff1aSopenharmony_ci *
286cabdff1aSopenharmony_ci * Out buffer size: extra bytes are needed to cope with
287cabdff1aSopenharmony_ci * padding/misalignment.
288cabdff1aSopenharmony_ci * Subpackets passed to the decoder can contain two, consecutive
289cabdff1aSopenharmony_ci * half-subpackets, of identical but arbitrary size.
290cabdff1aSopenharmony_ci *          1234 1234 1234 1234  extraA extraB
291cabdff1aSopenharmony_ci * Case 1:  AAAA BBBB              0      0
292cabdff1aSopenharmony_ci * Case 2:  AAAA ABBB BB--         3      3
293cabdff1aSopenharmony_ci * Case 3:  AAAA AABB BBBB         2      2
294cabdff1aSopenharmony_ci * Case 4:  AAAA AAAB BBBB BB--    1      5
295cabdff1aSopenharmony_ci *
296cabdff1aSopenharmony_ci * Nice way to waste CPU cycles.
297cabdff1aSopenharmony_ci *
298cabdff1aSopenharmony_ci * @param inbuffer  pointer to byte array of indata
299cabdff1aSopenharmony_ci * @param out       pointer to byte array of outdata
300cabdff1aSopenharmony_ci * @param bytes     number of bytes
301cabdff1aSopenharmony_ci */
302cabdff1aSopenharmony_cistatic inline int decode_bytes(const uint8_t *inbuffer, uint8_t *out, int bytes)
303cabdff1aSopenharmony_ci{
304cabdff1aSopenharmony_ci    static const uint32_t tab[4] = {
305cabdff1aSopenharmony_ci        AV_BE2NE32C(0x37c511f2u), AV_BE2NE32C(0xf237c511u),
306cabdff1aSopenharmony_ci        AV_BE2NE32C(0x11f237c5u), AV_BE2NE32C(0xc511f237u),
307cabdff1aSopenharmony_ci    };
308cabdff1aSopenharmony_ci    int i, off;
309cabdff1aSopenharmony_ci    uint32_t c;
310cabdff1aSopenharmony_ci    const uint32_t *buf;
311cabdff1aSopenharmony_ci    uint32_t *obuf = (uint32_t *) out;
312cabdff1aSopenharmony_ci    /* FIXME: 64 bit platforms would be able to do 64 bits at a time.
313cabdff1aSopenharmony_ci     * I'm too lazy though, should be something like
314cabdff1aSopenharmony_ci     * for (i = 0; i < bitamount / 64; i++)
315cabdff1aSopenharmony_ci     *     (int64_t) out[i] = 0x37c511f237c511f2 ^ av_be2ne64(int64_t) in[i]);
316cabdff1aSopenharmony_ci     * Buffer alignment needs to be checked. */
317cabdff1aSopenharmony_ci
318cabdff1aSopenharmony_ci    off = (intptr_t) inbuffer & 3;
319cabdff1aSopenharmony_ci    buf = (const uint32_t *) (inbuffer - off);
320cabdff1aSopenharmony_ci    c = tab[off];
321cabdff1aSopenharmony_ci    bytes += 3 + off;
322cabdff1aSopenharmony_ci    for (i = 0; i < bytes / 4; i++)
323cabdff1aSopenharmony_ci        obuf[i] = c ^ buf[i];
324cabdff1aSopenharmony_ci
325cabdff1aSopenharmony_ci    return off;
326cabdff1aSopenharmony_ci}
327cabdff1aSopenharmony_ci
328cabdff1aSopenharmony_cistatic av_cold int cook_decode_close(AVCodecContext *avctx)
329cabdff1aSopenharmony_ci{
330cabdff1aSopenharmony_ci    int i;
331cabdff1aSopenharmony_ci    COOKContext *q = avctx->priv_data;
332cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n");
333cabdff1aSopenharmony_ci
334cabdff1aSopenharmony_ci    /* Free allocated memory buffers. */
335cabdff1aSopenharmony_ci    av_freep(&q->mlt_window);
336cabdff1aSopenharmony_ci    av_freep(&q->decoded_bytes_buffer);
337cabdff1aSopenharmony_ci
338cabdff1aSopenharmony_ci    /* Free the transform. */
339cabdff1aSopenharmony_ci    ff_mdct_end(&q->mdct_ctx);
340cabdff1aSopenharmony_ci
341cabdff1aSopenharmony_ci    /* Free the VLC tables. */
342cabdff1aSopenharmony_ci    for (i = 0; i < 13; i++)
343cabdff1aSopenharmony_ci        ff_free_vlc(&q->envelope_quant_index[i]);
344cabdff1aSopenharmony_ci    for (i = 0; i < 7; i++)
345cabdff1aSopenharmony_ci        ff_free_vlc(&q->sqvh[i]);
346cabdff1aSopenharmony_ci    for (i = 0; i < q->num_subpackets; i++)
347cabdff1aSopenharmony_ci        ff_free_vlc(&q->subpacket[i].channel_coupling);
348cabdff1aSopenharmony_ci
349cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_DEBUG, "Memory deallocated.\n");
350cabdff1aSopenharmony_ci
351cabdff1aSopenharmony_ci    return 0;
352cabdff1aSopenharmony_ci}
353cabdff1aSopenharmony_ci
354cabdff1aSopenharmony_ci/**
355cabdff1aSopenharmony_ci * Fill the gain array for the timedomain quantization.
356cabdff1aSopenharmony_ci *
357cabdff1aSopenharmony_ci * @param gb          pointer to the GetBitContext
358cabdff1aSopenharmony_ci * @param gaininfo    array[9] of gain indexes
359cabdff1aSopenharmony_ci */
360cabdff1aSopenharmony_cistatic void decode_gain_info(GetBitContext *gb, int *gaininfo)
361cabdff1aSopenharmony_ci{
362cabdff1aSopenharmony_ci    int i, n;
363cabdff1aSopenharmony_ci
364cabdff1aSopenharmony_ci    n = get_unary(gb, 0, get_bits_left(gb));     // amount of elements*2 to update
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_ci    i = 0;
367cabdff1aSopenharmony_ci    while (n--) {
368cabdff1aSopenharmony_ci        int index = get_bits(gb, 3);
369cabdff1aSopenharmony_ci        int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1;
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_ci        while (i <= index)
372cabdff1aSopenharmony_ci            gaininfo[i++] = gain;
373cabdff1aSopenharmony_ci    }
374cabdff1aSopenharmony_ci    while (i <= 8)
375cabdff1aSopenharmony_ci        gaininfo[i++] = 0;
376cabdff1aSopenharmony_ci}
377cabdff1aSopenharmony_ci
378cabdff1aSopenharmony_ci/**
379cabdff1aSopenharmony_ci * Create the quant index table needed for the envelope.
380cabdff1aSopenharmony_ci *
381cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
382cabdff1aSopenharmony_ci * @param quant_index_table pointer to the array
383cabdff1aSopenharmony_ci */
384cabdff1aSopenharmony_cistatic int decode_envelope(COOKContext *q, COOKSubpacket *p,
385cabdff1aSopenharmony_ci                           int *quant_index_table)
386cabdff1aSopenharmony_ci{
387cabdff1aSopenharmony_ci    int i, j, vlc_index;
388cabdff1aSopenharmony_ci
389cabdff1aSopenharmony_ci    quant_index_table[0] = get_bits(&q->gb, 6) - 6; // This is used later in categorize
390cabdff1aSopenharmony_ci
391cabdff1aSopenharmony_ci    for (i = 1; i < p->total_subbands; i++) {
392cabdff1aSopenharmony_ci        vlc_index = i;
393cabdff1aSopenharmony_ci        if (i >= p->js_subband_start * 2) {
394cabdff1aSopenharmony_ci            vlc_index -= p->js_subband_start;
395cabdff1aSopenharmony_ci        } else {
396cabdff1aSopenharmony_ci            vlc_index /= 2;
397cabdff1aSopenharmony_ci            if (vlc_index < 1)
398cabdff1aSopenharmony_ci                vlc_index = 1;
399cabdff1aSopenharmony_ci        }
400cabdff1aSopenharmony_ci        if (vlc_index > 13)
401cabdff1aSopenharmony_ci            vlc_index = 13; // the VLC tables >13 are identical to No. 13
402cabdff1aSopenharmony_ci
403cabdff1aSopenharmony_ci        j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table,
404cabdff1aSopenharmony_ci                     QUANT_VLC_BITS, 2);
405cabdff1aSopenharmony_ci        quant_index_table[i] = quant_index_table[i - 1] + j; // differential encoding
406cabdff1aSopenharmony_ci        if (quant_index_table[i] > 63 || quant_index_table[i] < -63) {
407cabdff1aSopenharmony_ci            av_log(q->avctx, AV_LOG_ERROR,
408cabdff1aSopenharmony_ci                   "Invalid quantizer %d at position %d, outside [-63, 63] range\n",
409cabdff1aSopenharmony_ci                   quant_index_table[i], i);
410cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
411cabdff1aSopenharmony_ci        }
412cabdff1aSopenharmony_ci    }
413cabdff1aSopenharmony_ci
414cabdff1aSopenharmony_ci    return 0;
415cabdff1aSopenharmony_ci}
416cabdff1aSopenharmony_ci
417cabdff1aSopenharmony_ci/**
418cabdff1aSopenharmony_ci * Calculate the category and category_index vector.
419cabdff1aSopenharmony_ci *
420cabdff1aSopenharmony_ci * @param q                     pointer to the COOKContext
421cabdff1aSopenharmony_ci * @param quant_index_table     pointer to the array
422cabdff1aSopenharmony_ci * @param category              pointer to the category array
423cabdff1aSopenharmony_ci * @param category_index        pointer to the category_index array
424cabdff1aSopenharmony_ci */
425cabdff1aSopenharmony_cistatic void categorize(COOKContext *q, COOKSubpacket *p, const int *quant_index_table,
426cabdff1aSopenharmony_ci                       int *category, int *category_index)
427cabdff1aSopenharmony_ci{
428cabdff1aSopenharmony_ci    int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j;
429cabdff1aSopenharmony_ci    int exp_index2[102] = { 0 };
430cabdff1aSopenharmony_ci    int exp_index1[102] = { 0 };
431cabdff1aSopenharmony_ci
432cabdff1aSopenharmony_ci    int tmp_categorize_array[128 * 2] = { 0 };
433cabdff1aSopenharmony_ci    int tmp_categorize_array1_idx = p->numvector_size;
434cabdff1aSopenharmony_ci    int tmp_categorize_array2_idx = p->numvector_size;
435cabdff1aSopenharmony_ci
436cabdff1aSopenharmony_ci    bits_left = p->bits_per_subpacket - get_bits_count(&q->gb);
437cabdff1aSopenharmony_ci
438cabdff1aSopenharmony_ci    if (bits_left > q->samples_per_channel)
439cabdff1aSopenharmony_ci        bits_left = q->samples_per_channel +
440cabdff1aSopenharmony_ci                    ((bits_left - q->samples_per_channel) * 5) / 8;
441cabdff1aSopenharmony_ci
442cabdff1aSopenharmony_ci    bias = -32;
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_ci    /* Estimate bias. */
445cabdff1aSopenharmony_ci    for (i = 32; i > 0; i = i / 2) {
446cabdff1aSopenharmony_ci        num_bits = 0;
447cabdff1aSopenharmony_ci        index    = 0;
448cabdff1aSopenharmony_ci        for (j = p->total_subbands; j > 0; j--) {
449cabdff1aSopenharmony_ci            exp_idx = av_clip_uintp2((i - quant_index_table[index] + bias) / 2, 3);
450cabdff1aSopenharmony_ci            index++;
451cabdff1aSopenharmony_ci            num_bits += expbits_tab[exp_idx];
452cabdff1aSopenharmony_ci        }
453cabdff1aSopenharmony_ci        if (num_bits >= bits_left - 32)
454cabdff1aSopenharmony_ci            bias += i;
455cabdff1aSopenharmony_ci    }
456cabdff1aSopenharmony_ci
457cabdff1aSopenharmony_ci    /* Calculate total number of bits. */
458cabdff1aSopenharmony_ci    num_bits = 0;
459cabdff1aSopenharmony_ci    for (i = 0; i < p->total_subbands; i++) {
460cabdff1aSopenharmony_ci        exp_idx = av_clip_uintp2((bias - quant_index_table[i]) / 2, 3);
461cabdff1aSopenharmony_ci        num_bits += expbits_tab[exp_idx];
462cabdff1aSopenharmony_ci        exp_index1[i] = exp_idx;
463cabdff1aSopenharmony_ci        exp_index2[i] = exp_idx;
464cabdff1aSopenharmony_ci    }
465cabdff1aSopenharmony_ci    tmpbias1 = tmpbias2 = num_bits;
466cabdff1aSopenharmony_ci
467cabdff1aSopenharmony_ci    for (j = 1; j < p->numvector_size; j++) {
468cabdff1aSopenharmony_ci        if (tmpbias1 + tmpbias2 > 2 * bits_left) {  /* ---> */
469cabdff1aSopenharmony_ci            int max = -999999;
470cabdff1aSopenharmony_ci            index = -1;
471cabdff1aSopenharmony_ci            for (i = 0; i < p->total_subbands; i++) {
472cabdff1aSopenharmony_ci                if (exp_index1[i] < 7) {
473cabdff1aSopenharmony_ci                    v = (-2 * exp_index1[i]) - quant_index_table[i] + bias;
474cabdff1aSopenharmony_ci                    if (v >= max) {
475cabdff1aSopenharmony_ci                        max   = v;
476cabdff1aSopenharmony_ci                        index = i;
477cabdff1aSopenharmony_ci                    }
478cabdff1aSopenharmony_ci                }
479cabdff1aSopenharmony_ci            }
480cabdff1aSopenharmony_ci            if (index == -1)
481cabdff1aSopenharmony_ci                break;
482cabdff1aSopenharmony_ci            tmp_categorize_array[tmp_categorize_array1_idx++] = index;
483cabdff1aSopenharmony_ci            tmpbias1 -= expbits_tab[exp_index1[index]] -
484cabdff1aSopenharmony_ci                        expbits_tab[exp_index1[index] + 1];
485cabdff1aSopenharmony_ci            ++exp_index1[index];
486cabdff1aSopenharmony_ci        } else {  /* <--- */
487cabdff1aSopenharmony_ci            int min = 999999;
488cabdff1aSopenharmony_ci            index = -1;
489cabdff1aSopenharmony_ci            for (i = 0; i < p->total_subbands; i++) {
490cabdff1aSopenharmony_ci                if (exp_index2[i] > 0) {
491cabdff1aSopenharmony_ci                    v = (-2 * exp_index2[i]) - quant_index_table[i] + bias;
492cabdff1aSopenharmony_ci                    if (v < min) {
493cabdff1aSopenharmony_ci                        min   = v;
494cabdff1aSopenharmony_ci                        index = i;
495cabdff1aSopenharmony_ci                    }
496cabdff1aSopenharmony_ci                }
497cabdff1aSopenharmony_ci            }
498cabdff1aSopenharmony_ci            if (index == -1)
499cabdff1aSopenharmony_ci                break;
500cabdff1aSopenharmony_ci            tmp_categorize_array[--tmp_categorize_array2_idx] = index;
501cabdff1aSopenharmony_ci            tmpbias2 -= expbits_tab[exp_index2[index]] -
502cabdff1aSopenharmony_ci                        expbits_tab[exp_index2[index] - 1];
503cabdff1aSopenharmony_ci            --exp_index2[index];
504cabdff1aSopenharmony_ci        }
505cabdff1aSopenharmony_ci    }
506cabdff1aSopenharmony_ci
507cabdff1aSopenharmony_ci    for (i = 0; i < p->total_subbands; i++)
508cabdff1aSopenharmony_ci        category[i] = exp_index2[i];
509cabdff1aSopenharmony_ci
510cabdff1aSopenharmony_ci    for (i = 0; i < p->numvector_size - 1; i++)
511cabdff1aSopenharmony_ci        category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++];
512cabdff1aSopenharmony_ci}
513cabdff1aSopenharmony_ci
514cabdff1aSopenharmony_ci
515cabdff1aSopenharmony_ci/**
516cabdff1aSopenharmony_ci * Expand the category vector.
517cabdff1aSopenharmony_ci *
518cabdff1aSopenharmony_ci * @param q                     pointer to the COOKContext
519cabdff1aSopenharmony_ci * @param category              pointer to the category array
520cabdff1aSopenharmony_ci * @param category_index        pointer to the category_index array
521cabdff1aSopenharmony_ci */
522cabdff1aSopenharmony_cistatic inline void expand_category(COOKContext *q, int *category,
523cabdff1aSopenharmony_ci                                   int *category_index)
524cabdff1aSopenharmony_ci{
525cabdff1aSopenharmony_ci    int i;
526cabdff1aSopenharmony_ci    for (i = 0; i < q->num_vectors; i++)
527cabdff1aSopenharmony_ci    {
528cabdff1aSopenharmony_ci        int idx = category_index[i];
529cabdff1aSopenharmony_ci        if (++category[idx] >= FF_ARRAY_ELEMS(dither_tab))
530cabdff1aSopenharmony_ci            --category[idx];
531cabdff1aSopenharmony_ci    }
532cabdff1aSopenharmony_ci}
533cabdff1aSopenharmony_ci
534cabdff1aSopenharmony_ci/**
535cabdff1aSopenharmony_ci * The real requantization of the mltcoefs
536cabdff1aSopenharmony_ci *
537cabdff1aSopenharmony_ci * @param q                     pointer to the COOKContext
538cabdff1aSopenharmony_ci * @param index                 index
539cabdff1aSopenharmony_ci * @param quant_index           quantisation index
540cabdff1aSopenharmony_ci * @param subband_coef_index    array of indexes to quant_centroid_tab
541cabdff1aSopenharmony_ci * @param subband_coef_sign     signs of coefficients
542cabdff1aSopenharmony_ci * @param mlt_p                 pointer into the mlt buffer
543cabdff1aSopenharmony_ci */
544cabdff1aSopenharmony_cistatic void scalar_dequant_float(COOKContext *q, int index, int quant_index,
545cabdff1aSopenharmony_ci                                 int *subband_coef_index, int *subband_coef_sign,
546cabdff1aSopenharmony_ci                                 float *mlt_p)
547cabdff1aSopenharmony_ci{
548cabdff1aSopenharmony_ci    int i;
549cabdff1aSopenharmony_ci    float f1;
550cabdff1aSopenharmony_ci
551cabdff1aSopenharmony_ci    for (i = 0; i < SUBBAND_SIZE; i++) {
552cabdff1aSopenharmony_ci        if (subband_coef_index[i]) {
553cabdff1aSopenharmony_ci            f1 = quant_centroid_tab[index][subband_coef_index[i]];
554cabdff1aSopenharmony_ci            if (subband_coef_sign[i])
555cabdff1aSopenharmony_ci                f1 = -f1;
556cabdff1aSopenharmony_ci        } else {
557cabdff1aSopenharmony_ci            /* noise coding if subband_coef_index[i] == 0 */
558cabdff1aSopenharmony_ci            f1 = dither_tab[index];
559cabdff1aSopenharmony_ci            if (av_lfg_get(&q->random_state) < 0x80000000)
560cabdff1aSopenharmony_ci                f1 = -f1;
561cabdff1aSopenharmony_ci        }
562cabdff1aSopenharmony_ci        mlt_p[i] = f1 * rootpow2tab[quant_index + 63];
563cabdff1aSopenharmony_ci    }
564cabdff1aSopenharmony_ci}
565cabdff1aSopenharmony_ci/**
566cabdff1aSopenharmony_ci * Unpack the subband_coef_index and subband_coef_sign vectors.
567cabdff1aSopenharmony_ci *
568cabdff1aSopenharmony_ci * @param q                     pointer to the COOKContext
569cabdff1aSopenharmony_ci * @param category              pointer to the category array
570cabdff1aSopenharmony_ci * @param subband_coef_index    array of indexes to quant_centroid_tab
571cabdff1aSopenharmony_ci * @param subband_coef_sign     signs of coefficients
572cabdff1aSopenharmony_ci */
573cabdff1aSopenharmony_cistatic int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category,
574cabdff1aSopenharmony_ci                       int *subband_coef_index, int *subband_coef_sign)
575cabdff1aSopenharmony_ci{
576cabdff1aSopenharmony_ci    int i, j;
577cabdff1aSopenharmony_ci    int vlc, vd, tmp, result;
578cabdff1aSopenharmony_ci
579cabdff1aSopenharmony_ci    vd = vd_tab[category];
580cabdff1aSopenharmony_ci    result = 0;
581cabdff1aSopenharmony_ci    for (i = 0; i < vpr_tab[category]; i++) {
582cabdff1aSopenharmony_ci        vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3);
583cabdff1aSopenharmony_ci        if (p->bits_per_subpacket < get_bits_count(&q->gb)) {
584cabdff1aSopenharmony_ci            vlc = 0;
585cabdff1aSopenharmony_ci            result = 1;
586cabdff1aSopenharmony_ci        }
587cabdff1aSopenharmony_ci        for (j = vd - 1; j >= 0; j--) {
588cabdff1aSopenharmony_ci            tmp = (vlc * invradix_tab[category]) / 0x100000;
589cabdff1aSopenharmony_ci            subband_coef_index[vd * i + j] = vlc - tmp * (kmax_tab[category] + 1);
590cabdff1aSopenharmony_ci            vlc = tmp;
591cabdff1aSopenharmony_ci        }
592cabdff1aSopenharmony_ci        for (j = 0; j < vd; j++) {
593cabdff1aSopenharmony_ci            if (subband_coef_index[i * vd + j]) {
594cabdff1aSopenharmony_ci                if (get_bits_count(&q->gb) < p->bits_per_subpacket) {
595cabdff1aSopenharmony_ci                    subband_coef_sign[i * vd + j] = get_bits1(&q->gb);
596cabdff1aSopenharmony_ci                } else {
597cabdff1aSopenharmony_ci                    result = 1;
598cabdff1aSopenharmony_ci                    subband_coef_sign[i * vd + j] = 0;
599cabdff1aSopenharmony_ci                }
600cabdff1aSopenharmony_ci            } else {
601cabdff1aSopenharmony_ci                subband_coef_sign[i * vd + j] = 0;
602cabdff1aSopenharmony_ci            }
603cabdff1aSopenharmony_ci        }
604cabdff1aSopenharmony_ci    }
605cabdff1aSopenharmony_ci    return result;
606cabdff1aSopenharmony_ci}
607cabdff1aSopenharmony_ci
608cabdff1aSopenharmony_ci
609cabdff1aSopenharmony_ci/**
610cabdff1aSopenharmony_ci * Fill the mlt_buffer with mlt coefficients.
611cabdff1aSopenharmony_ci *
612cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
613cabdff1aSopenharmony_ci * @param category          pointer to the category array
614cabdff1aSopenharmony_ci * @param quant_index_table pointer to the array
615cabdff1aSopenharmony_ci * @param mlt_buffer        pointer to mlt coefficients
616cabdff1aSopenharmony_ci */
617cabdff1aSopenharmony_cistatic void decode_vectors(COOKContext *q, COOKSubpacket *p, int *category,
618cabdff1aSopenharmony_ci                           int *quant_index_table, float *mlt_buffer)
619cabdff1aSopenharmony_ci{
620cabdff1aSopenharmony_ci    /* A zero in this table means that the subband coefficient is
621cabdff1aSopenharmony_ci       random noise coded. */
622cabdff1aSopenharmony_ci    int subband_coef_index[SUBBAND_SIZE];
623cabdff1aSopenharmony_ci    /* A zero in this table means that the subband coefficient is a
624cabdff1aSopenharmony_ci       positive multiplicator. */
625cabdff1aSopenharmony_ci    int subband_coef_sign[SUBBAND_SIZE];
626cabdff1aSopenharmony_ci    int band, j;
627cabdff1aSopenharmony_ci    int index = 0;
628cabdff1aSopenharmony_ci
629cabdff1aSopenharmony_ci    for (band = 0; band < p->total_subbands; band++) {
630cabdff1aSopenharmony_ci        index = category[band];
631cabdff1aSopenharmony_ci        if (category[band] < 7) {
632cabdff1aSopenharmony_ci            if (unpack_SQVH(q, p, category[band], subband_coef_index, subband_coef_sign)) {
633cabdff1aSopenharmony_ci                index = 7;
634cabdff1aSopenharmony_ci                for (j = 0; j < p->total_subbands; j++)
635cabdff1aSopenharmony_ci                    category[band + j] = 7;
636cabdff1aSopenharmony_ci            }
637cabdff1aSopenharmony_ci        }
638cabdff1aSopenharmony_ci        if (index >= 7) {
639cabdff1aSopenharmony_ci            memset(subband_coef_index, 0, sizeof(subband_coef_index));
640cabdff1aSopenharmony_ci            memset(subband_coef_sign,  0, sizeof(subband_coef_sign));
641cabdff1aSopenharmony_ci        }
642cabdff1aSopenharmony_ci        q->scalar_dequant(q, index, quant_index_table[band],
643cabdff1aSopenharmony_ci                          subband_coef_index, subband_coef_sign,
644cabdff1aSopenharmony_ci                          &mlt_buffer[band * SUBBAND_SIZE]);
645cabdff1aSopenharmony_ci    }
646cabdff1aSopenharmony_ci
647cabdff1aSopenharmony_ci    /* FIXME: should this be removed, or moved into loop above? */
648cabdff1aSopenharmony_ci    if (p->total_subbands * SUBBAND_SIZE >= q->samples_per_channel)
649cabdff1aSopenharmony_ci        return;
650cabdff1aSopenharmony_ci}
651cabdff1aSopenharmony_ci
652cabdff1aSopenharmony_ci
653cabdff1aSopenharmony_cistatic int mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer)
654cabdff1aSopenharmony_ci{
655cabdff1aSopenharmony_ci    int category_index[128] = { 0 };
656cabdff1aSopenharmony_ci    int category[128]       = { 0 };
657cabdff1aSopenharmony_ci    int quant_index_table[102];
658cabdff1aSopenharmony_ci    int res, i;
659cabdff1aSopenharmony_ci
660cabdff1aSopenharmony_ci    if ((res = decode_envelope(q, p, quant_index_table)) < 0)
661cabdff1aSopenharmony_ci        return res;
662cabdff1aSopenharmony_ci    q->num_vectors = get_bits(&q->gb, p->log2_numvector_size);
663cabdff1aSopenharmony_ci    categorize(q, p, quant_index_table, category, category_index);
664cabdff1aSopenharmony_ci    expand_category(q, category, category_index);
665cabdff1aSopenharmony_ci    for (i=0; i<p->total_subbands; i++) {
666cabdff1aSopenharmony_ci        if (category[i] > 7)
667cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
668cabdff1aSopenharmony_ci    }
669cabdff1aSopenharmony_ci    decode_vectors(q, p, category, quant_index_table, mlt_buffer);
670cabdff1aSopenharmony_ci
671cabdff1aSopenharmony_ci    return 0;
672cabdff1aSopenharmony_ci}
673cabdff1aSopenharmony_ci
674cabdff1aSopenharmony_ci
675cabdff1aSopenharmony_ci/**
676cabdff1aSopenharmony_ci * the actual requantization of the timedomain samples
677cabdff1aSopenharmony_ci *
678cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
679cabdff1aSopenharmony_ci * @param buffer            pointer to the timedomain buffer
680cabdff1aSopenharmony_ci * @param gain_index        index for the block multiplier
681cabdff1aSopenharmony_ci * @param gain_index_next   index for the next block multiplier
682cabdff1aSopenharmony_ci */
683cabdff1aSopenharmony_cistatic void interpolate_float(COOKContext *q, float *buffer,
684cabdff1aSopenharmony_ci                              int gain_index, int gain_index_next)
685cabdff1aSopenharmony_ci{
686cabdff1aSopenharmony_ci    int i;
687cabdff1aSopenharmony_ci    float fc1, fc2;
688cabdff1aSopenharmony_ci    fc1 = pow2tab[gain_index + 63];
689cabdff1aSopenharmony_ci
690cabdff1aSopenharmony_ci    if (gain_index == gain_index_next) {             // static gain
691cabdff1aSopenharmony_ci        for (i = 0; i < q->gain_size_factor; i++)
692cabdff1aSopenharmony_ci            buffer[i] *= fc1;
693cabdff1aSopenharmony_ci    } else {                                        // smooth gain
694cabdff1aSopenharmony_ci        fc2 = q->gain_table[15 + (gain_index_next - gain_index)];
695cabdff1aSopenharmony_ci        for (i = 0; i < q->gain_size_factor; i++) {
696cabdff1aSopenharmony_ci            buffer[i] *= fc1;
697cabdff1aSopenharmony_ci            fc1       *= fc2;
698cabdff1aSopenharmony_ci        }
699cabdff1aSopenharmony_ci    }
700cabdff1aSopenharmony_ci}
701cabdff1aSopenharmony_ci
702cabdff1aSopenharmony_ci/**
703cabdff1aSopenharmony_ci * Apply transform window, overlap buffers.
704cabdff1aSopenharmony_ci *
705cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
706cabdff1aSopenharmony_ci * @param inbuffer          pointer to the mltcoefficients
707cabdff1aSopenharmony_ci * @param gains_ptr         current and previous gains
708cabdff1aSopenharmony_ci * @param previous_buffer   pointer to the previous buffer to be used for overlapping
709cabdff1aSopenharmony_ci */
710cabdff1aSopenharmony_cistatic void imlt_window_float(COOKContext *q, float *inbuffer,
711cabdff1aSopenharmony_ci                              cook_gains *gains_ptr, float *previous_buffer)
712cabdff1aSopenharmony_ci{
713cabdff1aSopenharmony_ci    const float fc = pow2tab[gains_ptr->previous[0] + 63];
714cabdff1aSopenharmony_ci    int i;
715cabdff1aSopenharmony_ci    /* The weird thing here, is that the two halves of the time domain
716cabdff1aSopenharmony_ci     * buffer are swapped. Also, the newest data, that we save away for
717cabdff1aSopenharmony_ci     * next frame, has the wrong sign. Hence the subtraction below.
718cabdff1aSopenharmony_ci     * Almost sounds like a complex conjugate/reverse data/FFT effect.
719cabdff1aSopenharmony_ci     */
720cabdff1aSopenharmony_ci
721cabdff1aSopenharmony_ci    /* Apply window and overlap */
722cabdff1aSopenharmony_ci    for (i = 0; i < q->samples_per_channel; i++)
723cabdff1aSopenharmony_ci        inbuffer[i] = inbuffer[i] * fc * q->mlt_window[i] -
724cabdff1aSopenharmony_ci                      previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i];
725cabdff1aSopenharmony_ci}
726cabdff1aSopenharmony_ci
727cabdff1aSopenharmony_ci/**
728cabdff1aSopenharmony_ci * The modulated lapped transform, this takes transform coefficients
729cabdff1aSopenharmony_ci * and transforms them into timedomain samples.
730cabdff1aSopenharmony_ci * Apply transform window, overlap buffers, apply gain profile
731cabdff1aSopenharmony_ci * and buffer management.
732cabdff1aSopenharmony_ci *
733cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
734cabdff1aSopenharmony_ci * @param inbuffer          pointer to the mltcoefficients
735cabdff1aSopenharmony_ci * @param gains_ptr         current and previous gains
736cabdff1aSopenharmony_ci * @param previous_buffer   pointer to the previous buffer to be used for overlapping
737cabdff1aSopenharmony_ci */
738cabdff1aSopenharmony_cistatic void imlt_gain(COOKContext *q, float *inbuffer,
739cabdff1aSopenharmony_ci                      cook_gains *gains_ptr, float *previous_buffer)
740cabdff1aSopenharmony_ci{
741cabdff1aSopenharmony_ci    float *buffer0 = q->mono_mdct_output;
742cabdff1aSopenharmony_ci    float *buffer1 = q->mono_mdct_output + q->samples_per_channel;
743cabdff1aSopenharmony_ci    int i;
744cabdff1aSopenharmony_ci
745cabdff1aSopenharmony_ci    /* Inverse modified discrete cosine transform */
746cabdff1aSopenharmony_ci    q->mdct_ctx.imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer);
747cabdff1aSopenharmony_ci
748cabdff1aSopenharmony_ci    q->imlt_window(q, buffer1, gains_ptr, previous_buffer);
749cabdff1aSopenharmony_ci
750cabdff1aSopenharmony_ci    /* Apply gain profile */
751cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++)
752cabdff1aSopenharmony_ci        if (gains_ptr->now[i] || gains_ptr->now[i + 1])
753cabdff1aSopenharmony_ci            q->interpolate(q, &buffer1[q->gain_size_factor * i],
754cabdff1aSopenharmony_ci                           gains_ptr->now[i], gains_ptr->now[i + 1]);
755cabdff1aSopenharmony_ci
756cabdff1aSopenharmony_ci    /* Save away the current to be previous block. */
757cabdff1aSopenharmony_ci    memcpy(previous_buffer, buffer0,
758cabdff1aSopenharmony_ci           q->samples_per_channel * sizeof(*previous_buffer));
759cabdff1aSopenharmony_ci}
760cabdff1aSopenharmony_ci
761cabdff1aSopenharmony_ci
762cabdff1aSopenharmony_ci/**
763cabdff1aSopenharmony_ci * function for getting the jointstereo coupling information
764cabdff1aSopenharmony_ci *
765cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
766cabdff1aSopenharmony_ci * @param decouple_tab      decoupling array
767cabdff1aSopenharmony_ci */
768cabdff1aSopenharmony_cistatic int decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
769cabdff1aSopenharmony_ci{
770cabdff1aSopenharmony_ci    int i;
771cabdff1aSopenharmony_ci    int vlc    = get_bits1(&q->gb);
772cabdff1aSopenharmony_ci    int start  = cplband[p->js_subband_start];
773cabdff1aSopenharmony_ci    int end    = cplband[p->subbands - 1];
774cabdff1aSopenharmony_ci    int length = end - start + 1;
775cabdff1aSopenharmony_ci
776cabdff1aSopenharmony_ci    if (start > end)
777cabdff1aSopenharmony_ci        return 0;
778cabdff1aSopenharmony_ci
779cabdff1aSopenharmony_ci    if (vlc)
780cabdff1aSopenharmony_ci        for (i = 0; i < length; i++)
781cabdff1aSopenharmony_ci            decouple_tab[start + i] = get_vlc2(&q->gb,
782cabdff1aSopenharmony_ci                                               p->channel_coupling.table,
783cabdff1aSopenharmony_ci                                               COUPLING_VLC_BITS, 3);
784cabdff1aSopenharmony_ci    else
785cabdff1aSopenharmony_ci        for (i = 0; i < length; i++) {
786cabdff1aSopenharmony_ci            int v = get_bits(&q->gb, p->js_vlc_bits);
787cabdff1aSopenharmony_ci            if (v == (1<<p->js_vlc_bits)-1) {
788cabdff1aSopenharmony_ci                av_log(q->avctx, AV_LOG_ERROR, "decouple value too large\n");
789cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
790cabdff1aSopenharmony_ci            }
791cabdff1aSopenharmony_ci            decouple_tab[start + i] = v;
792cabdff1aSopenharmony_ci        }
793cabdff1aSopenharmony_ci    return 0;
794cabdff1aSopenharmony_ci}
795cabdff1aSopenharmony_ci
796cabdff1aSopenharmony_ci/**
797cabdff1aSopenharmony_ci * function decouples a pair of signals from a single signal via multiplication.
798cabdff1aSopenharmony_ci *
799cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
800cabdff1aSopenharmony_ci * @param subband           index of the current subband
801cabdff1aSopenharmony_ci * @param f1                multiplier for channel 1 extraction
802cabdff1aSopenharmony_ci * @param f2                multiplier for channel 2 extraction
803cabdff1aSopenharmony_ci * @param decode_buffer     input buffer
804cabdff1aSopenharmony_ci * @param mlt_buffer1       pointer to left channel mlt coefficients
805cabdff1aSopenharmony_ci * @param mlt_buffer2       pointer to right channel mlt coefficients
806cabdff1aSopenharmony_ci */
807cabdff1aSopenharmony_cistatic void decouple_float(COOKContext *q,
808cabdff1aSopenharmony_ci                           COOKSubpacket *p,
809cabdff1aSopenharmony_ci                           int subband,
810cabdff1aSopenharmony_ci                           float f1, float f2,
811cabdff1aSopenharmony_ci                           float *decode_buffer,
812cabdff1aSopenharmony_ci                           float *mlt_buffer1, float *mlt_buffer2)
813cabdff1aSopenharmony_ci{
814cabdff1aSopenharmony_ci    int j, tmp_idx;
815cabdff1aSopenharmony_ci    for (j = 0; j < SUBBAND_SIZE; j++) {
816cabdff1aSopenharmony_ci        tmp_idx = ((p->js_subband_start + subband) * SUBBAND_SIZE) + j;
817cabdff1aSopenharmony_ci        mlt_buffer1[SUBBAND_SIZE * subband + j] = f1 * decode_buffer[tmp_idx];
818cabdff1aSopenharmony_ci        mlt_buffer2[SUBBAND_SIZE * subband + j] = f2 * decode_buffer[tmp_idx];
819cabdff1aSopenharmony_ci    }
820cabdff1aSopenharmony_ci}
821cabdff1aSopenharmony_ci
822cabdff1aSopenharmony_ci/**
823cabdff1aSopenharmony_ci * function for decoding joint stereo data
824cabdff1aSopenharmony_ci *
825cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
826cabdff1aSopenharmony_ci * @param mlt_buffer1       pointer to left channel mlt coefficients
827cabdff1aSopenharmony_ci * @param mlt_buffer2       pointer to right channel mlt coefficients
828cabdff1aSopenharmony_ci */
829cabdff1aSopenharmony_cistatic int joint_decode(COOKContext *q, COOKSubpacket *p,
830cabdff1aSopenharmony_ci                        float *mlt_buffer_left, float *mlt_buffer_right)
831cabdff1aSopenharmony_ci{
832cabdff1aSopenharmony_ci    int i, j, res;
833cabdff1aSopenharmony_ci    int decouple_tab[SUBBAND_SIZE] = { 0 };
834cabdff1aSopenharmony_ci    float *decode_buffer = q->decode_buffer_0;
835cabdff1aSopenharmony_ci    int idx, cpl_tmp;
836cabdff1aSopenharmony_ci    float f1, f2;
837cabdff1aSopenharmony_ci    const float *cplscale;
838cabdff1aSopenharmony_ci
839cabdff1aSopenharmony_ci    memset(decode_buffer, 0, sizeof(q->decode_buffer_0));
840cabdff1aSopenharmony_ci
841cabdff1aSopenharmony_ci    /* Make sure the buffers are zeroed out. */
842cabdff1aSopenharmony_ci    memset(mlt_buffer_left,  0, 1024 * sizeof(*mlt_buffer_left));
843cabdff1aSopenharmony_ci    memset(mlt_buffer_right, 0, 1024 * sizeof(*mlt_buffer_right));
844cabdff1aSopenharmony_ci    if ((res = decouple_info(q, p, decouple_tab)) < 0)
845cabdff1aSopenharmony_ci        return res;
846cabdff1aSopenharmony_ci    if ((res = mono_decode(q, p, decode_buffer)) < 0)
847cabdff1aSopenharmony_ci        return res;
848cabdff1aSopenharmony_ci    /* The two channels are stored interleaved in decode_buffer. */
849cabdff1aSopenharmony_ci    for (i = 0; i < p->js_subband_start; i++) {
850cabdff1aSopenharmony_ci        for (j = 0; j < SUBBAND_SIZE; j++) {
851cabdff1aSopenharmony_ci            mlt_buffer_left[i  * 20 + j] = decode_buffer[i * 40 + j];
852cabdff1aSopenharmony_ci            mlt_buffer_right[i * 20 + j] = decode_buffer[i * 40 + 20 + j];
853cabdff1aSopenharmony_ci        }
854cabdff1aSopenharmony_ci    }
855cabdff1aSopenharmony_ci
856cabdff1aSopenharmony_ci    /* When we reach js_subband_start (the higher frequencies)
857cabdff1aSopenharmony_ci       the coefficients are stored in a coupling scheme. */
858cabdff1aSopenharmony_ci    idx = (1 << p->js_vlc_bits) - 1;
859cabdff1aSopenharmony_ci    for (i = p->js_subband_start; i < p->subbands; i++) {
860cabdff1aSopenharmony_ci        cpl_tmp = cplband[i];
861cabdff1aSopenharmony_ci        idx -= decouple_tab[cpl_tmp];
862cabdff1aSopenharmony_ci        cplscale = q->cplscales[p->js_vlc_bits - 2];  // choose decoupler table
863cabdff1aSopenharmony_ci        f1 = cplscale[decouple_tab[cpl_tmp] + 1];
864cabdff1aSopenharmony_ci        f2 = cplscale[idx];
865cabdff1aSopenharmony_ci        q->decouple(q, p, i, f1, f2, decode_buffer,
866cabdff1aSopenharmony_ci                    mlt_buffer_left, mlt_buffer_right);
867cabdff1aSopenharmony_ci        idx = (1 << p->js_vlc_bits) - 1;
868cabdff1aSopenharmony_ci    }
869cabdff1aSopenharmony_ci
870cabdff1aSopenharmony_ci    return 0;
871cabdff1aSopenharmony_ci}
872cabdff1aSopenharmony_ci
873cabdff1aSopenharmony_ci/**
874cabdff1aSopenharmony_ci * First part of subpacket decoding:
875cabdff1aSopenharmony_ci *  decode raw stream bytes and read gain info.
876cabdff1aSopenharmony_ci *
877cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
878cabdff1aSopenharmony_ci * @param inbuffer          pointer to raw stream data
879cabdff1aSopenharmony_ci * @param gains_ptr         array of current/prev gain pointers
880cabdff1aSopenharmony_ci */
881cabdff1aSopenharmony_cistatic inline void decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p,
882cabdff1aSopenharmony_ci                                         const uint8_t *inbuffer,
883cabdff1aSopenharmony_ci                                         cook_gains *gains_ptr)
884cabdff1aSopenharmony_ci{
885cabdff1aSopenharmony_ci    int offset;
886cabdff1aSopenharmony_ci
887cabdff1aSopenharmony_ci    offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,
888cabdff1aSopenharmony_ci                          p->bits_per_subpacket / 8);
889cabdff1aSopenharmony_ci    init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
890cabdff1aSopenharmony_ci                  p->bits_per_subpacket);
891cabdff1aSopenharmony_ci    decode_gain_info(&q->gb, gains_ptr->now);
892cabdff1aSopenharmony_ci
893cabdff1aSopenharmony_ci    /* Swap current and previous gains */
894cabdff1aSopenharmony_ci    FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
895cabdff1aSopenharmony_ci}
896cabdff1aSopenharmony_ci
897cabdff1aSopenharmony_ci/**
898cabdff1aSopenharmony_ci * Saturate the output signal and interleave.
899cabdff1aSopenharmony_ci *
900cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
901cabdff1aSopenharmony_ci * @param out               pointer to the output vector
902cabdff1aSopenharmony_ci */
903cabdff1aSopenharmony_cistatic void saturate_output_float(COOKContext *q, float *out)
904cabdff1aSopenharmony_ci{
905cabdff1aSopenharmony_ci    q->adsp.vector_clipf(out, q->mono_mdct_output + q->samples_per_channel,
906cabdff1aSopenharmony_ci                         FFALIGN(q->samples_per_channel, 8), -1.0f, 1.0f);
907cabdff1aSopenharmony_ci}
908cabdff1aSopenharmony_ci
909cabdff1aSopenharmony_ci
910cabdff1aSopenharmony_ci/**
911cabdff1aSopenharmony_ci * Final part of subpacket decoding:
912cabdff1aSopenharmony_ci *  Apply modulated lapped transform, gain compensation,
913cabdff1aSopenharmony_ci *  clip and convert to integer.
914cabdff1aSopenharmony_ci *
915cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
916cabdff1aSopenharmony_ci * @param decode_buffer     pointer to the mlt coefficients
917cabdff1aSopenharmony_ci * @param gains_ptr         array of current/prev gain pointers
918cabdff1aSopenharmony_ci * @param previous_buffer   pointer to the previous buffer to be used for overlapping
919cabdff1aSopenharmony_ci * @param out               pointer to the output buffer
920cabdff1aSopenharmony_ci */
921cabdff1aSopenharmony_cistatic inline void mlt_compensate_output(COOKContext *q, float *decode_buffer,
922cabdff1aSopenharmony_ci                                         cook_gains *gains_ptr, float *previous_buffer,
923cabdff1aSopenharmony_ci                                         float *out)
924cabdff1aSopenharmony_ci{
925cabdff1aSopenharmony_ci    imlt_gain(q, decode_buffer, gains_ptr, previous_buffer);
926cabdff1aSopenharmony_ci    if (out)
927cabdff1aSopenharmony_ci        q->saturate_output(q, out);
928cabdff1aSopenharmony_ci}
929cabdff1aSopenharmony_ci
930cabdff1aSopenharmony_ci
931cabdff1aSopenharmony_ci/**
932cabdff1aSopenharmony_ci * Cook subpacket decoding. This function returns one decoded subpacket,
933cabdff1aSopenharmony_ci * usually 1024 samples per channel.
934cabdff1aSopenharmony_ci *
935cabdff1aSopenharmony_ci * @param q                 pointer to the COOKContext
936cabdff1aSopenharmony_ci * @param inbuffer          pointer to the inbuffer
937cabdff1aSopenharmony_ci * @param outbuffer         pointer to the outbuffer
938cabdff1aSopenharmony_ci */
939cabdff1aSopenharmony_cistatic int decode_subpacket(COOKContext *q, COOKSubpacket *p,
940cabdff1aSopenharmony_ci                            const uint8_t *inbuffer, float **outbuffer)
941cabdff1aSopenharmony_ci{
942cabdff1aSopenharmony_ci    int sub_packet_size = p->size;
943cabdff1aSopenharmony_ci    int res;
944cabdff1aSopenharmony_ci
945cabdff1aSopenharmony_ci    memset(q->decode_buffer_1, 0, sizeof(q->decode_buffer_1));
946cabdff1aSopenharmony_ci    decode_bytes_and_gain(q, p, inbuffer, &p->gains1);
947cabdff1aSopenharmony_ci
948cabdff1aSopenharmony_ci    if (p->joint_stereo) {
949cabdff1aSopenharmony_ci        if ((res = joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2)) < 0)
950cabdff1aSopenharmony_ci            return res;
951cabdff1aSopenharmony_ci    } else {
952cabdff1aSopenharmony_ci        if ((res = mono_decode(q, p, q->decode_buffer_1)) < 0)
953cabdff1aSopenharmony_ci            return res;
954cabdff1aSopenharmony_ci
955cabdff1aSopenharmony_ci        if (p->num_channels == 2) {
956cabdff1aSopenharmony_ci            decode_bytes_and_gain(q, p, inbuffer + sub_packet_size / 2, &p->gains2);
957cabdff1aSopenharmony_ci            if ((res = mono_decode(q, p, q->decode_buffer_2)) < 0)
958cabdff1aSopenharmony_ci                return res;
959cabdff1aSopenharmony_ci        }
960cabdff1aSopenharmony_ci    }
961cabdff1aSopenharmony_ci
962cabdff1aSopenharmony_ci    mlt_compensate_output(q, q->decode_buffer_1, &p->gains1,
963cabdff1aSopenharmony_ci                          p->mono_previous_buffer1,
964cabdff1aSopenharmony_ci                          outbuffer ? outbuffer[p->ch_idx] : NULL);
965cabdff1aSopenharmony_ci
966cabdff1aSopenharmony_ci    if (p->num_channels == 2) {
967cabdff1aSopenharmony_ci        if (p->joint_stereo)
968cabdff1aSopenharmony_ci            mlt_compensate_output(q, q->decode_buffer_2, &p->gains1,
969cabdff1aSopenharmony_ci                                  p->mono_previous_buffer2,
970cabdff1aSopenharmony_ci                                  outbuffer ? outbuffer[p->ch_idx + 1] : NULL);
971cabdff1aSopenharmony_ci        else
972cabdff1aSopenharmony_ci            mlt_compensate_output(q, q->decode_buffer_2, &p->gains2,
973cabdff1aSopenharmony_ci                                  p->mono_previous_buffer2,
974cabdff1aSopenharmony_ci                                  outbuffer ? outbuffer[p->ch_idx + 1] : NULL);
975cabdff1aSopenharmony_ci    }
976cabdff1aSopenharmony_ci
977cabdff1aSopenharmony_ci    return 0;
978cabdff1aSopenharmony_ci}
979cabdff1aSopenharmony_ci
980cabdff1aSopenharmony_ci
981cabdff1aSopenharmony_cistatic int cook_decode_frame(AVCodecContext *avctx, AVFrame *frame,
982cabdff1aSopenharmony_ci                             int *got_frame_ptr, AVPacket *avpkt)
983cabdff1aSopenharmony_ci{
984cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
985cabdff1aSopenharmony_ci    int buf_size = avpkt->size;
986cabdff1aSopenharmony_ci    COOKContext *q = avctx->priv_data;
987cabdff1aSopenharmony_ci    float **samples = NULL;
988cabdff1aSopenharmony_ci    int i, ret;
989cabdff1aSopenharmony_ci    int offset = 0;
990cabdff1aSopenharmony_ci    int chidx = 0;
991cabdff1aSopenharmony_ci
992cabdff1aSopenharmony_ci    if (buf_size < avctx->block_align)
993cabdff1aSopenharmony_ci        return buf_size;
994cabdff1aSopenharmony_ci
995cabdff1aSopenharmony_ci    /* get output buffer */
996cabdff1aSopenharmony_ci    if (q->discarded_packets >= 2) {
997cabdff1aSopenharmony_ci        frame->nb_samples = q->samples_per_channel;
998cabdff1aSopenharmony_ci        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
999cabdff1aSopenharmony_ci            return ret;
1000cabdff1aSopenharmony_ci        samples = (float **)frame->extended_data;
1001cabdff1aSopenharmony_ci    }
1002cabdff1aSopenharmony_ci
1003cabdff1aSopenharmony_ci    /* estimate subpacket sizes */
1004cabdff1aSopenharmony_ci    q->subpacket[0].size = avctx->block_align;
1005cabdff1aSopenharmony_ci
1006cabdff1aSopenharmony_ci    for (i = 1; i < q->num_subpackets; i++) {
1007cabdff1aSopenharmony_ci        q->subpacket[i].size = 2 * buf[avctx->block_align - q->num_subpackets + i];
1008cabdff1aSopenharmony_ci        q->subpacket[0].size -= q->subpacket[i].size + 1;
1009cabdff1aSopenharmony_ci        if (q->subpacket[0].size < 0) {
1010cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_DEBUG,
1011cabdff1aSopenharmony_ci                   "frame subpacket size total > avctx->block_align!\n");
1012cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
1013cabdff1aSopenharmony_ci        }
1014cabdff1aSopenharmony_ci    }
1015cabdff1aSopenharmony_ci
1016cabdff1aSopenharmony_ci    /* decode supbackets */
1017cabdff1aSopenharmony_ci    for (i = 0; i < q->num_subpackets; i++) {
1018cabdff1aSopenharmony_ci        q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size * 8) >>
1019cabdff1aSopenharmony_ci                                              q->subpacket[i].bits_per_subpdiv;
1020cabdff1aSopenharmony_ci        q->subpacket[i].ch_idx = chidx;
1021cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_DEBUG,
1022cabdff1aSopenharmony_ci               "subpacket[%i] size %i js %i %i block_align %i\n",
1023cabdff1aSopenharmony_ci               i, q->subpacket[i].size, q->subpacket[i].joint_stereo, offset,
1024cabdff1aSopenharmony_ci               avctx->block_align);
1025cabdff1aSopenharmony_ci
1026cabdff1aSopenharmony_ci        if ((ret = decode_subpacket(q, &q->subpacket[i], buf + offset, samples)) < 0)
1027cabdff1aSopenharmony_ci            return ret;
1028cabdff1aSopenharmony_ci        offset += q->subpacket[i].size;
1029cabdff1aSopenharmony_ci        chidx += q->subpacket[i].num_channels;
1030cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_DEBUG, "subpacket[%i] %i %i\n",
1031cabdff1aSopenharmony_ci               i, q->subpacket[i].size * 8, get_bits_count(&q->gb));
1032cabdff1aSopenharmony_ci    }
1033cabdff1aSopenharmony_ci
1034cabdff1aSopenharmony_ci    /* Discard the first two frames: no valid audio. */
1035cabdff1aSopenharmony_ci    if (q->discarded_packets < 2) {
1036cabdff1aSopenharmony_ci        q->discarded_packets++;
1037cabdff1aSopenharmony_ci        *got_frame_ptr = 0;
1038cabdff1aSopenharmony_ci        return avctx->block_align;
1039cabdff1aSopenharmony_ci    }
1040cabdff1aSopenharmony_ci
1041cabdff1aSopenharmony_ci    *got_frame_ptr = 1;
1042cabdff1aSopenharmony_ci
1043cabdff1aSopenharmony_ci    return avctx->block_align;
1044cabdff1aSopenharmony_ci}
1045cabdff1aSopenharmony_ci
1046cabdff1aSopenharmony_cistatic void dump_cook_context(COOKContext *q)
1047cabdff1aSopenharmony_ci{
1048cabdff1aSopenharmony_ci    //int i=0;
1049cabdff1aSopenharmony_ci#define PRINT(a, b) ff_dlog(q->avctx, " %s = %d\n", a, b);
1050cabdff1aSopenharmony_ci    ff_dlog(q->avctx, "COOKextradata\n");
1051cabdff1aSopenharmony_ci    ff_dlog(q->avctx, "cookversion=%x\n", q->subpacket[0].cookversion);
1052cabdff1aSopenharmony_ci    if (q->subpacket[0].cookversion > STEREO) {
1053cabdff1aSopenharmony_ci        PRINT("js_subband_start", q->subpacket[0].js_subband_start);
1054cabdff1aSopenharmony_ci        PRINT("js_vlc_bits", q->subpacket[0].js_vlc_bits);
1055cabdff1aSopenharmony_ci    }
1056cabdff1aSopenharmony_ci    ff_dlog(q->avctx, "COOKContext\n");
1057cabdff1aSopenharmony_ci    PRINT("nb_channels", q->avctx->ch_layout.nb_channels);
1058cabdff1aSopenharmony_ci    PRINT("bit_rate", (int)q->avctx->bit_rate);
1059cabdff1aSopenharmony_ci    PRINT("sample_rate", q->avctx->sample_rate);
1060cabdff1aSopenharmony_ci    PRINT("samples_per_channel", q->subpacket[0].samples_per_channel);
1061cabdff1aSopenharmony_ci    PRINT("subbands", q->subpacket[0].subbands);
1062cabdff1aSopenharmony_ci    PRINT("js_subband_start", q->subpacket[0].js_subband_start);
1063cabdff1aSopenharmony_ci    PRINT("log2_numvector_size", q->subpacket[0].log2_numvector_size);
1064cabdff1aSopenharmony_ci    PRINT("numvector_size", q->subpacket[0].numvector_size);
1065cabdff1aSopenharmony_ci    PRINT("total_subbands", q->subpacket[0].total_subbands);
1066cabdff1aSopenharmony_ci}
1067cabdff1aSopenharmony_ci
1068cabdff1aSopenharmony_ci/**
1069cabdff1aSopenharmony_ci * Cook initialization
1070cabdff1aSopenharmony_ci *
1071cabdff1aSopenharmony_ci * @param avctx     pointer to the AVCodecContext
1072cabdff1aSopenharmony_ci */
1073cabdff1aSopenharmony_cistatic av_cold int cook_decode_init(AVCodecContext *avctx)
1074cabdff1aSopenharmony_ci{
1075cabdff1aSopenharmony_ci    static AVOnce init_static_once = AV_ONCE_INIT;
1076cabdff1aSopenharmony_ci    COOKContext *q = avctx->priv_data;
1077cabdff1aSopenharmony_ci    GetByteContext gb;
1078cabdff1aSopenharmony_ci    int s = 0;
1079cabdff1aSopenharmony_ci    unsigned int channel_mask = 0;
1080cabdff1aSopenharmony_ci    int samples_per_frame = 0;
1081cabdff1aSopenharmony_ci    int ret;
1082cabdff1aSopenharmony_ci    int channels = avctx->ch_layout.nb_channels;
1083cabdff1aSopenharmony_ci
1084cabdff1aSopenharmony_ci    q->avctx = avctx;
1085cabdff1aSopenharmony_ci
1086cabdff1aSopenharmony_ci    /* Take care of the codec specific extradata. */
1087cabdff1aSopenharmony_ci    if (avctx->extradata_size < 8) {
1088cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n");
1089cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
1090cabdff1aSopenharmony_ci    }
1091cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size);
1092cabdff1aSopenharmony_ci
1093cabdff1aSopenharmony_ci    bytestream2_init(&gb, avctx->extradata, avctx->extradata_size);
1094cabdff1aSopenharmony_ci
1095cabdff1aSopenharmony_ci    /* Take data from the AVCodecContext (RM container). */
1096cabdff1aSopenharmony_ci    if (!channels) {
1097cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
1098cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
1099cabdff1aSopenharmony_ci    }
1100cabdff1aSopenharmony_ci
1101cabdff1aSopenharmony_ci    if (avctx->block_align >= INT_MAX / 8)
1102cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
1103cabdff1aSopenharmony_ci
1104cabdff1aSopenharmony_ci    /* Initialize RNG. */
1105cabdff1aSopenharmony_ci    av_lfg_init(&q->random_state, 0);
1106cabdff1aSopenharmony_ci
1107cabdff1aSopenharmony_ci    ff_audiodsp_init(&q->adsp);
1108cabdff1aSopenharmony_ci
1109cabdff1aSopenharmony_ci    while (bytestream2_get_bytes_left(&gb)) {
1110cabdff1aSopenharmony_ci        if (s >= FFMIN(MAX_SUBPACKETS, avctx->block_align)) {
1111cabdff1aSopenharmony_ci            avpriv_request_sample(avctx, "subpackets > %d", FFMIN(MAX_SUBPACKETS, avctx->block_align));
1112cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
1113cabdff1aSopenharmony_ci        }
1114cabdff1aSopenharmony_ci        /* 8 for mono, 16 for stereo, ? for multichannel
1115cabdff1aSopenharmony_ci           Swap to right endianness so we don't need to care later on. */
1116cabdff1aSopenharmony_ci        q->subpacket[s].cookversion      = bytestream2_get_be32(&gb);
1117cabdff1aSopenharmony_ci        samples_per_frame                = bytestream2_get_be16(&gb);
1118cabdff1aSopenharmony_ci        q->subpacket[s].subbands         = bytestream2_get_be16(&gb);
1119cabdff1aSopenharmony_ci        bytestream2_get_be32(&gb);    // Unknown unused
1120cabdff1aSopenharmony_ci        q->subpacket[s].js_subband_start = bytestream2_get_be16(&gb);
1121cabdff1aSopenharmony_ci        if (q->subpacket[s].js_subband_start >= 51) {
1122cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "js_subband_start %d is too large\n", q->subpacket[s].js_subband_start);
1123cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
1124cabdff1aSopenharmony_ci        }
1125cabdff1aSopenharmony_ci        q->subpacket[s].js_vlc_bits      = bytestream2_get_be16(&gb);
1126cabdff1aSopenharmony_ci
1127cabdff1aSopenharmony_ci        /* Initialize extradata related variables. */
1128cabdff1aSopenharmony_ci        q->subpacket[s].samples_per_channel = samples_per_frame / channels;
1129cabdff1aSopenharmony_ci        q->subpacket[s].bits_per_subpacket = avctx->block_align * 8;
1130cabdff1aSopenharmony_ci
1131cabdff1aSopenharmony_ci        /* Initialize default data states. */
1132cabdff1aSopenharmony_ci        q->subpacket[s].log2_numvector_size = 5;
1133cabdff1aSopenharmony_ci        q->subpacket[s].total_subbands = q->subpacket[s].subbands;
1134cabdff1aSopenharmony_ci        q->subpacket[s].num_channels = 1;
1135cabdff1aSopenharmony_ci
1136cabdff1aSopenharmony_ci        /* Initialize version-dependent variables */
1137cabdff1aSopenharmony_ci
1138cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_DEBUG, "subpacket[%i].cookversion=%x\n", s,
1139cabdff1aSopenharmony_ci               q->subpacket[s].cookversion);
1140cabdff1aSopenharmony_ci        q->subpacket[s].joint_stereo = 0;
1141cabdff1aSopenharmony_ci        switch (q->subpacket[s].cookversion) {
1142cabdff1aSopenharmony_ci        case MONO:
1143cabdff1aSopenharmony_ci            if (channels != 1) {
1144cabdff1aSopenharmony_ci                avpriv_request_sample(avctx, "Container channels != 1");
1145cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
1146cabdff1aSopenharmony_ci            }
1147cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_DEBUG, "MONO\n");
1148cabdff1aSopenharmony_ci            break;
1149cabdff1aSopenharmony_ci        case STEREO:
1150cabdff1aSopenharmony_ci            if (channels != 1) {
1151cabdff1aSopenharmony_ci                q->subpacket[s].bits_per_subpdiv = 1;
1152cabdff1aSopenharmony_ci                q->subpacket[s].num_channels = 2;
1153cabdff1aSopenharmony_ci            }
1154cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_DEBUG, "STEREO\n");
1155cabdff1aSopenharmony_ci            break;
1156cabdff1aSopenharmony_ci        case JOINT_STEREO:
1157cabdff1aSopenharmony_ci            if (channels != 2) {
1158cabdff1aSopenharmony_ci                avpriv_request_sample(avctx, "Container channels != 2");
1159cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
1160cabdff1aSopenharmony_ci            }
1161cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n");
1162cabdff1aSopenharmony_ci            if (avctx->extradata_size >= 16) {
1163cabdff1aSopenharmony_ci                q->subpacket[s].total_subbands = q->subpacket[s].subbands +
1164cabdff1aSopenharmony_ci                                                 q->subpacket[s].js_subband_start;
1165cabdff1aSopenharmony_ci                q->subpacket[s].joint_stereo = 1;
1166cabdff1aSopenharmony_ci                q->subpacket[s].num_channels = 2;
1167cabdff1aSopenharmony_ci            }
1168cabdff1aSopenharmony_ci            if (q->subpacket[s].samples_per_channel > 256) {
1169cabdff1aSopenharmony_ci                q->subpacket[s].log2_numvector_size = 6;
1170cabdff1aSopenharmony_ci            }
1171cabdff1aSopenharmony_ci            if (q->subpacket[s].samples_per_channel > 512) {
1172cabdff1aSopenharmony_ci                q->subpacket[s].log2_numvector_size = 7;
1173cabdff1aSopenharmony_ci            }
1174cabdff1aSopenharmony_ci            break;
1175cabdff1aSopenharmony_ci        case MC_COOK:
1176cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n");
1177cabdff1aSopenharmony_ci            channel_mask |= q->subpacket[s].channel_mask = bytestream2_get_be32(&gb);
1178cabdff1aSopenharmony_ci
1179cabdff1aSopenharmony_ci            if (av_popcount64(q->subpacket[s].channel_mask) > 1) {
1180cabdff1aSopenharmony_ci                q->subpacket[s].total_subbands = q->subpacket[s].subbands +
1181cabdff1aSopenharmony_ci                                                 q->subpacket[s].js_subband_start;
1182cabdff1aSopenharmony_ci                q->subpacket[s].joint_stereo = 1;
1183cabdff1aSopenharmony_ci                q->subpacket[s].num_channels = 2;
1184cabdff1aSopenharmony_ci                q->subpacket[s].samples_per_channel = samples_per_frame >> 1;
1185cabdff1aSopenharmony_ci
1186cabdff1aSopenharmony_ci                if (q->subpacket[s].samples_per_channel > 256) {
1187cabdff1aSopenharmony_ci                    q->subpacket[s].log2_numvector_size = 6;
1188cabdff1aSopenharmony_ci                }
1189cabdff1aSopenharmony_ci                if (q->subpacket[s].samples_per_channel > 512) {
1190cabdff1aSopenharmony_ci                    q->subpacket[s].log2_numvector_size = 7;
1191cabdff1aSopenharmony_ci                }
1192cabdff1aSopenharmony_ci            } else
1193cabdff1aSopenharmony_ci                q->subpacket[s].samples_per_channel = samples_per_frame;
1194cabdff1aSopenharmony_ci
1195cabdff1aSopenharmony_ci            break;
1196cabdff1aSopenharmony_ci        default:
1197cabdff1aSopenharmony_ci            avpriv_request_sample(avctx, "Cook version %d",
1198cabdff1aSopenharmony_ci                                  q->subpacket[s].cookversion);
1199cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
1200cabdff1aSopenharmony_ci        }
1201cabdff1aSopenharmony_ci
1202cabdff1aSopenharmony_ci        if (s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) {
1203cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "different number of samples per channel!\n");
1204cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
1205cabdff1aSopenharmony_ci        } else
1206cabdff1aSopenharmony_ci            q->samples_per_channel = q->subpacket[0].samples_per_channel;
1207cabdff1aSopenharmony_ci
1208cabdff1aSopenharmony_ci
1209cabdff1aSopenharmony_ci        /* Initialize variable relations */
1210cabdff1aSopenharmony_ci        q->subpacket[s].numvector_size = (1 << q->subpacket[s].log2_numvector_size);
1211cabdff1aSopenharmony_ci
1212cabdff1aSopenharmony_ci        /* Try to catch some obviously faulty streams, otherwise it might be exploitable */
1213cabdff1aSopenharmony_ci        if (q->subpacket[s].total_subbands > 53) {
1214cabdff1aSopenharmony_ci            avpriv_request_sample(avctx, "total_subbands > 53");
1215cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
1216cabdff1aSopenharmony_ci        }
1217cabdff1aSopenharmony_ci
1218cabdff1aSopenharmony_ci        if ((q->subpacket[s].js_vlc_bits > 6) ||
1219cabdff1aSopenharmony_ci            (q->subpacket[s].js_vlc_bits < 2 * q->subpacket[s].joint_stereo)) {
1220cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "js_vlc_bits = %d, only >= %d and <= 6 allowed!\n",
1221cabdff1aSopenharmony_ci                   q->subpacket[s].js_vlc_bits, 2 * q->subpacket[s].joint_stereo);
1222cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
1223cabdff1aSopenharmony_ci        }
1224cabdff1aSopenharmony_ci
1225cabdff1aSopenharmony_ci        if (q->subpacket[s].subbands > 50) {
1226cabdff1aSopenharmony_ci            avpriv_request_sample(avctx, "subbands > 50");
1227cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
1228cabdff1aSopenharmony_ci        }
1229cabdff1aSopenharmony_ci        if (q->subpacket[s].subbands == 0) {
1230cabdff1aSopenharmony_ci            avpriv_request_sample(avctx, "subbands = 0");
1231cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
1232cabdff1aSopenharmony_ci        }
1233cabdff1aSopenharmony_ci        q->subpacket[s].gains1.now      = q->subpacket[s].gain_1;
1234cabdff1aSopenharmony_ci        q->subpacket[s].gains1.previous = q->subpacket[s].gain_2;
1235cabdff1aSopenharmony_ci        q->subpacket[s].gains2.now      = q->subpacket[s].gain_3;
1236cabdff1aSopenharmony_ci        q->subpacket[s].gains2.previous = q->subpacket[s].gain_4;
1237cabdff1aSopenharmony_ci
1238cabdff1aSopenharmony_ci        if (q->num_subpackets + q->subpacket[s].num_channels > channels) {
1239cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "Too many subpackets %d for channels %d\n", q->num_subpackets, channels);
1240cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
1241cabdff1aSopenharmony_ci        }
1242cabdff1aSopenharmony_ci
1243cabdff1aSopenharmony_ci        q->num_subpackets++;
1244cabdff1aSopenharmony_ci        s++;
1245cabdff1aSopenharmony_ci    }
1246cabdff1aSopenharmony_ci
1247cabdff1aSopenharmony_ci    /* Try to catch some obviously faulty streams, otherwise it might be exploitable */
1248cabdff1aSopenharmony_ci    if (q->samples_per_channel != 256 && q->samples_per_channel != 512 &&
1249cabdff1aSopenharmony_ci        q->samples_per_channel != 1024) {
1250cabdff1aSopenharmony_ci        avpriv_request_sample(avctx, "samples_per_channel = %d",
1251cabdff1aSopenharmony_ci                              q->samples_per_channel);
1252cabdff1aSopenharmony_ci        return AVERROR_PATCHWELCOME;
1253cabdff1aSopenharmony_ci    }
1254cabdff1aSopenharmony_ci
1255cabdff1aSopenharmony_ci    /* Generate tables */
1256cabdff1aSopenharmony_ci    ff_thread_once(&init_static_once, init_pow2table);
1257cabdff1aSopenharmony_ci    init_gain_table(q);
1258cabdff1aSopenharmony_ci    init_cplscales_table(q);
1259cabdff1aSopenharmony_ci
1260cabdff1aSopenharmony_ci    if ((ret = init_cook_vlc_tables(q)))
1261cabdff1aSopenharmony_ci        return ret;
1262cabdff1aSopenharmony_ci
1263cabdff1aSopenharmony_ci    /* Pad the databuffer with:
1264cabdff1aSopenharmony_ci       DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),
1265cabdff1aSopenharmony_ci       AV_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */
1266cabdff1aSopenharmony_ci    q->decoded_bytes_buffer =
1267cabdff1aSopenharmony_ci        av_mallocz(avctx->block_align
1268cabdff1aSopenharmony_ci                   + DECODE_BYTES_PAD1(avctx->block_align)
1269cabdff1aSopenharmony_ci                   + AV_INPUT_BUFFER_PADDING_SIZE);
1270cabdff1aSopenharmony_ci    if (!q->decoded_bytes_buffer)
1271cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
1272cabdff1aSopenharmony_ci
1273cabdff1aSopenharmony_ci    /* Initialize transform. */
1274cabdff1aSopenharmony_ci    if ((ret = init_cook_mlt(q)))
1275cabdff1aSopenharmony_ci        return ret;
1276cabdff1aSopenharmony_ci
1277cabdff1aSopenharmony_ci    /* Initialize COOK signal arithmetic handling */
1278cabdff1aSopenharmony_ci    if (1) {
1279cabdff1aSopenharmony_ci        q->scalar_dequant  = scalar_dequant_float;
1280cabdff1aSopenharmony_ci        q->decouple        = decouple_float;
1281cabdff1aSopenharmony_ci        q->imlt_window     = imlt_window_float;
1282cabdff1aSopenharmony_ci        q->interpolate     = interpolate_float;
1283cabdff1aSopenharmony_ci        q->saturate_output = saturate_output_float;
1284cabdff1aSopenharmony_ci    }
1285cabdff1aSopenharmony_ci
1286cabdff1aSopenharmony_ci    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
1287cabdff1aSopenharmony_ci    av_channel_layout_uninit(&avctx->ch_layout);
1288cabdff1aSopenharmony_ci    if (channel_mask)
1289cabdff1aSopenharmony_ci        av_channel_layout_from_mask(&avctx->ch_layout, channel_mask);
1290cabdff1aSopenharmony_ci    else
1291cabdff1aSopenharmony_ci        av_channel_layout_default(&avctx->ch_layout, channels);
1292cabdff1aSopenharmony_ci
1293cabdff1aSopenharmony_ci
1294cabdff1aSopenharmony_ci    dump_cook_context(q);
1295cabdff1aSopenharmony_ci
1296cabdff1aSopenharmony_ci    return 0;
1297cabdff1aSopenharmony_ci}
1298cabdff1aSopenharmony_ci
1299cabdff1aSopenharmony_ciconst FFCodec ff_cook_decoder = {
1300cabdff1aSopenharmony_ci    .p.name         = "cook",
1301cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"),
1302cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
1303cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_COOK,
1304cabdff1aSopenharmony_ci    .priv_data_size = sizeof(COOKContext),
1305cabdff1aSopenharmony_ci    .init           = cook_decode_init,
1306cabdff1aSopenharmony_ci    .close          = cook_decode_close,
1307cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(cook_decode_frame),
1308cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1,
1309cabdff1aSopenharmony_ci    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
1310cabdff1aSopenharmony_ci                                                      AV_SAMPLE_FMT_NONE },
1311cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1312cabdff1aSopenharmony_ci};
1313