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