Originally committed as revision 6960 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -125,21 +125,24 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch |
| 125 | 125 |
return 1; |
| 126 | 126 |
} |
| 127 | 127 |
|
| 128 |
+#define MP3_MASK 0xFFFE0CCF |
|
| 129 |
+ |
|
| 128 | 130 |
static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, |
| 129 | 131 |
uint8_t **poutbuf, int *poutbuf_size, |
| 130 | 132 |
const uint8_t *buf, int buf_size, int keyframe){
|
| 131 |
- uint32_t header; |
|
| 132 |
- int mode_extension; |
|
| 133 |
+ uint32_t header, extraheader; |
|
| 134 |
+ int mode_extension, header_size; |
|
| 133 | 135 |
|
| 134 | 136 |
if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
|
| 135 | 137 |
av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); |
| 136 | 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 | 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 | 146 |
*poutbuf= (uint8_t *) buf; |
| 144 | 147 |
*poutbuf_size= buf_size; |
| 145 | 148 |
|
| ... | ... |
@@ -147,9 +150,25 @@ static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *a |
| 147 | 147 |
return 0; |
| 148 | 148 |
} |
| 149 | 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); |
|
| 150 |
+ if(avctx->extradata_size == 0){
|
|
| 151 |
+ avctx->extradata_size=15; |
|
| 152 |
+ avctx->extradata= av_malloc(avctx->extradata_size); |
|
| 153 |
+ strcpy(avctx->extradata, "FFCMP3 0.0"); |
|
| 154 |
+ memcpy(avctx->extradata+11, buf, 4); |
|
| 155 |
+ } |
|
| 156 |
+ if(avctx->extradata_size != 15){
|
|
| 157 |
+ av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n"); |
|
| 158 |
+ return -1; |
|
| 159 |
+ } |
|
| 160 |
+ extraheader = BE_32(avctx->extradata+11); |
|
| 161 |
+ if((extraheader&MP3_MASK) != (header&MP3_MASK)) |
|
| 162 |
+ goto output_unchanged; |
|
| 163 |
+ |
|
| 164 |
+ header_size= (header&0x10000) ? 4 : 6; |
|
| 165 |
+ |
|
| 166 |
+ *poutbuf_size= buf_size - header_size; |
|
| 167 |
+ *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 168 |
+ memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 153 | 169 |
|
| 154 | 170 |
if(avctx->channels==2){
|
| 155 | 171 |
if((header & (3<<19)) != 3<<19){
|
| ... | ... |
@@ -173,7 +192,7 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext |
| 173 | 173 |
int sample_rate_index=0; |
| 174 | 174 |
int lsf, mpeg25, bitrate_index, frame_size; |
| 175 | 175 |
|
| 176 |
- header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
|
| 176 |
+ header = BE_32(buf); |
|
| 177 | 177 |
if(ff_mpa_check_header(header) >= 0){
|
| 178 | 178 |
*poutbuf= (uint8_t *) buf; |
| 179 | 179 |
*poutbuf_size= buf_size; |
| ... | ... |
@@ -181,18 +200,16 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext |
| 181 | 181 |
return 0; |
| 182 | 182 |
} |
| 183 | 183 |
|
| 184 |
- header= 0xFFE00000 | ((4-3)<<17) | (1<<16); //FIXME simplify |
|
| 184 |
+ if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){
|
|
| 185 |
+ av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size); |
|
| 186 |
+ return -1; |
|
| 187 |
+ } |
|
| 188 |
+ |
|
| 189 |
+ header= BE_32(avctx->extradata+11) & MP3_MASK; |
|
| 185 | 190 |
|
| 186 | 191 |
lsf = sample_rate < (24000+32000)/2; |
| 187 | 192 |
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; |
|
| 193 |
+ sample_rate_index= (header>>10)&3; |
|
| 196 | 194 |
sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off |
| 197 | 195 |
|
| 198 | 196 |
for(bitrate_index=2; bitrate_index<30; bitrate_index++){
|
| ... | ... |
@@ -200,6 +217,8 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext |
| 200 | 200 |
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); |
| 201 | 201 |
if(frame_size == buf_size + 4) |
| 202 | 202 |
break; |
| 203 |
+ if(frame_size == buf_size + 6) |
|
| 204 |
+ break; |
|
| 203 | 205 |
} |
| 204 | 206 |
if(bitrate_index == 30){
|
| 205 | 207 |
av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n"); |
| ... | ... |
@@ -208,18 +227,19 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext |
| 208 | 208 |
|
| 209 | 209 |
header |= (bitrate_index&1)<<9; |
| 210 | 210 |
header |= (bitrate_index>>1)<<12; |
| 211 |
- header |= (avctx->channels==1 ? MPA_MONO : MPA_JSTEREO)<<6; |
|
| 211 |
+ header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0 |
|
| 212 | 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); |
|
| 213 |
+ *poutbuf_size= frame_size; |
|
| 214 |
+ *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 215 |
+ memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
| 216 | 216 |
|
| 217 | 217 |
if(avctx->channels==2){
|
| 218 |
+ uint8_t *p= *poutbuf + frame_size - buf_size; |
|
| 218 | 219 |
if(lsf){
|
| 219 |
- FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]); |
|
| 220 |
- header |= ((*poutbuf)[5] & 0xC0)>>2; |
|
| 220 |
+ FFSWAP(int, p[1], p[2]); |
|
| 221 |
+ header |= (p[1] & 0xC0)>>2; |
|
| 221 | 222 |
}else{
|
| 222 |
- header |= (*poutbuf)[5] & 0x30; |
|
| 223 |
+ header |= p[1] & 0x30; |
|
| 223 | 224 |
} |
| 224 | 225 |
} |
| 225 | 226 |
|