Mercurial > libavcodec.hg
comparison bitstream_filter.c @ 4167:a3134db4857e libavcodec
store a identifer and the first header in extradata
with this mp3 should be binary identical to what you had before header compression
support mp3 with crc (by droping the crc and putting it back during header decompress, currently its just random tough, does any deocoder even check it?)
author | michael |
---|---|
date | Fri, 10 Nov 2006 11:31:02 +0000 |
parents | eced83504436 |
children | 38bb77e11353 |
comparison
equal
deleted
inserted
replaced
4166:eced83504436 | 4167:a3134db4857e |
---|---|
123 (*poutbuf)[i] = *state; | 123 (*poutbuf)[i] = *state; |
124 } | 124 } |
125 return 1; | 125 return 1; |
126 } | 126 } |
127 | 127 |
128 #define MP3_MASK 0xFFFE0CCF | |
129 | |
128 static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, | 130 static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, |
129 uint8_t **poutbuf, int *poutbuf_size, | 131 uint8_t **poutbuf, int *poutbuf_size, |
130 const uint8_t *buf, int buf_size, int keyframe){ | 132 const uint8_t *buf, int buf_size, int keyframe){ |
131 uint32_t header; | 133 uint32_t header, extraheader; |
132 int mode_extension; | 134 int mode_extension, header_size; |
133 | 135 |
134 if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ | 136 if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ |
135 av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); | 137 av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); |
136 return -1; | 138 return -1; |
137 } | 139 } |
138 | 140 |
139 header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | 141 header = BE_32(buf); |
140 mode_extension= (header>>4)&3; | 142 mode_extension= (header>>4)&3; |
141 | 143 |
142 if(ff_mpa_check_header(header) < 0 || (header&0x70000) != 0x30000){ | 144 if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){ |
145 output_unchanged: | |
143 *poutbuf= (uint8_t *) buf; | 146 *poutbuf= (uint8_t *) buf; |
144 *poutbuf_size= buf_size; | 147 *poutbuf_size= buf_size; |
145 | 148 |
146 av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); | 149 av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); |
147 return 0; | 150 return 0; |
148 } | 151 } |
149 | 152 |
150 *poutbuf_size= buf_size - 4; | 153 if(avctx->extradata_size == 0){ |
151 *poutbuf= av_malloc(buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE); | 154 avctx->extradata_size=15; |
152 memcpy(*poutbuf, buf + 4, buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE); | 155 avctx->extradata= av_malloc(avctx->extradata_size); |
156 strcpy(avctx->extradata, "FFCMP3 0.0"); | |
157 memcpy(avctx->extradata+11, buf, 4); | |
158 } | |
159 if(avctx->extradata_size != 15){ | |
160 av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n"); | |
161 return -1; | |
162 } | |
163 extraheader = BE_32(avctx->extradata+11); | |
164 if((extraheader&MP3_MASK) != (header&MP3_MASK)) | |
165 goto output_unchanged; | |
166 | |
167 header_size= (header&0x10000) ? 4 : 6; | |
168 | |
169 *poutbuf_size= buf_size - header_size; | |
170 *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
171 memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
153 | 172 |
154 if(avctx->channels==2){ | 173 if(avctx->channels==2){ |
155 if((header & (3<<19)) != 3<<19){ | 174 if((header & (3<<19)) != 3<<19){ |
156 (*poutbuf)[1] &= 0x3F; | 175 (*poutbuf)[1] &= 0x3F; |
157 (*poutbuf)[1] |= mode_extension<<6; | 176 (*poutbuf)[1] |= mode_extension<<6; |
171 uint32_t header; | 190 uint32_t header; |
172 int sample_rate= avctx->sample_rate; | 191 int sample_rate= avctx->sample_rate; |
173 int sample_rate_index=0; | 192 int sample_rate_index=0; |
174 int lsf, mpeg25, bitrate_index, frame_size; | 193 int lsf, mpeg25, bitrate_index, frame_size; |
175 | 194 |
176 header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | 195 header = BE_32(buf); |
177 if(ff_mpa_check_header(header) >= 0){ | 196 if(ff_mpa_check_header(header) >= 0){ |
178 *poutbuf= (uint8_t *) buf; | 197 *poutbuf= (uint8_t *) buf; |
179 *poutbuf_size= buf_size; | 198 *poutbuf_size= buf_size; |
180 | 199 |
181 return 0; | 200 return 0; |
182 } | 201 } |
183 | 202 |
184 header= 0xFFE00000 | ((4-3)<<17) | (1<<16); //FIXME simplify | 203 if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){ |
204 av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size); | |
205 return -1; | |
206 } | |
207 | |
208 header= BE_32(avctx->extradata+11) & MP3_MASK; | |
185 | 209 |
186 lsf = sample_rate < (24000+32000)/2; | 210 lsf = sample_rate < (24000+32000)/2; |
187 mpeg25 = sample_rate < (12000+16000)/2; | 211 mpeg25 = sample_rate < (12000+16000)/2; |
188 header |= (!mpeg25)<<20; | 212 sample_rate_index= (header>>10)&3; |
189 header |= (!lsf )<<19; | |
190 if(sample_rate<<(lsf+mpeg25) < (44100+32000)/2) | |
191 sample_rate_index |= 2; | |
192 else if(sample_rate<<(lsf+mpeg25) > (44100+48000)/2) | |
193 sample_rate_index |= 1; | |
194 | |
195 header |= sample_rate_index<<10; | |
196 sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off | 213 sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off |
197 | 214 |
198 for(bitrate_index=2; bitrate_index<30; bitrate_index++){ | 215 for(bitrate_index=2; bitrate_index<30; bitrate_index++){ |
199 frame_size = mpa_bitrate_tab[lsf][2][bitrate_index>>1]; | 216 frame_size = mpa_bitrate_tab[lsf][2][bitrate_index>>1]; |
200 frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); | 217 frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); |
201 if(frame_size == buf_size + 4) | 218 if(frame_size == buf_size + 4) |
202 break; | 219 break; |
220 if(frame_size == buf_size + 6) | |
221 break; | |
203 } | 222 } |
204 if(bitrate_index == 30){ | 223 if(bitrate_index == 30){ |
205 av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n"); | 224 av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n"); |
206 return -1; | 225 return -1; |
207 } | 226 } |
208 | 227 |
209 header |= (bitrate_index&1)<<9; | 228 header |= (bitrate_index&1)<<9; |
210 header |= (bitrate_index>>1)<<12; | 229 header |= (bitrate_index>>1)<<12; |
211 header |= (avctx->channels==1 ? MPA_MONO : MPA_JSTEREO)<<6; | 230 header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0 |
212 | 231 |
213 *poutbuf_size= buf_size + 4; | 232 *poutbuf_size= frame_size; |
214 *poutbuf= av_malloc(buf_size + 4 + FF_INPUT_BUFFER_PADDING_SIZE); | 233 *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE); |
215 memcpy(*poutbuf + 4, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); | 234 memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
216 | 235 |
217 if(avctx->channels==2){ | 236 if(avctx->channels==2){ |
237 uint8_t *p= *poutbuf + frame_size - buf_size; | |
218 if(lsf){ | 238 if(lsf){ |
219 FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]); | 239 FFSWAP(int, p[1], p[2]); |
220 header |= ((*poutbuf)[5] & 0xC0)>>2; | 240 header |= (p[1] & 0xC0)>>2; |
221 }else{ | 241 }else{ |
222 header |= (*poutbuf)[5] & 0x30; | 242 header |= p[1] & 0x30; |
223 } | 243 } |
224 } | 244 } |
225 | 245 |
226 (*poutbuf)[0]= header>>24; | 246 (*poutbuf)[0]= header>>24; |
227 (*poutbuf)[1]= header>>16; | 247 (*poutbuf)[1]= header>>16; |