Originally committed as revision 6958 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -869,5 +869,7 @@ void avcodec_register_all(void) |
| 869 | 869 |
av_register_bitstream_filter(&dump_extradata_bsf); |
| 870 | 870 |
av_register_bitstream_filter(&remove_extradata_bsf); |
| 871 | 871 |
av_register_bitstream_filter(&noise_bsf); |
| 872 |
+ av_register_bitstream_filter(&mp3_header_compress_bsf); |
|
| 873 |
+ av_register_bitstream_filter(&mp3_header_decompress_bsf); |
|
| 872 | 874 |
} |
| 873 | 875 |
|
| ... | ... |
@@ -2662,6 +2662,8 @@ void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); |
| 2662 | 2662 |
extern AVBitStreamFilter dump_extradata_bsf; |
| 2663 | 2663 |
extern AVBitStreamFilter remove_extradata_bsf; |
| 2664 | 2664 |
extern AVBitStreamFilter noise_bsf; |
| 2665 |
+extern AVBitStreamFilter mp3_header_compress_bsf; |
|
| 2666 |
+extern AVBitStreamFilter mp3_header_decompress_bsf; |
|
| 2665 | 2667 |
|
| 2666 | 2668 |
|
| 2667 | 2669 |
/* memory */ |
| ... | ... |
@@ -19,6 +19,7 @@ |
| 19 | 19 |
*/ |
| 20 | 20 |
|
| 21 | 21 |
#include "avcodec.h" |
| 22 |
+#include "mpegaudio.h" |
|
| 22 | 23 |
|
| 23 | 24 |
AVBitStreamFilter *first_bitstream_filter= NULL; |
| 24 | 25 |
|
| ... | ... |
@@ -124,6 +125,112 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch |
| 124 | 124 |
return 1; |
| 125 | 125 |
} |
| 126 | 126 |
|
| 127 |
+static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, |
|
| 128 |
+ uint8_t **poutbuf, int *poutbuf_size, |
|
| 129 |
+ const uint8_t *buf, int buf_size, int keyframe){
|
|
| 130 |
+ uint32_t header; |
|
| 131 |
+ int mode_extension; |
|
| 132 |
+ |
|
| 133 |
+ if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
|
|
| 134 |
+ av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); |
|
| 135 |
+ return -1; |
|
| 136 |
+ } |
|
| 137 |
+ |
|
| 138 |
+ header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
|
| 139 |
+ mode_extension= (header>>4)&3; |
|
| 140 |
+ |
|
| 141 |
+ if(ff_mpa_check_header(header) < 0 || (header&0x70000) != 0x30000){
|
|
| 142 |
+ *poutbuf= (uint8_t *) buf; |
|
| 143 |
+ *poutbuf_size= buf_size; |
|
| 144 |
+ |
|
| 145 |
+ av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); |
|
| 146 |
+ return 0; |
|
| 147 |
+ } |
|
| 148 |
+ |
|
| 149 |
+ *poutbuf_size= buf_size - 4; |
|
| 150 |
+ *poutbuf= av_malloc(buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 151 |
+ memcpy(*poutbuf, buf + 4, buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 152 |
+ |
|
| 153 |
+ if(avctx->channels==2){
|
|
| 154 |
+ if((header & (3<<19)) != 3<<19){
|
|
| 155 |
+ (*poutbuf)[1] &= 0x3F; |
|
| 156 |
+ (*poutbuf)[1] |= mode_extension<<6; |
|
| 157 |
+ FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]); |
|
| 158 |
+ }else{
|
|
| 159 |
+ (*poutbuf)[1] &= 0x8F; |
|
| 160 |
+ (*poutbuf)[1] |= mode_extension<<4; |
|
| 161 |
+ } |
|
| 162 |
+ } |
|
| 163 |
+ |
|
| 164 |
+ return 1; |
|
| 165 |
+} |
|
| 166 |
+ |
|
| 167 |
+static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, |
|
| 168 |
+ uint8_t **poutbuf, int *poutbuf_size, |
|
| 169 |
+ const uint8_t *buf, int buf_size, int keyframe){
|
|
| 170 |
+ uint32_t header; |
|
| 171 |
+ int sample_rate= avctx->sample_rate; |
|
| 172 |
+ int sample_rate_index=0; |
|
| 173 |
+ int lsf, mpeg25, bitrate_index, frame_size; |
|
| 174 |
+ |
|
| 175 |
+ header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
|
| 176 |
+ if(ff_mpa_check_header(header) >= 0){
|
|
| 177 |
+ *poutbuf= (uint8_t *) buf; |
|
| 178 |
+ *poutbuf_size= buf_size; |
|
| 179 |
+ |
|
| 180 |
+ return 0; |
|
| 181 |
+ } |
|
| 182 |
+ |
|
| 183 |
+ header= 0xFFE00000 | ((4-3)<<17) | (1<<16); //FIXME simplify |
|
| 184 |
+ |
|
| 185 |
+ lsf = sample_rate < (24000+32000)/2; |
|
| 186 |
+ mpeg25 = sample_rate < (12000+16000)/2; |
|
| 187 |
+ header |= (!mpeg25)<<20; |
|
| 188 |
+ header |= (!lsf )<<19; |
|
| 189 |
+ if(sample_rate<<(lsf+mpeg25) < (44100+32000)/2) |
|
| 190 |
+ sample_rate_index |= 2; |
|
| 191 |
+ else if(sample_rate<<(lsf+mpeg25) > (44100+48000)/2) |
|
| 192 |
+ sample_rate_index |= 1; |
|
| 193 |
+ |
|
| 194 |
+ header |= sample_rate_index<<10; |
|
| 195 |
+ sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off |
|
| 196 |
+ |
|
| 197 |
+ for(bitrate_index=2; bitrate_index<30; bitrate_index++){
|
|
| 198 |
+ frame_size = mpa_bitrate_tab[lsf][2][bitrate_index>>1]; |
|
| 199 |
+ frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); |
|
| 200 |
+ if(frame_size == buf_size + 4) |
|
| 201 |
+ break; |
|
| 202 |
+ } |
|
| 203 |
+ if(bitrate_index == 30){
|
|
| 204 |
+ av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n"); |
|
| 205 |
+ return -1; |
|
| 206 |
+ } |
|
| 207 |
+ |
|
| 208 |
+ header |= (bitrate_index&1)<<9; |
|
| 209 |
+ header |= (bitrate_index>>1)<<12; |
|
| 210 |
+ header |= (avctx->channels==1 ? MPA_MONO : MPA_JSTEREO)<<6; |
|
| 211 |
+ |
|
| 212 |
+ *poutbuf_size= buf_size + 4; |
|
| 213 |
+ *poutbuf= av_malloc(buf_size + 4 + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 214 |
+ memcpy(*poutbuf + 4, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 215 |
+ |
|
| 216 |
+ if(avctx->channels==2){
|
|
| 217 |
+ if(lsf){
|
|
| 218 |
+ FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]); |
|
| 219 |
+ header |= ((*poutbuf)[5] & 0xC0)>>2; |
|
| 220 |
+ }else{
|
|
| 221 |
+ header |= (*poutbuf)[5] & 0x30; |
|
| 222 |
+ } |
|
| 223 |
+ } |
|
| 224 |
+ |
|
| 225 |
+ (*poutbuf)[0]= header>>24; |
|
| 226 |
+ (*poutbuf)[1]= header>>16; |
|
| 227 |
+ (*poutbuf)[2]= header>> 8; |
|
| 228 |
+ (*poutbuf)[3]= header ; |
|
| 229 |
+ |
|
| 230 |
+ return 1; |
|
| 231 |
+} |
|
| 232 |
+ |
|
| 127 | 233 |
AVBitStreamFilter dump_extradata_bsf={
|
| 128 | 234 |
"dump_extra", |
| 129 | 235 |
0, |
| ... | ... |
@@ -141,3 +248,15 @@ AVBitStreamFilter noise_bsf={
|
| 141 | 141 |
sizeof(int), |
| 142 | 142 |
noise, |
| 143 | 143 |
}; |
| 144 |
+ |
|
| 145 |
+AVBitStreamFilter mp3_header_compress_bsf={
|
|
| 146 |
+ "mp3comp", |
|
| 147 |
+ 0, |
|
| 148 |
+ mp3_header_compress, |
|
| 149 |
+}; |
|
| 150 |
+ |
|
| 151 |
+AVBitStreamFilter mp3_header_decompress_bsf={
|
|
| 152 |
+ "mp3decomp", |
|
| 153 |
+ 0, |
|
| 154 |
+ mp3_header_decompress, |
|
| 155 |
+}; |