diff options
author | Michael Giacomelli <giac2000@hotmail.com> | 2009-05-10 23:18:04 +0000 |
---|---|---|
committer | Michael Giacomelli <giac2000@hotmail.com> | 2009-05-10 23:18:04 +0000 |
commit | 65649de515257493dd1b8db599201097208677bb (patch) | |
tree | 23dcc4b3ae9c156568d29f90dc5fd0f2f951b21d | |
parent | fc28cb4ed5adf4a0bc548af38ca6de95bbf027e5 (diff) | |
download | rockbox-65649de515257493dd1b8db599201097208677bb.tar.gz rockbox-65649de515257493dd1b8db599201097208677bb.zip |
Patch by Mohamed Tarek from FS #10182. Remove floating point code (FFT, MDCT, etc) from libcook.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20902 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/libcook/Makefile.test | 2 | ||||
-rw-r--r-- | apps/codecs/libcook/cook.c | 267 | ||||
-rw-r--r-- | apps/codecs/libcook/cook.h | 17 | ||||
-rw-r--r-- | apps/codecs/libcook/dsputil.h | 908 | ||||
-rw-r--r-- | apps/codecs/libcook/fft.c | 374 | ||||
-rw-r--r-- | apps/codecs/libcook/main.c | 2 | ||||
-rw-r--r-- | apps/codecs/libcook/mdct.c | 229 |
7 files changed, 2 insertions, 1797 deletions
diff --git a/apps/codecs/libcook/Makefile.test b/apps/codecs/libcook/Makefile.test index 5b60ca3ef5..d992eceeb8 100644 --- a/apps/codecs/libcook/Makefile.test +++ b/apps/codecs/libcook/Makefile.test | |||
@@ -1,5 +1,5 @@ | |||
1 | CFLAGS = -Wall -O3 | 1 | CFLAGS = -Wall -O3 |
2 | OBJS = main.o bitstream.o cook.o fft.o libavutil/log.o mdct.o libavutil/mem.o libavutil/lfg.o libavutil/md5.o rm2wav.o | 2 | OBJS = main.o bitstream.o cook.o libavutil/log.o libavutil/mem.o libavutil/lfg.o libavutil/md5.o rm2wav.o |
3 | cooktest: $(OBJS) | 3 | cooktest: $(OBJS) |
4 | gcc -o cooktest $(OBJS) -lm | 4 | gcc -o cooktest $(OBJS) -lm |
5 | 5 | ||
diff --git a/apps/codecs/libcook/cook.c b/apps/codecs/libcook/cook.c index 8bb3b5a113..bd72179cbd 100644 --- a/apps/codecs/libcook/cook.c +++ b/apps/codecs/libcook/cook.c | |||
@@ -71,23 +71,11 @@ const uint8_t ff_log2_tab[256]={ | |||
71 | #define MAX_SUBPACKETS 5 | 71 | #define MAX_SUBPACKETS 5 |
72 | //#define COOKDEBUG | 72 | //#define COOKDEBUG |
73 | #define DEBUGF(message,args ...) av_log(NULL,AV_LOG_ERROR,message,## args) | 73 | #define DEBUGF(message,args ...) av_log(NULL,AV_LOG_ERROR,message,## args) |
74 | |||
75 | static float pow2tab[127]; | ||
76 | static float rootpow2tab[127]; | ||
77 | #include "cook_fixpoint.h" | 74 | #include "cook_fixpoint.h" |
78 | 75 | ||
79 | /* debug functions */ | 76 | /* debug functions */ |
80 | 77 | ||
81 | #ifdef COOKDEBUG | 78 | #ifdef COOKDEBUG |
82 | static void dump_float_table(float* table, int size, int delimiter) { | ||
83 | int i=0; | ||
84 | av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); | ||
85 | for (i=0 ; i<size ; i++) { | ||
86 | av_log(NULL, AV_LOG_ERROR, "%5.1f, ", table[i]); | ||
87 | if ((i+1)%delimiter == 0) av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i+1); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static void dump_int_table(int* table, int size, int delimiter) { | 79 | static void dump_int_table(int* table, int size, int delimiter) { |
92 | int i=0; | 80 | int i=0; |
93 | av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); | 81 | av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); |
@@ -109,27 +97,6 @@ static void dump_short_table(short* table, int size, int delimiter) { | |||
109 | #endif | 97 | #endif |
110 | 98 | ||
111 | /*************** init functions ***************/ | 99 | /*************** init functions ***************/ |
112 | |||
113 | /* table generator */ | ||
114 | static av_cold void init_pow2table(void){ | ||
115 | int i; | ||
116 | for (i=-63 ; i<64 ; i++){ | ||
117 | pow2tab[63+i]= pow(2, i); | ||
118 | rootpow2tab[63+i]=sqrt(pow(2, i)); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /* table generator */ | ||
123 | static av_cold void init_gain_table(COOKContext *q) { | ||
124 | int i; | ||
125 | q->gain_size_factor = q->samples_per_channel/8; | ||
126 | for (i=0 ; i<23 ; i++) { | ||
127 | q->gain_table[i] = pow(pow2tab[i+52] , | ||
128 | (1.0/(double)q->gain_size_factor)); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | |||
133 | static av_cold int init_cook_vlc_tables(COOKContext *q) { | 100 | static av_cold int init_cook_vlc_tables(COOKContext *q) { |
134 | int i, result; | 101 | int i, result; |
135 | 102 | ||
@@ -156,42 +123,6 @@ static av_cold int init_cook_vlc_tables(COOKContext *q) { | |||
156 | av_log(NULL,AV_LOG_ERROR,"VLC tables initialized. Result = %d\n",result); | 123 | av_log(NULL,AV_LOG_ERROR,"VLC tables initialized. Result = %d\n",result); |
157 | return result; | 124 | return result; |
158 | } | 125 | } |
159 | |||
160 | static av_cold int init_cook_mlt(COOKContext *q) { | ||
161 | int j; | ||
162 | int mlt_size = q->samples_per_channel; | ||
163 | |||
164 | if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0) | ||
165 | return -1; | ||
166 | |||
167 | /* Initialize the MLT window: simple sine window. */ | ||
168 | ff_sine_window_init(q->mlt_window, mlt_size); | ||
169 | for(j=0 ; j<mlt_size ; j++) | ||
170 | q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); | ||
171 | |||
172 | /* Initialize the MDCT. */ | ||
173 | if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1)) { | ||
174 | av_free(q->mlt_window); | ||
175 | return -1; | ||
176 | } | ||
177 | av_log(NULL,AV_LOG_ERROR,"MDCT initialized, order = %d. mlt_window = %d\n", | ||
178 | av_log2(mlt_size)+1,sizeof(q->mlt_window)*mlt_size); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static const float *maybe_reformat_buffer32 (COOKContext *q, const float *ptr, int n) | ||
184 | { | ||
185 | if (1) | ||
186 | return ptr; | ||
187 | } | ||
188 | |||
189 | static av_cold void init_cplscales_table (COOKContext *q) { | ||
190 | int i; | ||
191 | for (i=0;i<5;i++) | ||
192 | q->cplscales[i] = maybe_reformat_buffer32 (q, q->cplscales[i], (1<<(i+2))-1); | ||
193 | } | ||
194 | |||
195 | /*************** init functions end ***********/ | 126 | /*************** init functions end ***********/ |
196 | 127 | ||
197 | /** | 128 | /** |
@@ -249,12 +180,8 @@ av_cold int cook_decode_close(COOKContext *q) | |||
249 | av_log(NULL,AV_LOG_ERROR, "Deallocating memory.\n"); | 180 | av_log(NULL,AV_LOG_ERROR, "Deallocating memory.\n"); |
250 | 181 | ||
251 | /* Free allocated memory buffers. */ | 182 | /* Free allocated memory buffers. */ |
252 | av_free(q->mlt_window); | ||
253 | av_free(q->decoded_bytes_buffer); | 183 | av_free(q->decoded_bytes_buffer); |
254 | 184 | ||
255 | /* Free the transform. */ | ||
256 | ff_mdct_end(&q->mdct_ctx); | ||
257 | |||
258 | /* Free the VLC tables. */ | 185 | /* Free the VLC tables. */ |
259 | for (i=0 ; i<13 ; i++) { | 186 | for (i=0 ; i<13 ; i++) { |
260 | free_vlc(&q->envelope_quant_index[i]); | 187 | free_vlc(&q->envelope_quant_index[i]); |
@@ -444,37 +371,6 @@ static inline void expand_category(COOKContext *q, int* category, | |||
444 | } | 371 | } |
445 | 372 | ||
446 | /** | 373 | /** |
447 | * The real requantization of the mltcoefs | ||
448 | * | ||
449 | * @param q pointer to the COOKContext | ||
450 | * @param index index | ||
451 | * @param quant_index quantisation index | ||
452 | * @param subband_coef_index array of indexes to quant_centroid_tab | ||
453 | * @param subband_coef_sign signs of coefficients | ||
454 | * @param mlt_p pointer into the mlt buffer | ||
455 | */ | ||
456 | |||
457 | #if 0 | ||
458 | static void scalar_dequant_float(COOKContext *q, int index, int quant_index, | ||
459 | int* subband_coef_index, int* subband_coef_sign, | ||
460 | float* mlt_p){ | ||
461 | int i; | ||
462 | float f1; | ||
463 | |||
464 | for(i=0 ; i<SUBBAND_SIZE ; i++) { | ||
465 | if (subband_coef_index[i]) { | ||
466 | f1 = quant_centroid_tab[index][subband_coef_index[i]]; | ||
467 | if (subband_coef_sign[i]) f1 = -f1; | ||
468 | } else { | ||
469 | /* noise coding if subband_coef_index[i] == 0 */ | ||
470 | f1 = dither_tab[index]; | ||
471 | if (av_lfg_get(&q->random_state) < 0x80000000) f1 = -f1; | ||
472 | } | ||
473 | mlt_p[i] = f1 * rootpow2tab[quant_index+63]; | ||
474 | } | ||
475 | } | ||
476 | #endif | ||
477 | /** | ||
478 | * Unpack the subband_coef_index and subband_coef_sign vectors. | 374 | * Unpack the subband_coef_index and subband_coef_sign vectors. |
479 | * | 375 | * |
480 | * @param q pointer to the COOKContext | 376 | * @param q pointer to the COOKContext |
@@ -585,102 +481,6 @@ static void mono_decode(COOKContext *q, REAL_T* mlt_buffer) { | |||
585 | decode_vectors(q, category, quant_index_table, mlt_buffer); | 481 | decode_vectors(q, category, quant_index_table, mlt_buffer); |
586 | } | 482 | } |
587 | 483 | ||
588 | |||
589 | /** | ||
590 | * the actual requantization of the timedomain samples | ||
591 | * | ||
592 | * @param q pointer to the COOKContext | ||
593 | * @param buffer pointer to the timedomain buffer | ||
594 | * @param gain_index index for the block multiplier | ||
595 | * @param gain_index_next index for the next block multiplier | ||
596 | */ | ||
597 | |||
598 | #if 0 | ||
599 | static void interpolate_float(COOKContext *q, float* buffer, | ||
600 | int gain_index, int gain_index_next){ | ||
601 | int i; | ||
602 | float fc1, fc2; | ||
603 | fc1 = pow2tab[gain_index+63]; | ||
604 | |||
605 | if(gain_index == gain_index_next){ //static gain | ||
606 | for(i=0 ; i<q->gain_size_factor ; i++){ | ||
607 | buffer[i]*=fc1; | ||
608 | } | ||
609 | return; | ||
610 | } else { //smooth gain | ||
611 | fc2 = q->gain_table[11 + (gain_index_next-gain_index)]; | ||
612 | for(i=0 ; i<q->gain_size_factor ; i++){ | ||
613 | buffer[i]*=fc1; | ||
614 | fc1*=fc2; | ||
615 | } | ||
616 | return; | ||
617 | } | ||
618 | } | ||
619 | #endif | ||
620 | |||
621 | /** | ||
622 | * Apply transform window, overlap buffers. | ||
623 | * | ||
624 | * @param q pointer to the COOKContext | ||
625 | * @param inbuffer pointer to the mltcoefficients | ||
626 | * @param gains_ptr current and previous gains | ||
627 | * @param previous_buffer pointer to the previous buffer to be used for overlapping | ||
628 | */ | ||
629 | |||
630 | static void imlt_window_float (COOKContext *q, float *buffer1, | ||
631 | cook_gains *gains_ptr, float *previous_buffer) | ||
632 | { | ||
633 | const float fc = pow2tab[gains_ptr->previous[0] + 63]; | ||
634 | int i; | ||
635 | /* The weird thing here, is that the two halves of the time domain | ||
636 | * buffer are swapped. Also, the newest data, that we save away for | ||
637 | * next frame, has the wrong sign. Hence the subtraction below. | ||
638 | * Almost sounds like a complex conjugate/reverse data/FFT effect. | ||
639 | */ | ||
640 | |||
641 | /* Apply window and overlap */ | ||
642 | for(i = 0; i < q->samples_per_channel; i++){ | ||
643 | buffer1[i] = buffer1[i] * fc * q->mlt_window[i] - | ||
644 | previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i]; | ||
645 | } | ||
646 | } | ||
647 | |||
648 | /** | ||
649 | * The modulated lapped transform, this takes transform coefficients | ||
650 | * and transforms them into timedomain samples. | ||
651 | * Apply transform window, overlap buffers, apply gain profile | ||
652 | * and buffer management. | ||
653 | * | ||
654 | * @param q pointer to the COOKContext | ||
655 | * @param inbuffer pointer to the mltcoefficients | ||
656 | * @param gains_ptr current and previous gains | ||
657 | * @param previous_buffer pointer to the previous buffer to be used for overlapping | ||
658 | */ | ||
659 | #if 0 | ||
660 | static void imlt_gain(COOKContext *q, REAL_T *inbuffer, | ||
661 | cook_gains *gains_ptr, REAL_T* previous_buffer) | ||
662 | { | ||
663 | REAL_T *buffer0 = q->mono_mdct_output; | ||
664 | REAL_T *buffer1 = q->mono_mdct_output + q->samples_per_channel; | ||
665 | int i; | ||
666 | |||
667 | /* Inverse modified discrete cosine transform */ | ||
668 | ff_imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer); | ||
669 | |||
670 | q->imlt_window (q, buffer1, gains_ptr, previous_buffer); | ||
671 | |||
672 | /* Apply gain profile */ | ||
673 | for (i = 0; i < 8; i++) { | ||
674 | if (gains_ptr->now[i] || gains_ptr->now[i + 1]) | ||
675 | q->interpolate(q, &buffer1[q->gain_size_factor * i], | ||
676 | gains_ptr->now[i], gains_ptr->now[i + 1]); | ||
677 | } | ||
678 | |||
679 | /* Save away the current to be previous block. */ | ||
680 | memcpy(previous_buffer, buffer0, sizeof(float)*q->samples_per_channel); | ||
681 | } | ||
682 | |||
683 | #endif | ||
684 | /** | 484 | /** |
685 | * function for getting the jointstereo coupling information | 485 | * function for getting the jointstereo coupling information |
686 | * | 486 | * |
@@ -711,31 +511,6 @@ static void decouple_info(COOKContext *q, int* decouple_tab){ | |||
711 | return; | 511 | return; |
712 | } | 512 | } |
713 | 513 | ||
714 | /* | ||
715 | * function decouples a pair of signals from a single signal via multiplication. | ||
716 | * | ||
717 | * @param q pointer to the COOKContext | ||
718 | * @param subband index of the current subband | ||
719 | * @param f1 multiplier for channel 1 extraction | ||
720 | * @param f2 multiplier for channel 2 extraction | ||
721 | * @param decode_buffer input buffer | ||
722 | * @param mlt_buffer1 pointer to left channel mlt coefficients | ||
723 | * @param mlt_buffer2 pointer to right channel mlt coefficients | ||
724 | */ | ||
725 | static void decouple_float (COOKContext *q, | ||
726 | int subband, | ||
727 | REAL_T f1, REAL_T f2, | ||
728 | REAL_T *decode_buffer, | ||
729 | REAL_T *mlt_buffer1, REAL_T *mlt_buffer2) | ||
730 | { | ||
731 | int j, tmp_idx; | ||
732 | for (j=0 ; j<SUBBAND_SIZE ; j++) { | ||
733 | tmp_idx = ((q->js_subband_start + subband)*SUBBAND_SIZE)+j; | ||
734 | mlt_buffer1[SUBBAND_SIZE*subband + j] = f1 * decode_buffer[tmp_idx]; | ||
735 | mlt_buffer2[SUBBAND_SIZE*subband + j] = f2 * decode_buffer[tmp_idx]; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | /** | 514 | /** |
740 | * function for decoding joint stereo data | 515 | * function for decoding joint stereo data |
741 | * | 516 | * |
@@ -809,26 +584,6 @@ decode_bytes_and_gain(COOKContext *q, const uint8_t *inbuffer, | |||
809 | FFSWAP(int *, gains_ptr->now, gains_ptr->previous); | 584 | FFSWAP(int *, gains_ptr->now, gains_ptr->previous); |
810 | } | 585 | } |
811 | 586 | ||
812 | /** | ||
813 | * Saturate the output signal to signed 16bit integers. | ||
814 | * | ||
815 | * @param q pointer to the COOKContext | ||
816 | * @param chan channel to saturate | ||
817 | * @param out pointer to the output vector | ||
818 | */ | ||
819 | static void | ||
820 | saturate_output_float (COOKContext *q, int chan, int16_t *out) | ||
821 | { | ||
822 | int j; | ||
823 | float *output = (float*)q->mono_mdct_output + q->samples_per_channel; | ||
824 | /* Clip and convert floats to 16 bits. | ||
825 | */ | ||
826 | for (j = 0; j < q->samples_per_channel; j++) { | ||
827 | out[chan + q->nb_channels * j] = | ||
828 | av_clip_int16(lrintf(output[j])); | ||
829 | } | ||
830 | } | ||
831 | |||
832 | /** | 587 | /** |
833 | * Final part of subpacket decoding: | 588 | * Final part of subpacket decoding: |
834 | * Apply modulated lapped transform, gain compensation, | 589 | * Apply modulated lapped transform, gain compensation, |
@@ -965,18 +720,6 @@ static void dump_cook_context(COOKContext *q) | |||
965 | } | 720 | } |
966 | #endif | 721 | #endif |
967 | 722 | ||
968 | #if 0 | ||
969 | static av_cold int cook_count_channels(unsigned int mask){ | ||
970 | int i; | ||
971 | int channels = 0; | ||
972 | for(i = 0;i<32;i++){ | ||
973 | if(mask & (1<<i)) | ||
974 | ++channels; | ||
975 | } | ||
976 | return channels; | ||
977 | } | ||
978 | #endif | ||
979 | |||
980 | /** | 723 | /** |
981 | * Cook initialization | 724 | * Cook initialization |
982 | */ | 725 | */ |
@@ -1057,10 +800,6 @@ av_cold int cook_decode_init(RMContext *rmctx, COOKContext *q) | |||
1057 | q->numvector_size = (1 << q->log2_numvector_size); | 800 | q->numvector_size = (1 << q->log2_numvector_size); |
1058 | 801 | ||
1059 | /* Generate tables */ | 802 | /* Generate tables */ |
1060 | init_pow2table(); | ||
1061 | init_gain_table(q); | ||
1062 | init_cplscales_table(q); | ||
1063 | |||
1064 | if (init_cook_vlc_tables(q) != 0) | 803 | if (init_cook_vlc_tables(q) != 0) |
1065 | return -1; | 804 | return -1; |
1066 | 805 | ||
@@ -1092,17 +831,11 @@ av_cold int cook_decode_init(RMContext *rmctx, COOKContext *q) | |||
1092 | q->gains2.now = q->gain_3; | 831 | q->gains2.now = q->gain_3; |
1093 | q->gains2.previous = q->gain_4; | 832 | q->gains2.previous = q->gain_4; |
1094 | 833 | ||
1095 | /* Initialize transform. */ | ||
1096 | if ( init_cook_mlt(q) != 0 ) | ||
1097 | return -1; | ||
1098 | 834 | ||
1099 | /* Initialize COOK signal arithmetic handling */ | 835 | /* Initialize COOK signal arithmetic handling */ |
1100 | if (1) { | 836 | if (1) { |
1101 | q->scalar_dequant = scalar_dequant_math; | 837 | q->scalar_dequant = scalar_dequant_math; |
1102 | q->decouple = decouple_float; | ||
1103 | q->imlt_window = imlt_window_float; | ||
1104 | q->interpolate = interpolate_math; | 838 | q->interpolate = interpolate_math; |
1105 | q->saturate_output = saturate_output_float; | ||
1106 | } | 839 | } |
1107 | 840 | ||
1108 | /* Try to catch some obviously faulty streams, othervise it might be exploitable */ | 841 | /* Try to catch some obviously faulty streams, othervise it might be exploitable */ |
diff --git a/apps/codecs/libcook/cook.h b/apps/codecs/libcook/cook.h index c4c06cd4f1..e34883255b 100644 --- a/apps/codecs/libcook/cook.h +++ b/apps/codecs/libcook/cook.h | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <stdint.h> | 25 | #include <stdint.h> |
26 | #include "libavutil/lfg.h" | 26 | #include "libavutil/lfg.h" |
27 | #include "bitstream.h" | 27 | #include "bitstream.h" |
28 | #include "dsputil.h" | ||
29 | #include "bytestream.h" | 28 | #include "bytestream.h" |
30 | #include "rm2wav.h" | 29 | #include "rm2wav.h" |
31 | #include "cookdata_fixpoint.h" | 30 | #include "cookdata_fixpoint.h" |
@@ -44,20 +43,9 @@ typedef struct cook { | |||
44 | int* subband_coef_index, int* subband_coef_sign, | 43 | int* subband_coef_index, int* subband_coef_sign, |
45 | REAL_T* mlt_p); | 44 | REAL_T* mlt_p); |
46 | 45 | ||
47 | void (* decouple) (struct cook *q, | ||
48 | int subband, | ||
49 | REAL_T f1, REAL_T f2, | ||
50 | REAL_T *decode_buffer, | ||
51 | REAL_T *mlt_buffer1, REAL_T *mlt_buffer2); | ||
52 | |||
53 | void (* imlt_window) (struct cook *q, float *buffer1, | ||
54 | cook_gains *gains_ptr, float *previous_buffer); | ||
55 | |||
56 | void (* interpolate) (struct cook *q, REAL_T* buffer, | 46 | void (* interpolate) (struct cook *q, REAL_T* buffer, |
57 | int gain_index, int gain_index_next); | 47 | int gain_index, int gain_index_next); |
58 | 48 | ||
59 | void (* saturate_output) (struct cook *q, int chan, int16_t *out); | ||
60 | |||
61 | GetBitContext gb; | 49 | GetBitContext gb; |
62 | int frame_number; | 50 | int frame_number; |
63 | int block_align; | 51 | int block_align; |
@@ -79,9 +67,6 @@ typedef struct cook { | |||
79 | int cookversion; | 67 | int cookversion; |
80 | /* states */ | 68 | /* states */ |
81 | AVLFG random_state; | 69 | AVLFG random_state; |
82 | /* transform data */ | ||
83 | MDCTContext mdct_ctx; | ||
84 | float* mlt_window; | ||
85 | 70 | ||
86 | /* gain buffers */ | 71 | /* gain buffers */ |
87 | cook_gains gains1; | 72 | cook_gains gains1; |
@@ -110,8 +95,6 @@ typedef struct cook { | |||
110 | REAL_T decode_buffer_1[1024]; | 95 | REAL_T decode_buffer_1[1024]; |
111 | REAL_T decode_buffer_2[1024]; | 96 | REAL_T decode_buffer_2[1024]; |
112 | REAL_T decode_buffer_0[1060]; /* static allocation for joint decode */ | 97 | REAL_T decode_buffer_0[1060]; /* static allocation for joint decode */ |
113 | |||
114 | const float *cplscales[5]; | ||
115 | } COOKContext; | 98 | } COOKContext; |
116 | 99 | ||
117 | av_cold int cook_decode_init(RMContext *rmctx, COOKContext *q); | 100 | av_cold int cook_decode_init(RMContext *rmctx, COOKContext *q); |
diff --git a/apps/codecs/libcook/dsputil.h b/apps/codecs/libcook/dsputil.h index 4573c17a62..e69de29bb2 100644 --- a/apps/codecs/libcook/dsputil.h +++ b/apps/codecs/libcook/dsputil.h | |||
@@ -1,908 +0,0 @@ | |||
1 | /* | ||
2 | * DSP utils | ||
3 | * Copyright (c) 2000, 2001, 2002 Fabrice Bellard | ||
4 | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> | ||
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 | * @file libavcodec/dsputil.h | ||
25 | * DSP utils. | ||
26 | * note, many functions in here may use MMX which trashes the FPU state, it is | ||
27 | * absolutely necessary to call emms_c() between dsp & float/double code | ||
28 | */ | ||
29 | |||
30 | #ifndef AVCODEC_DSPUTIL_H | ||
31 | #define AVCODEC_DSPUTIL_H | ||
32 | |||
33 | #include "libavutil/intreadwrite.h" | ||
34 | #include "avcodec.h" | ||
35 | |||
36 | |||
37 | //#define DEBUG | ||
38 | /* dct code */ | ||
39 | #if 0 /*MT : DELETE THIS LINE.*/ | ||
40 | typedef short DCTELEM; | ||
41 | typedef int DWTELEM; | ||
42 | typedef short IDWTELEM; | ||
43 | |||
44 | void fdct_ifast (DCTELEM *data); | ||
45 | void fdct_ifast248 (DCTELEM *data); | ||
46 | void ff_jpeg_fdct_islow (DCTELEM *data); | ||
47 | void ff_fdct248_islow (DCTELEM *data); | ||
48 | |||
49 | void j_rev_dct (DCTELEM *data); | ||
50 | void j_rev_dct4 (DCTELEM *data); | ||
51 | void j_rev_dct2 (DCTELEM *data); | ||
52 | void j_rev_dct1 (DCTELEM *data); | ||
53 | void ff_wmv2_idct_c(DCTELEM *data); | ||
54 | |||
55 | void ff_fdct_mmx(DCTELEM *block); | ||
56 | void ff_fdct_mmx2(DCTELEM *block); | ||
57 | void ff_fdct_sse2(DCTELEM *block); | ||
58 | |||
59 | void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); | ||
60 | void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); | ||
61 | void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); | ||
62 | void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); | ||
63 | void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); | ||
64 | void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); | ||
65 | void ff_h264_idct_add16_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); | ||
66 | void ff_h264_idct_add16intra_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); | ||
67 | void ff_h264_idct8_add4_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); | ||
68 | void ff_h264_idct_add8_c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); | ||
69 | |||
70 | void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, | ||
71 | const float *src2, int src3, int blocksize, int step); | ||
72 | void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, | ||
73 | const float *win, float add_bias, int len); | ||
74 | void ff_float_to_int16_c(int16_t *dst, const float *src, long len); | ||
75 | void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels); | ||
76 | |||
77 | /* encoding scans */ | ||
78 | extern const uint8_t ff_alternate_horizontal_scan[64]; | ||
79 | extern const uint8_t ff_alternate_vertical_scan[64]; | ||
80 | extern const uint8_t ff_zigzag_direct[64]; | ||
81 | extern const uint8_t ff_zigzag248_direct[64]; | ||
82 | |||
83 | /* pixel operations */ | ||
84 | #define MAX_NEG_CROP 1024 | ||
85 | |||
86 | /* temporary */ | ||
87 | extern uint32_t ff_squareTbl[512]; | ||
88 | extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP]; | ||
89 | |||
90 | /* VP3 DSP functions */ | ||
91 | void ff_vp3_idct_c(DCTELEM *block/* align 16*/); | ||
92 | void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); | ||
93 | void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); | ||
94 | |||
95 | void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values); | ||
96 | void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); | ||
97 | |||
98 | /* VP6 DSP functions */ | ||
99 | void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, | ||
100 | const int16_t *h_weights, const int16_t *v_weights); | ||
101 | |||
102 | /* 1/2^n downscaling functions from imgconvert.c */ | ||
103 | void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); | ||
104 | void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); | ||
105 | void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); | ||
106 | void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); | ||
107 | |||
108 | void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, | ||
109 | int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); | ||
110 | |||
111 | /* minimum alignment rules ;) | ||
112 | If you notice errors in the align stuff, need more alignment for some ASM code | ||
113 | for some CPU or need to use a function with less aligned data then send a mail | ||
114 | to the ffmpeg-devel mailing list, ... | ||
115 | |||
116 | !warning These alignments might not match reality, (missing attribute((align)) | ||
117 | stuff somewhere possible). | ||
118 | I (Michael) did not check them, these are just the alignments which I think | ||
119 | could be reached easily ... | ||
120 | |||
121 | !future video codecs might need functions with less strict alignment | ||
122 | */ | ||
123 | |||
124 | /* | ||
125 | void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size); | ||
126 | void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride); | ||
127 | void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); | ||
128 | void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); | ||
129 | void clear_blocks_c(DCTELEM *blocks); | ||
130 | */ | ||
131 | |||
132 | /* add and put pixel (decoding) */ | ||
133 | // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 | ||
134 | //h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 | ||
135 | typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); | ||
136 | typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); | ||
137 | typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); | ||
138 | typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); | ||
139 | typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset); | ||
140 | typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset); | ||
141 | |||
142 | #define DEF_OLD_QPEL(name)\ | ||
143 | void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ | ||
144 | void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ | ||
145 | void ff_avg_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); | ||
146 | |||
147 | DEF_OLD_QPEL(qpel16_mc11_old_c) | ||
148 | DEF_OLD_QPEL(qpel16_mc31_old_c) | ||
149 | DEF_OLD_QPEL(qpel16_mc12_old_c) | ||
150 | DEF_OLD_QPEL(qpel16_mc32_old_c) | ||
151 | DEF_OLD_QPEL(qpel16_mc13_old_c) | ||
152 | DEF_OLD_QPEL(qpel16_mc33_old_c) | ||
153 | DEF_OLD_QPEL(qpel8_mc11_old_c) | ||
154 | DEF_OLD_QPEL(qpel8_mc31_old_c) | ||
155 | DEF_OLD_QPEL(qpel8_mc12_old_c) | ||
156 | DEF_OLD_QPEL(qpel8_mc32_old_c) | ||
157 | DEF_OLD_QPEL(qpel8_mc13_old_c) | ||
158 | DEF_OLD_QPEL(qpel8_mc33_old_c) | ||
159 | |||
160 | #define CALL_2X_PIXELS(a, b, n)\ | ||
161 | static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ | ||
162 | b(block , pixels , line_size, h);\ | ||
163 | b(block+n, pixels+n, line_size, h);\ | ||
164 | } | ||
165 | |||
166 | /* motion estimation */ | ||
167 | // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 | ||
168 | // although currently h<4 is not used as functions with width <8 are neither used nor implemented | ||
169 | typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; | ||
170 | |||
171 | |||
172 | // for snow slices | ||
173 | typedef struct slice_buffer_s slice_buffer; | ||
174 | |||
175 | /** | ||
176 | * Scantable. | ||
177 | */ | ||
178 | typedef struct ScanTable{ | ||
179 | const uint8_t *scantable; | ||
180 | uint8_t permutated[64]; | ||
181 | uint8_t raster_end[64]; | ||
182 | #if ARCH_PPC | ||
183 | /** Used by dct_quantize_altivec to find last-non-zero */ | ||
184 | DECLARE_ALIGNED(16, uint8_t, inverse[64]); | ||
185 | #endif | ||
186 | } ScanTable; | ||
187 | |||
188 | void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); | ||
189 | |||
190 | void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, | ||
191 | int block_w, int block_h, | ||
192 | int src_x, int src_y, int w, int h); | ||
193 | |||
194 | /** | ||
195 | * DSPContext. | ||
196 | */ | ||
197 | typedef struct DSPContext { | ||
198 | /* pixel ops : interface with DCT */ | ||
199 | void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); | ||
200 | void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); | ||
201 | void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); | ||
202 | void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); | ||
203 | void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); | ||
204 | void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); | ||
205 | void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); | ||
206 | int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); | ||
207 | /** | ||
208 | * translational global motion compensation. | ||
209 | */ | ||
210 | void (*gmc1)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder); | ||
211 | /** | ||
212 | * global motion compensation. | ||
213 | */ | ||
214 | void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, | ||
215 | int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); | ||
216 | void (*clear_block)(DCTELEM *block/*align 16*/); | ||
217 | void (*clear_blocks)(DCTELEM *blocks/*align 16*/); | ||
218 | int (*pix_sum)(uint8_t * pix, int line_size); | ||
219 | int (*pix_norm1)(uint8_t * pix, int line_size); | ||
220 | // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 | ||
221 | |||
222 | me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */ | ||
223 | me_cmp_func sse[6]; | ||
224 | me_cmp_func hadamard8_diff[6]; | ||
225 | me_cmp_func dct_sad[6]; | ||
226 | me_cmp_func quant_psnr[6]; | ||
227 | me_cmp_func bit[6]; | ||
228 | me_cmp_func rd[6]; | ||
229 | me_cmp_func vsad[6]; | ||
230 | me_cmp_func vsse[6]; | ||
231 | me_cmp_func nsse[6]; | ||
232 | me_cmp_func w53[6]; | ||
233 | me_cmp_func w97[6]; | ||
234 | me_cmp_func dct_max[6]; | ||
235 | me_cmp_func dct264_sad[6]; | ||
236 | |||
237 | me_cmp_func me_pre_cmp[6]; | ||
238 | me_cmp_func me_cmp[6]; | ||
239 | me_cmp_func me_sub_cmp[6]; | ||
240 | me_cmp_func mb_cmp[6]; | ||
241 | me_cmp_func ildct_cmp[6]; //only width 16 used | ||
242 | me_cmp_func frame_skip_cmp[6]; //only width 8 used | ||
243 | |||
244 | int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, | ||
245 | int size); | ||
246 | |||
247 | /** | ||
248 | * Halfpel motion compensation with rounding (a+b+1)>>1. | ||
249 | * this is an array[4][4] of motion compensation functions for 4 | ||
250 | * horizontal blocksizes (8,16) and the 4 halfpel positions<br> | ||
251 | * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] | ||
252 | * @param block destination where the result is stored | ||
253 | * @param pixels source | ||
254 | * @param line_size number of bytes in a horizontal line of block | ||
255 | * @param h height | ||
256 | */ | ||
257 | op_pixels_func put_pixels_tab[4][4]; | ||
258 | |||
259 | /** | ||
260 | * Halfpel motion compensation with rounding (a+b+1)>>1. | ||
261 | * This is an array[4][4] of motion compensation functions for 4 | ||
262 | * horizontal blocksizes (8,16) and the 4 halfpel positions<br> | ||
263 | * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] | ||
264 | * @param block destination into which the result is averaged (a+b+1)>>1 | ||
265 | * @param pixels source | ||
266 | * @param line_size number of bytes in a horizontal line of block | ||
267 | * @param h height | ||
268 | */ | ||
269 | op_pixels_func avg_pixels_tab[4][4]; | ||
270 | |||
271 | /** | ||
272 | * Halfpel motion compensation with no rounding (a+b)>>1. | ||
273 | * this is an array[2][4] of motion compensation functions for 2 | ||
274 | * horizontal blocksizes (8,16) and the 4 halfpel positions<br> | ||
275 | * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] | ||
276 | * @param block destination where the result is stored | ||
277 | * @param pixels source | ||
278 | * @param line_size number of bytes in a horizontal line of block | ||
279 | * @param h height | ||
280 | */ | ||
281 | op_pixels_func put_no_rnd_pixels_tab[4][4]; | ||
282 | |||
283 | /** | ||
284 | * Halfpel motion compensation with no rounding (a+b)>>1. | ||
285 | * this is an array[2][4] of motion compensation functions for 2 | ||
286 | * horizontal blocksizes (8,16) and the 4 halfpel positions<br> | ||
287 | * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] | ||
288 | * @param block destination into which the result is averaged (a+b)>>1 | ||
289 | * @param pixels source | ||
290 | * @param line_size number of bytes in a horizontal line of block | ||
291 | * @param h height | ||
292 | */ | ||
293 | op_pixels_func avg_no_rnd_pixels_tab[4][4]; | ||
294 | |||
295 | void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h); | ||
296 | |||
297 | /** | ||
298 | * Thirdpel motion compensation with rounding (a+b+1)>>1. | ||
299 | * this is an array[12] of motion compensation functions for the 9 thirdpe | ||
300 | * positions<br> | ||
301 | * *pixels_tab[ xthirdpel + 4*ythirdpel ] | ||
302 | * @param block destination where the result is stored | ||
303 | * @param pixels source | ||
304 | * @param line_size number of bytes in a horizontal line of block | ||
305 | * @param h height | ||
306 | */ | ||
307 | tpel_mc_func put_tpel_pixels_tab[11]; //FIXME individual func ptr per width? | ||
308 | tpel_mc_func avg_tpel_pixels_tab[11]; //FIXME individual func ptr per width? | ||
309 | |||
310 | qpel_mc_func put_qpel_pixels_tab[2][16]; | ||
311 | qpel_mc_func avg_qpel_pixels_tab[2][16]; | ||
312 | qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; | ||
313 | qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; | ||
314 | qpel_mc_func put_mspel_pixels_tab[8]; | ||
315 | |||
316 | /** | ||
317 | * h264 Chroma MC | ||
318 | */ | ||
319 | h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; | ||
320 | /* This is really one func used in VC-1 decoding */ | ||
321 | h264_chroma_mc_func put_no_rnd_h264_chroma_pixels_tab[3]; | ||
322 | h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; | ||
323 | |||
324 | qpel_mc_func put_h264_qpel_pixels_tab[4][16]; | ||
325 | qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; | ||
326 | |||
327 | qpel_mc_func put_2tap_qpel_pixels_tab[4][16]; | ||
328 | qpel_mc_func avg_2tap_qpel_pixels_tab[4][16]; | ||
329 | |||
330 | h264_weight_func weight_h264_pixels_tab[10]; | ||
331 | h264_biweight_func biweight_h264_pixels_tab[10]; | ||
332 | |||
333 | /* AVS specific */ | ||
334 | qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; | ||
335 | qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; | ||
336 | void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); | ||
337 | void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); | ||
338 | void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); | ||
339 | void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); | ||
340 | void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); | ||
341 | |||
342 | me_cmp_func pix_abs[2][4]; | ||
343 | |||
344 | /* huffyuv specific */ | ||
345 | void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); | ||
346 | void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); | ||
347 | void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); | ||
348 | /** | ||
349 | * subtract huffyuv's variant of median prediction | ||
350 | * note, this might read from src1[-1], src2[-1] | ||
351 | */ | ||
352 | void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); | ||
353 | void (*add_hfyu_median_prediction)(uint8_t *dst, uint8_t *top, uint8_t *diff, int w, int *left, int *left_top); | ||
354 | /* this might write to dst[w] */ | ||
355 | void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); | ||
356 | void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); | ||
357 | |||
358 | void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0); | ||
359 | void (*h264_h_loop_filter_luma)(uint8_t *pix/*align 4 */, int stride, int alpha, int beta, int8_t *tc0); | ||
360 | /* v/h_loop_filter_luma_intra: align 16 */ | ||
361 | void (*h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta); | ||
362 | void (*h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta); | ||
363 | void (*h264_v_loop_filter_chroma)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0); | ||
364 | void (*h264_h_loop_filter_chroma)(uint8_t *pix/*align 4*/, int stride, int alpha, int beta, int8_t *tc0); | ||
365 | void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); | ||
366 | void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); | ||
367 | // h264_loop_filter_strength: simd only. the C version is inlined in h264.c | ||
368 | void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], | ||
369 | int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field); | ||
370 | |||
371 | void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); | ||
372 | void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); | ||
373 | |||
374 | void (*h261_loop_filter)(uint8_t *src, int stride); | ||
375 | |||
376 | void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); | ||
377 | void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); | ||
378 | |||
379 | void (*vp3_v_loop_filter)(uint8_t *src, int stride, int *bounding_values); | ||
380 | void (*vp3_h_loop_filter)(uint8_t *src, int stride, int *bounding_values); | ||
381 | |||
382 | void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, | ||
383 | const int16_t *h_weights,const int16_t *v_weights); | ||
384 | |||
385 | /* assume len is a multiple of 4, and arrays are 16-byte aligned */ | ||
386 | void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); | ||
387 | void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); | ||
388 | /* no alignment needed */ | ||
389 | void (*flac_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc); | ||
390 | /* assume len is a multiple of 8, and arrays are 16-byte aligned */ | ||
391 | void (*vector_fmul)(float *dst, const float *src, int len); | ||
392 | void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); | ||
393 | /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ | ||
394 | void (*vector_fmul_add_add)(float *dst, const float *src0, const float *src1, const float *src2, int src3, int len, int step); | ||
395 | /* assume len is a multiple of 4, and arrays are 16-byte aligned */ | ||
396 | void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); | ||
397 | /* assume len is a multiple of 8, and arrays are 16-byte aligned */ | ||
398 | void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); | ||
399 | |||
400 | /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] | ||
401 | * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ | ||
402 | void (*float_to_int16)(int16_t *dst, const float *src, long len); | ||
403 | void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); | ||
404 | |||
405 | /* (I)DCT */ | ||
406 | void (*fdct)(DCTELEM *block/* align 16*/); | ||
407 | void (*fdct248)(DCTELEM *block/* align 16*/); | ||
408 | |||
409 | /* IDCT really*/ | ||
410 | void (*idct)(DCTELEM *block/* align 16*/); | ||
411 | |||
412 | /** | ||
413 | * block -> idct -> clip to unsigned 8 bit -> dest. | ||
414 | * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) | ||
415 | * @param line_size size in bytes of a horizontal line of dest | ||
416 | */ | ||
417 | void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); | ||
418 | |||
419 | /** | ||
420 | * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. | ||
421 | * @param line_size size in bytes of a horizontal line of dest | ||
422 | */ | ||
423 | void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); | ||
424 | |||
425 | /** | ||
426 | * idct input permutation. | ||
427 | * several optimized IDCTs need a permutated input (relative to the normal order of the reference | ||
428 | * IDCT) | ||
429 | * this permutation must be performed before the idct_put/add, note, normally this can be merged | ||
430 | * with the zigzag/alternate scan<br> | ||
431 | * an example to avoid confusion: | ||
432 | * - (->decode coeffs -> zigzag reorder -> dequant -> reference idct ->...) | ||
433 | * - (x -> referece dct -> reference idct -> x) | ||
434 | * - (x -> referece dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x) | ||
435 | * - (->decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant -> simple_idct_mmx ->...) | ||
436 | */ | ||
437 | uint8_t idct_permutation[64]; | ||
438 | int idct_permutation_type; | ||
439 | #define FF_NO_IDCT_PERM 1 | ||
440 | #define FF_LIBMPEG2_IDCT_PERM 2 | ||
441 | #define FF_SIMPLE_IDCT_PERM 3 | ||
442 | #define FF_TRANSPOSE_IDCT_PERM 4 | ||
443 | #define FF_PARTTRANS_IDCT_PERM 5 | ||
444 | #define FF_SSE2_IDCT_PERM 6 | ||
445 | |||
446 | int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); | ||
447 | void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); | ||
448 | #define BASIS_SHIFT 16 | ||
449 | #define RECON_SHIFT 6 | ||
450 | |||
451 | void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); | ||
452 | #define EDGE_WIDTH 16 | ||
453 | |||
454 | /* h264 functions */ | ||
455 | /* NOTE!!! if you implement any of h264_idct8_add, h264_idct8_add4 then you must implement all of them | ||
456 | NOTE!!! if you implement any of h264_idct_add, h264_idct_add16, h264_idct_add16intra, h264_idct_add8 then you must implement all of them | ||
457 | The reason for above, is that no 2 out of one list may use a different permutation. | ||
458 | */ | ||
459 | void (*h264_idct_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); | ||
460 | void (*h264_idct8_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); | ||
461 | void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); | ||
462 | void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); | ||
463 | void (*h264_dct)(DCTELEM block[4][4]); | ||
464 | void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | ||
465 | void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | ||
466 | void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | ||
467 | void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | ||
468 | |||
469 | /* snow wavelet */ | ||
470 | void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); | ||
471 | void (*horizontal_compose97i)(IDWTELEM *b, int width); | ||
472 | void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); | ||
473 | |||
474 | void (*prefetch)(void *mem, int stride, int h); | ||
475 | |||
476 | void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); | ||
477 | |||
478 | /* vc1 functions */ | ||
479 | void (*vc1_inv_trans_8x8)(DCTELEM *b); | ||
480 | void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); | ||
481 | void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); | ||
482 | void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); | ||
483 | void (*vc1_v_overlap)(uint8_t* src, int stride); | ||
484 | void (*vc1_h_overlap)(uint8_t* src, int stride); | ||
485 | /* put 8x8 block with bicubic interpolation and quarterpel precision | ||
486 | * last argument is actually round value instead of height | ||
487 | */ | ||
488 | op_pixels_func put_vc1_mspel_pixels_tab[16]; | ||
489 | |||
490 | /* intrax8 functions */ | ||
491 | void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); | ||
492 | void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, | ||
493 | int * range, int * sum, int edges); | ||
494 | |||
495 | /* ape functions */ | ||
496 | /** | ||
497 | * Add contents of the second vector to the first one. | ||
498 | * @param len length of vectors, should be multiple of 16 | ||
499 | */ | ||
500 | void (*add_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); | ||
501 | /** | ||
502 | * Add contents of the second vector to the first one. | ||
503 | * @param len length of vectors, should be multiple of 16 | ||
504 | */ | ||
505 | void (*sub_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); | ||
506 | /** | ||
507 | * Calculate scalar product of two vectors. | ||
508 | * @param len length of vectors, should be multiple of 16 | ||
509 | * @param shift number of bits to discard from product | ||
510 | */ | ||
511 | int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift); | ||
512 | |||
513 | /* rv30 functions */ | ||
514 | qpel_mc_func put_rv30_tpel_pixels_tab[4][16]; | ||
515 | qpel_mc_func avg_rv30_tpel_pixels_tab[4][16]; | ||
516 | |||
517 | /* rv40 functions */ | ||
518 | qpel_mc_func put_rv40_qpel_pixels_tab[4][16]; | ||
519 | qpel_mc_func avg_rv40_qpel_pixels_tab[4][16]; | ||
520 | h264_chroma_mc_func put_rv40_chroma_pixels_tab[3]; | ||
521 | h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3]; | ||
522 | } DSPContext; | ||
523 | |||
524 | void dsputil_static_init(void); | ||
525 | void dsputil_init(DSPContext* p, AVCodecContext *avctx); | ||
526 | |||
527 | int ff_check_alignment(void); | ||
528 | |||
529 | /** | ||
530 | * permute block according to permuatation. | ||
531 | * @param last last non zero element in scantable order | ||
532 | */ | ||
533 | void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last); | ||
534 | |||
535 | void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); | ||
536 | |||
537 | #define BYTE_VEC32(c) ((c)*0x01010101UL) | ||
538 | |||
539 | static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) | ||
540 | { | ||
541 | return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); | ||
542 | } | ||
543 | |||
544 | static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) | ||
545 | { | ||
546 | return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); | ||
547 | } | ||
548 | |||
549 | static inline int get_penalty_factor(int lambda, int lambda2, int type){ | ||
550 | switch(type&0xFF){ | ||
551 | default: | ||
552 | case FF_CMP_SAD: | ||
553 | return lambda>>FF_LAMBDA_SHIFT; | ||
554 | case FF_CMP_DCT: | ||
555 | return (3*lambda)>>(FF_LAMBDA_SHIFT+1); | ||
556 | case FF_CMP_W53: | ||
557 | return (4*lambda)>>(FF_LAMBDA_SHIFT); | ||
558 | case FF_CMP_W97: | ||
559 | return (2*lambda)>>(FF_LAMBDA_SHIFT); | ||
560 | case FF_CMP_SATD: | ||
561 | case FF_CMP_DCT264: | ||
562 | return (2*lambda)>>FF_LAMBDA_SHIFT; | ||
563 | case FF_CMP_RD: | ||
564 | case FF_CMP_PSNR: | ||
565 | case FF_CMP_SSE: | ||
566 | case FF_CMP_NSSE: | ||
567 | return lambda2>>FF_LAMBDA_SHIFT; | ||
568 | case FF_CMP_BIT: | ||
569 | return 1; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | /** | ||
574 | * Empty mmx state. | ||
575 | * this must be called between any dsp function and float/double code. | ||
576 | * for example sin(); dsp->idct_put(); emms_c(); cos() | ||
577 | */ | ||
578 | #define emms_c() | ||
579 | |||
580 | /* should be defined by architectures supporting | ||
581 | one or more MultiMedia extension */ | ||
582 | int mm_support(void); | ||
583 | |||
584 | void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); | ||
585 | void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); | ||
586 | void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); | ||
587 | void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); | ||
588 | void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); | ||
589 | void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); | ||
590 | void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); | ||
591 | void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); | ||
592 | void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); | ||
593 | |||
594 | #endif /*MT : DELETE THIS LINE ONLY. */ | ||
595 | #define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v) | ||
596 | |||
597 | #if 0 /*MT : DELETE THIS LINE ONLY. */ | ||
598 | #if HAVE_MMX | ||
599 | |||
600 | #undef emms_c | ||
601 | |||
602 | extern int mm_flags; | ||
603 | |||
604 | void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); | ||
605 | void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); | ||
606 | void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); | ||
607 | |||
608 | static inline void emms(void) | ||
609 | { | ||
610 | __asm__ volatile ("emms;":::"memory"); | ||
611 | } | ||
612 | |||
613 | |||
614 | #define emms_c() \ | ||
615 | {\ | ||
616 | if (mm_flags & FF_MM_MMX)\ | ||
617 | emms();\ | ||
618 | } | ||
619 | |||
620 | void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); | ||
621 | |||
622 | #elif ARCH_ARM | ||
623 | |||
624 | extern int mm_flags; | ||
625 | |||
626 | #if HAVE_NEON | ||
627 | # define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) | ||
628 | # define STRIDE_ALIGN 16 | ||
629 | #endif | ||
630 | |||
631 | #elif ARCH_PPC | ||
632 | |||
633 | extern int mm_flags; | ||
634 | |||
635 | #define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) | ||
636 | #define STRIDE_ALIGN 16 | ||
637 | |||
638 | #elif HAVE_MMI | ||
639 | |||
640 | #define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) | ||
641 | #define STRIDE_ALIGN 16 | ||
642 | |||
643 | #else | ||
644 | |||
645 | #define mm_flags 0 | ||
646 | #define mm_support() 0 | ||
647 | |||
648 | #endif | ||
649 | |||
650 | #endif /* MT : DELETE THIS LINE ONLY */ | ||
651 | #ifndef DECLARE_ALIGNED_8 | ||
652 | # define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(8, t, v) | ||
653 | #endif | ||
654 | |||
655 | #if 0 /* MT : DELETE THIS LINE ONLY */ | ||
656 | #ifndef STRIDE_ALIGN | ||
657 | # define STRIDE_ALIGN 8 | ||
658 | #endif | ||
659 | |||
660 | /* PSNR */ | ||
661 | void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], | ||
662 | int orig_linesize[3], int coded_linesize, | ||
663 | AVCodecContext *avctx); | ||
664 | |||
665 | #endif /*MT : DELETE THIS LINE.*/ | ||
666 | /* FFT computation */ | ||
667 | |||
668 | /* NOTE: soon integer code will be added, so you must use the | ||
669 | FFTSample type */ | ||
670 | typedef float FFTSample; | ||
671 | |||
672 | struct MDCTContext; | ||
673 | |||
674 | typedef struct FFTComplex { | ||
675 | FFTSample re, im; | ||
676 | } FFTComplex; | ||
677 | |||
678 | typedef struct FFTContext { | ||
679 | int nbits; | ||
680 | int inverse; | ||
681 | uint16_t *revtab; | ||
682 | FFTComplex *exptab; | ||
683 | FFTComplex *exptab1; /* only used by SSE code */ | ||
684 | FFTComplex *tmp_buf; | ||
685 | void (*fft_permute)(struct FFTContext *s, FFTComplex *z); | ||
686 | void (*fft_calc)(struct FFTContext *s, FFTComplex *z); | ||
687 | void (*imdct_calc)(struct MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
688 | void (*imdct_half)(struct MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
689 | } FFTContext; | ||
690 | |||
691 | extern FFTSample* ff_cos_tabs[13]; | ||
692 | |||
693 | /** | ||
694 | * Sets up a complex FFT. | ||
695 | * @param nbits log2 of the length of the input array | ||
696 | * @param inverse if 0 perform the forward transform, if 1 perform the inverse | ||
697 | */ | ||
698 | int ff_fft_init(FFTContext *s, int nbits, int inverse); | ||
699 | void ff_fft_permute_c(FFTContext *s, FFTComplex *z); | ||
700 | void ff_fft_permute_sse(FFTContext *s, FFTComplex *z); | ||
701 | void ff_fft_calc_c(FFTContext *s, FFTComplex *z); | ||
702 | void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); | ||
703 | void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z); | ||
704 | void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z); | ||
705 | void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z); | ||
706 | |||
707 | /** | ||
708 | * Do the permutation needed BEFORE calling ff_fft_calc(). | ||
709 | */ | ||
710 | static inline void ff_fft_permute(FFTContext *s, FFTComplex *z) | ||
711 | { | ||
712 | s->fft_permute(s, z); | ||
713 | } | ||
714 | /** | ||
715 | * Do a complex FFT with the parameters defined in ff_fft_init(). The | ||
716 | * input data must be permuted before. No 1.0/sqrt(n) normalization is done. | ||
717 | */ | ||
718 | static inline void ff_fft_calc(FFTContext *s, FFTComplex *z) | ||
719 | { | ||
720 | s->fft_calc(s, z); | ||
721 | } | ||
722 | void ff_fft_end(FFTContext *s); | ||
723 | |||
724 | #endif /*MT : DELETE THIS LINE.*/ | ||
725 | /* MDCT computation */ | ||
726 | |||
727 | typedef struct MDCTContext { | ||
728 | int n; /* size of MDCT (i.e. number of input data * 2) */ | ||
729 | int nbits; /* n = 2^nbits */ | ||
730 | /* pre/post rotation tables */ | ||
731 | FFTSample *tcos; | ||
732 | FFTSample *tsin; | ||
733 | FFTContext fft; | ||
734 | } MDCTContext; | ||
735 | |||
736 | static inline void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input) | ||
737 | { | ||
738 | s->fft.imdct_calc(s, output, input); | ||
739 | } | ||
740 | static inline void ff_imdct_half(MDCTContext *s, FFTSample *output, const FFTSample *input) | ||
741 | { | ||
742 | s->fft.imdct_half(s, output, input); | ||
743 | } | ||
744 | |||
745 | #if 0 /* MT : DELETE THIS LINE. */ | ||
746 | /** | ||
747 | * Generate a Kaiser-Bessel Derived Window. | ||
748 | * @param window pointer to half window | ||
749 | * @param alpha determines window shape | ||
750 | * @param n size of half window | ||
751 | */ | ||
752 | void ff_kbd_window_init(float *window, float alpha, int n); | ||
753 | #endif /* MT : DELETE THIS LINE.*/ | ||
754 | |||
755 | /** | ||
756 | * Generate a sine window. | ||
757 | * @param window pointer to half window | ||
758 | * @param n size of half window | ||
759 | */ | ||
760 | void ff_sine_window_init(float *window, int n); | ||
761 | extern float ff_sine_128 [ 128]; | ||
762 | extern float ff_sine_256 [ 256]; | ||
763 | extern float ff_sine_512 [ 512]; | ||
764 | extern float ff_sine_1024[1024]; | ||
765 | extern float ff_sine_2048[2048]; | ||
766 | extern float ff_sine_4096[4096]; | ||
767 | extern float *ff_sine_windows[6]; | ||
768 | |||
769 | int ff_mdct_init(MDCTContext *s, int nbits, int inverse); | ||
770 | void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
771 | void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
772 | void ff_imdct_calc_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
773 | void ff_imdct_half_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
774 | void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
775 | void ff_imdct_half_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
776 | void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
777 | void ff_imdct_half_sse(MDCTContext *s, FFTSample *output, const FFTSample *input); | ||
778 | void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input); | ||
779 | void ff_mdct_end(MDCTContext *s); | ||
780 | |||
781 | #if 0 /* MT : DELETE THIS LINE.*/ | ||
782 | /* Real Discrete Fourier Transform */ | ||
783 | |||
784 | enum RDFTransformType { | ||
785 | RDFT, | ||
786 | IRDFT, | ||
787 | RIDFT, | ||
788 | IRIDFT, | ||
789 | }; | ||
790 | |||
791 | typedef struct { | ||
792 | int nbits; | ||
793 | int inverse; | ||
794 | int sign_convention; | ||
795 | |||
796 | /* pre/post rotation tables */ | ||
797 | FFTSample *tcos; | ||
798 | FFTSample *tsin; | ||
799 | FFTContext fft; | ||
800 | } RDFTContext; | ||
801 | |||
802 | /** | ||
803 | * Sets up a real FFT. | ||
804 | * @param nbits log2 of the length of the input array | ||
805 | * @param trans the type of transform | ||
806 | */ | ||
807 | int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans); | ||
808 | void ff_rdft_calc(RDFTContext *s, FFTSample *data); | ||
809 | void ff_rdft_end(RDFTContext *s); | ||
810 | |||
811 | #define WRAPPER8_16(name8, name16)\ | ||
812 | static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ | ||
813 | return name8(s, dst , src , stride, h)\ | ||
814 | +name8(s, dst+8 , src+8 , stride, h);\ | ||
815 | } | ||
816 | |||
817 | #define WRAPPER8_16_SQ(name8, name16)\ | ||
818 | static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ | ||
819 | int score=0;\ | ||
820 | score +=name8(s, dst , src , stride, 8);\ | ||
821 | score +=name8(s, dst+8 , src+8 , stride, 8);\ | ||
822 | if(h==16){\ | ||
823 | dst += 8*stride;\ | ||
824 | src += 8*stride;\ | ||
825 | score +=name8(s, dst , src , stride, 8);\ | ||
826 | score +=name8(s, dst+8 , src+8 , stride, 8);\ | ||
827 | }\ | ||
828 | return score;\ | ||
829 | } | ||
830 | |||
831 | |||
832 | static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) | ||
833 | { | ||
834 | int i; | ||
835 | for(i=0; i<h; i++) | ||
836 | { | ||
837 | AV_WN16(dst , AV_RN16(src )); | ||
838 | dst+=dstStride; | ||
839 | src+=srcStride; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | static inline void copy_block4(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) | ||
844 | { | ||
845 | int i; | ||
846 | for(i=0; i<h; i++) | ||
847 | { | ||
848 | AV_WN32(dst , AV_RN32(src )); | ||
849 | dst+=dstStride; | ||
850 | src+=srcStride; | ||
851 | } | ||
852 | } | ||
853 | |||
854 | static inline void copy_block8(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) | ||
855 | { | ||
856 | int i; | ||
857 | for(i=0; i<h; i++) | ||
858 | { | ||
859 | AV_WN32(dst , AV_RN32(src )); | ||
860 | AV_WN32(dst+4 , AV_RN32(src+4 )); | ||
861 | dst+=dstStride; | ||
862 | src+=srcStride; | ||
863 | } | ||
864 | } | ||
865 | |||
866 | static inline void copy_block9(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) | ||
867 | { | ||
868 | int i; | ||
869 | for(i=0; i<h; i++) | ||
870 | { | ||
871 | AV_WN32(dst , AV_RN32(src )); | ||
872 | AV_WN32(dst+4 , AV_RN32(src+4 )); | ||
873 | dst[8]= src[8]; | ||
874 | dst+=dstStride; | ||
875 | src+=srcStride; | ||
876 | } | ||
877 | } | ||
878 | |||
879 | static inline void copy_block16(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) | ||
880 | { | ||
881 | int i; | ||
882 | for(i=0; i<h; i++) | ||
883 | { | ||
884 | AV_WN32(dst , AV_RN32(src )); | ||
885 | AV_WN32(dst+4 , AV_RN32(src+4 )); | ||
886 | AV_WN32(dst+8 , AV_RN32(src+8 )); | ||
887 | AV_WN32(dst+12, AV_RN32(src+12)); | ||
888 | dst+=dstStride; | ||
889 | src+=srcStride; | ||
890 | } | ||
891 | } | ||
892 | |||
893 | static inline void copy_block17(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) | ||
894 | { | ||
895 | int i; | ||
896 | for(i=0; i<h; i++) | ||
897 | { | ||
898 | AV_WN32(dst , AV_RN32(src )); | ||
899 | AV_WN32(dst+4 , AV_RN32(src+4 )); | ||
900 | AV_WN32(dst+8 , AV_RN32(src+8 )); | ||
901 | AV_WN32(dst+12, AV_RN32(src+12)); | ||
902 | dst[16]= src[16]; | ||
903 | dst+=dstStride; | ||
904 | src+=srcStride; | ||
905 | } | ||
906 | } | ||
907 | |||
908 | #endif /* AVCODEC_DSPUTIL_H */ | ||
diff --git a/apps/codecs/libcook/fft.c b/apps/codecs/libcook/fft.c index a3f1151472..e69de29bb2 100644 --- a/apps/codecs/libcook/fft.c +++ b/apps/codecs/libcook/fft.c | |||
@@ -1,374 +0,0 @@ | |||
1 | /* | ||
2 | * FFT/IFFT transforms | ||
3 | * Copyright (c) 2008 Loren Merritt | ||
4 | * Copyright (c) 2002 Fabrice Bellard | ||
5 | * Partly based on libdjbfft by D. J. Bernstein | ||
6 | * | ||
7 | * This file is part of FFmpeg. | ||
8 | * | ||
9 | * FFmpeg is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU Lesser General Public | ||
11 | * License as published by the Free Software Foundation; either | ||
12 | * version 2.1 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * FFmpeg is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * Lesser General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public | ||
20 | * License along with FFmpeg; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | */ | ||
23 | |||
24 | /** | ||
25 | * @file libavcodec/fft.c | ||
26 | * FFT/IFFT transforms. | ||
27 | */ | ||
28 | |||
29 | #include "dsputil.h" | ||
30 | |||
31 | /* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */ | ||
32 | DECLARE_ALIGNED_16(FFTSample, ff_cos_16[8]); | ||
33 | DECLARE_ALIGNED_16(FFTSample, ff_cos_32[16]); | ||
34 | DECLARE_ALIGNED_16(FFTSample, ff_cos_64[32]); | ||
35 | DECLARE_ALIGNED_16(FFTSample, ff_cos_128[64]); | ||
36 | DECLARE_ALIGNED_16(FFTSample, ff_cos_256[128]); | ||
37 | DECLARE_ALIGNED_16(FFTSample, ff_cos_512[256]); | ||
38 | DECLARE_ALIGNED_16(FFTSample, ff_cos_1024[512]); | ||
39 | DECLARE_ALIGNED_16(FFTSample, ff_cos_2048[1024]); | ||
40 | DECLARE_ALIGNED_16(FFTSample, ff_cos_4096[2048]); | ||
41 | DECLARE_ALIGNED_16(FFTSample, ff_cos_8192[4096]); | ||
42 | DECLARE_ALIGNED_16(FFTSample, ff_cos_16384[8192]); | ||
43 | DECLARE_ALIGNED_16(FFTSample, ff_cos_32768[16384]); | ||
44 | DECLARE_ALIGNED_16(FFTSample, ff_cos_65536[32768]); | ||
45 | FFTSample *ff_cos_tabs[] = { | ||
46 | ff_cos_16, ff_cos_32, ff_cos_64, ff_cos_128, ff_cos_256, ff_cos_512, ff_cos_1024, | ||
47 | ff_cos_2048, ff_cos_4096, ff_cos_8192, ff_cos_16384, ff_cos_32768, ff_cos_65536, | ||
48 | }; | ||
49 | |||
50 | static int split_radix_permutation(int i, int n, int inverse) | ||
51 | { | ||
52 | int m; | ||
53 | if(n <= 2) return i&1; | ||
54 | m = n >> 1; | ||
55 | if(!(i&m)) return split_radix_permutation(i, m, inverse)*2; | ||
56 | m >>= 1; | ||
57 | if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1; | ||
58 | else return split_radix_permutation(i, m, inverse)*4 - 1; | ||
59 | } | ||
60 | |||
61 | av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) | ||
62 | { | ||
63 | int i, j, m, n; | ||
64 | float alpha, c1, s1, s2; | ||
65 | int split_radix = 1; | ||
66 | int av_unused has_vectors; | ||
67 | |||
68 | if (nbits < 2 || nbits > 16) | ||
69 | goto fail; | ||
70 | s->nbits = nbits; | ||
71 | n = 1 << nbits; | ||
72 | |||
73 | s->tmp_buf = NULL; | ||
74 | s->exptab = av_malloc((n / 2) * sizeof(FFTComplex)); | ||
75 | if (!s->exptab) | ||
76 | goto fail; | ||
77 | s->revtab = av_malloc(n * sizeof(uint16_t)); | ||
78 | if (!s->revtab) | ||
79 | goto fail; | ||
80 | s->inverse = inverse; | ||
81 | |||
82 | s2 = inverse ? 1.0 : -1.0; | ||
83 | |||
84 | s->fft_permute = ff_fft_permute_c; | ||
85 | s->fft_calc = ff_fft_calc_c; | ||
86 | s->imdct_calc = ff_imdct_calc_c; | ||
87 | s->imdct_half = ff_imdct_half_c; | ||
88 | s->exptab1 = NULL; | ||
89 | |||
90 | #if HAVE_MMX && HAVE_YASM | ||
91 | has_vectors = mm_support(); | ||
92 | if (has_vectors & FF_MM_SSE && HAVE_SSE) { | ||
93 | /* SSE for P3/P4/K8 */ | ||
94 | s->imdct_calc = ff_imdct_calc_sse; | ||
95 | s->imdct_half = ff_imdct_half_sse; | ||
96 | s->fft_permute = ff_fft_permute_sse; | ||
97 | s->fft_calc = ff_fft_calc_sse; | ||
98 | } else if (has_vectors & FF_MM_3DNOWEXT && HAVE_AMD3DNOWEXT) { | ||
99 | /* 3DNowEx for K7 */ | ||
100 | s->imdct_calc = ff_imdct_calc_3dn2; | ||
101 | s->imdct_half = ff_imdct_half_3dn2; | ||
102 | s->fft_calc = ff_fft_calc_3dn2; | ||
103 | } else if (has_vectors & FF_MM_3DNOW && HAVE_AMD3DNOW) { | ||
104 | /* 3DNow! for K6-2/3 */ | ||
105 | s->imdct_calc = ff_imdct_calc_3dn; | ||
106 | s->imdct_half = ff_imdct_half_3dn; | ||
107 | s->fft_calc = ff_fft_calc_3dn; | ||
108 | } | ||
109 | #elif HAVE_ALTIVEC | ||
110 | has_vectors = mm_support(); | ||
111 | if (has_vectors & FF_MM_ALTIVEC) { | ||
112 | s->fft_calc = ff_fft_calc_altivec; | ||
113 | split_radix = 0; | ||
114 | } | ||
115 | #endif | ||
116 | |||
117 | if (split_radix) { | ||
118 | for(j=4; j<=nbits; j++) { | ||
119 | int m = 1<<j; | ||
120 | double freq = 2*M_PI/m; | ||
121 | FFTSample *tab = ff_cos_tabs[j-4]; | ||
122 | for(i=0; i<=m/4; i++) | ||
123 | tab[i] = cos(i*freq); | ||
124 | for(i=1; i<m/4; i++) | ||
125 | tab[m/2-i] = tab[i]; | ||
126 | } | ||
127 | for(i=0; i<n; i++) | ||
128 | s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i; | ||
129 | s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); | ||
130 | } else { | ||
131 | int np, nblocks, np2, l; | ||
132 | FFTComplex *q; | ||
133 | |||
134 | for(i=0; i<(n/2); i++) { | ||
135 | alpha = 2 * M_PI * (float)i / (float)n; | ||
136 | c1 = cos(alpha); | ||
137 | s1 = sin(alpha) * s2; | ||
138 | s->exptab[i].re = c1; | ||
139 | s->exptab[i].im = s1; | ||
140 | } | ||
141 | |||
142 | np = 1 << nbits; | ||
143 | nblocks = np >> 3; | ||
144 | np2 = np >> 1; | ||
145 | s->exptab1 = av_malloc(np * 2 * sizeof(FFTComplex)); | ||
146 | if (!s->exptab1) | ||
147 | goto fail; | ||
148 | q = s->exptab1; | ||
149 | do { | ||
150 | for(l = 0; l < np2; l += 2 * nblocks) { | ||
151 | *q++ = s->exptab[l]; | ||
152 | *q++ = s->exptab[l + nblocks]; | ||
153 | |||
154 | q->re = -s->exptab[l].im; | ||
155 | q->im = s->exptab[l].re; | ||
156 | q++; | ||
157 | q->re = -s->exptab[l + nblocks].im; | ||
158 | q->im = s->exptab[l + nblocks].re; | ||
159 | q++; | ||
160 | } | ||
161 | nblocks = nblocks >> 1; | ||
162 | } while (nblocks != 0); | ||
163 | av_freep(&s->exptab); | ||
164 | |||
165 | /* compute bit reverse table */ | ||
166 | for(i=0;i<n;i++) { | ||
167 | m=0; | ||
168 | for(j=0;j<nbits;j++) { | ||
169 | m |= ((i >> j) & 1) << (nbits-j-1); | ||
170 | } | ||
171 | s->revtab[i]=m; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return 0; | ||
176 | fail: | ||
177 | av_freep(&s->revtab); | ||
178 | av_freep(&s->exptab); | ||
179 | av_freep(&s->exptab1); | ||
180 | av_freep(&s->tmp_buf); | ||
181 | return -1; | ||
182 | } | ||
183 | |||
184 | void ff_fft_permute_c(FFTContext *s, FFTComplex *z) | ||
185 | { | ||
186 | int j, k, np; | ||
187 | FFTComplex tmp; | ||
188 | const uint16_t *revtab = s->revtab; | ||
189 | np = 1 << s->nbits; | ||
190 | |||
191 | if (s->tmp_buf) { | ||
192 | /* TODO: handle split-radix permute in a more optimal way, probably in-place */ | ||
193 | for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j]; | ||
194 | memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | /* reverse */ | ||
199 | for(j=0;j<np;j++) { | ||
200 | k = revtab[j]; | ||
201 | if (k < j) { | ||
202 | tmp = z[k]; | ||
203 | z[k] = z[j]; | ||
204 | z[j] = tmp; | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | |||
209 | av_cold void ff_fft_end(FFTContext *s) | ||
210 | { | ||
211 | av_freep(&s->revtab); | ||
212 | av_freep(&s->exptab); | ||
213 | av_freep(&s->exptab1); | ||
214 | av_freep(&s->tmp_buf); | ||
215 | } | ||
216 | |||
217 | #define sqrthalf (float)M_SQRT1_2 | ||
218 | |||
219 | #define BF(x,y,a,b) {\ | ||
220 | x = a - b;\ | ||
221 | y = a + b;\ | ||
222 | } | ||
223 | |||
224 | #define BUTTERFLIES(a0,a1,a2,a3) {\ | ||
225 | BF(t3, t5, t5, t1);\ | ||
226 | BF(a2.re, a0.re, a0.re, t5);\ | ||
227 | BF(a3.im, a1.im, a1.im, t3);\ | ||
228 | BF(t4, t6, t2, t6);\ | ||
229 | BF(a3.re, a1.re, a1.re, t4);\ | ||
230 | BF(a2.im, a0.im, a0.im, t6);\ | ||
231 | } | ||
232 | |||
233 | // force loading all the inputs before storing any. | ||
234 | // this is slightly slower for small data, but avoids store->load aliasing | ||
235 | // for addresses separated by large powers of 2. | ||
236 | #define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ | ||
237 | FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ | ||
238 | BF(t3, t5, t5, t1);\ | ||
239 | BF(a2.re, a0.re, r0, t5);\ | ||
240 | BF(a3.im, a1.im, i1, t3);\ | ||
241 | BF(t4, t6, t2, t6);\ | ||
242 | BF(a3.re, a1.re, r1, t4);\ | ||
243 | BF(a2.im, a0.im, i0, t6);\ | ||
244 | } | ||
245 | |||
246 | #define TRANSFORM(a0,a1,a2,a3,wre,wim) {\ | ||
247 | t1 = a2.re * wre + a2.im * wim;\ | ||
248 | t2 = a2.im * wre - a2.re * wim;\ | ||
249 | t5 = a3.re * wre - a3.im * wim;\ | ||
250 | t6 = a3.im * wre + a3.re * wim;\ | ||
251 | BUTTERFLIES(a0,a1,a2,a3)\ | ||
252 | } | ||
253 | |||
254 | #define TRANSFORM_ZERO(a0,a1,a2,a3) {\ | ||
255 | t1 = a2.re;\ | ||
256 | t2 = a2.im;\ | ||
257 | t5 = a3.re;\ | ||
258 | t6 = a3.im;\ | ||
259 | BUTTERFLIES(a0,a1,a2,a3)\ | ||
260 | } | ||
261 | |||
262 | /* z[0...8n-1], w[1...2n-1] */ | ||
263 | #define PASS(name)\ | ||
264 | static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\ | ||
265 | {\ | ||
266 | FFTSample t1, t2, t3, t4, t5, t6;\ | ||
267 | int o1 = 2*n;\ | ||
268 | int o2 = 4*n;\ | ||
269 | int o3 = 6*n;\ | ||
270 | const FFTSample *wim = wre+o1;\ | ||
271 | n--;\ | ||
272 | \ | ||
273 | TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\ | ||
274 | TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ | ||
275 | do {\ | ||
276 | z += 2;\ | ||
277 | wre += 2;\ | ||
278 | wim -= 2;\ | ||
279 | TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\ | ||
280 | TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ | ||
281 | } while(--n);\ | ||
282 | } | ||
283 | |||
284 | PASS(pass) | ||
285 | #undef BUTTERFLIES | ||
286 | #define BUTTERFLIES BUTTERFLIES_BIG | ||
287 | PASS(pass_big) | ||
288 | |||
289 | #define DECL_FFT(n,n2,n4)\ | ||
290 | static void fft##n(FFTComplex *z)\ | ||
291 | {\ | ||
292 | fft##n2(z);\ | ||
293 | fft##n4(z+n4*2);\ | ||
294 | fft##n4(z+n4*3);\ | ||
295 | pass(z,ff_cos_##n,n4/2);\ | ||
296 | } | ||
297 | |||
298 | static void fft4(FFTComplex *z) | ||
299 | { | ||
300 | FFTSample t1, t2, t3, t4, t5, t6, t7, t8; | ||
301 | |||
302 | BF(t3, t1, z[0].re, z[1].re); | ||
303 | BF(t8, t6, z[3].re, z[2].re); | ||
304 | BF(z[2].re, z[0].re, t1, t6); | ||
305 | BF(t4, t2, z[0].im, z[1].im); | ||
306 | BF(t7, t5, z[2].im, z[3].im); | ||
307 | BF(z[3].im, z[1].im, t4, t8); | ||
308 | BF(z[3].re, z[1].re, t3, t7); | ||
309 | BF(z[2].im, z[0].im, t2, t5); | ||
310 | } | ||
311 | |||
312 | static void fft8(FFTComplex *z) | ||
313 | { | ||
314 | FFTSample t1, t2, t3, t4, t5, t6, t7, t8; | ||
315 | |||
316 | fft4(z); | ||
317 | |||
318 | BF(t1, z[5].re, z[4].re, -z[5].re); | ||
319 | BF(t2, z[5].im, z[4].im, -z[5].im); | ||
320 | BF(t3, z[7].re, z[6].re, -z[7].re); | ||
321 | BF(t4, z[7].im, z[6].im, -z[7].im); | ||
322 | BF(t8, t1, t3, t1); | ||
323 | BF(t7, t2, t2, t4); | ||
324 | BF(z[4].re, z[0].re, z[0].re, t1); | ||
325 | BF(z[4].im, z[0].im, z[0].im, t2); | ||
326 | BF(z[6].re, z[2].re, z[2].re, t7); | ||
327 | BF(z[6].im, z[2].im, z[2].im, t8); | ||
328 | |||
329 | TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf); | ||
330 | } | ||
331 | |||
332 | #if !CONFIG_SMALL | ||
333 | static void fft16(FFTComplex *z) | ||
334 | { | ||
335 | FFTSample t1, t2, t3, t4, t5, t6; | ||
336 | |||
337 | fft8(z); | ||
338 | fft4(z+8); | ||
339 | fft4(z+12); | ||
340 | |||
341 | TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); | ||
342 | TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf); | ||
343 | TRANSFORM(z[1],z[5],z[9],z[13],ff_cos_16[1],ff_cos_16[3]); | ||
344 | TRANSFORM(z[3],z[7],z[11],z[15],ff_cos_16[3],ff_cos_16[1]); | ||
345 | } | ||
346 | #else | ||
347 | DECL_FFT(16,8,4) | ||
348 | #endif | ||
349 | DECL_FFT(32,16,8) | ||
350 | DECL_FFT(64,32,16) | ||
351 | DECL_FFT(128,64,32) | ||
352 | DECL_FFT(256,128,64) | ||
353 | DECL_FFT(512,256,128) | ||
354 | #if !CONFIG_SMALL | ||
355 | #define pass pass_big | ||
356 | #endif | ||
357 | DECL_FFT(1024,512,256) | ||
358 | DECL_FFT(2048,1024,512) | ||
359 | DECL_FFT(4096,2048,1024) | ||
360 | DECL_FFT(8192,4096,2048) | ||
361 | DECL_FFT(16384,8192,4096) | ||
362 | DECL_FFT(32768,16384,8192) | ||
363 | DECL_FFT(65536,32768,16384) | ||
364 | |||
365 | static void (*fft_dispatch[])(FFTComplex*) = { | ||
366 | fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, | ||
367 | fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, | ||
368 | }; | ||
369 | |||
370 | void ff_fft_calc_c(FFTContext *s, FFTComplex *z) | ||
371 | { | ||
372 | fft_dispatch[s->nbits-2](z); | ||
373 | } | ||
374 | |||
diff --git a/apps/codecs/libcook/main.c b/apps/codecs/libcook/main.c index 2f85295fb5..40e2fd8a4f 100644 --- a/apps/codecs/libcook/main.c +++ b/apps/codecs/libcook/main.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ main.c 20898 2009-05-09 23:24:02Z dave $ |
9 | * | 9 | * |
10 | * Copyright (C) 2009 Mohamed Tarek | 10 | * Copyright (C) 2009 Mohamed Tarek |
11 | * | 11 | * |
diff --git a/apps/codecs/libcook/mdct.c b/apps/codecs/libcook/mdct.c index cb3388f6ff..e69de29bb2 100644 --- a/apps/codecs/libcook/mdct.c +++ b/apps/codecs/libcook/mdct.c | |||
@@ -1,229 +0,0 @@ | |||
1 | /* | ||
2 | * MDCT/IMDCT transforms | ||
3 | * Copyright (c) 2002 Fabrice Bellard | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | #include "dsputil.h" | ||
22 | |||
23 | /** | ||
24 | * @file libavcodec/mdct.c | ||
25 | * MDCT/IMDCT transforms. | ||
26 | */ | ||
27 | |||
28 | // Generate a Kaiser-Bessel Derived Window. | ||
29 | #define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation | ||
30 | av_cold void ff_kbd_window_init(float *window, float alpha, int n) | ||
31 | { | ||
32 | int i, j; | ||
33 | double sum = 0.0, bessel, tmp; | ||
34 | double local_window[n]; | ||
35 | double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n); | ||
36 | |||
37 | for (i = 0; i < n; i++) { | ||
38 | tmp = i * (n - i) * alpha2; | ||
39 | bessel = 1.0; | ||
40 | for (j = BESSEL_I0_ITER; j > 0; j--) | ||
41 | bessel = bessel * tmp / (j * j) + 1; | ||
42 | sum += bessel; | ||
43 | local_window[i] = sum; | ||
44 | } | ||
45 | |||
46 | sum++; | ||
47 | for (i = 0; i < n; i++) | ||
48 | window[i] = sqrt(local_window[i] / sum); | ||
49 | } | ||
50 | |||
51 | DECLARE_ALIGNED(16, float, ff_sine_128 [ 128]); | ||
52 | DECLARE_ALIGNED(16, float, ff_sine_256 [ 256]); | ||
53 | DECLARE_ALIGNED(16, float, ff_sine_512 [ 512]); | ||
54 | DECLARE_ALIGNED(16, float, ff_sine_1024[1024]); | ||
55 | DECLARE_ALIGNED(16, float, ff_sine_2048[2048]); | ||
56 | DECLARE_ALIGNED(16, float, ff_sine_4096[4096]); | ||
57 | float *ff_sine_windows[6] = { | ||
58 | ff_sine_128, ff_sine_256, ff_sine_512, ff_sine_1024, ff_sine_2048, ff_sine_4096 | ||
59 | }; | ||
60 | |||
61 | // Generate a sine window. | ||
62 | av_cold void ff_sine_window_init(float *window, int n) { | ||
63 | int i; | ||
64 | for(i = 0; i < n; i++) | ||
65 | window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n))); | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * init MDCT or IMDCT computation. | ||
70 | */ | ||
71 | av_cold int ff_mdct_init(MDCTContext *s, int nbits, int inverse) | ||
72 | { | ||
73 | int n, n4, i; | ||
74 | double alpha; | ||
75 | |||
76 | memset(s, 0, sizeof(*s)); | ||
77 | n = 1 << nbits; | ||
78 | s->nbits = nbits; | ||
79 | s->n = n; | ||
80 | n4 = n >> 2; | ||
81 | s->tcos = av_malloc(n4 * sizeof(FFTSample)); | ||
82 | if (!s->tcos) | ||
83 | goto fail; | ||
84 | s->tsin = av_malloc(n4 * sizeof(FFTSample)); | ||
85 | if (!s->tsin) | ||
86 | goto fail; | ||
87 | |||
88 | for(i=0;i<n4;i++) { | ||
89 | alpha = 2 * M_PI * (i + 1.0 / 8.0) / n; | ||
90 | s->tcos[i] = -cos(alpha); | ||
91 | s->tsin[i] = -sin(alpha); | ||
92 | } | ||
93 | if (ff_fft_init(&s->fft, s->nbits - 2, inverse) < 0) | ||
94 | goto fail; | ||
95 | return 0; | ||
96 | fail: | ||
97 | av_freep(&s->tcos); | ||
98 | av_freep(&s->tsin); | ||
99 | return -1; | ||
100 | } | ||
101 | |||
102 | /* complex multiplication: p = a * b */ | ||
103 | #define CMUL(pre, pim, are, aim, bre, bim) \ | ||
104 | {\ | ||
105 | FFTSample _are = (are);\ | ||
106 | FFTSample _aim = (aim);\ | ||
107 | FFTSample _bre = (bre);\ | ||
108 | FFTSample _bim = (bim);\ | ||
109 | (pre) = _are * _bre - _aim * _bim;\ | ||
110 | (pim) = _are * _bim + _aim * _bre;\ | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Compute the middle half of the inverse MDCT of size N = 2^nbits, | ||
115 | * thus excluding the parts that can be derived by symmetry | ||
116 | * @param output N/2 samples | ||
117 | * @param input N/2 samples | ||
118 | */ | ||
119 | void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input) | ||
120 | { | ||
121 | int k, n8, n4, n2, n, j; | ||
122 | const uint16_t *revtab = s->fft.revtab; | ||
123 | const FFTSample *tcos = s->tcos; | ||
124 | const FFTSample *tsin = s->tsin; | ||
125 | const FFTSample *in1, *in2; | ||
126 | FFTComplex *z = (FFTComplex *)output; | ||
127 | |||
128 | n = 1 << s->nbits; | ||
129 | n2 = n >> 1; | ||
130 | n4 = n >> 2; | ||
131 | n8 = n >> 3; | ||
132 | |||
133 | /* pre rotation */ | ||
134 | in1 = input; | ||
135 | in2 = input + n2 - 1; | ||
136 | for(k = 0; k < n4; k++) { | ||
137 | j=revtab[k]; | ||
138 | CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); | ||
139 | in1 += 2; | ||
140 | in2 -= 2; | ||
141 | } | ||
142 | ff_fft_calc(&s->fft, z); | ||
143 | |||
144 | /* post rotation + reordering */ | ||
145 | output += n4; | ||
146 | for(k = 0; k < n8; k++) { | ||
147 | FFTSample r0, i0, r1, i1; | ||
148 | CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); | ||
149 | CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]); | ||
150 | z[n8-k-1].re = r0; | ||
151 | z[n8-k-1].im = i0; | ||
152 | z[n8+k ].re = r1; | ||
153 | z[n8+k ].im = i1; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * Compute inverse MDCT of size N = 2^nbits | ||
159 | * @param output N samples | ||
160 | * @param input N/2 samples | ||
161 | */ | ||
162 | void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input) | ||
163 | { | ||
164 | int k; | ||
165 | int n = 1 << s->nbits; | ||
166 | int n2 = n >> 1; | ||
167 | int n4 = n >> 2; | ||
168 | |||
169 | ff_imdct_half_c(s, output+n4, input); | ||
170 | |||
171 | for(k = 0; k < n4; k++) { | ||
172 | output[k] = -output[n2-k-1]; | ||
173 | output[n-k-1] = output[n2+k]; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * Compute MDCT of size N = 2^nbits | ||
179 | * @param input N samples | ||
180 | * @param out N/2 samples | ||
181 | */ | ||
182 | void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input) | ||
183 | { | ||
184 | int i, j, n, n8, n4, n2, n3; | ||
185 | FFTSample re, im; | ||
186 | const uint16_t *revtab = s->fft.revtab; | ||
187 | const FFTSample *tcos = s->tcos; | ||
188 | const FFTSample *tsin = s->tsin; | ||
189 | FFTComplex *x = (FFTComplex *)out; | ||
190 | |||
191 | n = 1 << s->nbits; | ||
192 | n2 = n >> 1; | ||
193 | n4 = n >> 2; | ||
194 | n8 = n >> 3; | ||
195 | n3 = 3 * n4; | ||
196 | |||
197 | /* pre rotation */ | ||
198 | for(i=0;i<n8;i++) { | ||
199 | re = -input[2*i+3*n4] - input[n3-1-2*i]; | ||
200 | im = -input[n4+2*i] + input[n4-1-2*i]; | ||
201 | j = revtab[i]; | ||
202 | CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]); | ||
203 | |||
204 | re = input[2*i] - input[n2-1-2*i]; | ||
205 | im = -(input[n2+2*i] + input[n-1-2*i]); | ||
206 | j = revtab[n8 + i]; | ||
207 | CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]); | ||
208 | } | ||
209 | |||
210 | ff_fft_calc(&s->fft, x); | ||
211 | |||
212 | /* post rotation */ | ||
213 | for(i=0;i<n8;i++) { | ||
214 | FFTSample r0, i0, r1, i1; | ||
215 | CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]); | ||
216 | CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]); | ||
217 | x[n8-i-1].re = r0; | ||
218 | x[n8-i-1].im = i0; | ||
219 | x[n8+i ].re = r1; | ||
220 | x[n8+i ].im = i1; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | av_cold void ff_mdct_end(MDCTContext *s) | ||
225 | { | ||
226 | av_freep(&s->tcos); | ||
227 | av_freep(&s->tsin); | ||
228 | ff_fft_end(&s->fft); | ||
229 | } | ||