Browse code

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

Michael Niedermayer authored on 2006/11/10 20:31:02
Showing 1 changed files
... ...
@@ -125,21 +125,24 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch
125 125
     return 1;
126 126
 }
127 127
 
128
+#define MP3_MASK 0xFFFE0CCF
129
+
128 130
 static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
129 131
                      uint8_t **poutbuf, int *poutbuf_size,
130 132
                      const uint8_t *buf, int buf_size, int keyframe){
131
-    uint32_t header;
132
-    int mode_extension;
133
+    uint32_t header, extraheader;
134
+    int mode_extension, header_size;
133 135
 
134 136
     if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
135 137
         av_log(avctx, AV_LOG_ERROR, "not standards compliant\n");
136 138
         return -1;
137 139
     }
138 140
 
139
-    header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
141
+    header = BE_32(buf);
140 142
     mode_extension= (header>>4)&3;
141 143
 
142
-    if(ff_mpa_check_header(header) < 0 || (header&0x70000) != 0x30000){
144
+    if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){
145
+output_unchanged:
143 146
         *poutbuf= (uint8_t *) buf;
144 147
         *poutbuf_size= buf_size;
145 148
 
... ...
@@ -147,9 +150,25 @@ static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *a
147 147
         return 0;
148 148
     }
149 149
 
150
-    *poutbuf_size= buf_size - 4;
151
-    *poutbuf= av_malloc(buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE);
152
-    memcpy(*poutbuf, buf + 4, buf_size - 4 + FF_INPUT_BUFFER_PADDING_SIZE);
150
+    if(avctx->extradata_size == 0){
151
+        avctx->extradata_size=15;
152
+        avctx->extradata= av_malloc(avctx->extradata_size);
153
+        strcpy(avctx->extradata, "FFCMP3 0.0");
154
+        memcpy(avctx->extradata+11, buf, 4);
155
+    }
156
+    if(avctx->extradata_size != 15){
157
+        av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n");
158
+        return -1;
159
+    }
160
+    extraheader = BE_32(avctx->extradata+11);
161
+    if((extraheader&MP3_MASK) != (header&MP3_MASK))
162
+        goto output_unchanged;
163
+
164
+    header_size= (header&0x10000) ? 4 : 6;
165
+
166
+    *poutbuf_size= buf_size - header_size;
167
+    *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
168
+    memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
153 169
 
154 170
     if(avctx->channels==2){
155 171
         if((header & (3<<19)) != 3<<19){
... ...
@@ -173,7 +192,7 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
173 173
     int sample_rate_index=0;
174 174
     int lsf, mpeg25, bitrate_index, frame_size;
175 175
 
176
-    header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
176
+    header = BE_32(buf);
177 177
     if(ff_mpa_check_header(header) >= 0){
178 178
         *poutbuf= (uint8_t *) buf;
179 179
         *poutbuf_size= buf_size;
... ...
@@ -181,18 +200,16 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
181 181
         return 0;
182 182
     }
183 183
 
184
-    header= 0xFFE00000 | ((4-3)<<17) | (1<<16); //FIXME simplify
184
+    if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){
185
+        av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size);
186
+        return -1;
187
+    }
188
+
189
+    header= BE_32(avctx->extradata+11) & MP3_MASK;
185 190
 
186 191
     lsf     = sample_rate < (24000+32000)/2;
187 192
     mpeg25  = sample_rate < (12000+16000)/2;
188
-    header |= (!mpeg25)<<20;
189
-    header |= (!lsf   )<<19;
190
-    if(sample_rate<<(lsf+mpeg25) < (44100+32000)/2)
191
-        sample_rate_index |= 2;
192
-    else if(sample_rate<<(lsf+mpeg25) > (44100+48000)/2)
193
-        sample_rate_index |= 1;
194
-
195
-    header |= sample_rate_index<<10;
193
+    sample_rate_index= (header>>10)&3;
196 194
     sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
197 195
 
198 196
     for(bitrate_index=2; bitrate_index<30; bitrate_index++){
... ...
@@ -200,6 +217,8 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
200 200
         frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
201 201
         if(frame_size == buf_size + 4)
202 202
             break;
203
+        if(frame_size == buf_size + 6)
204
+            break;
203 205
     }
204 206
     if(bitrate_index == 30){
205 207
         av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n");
... ...
@@ -208,18 +227,19 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
208 208
 
209 209
     header |= (bitrate_index&1)<<9;
210 210
     header |= (bitrate_index>>1)<<12;
211
-    header |= (avctx->channels==1 ? MPA_MONO : MPA_JSTEREO)<<6;
211
+    header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0
212 212
 
213
-    *poutbuf_size= buf_size + 4;
214
-    *poutbuf= av_malloc(buf_size + 4 + FF_INPUT_BUFFER_PADDING_SIZE);
215
-    memcpy(*poutbuf + 4, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
213
+    *poutbuf_size= frame_size;
214
+    *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
215
+    memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
216 216
 
217 217
     if(avctx->channels==2){
218
+        uint8_t *p= *poutbuf + frame_size - buf_size;
218 219
         if(lsf){
219
-            FFSWAP(int, (*poutbuf)[5], (*poutbuf)[6]);
220
-            header |= ((*poutbuf)[5] & 0xC0)>>2;
220
+            FFSWAP(int, p[1], p[2]);
221
+            header |= (p[1] & 0xC0)>>2;
221 222
         }else{
222
-            header |= (*poutbuf)[5] & 0x30;
223
+            header |= p[1] & 0x30;
223 224
         }
224 225
     }
225 226