Mercurial > libavcodec.hg
comparison bitstream_filter.c @ 4166:eced83504436 libavcodec
mp3 header (de)compression bitstream filter
this will make mp3 frames 4 bytes smaller, it will not give you binary identical mp3 files, but it will give you mp3 files which decode to binary identical output
this will only work in containers providing at least packet size, sample_rate and number of channels
bugreports about mp3 files for which this fails are welcome
and this is experimental (dont expect compatibility and dont even expect to be able to decompress what you compressed, hell dont even expect this to work without editing the source a little)
author | michael |
---|---|
date | Fri, 10 Nov 2006 01:41:53 +0000 |
parents | c8c591fe26f8 |
children | a3134db4857e |
comparison
equal
deleted
inserted
replaced
4165:5c14c4c7974f | 4166:eced83504436 |
---|---|
17 * License along with FFmpeg; if not, write to the Free Software | 17 * License along with FFmpeg; if not, write to the Free Software |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 */ | 19 */ |
20 | 20 |
21 #include "avcodec.h" | 21 #include "avcodec.h" |
22 #include "mpegaudio.h" | |
22 | 23 |
23 AVBitStreamFilter *first_bitstream_filter= NULL; | 24 AVBitStreamFilter *first_bitstream_filter= NULL; |
24 | 25 |
25 void av_register_bitstream_filter(AVBitStreamFilter *bsf){ | 26 void av_register_bitstream_filter(AVBitStreamFilter *bsf){ |
26 bsf->next = first_bitstream_filter; | 27 bsf->next = first_bitstream_filter; |
122 (*poutbuf)[i] = *state; | 123 (*poutbuf)[i] = *state; |
123 } | 124 } |
124 return 1; | 125 return 1; |
125 } | 126 } |
126 | 127 |
128 static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, | |
129 uint8_t **poutbuf, int *poutbuf_size, | |
130 const uint8_t *buf, int buf_size, int keyframe){ | |
131 uint32_t header; | |
132 int mode_extension; | |
133 | |
134 if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ | |
135 av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); | |
136 return -1; | |
137 } | |
138 | |
139 header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | |
140 mode_extension= (header>>4)&3; | |
141 | |
142 if(ff_mpa_check_header(header) < 0 || (header&0x70000) != 0x30000){ | |
143 *poutbuf= (uint8_t *) buf; | |
144 *poutbuf_size= buf_size; | |
145 | |
146 av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); | |
147 return 0; | |
148 } | |
149 | |
150 *poutbuf_size= buf_size - 4; | |
151 *poutbuf= av_malloc(buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE); | |
152 memcpy(*poutbuf, buf + 4, buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE); | |
153 | |
154 if(avctx->channels==2){ | |
155 if((header & (3<<19)) != 3<<19){ | |
156 (*poutbuf)[1] &= 0x3F; | |
157 (*poutbuf)[1] |= mode_extension<<6; | |
158 FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]); | |
159 }else{ | |
160 (*poutbuf)[1] &= 0x8F; | |
161 (*poutbuf)[1] |= mode_extension<<4; | |
162 } | |
163 } | |
164 | |
165 return 1; | |
166 } | |
167 | |
168 static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, | |
169 uint8_t **poutbuf, int *poutbuf_size, | |
170 const uint8_t *buf, int buf_size, int keyframe){ | |
171 uint32_t header; | |
172 int sample_rate= avctx->sample_rate; | |
173 int sample_rate_index=0; | |
174 int lsf, mpeg25, bitrate_index, frame_size; | |
175 | |
176 header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | |
177 if(ff_mpa_check_header(header) >= 0){ | |
178 *poutbuf= (uint8_t *) buf; | |
179 *poutbuf_size= buf_size; | |
180 | |
181 return 0; | |
182 } | |
183 | |
184 header= 0xFFE00000 | ((4-3)<<17) | (1<<16); //FIXME simplify | |
185 | |
186 lsf = sample_rate < (24000+32000)/2; | |
187 mpeg25 = sample_rate < (12000+16000)/2; | |
188 header |= (!mpeg25)<<20; | |
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 | |
197 | |
198 for(bitrate_index=2; bitrate_index<30; bitrate_index++){ | |
199 frame_size = mpa_bitrate_tab[lsf][2][bitrate_index>>1]; | |
200 frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); | |
201 if(frame_size == buf_size + 4) | |
202 break; | |
203 } | |
204 if(bitrate_index == 30){ | |
205 av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n"); | |
206 return -1; | |
207 } | |
208 | |
209 header |= (bitrate_index&1)<<9; | |
210 header |= (bitrate_index>>1)<<12; | |
211 header |= (avctx->channels==1 ? MPA_MONO : MPA_JSTEREO)<<6; | |
212 | |
213 *poutbuf_size= buf_size + 4; | |
214 *poutbuf= av_malloc(buf_size + 4 + FF_INPUT_BUFFER_PADDING_SIZE); | |
215 memcpy(*poutbuf + 4, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
216 | |
217 if(avctx->channels==2){ | |
218 if(lsf){ | |
219 FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]); | |
220 header |= ((*poutbuf)[5] & 0xC0)>>2; | |
221 }else{ | |
222 header |= (*poutbuf)[5] & 0x30; | |
223 } | |
224 } | |
225 | |
226 (*poutbuf)[0]= header>>24; | |
227 (*poutbuf)[1]= header>>16; | |
228 (*poutbuf)[2]= header>> 8; | |
229 (*poutbuf)[3]= header ; | |
230 | |
231 return 1; | |
232 } | |
233 | |
127 AVBitStreamFilter dump_extradata_bsf={ | 234 AVBitStreamFilter dump_extradata_bsf={ |
128 "dump_extra", | 235 "dump_extra", |
129 0, | 236 0, |
130 dump_extradata, | 237 dump_extradata, |
131 }; | 238 }; |
139 AVBitStreamFilter noise_bsf={ | 246 AVBitStreamFilter noise_bsf={ |
140 "noise", | 247 "noise", |
141 sizeof(int), | 248 sizeof(int), |
142 noise, | 249 noise, |
143 }; | 250 }; |
251 | |
252 AVBitStreamFilter mp3_header_compress_bsf={ | |
253 "mp3comp", | |
254 0, | |
255 mp3_header_compress, | |
256 }; | |
257 | |
258 AVBitStreamFilter mp3_header_decompress_bsf={ | |
259 "mp3decomp", | |
260 0, | |
261 mp3_header_decompress, | |
262 }; |