summaryrefslogtreecommitdiff
path: root/libavcodec/bitstream_filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/bitstream_filter.c')
-rw-r--r--libavcodec/bitstream_filter.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c
index ef2d7414a6..e4be773c6e 100644
--- a/libavcodec/bitstream_filter.c
+++ b/libavcodec/bitstream_filter.c
@@ -125,21 +125,24 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch
return 1;
}
+#define MP3_MASK 0xFFFE0CCF
+
static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size, int keyframe){
- uint32_t header;
- int mode_extension;
+ uint32_t header, extraheader;
+ int mode_extension, header_size;
if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
av_log(avctx, AV_LOG_ERROR, "not standards compliant\n");
return -1;
}
- header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ header = BE_32(buf);
mode_extension= (header>>4)&3;
- if(ff_mpa_check_header(header) < 0 || (header&0x70000) != 0x30000){
+ if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){
+output_unchanged:
*poutbuf= (uint8_t *) buf;
*poutbuf_size= buf_size;
@@ -147,9 +150,25 @@ static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *a
return 0;
}
- *poutbuf_size= buf_size - 4;
- *poutbuf= av_malloc(buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE);
- memcpy(*poutbuf, buf + 4, buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if(avctx->extradata_size == 0){
+ avctx->extradata_size=15;
+ avctx->extradata= av_malloc(avctx->extradata_size);
+ strcpy(avctx->extradata, "FFCMP3 0.0");
+ memcpy(avctx->extradata+11, buf, 4);
+ }
+ if(avctx->extradata_size != 15){
+ av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n");
+ return -1;
+ }
+ extraheader = BE_32(avctx->extradata+11);
+ if((extraheader&MP3_MASK) != (header&MP3_MASK))
+ goto output_unchanged;
+
+ header_size= (header&0x10000) ? 4 : 6;
+
+ *poutbuf_size= buf_size - header_size;
+ *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
if(avctx->channels==2){
if((header & (3<<19)) != 3<<19){
@@ -173,7 +192,7 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
int sample_rate_index=0;
int lsf, mpeg25, bitrate_index, frame_size;
- header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ header = BE_32(buf);
if(ff_mpa_check_header(header) >= 0){
*poutbuf= (uint8_t *) buf;
*poutbuf_size= buf_size;
@@ -181,18 +200,16 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
return 0;
}
- header= 0xFFE00000 | ((4-3)<<17) | (1<<16); //FIXME simplify
+ if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){
+ av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size);
+ return -1;
+ }
+
+ header= BE_32(avctx->extradata+11) & MP3_MASK;
lsf = sample_rate < (24000+32000)/2;
mpeg25 = sample_rate < (12000+16000)/2;
- header |= (!mpeg25)<<20;
- header |= (!lsf )<<19;
- if(sample_rate<<(lsf+mpeg25) < (44100+32000)/2)
- sample_rate_index |= 2;
- else if(sample_rate<<(lsf+mpeg25) > (44100+48000)/2)
- sample_rate_index |= 1;
-
- header |= sample_rate_index<<10;
+ sample_rate_index= (header>>10)&3;
sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
for(bitrate_index=2; bitrate_index<30; bitrate_index++){
@@ -200,6 +217,8 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
if(frame_size == buf_size + 4)
break;
+ if(frame_size == buf_size + 6)
+ break;
}
if(bitrate_index == 30){
av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n");
@@ -208,18 +227,19 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
header |= (bitrate_index&1)<<9;
header |= (bitrate_index>>1)<<12;
- header |= (avctx->channels==1 ? MPA_MONO : MPA_JSTEREO)<<6;
+ header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0
- *poutbuf_size= buf_size + 4;
- *poutbuf= av_malloc(buf_size + 4 + FF_INPUT_BUFFER_PADDING_SIZE);
- memcpy(*poutbuf + 4, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ *poutbuf_size= frame_size;
+ *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
if(avctx->channels==2){
+ uint8_t *p= *poutbuf + frame_size - buf_size;
if(lsf){
- FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]);
- header |= ((*poutbuf)[5] & 0xC0)>>2;
+ FFSWAP(int, p[1], p[2]);
+ header |= (p[1] & 0xC0)>>2;
}else{
- header |= (*poutbuf)[5] & 0x30;
+ header |= p[1] & 0x30;
}
}