From eea784dab00d9f123c508d3e0c6b16e4f3123bb0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 10 Nov 2006 11:31:02 +0000 Subject: store a identifer and the first header in extradata with this mp3 should be binary identical to what you had before header compression support mp3 with crc (by droping the crc and putting it back during header decompress, currently its just random tough, does any deocoder even check it?) Originally committed as revision 6960 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/bitstream_filter.c | 68 ++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 24 deletions(-) (limited to 'libavcodec/bitstream_filter.c') 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; } } -- cgit v1.2.3