cook.c File Reference

#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include "libavutil/random.h"
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"
#include "bytestream.h"
#include "cookdata.h"

Go to the source code of this file.

Data Structures

struct  cook_gains
struct  cook

Defines

#define MONO   0x1000001
#define STEREO   0x1000002
#define JOINT_STEREO   0x1000003
#define MC_COOK   0x2000000
#define SUBBAND_SIZE   20
#define DECODE_BYTES_PAD1(bytes)   (3 - ((bytes)+3) % 4)
#define DECODE_BYTES_PAD2(bytes)   ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes)))

Typedefs

typedef cook COOKContext

Functions

static void init_pow2table (void)
static void init_gain_table (COOKContext *q)
static int init_cook_vlc_tables (COOKContext *q)
static int init_cook_mlt (COOKContext *q)
static const float * maybe_reformat_buffer32 (COOKContext *q, const float *ptr, int n)
static void init_cplscales_table (COOKContext *q)
static int decode_bytes (const uint8_t *inbuffer, uint8_t *out, int bytes)
static int cook_decode_close (AVCodecContext *avctx)
static void decode_gain_info (GetBitContext *gb, int *gaininfo)
static void decode_envelope (COOKContext *q, int *quant_index_table)
static void categorize (COOKContext *q, int *quant_index_table, int *category, int *category_index)
static void expand_category (COOKContext *q, int *category, int *category_index)
static void scalar_dequant_float (COOKContext *q, int index, int quant_index, int *subband_coef_index, int *subband_coef_sign, float *mlt_p)
static int unpack_SQVH (COOKContext *q, int category, int *subband_coef_index, int *subband_coef_sign)
static void decode_vectors (COOKContext *q, int *category, int *quant_index_table, float *mlt_buffer)
static void mono_decode (COOKContext *q, float *mlt_buffer)
static void interpolate_float (COOKContext *q, float *buffer, int gain_index, int gain_index_next)
static void imlt_window_float (COOKContext *q, float *buffer1, cook_gains *gains_ptr, float *previous_buffer)
static void imlt_gain (COOKContext *q, float *inbuffer, cook_gains *gains_ptr, float *previous_buffer)
static void decouple_info (COOKContext *q, int *decouple_tab)
static void decouple_float (COOKContext *q, int subband, float f1, float f2, float *decode_buffer, float *mlt_buffer1, float *mlt_buffer2)
static void joint_decode (COOKContext *q, float *mlt_buffer1, float *mlt_buffer2)
static void decode_bytes_and_gain (COOKContext *q, const uint8_t *inbuffer, cook_gains *gains_ptr)
static void saturate_output_float (COOKContext *q, int chan, int16_t *out)
static void mlt_compensate_output (COOKContext *q, float *decode_buffer, cook_gains *gains, float *previous_buffer, int16_t *out, int chan)
static int decode_subpacket (COOKContext *q, const uint8_t *inbuffer, int sub_packet_size, int16_t *outbuffer)
static int cook_decode_frame (AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
static int cook_decode_init (AVCodecContext *avctx)

Variables

static float pow2tab [127]
static float rootpow2tab [127]
AVCodec cook_decoder


Detailed Description

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.

Definition in file cook.c.


Define Documentation

#define DECODE_BYTES_PAD1 ( bytes   )     (3 - ((bytes)+3) % 4)

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.

Parameters:
inbuffer pointer to byte array of indata
out pointer to byte array of outdata
bytes number of bytes

Definition at line 290 of file cook.c.

Referenced by cook_decode_init().

#define DECODE_BYTES_PAD2 ( bytes   )     ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes)))

Definition at line 291 of file cook.c.

Referenced by cook_decode_init().

#define JOINT_STEREO   0x1000003

Definition at line 60 of file cook.c.

#define MC_COOK   0x2000000

Definition at line 61 of file cook.c.

Referenced by cook_decode_init().

#define MONO   0x1000001

Definition at line 58 of file cook.c.

Referenced by cook_decode_init().

#define STEREO   0x1000002

Definition at line 59 of file cook.c.

#define SUBBAND_SIZE   20

Definition at line 63 of file cook.c.

Referenced by decode_vectors(), decouple_float(), joint_decode(), and scalar_dequant_float().


Typedef Documentation

typedef struct cook COOKContext


Function Documentation

static void categorize ( COOKContext q,
int *  quant_index_table,
int *  category,
int *  category_index 
) [static]

Calculate the category and category_index vector.

Parameters:
q pointer to the COOKContext
quant_index_table pointer to the array
category pointer to the category array
category_index pointer to the category_index array

Definition at line 408 of file cook.c.

References av_clip(), cook::bits_per_subpacket, expbits_tab, cook::gb, get_bits_count(), cook::numvector_size, cook::samples_per_channel, and cook::total_subbands.

Referenced by mono_decode().

00409                                                           {
00410     int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j;
00411     int exp_index2[102];
00412     int exp_index1[102];
00413 
00414     int tmp_categorize_array[128*2];
00415     int tmp_categorize_array1_idx=q->numvector_size;
00416     int tmp_categorize_array2_idx=q->numvector_size;
00417 
00418     bits_left =  q->bits_per_subpacket - get_bits_count(&q->gb);
00419 
00420     if(bits_left > q->samples_per_channel) {
00421         bits_left = q->samples_per_channel +
00422                     ((bits_left - q->samples_per_channel)*5)/8;
00423         //av_log(NULL, AV_LOG_ERROR, "bits_left = %d\n",bits_left);
00424     }
00425 
00426     memset(&exp_index1,0,102*sizeof(int));
00427     memset(&exp_index2,0,102*sizeof(int));
00428     memset(&tmp_categorize_array,0,128*2*sizeof(int));
00429 
00430     bias=-32;
00431 
00432     /* Estimate bias. */
00433     for (i=32 ; i>0 ; i=i/2){
00434         num_bits = 0;
00435         index = 0;
00436         for (j=q->total_subbands ; j>0 ; j--){
00437             exp_idx = av_clip((i - quant_index_table[index] + bias) / 2, 0, 7);
00438             index++;
00439             num_bits+=expbits_tab[exp_idx];
00440         }
00441         if(num_bits >= bits_left - 32){
00442             bias+=i;
00443         }
00444     }
00445 
00446     /* Calculate total number of bits. */
00447     num_bits=0;
00448     for (i=0 ; i<q->total_subbands ; i++) {
00449         exp_idx = av_clip((bias - quant_index_table[i]) / 2, 0, 7);
00450         num_bits += expbits_tab[exp_idx];
00451         exp_index1[i] = exp_idx;
00452         exp_index2[i] = exp_idx;
00453     }
00454     tmpbias1 = tmpbias2 = num_bits;
00455 
00456     for (j = 1 ; j < q->numvector_size ; j++) {
00457         if (tmpbias1 + tmpbias2 > 2*bits_left) {  /* ---> */
00458             int max = -999999;
00459             index=-1;
00460             for (i=0 ; i<q->total_subbands ; i++){
00461                 if (exp_index1[i] < 7) {
00462                     v = (-2*exp_index1[i]) - quant_index_table[i] + bias;
00463                     if ( v >= max) {
00464                         max = v;
00465                         index = i;
00466                     }
00467                 }
00468             }
00469             if(index==-1)break;
00470             tmp_categorize_array[tmp_categorize_array1_idx++] = index;
00471             tmpbias1 -= expbits_tab[exp_index1[index]] -
00472                         expbits_tab[exp_index1[index]+1];
00473             ++exp_index1[index];
00474         } else {  /* <--- */
00475             int min = 999999;
00476             index=-1;
00477             for (i=0 ; i<q->total_subbands ; i++){
00478                 if(exp_index2[i] > 0){
00479                     v = (-2*exp_index2[i])-quant_index_table[i]+bias;
00480                     if ( v < min) {
00481                         min = v;
00482                         index = i;
00483                     }
00484                 }
00485             }
00486             if(index == -1)break;
00487             tmp_categorize_array[--tmp_categorize_array2_idx] = index;
00488             tmpbias2 -= expbits_tab[exp_index2[index]] -
00489                         expbits_tab[exp_index2[index]-1];
00490             --exp_index2[index];
00491         }
00492     }
00493 
00494     for(i=0 ; i<q->total_subbands ; i++)
00495         category[i] = exp_index2[i];
00496 
00497     for(i=0 ; i<q->numvector_size-1 ; i++)
00498         category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++];
00499 
00500 }

static int cook_decode_close ( AVCodecContext avctx  )  [static]

Cook uninit

Definition at line 318 of file cook.c.

References av_free(), av_log(), AV_LOG_DEBUG, cook::ccpl, cook::decoded_bytes_buffer, cook::envelope_quant_index, ff_mdct_end(), free_vlc(), cook::joint_stereo, cook::mdct_ctx, cook::mlt_window, cook::nb_channels, AVCodecContext::priv_data, and cook::sqvh.

00319 {
00320     int i;
00321     COOKContext *q = avctx->priv_data;
00322     av_log(avctx,AV_LOG_DEBUG, "Deallocating memory.\n");
00323 
00324     /* Free allocated memory buffers. */
00325     av_free(q->mlt_window);
00326     av_free(q->decoded_bytes_buffer);
00327 
00328     /* Free the transform. */
00329     ff_mdct_end(&q->mdct_ctx);
00330 
00331     /* Free the VLC tables. */
00332     for (i=0 ; i<13 ; i++) {
00333         free_vlc(&q->envelope_quant_index[i]);
00334     }
00335     for (i=0 ; i<7 ; i++) {
00336         free_vlc(&q->sqvh[i]);
00337     }
00338     if(q->nb_channels==2 && q->joint_stereo==1 ){
00339         free_vlc(&q->ccpl);
00340     }
00341 
00342     av_log(NULL,AV_LOG_DEBUG,"Memory deallocated.\n");
00343 
00344     return 0;
00345 }

static int cook_decode_frame ( AVCodecContext avctx,
void *  data,
int *  data_size,
const uint8_t *  buf,
int  buf_size 
) [static]

Cook frame decoding

Parameters:
avctx pointer to the AVCodecContext

Definition at line 979 of file cook.c.

References AVCodecContext::block_align, decode_subpacket(), AVCodecContext::frame_number, and AVCodecContext::priv_data.

00981                                               {
00982     COOKContext *q = avctx->priv_data;
00983 
00984     if (buf_size < avctx->block_align)
00985         return buf_size;
00986 
00987     *data_size = decode_subpacket(q, buf, avctx->block_align, data);
00988 
00989     /* Discard the first two frames: no valid audio. */
00990     if (avctx->frame_number < 2) *data_size = 0;
00991 
00992     return avctx->block_align;
00993 }

static int cook_decode_init ( AVCodecContext avctx  )  [static]

Cook initialization

Parameters:
avctx pointer to the AVCodecContext

Definition at line 1027 of file cook.c.

References av_init_random(), av_log(), AV_LOG_DEBUG, AV_LOG_ERROR, av_mallocz(), AVCodecContext::bit_rate, cook::bit_rate, cook::bits_per_subpacket, AVCodecContext::block_align, AVCodecContext::channels, cook::cookversion, DECODE_BYTES_PAD1, DECODE_BYTES_PAD2, cook::decoded_bytes_buffer, cook::decouple, decouple_float(), AVCodecContext::extradata, AVCodecContext::extradata_size, FF_INPUT_BUFFER_PADDING_SIZE, cook::gain_1, cook::gain_2, cook::gain_3, cook::gain_4, cook::gains1, cook::gains2, cook::imlt_window, imlt_window_float(), init_cook_mlt(), init_cook_vlc_tables(), init_cplscales_table(), init_gain_table(), init_pow2table(), cook::interpolate, interpolate_float(), JOINT_STEREO, cook::joint_stereo, cook::js_subband_start, cook::js_vlc_bits, cook::log2_numvector_size, MC_COOK, MONO, cook::nb_channels, cook_gains::now, NULL, cook::numvector_size, cook_gains::previous, AVCodecContext::priv_data, cook::random_state, AVCodecContext::sample_rate, cook::sample_rate, cook::samples_per_channel, cook::samples_per_frame, cook::saturate_output, saturate_output_float(), cook::scalar_dequant, scalar_dequant_float(), STEREO, cook::subbands, and cook::total_subbands.

01028 {
01029     COOKContext *q = avctx->priv_data;
01030     const uint8_t *edata_ptr = avctx->extradata;
01031 
01032     /* Take care of the codec specific extradata. */
01033     if (avctx->extradata_size <= 0) {
01034         av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n");
01035         return -1;
01036     } else {
01037         /* 8 for mono, 16 for stereo, ? for multichannel
01038            Swap to right endianness so we don't need to care later on. */
01039         av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size);
01040         if (avctx->extradata_size >= 8){
01041             q->cookversion = bytestream_get_be32(&edata_ptr);
01042             q->samples_per_frame =  bytestream_get_be16(&edata_ptr);
01043             q->subbands = bytestream_get_be16(&edata_ptr);
01044         }
01045         if (avctx->extradata_size >= 16){
01046             bytestream_get_be32(&edata_ptr);    //Unknown unused
01047             q->js_subband_start = bytestream_get_be16(&edata_ptr);
01048             q->js_vlc_bits = bytestream_get_be16(&edata_ptr);
01049         }
01050     }
01051 
01052     /* Take data from the AVCodecContext (RM container). */
01053     q->sample_rate = avctx->sample_rate;
01054     q->nb_channels = avctx->channels;
01055     q->bit_rate = avctx->bit_rate;
01056 
01057     /* Initialize RNG. */
01058     av_init_random(1, &q->random_state);
01059 
01060     /* Initialize extradata related variables. */
01061     q->samples_per_channel = q->samples_per_frame / q->nb_channels;
01062     q->bits_per_subpacket = avctx->block_align * 8;
01063 
01064     /* Initialize default data states. */
01065     q->log2_numvector_size = 5;
01066     q->total_subbands = q->subbands;
01067 
01068     /* Initialize version-dependent variables */
01069     av_log(NULL,AV_LOG_DEBUG,"q->cookversion=%x\n",q->cookversion);
01070     q->joint_stereo = 0;
01071     switch (q->cookversion) {
01072         case MONO:
01073             if (q->nb_channels != 1) {
01074                 av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n");
01075                 return -1;
01076             }
01077             av_log(avctx,AV_LOG_DEBUG,"MONO\n");
01078             break;
01079         case STEREO:
01080             if (q->nb_channels != 1) {
01081                 q->bits_per_subpacket = q->bits_per_subpacket/2;
01082             }
01083             av_log(avctx,AV_LOG_DEBUG,"STEREO\n");
01084             break;
01085         case JOINT_STEREO:
01086             if (q->nb_channels != 2) {
01087                 av_log(avctx,AV_LOG_ERROR,"Container channels != 2, report sample!\n");
01088                 return -1;
01089             }
01090             av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n");
01091             if (avctx->extradata_size >= 16){
01092                 q->total_subbands = q->subbands + q->js_subband_start;
01093                 q->joint_stereo = 1;
01094             }
01095             if (q->samples_per_channel > 256) {
01096                 q->log2_numvector_size  = 6;
01097             }
01098             if (q->samples_per_channel > 512) {
01099                 q->log2_numvector_size  = 7;
01100             }
01101             break;
01102         case MC_COOK:
01103             av_log(avctx,AV_LOG_ERROR,"MC_COOK not supported!\n");
01104             return -1;
01105             break;
01106         default:
01107             av_log(avctx,AV_LOG_ERROR,"Unknown Cook version, report sample!\n");
01108             return -1;
01109             break;
01110     }
01111 
01112     /* Initialize variable relations */
01113     q->numvector_size = (1 << q->log2_numvector_size);
01114 
01115     /* Generate tables */
01116     init_pow2table();
01117     init_gain_table(q);
01118     init_cplscales_table(q);
01119 
01120     if (init_cook_vlc_tables(q) != 0)
01121         return -1;
01122 
01123 
01124     if(avctx->block_align >= UINT_MAX/2)
01125         return -1;
01126 
01127     /* Pad the databuffer with:
01128        DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),
01129        FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */
01130     if (q->nb_channels==2 && q->joint_stereo==0) {
01131         q->decoded_bytes_buffer =
01132           av_mallocz(avctx->block_align/2
01133                      + DECODE_BYTES_PAD2(avctx->block_align/2)
01134                      + FF_INPUT_BUFFER_PADDING_SIZE);
01135     } else {
01136         q->decoded_bytes_buffer =
01137           av_mallocz(avctx->block_align
01138                      + DECODE_BYTES_PAD1(avctx->block_align)
01139                      + FF_INPUT_BUFFER_PADDING_SIZE);
01140     }
01141     if (q->decoded_bytes_buffer == NULL)
01142         return -1;
01143 
01144     q->gains1.now      = q->gain_1;
01145     q->gains1.previous = q->gain_2;
01146     q->gains2.now      = q->gain_3;
01147     q->gains2.previous = q->gain_4;
01148 
01149     /* Initialize transform. */
01150     if ( init_cook_mlt(q) != 0 )
01151         return -1;
01152 
01153     /* Initialize COOK signal arithmetic handling */
01154     if (1) {
01155         q->scalar_dequant  = scalar_dequant_float;
01156         q->decouple        = decouple_float;
01157         q->imlt_window     = imlt_window_float;
01158         q->interpolate     = interpolate_float;
01159         q->saturate_output = saturate_output_float;
01160     }
01161 
01162     /* Try to catch some obviously faulty streams, othervise it might be exploitable */
01163     if (q->total_subbands > 53) {
01164         av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n");
01165         return -1;
01166     }
01167     if (q->subbands > 50) {
01168         av_log(avctx,AV_LOG_ERROR,"subbands > 50, report sample!\n");
01169         return -1;
01170     }
01171     if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) {
01172     } else {
01173         av_log(avctx,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel);
01174         return -1;
01175     }
01176     if ((q->js_vlc_bits > 6) || (q->js_vlc_bits < 0)) {
01177         av_log(avctx,AV_LOG_ERROR,"q->js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->js_vlc_bits);
01178         return -1;
01179     }
01180 
01181 #ifdef COOKDEBUG
01182     dump_cook_context(q);
01183 #endif
01184     return 0;
01185 }

static int decode_bytes ( const uint8_t *  inbuffer,
uint8_t *  out,
int  bytes 
) [inline, static]

Definition at line 293 of file cook.c.

References be2me_32, c, and off.

00293                                                                                 {
00294     int i, off;
00295     uint32_t c;
00296     const uint32_t* buf;
00297     uint32_t* obuf = (uint32_t*) out;
00298     /* FIXME: 64 bit platforms would be able to do 64 bits at a time.
00299      * I'm too lazy though, should be something like
00300      * for(i=0 ; i<bitamount/64 ; i++)
00301      *     (int64_t)out[i] = 0x37c511f237c511f2^be2me_64(int64_t)in[i]);
00302      * Buffer alignment needs to be checked. */
00303 
00304     off = (int)((long)inbuffer & 3);
00305     buf = (const uint32_t*) (inbuffer - off);
00306     c = be2me_32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8))));
00307     bytes += 3 + off;
00308     for (i = 0; i < bytes/4; i++)
00309         obuf[i] = c ^ buf[i];
00310 
00311     return off;
00312 }

static void decode_bytes_and_gain ( COOKContext q,
const uint8_t *  inbuffer,
cook_gains gains_ptr 
) [inline, static]

First part of subpacket decoding: decode raw stream bytes and read gain info.

Parameters:
q pointer to the COOKContext
inbuffer pointer to raw stream data
gain_ptr array of current/prev gain pointers

Definition at line 867 of file cook.c.

References cook::bits_per_subpacket, decode_bytes(), decode_gain_info(), cook::decoded_bytes_buffer, FFSWAP, cook::gb, init_get_bits(), cook_gains::now, offset, and cook_gains::previous.

Referenced by decode_subpacket().

00869 {
00870     int offset;
00871 
00872     offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,
00873                           q->bits_per_subpacket/8);
00874     init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
00875                   q->bits_per_subpacket);
00876     decode_gain_info(&q->gb, gains_ptr->now);
00877 
00878     /* Swap current and previous gains */
00879     FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
00880 }

static void decode_envelope ( COOKContext q,
int *  quant_index_table 
) [static]

Create the quant index table needed for the envelope.

Parameters:
q pointer to the COOKContext
quant_index_table pointer to the array

Definition at line 378 of file cook.c.

References VLC::bits, cook::envelope_quant_index, cook::gb, get_bits(), get_vlc2(), cook::js_subband_start, VLC::table, and cook::total_subbands.

Referenced by mono_decode().

00378                                                                     {
00379     int i,j, vlc_index;
00380 
00381     quant_index_table[0]= get_bits(&q->gb,6) - 6;       //This is used later in categorize
00382 
00383     for (i=1 ; i < q->total_subbands ; i++){
00384         vlc_index=i;
00385         if (i >= q->js_subband_start * 2) {
00386             vlc_index-=q->js_subband_start;
00387         } else {
00388             vlc_index/=2;
00389             if(vlc_index < 1) vlc_index = 1;
00390         }
00391         if (vlc_index>13) vlc_index = 13;           //the VLC tables >13 are identical to No. 13
00392 
00393         j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index-1].table,
00394                      q->envelope_quant_index[vlc_index-1].bits,2);
00395         quant_index_table[i] = quant_index_table[i-1] + j - 12;    //differential encoding
00396     }
00397 }

static void decode_gain_info ( GetBitContext gb,
int *  gaininfo 
) [static]

Fill the gain array for the timedomain quantization.

Parameters:
q pointer to the COOKContext
gaininfo[9] array of gain indexes

Definition at line 354 of file cook.c.

References cook::gb, get_bits(), get_bits1(), and get_bits_count().

Referenced by decode_bytes_and_gain().

00355 {
00356     int i, n;
00357 
00358     while (get_bits1(gb)) {}
00359     n = get_bits_count(gb) - 1;     //amount of elements*2 to update
00360 
00361     i = 0;
00362     while (n--) {
00363         int index = get_bits(gb, 3);
00364         int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1;
00365 
00366         while (i <= index) gaininfo[i++] = gain;
00367     }
00368     while (i <= 8) gaininfo[i++] = 0;
00369 }

static int decode_subpacket ( COOKContext q,
const uint8_t *  inbuffer,
int  sub_packet_size,
int16_t *  outbuffer 
) [static]

Cook subpacket decoding. This function returns one decoded subpacket, usually 1024 samples per channel.

Parameters:
q pointer to the COOKContext
inbuffer pointer to the inbuffer
sub_packet_size subpacket size
outbuffer pointer to the outbuffer

Definition at line 936 of file cook.c.

References cook::decode_buffer_1, cook::decode_buffer_2, decode_bytes_and_gain(), cook::gains1, cook::gains2, joint_decode(), cook::joint_stereo, mlt_compensate_output(), mono_decode(), cook::mono_previous_buffer1, cook::mono_previous_buffer2, cook::nb_channels, and cook::samples_per_frame.

Referenced by cook_decode_frame().

00937                                                                      {
00938     /* packet dump */
00939 //    for (i=0 ; i<sub_packet_size ; i++) {
00940 //        av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
00941 //    }
00942 //    av_log(NULL, AV_LOG_ERROR, "\n");
00943 
00944     decode_bytes_and_gain(q, inbuffer, &q->gains1);
00945 
00946     if (q->joint_stereo) {
00947         joint_decode(q, q->decode_buffer_1, q->decode_buffer_2);
00948     } else {
00949         mono_decode(q, q->decode_buffer_1);
00950 
00951         if (q->nb_channels == 2) {
00952             decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2);
00953             mono_decode(q, q->decode_buffer_2);
00954         }
00955     }
00956 
00957     mlt_compensate_output(q, q->decode_buffer_1, &q->gains1,
00958                           q->mono_previous_buffer1, outbuffer, 0);
00959 
00960     if (q->nb_channels == 2) {
00961         if (q->joint_stereo) {
00962             mlt_compensate_output(q, q->decode_buffer_2, &q->gains1,
00963                                   q->mono_previous_buffer2, outbuffer, 1);
00964         } else {
00965             mlt_compensate_output(q, q->decode_buffer_2, &q->gains2,
00966                                   q->mono_previous_buffer2, outbuffer, 1);
00967         }
00968     }
00969     return q->samples_per_frame * sizeof(int16_t);
00970 }

static void decode_vectors ( COOKContext q,
int *  category,
int *  quant_index_table,
float *  mlt_buffer 
) [static]

Fill the mlt_buffer with mlt coefficients.

Parameters:
q pointer to the COOKContext
category pointer to the category array
quant_index_table pointer to the array
mlt_buffer pointer to mlt coefficients

Definition at line 602 of file cook.c.

References cook::samples_per_channel, cook::scalar_dequant, SUBBAND_SIZE, cook::total_subbands, and unpack_SQVH().

Referenced by mono_decode().

00603                                                                      {
00604     /* A zero in this table means that the subband coefficient is
00605        random noise coded. */
00606     int subband_coef_index[SUBBAND_SIZE];
00607     /* A zero in this table means that the subband coefficient is a
00608        positive multiplicator. */
00609     int subband_coef_sign[SUBBAND_SIZE];
00610     int band, j;
00611     int index=0;
00612 
00613     for(band=0 ; band<q->total_subbands ; band++){
00614         index = category[band];
00615         if(category[band] < 7){
00616             if(unpack_SQVH(q, category[band], subband_coef_index, subband_coef_sign)){
00617                 index=7;
00618                 for(j=0 ; j<q->total_subbands ; j++) category[band+j]=7;
00619             }
00620         }
00621         if(index==7) {
00622             memset(subband_coef_index, 0, sizeof(subband_coef_index));
00623             memset(subband_coef_sign, 0, sizeof(subband_coef_sign));
00624         }
00625         q->scalar_dequant(q, index, quant_index_table[band],
00626                           subband_coef_index, subband_coef_sign,
00627                           &mlt_buffer[band * SUBBAND_SIZE]);
00628     }
00629 
00630     if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){
00631         return;
00632     } /* FIXME: should this be removed, or moved into loop above? */
00633 }

static void decouple_float ( COOKContext q,
int  subband,
float  f1,
float  f2,
float *  decode_buffer,
float *  mlt_buffer1,
float *  mlt_buffer2 
) [static]

Definition at line 795 of file cook.c.

References cook::js_subband_start, and SUBBAND_SIZE.

Referenced by cook_decode_init().

00800 {
00801     int j, tmp_idx;
00802     for (j=0 ; j<SUBBAND_SIZE ; j++) {
00803         tmp_idx = ((q->js_subband_start + subband)*SUBBAND_SIZE)+j;
00804         mlt_buffer1[SUBBAND_SIZE*subband + j] = f1 * decode_buffer[tmp_idx];
00805         mlt_buffer2[SUBBAND_SIZE*subband + j] = f2 * decode_buffer[tmp_idx];
00806     }
00807 }

static void decouple_info ( COOKContext q,
int *  decouple_tab 
) [static]

function for getting the jointstereo coupling information

Parameters:
q pointer to the COOKContext
decouple_tab decoupling array

Definition at line 762 of file cook.c.

References VLC::bits, cook::ccpl, cplband, for(), cook::gb, get_bits(), get_bits1(), get_vlc2(), cook::js_subband_start, cook::js_vlc_bits, cook::subbands, and VLC::table.

Referenced by joint_decode().

00762                                                             {
00763     int length, i;
00764 
00765     if(get_bits1(&q->gb)) {
00766         if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return;
00767 
00768         length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1;
00769         for (i=0 ; i<length ; i++) {
00770             decouple_tab[cplband[q->js_subband_start] + i] = get_vlc2(&q->gb, q->ccpl.table, q->ccpl.bits, 2);
00771         }
00772         return;
00773     }
00774 
00775     if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return;
00776 
00777     length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1;
00778     for (i=0 ; i<length ; i++) {
00779        decouple_tab[cplband[q->js_subband_start] + i] = get_bits(&q->gb, q->js_vlc_bits);
00780     }
00781     return;
00782 }

static void expand_category ( COOKContext q,
int *  category,
int *  category_index 
) [inline, static]

Expand the category vector.

Parameters:
q pointer to the COOKContext
category pointer to the category array
category_index pointer to the category_index array

Definition at line 511 of file cook.c.

References cook::num_vectors.

Referenced by mono_decode().

00512                                                        {
00513     int i;
00514     for(i=0 ; i<q->num_vectors ; i++){
00515         ++category[category_index[i]];
00516     }
00517 }

static void imlt_gain ( COOKContext q,
float *  inbuffer,
cook_gains gains_ptr,
float *  previous_buffer 
) [static]

The modulated lapped transform, this takes transform coefficients and transforms them into timedomain samples. Apply transform window, overlap buffers, apply gain profile and buffer management.

Parameters:
q pointer to the COOKContext
inbuffer pointer to the mltcoefficients
gains_ptr current and previous gains
previous_buffer pointer to the previous buffer to be used for overlapping

Definition at line 729 of file cook.c.

References MDCTContext::fft, cook::gain_size_factor, FFTContext::imdct_calc, cook::imlt_window, cook::interpolate, cook::mdct_ctx, cook_gains::now, and cook::samples_per_channel.

Referenced by mlt_compensate_output().

00731 {
00732     float *buffer0 = q->mono_mdct_output;
00733     float *buffer1 = q->mono_mdct_output + q->samples_per_channel;
00734     int i;
00735 
00736     /* Inverse modified discrete cosine transform */
00737     q->mdct_ctx.fft.imdct_calc(&q->mdct_ctx, q->mono_mdct_output,
00738                                inbuffer, q->mdct_tmp);
00739 
00740     q->imlt_window (q, buffer1, gains_ptr, previous_buffer);
00741 
00742     /* Apply gain profile */
00743     for (i = 0; i < 8; i++) {
00744         if (gains_ptr->now[i] || gains_ptr->now[i + 1])
00745             q->interpolate(q, &buffer1[q->gain_size_factor * i],
00746                            gains_ptr->now[i], gains_ptr->now[i + 1]);
00747     }
00748 
00749     /* Save away the current to be previous block. */
00750     memcpy(previous_buffer, buffer0, sizeof(float)*q->samples_per_channel);
00751 }

static void imlt_window_float ( COOKContext q,
float *  buffer1,
cook_gains gains_ptr,
float *  previous_buffer 
) [static]

Apply transform window, overlap buffers.

Parameters:
q pointer to the COOKContext
inbuffer pointer to the mltcoefficients
gains_ptr current and previous gains
previous_buffer pointer to the previous buffer to be used for overlapping

Definition at line 699 of file cook.c.

References cook::mlt_window, pow2tab, cook_gains::previous, and cook::samples_per_channel.

Referenced by cook_decode_init().

00701 {
00702     const float fc = pow2tab[gains_ptr->previous[0] + 63];
00703     int i;
00704     /* The weird thing here, is that the two halves of the time domain
00705      * buffer are swapped. Also, the newest data, that we save away for
00706      * next frame, has the wrong sign. Hence the subtraction below.
00707      * Almost sounds like a complex conjugate/reverse data/FFT effect.
00708      */
00709 
00710     /* Apply window and overlap */
00711     for(i = 0; i < q->samples_per_channel; i++){
00712         buffer1[i] = buffer1[i] * fc * q->mlt_window[i] -
00713           previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i];
00714     }
00715 }

static int init_cook_mlt ( COOKContext q  )  [static]

Definition at line 233 of file cook.c.

References av_free(), av_log(), av_log2(), AV_LOG_DEBUG, av_malloc(), ff_mdct_init(), ff_sine_window_init(), cook::mdct_ctx, cook::mlt_window, NULL, and cook::samples_per_channel.

Referenced by cook_decode_init().

00233                                          {
00234     int j;
00235     int mlt_size = q->samples_per_channel;
00236 
00237     if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0)
00238       return -1;
00239 
00240     /* Initialize the MLT window: simple sine window. */
00241     ff_sine_window_init(q->mlt_window, mlt_size);
00242     for(j=0 ; j<mlt_size ; j++)
00243         q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel);
00244 
00245     /* Initialize the MDCT. */
00246     if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1)) {
00247       av_free(q->mlt_window);
00248       return -1;
00249     }
00250     av_log(NULL,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n",
00251            av_log2(mlt_size)+1);
00252 
00253     return 0;
00254 }

static int init_cook_vlc_tables ( COOKContext q  )  [static]

Definition at line 206 of file cook.c.

References av_log(), AV_LOG_DEBUG, cook::ccpl, ccpl_huffbits, ccpl_huffcodes, cvh_huffbits, cvh_huffcodes, cook::envelope_quant_index, envelope_quant_index_huffbits, envelope_quant_index_huffcodes, init_vlc, cook::joint_stereo, cook::js_vlc_bits, cook::nb_channels, NULL, cook::sqvh, vhsize_tab, and vhvlcsize_tab.

Referenced by cook_decode_init().

00206                                                 {
00207     int i, result;
00208 
00209     result = 0;
00210     for (i=0 ; i<13 ; i++) {
00211         result |= init_vlc (&q->envelope_quant_index[i], 9, 24,
00212