Mercurial > libavcodec.hg
comparison cook.c @ 4639:33fc84eae7c3 libavcodec
Simplify gain block handling.
Patch by Ian Braithwaite <ian at braithwaite dot dk>
author | banan |
---|---|
date | Thu, 08 Mar 2007 20:43:51 +0000 |
parents | 9f74306d4ac7 |
children | 31bf54d9353d |
comparison
equal
deleted
inserted
replaced
4638:9f74306d4ac7 | 4639:33fc84eae7c3 |
---|---|
63 | 63 |
64 #define SUBBAND_SIZE 20 | 64 #define SUBBAND_SIZE 20 |
65 //#define COOKDEBUG | 65 //#define COOKDEBUG |
66 | 66 |
67 typedef struct { | 67 typedef struct { |
68 int size; | 68 int *now; |
69 int loccode[8]; | 69 int *previous; |
70 int levcode[8]; | 70 } cook_gains; |
71 } COOKgain; | |
72 | 71 |
73 typedef struct { | 72 typedef struct { |
74 GetBitContext gb; | 73 GetBitContext gb; |
75 /* stream data */ | 74 /* stream data */ |
76 int nb_channels; | 75 int nb_channels; |
100 int fft_size; | 99 int fft_size; |
101 int fft_order; | 100 int fft_order; |
102 int mlt_size; //modulated lapped transform size | 101 int mlt_size; //modulated lapped transform size |
103 | 102 |
104 /* gain buffers */ | 103 /* gain buffers */ |
105 COOKgain *gain_ptr1[2]; | 104 cook_gains gains1; |
106 COOKgain *gain_ptr2[2]; | 105 cook_gains gains2; |
107 COOKgain gain_1; | 106 int gain_1[9]; |
108 COOKgain gain_2; | 107 int gain_2[9]; |
109 COOKgain gain_3; | 108 int gain_3[9]; |
110 COOKgain gain_4; | 109 int gain_4[9]; |
111 | 110 |
112 /* VLC data */ | 111 /* VLC data */ |
113 int js_vlc_bits; | 112 int js_vlc_bits; |
114 VLC envelope_quant_index[13]; | 113 VLC envelope_quant_index[13]; |
115 VLC sqvh[7]; //scalar quantization | 114 VLC sqvh[7]; //scalar quantization |
337 | 336 |
338 return 0; | 337 return 0; |
339 } | 338 } |
340 | 339 |
341 /** | 340 /** |
342 * Fill the COOKgain structure for the timedomain quantization. | 341 * Fill the gain array for the timedomain quantization. |
343 * | 342 * |
344 * @param q pointer to the COOKContext | 343 * @param q pointer to the COOKContext |
345 * @param gaininfo pointer to the COOKgain | 344 * @param gaininfo[9] array of gain indices |
346 */ | 345 */ |
347 | 346 |
348 static void decode_gain_info(GetBitContext *gb, COOKgain* gaininfo) { | 347 static void decode_gain_info(GetBitContext *gb, int *gaininfo) |
349 int i; | 348 { |
349 int i, n; | |
350 | 350 |
351 while (get_bits1(gb)) {} | 351 while (get_bits1(gb)) {} |
352 | 352 n = get_bits_count(gb) - 1; //amount of elements*2 to update |
353 gaininfo->size = get_bits_count(gb) - 1; //amount of elements*2 to update | 353 |
354 | 354 i = 0; |
355 if (get_bits_count(gb) - 1 <= 0) return; | 355 while (n--) { |
356 | 356 int index = get_bits(gb, 3); |
357 for (i=0 ; i<gaininfo->size ; i++){ | 357 int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; |
358 gaininfo->loccode[i] = get_bits(gb,3); | 358 |
359 if (get_bits1(gb)) { | 359 while (i <= index) gaininfo[i++] = gain; |
360 gaininfo->levcode[i] = get_bits(gb,4) - 7; //convert to signed | 360 } |
361 } else { | 361 while (i <= 8) gaininfo[i++] = 0; |
362 gaininfo->levcode[i] = -1; | |
363 } | |
364 } | |
365 } | 362 } |
366 | 363 |
367 /** | 364 /** |
368 * Create the quant index table needed for the envelope. | 365 * Create the quant index table needed for the envelope. |
369 * | 366 * |
782 } | 779 } |
783 return; | 780 return; |
784 } | 781 } |
785 } | 782 } |
786 | 783 |
787 /** | 784 |
788 * timedomain requantization of the timedomain samples | 785 /** |
786 * mlt overlapping and buffer management | |
789 * | 787 * |
790 * @param q pointer to the COOKContext | 788 * @param q pointer to the COOKContext |
791 * @param buffer pointer to the timedomain buffer | 789 * @param gains_ptr current and previous gains |
792 * @param gain_now current gain structure | |
793 * @param gain_previous previous gain structure | |
794 */ | |
795 | |
796 static void gain_window(COOKContext *q, float* buffer, COOKgain* gain_now, | |
797 COOKgain* gain_previous){ | |
798 int i, index; | |
799 int gain_index[9]; | |
800 int tmp_gain_index; | |
801 | |
802 gain_index[8]=0; | |
803 index = gain_previous->size; | |
804 for (i=7 ; i>=0 ; i--) { | |
805 if(index && gain_previous->loccode[index-1]==i) { | |
806 gain_index[i] = gain_previous->levcode[index-1]; | |
807 index--; | |
808 } else { | |
809 gain_index[i]=gain_index[i+1]; | |
810 } | |
811 } | |
812 /* This is applied to the to be previous data buffer. */ | |
813 for(i=0;i<8;i++){ | |
814 interpolate(q, &buffer[q->samples_per_channel+q->gain_size_factor*i], | |
815 gain_index[i], gain_index[i+1]); | |
816 } | |
817 | |
818 tmp_gain_index = gain_index[0]; | |
819 index = gain_now->size; | |
820 for (i=7 ; i>=0 ; i--) { | |
821 if(index && gain_now->loccode[index-1]==i) { | |
822 gain_index[i]= gain_now->levcode[index-1]; | |
823 index--; | |
824 } else { | |
825 gain_index[i]=gain_index[i+1]; | |
826 } | |
827 } | |
828 | |
829 /* This is applied to the to be current block. */ | |
830 for(i=0;i<8;i++){ | |
831 interpolate(q, &buffer[i*q->gain_size_factor], | |
832 tmp_gain_index+gain_index[i], | |
833 tmp_gain_index+gain_index[i+1]); | |
834 } | |
835 } | |
836 | |
837 | |
838 /** | |
839 * mlt overlapping and buffer management | |
840 * | |
841 * @param q pointer to the COOKContext | |
842 * @param buffer pointer to the timedomain buffer | |
843 * @param gain_now current gain structure | |
844 * @param gain_previous previous gain structure | |
845 * @param previous_buffer pointer to the previous buffer to be used for overlapping | 790 * @param previous_buffer pointer to the previous buffer to be used for overlapping |
846 * | 791 */ |
847 */ | 792 |
848 | 793 static void gain_compensate(COOKContext *q, cook_gains *gains_ptr, |
849 static void gain_compensate(COOKContext *q, float* buffer, COOKgain* gain_now, | 794 float* previous_buffer) |
850 COOKgain* gain_previous, float* previous_buffer) { | 795 { |
796 const float fc = q->pow2tab[gains_ptr->previous[0] + 63]; | |
797 float *buffer = q->mono_mdct_output; | |
851 int i; | 798 int i; |
852 if((gain_now->size || gain_previous->size)) { | |
853 gain_window(q, buffer, gain_now, gain_previous); | |
854 } | |
855 | 799 |
856 /* Overlap with the previous block. */ | 800 /* Overlap with the previous block. */ |
857 for(i=0 ; i<q->samples_per_channel ; i++) buffer[i]+=previous_buffer[i]; | 801 for(i=0 ; i<q->samples_per_channel ; i++) { |
802 buffer[i] *= fc; | |
803 buffer[i] += previous_buffer[i]; | |
804 } | |
805 | |
806 /* Apply gain profile */ | |
807 for (i = 0; i < 8; i++) { | |
808 if (gains_ptr->now[i] || gains_ptr->now[i + 1]) | |
809 interpolate(q, &buffer[q->gain_size_factor * i], | |
810 gains_ptr->now[i], gains_ptr->now[i + 1]); | |
811 } | |
858 | 812 |
859 /* Save away the current to be previous block. */ | 813 /* Save away the current to be previous block. */ |
860 memcpy(previous_buffer, buffer+q->samples_per_channel, | 814 memcpy(previous_buffer, buffer+q->samples_per_channel, |
861 sizeof(float)*q->samples_per_channel); | 815 sizeof(float)*q->samples_per_channel); |
862 } | 816 } |
954 * @param gain_ptr array of current/prev gain pointers | 908 * @param gain_ptr array of current/prev gain pointers |
955 */ | 909 */ |
956 | 910 |
957 static inline void | 911 static inline void |
958 decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, | 912 decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, |
959 COOKgain *gain_ptr[]) | 913 cook_gains *gains_ptr) |
960 { | 914 { |
961 int offset; | 915 int offset; |
962 | 916 |
963 offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, | 917 offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, |
964 q->bits_per_subpacket/8); | 918 q->bits_per_subpacket/8); |
965 init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, | 919 init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, |
966 q->bits_per_subpacket); | 920 q->bits_per_subpacket); |
967 decode_gain_info(&q->gb, gain_ptr[0]); | 921 decode_gain_info(&q->gb, gains_ptr->now); |
968 | 922 |
969 /* Swap current and previous gains */ | 923 /* Swap current and previous gains */ |
970 FFSWAP(COOKgain *, gain_ptr[0], gain_ptr[1]); | 924 FFSWAP(int *, gains_ptr->now, gains_ptr->previous); |
971 } | 925 } |
972 | 926 |
973 /** | 927 /** |
974 * Final part of subpacket decoding: | 928 * Final part of subpacket decoding: |
975 * Apply modulated lapped transform, gain compensation, | 929 * Apply modulated lapped transform, gain compensation, |
983 * @param chan 0: left or single channel, 1: right channel | 937 * @param chan 0: left or single channel, 1: right channel |
984 */ | 938 */ |
985 | 939 |
986 static inline void | 940 static inline void |
987 mlt_compensate_output(COOKContext *q, float *decode_buffer, | 941 mlt_compensate_output(COOKContext *q, float *decode_buffer, |
988 COOKgain *gain_ptr[], float *previous_buffer, | 942 cook_gains *gains, float *previous_buffer, |
989 int16_t *out, int chan) | 943 int16_t *out, int chan) |
990 { | 944 { |
991 int j; | 945 int j; |
992 | 946 |
993 cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp); | 947 cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp); |
994 gain_compensate(q, q->mono_mdct_output, gain_ptr[0], | 948 gain_compensate(q, gains, previous_buffer); |
995 gain_ptr[1], previous_buffer); | |
996 | 949 |
997 /* Clip and convert floats to 16 bits. | 950 /* Clip and convert floats to 16 bits. |
998 */ | 951 */ |
999 for (j = 0; j < q->samples_per_channel; j++) { | 952 for (j = 0; j < q->samples_per_channel; j++) { |
1000 out[chan + q->nb_channels * j] = | 953 out[chan + q->nb_channels * j] = |
1020 // for (i=0 ; i<sub_packet_size ; i++) { | 973 // for (i=0 ; i<sub_packet_size ; i++) { |
1021 // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]); | 974 // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]); |
1022 // } | 975 // } |
1023 // av_log(NULL, AV_LOG_ERROR, "\n"); | 976 // av_log(NULL, AV_LOG_ERROR, "\n"); |
1024 | 977 |
1025 decode_bytes_and_gain(q, inbuffer, q->gain_ptr1); | 978 decode_bytes_and_gain(q, inbuffer, &q->gains1); |
1026 | 979 |
1027 if (q->joint_stereo) { | 980 if (q->joint_stereo) { |
1028 joint_decode(q, q->decode_buffer_1, q->decode_buffer_2); | 981 joint_decode(q, q->decode_buffer_1, q->decode_buffer_2); |
1029 } else { | 982 } else { |
1030 mono_decode(q, q->decode_buffer_1); | 983 mono_decode(q, q->decode_buffer_1); |
1031 | 984 |
1032 if (q->nb_channels == 2) { | 985 if (q->nb_channels == 2) { |
1033 decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, | 986 decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2); |
1034 q->gain_ptr2); | |
1035 mono_decode(q, q->decode_buffer_2); | 987 mono_decode(q, q->decode_buffer_2); |
1036 } | 988 } |
1037 } | 989 } |
1038 | 990 |
1039 mlt_compensate_output(q, q->decode_buffer_1, q->gain_ptr1, | 991 mlt_compensate_output(q, q->decode_buffer_1, &q->gains1, |
1040 q->mono_previous_buffer1, outbuffer, 0); | 992 q->mono_previous_buffer1, outbuffer, 0); |
1041 | 993 |
1042 if (q->nb_channels == 2) { | 994 if (q->nb_channels == 2) { |
1043 if (q->joint_stereo) { | 995 if (q->joint_stereo) { |
1044 mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr1, | 996 mlt_compensate_output(q, q->decode_buffer_2, &q->gains1, |
1045 q->mono_previous_buffer2, outbuffer, 1); | 997 q->mono_previous_buffer2, outbuffer, 1); |
1046 } else { | 998 } else { |
1047 mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr2, | 999 mlt_compensate_output(q, q->decode_buffer_2, &q->gains2, |
1048 q->mono_previous_buffer2, outbuffer, 1); | 1000 q->mono_previous_buffer2, outbuffer, 1); |
1049 } | 1001 } |
1050 } | 1002 } |
1051 return q->samples_per_frame * sizeof(int16_t); | 1003 return q->samples_per_frame * sizeof(int16_t); |
1052 } | 1004 } |
1223 + FF_INPUT_BUFFER_PADDING_SIZE); | 1175 + FF_INPUT_BUFFER_PADDING_SIZE); |
1224 } | 1176 } |
1225 if (q->decoded_bytes_buffer == NULL) | 1177 if (q->decoded_bytes_buffer == NULL) |
1226 return -1; | 1178 return -1; |
1227 | 1179 |
1228 q->gain_ptr1[0] = &q->gain_1; | 1180 q->gains1.now = q->gain_1; |
1229 q->gain_ptr1[1] = &q->gain_2; | 1181 q->gains1.previous = q->gain_2; |
1230 q->gain_ptr2[0] = &q->gain_3; | 1182 q->gains2.now = q->gain_3; |
1231 q->gain_ptr2[1] = &q->gain_4; | 1183 q->gains2.previous = q->gain_4; |
1232 | 1184 |
1233 /* Initialize transform. */ | 1185 /* Initialize transform. */ |
1234 if ( init_cook_mlt(q) == 0 ) | 1186 if ( init_cook_mlt(q) == 0 ) |
1235 return -1; | 1187 return -1; |
1236 | 1188 |