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
This commit is contained in:
parent
f889d3f9e4
commit
eea784dab0
@ -125,21 +125,24 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MP3_MASK 0xFFFE0CCF
|
||||||
|
|
||||||
static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
|
static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
|
||||||
uint8_t **poutbuf, int *poutbuf_size,
|
uint8_t **poutbuf, int *poutbuf_size,
|
||||||
const uint8_t *buf, int buf_size, int keyframe){
|
const uint8_t *buf, int buf_size, int keyframe){
|
||||||
uint32_t header;
|
uint32_t header, extraheader;
|
||||||
int mode_extension;
|
int mode_extension, header_size;
|
||||||
|
|
||||||
if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
|
if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
|
||||||
av_log(avctx, AV_LOG_ERROR, "not standards compliant\n");
|
av_log(avctx, AV_LOG_ERROR, "not standards compliant\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
header = BE_32(buf);
|
||||||
mode_extension= (header>>4)&3;
|
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= (uint8_t *) buf;
|
||||||
*poutbuf_size= buf_size;
|
*poutbuf_size= buf_size;
|
||||||
|
|
||||||
@ -147,9 +150,25 @@ static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *a
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*poutbuf_size= buf_size - 4;
|
if(avctx->extradata_size == 0){
|
||||||
*poutbuf= av_malloc(buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE);
|
avctx->extradata_size=15;
|
||||||
memcpy(*poutbuf, buf + 4, buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE);
|
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(avctx->channels==2){
|
||||||
if((header & (3<<19)) != 3<<19){
|
if((header & (3<<19)) != 3<<19){
|
||||||
@ -173,7 +192,7 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
|
|||||||
int sample_rate_index=0;
|
int sample_rate_index=0;
|
||||||
int lsf, mpeg25, bitrate_index, frame_size;
|
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){
|
if(ff_mpa_check_header(header) >= 0){
|
||||||
*poutbuf= (uint8_t *) buf;
|
*poutbuf= (uint8_t *) buf;
|
||||||
*poutbuf_size= buf_size;
|
*poutbuf_size= buf_size;
|
||||||
@ -181,18 +200,16 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
|
|||||||
return 0;
|
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;
|
lsf = sample_rate < (24000+32000)/2;
|
||||||
mpeg25 = sample_rate < (12000+16000)/2;
|
mpeg25 = sample_rate < (12000+16000)/2;
|
||||||
header |= (!mpeg25)<<20;
|
sample_rate_index= (header>>10)&3;
|
||||||
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= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
|
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++){
|
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);
|
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
|
||||||
if(frame_size == buf_size + 4)
|
if(frame_size == buf_size + 4)
|
||||||
break;
|
break;
|
||||||
|
if(frame_size == buf_size + 6)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(bitrate_index == 30){
|
if(bitrate_index == 30){
|
||||||
av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n");
|
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)<<9;
|
||||||
header |= (bitrate_index>>1)<<12;
|
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_size= frame_size;
|
||||||
*poutbuf= av_malloc(buf_size + 4 + FF_INPUT_BUFFER_PADDING_SIZE);
|
*poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
memcpy(*poutbuf + 4, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
|
||||||
if(avctx->channels==2){
|
if(avctx->channels==2){
|
||||||
|
uint8_t *p= *poutbuf + frame_size - buf_size;
|
||||||
if(lsf){
|
if(lsf){
|
||||||
FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]);
|
FFSWAP(int, p[1], p[2]);
|
||||||
header |= ((*poutbuf)[5] & 0xC0)>>2;
|
header |= (p[1] & 0xC0)>>2;
|
||||||
}else{
|
}else{
|
||||||
header |= (*poutbuf)[5] & 0x30;
|
header |= p[1] & 0x30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user