#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 |
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 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.
| 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))) |
| #define MC_COOK 0x2000000 |
| #define MONO 0x1000001 |
| #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 struct cook COOKContext |
| static void categorize | ( | COOKContext * | q, | |
| int * | quant_index_table, | |||
| int * | category, | |||
| int * | category_index | |||
| ) | [static] |
Calculate the category and category_index vector.
| 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
| 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
| 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.
| 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.
| 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.
| 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.
| 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.
| 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
| 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.
| 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.
| 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.
| 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