Commit dce9e386 authored by michael's avatar michael

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?)


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@6960 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 15ff4425
......@@ -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;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment