ffmpeg / libavcodec / cook.c @ f66e4f5f
History | View | Annotate | Download (40.6 KB)
1 |
/*
|
---|---|
2 |
* COOK compatible decoder
|
3 |
* Copyright (c) 2003 Sascha Sommer
|
4 |
* Copyright (c) 2005 Benjamin Larsson
|
5 |
*
|
6 |
* This file is part of FFmpeg.
|
7 |
*
|
8 |
* FFmpeg is free software; you can redistribute it and/or
|
9 |
* modify it under the terms of the GNU Lesser General Public
|
10 |
* License as published by the Free Software Foundation; either
|
11 |
* version 2.1 of the License, or (at your option) any later version.
|
12 |
*
|
13 |
* FFmpeg is distributed in the hope that it will be useful,
|
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16 |
* Lesser General Public License for more details.
|
17 |
*
|
18 |
* You should have received a copy of the GNU Lesser General Public
|
19 |
* License along with FFmpeg; if not, write to the Free Software
|
20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 |
*
|
22 |
*/
|
23 |
|
24 |
/**
|
25 |
* @file cook.c
|
26 |
* Cook compatible decoder.
|
27 |
* This decoder handles RealNetworks, RealAudio G2 data.
|
28 |
* Cook is identified by the codec name cook in RM files.
|
29 |
*
|
30 |
* To use this decoder, a calling application must supply the extradata
|
31 |
* bytes provided from the RM container; 8+ bytes for mono streams and
|
32 |
* 16+ for stereo streams (maybe more).
|
33 |
*
|
34 |
* Codec technicalities (all this assume a buffer length of 1024):
|
35 |
* Cook works with several different techniques to achieve its compression.
|
36 |
* In the timedomain the buffer is divided into 8 pieces and quantized. If
|
37 |
* two neighboring pieces have different quantization index a smooth
|
38 |
* quantization curve is used to get a smooth overlap between the different
|
39 |
* pieces.
|
40 |
* To get to the transformdomain Cook uses a modulated lapped transform.
|
41 |
* The transform domain has 50 subbands with 20 elements each. This
|
42 |
* means only a maximum of 50*20=1000 coefficients are used out of the 1024
|
43 |
* available.
|
44 |
*/
|
45 |
|
46 |
#include <math.h> |
47 |
#include <stddef.h> |
48 |
#include <stdio.h> |
49 |
|
50 |
#include "avcodec.h" |
51 |
#include "bitstream.h" |
52 |
#include "dsputil.h" |
53 |
#include "common.h" |
54 |
#include "bytestream.h" |
55 |
|
56 |
#include "cookdata.h" |
57 |
|
58 |
/* the different Cook versions */
|
59 |
#define MONO 0x1000001 |
60 |
#define STEREO 0x1000002 |
61 |
#define JOINT_STEREO 0x1000003 |
62 |
#define MC_COOK 0x2000000 //multichannel Cook, not supported |
63 |
|
64 |
#define SUBBAND_SIZE 20 |
65 |
//#define COOKDEBUG
|
66 |
|
67 |
typedef struct { |
68 |
int size;
|
69 |
int loccode[8]; |
70 |
int levcode[8]; |
71 |
} COOKgain; |
72 |
|
73 |
typedef struct { |
74 |
GetBitContext gb; |
75 |
/* stream data */
|
76 |
int nb_channels;
|
77 |
int joint_stereo;
|
78 |
int bit_rate;
|
79 |
int sample_rate;
|
80 |
int samples_per_channel;
|
81 |
int samples_per_frame;
|
82 |
int subbands;
|
83 |
int log2_numvector_size;
|
84 |
int numvector_size; //1 << log2_numvector_size; |
85 |
int js_subband_start;
|
86 |
int total_subbands;
|
87 |
int num_vectors;
|
88 |
int bits_per_subpacket;
|
89 |
int cookversion;
|
90 |
/* states */
|
91 |
int random_state;
|
92 |
|
93 |
/* transform data */
|
94 |
FFTContext fft_ctx; |
95 |
DECLARE_ALIGNED_16(FFTSample, mlt_tmp[1024]); /* temporary storage for imlt */ |
96 |
float* mlt_window;
|
97 |
float* mlt_precos;
|
98 |
float* mlt_presin;
|
99 |
float* mlt_postcos;
|
100 |
int fft_size;
|
101 |
int fft_order;
|
102 |
int mlt_size; //modulated lapped transform size |
103 |
|
104 |
/* gain buffers */
|
105 |
COOKgain *gain_ptr1[2];
|
106 |
COOKgain *gain_ptr2[2];
|
107 |
COOKgain gain_1; |
108 |
COOKgain gain_2; |
109 |
COOKgain gain_3; |
110 |
COOKgain gain_4; |
111 |
|
112 |
/* VLC data */
|
113 |
int js_vlc_bits;
|
114 |
VLC envelope_quant_index[13];
|
115 |
VLC sqvh[7]; //scalar quantization |
116 |
VLC ccpl; //channel coupling
|
117 |
|
118 |
/* generatable tables and related variables */
|
119 |
int gain_size_factor;
|
120 |
float gain_table[23]; |
121 |
float pow2tab[127]; |
122 |
float rootpow2tab[127]; |
123 |
|
124 |
/* data buffers */
|
125 |
|
126 |
uint8_t* decoded_bytes_buffer; |
127 |
DECLARE_ALIGNED_16(float,mono_mdct_output[2048]); |
128 |
float mono_previous_buffer1[1024]; |
129 |
float mono_previous_buffer2[1024]; |
130 |
float decode_buffer_1[1024]; |
131 |
float decode_buffer_2[1024]; |
132 |
} COOKContext; |
133 |
|
134 |
/* debug functions */
|
135 |
|
136 |
#ifdef COOKDEBUG
|
137 |
static void dump_float_table(float* table, int size, int delimiter) { |
138 |
int i=0; |
139 |
av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); |
140 |
for (i=0 ; i<size ; i++) { |
141 |
av_log(NULL, AV_LOG_ERROR, "%5.1f, ", table[i]); |
142 |
if ((i+1)%delimiter == 0) av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i+1); |
143 |
} |
144 |
} |
145 |
|
146 |
static void dump_int_table(int* table, int size, int delimiter) { |
147 |
int i=0; |
148 |
av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); |
149 |
for (i=0 ; i<size ; i++) { |
150 |
av_log(NULL, AV_LOG_ERROR, "%d, ", table[i]); |
151 |
if ((i+1)%delimiter == 0) av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i+1); |
152 |
} |
153 |
} |
154 |
|
155 |
static void dump_short_table(short* table, int size, int delimiter) { |
156 |
int i=0; |
157 |
av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); |
158 |
for (i=0 ; i<size ; i++) { |
159 |
av_log(NULL, AV_LOG_ERROR, "%d, ", table[i]); |
160 |
if ((i+1)%delimiter == 0) av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i+1); |
161 |
} |
162 |
} |
163 |
|
164 |
#endif
|
165 |
|
166 |
/*************** init functions ***************/
|
167 |
|
168 |
/* table generator */
|
169 |
static void init_pow2table(COOKContext *q){ |
170 |
int i;
|
171 |
q->pow2tab[63] = 1.0; |
172 |
for (i=1 ; i<64 ; i++){ |
173 |
q->pow2tab[63+i]=(float)((uint64_t)1<<i); |
174 |
q->pow2tab[63-i]=1.0/(float)((uint64_t)1<<i); |
175 |
} |
176 |
} |
177 |
|
178 |
/* table generator */
|
179 |
static void init_rootpow2table(COOKContext *q){ |
180 |
int i;
|
181 |
q->rootpow2tab[63] = 1.0; |
182 |
for (i=1 ; i<64 ; i++){ |
183 |
q->rootpow2tab[63+i]=sqrt((float)((uint64_t)1<<i)); |
184 |
q->rootpow2tab[63-i]=sqrt(1.0/(float)((uint64_t)1<<i)); |
185 |
} |
186 |
} |
187 |
|
188 |
/* table generator */
|
189 |
static void init_gain_table(COOKContext *q) { |
190 |
int i;
|
191 |
q->gain_size_factor = q->samples_per_channel/8;
|
192 |
for (i=0 ; i<23 ; i++) { |
193 |
q->gain_table[i] = pow((double)q->pow2tab[i+52] , |
194 |
(1.0/(double)q->gain_size_factor)); |
195 |
} |
196 |
} |
197 |
|
198 |
|
199 |
static int init_cook_vlc_tables(COOKContext *q) { |
200 |
int i, result;
|
201 |
|
202 |
result = 0;
|
203 |
for (i=0 ; i<13 ; i++) { |
204 |
result &= init_vlc (&q->envelope_quant_index[i], 9, 24, |
205 |
envelope_quant_index_huffbits[i], 1, 1, |
206 |
envelope_quant_index_huffcodes[i], 2, 2, 0); |
207 |
} |
208 |
av_log(NULL,AV_LOG_DEBUG,"sqvh VLC init\n"); |
209 |
for (i=0 ; i<7 ; i++) { |
210 |
result &= init_vlc (&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], |
211 |
cvh_huffbits[i], 1, 1, |
212 |
cvh_huffcodes[i], 2, 2, 0); |
213 |
} |
214 |
|
215 |
if (q->nb_channels==2 && q->joint_stereo==1){ |
216 |
result &= init_vlc (&q->ccpl, 6, (1<<q->js_vlc_bits)-1, |
217 |
ccpl_huffbits[q->js_vlc_bits-2], 1, 1, |
218 |
ccpl_huffcodes[q->js_vlc_bits-2], 2, 2, 0); |
219 |
av_log(NULL,AV_LOG_DEBUG,"Joint-stereo VLC used.\n"); |
220 |
} |
221 |
|
222 |
av_log(NULL,AV_LOG_DEBUG,"VLC tables initialized.\n"); |
223 |
return result;
|
224 |
} |
225 |
|
226 |
static int init_cook_mlt(COOKContext *q) { |
227 |
int j;
|
228 |
float alpha;
|
229 |
|
230 |
/* Allocate the buffers, could be replaced with a static [512]
|
231 |
array if needed. */
|
232 |
q->mlt_size = q->samples_per_channel; |
233 |
q->mlt_window = av_malloc(sizeof(float)*q->mlt_size); |
234 |
q->mlt_precos = av_malloc(sizeof(float)*q->mlt_size/2); |
235 |
q->mlt_presin = av_malloc(sizeof(float)*q->mlt_size/2); |
236 |
q->mlt_postcos = av_malloc(sizeof(float)*q->mlt_size/2); |
237 |
|
238 |
/* Initialize the MLT window: simple sine window. */
|
239 |
alpha = M_PI / (2.0 * (float)q->mlt_size); |
240 |
for(j=0 ; j<q->mlt_size ; j++) { |
241 |
q->mlt_window[j] = sin((j + 512.0/(float)q->mlt_size) * alpha); |
242 |
} |
243 |
|
244 |
/* pre/post twiddle factors */
|
245 |
for (j=0 ; j<q->mlt_size/2 ; j++){ |
246 |
q->mlt_precos[j] = cos( ((j+0.25)*M_PI)/q->mlt_size); |
247 |
q->mlt_presin[j] = sin( ((j+0.25)*M_PI)/q->mlt_size); |
248 |
q->mlt_postcos[j] = (float)sqrt(2.0/(float)q->mlt_size)*cos( ((float)j*M_PI) /q->mlt_size); //sqrt(2/MLT_size) = scalefactor |
249 |
} |
250 |
|
251 |
/* Initialize the FFT. */
|
252 |
ff_fft_init(&q->fft_ctx, av_log2(q->mlt_size)-1, 0); |
253 |
av_log(NULL,AV_LOG_DEBUG,"FFT initialized, order = %d.\n", |
254 |
av_log2(q->samples_per_channel)-1);
|
255 |
|
256 |
return (int)(q->mlt_window && q->mlt_precos && q->mlt_presin && q->mlt_postcos); |
257 |
} |
258 |
|
259 |
/*************** init functions end ***********/
|
260 |
|
261 |
/**
|
262 |
* Cook indata decoding, every 32 bits are XORed with 0x37c511f2.
|
263 |
* Why? No idea, some checksum/error detection method maybe.
|
264 |
*
|
265 |
* Out buffer size: extra bytes are needed to cope with
|
266 |
* padding/missalignment.
|
267 |
* Subpackets passed to the decoder can contain two, consecutive
|
268 |
* half-subpackets, of identical but arbitrary size.
|
269 |
* 1234 1234 1234 1234 extraA extraB
|
270 |
* Case 1: AAAA BBBB 0 0
|
271 |
* Case 2: AAAA ABBB BB-- 3 3
|
272 |
* Case 3: AAAA AABB BBBB 2 2
|
273 |
* Case 4: AAAA AAAB BBBB BB-- 1 5
|
274 |
*
|
275 |
* Nice way to waste CPU cycles.
|
276 |
*
|
277 |
* @param inbuffer pointer to byte array of indata
|
278 |
* @param out pointer to byte array of outdata
|
279 |
* @param bytes number of bytes
|
280 |
*/
|
281 |
#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes)+3) % 4) |
282 |
#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) |
283 |
|
284 |
static inline int decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ |
285 |
int i, off;
|
286 |
uint32_t c; |
287 |
uint32_t* buf; |
288 |
uint32_t* obuf = (uint32_t*) out; |
289 |
/* FIXME: 64 bit platforms would be able to do 64 bits at a time.
|
290 |
* I'm too lazy though, should be something like
|
291 |
* for(i=0 ; i<bitamount/64 ; i++)
|
292 |
* (int64_t)out[i] = 0x37c511f237c511f2^be2me_64(int64_t)in[i]);
|
293 |
* Buffer alignment needs to be checked. */
|
294 |
|
295 |
off = (int)((long)inbuffer & 3); |
296 |
buf = (uint32_t*) (inbuffer - off); |
297 |
c = be2me_32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8)))); |
298 |
bytes += 3 + off;
|
299 |
for (i = 0; i < bytes/4; i++) |
300 |
obuf[i] = c ^ buf[i]; |
301 |
|
302 |
return off;
|
303 |
} |
304 |
|
305 |
/**
|
306 |
* Cook uninit
|
307 |
*/
|
308 |
|
309 |
static int cook_decode_close(AVCodecContext *avctx) |
310 |
{ |
311 |
int i;
|
312 |
COOKContext *q = avctx->priv_data; |
313 |
av_log(avctx,AV_LOG_DEBUG, "Deallocating memory.\n");
|
314 |
|
315 |
/* Free allocated memory buffers. */
|
316 |
av_free(q->mlt_window); |
317 |
av_free(q->mlt_precos); |
318 |
av_free(q->mlt_presin); |
319 |
av_free(q->mlt_postcos); |
320 |
av_free(q->decoded_bytes_buffer); |
321 |
|
322 |
/* Free the transform. */
|
323 |
ff_fft_end(&q->fft_ctx); |
324 |
|
325 |
/* Free the VLC tables. */
|
326 |
for (i=0 ; i<13 ; i++) { |
327 |
free_vlc(&q->envelope_quant_index[i]); |
328 |
} |
329 |
for (i=0 ; i<7 ; i++) { |
330 |
free_vlc(&q->sqvh[i]); |
331 |
} |
332 |
if(q->nb_channels==2 && q->joint_stereo==1 ){ |
333 |
free_vlc(&q->ccpl); |
334 |
} |
335 |
|
336 |
av_log(NULL,AV_LOG_DEBUG,"Memory deallocated.\n"); |
337 |
|
338 |
return 0; |
339 |
} |
340 |
|
341 |
/**
|
342 |
* Fill the COOKgain structure for the timedomain quantization.
|
343 |
*
|
344 |
* @param q pointer to the COOKContext
|
345 |
* @param gaininfo pointer to the COOKgain
|
346 |
*/
|
347 |
|
348 |
static void decode_gain_info(GetBitContext *gb, COOKgain* gaininfo) { |
349 |
int i;
|
350 |
|
351 |
while (get_bits1(gb)) {}
|
352 |
|
353 |
gaininfo->size = get_bits_count(gb) - 1; //amount of elements*2 to update |
354 |
|
355 |
if (get_bits_count(gb) - 1 <= 0) return; |
356 |
|
357 |
for (i=0 ; i<gaininfo->size ; i++){ |
358 |
gaininfo->loccode[i] = get_bits(gb,3);
|
359 |
if (get_bits1(gb)) {
|
360 |
gaininfo->levcode[i] = get_bits(gb,4) - 7; //convert to signed |
361 |
} else {
|
362 |
gaininfo->levcode[i] = -1;
|
363 |
} |
364 |
} |
365 |
} |
366 |
|
367 |
/**
|
368 |
* Create the quant index table needed for the envelope.
|
369 |
*
|
370 |
* @param q pointer to the COOKContext
|
371 |
* @param quant_index_table pointer to the array
|
372 |
*/
|
373 |
|
374 |
static void decode_envelope(COOKContext *q, int* quant_index_table) { |
375 |
int i,j, vlc_index;
|
376 |
int bitbias;
|
377 |
|
378 |
bitbias = get_bits_count(&q->gb); |
379 |
quant_index_table[0]= get_bits(&q->gb,6) - 6; //This is used later in categorize |
380 |
|
381 |
for (i=1 ; i < q->total_subbands ; i++){ |
382 |
vlc_index=i; |
383 |
if (i >= q->js_subband_start * 2) { |
384 |
vlc_index-=q->js_subband_start; |
385 |
} else {
|
386 |
vlc_index/=2;
|
387 |
if(vlc_index < 1) vlc_index = 1; |
388 |
} |
389 |
if (vlc_index>13) vlc_index = 13; //the VLC tables >13 are identical to No. 13 |
390 |
|
391 |
j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index-1].table,
|
392 |
q->envelope_quant_index[vlc_index-1].bits,2); |
393 |
quant_index_table[i] = quant_index_table[i-1] + j - 12; //differential encoding |
394 |
} |
395 |
} |
396 |
|
397 |
/**
|
398 |
* Create the quant value table.
|
399 |
*
|
400 |
* @param q pointer to the COOKContext
|
401 |
* @param quant_value_table pointer to the array
|
402 |
*/
|
403 |
|
404 |
static void inline dequant_envelope(COOKContext *q, int* quant_index_table, |
405 |
float* quant_value_table){
|
406 |
|
407 |
int i;
|
408 |
for(i=0 ; i < q->total_subbands ; i++){ |
409 |
quant_value_table[i] = q->rootpow2tab[quant_index_table[i]+63];
|
410 |
} |
411 |
} |
412 |
|
413 |
/**
|
414 |
* Calculate the category and category_index vector.
|
415 |
*
|
416 |
* @param q pointer to the COOKContext
|
417 |
* @param quant_index_table pointer to the array
|
418 |
* @param category pointer to the category array
|
419 |
* @param category_index pointer to the category_index array
|
420 |
*/
|
421 |
|
422 |
static void categorize(COOKContext *q, int* quant_index_table, |
423 |
int* category, int* category_index){ |
424 |
int exp_idx, bias, tmpbias, bits_left, num_bits, index, v, i, j;
|
425 |
int exp_index2[102]; |
426 |
int exp_index1[102]; |
427 |
|
428 |
int tmp_categorize_array1[128]; |
429 |
int tmp_categorize_array1_idx=0; |
430 |
int tmp_categorize_array2[128]; |
431 |
int tmp_categorize_array2_idx=0; |
432 |
int category_index_size=0; |
433 |
|
434 |
bits_left = q->bits_per_subpacket - get_bits_count(&q->gb); |
435 |
|
436 |
if(bits_left > q->samples_per_channel) {
|
437 |
bits_left = q->samples_per_channel + |
438 |
((bits_left - q->samples_per_channel)*5)/8; |
439 |
//av_log(NULL, AV_LOG_ERROR, "bits_left = %d\n",bits_left);
|
440 |
} |
441 |
|
442 |
memset(&exp_index1,0,102*sizeof(int)); |
443 |
memset(&exp_index2,0,102*sizeof(int)); |
444 |
memset(&tmp_categorize_array1,0,128*sizeof(int)); |
445 |
memset(&tmp_categorize_array2,0,128*sizeof(int)); |
446 |
|
447 |
bias=-32;
|
448 |
|
449 |
/* Estimate bias. */
|
450 |
for (i=32 ; i>0 ; i=i/2){ |
451 |
num_bits = 0;
|
452 |
index = 0;
|
453 |
for (j=q->total_subbands ; j>0 ; j--){ |
454 |
exp_idx = (i - quant_index_table[index] + bias) / 2;
|
455 |
if (exp_idx<0){ |
456 |
exp_idx=0;
|
457 |
} else if(exp_idx >7) { |
458 |
exp_idx=7;
|
459 |
} |
460 |
index++; |
461 |
num_bits+=expbits_tab[exp_idx]; |
462 |
} |
463 |
if(num_bits >= bits_left - 32){ |
464 |
bias+=i; |
465 |
} |
466 |
} |
467 |
|
468 |
/* Calculate total number of bits. */
|
469 |
num_bits=0;
|
470 |
for (i=0 ; i<q->total_subbands ; i++) { |
471 |
exp_idx = (bias - quant_index_table[i]) / 2;
|
472 |
if (exp_idx<0) { |
473 |
exp_idx=0;
|
474 |
} else if(exp_idx >7) { |
475 |
exp_idx=7;
|
476 |
} |
477 |
num_bits += expbits_tab[exp_idx]; |
478 |
exp_index1[i] = exp_idx; |
479 |
exp_index2[i] = exp_idx; |
480 |
} |
481 |
tmpbias = bias = num_bits; |
482 |
|
483 |
for (j = 1 ; j < q->numvector_size ; j++) { |
484 |
if (tmpbias + bias > 2*bits_left) { /* ---> */ |
485 |
int max = -999999; |
486 |
index=-1;
|
487 |
for (i=0 ; i<q->total_subbands ; i++){ |
488 |
if (exp_index1[i] < 7) { |
489 |
v = (-2*exp_index1[i]) - quant_index_table[i] - 32; |
490 |
if ( v >= max) {
|
491 |
max = v; |
492 |
index = i; |
493 |
} |
494 |
} |
495 |
} |
496 |
if(index==-1)break; |
497 |
tmp_categorize_array1[tmp_categorize_array1_idx++] = index; |
498 |
tmpbias -= expbits_tab[exp_index1[index]] - |
499 |
expbits_tab[exp_index1[index]+1];
|
500 |
++exp_index1[index]; |
501 |
} else { /* <--- */ |
502 |
int min = 999999; |
503 |
index=-1;
|
504 |
for (i=0 ; i<q->total_subbands ; i++){ |
505 |
if(exp_index2[i] > 0){ |
506 |
v = (-2*exp_index2[i])-quant_index_table[i];
|
507 |
if ( v < min) {
|
508 |
min = v; |
509 |
index = i; |
510 |
} |
511 |
} |
512 |
} |
513 |
if(index == -1)break; |
514 |
tmp_categorize_array2[tmp_categorize_array2_idx++] = index; |
515 |
tmpbias -= expbits_tab[exp_index2[index]] - |
516 |
expbits_tab[exp_index2[index]-1];
|
517 |
--exp_index2[index]; |
518 |
} |
519 |
} |
520 |
|
521 |
for(i=0 ; i<q->total_subbands ; i++) |
522 |
category[i] = exp_index2[i]; |
523 |
|
524 |
/* Concatenate the two arrays. */
|
525 |
for(i=tmp_categorize_array2_idx-1 ; i >= 0; i--) |
526 |
category_index[category_index_size++] = tmp_categorize_array2[i]; |
527 |
|
528 |
for(i=0;i<tmp_categorize_array1_idx;i++) |
529 |
category_index[category_index_size++ ] = tmp_categorize_array1[i]; |
530 |
|
531 |
/* FIXME: mc_sich_ra8_20.rm triggers this, not sure with what we
|
532 |
should fill the remaining bytes. */
|
533 |
for(i=category_index_size;i<q->numvector_size;i++)
|
534 |
category_index[i]=0;
|
535 |
|
536 |
} |
537 |
|
538 |
|
539 |
/**
|
540 |
* Expand the category vector.
|
541 |
*
|
542 |
* @param q pointer to the COOKContext
|
543 |
* @param category pointer to the category array
|
544 |
* @param category_index pointer to the category_index array
|
545 |
*/
|
546 |
|
547 |
static void inline expand_category(COOKContext *q, int* category, |
548 |
int* category_index){
|
549 |
int i;
|
550 |
for(i=0 ; i<q->num_vectors ; i++){ |
551 |
++category[category_index[i]]; |
552 |
} |
553 |
} |
554 |
|
555 |
/**
|
556 |
* The real requantization of the mltcoefs
|
557 |
*
|
558 |
* @param q pointer to the COOKContext
|
559 |
* @param index index
|
560 |
* @param band current subband
|
561 |
* @param quant_value_table pointer to the array
|
562 |
* @param subband_coef_index array of indexes to quant_centroid_tab
|
563 |
* @param subband_coef_noise use random noise instead of predetermined value
|
564 |
* @param mlt_buffer pointer to the mlt buffer
|
565 |
*/
|
566 |
|
567 |
|
568 |
static void scalar_dequant(COOKContext *q, int index, int band, |
569 |
float* quant_value_table, int* subband_coef_index, |
570 |
int* subband_coef_noise, float* mlt_buffer){ |
571 |
int i;
|
572 |
float f1;
|
573 |
|
574 |
for(i=0 ; i<SUBBAND_SIZE ; i++) { |
575 |
if (subband_coef_index[i]) {
|
576 |
if (subband_coef_noise[i]) {
|
577 |
f1 = -quant_centroid_tab[index][subband_coef_index[i]]; |
578 |
} else {
|
579 |
f1 = quant_centroid_tab[index][subband_coef_index[i]]; |
580 |
} |
581 |
} else {
|
582 |
/* noise coding if subband_coef_noise[i] == 0 */
|
583 |
q->random_state = q->random_state * 214013 + 2531011; //typical RNG numbers |
584 |
f1 = randsign[(q->random_state/0x1000000)&1] * dither_tab[index]; //>>31 |
585 |
} |
586 |
mlt_buffer[band*20+ i] = f1 * quant_value_table[band];
|
587 |
} |
588 |
} |
589 |
/**
|
590 |
* Unpack the subband_coef_index and subband_coef_noise vectors.
|
591 |
*
|
592 |
* @param q pointer to the COOKContext
|
593 |
* @param category pointer to the category array
|
594 |
* @param subband_coef_index array of indexes to quant_centroid_tab
|
595 |
* @param subband_coef_noise use random noise instead of predetermined value
|
596 |
*/
|
597 |
|
598 |
static int unpack_SQVH(COOKContext *q, int category, int* subband_coef_index, |
599 |
int* subband_coef_noise) {
|
600 |
int i,j;
|
601 |
int vlc, vd ,tmp, result;
|
602 |
int ub;
|
603 |
int cb;
|
604 |
|
605 |
vd = vd_tab[category]; |
606 |
result = 0;
|
607 |
for(i=0 ; i<vpr_tab[category] ; i++){ |
608 |
ub = get_bits_count(&q->gb); |
609 |
vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3);
|
610 |
cb = get_bits_count(&q->gb); |
611 |
if (q->bits_per_subpacket < get_bits_count(&q->gb)){
|
612 |
vlc = 0;
|
613 |
result = 1;
|
614 |
} |
615 |
for(j=vd-1 ; j>=0 ; j--){ |
616 |
tmp = (vlc * invradix_tab[category])/0x100000;
|
617 |
subband_coef_index[vd*i+j] = vlc - tmp * (kmax_tab[category]+1);
|
618 |
vlc = tmp; |
619 |
} |
620 |
for(j=0 ; j<vd ; j++){ |
621 |
if (subband_coef_index[i*vd + j]) {
|
622 |
if(get_bits_count(&q->gb) < q->bits_per_subpacket){
|
623 |
subband_coef_noise[i*vd+j] = get_bits1(&q->gb); |
624 |
} else {
|
625 |
result=1;
|
626 |
subband_coef_noise[i*vd+j]=0;
|
627 |
} |
628 |
} else {
|
629 |
subband_coef_noise[i*vd+j]=0;
|
630 |
} |
631 |
} |
632 |
} |
633 |
return result;
|
634 |
} |
635 |
|
636 |
|
637 |
/**
|
638 |
* Fill the mlt_buffer with mlt coefficients.
|
639 |
*
|
640 |
* @param q pointer to the COOKContext
|
641 |
* @param category pointer to the category array
|
642 |
* @param quant_value_table pointer to the array
|
643 |
* @param mlt_buffer pointer to mlt coefficients
|
644 |
*/
|
645 |
|
646 |
|
647 |
static void decode_vectors(COOKContext* q, int* category, |
648 |
float* quant_value_table, float* mlt_buffer){ |
649 |
/* A zero in this table means that the subband coefficient is
|
650 |
random noise coded. */
|
651 |
int subband_coef_noise[SUBBAND_SIZE];
|
652 |
/* A zero in this table means that the subband coefficient is a
|
653 |
positive multiplicator. */
|
654 |
int subband_coef_index[SUBBAND_SIZE];
|
655 |
int band, j;
|
656 |
int index=0; |
657 |
|
658 |
for(band=0 ; band<q->total_subbands ; band++){ |
659 |
index = category[band]; |
660 |
if(category[band] < 7){ |
661 |
if(unpack_SQVH(q, category[band], subband_coef_index, subband_coef_noise)){
|
662 |
index=7;
|
663 |
for(j=0 ; j<q->total_subbands ; j++) category[band+j]=7; |
664 |
} |
665 |
} |
666 |
if(index==7) { |
667 |
memset(subband_coef_index, 0, sizeof(subband_coef_index)); |
668 |
memset(subband_coef_noise, 0, sizeof(subband_coef_noise)); |
669 |
} |
670 |
scalar_dequant(q, index, band, quant_value_table, subband_coef_index, |
671 |
subband_coef_noise, mlt_buffer); |
672 |
} |
673 |
|
674 |
if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){
|
675 |
return;
|
676 |
} |
677 |
} |
678 |
|
679 |
|
680 |
/**
|
681 |
* function for decoding mono data
|
682 |
*
|
683 |
* @param q pointer to the COOKContext
|
684 |
* @param mlt_buffer1 pointer to left channel mlt coefficients
|
685 |
* @param mlt_buffer2 pointer to right channel mlt coefficients
|
686 |
*/
|
687 |
|
688 |
static void mono_decode(COOKContext *q, float* mlt_buffer) { |
689 |
|
690 |
int category_index[128]; |
691 |
float quant_value_table[102]; |
692 |
int quant_index_table[102]; |
693 |
int category[128]; |
694 |
|
695 |
memset(&category, 0, 128*sizeof(int)); |
696 |
memset(&quant_value_table, 0, 102*sizeof(int)); |
697 |
memset(&category_index, 0, 128*sizeof(int)); |
698 |
|
699 |
decode_envelope(q, quant_index_table); |
700 |
q->num_vectors = get_bits(&q->gb,q->log2_numvector_size); |
701 |
dequant_envelope(q, quant_index_table, quant_value_table); |
702 |
categorize(q, quant_index_table, category, category_index); |
703 |
expand_category(q, category, category_index); |
704 |
decode_vectors(q, category, quant_value_table, mlt_buffer); |
705 |
} |
706 |
|
707 |
|
708 |
/**
|
709 |
* The modulated lapped transform, this takes transform coefficients
|
710 |
* and transforms them into timedomain samples. This is done through
|
711 |
* an FFT-based algorithm with pre- and postrotation steps.
|
712 |
* A window and reorder step is also included.
|
713 |
*
|
714 |
* @param q pointer to the COOKContext
|
715 |
* @param inbuffer pointer to the mltcoefficients
|
716 |
* @param outbuffer pointer to the timedomain buffer
|
717 |
* @param mlt_tmp pointer to temporary storage space
|
718 |
*/
|
719 |
|
720 |
static void cook_imlt(COOKContext *q, float* inbuffer, float* outbuffer, |
721 |
float* mlt_tmp){
|
722 |
int i;
|
723 |
|
724 |
/* prerotation */
|
725 |
for(i=0 ; i<q->mlt_size ; i+=2){ |
726 |
outbuffer[i] = (q->mlt_presin[i/2] * inbuffer[q->mlt_size-1-i]) + |
727 |
(q->mlt_precos[i/2] * inbuffer[i]);
|
728 |
outbuffer[i+1] = (q->mlt_precos[i/2] * inbuffer[q->mlt_size-1-i]) - |
729 |
(q->mlt_presin[i/2] * inbuffer[i]);
|
730 |
} |
731 |
|
732 |
/* FFT */
|
733 |
ff_fft_permute(&q->fft_ctx, (FFTComplex *) outbuffer); |
734 |
ff_fft_calc (&q->fft_ctx, (FFTComplex *) outbuffer); |
735 |
|
736 |
/* postrotation */
|
737 |
for(i=0 ; i<q->mlt_size ; i+=2){ |
738 |
mlt_tmp[i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i+1]) + |
739 |
(q->mlt_postcos[i/2] * outbuffer[i]);
|
740 |
mlt_tmp[q->mlt_size-1-i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i]) - |
741 |
(q->mlt_postcos[i/2] * outbuffer[i+1]); |
742 |
} |
743 |
|
744 |
/* window and reorder */
|
745 |
for(i=0 ; i<q->mlt_size/2 ; i++){ |
746 |
outbuffer[i] = mlt_tmp[q->mlt_size/2-1-i] * q->mlt_window[i]; |
747 |
outbuffer[q->mlt_size-1-i]= mlt_tmp[q->mlt_size/2-1-i] * |
748 |
q->mlt_window[q->mlt_size-1-i];
|
749 |
outbuffer[q->mlt_size+i]= mlt_tmp[q->mlt_size/2+i] *
|
750 |
q->mlt_window[q->mlt_size-1-i];
|
751 |
outbuffer[2*q->mlt_size-1-i]= -(mlt_tmp[q->mlt_size/2+i] * |
752 |
q->mlt_window[i]); |
753 |
} |
754 |
} |
755 |
|
756 |
|
757 |
/**
|
758 |
* the actual requantization of the timedomain samples
|
759 |
*
|
760 |
* @param q pointer to the COOKContext
|
761 |
* @param buffer pointer to the timedomain buffer
|
762 |
* @param gain_index index for the block multiplier
|
763 |
* @param gain_index_next index for the next block multiplier
|
764 |
*/
|
765 |
|
766 |
static void interpolate(COOKContext *q, float* buffer, |
767 |
int gain_index, int gain_index_next){ |
768 |
int i;
|
769 |
float fc1, fc2;
|
770 |
fc1 = q->pow2tab[gain_index+63];
|
771 |
|
772 |
if(gain_index == gain_index_next){ //static gain |
773 |
for(i=0 ; i<q->gain_size_factor ; i++){ |
774 |
buffer[i]*=fc1; |
775 |
} |
776 |
return;
|
777 |
} else { //smooth gain |
778 |
fc2 = q->gain_table[11 + (gain_index_next-gain_index)];
|
779 |
for(i=0 ; i<q->gain_size_factor ; i++){ |
780 |
buffer[i]*=fc1; |
781 |
fc1*=fc2; |
782 |
} |
783 |
return;
|
784 |
} |
785 |
} |
786 |
|
787 |
/**
|
788 |
* timedomain requantization of the timedomain samples
|
789 |
*
|
790 |
* @param q pointer to the COOKContext
|
791 |
* @param buffer pointer to the timedomain buffer
|
792 |
* @param gain_now current gain structure
|
793 |
* @param gain_previous previous gain structure
|
794 |
*/
|
795 |
|
796 |
static void gain_window(COOKContext *q, float* buffer, COOKgain* gain_now, |
797 |
COOKgain* gain_previous){ |
798 |
int i, index;
|
799 |
int gain_index[9]; |
800 |
int tmp_gain_index;
|
801 |
|
802 |
gain_index[8]=0; |
803 |
index = gain_previous->size; |
804 |
for (i=7 ; i>=0 ; i--) { |
805 |
if(index && gain_previous->loccode[index-1]==i) { |
806 |
gain_index[i] = gain_previous->levcode[index-1];
|
807 |
index--; |
808 |
} else {
|
809 |
gain_index[i]=gain_index[i+1];
|
810 |
} |
811 |
} |
812 |
/* This is applied to the to be previous data buffer. */
|
813 |
for(i=0;i<8;i++){ |
814 |
interpolate(q, &buffer[q->samples_per_channel+q->gain_size_factor*i], |
815 |
gain_index[i], gain_index[i+1]);
|
816 |
} |
817 |
|
818 |
tmp_gain_index = gain_index[0];
|
819 |
index = gain_now->size; |
820 |
for (i=7 ; i>=0 ; i--) { |
821 |
if(index && gain_now->loccode[index-1]==i) { |
822 |
gain_index[i]= gain_now->levcode[index-1];
|
823 |
index--; |
824 |
} else {
|
825 |
gain_index[i]=gain_index[i+1];
|
826 |
} |
827 |
} |
828 |
|
829 |
/* This is applied to the to be current block. */
|
830 |
for(i=0;i<8;i++){ |
831 |
interpolate(q, &buffer[i*q->gain_size_factor], |
832 |
tmp_gain_index+gain_index[i], |
833 |
tmp_gain_index+gain_index[i+1]);
|
834 |
} |
835 |
} |
836 |
|
837 |
|
838 |
/**
|
839 |
* mlt overlapping and buffer management
|
840 |
*
|
841 |
* @param q pointer to the COOKContext
|
842 |
* @param buffer pointer to the timedomain buffer
|
843 |
* @param gain_now current gain structure
|
844 |
* @param gain_previous previous gain structure
|
845 |
* @param previous_buffer pointer to the previous buffer to be used for overlapping
|
846 |
*
|
847 |
*/
|
848 |
|
849 |
static void gain_compensate(COOKContext *q, float* buffer, COOKgain* gain_now, |
850 |
COOKgain* gain_previous, float* previous_buffer) {
|
851 |
int i;
|
852 |
if((gain_now->size || gain_previous->size)) {
|
853 |
gain_window(q, buffer, gain_now, gain_previous); |
854 |
} |
855 |
|
856 |
/* Overlap with the previous block. */
|
857 |
for(i=0 ; i<q->samples_per_channel ; i++) buffer[i]+=previous_buffer[i]; |
858 |
|
859 |
/* Save away the current to be previous block. */
|
860 |
memcpy(previous_buffer, buffer+q->samples_per_channel, |
861 |
sizeof(float)*q->samples_per_channel); |
862 |
} |
863 |
|
864 |
|
865 |
/**
|
866 |
* function for getting the jointstereo coupling information
|
867 |
*
|
868 |
* @param q pointer to the COOKContext
|
869 |
* @param decouple_tab decoupling array
|
870 |
*
|
871 |
*/
|
872 |
|
873 |
static void decouple_info(COOKContext *q, int* decouple_tab){ |
874 |
int length, i;
|
875 |
|
876 |
if(get_bits1(&q->gb)) {
|
877 |
if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; |
878 |
|
879 |
length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; |
880 |
for (i=0 ; i<length ; i++) { |
881 |
decouple_tab[cplband[q->js_subband_start] + i] = get_vlc2(&q->gb, q->ccpl.table, q->ccpl.bits, 2);
|
882 |
} |
883 |
return;
|
884 |
} |
885 |
|
886 |
if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; |
887 |
|
888 |
length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; |
889 |
for (i=0 ; i<length ; i++) { |
890 |
decouple_tab[cplband[q->js_subband_start] + i] = get_bits(&q->gb, q->js_vlc_bits); |
891 |
} |
892 |
return;
|
893 |
} |
894 |
|
895 |
|
896 |
/**
|
897 |
* function for decoding joint stereo data
|
898 |
*
|
899 |
* @param q pointer to the COOKContext
|
900 |
* @param mlt_buffer1 pointer to left channel mlt coefficients
|
901 |
* @param mlt_buffer2 pointer to right channel mlt coefficients
|
902 |
*/
|
903 |
|
904 |
static void joint_decode(COOKContext *q, float* mlt_buffer1, |
905 |
float* mlt_buffer2) {
|
906 |
int i,j;
|
907 |
int decouple_tab[SUBBAND_SIZE];
|
908 |
float decode_buffer[1060]; |
909 |
int idx, cpl_tmp,tmp_idx;
|
910 |
float f1,f2;
|
911 |
float* cplscale;
|
912 |
|
913 |
memset(decouple_tab, 0, sizeof(decouple_tab)); |
914 |
memset(decode_buffer, 0, sizeof(decode_buffer)); |
915 |
|
916 |
/* Make sure the buffers are zeroed out. */
|
917 |
memset(mlt_buffer1,0, 1024*sizeof(float)); |
918 |
memset(mlt_buffer2,0, 1024*sizeof(float)); |
919 |
decouple_info(q, decouple_tab); |
920 |
mono_decode(q, decode_buffer); |
921 |
|
922 |
/* The two channels are stored interleaved in decode_buffer. */
|
923 |
for (i=0 ; i<q->js_subband_start ; i++) { |
924 |
for (j=0 ; j<SUBBAND_SIZE ; j++) { |
925 |
mlt_buffer1[i*20+j] = decode_buffer[i*40+j]; |
926 |
mlt_buffer2[i*20+j] = decode_buffer[i*40+20+j]; |
927 |
} |
928 |
} |
929 |
|
930 |
/* When we reach js_subband_start (the higher frequencies)
|
931 |
the coefficients are stored in a coupling scheme. */
|
932 |
idx = (1 << q->js_vlc_bits) - 1; |
933 |
for (i=q->js_subband_start ; i<q->subbands ; i++) {
|
934 |
cpl_tmp = cplband[i]; |
935 |
idx -=decouple_tab[cpl_tmp]; |
936 |
cplscale = (float*)cplscales[q->js_vlc_bits-2]; //choose decoupler table |
937 |
f1 = cplscale[decouple_tab[cpl_tmp]]; |
938 |
f2 = cplscale[idx-1];
|
939 |
for (j=0 ; j<SUBBAND_SIZE ; j++) { |
940 |
tmp_idx = ((q->js_subband_start + i)*20)+j;
|
941 |
mlt_buffer1[20*i + j] = f1 * decode_buffer[tmp_idx];
|
942 |
mlt_buffer2[20*i + j] = f2 * decode_buffer[tmp_idx];
|
943 |
} |
944 |
idx = (1 << q->js_vlc_bits) - 1; |
945 |
} |
946 |
} |
947 |
|
948 |
/**
|
949 |
* First part of subpacket decoding:
|
950 |
* decode raw stream bytes and read gain info.
|
951 |
*
|
952 |
* @param q pointer to the COOKContext
|
953 |
* @param inbuffer pointer to raw stream data
|
954 |
* @param gain_ptr array of current/prev gain pointers
|
955 |
*/
|
956 |
|
957 |
static inline void |
958 |
decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, |
959 |
COOKgain *gain_ptr[]) |
960 |
{ |
961 |
int offset;
|
962 |
|
963 |
offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, |
964 |
q->bits_per_subpacket/8);
|
965 |
init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, |
966 |
q->bits_per_subpacket); |
967 |
decode_gain_info(&q->gb, gain_ptr[0]);
|
968 |
|
969 |
/* Swap current and previous gains */
|
970 |
FFSWAP(COOKgain *, gain_ptr[0], gain_ptr[1]); |
971 |
} |
972 |
|
973 |
/**
|
974 |
* Final part of subpacket decoding:
|
975 |
* Apply modulated lapped transform, gain compensation,
|
976 |
* clip and convert to integer.
|
977 |
*
|
978 |
* @param q pointer to the COOKContext
|
979 |
* @param decode_buffer pointer to the mlt coefficients
|
980 |
* @param gain_ptr array of current/prev gain pointers
|
981 |
* @param previous_buffer pointer to the previous buffer to be used for overlapping
|
982 |
* @param out pointer to the output buffer
|
983 |
* @param chan 0: left or single channel, 1: right channel
|
984 |
*/
|
985 |
|
986 |
static inline void |
987 |
mlt_compensate_output(COOKContext *q, float *decode_buffer,
|
988 |
COOKgain *gain_ptr[], float *previous_buffer,
|
989 |
int16_t *out, int chan)
|
990 |
{ |
991 |
int j;
|
992 |
|
993 |
cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp); |
994 |
gain_compensate(q, q->mono_mdct_output, gain_ptr[0],
|
995 |
gain_ptr[1], previous_buffer);
|
996 |
|
997 |
/* Clip and convert floats to 16 bits.
|
998 |
*/
|
999 |
for (j = 0; j < q->samples_per_channel; j++) { |
1000 |
out[chan + q->nb_channels * j] = |
1001 |
av_clip(lrintf(q->mono_mdct_output[j]), -32768, 32767); |
1002 |
} |
1003 |
} |
1004 |
|
1005 |
|
1006 |
/**
|
1007 |
* Cook subpacket decoding. This function returns one decoded subpacket,
|
1008 |
* usually 1024 samples per channel.
|
1009 |
*
|
1010 |
* @param q pointer to the COOKContext
|
1011 |
* @param inbuffer pointer to the inbuffer
|
1012 |
* @param sub_packet_size subpacket size
|
1013 |
* @param outbuffer pointer to the outbuffer
|
1014 |
*/
|
1015 |
|
1016 |
|
1017 |
static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, |
1018 |
int sub_packet_size, int16_t *outbuffer) {
|
1019 |
/* packet dump */
|
1020 |
// for (i=0 ; i<sub_packet_size ; i++) {
|
1021 |
// av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
|
1022 |
// }
|
1023 |
// av_log(NULL, AV_LOG_ERROR, "\n");
|
1024 |
|
1025 |
decode_bytes_and_gain(q, inbuffer, q->gain_ptr1); |
1026 |
|
1027 |
if (q->joint_stereo) {
|
1028 |
joint_decode(q, q->decode_buffer_1, q->decode_buffer_2); |
1029 |
} else {
|
1030 |
mono_decode(q, q->decode_buffer_1); |
1031 |
|
1032 |
if (q->nb_channels == 2) { |
1033 |
decode_bytes_and_gain(q, inbuffer + sub_packet_size/2,
|
1034 |
q->gain_ptr2); |
1035 |
mono_decode(q, q->decode_buffer_2); |
1036 |
} |
1037 |
} |
1038 |
|
1039 |
mlt_compensate_output(q, q->decode_buffer_1, q->gain_ptr1, |
1040 |
q->mono_previous_buffer1, outbuffer, 0);
|
1041 |
|
1042 |
if (q->nb_channels == 2) { |
1043 |
if (q->joint_stereo) {
|
1044 |
mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr1, |
1045 |
q->mono_previous_buffer2, outbuffer, 1);
|
1046 |
} else {
|
1047 |
mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr2, |
1048 |
q->mono_previous_buffer2, outbuffer, 1);
|
1049 |
} |
1050 |
} |
1051 |
return q->samples_per_frame * sizeof(int16_t); |
1052 |
} |
1053 |
|
1054 |
|
1055 |
/**
|
1056 |
* Cook frame decoding
|
1057 |
*
|
1058 |
* @param avctx pointer to the AVCodecContext
|
1059 |
*/
|
1060 |
|
1061 |
static int cook_decode_frame(AVCodecContext *avctx, |
1062 |
void *data, int *data_size, |
1063 |
uint8_t *buf, int buf_size) {
|
1064 |
COOKContext *q = avctx->priv_data; |
1065 |
|
1066 |
if (buf_size < avctx->block_align)
|
1067 |
return buf_size;
|
1068 |
|
1069 |
*data_size = decode_subpacket(q, buf, avctx->block_align, data); |
1070 |
|
1071 |
return avctx->block_align;
|
1072 |
} |
1073 |
|
1074 |
#ifdef COOKDEBUG
|
1075 |
static void dump_cook_context(COOKContext *q) |
1076 |
{ |
1077 |
//int i=0;
|
1078 |
#define PRINT(a,b) av_log(NULL,AV_LOG_ERROR," %s = %d\n", a, b); |
1079 |
av_log(NULL,AV_LOG_ERROR,"COOKextradata\n"); |
1080 |
av_log(NULL,AV_LOG_ERROR,"cookversion=%x\n",q->cookversion); |
1081 |
if (q->cookversion > STEREO) {
|
1082 |
PRINT("js_subband_start",q->js_subband_start);
|
1083 |
PRINT("js_vlc_bits",q->js_vlc_bits);
|
1084 |
} |
1085 |
av_log(NULL,AV_LOG_ERROR,"COOKContext\n"); |
1086 |
PRINT("nb_channels",q->nb_channels);
|
1087 |
PRINT("bit_rate",q->bit_rate);
|
1088 |
PRINT("sample_rate",q->sample_rate);
|
1089 |
PRINT("samples_per_channel",q->samples_per_channel);
|
1090 |
PRINT("samples_per_frame",q->samples_per_frame);
|
1091 |
PRINT("subbands",q->subbands);
|
1092 |
PRINT("random_state",q->random_state);
|
1093 |
PRINT("mlt_size",q->mlt_size);
|
1094 |
PRINT("js_subband_start",q->js_subband_start);
|
1095 |
PRINT("log2_numvector_size",q->log2_numvector_size);
|
1096 |
PRINT("numvector_size",q->numvector_size);
|
1097 |
PRINT("total_subbands",q->total_subbands);
|
1098 |
} |
1099 |
#endif
|
1100 |
|
1101 |
/**
|
1102 |
* Cook initialization
|
1103 |
*
|
1104 |
* @param avctx pointer to the AVCodecContext
|
1105 |
*/
|
1106 |
|
1107 |
static int cook_decode_init(AVCodecContext *avctx) |
1108 |
{ |
1109 |
COOKContext *q = avctx->priv_data; |
1110 |
uint8_t *edata_ptr = avctx->extradata; |
1111 |
|
1112 |
/* Take care of the codec specific extradata. */
|
1113 |
if (avctx->extradata_size <= 0) { |
1114 |
av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n");
|
1115 |
return -1; |
1116 |
} else {
|
1117 |
/* 8 for mono, 16 for stereo, ? for multichannel
|
1118 |
Swap to right endianness so we don't need to care later on. */
|
1119 |
av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size);
|
1120 |
if (avctx->extradata_size >= 8){ |
1121 |
q->cookversion = bytestream_get_be32(&edata_ptr); |
1122 |
q->samples_per_frame = bytestream_get_be16(&edata_ptr); |
1123 |
q->subbands = bytestream_get_be16(&edata_ptr); |
1124 |
} |
1125 |
if (avctx->extradata_size >= 16){ |
1126 |
bytestream_get_be32(&edata_ptr); //Unknown unused
|
1127 |
q->js_subband_start = bytestream_get_be16(&edata_ptr); |
1128 |
q->js_vlc_bits = bytestream_get_be16(&edata_ptr); |
1129 |
} |
1130 |
} |
1131 |
|
1132 |
/* Take data from the AVCodecContext (RM container). */
|
1133 |
q->sample_rate = avctx->sample_rate; |
1134 |
q->nb_channels = avctx->channels; |
1135 |
q->bit_rate = avctx->bit_rate; |
1136 |
|
1137 |
/* Initialize state. */
|
1138 |
q->random_state = 1;
|
1139 |
|
1140 |
/* Initialize extradata related variables. */
|
1141 |
q->samples_per_channel = q->samples_per_frame / q->nb_channels; |
1142 |
q->bits_per_subpacket = avctx->block_align * 8;
|
1143 |
|
1144 |
/* Initialize default data states. */
|
1145 |
q->log2_numvector_size = 5;
|
1146 |
q->total_subbands = q->subbands; |
1147 |
|
1148 |
/* Initialize version-dependent variables */
|
1149 |
av_log(NULL,AV_LOG_DEBUG,"q->cookversion=%x\n",q->cookversion); |
1150 |
q->joint_stereo = 0;
|
1151 |
switch (q->cookversion) {
|
1152 |
case MONO:
|
1153 |
if (q->nb_channels != 1) { |
1154 |
av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n");
|
1155 |
return -1; |
1156 |
} |
1157 |
av_log(avctx,AV_LOG_DEBUG,"MONO\n");
|
1158 |
break;
|
1159 |
case STEREO:
|
1160 |
if (q->nb_channels != 1) { |
1161 |
q->bits_per_subpacket = q->bits_per_subpacket/2;
|
1162 |
} |
1163 |
av_log(avctx,AV_LOG_DEBUG,"STEREO\n");
|
1164 |
break;
|
1165 |
case JOINT_STEREO:
|
1166 |
if (q->nb_channels != 2) { |
1167 |
av_log(avctx,AV_LOG_ERROR,"Container channels != 2, report sample!\n");
|
1168 |
return -1; |
1169 |
} |
1170 |
av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n");
|
1171 |
if (avctx->extradata_size >= 16){ |
1172 |
q->total_subbands = q->subbands + q->js_subband_start; |
1173 |
q->joint_stereo = 1;
|
1174 |
} |
1175 |
if (q->samples_per_channel > 256) { |
1176 |
q->log2_numvector_size = 6;
|
1177 |
} |
1178 |
if (q->samples_per_channel > 512) { |
1179 |
q->log2_numvector_size = 7;
|
1180 |
} |
1181 |
break;
|
1182 |
case MC_COOK:
|
1183 |
av_log(avctx,AV_LOG_ERROR,"MC_COOK not supported!\n");
|
1184 |
return -1; |
1185 |
break;
|
1186 |
default:
|
1187 |
av_log(avctx,AV_LOG_ERROR,"Unknown Cook version, report sample!\n");
|
1188 |
return -1; |
1189 |
break;
|
1190 |
} |
1191 |
|
1192 |
/* Initialize variable relations */
|
1193 |
q->mlt_size = q->samples_per_channel; |
1194 |
q->numvector_size = (1 << q->log2_numvector_size);
|
1195 |
|
1196 |
/* Generate tables */
|
1197 |
init_rootpow2table(q); |
1198 |
init_pow2table(q); |
1199 |
init_gain_table(q); |
1200 |
|
1201 |
if (init_cook_vlc_tables(q) != 0) |
1202 |
return -1; |
1203 |
|
1204 |
|
1205 |
if(avctx->block_align >= UINT_MAX/2) |
1206 |
return -1; |
1207 |
|
1208 |
/* Pad the databuffer with:
|
1209 |
DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),
|
1210 |
FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */
|
1211 |
if (q->nb_channels==2 && q->joint_stereo==0) { |
1212 |
q->decoded_bytes_buffer = |
1213 |
av_mallocz(avctx->block_align/2
|
1214 |
+ DECODE_BYTES_PAD2(avctx->block_align/2)
|
1215 |
+ FF_INPUT_BUFFER_PADDING_SIZE); |
1216 |
} else {
|
1217 |
q->decoded_bytes_buffer = |
1218 |
av_mallocz(avctx->block_align |
1219 |
+ DECODE_BYTES_PAD1(avctx->block_align) |
1220 |
+ FF_INPUT_BUFFER_PADDING_SIZE); |
1221 |
} |
1222 |
if (q->decoded_bytes_buffer == NULL) |
1223 |
return -1; |
1224 |
|
1225 |
q->gain_ptr1[0] = &q->gain_1;
|
1226 |
q->gain_ptr1[1] = &q->gain_2;
|
1227 |
q->gain_ptr2[0] = &q->gain_3;
|
1228 |
q->gain_ptr2[1] = &q->gain_4;
|
1229 |
|
1230 |
/* Initialize transform. */
|
1231 |
if ( init_cook_mlt(q) == 0 ) |
1232 |
return -1; |
1233 |
|
1234 |
/* Try to catch some obviously faulty streams, othervise it might be exploitable */
|
1235 |
if (q->total_subbands > 53) { |
1236 |
av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n");
|
1237 |
return -1; |
1238 |
} |
1239 |
if (q->subbands > 50) { |
1240 |
av_log(avctx,AV_LOG_ERROR,"subbands > 50, report sample!\n");
|
1241 |
return -1; |
1242 |
} |
1243 |
if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) { |
1244 |
} else {
|
1245 |
av_log(avctx,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel);
|
1246 |
return -1; |
1247 |
} |
1248 |
if ((q->js_vlc_bits > 6) || (q->js_vlc_bits < 0)) { |
1249 |
av_log(avctx,AV_LOG_ERROR,"q->js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->js_vlc_bits);
|
1250 |
return -1; |
1251 |
} |
1252 |
|
1253 |
#ifdef COOKDEBUG
|
1254 |
dump_cook_context(q); |
1255 |
#endif
|
1256 |
return 0; |
1257 |
} |
1258 |
|
1259 |
|
1260 |
AVCodec cook_decoder = |
1261 |
{ |
1262 |
.name = "cook",
|
1263 |
.type = CODEC_TYPE_AUDIO, |
1264 |
.id = CODEC_ID_COOK, |
1265 |
.priv_data_size = sizeof(COOKContext),
|
1266 |
.init = cook_decode_init, |
1267 |
.close = cook_decode_close, |
1268 |
.decode = cook_decode_frame, |
1269 |
}; |