/* * COOK compatible decoder * Copyright (c) 2003 Sascha Sommer * Copyright (c) 2005 Benjamin Larsson * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * Cook compatible decoder. Bastardization of the G.722.1 standard. * This decoder handles RealNetworks, RealAudio G2 data. * Cook is identified by the codec name cook in RM files. * * To use this decoder, a calling application must supply the extradata * bytes provided from the RM container; 8+ bytes for mono streams and * 16+ for stereo streams (maybe more). * * Codec technicalities (all this assume a buffer length of 1024): * Cook works with several different techniques to achieve its compression. * In the timedomain the buffer is divided into 8 pieces and quantized. If * two neighboring pieces have different quantization index a smooth * quantization curve is used to get a smooth overlap between the different * pieces. * To get to the transformdomain Cook uses a modulated lapped transform. * The transform domain has 50 subbands with 20 elements each. This * means only a maximum of 50*20=1000 coefficients are used out of the 1024 * available. */ #include "libavutil/channel_layout.h"#include "libavutil/lfg.h"#include "libavutil/mem.h"#include "libavutil/mem_internal.h"#include "libavutil/thread.h"#include "libavutil/tx.h" #include "audiodsp.h"#include "avcodec.h"#include "get_bits.h"#include "bytestream.h"#include "codec_internal.h"#include "decode.h"#include "sinewin.h"#include "unary.h" #include "cookdata.h" /* the different Cook versions */#define MONO 0x1000001#define STEREO 0x1000002#define JOINT_STEREO 0x1000003#define MC_COOK 0x2000000 #define SUBBAND_SIZE 20#define MAX_SUBPACKETS 5 #define QUANT_VLC_BITS 9#define COUPLING_VLC_BITS 6 typedef struct cook_gains { int *now; int *previous;} cook_gains; typedef struct COOKSubpacket { int ch_idx; int size; int num_channels; int cookversion; int subbands; int js_subband_start; int js_vlc_bits; int samples_per_channel; int log2_numvector_size; unsigned int channel_mask; VLC channel_coupling; int joint_stereo; int bits_per_subpacket; int bits_per_subpdiv; int total_subbands; int numvector_size; // 1 << log2_numvector_size; float mono_previous_buffer1[1024]; float mono_previous_buffer2[1024]; cook_gains gains1; cook_gains gains2; int gain_1[9]; int gain_2[9]; int gain_3[9]; int gain_4[9];} COOKSubpacket; typedef struct cook { /* * The following 5 functions provide the lowlevel arithmetic on * the internal audio buffers. */ void (*scalar_dequant)(struct cook *q, int index, int quant_index, int *subband_coef_index, int *subband_coef_sign, float *mlt_p); void (*decouple)(struct cook *q, COOKSubpacket *p, int subband, float f1, float f2, float *decode_buffer, float *mlt_buffer1, float *mlt_buffer2); void (*imlt_window)(struct cook *q, float *buffer1, cook_gains *gains_ptr, float *previous_buffer); void (*interpolate)(struct cook *q, float *buffer, int gain_index, int gain_index_next); void (*saturate_output)(struct cook *q, float *out); AVCodecContext* avctx; AudioDSPContext adsp; GetBitContext gb; /* stream data */ int num_vectors; int samples_per_channel; /* states */ AVLFG random_state; int discarded_packets; /* transform data */ AVTXContext *mdct_ctx; av_tx_fn mdct_fn; float* mlt_window; /* VLC data */ VLC envelope_quant_index[13]; VLC sqvh[7]; // scalar quantization /* generate tables and related variables */ int gain_size_factor; float gain_table[31]; /* data buffers */ uint8_t* decoded_bytes_buffer; DECLARE_ALIGNED(32, float, mono_mdct_output)[2048]; float decode_buffer_1[1024]; float decode_buffer_2[1024]; float decode_buffer_0[1060]; /* static allocation for joint decode */ const float *cplscales[5]; int num_subpackets; COOKSubpacket subpacket[MAX_SUBPACKETS];} COOKContext; static float pow2tab[127];static float rootpow2tab[127]; /*************** init functions ***************/ /* table generator */static av_cold void init_pow2table(void){ /* fast way of computing 2^i and 2^(0.5*i) for -63 <= i < 64 */ int i; static const float exp2_tab[2] = {1, M_SQRT2}; float exp2_val = powf(2, -63); float root_val = powf(2, -32); for (i = -63; i < 64; i++) { if (!(i & 1)) root_val *= 2; pow2tab[63 + i] = exp2_val; rootpow2tab[63 + i] = root_val * exp2_tab[i & 1]; exp2_val *= 2; }} /* table generator */static av_cold void init_gain_table(COOKContext *q){ int i; q->gain_size_factor = q->samples_per_channel / 8; for (i = 0; i < 31; i++) q->gain_table[i] = pow(pow2tab[i + 48], (1.0 / (double) q->gain_size_factor));} static av_cold int build_vlc(VLC *vlc, int nb_bits, const uint8_t counts[16], const void *syms, int symbol_size, int offset, void *logctx){ uint8_t lens[MAX_COOK_VLC_ENTRIES]; unsigned num = 0; for (int i = 0; i < 16; i++) for (unsigned count = num + counts[i]; num < count; num++) lens[num] = i + 1; return ff_vlc_init_from_lengths(vlc, nb_bits, num, lens, 1, syms, symbol_size, symbol_size, offset, 0, logctx);} static av_cold int init_cook_vlc_tables(COOKContext *q){ int i, result; result = 0; for (i = 0; i < 13; i++) { result |= build_vlc(&q->envelope_quant_index[i], QUANT_VLC_BITS, envelope_quant_index_huffcounts[i], envelope_quant_index_huffsyms[i], 1, -12, q->avctx); } av_log(q->avctx, AV_LOG_DEBUG, "sqvh VLC init\n"); for (i = 0; i < 7; i++) { int sym_size = 1 + (i == 3); result |= build_vlc(&q->sqvh[i], vhvlcsize_tab[i], cvh_huffcounts[i], cvh_huffsyms[i], sym_size, 0, q->avctx); } for (i = 0; i < q->num_subpackets; i++) { if (q->subpacket[i].joint_stereo == 1) { result |= build_vlc(&q->subpacket[i].channel_coupling, COUPLING_VLC_BITS, ccpl_huffcounts[q->subpacket[i].js_vlc_bits - 2], ccpl_huffsyms[q->subpacket[i].js_vlc_bits - 2], 1, 0, q->avctx); av_log(q->avctx, AV_LOG_DEBUG, "subpacket %i Joint-stereo VLC used.\n", i); } } av_log(q->avctx, AV_LOG_DEBUG, "VLC tables initialized.\n"); return result;} static av_cold int init_cook_mlt(COOKContext *q){ int j, ret; int mlt_size = q->samples_per_channel; const float scale = 1.0 / 32768.0; if (!(q->mlt_window = av_malloc_array(mlt_size, sizeof(*q->mlt_window)))) return AVERROR(ENOMEM); /* Initialize the MLT window: simple sine window. */ ff_sine_window_init(q->mlt_window, mlt_size); for (j = 0; j < mlt_size; j++) q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); /* Initialize the MDCT. */ ret = av_tx_init(&q->mdct_ctx, &q->mdct_fn, AV_TX_FLOAT_MDCT, 1, mlt_size, &scale, AV_TX_FULL_IMDCT); if (ret < 0) return ret; return 0;} static av_cold void init_cplscales_table(COOKContext *q){ int i; for (i = 0; i < 5; i++) q->cplscales[i] = cplscales[i];} /*************** init functions end ***********/ #define DECODE_BYTES_PAD1(bytes) (3 - ((bytes) + 3) % 4)#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) /** * Cook indata decoding, every 32 bits are XORed with 0x37c511f2. * Why? No idea, some checksum/error detection method maybe. * * Out buffer size: extra bytes are needed to cope with * padding/misalignment. * Subpackets passed to the decoder can contain two, consecutive * half-subpackets, of identical but arbitrary size. * 1234 1234 1234 1234 extraA extraB * Case 1: AAAA BBBB 0 0 * Case 2: AAAA ABBB BB-- 3 3 * Case 3: AAAA AABB BBBB 2 2 * Case 4: AAAA AAAB BBBB BB-- 1 5 * * Nice way to waste CPU cycles. * * @param inbuffer pointer to byte array of indata * @param out pointer to byte array of outdata * @param bytes number of bytes */static inline int decode_bytes(const uint8_t *inbuffer, uint8_t *out, int bytes){ static const uint32_t tab[4] = { AV_BE2NE32C(0x37c511f2u), AV_BE2NE32C(0xf237c511u), AV_BE2NE32C(0x11f237c5u), AV_BE2NE32C(0xc511f237u), }; int i, off; uint32_t c; const uint32_t *buf; uint32_t *obuf = (uint32_t *) out; /* FIXME: 64 bit platforms would be able to do 64 bits at a time. * I'm too lazy though, should be something like * for (i = 0; i < bitamount / 64; i++) * (int64_t) out[i] = 0x37c511f237c511f2 ^ av_be2ne64(int64_t) in[i]); * Buffer alignment needs to be checked. */ off = (intptr_t) inbuffer & 3; buf = (const uint32_t *) (inbuffer - off); c = tab[off]; bytes += 3 + off; for (i = 0; i < bytes / 4; i++) obuf[i] = c ^ buf[i]; return off;} static av_cold int cook_decode_close(AVCodecContext *avctx){ int i; COOKContext *q = avctx->priv_data; av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n"); /* Free allocated memory buffers. */ av_freep(&q->mlt_window); av_freep(&q->decoded_bytes_buffer); /* Free the transform. */ av_tx_uninit(&q->mdct_ctx); /* Free the VLC tables. */ for (i = 0; i < 13; i++) ff_vlc_free(&q->envelope_quant_index[i]); for (i = 0; i < 7; i++) ff_vlc_free(&q->sqvh[i]); for (i = 0; i < q->num_subpackets; i++) ff_vlc_free(&q->subpacket[i].channel_coupling); av_log(avctx, AV_LOG_DEBUG, "Memory deallocated.\n"); return 0;} /** * Fill the gain array for the timedomain quantization. * * @param gb pointer to the GetBitContext * @param gaininfo array[9] of gain indexes */static void decode_gain_info(GetBitContext *gb, int *gaininfo){ int i, n; n = get_unary(gb, 0, get_bits_left(gb)); // amount of elements*2 to update i = 0; while (n--) { int index = get_bits(gb, 3); int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; while (i <= index) gaininfo[i++] = gain; } while (i <= 8) gaininfo[i++] = 0;} /** * Create the quant index table needed for the envelope. * * @param q pointer to the COOKContext * @param quant_index_table pointer to the array */static int decode_envelope(COOKContext *q, COOKSubpacket *p, int *quant_index_table){ int i, j, vlc_index; quant_index_table[0] = get_bits(&q->gb, 6) - 6; // This is used later in categorize for (i = 1; i < p->total_subbands; i++) { vlc_index = i; if (i >= p->js_subband_start * 2) { vlc_index -= p->js_subband_start; } else { vlc_index /= 2; if (vlc_index < 1) vlc_index = 1; } if (vlc_index > 13) vlc_index = 13; // the VLC tables >13 are identical to No. 13 j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table, QUANT_VLC_BITS, 2); quant_index_table[i] = quant_index_table[i - 1] + j; // differential encoding if (quant_index_table[i] > 63 || quant_index_table[i] < -63) { av_log(q->avctx, AV_LOG_ERROR, "Invalid quantizer %d at position %d, outside [-63, 63] range\n", quant_index_table[i], i); return AVERROR_INVALIDDATA; } } return 0;} /** * Calculate the category and category_index vector. * * @param q pointer to the COOKContext * @param quant_index_table pointer to the array * @param category pointer to the category array * @param category_index pointer to the category_index array */static void categorize(COOKContext *q, COOKSubpacket *p, const int *quant_index_table, int *category, int *category_index){ int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j; int exp_index2[102] = { 0 }; int exp_index1[102] = { 0 }; int tmp_categorize_array[128 * 2] = { 0 }; int tmp_categorize_array1_idx = p->numvector_size; int tmp_categorize_array2_idx = p->numvector_size; bits_left = p->bits_per_subpacket - get_bits_count(&q->gb); if (bits_left > q->samples_per_channel) bits_left = q->samples_per_channel + ((bits_left - q->samples_per_channel) * 5) / 8; bias = -32; /* Estimate bias. */ for (i = 32; i > 0; i = i / 2) { num_bits = 0; index = 0; for (j = p->total_subbands; j > 0; j--) { exp_idx = av_clip_uintp2((i - quant_index_table[index] + bias) / 2, 3); index++; num_bits += expbits_tab[exp_idx]; } if (num_bits >= bits_left - 32) bias += i; } /* Calculate total number of bits. */ num_bits = 0; for (i = 0; i < p->total_subbands; i++) { exp_idx = av_clip_uintp2((bias - quant_index_table[i]) / 2, 3); num_bits += expbits_tab[exp_idx]; exp_index1[i] = exp_idx; exp_index2[i] = exp_idx; } tmpbias1 = tmpbias2 = num_bits; for (j = 1; j < p->numvector_size; j++) { if (tmpbias1 + tmpbias2 > 2 * bits_left) { /* ---> */ int max = -999999; index = -1; for (i = 0; i < p->total_subbands; i++) { if (exp_index1[i] < 7) { v = (-2 * exp_index1[i]) - quant_index_table[i] + bias; if (v >= max) { max = v; index = i; } } } if (index == -1) break; tmp_categorize_array[tmp_categorize_array1_idx++] = index; tmpbias1 -= expbits_tab[exp_index1[index]] - expbits_tab[exp_index1[index] + 1]; ++exp_index1[index]; } else { /* <--- */ int min = 999999; index = -1; for (i = 0; i < p->total_subbands; i++) { if (exp_index2[i] > 0) { v = (-2 * exp_index2[i]) - quant_index_table[i] + bias; if (v < min) { min = v; index = i; } } } if (index == -1)Lines 1–500 of 1314. Load more
/* * COOK compatible decoder * Copyright (c) 2003 Sascha Sommer * Copyright (c) 2005 Benjamin Larsson * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * Cook compatible decoder. Bastardization of the G.722.1 standard. * This decoder handles RealNetworks, RealAudio G2 data. * Cook is identified by the codec name cook in RM files. * * To use this decoder, a calling application must supply the extradata * bytes provided from the RM container; 8+ bytes for mono streams and * 16+ for stereo streams (maybe more). * * Codec technicalities (all this assume a buffer length of 1024): * Cook works with several different techniques to achieve its compression. * In the timedomain the buffer is divided into 8 pieces and quantized. If * two neighboring pieces have different quantization index a smooth * quantization curve is used to get a smooth overlap between the different * pieces. * To get to the transformdomain Cook uses a modulated lapped transform. * The transform domain has 50 subbands with 20 elements each. This * means only a maximum of 50*20=1000 coefficients are used out of the 1024 * available. */ #include "libavutil/channel_layout.h" #include "libavutil/lfg.h" #include "libavutil/mem.h" #include "libavutil/mem_internal.h" #include "libavutil/thread.h" #include "libavutil/tx.h" #include "audiodsp.h" #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" #include "codec_internal.h" #include "decode.h" #include "sinewin.h" #include "unary.h" #include "cookdata.h" /* the different Cook versions */ #define MONO 0x1000001 #define STEREO 0x1000002 #define JOINT_STEREO 0x1000003 #define MC_COOK 0x2000000 #define SUBBAND_SIZE 20 #define MAX_SUBPACKETS 5 #define QUANT_VLC_BITS 9 #define COUPLING_VLC_BITS 6 typedef struct cook_gains { int *now; int *previous; } cook_gains; typedef struct COOKSubpacket { int ch_idx; int size; int num_channels; int cookversion; int subbands; int js_subband_start; int js_vlc_bits; int samples_per_channel; int log2_numvector_size; unsigned int channel_mask; VLC channel_coupling; int joint_stereo; int bits_per_subpacket; int bits_per_subpdiv; int total_subbands; int numvector_size; // 1 << log2_numvector_size; float mono_previous_buffer1[1024]; float mono_previous_buffer2[1024]; cook_gains gains1; cook_gains gains2; int gain_1[9]; int gain_2[9]; int gain_3[9]; int gain_4[9]; } COOKSubpacket; typedef struct cook { /* * The following 5 functions provide the lowlevel arithmetic on * the internal audio buffers. */ void (*scalar_dequant)(struct cook *q, int index, int quant_index, int *subband_coef_index, int *subband_coef_sign, float *mlt_p); void (*decouple)(struct cook *q, COOKSubpacket *p, int subband, float f1, float f2, float *decode_buffer, float *mlt_buffer1, float *mlt_buffer2); void (*imlt_window)(struct cook *q, float *buffer1, cook_gains *gains_ptr, float *previous_buffer); void (*interpolate)(struct cook *q, float *buffer, int gain_index, int gain_index_next); void (*saturate_output)(struct cook *q, float *out); AVCodecContext* avctx; AudioDSPContext adsp; GetBitContext gb; /* stream data */ int num_vectors; int samples_per_channel; /* states */ AVLFG random_state; int discarded_packets; /* transform data */ AVTXContext *mdct_ctx; av_tx_fn mdct_fn; float* mlt_window; /* VLC data */ VLC envelope_quant_index[13]; VLC sqvh[7]; // scalar quantization /* generate tables and related variables */ int gain_size_factor; float gain_table[31]; /* data buffers */ uint8_t* decoded_bytes_buffer; DECLARE_ALIGNED(32, float, mono_mdct_output)[2048]; float decode_buffer_1[1024]; float decode_buffer_2[1024]; float decode_buffer_0[1060]; /* static allocation for joint decode */ const float *cplscales[5]; int num_subpackets; COOKSubpacket subpacket[MAX_SUBPACKETS]; } COOKContext; static float pow2tab[127]; static float rootpow2tab[127]; /*************** init functions ***************/ /* table generator */ static av_cold void init_pow2table(void) { /* fast way of computing 2^i and 2^(0.5*i) for -63 <= i < 64 */ int i; static const float exp2_tab[2] = {1, M_SQRT2}; float exp2_val = powf(2, -63); float root_val = powf(2, -32); for (i = -63; i < 64; i++) { if (!(i & 1)) root_val *= 2; pow2tab[63 + i] = exp2_val; rootpow2tab[63 + i] = root_val * exp2_tab[i & 1]; exp2_val *= 2; } } /* table generator */ static av_cold void init_gain_table(COOKContext *q) { int i; q->gain_size_factor = q->samples_per_channel / 8; for (i = 0; i < 31; i++) q->gain_table[i] = pow(pow2tab[i + 48], (1.0 / (double) q->gain_size_factor)); } static av_cold int build_vlc(VLC *vlc, int nb_bits, const uint8_t counts[16], const void *syms, int symbol_size, int offset, void *logctx) { uint8_t lens[MAX_COOK_VLC_ENTRIES]; unsigned num = 0; for (int i = 0; i < 16; i++) for (unsigned count = num + counts[i]; num < count; num++) lens[num] = i + 1; return ff_vlc_init_from_lengths(vlc, nb_bits, num, lens, 1, syms, symbol_size, symbol_size, offset, 0, logctx); } static av_cold int init_cook_vlc_tables(COOKContext *q) { int i, result; result = 0; for (i = 0; i < 13; i++) { result |= build_vlc(&q->envelope_quant_index[i], QUANT_VLC_BITS, envelope_quant_index_huffcounts[i], envelope_quant_index_huffsyms[i], 1, -12, q->avctx); } av_log(q->avctx, AV_LOG_DEBUG, "sqvh VLC init\n"); for (i = 0; i < 7; i++) { int sym_size = 1 + (i == 3); result |= build_vlc(&q->sqvh[i], vhvlcsize_tab[i], cvh_huffcounts[i], cvh_huffsyms[i], sym_size, 0, q->avctx); } for (i = 0; i < q->num_subpackets; i++) { if (q->subpacket[i].joint_stereo == 1) { result |= build_vlc(&q->subpacket[i].channel_coupling, COUPLING_VLC_BITS, ccpl_huffcounts[q->subpacket[i].js_vlc_bits - 2], ccpl_huffsyms[q->subpacket[i].js_vlc_bits - 2], 1, 0, q->avctx); av_log(q->avctx, AV_LOG_DEBUG, "subpacket %i Joint-stereo VLC used.\n", i); } } av_log(q->avctx, AV_LOG_DEBUG, "VLC tables initialized.\n"); return result; } static av_cold int init_cook_mlt(COOKContext *q) { int j, ret; int mlt_size = q->samples_per_channel; const float scale = 1.0 / 32768.0; if (!(q->mlt_window = av_malloc_array(mlt_size, sizeof(*q->mlt_window)))) return AVERROR(ENOMEM); /* Initialize the MLT window: simple sine window. */ ff_sine_window_init(q->mlt_window, mlt_size); for (j = 0; j < mlt_size; j++) q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); /* Initialize the MDCT. */ ret = av_tx_init(&q->mdct_ctx, &q->mdct_fn, AV_TX_FLOAT_MDCT, 1, mlt_size, &scale, AV_TX_FULL_IMDCT); if (ret < 0) return ret; return 0; } static av_cold void init_cplscales_table(COOKContext *q) { int i; for (i = 0; i < 5; i++) q->cplscales[i] = cplscales[i]; } /*************** init functions end ***********/ #define DECODE_BYTES_PAD1(bytes) (3 - ((bytes) + 3) % 4) #define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) /** * Cook indata decoding, every 32 bits are XORed with 0x37c511f2. * Why? No idea, some checksum/error detection method maybe. * * Out buffer size: extra bytes are needed to cope with * padding/misalignment. * Subpackets passed to the decoder can contain two, consecutive * half-subpackets, of identical but arbitrary size. * 1234 1234 1234 1234 extraA extraB * Case 1: AAAA BBBB 0 0 * Case 2: AAAA ABBB BB-- 3 3 * Case 3: AAAA AABB BBBB 2 2 * Case 4: AAAA AAAB BBBB BB-- 1 5 * * Nice way to waste CPU cycles. * * @param inbuffer pointer to byte array of indata * @param out pointer to byte array of outdata * @param bytes number of bytes */ static inline int decode_bytes(const uint8_t *inbuffer, uint8_t *out, int bytes) { static const uint32_t tab[4] = { AV_BE2NE32C(0x37c511f2u), AV_BE2NE32C(0xf237c511u), AV_BE2NE32C(0x11f237c5u), AV_BE2NE32C(0xc511f237u), }; int i, off; uint32_t c; const uint32_t *buf; uint32_t *obuf = (uint32_t *) out; /* FIXME: 64 bit platforms would be able to do 64 bits at a time. * I'm too lazy though, should be something like * for (i = 0; i < bitamount / 64; i++) * (int64_t) out[i] = 0x37c511f237c511f2 ^ av_be2ne64(int64_t) in[i]); * Buffer alignment needs to be checked. */ off = (intptr_t) inbuffer & 3; buf = (const uint32_t *) (inbuffer - off); c = tab[off]; bytes += 3 + off; for (i = 0; i < bytes / 4; i++) obuf[i] = c ^ buf[i]; return off; } static av_cold int cook_decode_close(AVCodecContext *avctx) { int i; COOKContext *q = avctx->priv_data; av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n"); /* Free allocated memory buffers. */ av_freep(&q->mlt_window); av_freep(&q->decoded_bytes_buffer); /* Free the transform. */ av_tx_uninit(&q->mdct_ctx); /* Free the VLC tables. */ for (i = 0; i < 13; i++) ff_vlc_free(&q->envelope_quant_index[i]); for (i = 0; i < 7; i++) ff_vlc_free(&q->sqvh[i]); for (i = 0; i < q->num_subpackets; i++) ff_vlc_free(&q->subpacket[i].channel_coupling); av_log(avctx, AV_LOG_DEBUG, "Memory deallocated.\n"); return 0; } /** * Fill the gain array for the timedomain quantization. * * @param gb pointer to the GetBitContext * @param gaininfo array[9] of gain indexes */ static void decode_gain_info(GetBitContext *gb, int *gaininfo) { int i, n; n = get_unary(gb, 0, get_bits_left(gb)); // amount of elements*2 to update i = 0; while (n--) { int index = get_bits(gb, 3); int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; while (i <= index) gaininfo[i++] = gain; } while (i <= 8) gaininfo[i++] = 0; } /** * Create the quant index table needed for the envelope. * * @param q pointer to the COOKContext * @param quant_index_table pointer to the array */ static int decode_envelope(COOKContext *q, COOKSubpacket *p, int *quant_index_table) { int i, j, vlc_index; quant_index_table[0] = get_bits(&q->gb, 6) - 6; // This is used later in categorize for (i = 1; i < p->total_subbands; i++) { vlc_index = i; if (i >= p->js_subband_start * 2) { vlc_index -= p->js_subband_start; } else { vlc_index /= 2; if (vlc_index < 1) vlc_index = 1; } if (vlc_index > 13) vlc_index = 13; // the VLC tables >13 are identical to No. 13 j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table, QUANT_VLC_BITS, 2); quant_index_table[i] = quant_index_table[i - 1] + j; // differential encoding if (quant_index_table[i] > 63 || quant_index_table[i] < -63) { av_log(q->avctx, AV_LOG_ERROR, "Invalid quantizer %d at position %d, outside [-63, 63] range\n", quant_index_table[i], i); return AVERROR_INVALIDDATA; } } return 0; } /** * Calculate the category and category_index vector. * * @param q pointer to the COOKContext * @param quant_index_table pointer to the array * @param category pointer to the category array * @param category_index pointer to the category_index array */ static void categorize(COOKContext *q, COOKSubpacket *p, const int *quant_index_table, int *category, int *category_index) { int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j; int exp_index2[102] = { 0 }; int exp_index1[102] = { 0 }; int tmp_categorize_array[128 * 2] = { 0 }; int tmp_categorize_array1_idx = p->numvector_size; int tmp_categorize_array2_idx = p->numvector_size; bits_left = p->bits_per_subpacket - get_bits_count(&q->gb); if (bits_left > q->samples_per_channel) bits_left = q->samples_per_channel + ((bits_left - q->samples_per_channel) * 5) / 8; bias = -32; /* Estimate bias. */ for (i = 32; i > 0; i = i / 2) { num_bits = 0; index = 0; for (j = p->total_subbands; j > 0; j--) { exp_idx = av_clip_uintp2((i - quant_index_table[index] + bias) / 2, 3); index++; num_bits += expbits_tab[exp_idx]; } if (num_bits >= bits_left - 32) bias += i; } /* Calculate total number of bits. */ num_bits = 0; for (i = 0; i < p->total_subbands; i++) { exp_idx = av_clip_uintp2((bias - quant_index_table[i]) / 2, 3); num_bits += expbits_tab[exp_idx]; exp_index1[i] = exp_idx; exp_index2[i] = exp_idx; } tmpbias1 = tmpbias2 = num_bits; for (j = 1; j < p->numvector_size; j++) { if (tmpbias1 + tmpbias2 > 2 * bits_left) { /* ---> */ int max = -999999; index = -1; for (i = 0; i < p->total_subbands; i++) { if (exp_index1[i] < 7) { v = (-2 * exp_index1[i]) - quant_index_table[i] + bias; if (v >= max) { max = v; index = i; } } } if (index == -1) break; tmp_categorize_array[tmp_categorize_array1_idx++] = index; tmpbias1 -= expbits_tab[exp_index1[index]] - expbits_tab[exp_index1[index] + 1]; ++exp_index1[index]; } else { /* <--- */ int min = 999999; index = -1; for (i = 0; i < p->total_subbands; i++) { if (exp_index2[i] > 0) { v = (-2 * exp_index2[i]) - quant_index_table[i] + bias; if (v < min) { min = v; index = i; } } } if (index == -1)