[Ffmpeg-cvslog] r6960 - trunk/libavcodec/bitstream_filter.c

michael subversion
Fri Nov 10 12:31:03 CET 2006


Author: michael
Date: Fri Nov 10 12:31:02 2006
New Revision: 6960

Modified:
   trunk/libavcodec/bitstream_filter.c

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


Modified: trunk/libavcodec/bitstream_filter.c
==============================================================================
--- trunk/libavcodec/bitstream_filter.c	(original)
+++ trunk/libavcodec/bitstream_filter.c	Fri Nov 10 12:31:02 2006
@@ -125,21 +125,24 @@
     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 @@
         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 @@
     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 @@
         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 @@
         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 @@
 
     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;
         }
     }
 




More information about the ffmpeg-cvslog mailing list