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