mp3dec.cpp
1 /* ***** BEGIN LICENSE BLOCK ***** 2 * Version: RCSL 1.0/RPSL 1.0 3 * 4 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 5 * 6 * The contents of this file, and the files included with this file, are 7 * subject to the current version of the RealNetworks Public Source License 8 * Version 1.0 (the "RPSL") available at 9 * http://www.helixcommunity.org/content/rpsl unless you have licensed 10 * the file under the RealNetworks Community Source License Version 1.0 11 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 12 * in which case the RCSL will apply. You may also obtain the license terms 13 * directly from RealNetworks. You may not use this file except in 14 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 15 * applicable to this file, the RCSL. Please see the applicable RPSL or 16 * RCSL for the rights, obligations and limitations governing use of the 17 * contents of the file. 18 * 19 * This file is part of the Helix DNA Technology. RealNetworks is the 20 * developer of the Original Code and owns the copyrights in the portions 21 * it created. 22 * 23 * This file, and the files included with this file, is distributed and made 24 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 25 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 26 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 27 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 28 * 29 * Technology Compatibility Kit Test Suite(s) Location: 30 * http://www.helixcommunity.org/content/tck 31 * 32 * Contributor(s): 33 * 34 * ***** END LICENSE BLOCK ***** */ 35 36 /************************************************************************************** 37 * Fixed-point MP3 decoder 38 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) 39 * June 2003 40 * 41 * mp3dec.c - platform-independent top level MP3 decoder API 42 **************************************************************************************/ 43 44 #include <string.h> /* for memmove, memcpy (can replace with different implementations if desired) */ 45 #include "mp3common.h" /* includes mp3dec.h (public API) and internal, platform-independent API */ 46 //#include "hxthreadyield.h" 47 48 /************************************************************************************** 49 * Function: MP3InitDecoder 50 * 51 * Description: allocate memory for platform-specific data 52 * clear all the user-accessible fields 53 * 54 * Inputs: none 55 * 56 * Outputs: none 57 * 58 * Return: handle to mp3 decoder instance, 0 if malloc fails 59 **************************************************************************************/ 60 HMP3Decoder MP3InitDecoder(void) 61 { 62 MP3DecInfo *mp3DecInfo; 63 64 mp3DecInfo = AllocateBuffers(); 65 66 return (HMP3Decoder)mp3DecInfo; 67 } 68 69 /************************************************************************************** 70 * Function: MP3FreeDecoder 71 * 72 * Description: free platform-specific data allocated by InitMP3Decoder 73 * zero out the contents of MP3DecInfo struct 74 * 75 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) 76 * 77 * Outputs: none 78 * 79 * Return: none 80 **************************************************************************************/ 81 void MP3FreeDecoder(HMP3Decoder hMP3Decoder) 82 { 83 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; 84 85 if (!mp3DecInfo) 86 return; 87 88 FreeBuffers(mp3DecInfo); 89 } 90 91 /************************************************************************************** 92 * Function: MP3FindSyncWord 93 * 94 * Description: locate the next byte-alinged sync word in the raw mp3 stream 95 * 96 * Inputs: buffer to search for sync word 97 * max number of bytes to search in buffer 98 * 99 * Outputs: none 100 * 101 * Return: offset to first sync word (bytes from start of buf) 102 * -1 if sync not found after searching nBytes 103 **************************************************************************************/ 104 int MP3FindSyncWord(unsigned char *buf, int nBytes) 105 { 106 int i; 107 108 /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */ 109 for (i = 0; i < nBytes - 1; i++) { 110 if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL ) 111 return i; 112 } 113 114 return -1; 115 } 116 117 /************************************************************************************** 118 * Function: MP3FindFreeSync 119 * 120 * Description: figure out number of bytes between adjacent sync words in "free" mode 121 * 122 * Inputs: buffer to search for next sync word 123 * the 4-byte frame header starting at the current sync word 124 * max number of bytes to search in buffer 125 * 126 * Outputs: none 127 * 128 * Return: offset to next sync word, minus any pad byte (i.e. nSlots) 129 * -1 if sync not found after searching nBytes 130 * 131 * Notes: this checks that the first 22 bits of the next frame header are the 132 * same as the current frame header, but it's still not foolproof 133 * (could accidentally find a sequence in the bitstream which 134 * appears to match but is not actually the next frame header) 135 * this could be made more error-resilient by checking several frames 136 * in a row and verifying that nSlots is the same in each case 137 * since free mode requires CBR (see spec) we generally only call 138 * this function once (first frame) then store the result (nSlots) 139 * and just use it from then on 140 **************************************************************************************/ 141 static int MP3FindFreeSync(unsigned char *buf, unsigned char firstFH[4], int nBytes) 142 { 143 int offset = 0; 144 unsigned char *bufPtr = buf; 145 146 /* loop until we either: 147 * - run out of nBytes (FindMP3SyncWord() returns -1) 148 * - find the next valid frame header (sync word, version, layer, CRC flag, bitrate, and sample rate 149 * in next header must match current header) 150 */ 151 while (1) { 152 offset = MP3FindSyncWord(bufPtr, nBytes); 153 bufPtr += offset; 154 if (offset < 0) { 155 return -1; 156 } else if ( (bufPtr[0] == firstFH[0]) && (bufPtr[1] == firstFH[1]) && ((bufPtr[2] & 0xfc) == (firstFH[2] & 0xfc)) ) { 157 /* want to return number of bytes per frame, NOT counting the padding byte, so subtract one if padFlag == 1 */ 158 if ((firstFH[2] >> 1) & 0x01) 159 bufPtr--; 160 return bufPtr - buf; 161 } 162 bufPtr += 3; 163 nBytes -= (offset + 3); 164 }; 165 166 return -1; 167 } 168 169 /************************************************************************************** 170 * Function: MP3GetLastFrameInfo 171 * 172 * Description: get info about last MP3 frame decoded (number of sampled decoded, 173 * sample rate, bitrate, etc.) 174 * 175 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) 176 * pointer to MP3FrameInfo struct 177 * 178 * Outputs: filled-in MP3FrameInfo struct 179 * 180 * Return: none 181 * 182 * Notes: call this right after calling MP3Decode 183 **************************************************************************************/ 184 void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo) 185 { 186 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; 187 188 if (!mp3DecInfo || mp3DecInfo->layer != 3) { 189 mp3FrameInfo->bitrate = 0; 190 mp3FrameInfo->nChans = 0; 191 mp3FrameInfo->samprate = 0; 192 mp3FrameInfo->bitsPerSample = 0; 193 mp3FrameInfo->outputSamps = 0; 194 mp3FrameInfo->layer = 0; 195 mp3FrameInfo->version = 0; 196 } else { 197 mp3FrameInfo->bitrate = mp3DecInfo->bitrate; 198 mp3FrameInfo->nChans = mp3DecInfo->nChans; 199 mp3FrameInfo->samprate = mp3DecInfo->samprate; 200 mp3FrameInfo->bitsPerSample = 16; 201 mp3FrameInfo->outputSamps = mp3DecInfo->nChans * (int)samplesPerFrameTab[mp3DecInfo->version][mp3DecInfo->layer - 1]; 202 mp3FrameInfo->layer = mp3DecInfo->layer; 203 mp3FrameInfo->version = mp3DecInfo->version; 204 } 205 } 206 207 /************************************************************************************** 208 * Function: MP3GetNextFrameInfo 209 * 210 * Description: parse MP3 frame header 211 * 212 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) 213 * pointer to MP3FrameInfo struct 214 * pointer to buffer containing valid MP3 frame header (located using 215 * MP3FindSyncWord(), above) 216 * 217 * Outputs: filled-in MP3FrameInfo struct 218 * 219 * Return: error code, defined in mp3dec.h (0 means no error, < 0 means error) 220 **************************************************************************************/ 221 int MP3GetNextFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo, unsigned char *buf) 222 { 223 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; 224 225 if (!mp3DecInfo) 226 return ERR_MP3_NULL_POINTER; 227 228 if (UnpackFrameHeader(mp3DecInfo, buf) == -1 || mp3DecInfo->layer != 3) 229 return ERR_MP3_INVALID_FRAMEHEADER; 230 231 MP3GetLastFrameInfo(mp3DecInfo, mp3FrameInfo); 232 233 return ERR_MP3_NONE; 234 } 235 236 /************************************************************************************** 237 * Function: MP3ClearBadFrame 238 * 239 * Description: zero out pcm buffer if error decoding MP3 frame 240 * 241 * Inputs: mp3DecInfo struct with correct frame size parameters filled in 242 * pointer pcm output buffer 243 * 244 * Outputs: zeroed out pcm buffer 245 * 246 * Return: none 247 **************************************************************************************/ 248 static void MP3ClearBadFrame(MP3DecInfo *mp3DecInfo, short *outbuf) 249 { 250 int i; 251 252 if (!mp3DecInfo) 253 return; 254 255 for (i = 0; i < mp3DecInfo->nGrans * mp3DecInfo->nGranSamps * mp3DecInfo->nChans; i++) 256 outbuf[i] = 0; 257 } 258 259 /************************************************************************************** 260 * Function: MP3Decode 261 * 262 * Description: decode one frame of MP3 data 263 * 264 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) 265 * double pointer to buffer of MP3 data (containing headers + mainData) 266 * number of valid bytes remaining in inbuf 267 * pointer to outbuf, big enough to hold one frame of decoded PCM samples 268 * flag indicating whether MP3 data is normal MPEG format (useSize = 0) 269 * or reformatted as "self-contained" frames (useSize = 1) 270 * 271 * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo 272 * number of output samples = nGrans * nGranSamps * nChans 273 * updated inbuf pointer, updated bytesLeft 274 * 275 * Return: error code, defined in mp3dec.h (0 means no error, < 0 means error) 276 * 277 * Notes: switching useSize on and off between frames in the same stream 278 * is not supported (bit reservoir is not maintained if useSize on) 279 **************************************************************************************/ 280 int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize) 281 { 282 int offset, bitOffset, mainBits, gr, ch, fhBytes, siBytes, freeFrameBytes; 283 int prevBitOffset, sfBlockBits, huffBlockBits; 284 unsigned char *mainPtr; 285 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; 286 // ULONG32 ulTime; 287 // StartYield(&ulTime); 288 if (!mp3DecInfo) 289 return ERR_MP3_NULL_POINTER; 290 291 /* unpack frame header */ 292 fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf); 293 if (fhBytes < 0) 294 return ERR_MP3_INVALID_FRAMEHEADER; /* don't clear outbuf since we don't know size (failed to parse header) */ 295 *inbuf += fhBytes; 296 297 /* unpack side info */ 298 siBytes = UnpackSideInfo(mp3DecInfo, *inbuf); 299 if (siBytes < 0) { 300 MP3ClearBadFrame(mp3DecInfo, outbuf); 301 return ERR_MP3_INVALID_SIDEINFO; 302 } 303 *inbuf += siBytes; 304 *bytesLeft -= (fhBytes + siBytes); 305 306 /* if free mode, need to calculate bitrate and nSlots manually, based on frame size */ 307 if (mp3DecInfo->bitrate == 0 || mp3DecInfo->freeBitrateFlag) { 308 if (!mp3DecInfo->freeBitrateFlag) { 309 /* first time through, need to scan for next sync word and figure out frame size */ 310 mp3DecInfo->freeBitrateFlag = 1; 311 mp3DecInfo->freeBitrateSlots = MP3FindFreeSync(*inbuf, *inbuf - fhBytes - siBytes, *bytesLeft); 312 if (mp3DecInfo->freeBitrateSlots < 0) { 313 MP3ClearBadFrame(mp3DecInfo, outbuf); 314 return ERR_MP3_FREE_BITRATE_SYNC; 315 } 316 freeFrameBytes = mp3DecInfo->freeBitrateSlots + fhBytes + siBytes; 317 mp3DecInfo->bitrate = (freeFrameBytes * mp3DecInfo->samprate * 8) / (mp3DecInfo->nGrans * mp3DecInfo->nGranSamps); 318 } 319 mp3DecInfo->nSlots = mp3DecInfo->freeBitrateSlots + CheckPadBit(mp3DecInfo); /* add pad byte, if required */ 320 } 321 322 /* useSize != 0 means we're getting reformatted (RTP) packets (see RFC 3119) 323 * - calling function assembles "self-contained" MP3 frames by shifting any main_data 324 * from the bit reservoir (in previous frames) to AFTER the sync word and side info 325 * - calling function should set mainDataBegin to 0, and tell us exactly how large this 326 * frame is (in bytesLeft) 327 */ 328 if (useSize) { 329 mp3DecInfo->nSlots = *bytesLeft; 330 if (mp3DecInfo->mainDataBegin != 0 || mp3DecInfo->nSlots <= 0) { 331 /* error - non self-contained frame, or missing frame (size <= 0), could do loss concealment here */ 332 MP3ClearBadFrame(mp3DecInfo, outbuf); 333 return ERR_MP3_INVALID_FRAMEHEADER; 334 } 335 336 /* can operate in-place on reformatted frames */ 337 mp3DecInfo->mainDataBytes = mp3DecInfo->nSlots; 338 mainPtr = *inbuf; 339 *inbuf += mp3DecInfo->nSlots; 340 *bytesLeft -= (mp3DecInfo->nSlots); 341 } else { 342 /* out of data - assume last or truncated frame */ 343 if (mp3DecInfo->nSlots > *bytesLeft) { 344 MP3ClearBadFrame(mp3DecInfo, outbuf); 345 return ERR_MP3_INDATA_UNDERFLOW; 346 } 347 /* fill main data buffer with enough new data for this frame */ 348 if (mp3DecInfo->mainDataBytes >= mp3DecInfo->mainDataBegin) { 349 /* adequate "old" main data available (i.e. bit reservoir) */ 350 memmove(mp3DecInfo->mainBuf, mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes - mp3DecInfo->mainDataBegin, mp3DecInfo->mainDataBegin); 351 memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBegin, *inbuf, mp3DecInfo->nSlots); 352 353 mp3DecInfo->mainDataBytes = mp3DecInfo->mainDataBegin + mp3DecInfo->nSlots; 354 *inbuf += mp3DecInfo->nSlots; 355 *bytesLeft -= (mp3DecInfo->nSlots); 356 mainPtr = mp3DecInfo->mainBuf; 357 } else { 358 /* not enough data in bit reservoir from previous frames (perhaps starting in middle of file) */ 359 memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes, *inbuf, mp3DecInfo->nSlots); 360 mp3DecInfo->mainDataBytes += mp3DecInfo->nSlots; 361 *inbuf += mp3DecInfo->nSlots; 362 *bytesLeft -= (mp3DecInfo->nSlots); 363 MP3ClearBadFrame(mp3DecInfo, outbuf); 364 return ERR_MP3_MAINDATA_UNDERFLOW; 365 } 366 } 367 bitOffset = 0; 368 mainBits = mp3DecInfo->mainDataBytes * 8; 369 370 /* decode one complete frame */ 371 for (gr = 0; gr < mp3DecInfo->nGrans; gr++) { 372 for (ch = 0; ch < mp3DecInfo->nChans; ch++) { 373 /* unpack scale factors and compute size of scale factor block */ 374 prevBitOffset = bitOffset; 375 offset = UnpackScaleFactors(mp3DecInfo, mainPtr, &bitOffset, mainBits, gr, ch); 376 377 sfBlockBits = 8*offset - prevBitOffset + bitOffset; 378 huffBlockBits = mp3DecInfo->part23Length[gr][ch] - sfBlockBits; 379 mainPtr += offset; 380 mainBits -= sfBlockBits; 381 382 if (offset < 0 || mainBits < huffBlockBits) { 383 MP3ClearBadFrame(mp3DecInfo, outbuf); 384 return ERR_MP3_INVALID_SCALEFACT; 385 } 386 387 /* decode Huffman code words */ 388 prevBitOffset = bitOffset; 389 offset = DecodeHuffman(mp3DecInfo, mainPtr, &bitOffset, huffBlockBits, gr, ch); 390 if (offset < 0) { 391 MP3ClearBadFrame(mp3DecInfo, outbuf); 392 return ERR_MP3_INVALID_HUFFCODES; 393 } 394 395 mainPtr += offset; 396 mainBits -= (8*offset - prevBitOffset + bitOffset); 397 } 398 // YieldIfRequired(&ulTime); 399 /* dequantize coefficients, decode stereo, reorder short blocks */ 400 if (Dequantize(mp3DecInfo, gr) < 0) { 401 MP3ClearBadFrame(mp3DecInfo, outbuf); 402 return ERR_MP3_INVALID_DEQUANTIZE; 403 } 404 405 /* alias reduction, inverse MDCT, overlap-add, frequency inversion */ 406 for (ch = 0; ch < mp3DecInfo->nChans; ch++) 407 if (IMDCT(mp3DecInfo, gr, ch) < 0) { 408 MP3ClearBadFrame(mp3DecInfo, outbuf); 409 return ERR_MP3_INVALID_IMDCT; 410 } 411 412 /* subband transform - if stereo, interleaves pcm LRLRLR */ 413 if (Subband(mp3DecInfo, outbuf + gr*mp3DecInfo->nGranSamps*mp3DecInfo->nChans) < 0) { 414 MP3ClearBadFrame(mp3DecInfo, outbuf); 415 return ERR_MP3_INVALID_SUBBAND; 416 } 417 } 418 return ERR_MP3_NONE; 419 }