summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/cook.c94
1 files changed, 26 insertions, 68 deletions
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 0bc97193b8..0a219451be 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -90,15 +90,9 @@ typedef struct {
int random_state;
/* transform data */
- FFTContext fft_ctx;
- DECLARE_ALIGNED_16(FFTSample, mlt_tmp[1024]); /* temporary storage for imlt */
+ MDCTContext mdct_ctx;
+ DECLARE_ALIGNED_16(FFTSample, mdct_tmp[1024]); /* temporary storage for imlt */
float* mlt_window;
- float* mlt_precos;
- float* mlt_presin;
- float* mlt_postcos;
- int fft_size;
- int fft_order;
- int mlt_size; //modulated lapped transform size
/* gain buffers */
cook_gains gains1;
@@ -225,34 +219,25 @@ static int init_cook_vlc_tables(COOKContext *q) {
static int init_cook_mlt(COOKContext *q) {
int j;
float alpha;
+ int mlt_size = q->samples_per_channel;
- /* Allocate the buffers, could be replaced with a static [512]
- array if needed. */
- q->mlt_size = q->samples_per_channel;
- q->mlt_window = av_malloc(sizeof(float)*q->mlt_size);
- q->mlt_precos = av_malloc(sizeof(float)*q->mlt_size/2);
- q->mlt_presin = av_malloc(sizeof(float)*q->mlt_size/2);
- q->mlt_postcos = av_malloc(sizeof(float)*q->mlt_size/2);
+ if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0)
+ return -1;
/* Initialize the MLT window: simple sine window. */
- alpha = M_PI / (2.0 * (float)q->mlt_size);
- for(j=0 ; j<q->mlt_size ; j++) {
- q->mlt_window[j] = sin((j + 512.0/(float)q->mlt_size) * alpha);
+ alpha = M_PI / (2.0 * (float)mlt_size);
+ for(j=0 ; j<mlt_size ; j++)
+ q->mlt_window[j] = sin((j + 0.5) * alpha) * sqrt(2.0 / q->samples_per_channel);
+
+ /* Initialize the MDCT. */
+ if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1)) {
+ av_free(q->mlt_window);
+ return -1;
}
+ av_log(NULL,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n",
+ av_log2(mlt_size)+1);
- /* pre/post twiddle factors */
- for (j=0 ; j<q->mlt_size/2 ; j++){
- q->mlt_precos[j] = cos( ((j+0.25)*M_PI)/q->mlt_size);
- q->mlt_presin[j] = sin( ((j+0.25)*M_PI)/q->mlt_size);
- 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
- }
-
- /* Initialize the FFT. */
- ff_fft_init(&q->fft_ctx, av_log2(q->mlt_size)-1, 0);
- av_log(NULL,AV_LOG_DEBUG,"FFT initialized, order = %d.\n",
- av_log2(q->samples_per_channel)-1);
-
- return (int)(q->mlt_window && q->mlt_precos && q->mlt_presin && q->mlt_postcos);
+ return 0;
}
/*************** init functions end ***********/
@@ -313,13 +298,10 @@ static int cook_decode_close(AVCodecContext *avctx)
/* Free allocated memory buffers. */
av_free(q->mlt_window);
- av_free(q->mlt_precos);
- av_free(q->mlt_presin);
- av_free(q->mlt_postcos);
av_free(q->decoded_bytes_buffer);
/* Free the transform. */
- ff_fft_end(&q->fft_ctx);
+ ff_mdct_end(&q->mdct_ctx);
/* Free the VLC tables. */
for (i=0 ; i<13 ; i++) {
@@ -714,39 +696,17 @@ static void mono_decode(COOKContext *q, float* mlt_buffer) {
* @param mlt_tmp pointer to temporary storage space
*/
-static void cook_imlt(COOKContext *q, float* inbuffer, float* outbuffer,
- float* mlt_tmp){
+static void cook_imlt(COOKContext *q, float* inbuffer, float* outbuffer)
+{
int i;
- /* prerotation */
- for(i=0 ; i<q->mlt_size ; i+=2){
- outbuffer[i] = (q->mlt_presin[i/2] * inbuffer[q->mlt_size-1-i]) +
- (q->mlt_precos[i/2] * inbuffer[i]);
- outbuffer[i+1] = (q->mlt_precos[i/2] * inbuffer[q->mlt_size-1-i]) -
- (q->mlt_presin[i/2] * inbuffer[i]);
- }
-
- /* FFT */
- ff_fft_permute(&q->fft_ctx, (FFTComplex *) outbuffer);
- ff_fft_calc (&q->fft_ctx, (FFTComplex *) outbuffer);
+ q->mdct_ctx.fft.imdct_calc(&q->mdct_ctx, outbuffer, inbuffer, q->mdct_tmp);
- /* postrotation */
- for(i=0 ; i<q->mlt_size ; i+=2){
- mlt_tmp[i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i+1]) +
- (q->mlt_postcos[i/2] * outbuffer[i]);
- mlt_tmp[q->mlt_size-1-i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i]) -
- (q->mlt_postcos[i/2] * outbuffer[i+1]);
- }
+ for(i = 0; i < q->samples_per_channel; i++){
+ float tmp = outbuffer[i];
- /* window and reorder */
- for(i=0 ; i<q->mlt_size/2 ; i++){
- outbuffer[i] = mlt_tmp[q->mlt_size/2-1-i] * q->mlt_window[i];
- outbuffer[q->mlt_size-1-i]= mlt_tmp[q->mlt_size/2-1-i] *
- q->mlt_window[q->mlt_size-1-i];
- outbuffer[q->mlt_size+i]= mlt_tmp[q->mlt_size/2+i] *
- q->mlt_window[q->mlt_size-1-i];
- outbuffer[2*q->mlt_size-1-i]= -(mlt_tmp[q->mlt_size/2+i] *
- q->mlt_window[i]);
+ outbuffer[i] = q->mlt_window[i] * outbuffer[q->samples_per_channel + i];
+ outbuffer[q->samples_per_channel + i] = q->mlt_window[q->samples_per_channel - 1 - i] * -tmp;
}
}
@@ -944,7 +904,7 @@ mlt_compensate_output(COOKContext *q, float *decode_buffer,
{
int j;
- cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp);
+ cook_imlt(q, decode_buffer, q->mono_mdct_output);
gain_compensate(q, gains, previous_buffer);
/* Clip and convert floats to 16 bits.
@@ -1045,7 +1005,6 @@ static void dump_cook_context(COOKContext *q)
PRINT("samples_per_frame",q->samples_per_frame);
PRINT("subbands",q->subbands);
PRINT("random_state",q->random_state);
- PRINT("mlt_size",q->mlt_size);
PRINT("js_subband_start",q->js_subband_start);
PRINT("log2_numvector_size",q->log2_numvector_size);
PRINT("numvector_size",q->numvector_size);
@@ -1145,7 +1104,6 @@ static int cook_decode_init(AVCodecContext *avctx)
}
/* Initialize variable relations */
- q->mlt_size = q->samples_per_channel;
q->numvector_size = (1 << q->log2_numvector_size);
/* Generate tables */
@@ -1183,7 +1141,7 @@ static int cook_decode_init(AVCodecContext *avctx)
q->gains2.previous = q->gain_4;
/* Initialize transform. */
- if ( init_cook_mlt(q) == 0 )
+ if ( init_cook_mlt(q) != 0 )
return -1;
/* Try to catch some obviously faulty streams, othervise it might be exploitable */