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 };