Mercurial > libavcodec.hg
comparison cook.c @ 4428:eeb16216b454 libavcodec
decode_subpacket cleanup by Ian Braithwaite ian braithwaite dot dk.
author | banan |
---|---|
date | Mon, 29 Jan 2007 08:37:22 +0000 |
parents | aca324d5bd58 |
children | ba087eea0a53 |
comparison
equal
deleted
inserted
replaced
4427:765df9cbb2b3 | 4428:eeb16216b454 |
---|---|
48 #include <stdio.h> | 48 #include <stdio.h> |
49 | 49 |
50 #include "avcodec.h" | 50 #include "avcodec.h" |
51 #include "bitstream.h" | 51 #include "bitstream.h" |
52 #include "dsputil.h" | 52 #include "dsputil.h" |
53 #include "common.h" | |
53 | 54 |
54 #include "cookdata.h" | 55 #include "cookdata.h" |
55 | 56 |
56 /* the different Cook versions */ | 57 /* the different Cook versions */ |
57 #define MONO 0x1000001 | 58 #define MONO 0x1000001 |
110 int fft_size; | 111 int fft_size; |
111 int fft_order; | 112 int fft_order; |
112 int mlt_size; //modulated lapped transform size | 113 int mlt_size; //modulated lapped transform size |
113 | 114 |
114 /* gain buffers */ | 115 /* gain buffers */ |
115 COOKgain* gain_now_ptr; | 116 COOKgain *gain_ptr1[2]; |
116 COOKgain* gain_previous_ptr; | 117 COOKgain *gain_ptr2[2]; |
117 COOKgain gain_current; | 118 COOKgain gain_1; |
118 COOKgain gain_now; | 119 COOKgain gain_2; |
119 COOKgain gain_previous; | 120 COOKgain gain_3; |
120 COOKgain gain_channel1[2]; | 121 COOKgain gain_4; |
121 COOKgain gain_channel2[2]; | |
122 | 122 |
123 /* VLC data */ | 123 /* VLC data */ |
124 int js_vlc_bits; | 124 int js_vlc_bits; |
125 VLC envelope_quant_index[13]; | 125 VLC envelope_quant_index[13]; |
126 VLC sqvh[7]; //scalar quantization | 126 VLC sqvh[7]; //scalar quantization |
134 | 134 |
135 /* data buffers */ | 135 /* data buffers */ |
136 | 136 |
137 uint8_t* decoded_bytes_buffer; | 137 uint8_t* decoded_bytes_buffer; |
138 float mono_mdct_output[2048] __attribute__((aligned(16))); | 138 float mono_mdct_output[2048] __attribute__((aligned(16))); |
139 float* previous_buffer_ptr[2]; | |
140 float mono_previous_buffer1[1024]; | 139 float mono_previous_buffer1[1024]; |
141 float mono_previous_buffer2[1024]; | 140 float mono_previous_buffer2[1024]; |
142 float* decode_buf_ptr[4]; | |
143 float* decode_buf_ptr2[2]; | |
144 float decode_buffer_1[1024]; | 141 float decode_buffer_1[1024]; |
145 float decode_buffer_2[1024]; | 142 float decode_buffer_2[1024]; |
146 float decode_buffer_3[1024]; | |
147 float decode_buffer_4[1024]; | |
148 } COOKContext; | 143 } COOKContext; |
149 | 144 |
150 /* debug functions */ | 145 /* debug functions */ |
151 | 146 |
152 #ifdef COOKDEBUG | 147 #ifdef COOKDEBUG |
969 * @param inbuffer pointer to raw stream data | 964 * @param inbuffer pointer to raw stream data |
970 * @param gain_ptr array of current/prev gain pointers | 965 * @param gain_ptr array of current/prev gain pointers |
971 */ | 966 */ |
972 | 967 |
973 static inline void | 968 static inline void |
974 decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr) | 969 decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, |
970 COOKgain *gain_ptr[]) | |
975 { | 971 { |
976 int offset; | 972 int offset; |
977 | 973 |
978 offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, | 974 offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, |
979 q->bits_per_subpacket/8); | 975 q->bits_per_subpacket/8); |
980 init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, | 976 init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, |
981 q->bits_per_subpacket); | 977 q->bits_per_subpacket); |
982 decode_gain_info(&q->gb, gain_ptr); | 978 decode_gain_info(&q->gb, gain_ptr[0]); |
979 | |
980 /* Swap current and previous gains */ | |
981 FFSWAP(COOKgain *, gain_ptr[0], gain_ptr[1]); | |
982 } | |
983 | |
984 /** | |
985 * Final part of subpacket decoding: | |
986 * Apply modulated lapped transform, gain compensation, | |
987 * clip and convert to integer. | |
988 * | |
989 * @param q pointer to the COOKContext | |
990 * @param decode_buffer pointer to the mlt coefficients | |
991 * @param gain_ptr array of current/prev gain pointers | |
992 * @param previous_buffer pointer to the previous buffer to be used for overlapping | |
993 * @param out pointer to the output buffer | |
994 * @param chan 0: left or single channel, 1: right channel | |
995 */ | |
996 | |
997 static inline void | |
998 mlt_compensate_output(COOKContext *q, float *decode_buffer, | |
999 COOKgain *gain_ptr[], float *previous_buffer, | |
1000 int16_t *out, int chan) | |
1001 { | |
1002 int j; | |
1003 | |
1004 cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp); | |
1005 gain_compensate(q, q->mono_mdct_output, gain_ptr[0], | |
1006 gain_ptr[1], previous_buffer); | |
1007 | |
1008 /* Clip and convert floats to 16 bits. | |
1009 */ | |
1010 for (j = 0; j < q->samples_per_channel; j++) { | |
1011 out[chan + q->nb_channels * j] = | |
1012 clip(lrintf(q->mono_mdct_output[j]), -32768, 32767); | |
1013 } | |
983 } | 1014 } |
984 | 1015 |
985 | 1016 |
986 /** | 1017 /** |
987 * Cook subpacket decoding. This function returns one decoded subpacket, | 1018 * Cook subpacket decoding. This function returns one decoded subpacket, |
994 */ | 1025 */ |
995 | 1026 |
996 | 1027 |
997 static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, | 1028 static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, |
998 int sub_packet_size, int16_t *outbuffer) { | 1029 int sub_packet_size, int16_t *outbuffer) { |
999 int i,j; | |
1000 int value; | |
1001 float* tmp_ptr; | |
1002 | |
1003 /* packet dump */ | 1030 /* packet dump */ |
1004 // for (i=0 ; i<sub_packet_size ; i++) { | 1031 // for (i=0 ; i<sub_packet_size ; i++) { |
1005 // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]); | 1032 // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]); |
1006 // } | 1033 // } |
1007 // av_log(NULL, AV_LOG_ERROR, "\n"); | 1034 // av_log(NULL, AV_LOG_ERROR, "\n"); |
1008 | 1035 |
1009 if(q->nb_channels==2 && q->joint_stereo==1){ | 1036 decode_bytes_and_gain(q, inbuffer, q->gain_ptr1); |
1010 decode_bytes_and_gain(q, inbuffer, &q->gain_current); | 1037 |
1011 | 1038 if (q->joint_stereo) { |
1012 joint_decode(q, q->decode_buf_ptr[0], q->decode_buf_ptr[2]); | 1039 joint_decode(q, q->decode_buffer_1, q->decode_buffer_2); |
1013 | 1040 } else { |
1014 /* Swap buffer pointers. */ | 1041 mono_decode(q, q->decode_buffer_1); |
1015 tmp_ptr = q->decode_buf_ptr[1]; | 1042 |
1016 q->decode_buf_ptr[1] = q->decode_buf_ptr[0]; | 1043 if (q->nb_channels == 2) { |
1017 q->decode_buf_ptr[0] = tmp_ptr; | |
1018 tmp_ptr = q->decode_buf_ptr[3]; | |
1019 q->decode_buf_ptr[3] = q->decode_buf_ptr[2]; | |
1020 q->decode_buf_ptr[2] = tmp_ptr; | |
1021 | |
1022 /* FIXME: Rethink the gainbuffer handling, maybe a rename? | |
1023 now/previous swap */ | |
1024 q->gain_now_ptr = &q->gain_now; | |
1025 q->gain_previous_ptr = &q->gain_previous; | |
1026 for (i=0 ; i<q->nb_channels ; i++){ | |
1027 | |
1028 cook_imlt(q, q->decode_buf_ptr[i*2], q->mono_mdct_output, q->mlt_tmp); | |
1029 gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, | |
1030 q->gain_previous_ptr, q->previous_buffer_ptr[0]); | |
1031 | |
1032 /* Swap out the previous buffer. */ | |
1033 tmp_ptr = q->previous_buffer_ptr[0]; | |
1034 q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1]; | |
1035 q->previous_buffer_ptr[1] = tmp_ptr; | |
1036 | |
1037 /* Clip and convert the floats to 16 bits. */ | |
1038 for (j=0 ; j<q->samples_per_frame ; j++){ | |
1039 value = lrintf(q->mono_mdct_output[j]); | |
1040 if(value < -32768) value = -32768; | |
1041 else if(value > 32767) value = 32767; | |
1042 outbuffer[2*j+i] = value; | |
1043 } | |
1044 } | |
1045 | |
1046 memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain)); | |
1047 memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain)); | |
1048 | |
1049 } else if (q->nb_channels==2 && q->joint_stereo==0) { | |
1050 /* channel 0 */ | |
1051 decode_bytes_and_gain(q, inbuffer, &q->gain_current); | |
1052 | |
1053 mono_decode(q, q->decode_buf_ptr2[0]); | |
1054 | |
1055 tmp_ptr = q->decode_buf_ptr2[0]; | |
1056 q->decode_buf_ptr2[0] = q->decode_buf_ptr2[1]; | |
1057 q->decode_buf_ptr2[1] = tmp_ptr; | |
1058 | |
1059 memcpy(&q->gain_channel1[0], &q->gain_current ,sizeof(COOKgain)); | |
1060 q->gain_now_ptr = &q->gain_channel1[0]; | |
1061 q->gain_previous_ptr = &q->gain_channel1[1]; | |
1062 | |
1063 cook_imlt(q, q->decode_buf_ptr2[0], q->mono_mdct_output,q->mlt_tmp); | |
1064 gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, | |
1065 q->gain_previous_ptr, q->mono_previous_buffer1); | |
1066 | |
1067 memcpy(&q->gain_channel1[1], &q->gain_channel1[0],sizeof(COOKgain)); | |
1068 | |
1069 | |
1070 for (j=0 ; j<q->samples_per_frame ; j++){ | |
1071 value = lrintf(q->mono_mdct_output[j]); | |
1072 if(value < -32768) value = -32768; | |
1073 else if(value > 32767) value = 32767; | |
1074 outbuffer[2*j] = value; | |
1075 } | |
1076 | |
1077 /* channel 1 */ | |
1078 //av_log(NULL,AV_LOG_ERROR,"bits = %d\n",get_bits_count(&q->gb)); | |
1079 decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, | 1044 decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, |
1080 &q->gain_channel2[0]); | 1045 q->gain_ptr2); |
1081 | 1046 mono_decode(q, q->decode_buffer_2); |
1082 q->gain_now_ptr = &q->gain_channel2[0]; | 1047 } |
1083 q->gain_previous_ptr = &q->gain_channel2[1]; | 1048 } |
1084 | 1049 |
1085 mono_decode(q, q->decode_buf_ptr[0]); | 1050 mlt_compensate_output(q, q->decode_buffer_1, q->gain_ptr1, |
1086 | 1051 q->mono_previous_buffer1, outbuffer, 0); |
1087 tmp_ptr = q->decode_buf_ptr[0]; | 1052 |
1088 q->decode_buf_ptr[0] = q->decode_buf_ptr[1]; | 1053 if (q->nb_channels == 2) { |
1089 q->decode_buf_ptr[1] = tmp_ptr; | 1054 if (q->joint_stereo) { |
1090 | 1055 mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr1, |
1091 cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp); | 1056 q->mono_previous_buffer2, outbuffer, 1); |
1092 gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, | 1057 } else { |
1093 q->gain_previous_ptr, q->mono_previous_buffer2); | 1058 mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr2, |
1094 | 1059 q->mono_previous_buffer2, outbuffer, 1); |
1095 /* Swap out the previous buffer. */ | 1060 } |
1096 tmp_ptr = q->previous_buffer_ptr[0]; | |
1097 q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1]; | |
1098 q->previous_buffer_ptr[1] = tmp_ptr; | |
1099 | |
1100 memcpy(&q->gain_channel2[1], &q->gain_channel2[0] ,sizeof(COOKgain)); | |
1101 | |
1102 for (j=0 ; j<q->samples_per_frame ; j++){ | |
1103 value = lrintf(q->mono_mdct_output[j]); | |
1104 if(value < -32768) value = -32768; | |
1105 else if(value > 32767) value = 32767; | |
1106 outbuffer[2*j+1] = value; | |
1107 } | |
1108 | |
1109 } else { | |
1110 decode_bytes_and_gain(q, inbuffer, &q->gain_current); | |
1111 | |
1112 mono_decode(q, q->decode_buf_ptr[0]); | |
1113 | |
1114 /* Swap buffer pointers. */ | |
1115 tmp_ptr = q->decode_buf_ptr[1]; | |
1116 q->decode_buf_ptr[1] = q->decode_buf_ptr[0]; | |
1117 q->decode_buf_ptr[0] = tmp_ptr; | |
1118 | |
1119 /* FIXME: Rethink the gainbuffer handling, maybe a rename? | |
1120 now/previous swap */ | |
1121 q->gain_now_ptr = &q->gain_now; | |
1122 q->gain_previous_ptr = &q->gain_previous; | |
1123 | |
1124 cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp); | |
1125 gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, | |
1126 q->gain_previous_ptr, q->mono_previous_buffer1); | |
1127 | |
1128 /* Clip and convert the floats to 16 bits */ | |
1129 for (j=0 ; j<q->samples_per_frame ; j++){ | |
1130 value = lrintf(q->mono_mdct_output[j]); | |
1131 if(value < -32768) value = -32768; | |
1132 else if(value > 32767) value = 32767; | |
1133 outbuffer[j] = value; | |
1134 } | |
1135 memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain)); | |
1136 memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain)); | |
1137 } | 1061 } |
1138 return q->samples_per_frame * sizeof(int16_t); | 1062 return q->samples_per_frame * sizeof(int16_t); |
1139 } | 1063 } |
1140 | 1064 |
1141 | 1065 |
1234 q->log2_numvector_size = 5; | 1158 q->log2_numvector_size = 5; |
1235 q->total_subbands = q->subbands; | 1159 q->total_subbands = q->subbands; |
1236 | 1160 |
1237 /* Initialize version-dependent variables */ | 1161 /* Initialize version-dependent variables */ |
1238 av_log(NULL,AV_LOG_DEBUG,"e->cookversion=%x\n",e->cookversion); | 1162 av_log(NULL,AV_LOG_DEBUG,"e->cookversion=%x\n",e->cookversion); |
1163 q->joint_stereo = 0; | |
1239 switch (e->cookversion) { | 1164 switch (e->cookversion) { |
1240 case MONO: | 1165 case MONO: |
1241 if (q->nb_channels != 1) { | 1166 if (q->nb_channels != 1) { |
1242 av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n"); | 1167 av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n"); |
1243 return -1; | 1168 return -1; |
1244 } | 1169 } |
1245 av_log(avctx,AV_LOG_DEBUG,"MONO\n"); | 1170 av_log(avctx,AV_LOG_DEBUG,"MONO\n"); |
1246 break; | 1171 break; |
1247 case STEREO: | 1172 case STEREO: |
1248 if (q->nb_channels != 1) { | 1173 if (q->nb_channels != 1) { |
1249 q->joint_stereo = 0; | |
1250 q->bits_per_subpacket = q->bits_per_subpacket/2; | 1174 q->bits_per_subpacket = q->bits_per_subpacket/2; |
1251 } | 1175 } |
1252 av_log(avctx,AV_LOG_DEBUG,"STEREO\n"); | 1176 av_log(avctx,AV_LOG_DEBUG,"STEREO\n"); |
1253 break; | 1177 break; |
1254 case JOINT_STEREO: | 1178 case JOINT_STEREO: |
1311 + FF_INPUT_BUFFER_PADDING_SIZE); | 1235 + FF_INPUT_BUFFER_PADDING_SIZE); |
1312 } | 1236 } |
1313 if (q->decoded_bytes_buffer == NULL) | 1237 if (q->decoded_bytes_buffer == NULL) |
1314 return -1; | 1238 return -1; |
1315 | 1239 |
1316 q->decode_buf_ptr[0] = q->decode_buffer_1; | 1240 q->gain_ptr1[0] = &q->gain_1; |
1317 q->decode_buf_ptr[1] = q->decode_buffer_2; | 1241 q->gain_ptr1[1] = &q->gain_2; |
1318 q->decode_buf_ptr[2] = q->decode_buffer_3; | 1242 q->gain_ptr2[0] = &q->gain_3; |
1319 q->decode_buf_ptr[3] = q->decode_buffer_4; | 1243 q->gain_ptr2[1] = &q->gain_4; |
1320 | |
1321 q->decode_buf_ptr2[0] = q->decode_buffer_3; | |
1322 q->decode_buf_ptr2[1] = q->decode_buffer_4; | |
1323 | |
1324 q->previous_buffer_ptr[0] = q->mono_previous_buffer1; | |
1325 q->previous_buffer_ptr[1] = q->mono_previous_buffer2; | |
1326 | 1244 |
1327 /* Initialize transform. */ | 1245 /* Initialize transform. */ |
1328 if ( init_cook_mlt(q) == 0 ) | 1246 if ( init_cook_mlt(q) == 0 ) |
1329 return -1; | 1247 return -1; |
1330 | 1248 |