videoeditorengine/mp3aacManipLib/MP3Gain/src/mpif.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**************************************************************************
       
    21   mpif.cpp - MPEG-1, MPEG-2 LSF and MPEG-2.5 file format implementations.
       
    22 
       
    23   Author(s): Juha Ojanpera
       
    24   Copyright (c) 1999-2004 by Nokia Research Center, Speech and Audio Systems.
       
    25   *************************************************************************/
       
    26 
       
    27 /*-- project headers --*/
       
    28 #include "mpif.h"
       
    29 //#include "auddef.h"
       
    30 #include "mpheader.h"
       
    31 #include "nok_bits.h"
       
    32 #include "mstream.h"
       
    33 
       
    34 
       
    35 /**************************************************************************
       
    36   Internal Objects
       
    37   *************************************************************************/
       
    38 
       
    39 /*
       
    40    Purpose:     Sync lost after 16384 bytes.
       
    41    Explanation: - */
       
    42 #define SYNC_THRESHOLD (16384 << 3)
       
    43 
       
    44 /**************************************************************************
       
    45   Title        : main_data_slots
       
    46 
       
    47   Purpose      : Computes the number of bytes for the layer III payload. The
       
    48                  payload consists of the scalefactors and quantized data of
       
    49                  the channel(s).
       
    50 
       
    51   Usage        : y = main_data_slots(mp)
       
    52 
       
    53   Input        : mp - mp3 file format parameters
       
    54 
       
    55   Output       : y  - # of payload bytes for this frame
       
    56 
       
    57   Author(s)    : Juha Ojanpera
       
    58   *************************************************************************/
       
    59 
       
    60 INLINE int32
       
    61 main_data_slots(TMpTransportHandle *tHandle)
       
    62 {
       
    63   int16 nSlots;
       
    64 
       
    65   if(bit_rate(&tHandle->header))
       
    66   {
       
    67     nSlots = tHandle->SlotTable[bit_rate_idx(&tHandle->header)];
       
    68 
       
    69     if(padding(&tHandle->header))
       
    70       nSlots++;
       
    71     if(error_protection(&tHandle->header))
       
    72       nSlots -= 2;
       
    73   }
       
    74   else
       
    75   {
       
    76     nSlots = tHandle->FreeFormatSlots;
       
    77 
       
    78     if(padding(&tHandle->header))
       
    79       nSlots++;
       
    80   }
       
    81 
       
    82   return(nSlots);
       
    83 }
       
    84 
       
    85 /*
       
    86  * Maximum # of bits needed for the header. Note that only
       
    87  * 20 bits are read since 12 bits were read already when 
       
    88  * locating the start of frame. 16 bits are needed for
       
    89  * the optional CRC codeword.
       
    90  */
       
    91 #define MAX_MP_HEADER_SIZE (20 + 16)
       
    92 
       
    93 /**************************************************************************
       
    94   Title        : decode_header
       
    95 
       
    96   Purpose      : Reads header information (excluding syncword) from the bitstream.
       
    97 
       
    98   Usage        : decode_header(tHandle, bs)
       
    99 
       
   100   Input        : tHandle - file format parser
       
   101                  bs      - input bitstream
       
   102 
       
   103   Explanation  : Header information is commmon to all layers. Note also that
       
   104                  this function doesn't interprete the fields of the header.
       
   105 
       
   106   Author(s)    : Juha Ojanpera
       
   107   *************************************************************************/
       
   108 
       
   109 INLINE SEEK_STATUS
       
   110 decode_header(TMpTransportHandle *tHandle, TBitStream *bs)
       
   111 {
       
   112   uint32 header, bitsLeft;
       
   113 
       
   114   bitsLeft = (BsGetBufSize(bs) << 3) - BsGetBitsRead(bs);
       
   115   if(bitsLeft < MAX_MP_HEADER_SIZE)
       
   116     return (SYNC_BITS_OUT);
       
   117 
       
   118   /*-- Read rest of the header bits. --*/
       
   119   tHandle->headerOld.header = tHandle->header.header;
       
   120   header = (!tHandle->mpeg25) << HEADER_BITS;
       
   121   header |= BsGetBits(bs, HEADER_BITS);
       
   122   tHandle->header.header = header;
       
   123 
       
   124   /*-- Read CRC codeword. --*/
       
   125   if(error_protection(&tHandle->header))
       
   126     tHandle->crc.crc = (int16) BsGetBits(bs, 16);
       
   127 
       
   128   return (SYNC_FOUND);
       
   129 }
       
   130 
       
   131 /**************************************************************************
       
   132   Title        : GetSideInfoSlots
       
   133 
       
   134   Purpose      : Retrieves the amount of side info for layer III stream.
       
   135 
       
   136   Usage        : y = GetSideInfoSlots(tHandle)
       
   137 
       
   138   Input        : tHandle - file format parser
       
   139 
       
   140   Output       : y       - # of side info bytes
       
   141 
       
   142   Author(s)    : Juha Ojanpera
       
   143   *************************************************************************/
       
   144 
       
   145 int16
       
   146 GetSideInfoSlots(TMpTransportHandle *tHandle)
       
   147 {
       
   148   int16 nSlots = 0;
       
   149 
       
   150   if(version(&tHandle->header) != MPEG_PHASE2_LSF)
       
   151     nSlots = (channels(&tHandle->header) == 1) ? (int16) 17 : (int16) 32;
       
   152   else
       
   153     nSlots = (channels(&tHandle->header) == 1) ? (int16) 9 : (int16) 17;
       
   154 
       
   155   return (nSlots);
       
   156 }
       
   157 
       
   158 int16
       
   159 GetSideInfoSlots(TMPEG_Header *header)
       
   160 {
       
   161   int16 nSlots = 0;
       
   162 
       
   163   if(version(header) != MPEG_PHASE2_LSF)
       
   164     nSlots = (channels(header) == 1) ? 17 : 32;
       
   165   else
       
   166     nSlots = (channels(header) == 1) ? 9 : 17;
       
   167 
       
   168   return (nSlots);
       
   169 }
       
   170 
       
   171 /**************************************************************************
       
   172   Title        : GetSlotSize
       
   173 
       
   174   Purpose      : Retrieves the amount of frame data for layer III stream.
       
   175 
       
   176   Usage        : y = GetSlotSize(tHandle)
       
   177 
       
   178   Input        : tHandle - file format parser
       
   179 
       
   180   Output       : y       - # of frame data bytes
       
   181 
       
   182   Author(s)    : Juha Ojanpera
       
   183   *************************************************************************/
       
   184 
       
   185 static INLINE int16
       
   186 GetSlotSize(TMpTransportHandle *tHandle)
       
   187 {
       
   188   int16 ave_slots;
       
   189   
       
   190   if(bit_rate(&tHandle->header))
       
   191     ave_slots = (int16) tHandle->aveFrameLen;
       
   192   else
       
   193   {
       
   194     ave_slots = (int16) (tHandle->FreeFormatSlots + GetSideInfoSlots(tHandle));
       
   195     if(error_protection(&tHandle->header))
       
   196       ave_slots += 2;
       
   197     ave_slots += 4;
       
   198   }
       
   199 
       
   200   return (ave_slots);
       
   201 }
       
   202 
       
   203 INLINE int32 *
       
   204 GetSeekOffset(TMpTransportHandle *tHandle, int32 *seekValues)
       
   205 {
       
   206   int16 main_data;
       
   207   int32 frameOffset, byte_offset;
       
   208   
       
   209   /*
       
   210    * Some reinitialization need to be performed after file pointer has been
       
   211    * moved to the new postion. For this reason, the total number of frames
       
   212    * to be skipped does not correspond exactly to the given time offset.
       
   213    * However, after reinitialization the playback position should be the correct.
       
   214    */
       
   215   byte_offset = GetSlotSize(tHandle);
       
   216   main_data = (int16) ((version(&tHandle->header) == MPEG_PHASE2_LSF) ? 256 : 512);
       
   217   frameOffset = (byte_offset) ? main_data / byte_offset : 0;
       
   218 
       
   219   if(byte_offset)
       
   220     if(main_data % byte_offset)
       
   221       frameOffset++;
       
   222 
       
   223   seekValues[0] = frameOffset;
       
   224   seekValues[1] = byte_offset;
       
   225 
       
   226   return (seekValues);
       
   227 }
       
   228 
       
   229 /*
       
   230  * Estimates the bitrate of the mp3 stream from the size of the 
       
   231  * payload + side info + header. The accuracy of the computed 
       
   232  * bitrate depends very much on the accuracy of the average frame 
       
   233  * size.
       
   234  */
       
   235 int16
       
   236 MP_EstimateBitrate(TMpTransportHandle *tHandle, uint8 isVbr)
       
   237 {
       
   238   int16 bitRate;
       
   239 
       
   240   if(!bit_rate(&tHandle->header) || isVbr)
       
   241   {
       
   242     FLOAT div;
       
   243 
       
   244     div = (FLOAT) ((version(&tHandle->header) == MPEG_PHASE2_LSF) ? 72 : 144);
       
   245     bitRate = (int16) (((frequency(&tHandle->header) / 1000.0f) * GetSlotSize(tHandle) / div) + 0.5f);
       
   246   }
       
   247   else
       
   248     bitRate = bit_rate(&tHandle->header);
       
   249 
       
   250   return (bitRate);
       
   251 }
       
   252 
       
   253 /*
       
   254  * Returns the length of the track in milliseconds.
       
   255  */
       
   256 uint32
       
   257 MP_FileLengthInMs(TMpTransportHandle *tHandle, int32 fileSize)
       
   258 {
       
   259   FLOAT frames = fileSize / (FLOAT) GetSlotSize(tHandle);
       
   260 
       
   261   return (uint32) (frames * GetFrameTime(&tHandle->header) + 0.5f);
       
   262 }
       
   263 
       
   264 /*
       
   265  * Returns the byte offset corresponding to the specified seeking position.
       
   266  */
       
   267 int32
       
   268 MP_GetSeekOffset(TMpTransportHandle *tHandle, int32 seekPos)
       
   269 {
       
   270   FLOAT numFrames;
       
   271   int32 seekValues[2], frameOffset, byte_offset;
       
   272 
       
   273   GetSeekOffset(tHandle, seekValues);
       
   274 
       
   275   frameOffset = seekValues[0];
       
   276   byte_offset = seekValues[1];
       
   277   
       
   278   numFrames = seekPos / (FLOAT) GetFrameTime(&tHandle->header);
       
   279   if(numFrames < frameOffset)
       
   280     frameOffset = 0;
       
   281 
       
   282   /*-- Total offset. --*/
       
   283   byte_offset = (int32) ((byte_offset * (numFrames - frameOffset)) + 0.5f);
       
   284 
       
   285   return (byte_offset);
       
   286 }
       
   287 
       
   288 /*
       
   289  * Returns the duration of each frame in milliseconds.
       
   290  */
       
   291 int32
       
   292 MP_GetFrameTime(TMpTransportHandle *tHandle)
       
   293 {
       
   294   return (GetFrameTime(&tHandle->header));
       
   295 }
       
   296 
       
   297 /*
       
   298  * Checks if the specified mp3 stream is using free format 
       
   299  * i.e., bitrate is not specified in the header part
       
   300  * of the frame.
       
   301  *
       
   302  * Return TRUE if bitrate not specified, FALSE otherwise
       
   303  */
       
   304 BOOL
       
   305 IsMP3FreeFormat(TMpTransportHandle *tHandle)
       
   306 {  
       
   307   return (bit_rate(&tHandle->header) == 0);
       
   308 }
       
   309 
       
   310 /**************************************************************************
       
   311   Title        : FillDataSlotTable
       
   312 
       
   313   Purpose      : Pre-computes (to avoid division operation during decoding) 
       
   314                  the payload size of layer III for all bitrates. This function
       
   315                  should be called once the start of 1st frame has been located.
       
   316 
       
   317   Usage        : y = FillDataSlotTable(tHandle)
       
   318 
       
   319   Input        : tHandle - file format parser
       
   320 
       
   321   Author(s)    : Juha Ojanpera
       
   322   *************************************************************************/
       
   323 
       
   324 INLINE void
       
   325 FillDataSlotTable(TMpTransportHandle *tHandle)
       
   326 {
       
   327   int16 nSlots;
       
   328   const int16 *brTbl;
       
   329   
       
   330   brTbl = GetBitRateTable(&tHandle->header);
       
   331 
       
   332   /*
       
   333    * index 0 is free format and index 14 illegal bitrate.
       
   334    */
       
   335   for(int16 i = 1; i < 15; i++)
       
   336   {
       
   337     nSlots = (int16)((144 * brTbl[i]) / (frequency(&tHandle->header) / 1000.0f));
       
   338 
       
   339     if(version(&tHandle->header) == MPEG_PHASE2_LSF)
       
   340       nSlots >>= 1;
       
   341 
       
   342     nSlots = (int16) (nSlots - GetSideInfoSlots(tHandle) - 4);
       
   343     tHandle->SlotTable[i] = nSlots;
       
   344   }
       
   345 }
       
   346 
       
   347 /**************************************************************************
       
   348   Title        : SeekSync
       
   349 
       
   350   Purpose      : Seeks for a byte aligned sync word in the bitstream and
       
   351                  places the bitstream pointer right after the sync word.
       
   352 
       
   353   Usage        : y = SeekSync(mp, bs_mcu, bufMapper, execState)
       
   354 
       
   355   Input        : mp             - mp3 stream parameters
       
   356                  bs_mcu         - bitstream parameters
       
   357                  execState      - exec status of this function
       
   358 
       
   359   Output       : y :
       
   360                   SYNC_BITS_OUT - bit buffer need to be updated
       
   361                   SYNC_LOST     - start of next frame was not found
       
   362                   SYNC_FOUND    - OK to decode next frame
       
   363 
       
   364   Author(s)    : Juha Ojanpera
       
   365   *************************************************************************/
       
   366 
       
   367 INLINE SEEK_STATUS
       
   368 SeekSync(TMpTransportHandle *tHandle, TBitStream *bs_mcu, ExecState *execState)
       
   369 {
       
   370 #define PRESYNCBITS  (MP_SYNC_WORD_LENGTH + 8)
       
   371 #define POSTSYNCBITS (MAX_MP_HEADER_SIZE + 1)
       
   372 
       
   373   uint32 hdr, bits_left;
       
   374   BOOL exitCheck = TRUE;
       
   375   int32 sync_cand, bits_read;
       
   376 
       
   377   bits_left = (BsSlotsLeft(bs_mcu) - 1) << 3;
       
   378   
       
   379   if(execState->execMode == GLITCH_FREE && bits_left > PRESYNCBITS)
       
   380   {
       
   381     bits_left -= (BsByteAlign(bs_mcu) + (bits_read = tHandle->syncInfo.sync_length));
       
   382     sync_cand = BsGetBits(bs_mcu, tHandle->syncInfo.sync_length);
       
   383   }
       
   384   else if(execState->execMode == GLITCH_FREE)
       
   385   {
       
   386     execState->execMode = GLITCH_FREE;
       
   387 
       
   388     return (SYNC_BITS_OUT);
       
   389   }
       
   390   else
       
   391   {
       
   392     sync_cand = (int32)execState->a0_u32[0];
       
   393     bits_read = (int32)execState->a0_u32[1];
       
   394   }
       
   395   
       
   396   while(exitCheck)
       
   397   {
       
   398     while(sync_cand != tHandle->syncInfo.sync_word && 
       
   399       bits_read < SYNC_THRESHOLD && bits_left)
       
   400     {
       
   401       bits_read++;
       
   402       bits_left--;
       
   403       sync_cand = (sync_cand << 1) & tHandle->syncInfo.sync_mask;
       
   404       sync_cand |= (int16) BsGetBits(bs_mcu, 1);
       
   405     }
       
   406     
       
   407     if(bits_read > SYNC_THRESHOLD)
       
   408       return (SYNC_LOST);
       
   409     else if(bits_left < POSTSYNCBITS)
       
   410     {
       
   411       execState->execMode = GLITCH0;
       
   412       execState->a0_u32[0] = sync_cand;
       
   413       execState->a0_u32[1] = bits_read;
       
   414 
       
   415       return (SYNC_BITS_OUT);
       
   416     }
       
   417     else
       
   418     {
       
   419       bits_read++;
       
   420       bits_left--;
       
   421       sync_cand = (sync_cand << 1) & tHandle->syncInfo.sync_mask;
       
   422       sync_cand |= (int16) BsGetBits(bs_mcu, 1);
       
   423       
       
   424       tHandle->mpeg25 = !(sync_cand & 0x1);
       
   425       
       
   426       /* Check the next frame header. */
       
   427       hdr = (!tHandle->mpeg25) << HEADER_BITS;
       
   428       tHandle->header.header = hdr | BsLookAhead(bs_mcu, HEADER_BITS);
       
   429       
       
   430       /* Detect false frame boundaries. */
       
   431       switch(tHandle->syncInfo.sync_status)
       
   432       {
       
   433         case LAYER3_STREAM:
       
   434           if(HEADER_MASK(tHandle->header.header) == HEADER_MASK(tHandle->headerOld.header) &&
       
   435             sfreq(&tHandle->header) != 3 && LAYER_MASK(tHandle->header.header) == 0x1)
       
   436           {
       
   437             if(tHandle->FreeFormatSlots == 0)
       
   438             {
       
   439               if(bit_rate(&tHandle->header))
       
   440                 exitCheck = FALSE;
       
   441             }
       
   442             else exitCheck = FALSE;
       
   443           }
       
   444           break;
       
   445       
       
   446         case INIT_LAYER3_STREAM:
       
   447           if(!(version(&tHandle->header) && mp25version(&tHandle->header)))
       
   448           {
       
   449             if(sfreq(&tHandle->header) != 3 && LAYER_MASK(tHandle->header.header) == 0x1 && bit_rate_idx(&tHandle->header) != 15)
       
   450             {
       
   451               tHandle->headerOld.header = tHandle->header.header;
       
   452               tHandle->syncInfo.sync_status = LAYER3_STREAM;
       
   453               exitCheck = FALSE;
       
   454             }
       
   455           }
       
   456           break;
       
   457 
       
   458         default:
       
   459           break;
       
   460       }
       
   461     }
       
   462   }  
       
   463 
       
   464   execState->execMode = GLITCH_FREE;
       
   465 
       
   466   return (SYNC_FOUND);
       
   467 }
       
   468 
       
   469 /**************************************************************************
       
   470   Title        : FindFreeFormatSlotCount
       
   471 
       
   472   Purpose      : Determines the size of the payload of a free format stream.
       
   473 
       
   474   Usage        : y = FindFreeFormatSlotCount(mpDec, bs_mcu, execState)
       
   475 
       
   476   Input        : mpDec     - mp3 stream parameters
       
   477                  bs_mcu    - bitstream parameters
       
   478                  execState - exec status of this function
       
   479 
       
   480   Output       : y :
       
   481                   SYNC_BITS_OUT - bit buffer need to be updated
       
   482                   SYNC_LOST     - stream is undecodable
       
   483                   SYNC_FOUND    - OK to start playback
       
   484 
       
   485   Author(s)    : Juha Ojanpera
       
   486   *************************************************************************/
       
   487 
       
   488 INLINE SEEK_STATUS
       
   489 FreeFormat(TMpTransportHandle *tHandle, TBitStream *bs_mcu, ExecState *execState)
       
   490 {
       
   491   int16 exitCheck;
       
   492   TMPEG_Header oldHeader;
       
   493   uint16 sync_cand;
       
   494   uint32 bits_read, bits_left;
       
   495 
       
   496   tHandle->FreeFormatSlots = 0;
       
   497   
       
   498   if(execState->execMode == GLITCH_FREE)
       
   499   {
       
   500     int16 nSlots, minBytes;
       
   501 
       
   502     nSlots = GetSideInfoSlots(tHandle);
       
   503     minBytes = (uint16) (nSlots + 7);
       
   504     if((BsSlotsLeft(bs_mcu) - 1) < (uint16) minBytes)
       
   505     {
       
   506       execState->execMode = GLITCH_FREE;
       
   507       return (SYNC_BITS_OUT);
       
   508     }
       
   509 
       
   510     /*-- Read 1st header. --*/
       
   511     decode_header(tHandle, bs_mcu);
       
   512     oldHeader.header = tHandle->header.header;
       
   513 
       
   514     /*-- Skip side info part. --*/
       
   515     BsSkipNBits(bs_mcu, nSlots << 3);
       
   516 
       
   517     sync_cand = (uint16) BsGetBits(bs_mcu, tHandle->syncInfo.sync_length);
       
   518     bits_read = tHandle->syncInfo.sync_length;
       
   519   }
       
   520   else
       
   521   {
       
   522     sync_cand = (uint16) execState->a0_u32[0];
       
   523     bits_read = (uint32) execState->a0_u32[1];
       
   524     oldHeader.header = (uint32)execState->a0_u32[2];
       
   525   }
       
   526 
       
   527   exitCheck = 1;
       
   528   bits_left = (BsSlotsLeft(bs_mcu) - 1) << 3;
       
   529   //mask = (uint16) ((1 << (tHandle->syncInfo.sync_length - 1)) - 1);
       
   530     
       
   531   while(exitCheck)
       
   532   {
       
   533     while(sync_cand != tHandle->syncInfo.sync_word && bits_left)
       
   534     {
       
   535       bits_read++;
       
   536       bits_left--;
       
   537       sync_cand = (uint16) ((sync_cand << 1) & tHandle->syncInfo.sync_mask);
       
   538       sync_cand |= (uint16) BsGetBits(bs_mcu, 1);
       
   539     }
       
   540 
       
   541     if(bits_left < (HEADER_BITS + 1))
       
   542     {
       
   543       execState->a0_u32[0] = sync_cand;
       
   544       execState->a0_u32[1] = bits_read;
       
   545       execState->a0_u32[2] = oldHeader.header;
       
   546       execState->execMode = GLITCH0;
       
   547 
       
   548       return (SYNC_BITS_OUT);
       
   549     }
       
   550     else
       
   551     {
       
   552       uint32 hdr;
       
   553 
       
   554       bits_read++;
       
   555       bits_left--;
       
   556       sync_cand = (sync_cand << 1) & tHandle->syncInfo.sync_mask;
       
   557       sync_cand |= (int16) BsGetBits(bs_mcu, 1);
       
   558       
       
   559       tHandle->mpeg25 = !(sync_cand & 0x1);
       
   560       
       
   561       /* Check the next frame header. */
       
   562       hdr = (!tHandle->mpeg25) << HEADER_BITS;
       
   563       tHandle->header.header = hdr | BsLookAhead(bs_mcu, HEADER_BITS);
       
   564       
       
   565       /* 
       
   566        * Detect false frame boundraries. We could use header macros here
       
   567        * to speed up the comparison but since this function is called only
       
   568        * once (before playback/editing starts) the advantages of macros are
       
   569        * negligible.
       
   570        */
       
   571       if(channels(&tHandle->header)         == channels(&oldHeader) &&
       
   572          sfreq(&tHandle->header)            == sfreq(&oldHeader) &&
       
   573          bit_rate(&tHandle->header)         == bit_rate(&oldHeader) &&
       
   574          layer_number(&tHandle->header)     == layer_number(&oldHeader) &&
       
   575          version(&tHandle->header)          == version(&oldHeader) &&
       
   576          mode(&tHandle->header)             == mode(&oldHeader) &&
       
   577          error_protection(&tHandle->header) == error_protection(&oldHeader))
       
   578          exitCheck = 0;
       
   579 
       
   580       /* The payload size cannot be determined. */
       
   581       else if(bits_read > SYNC_THRESHOLD)     
       
   582         return (SYNC_LOST);
       
   583     }
       
   584   }
       
   585     
       
   586   /*-- Determine the size of the payload data. --*/
       
   587   if(bits_read != 0)
       
   588   {
       
   589     bits_read -= (tHandle->syncInfo.sync_length + 1);
       
   590     tHandle->FreeFormatSlots = (int16) (bits_read >> 3);
       
   591 
       
   592     if(padding(&oldHeader))
       
   593       tHandle->FreeFormatSlots -= 1;
       
   594   }
       
   595   else
       
   596   {
       
   597     tHandle->FreeFormatSlots = -1;
       
   598 
       
   599     return (SYNC_LOST);
       
   600   }
       
   601   
       
   602   execState->execMode = GLITCH_FREE;
       
   603   tHandle->transportType = GET_MPSYNC_STREAM;
       
   604   tHandle->syncInfo.sync_status = INIT_LAYER3_STREAM;
       
   605 
       
   606   return (SYNC_FOUND);
       
   607 }
       
   608 
       
   609 /**************************************************************************
       
   610   Title        : mpSyncTransport
       
   611 
       
   612   Purpose      : Sync layer interface for MPEG Layer I/II/III file formats.
       
   613 
       
   614   Usage        : y = mpSyncTransport(tHandle, syncBuf, syncBufLen, readBits)
       
   615 
       
   616   Input        : tHandle        - handle to MPEG Layer I/II/III parser
       
   617                  syncBuf        - handle to sync layer buffer
       
   618                  syncBufLen     - # of bytes present in sync layer buffer
       
   619   
       
   620   Output       : y              - status of operation
       
   621                   SYNC_BITS_OUT - the sync layer buffer needs to be updated
       
   622                   SYNC_LOST     - function failed
       
   623                   SYNC_FOUND    - sync layer processing successfull
       
   624                  readBits       - # of bits read from sync layer buffer
       
   625 
       
   626   Author(s)    : Juha Ojanpera
       
   627   *************************************************************************/
       
   628 
       
   629 
       
   630 SEEK_STATUS
       
   631 mpSyncTransport(TMpTransportHandle *tHandle, uint8 *syncBuf, 
       
   632                 uint32 syncBufLen, uint32 *readBits)
       
   633 {
       
   634   BOOL hitExit;
       
   635   ExecState *execState;
       
   636   TBitStream m_Bitstream;
       
   637   SEEK_STATUS frameStatus;
       
   638 
       
   639   *readBits = 0;
       
   640   hitExit = FALSE;
       
   641   frameStatus = SYNC_LOST;
       
   642   execState = &tHandle->execState;
       
   643 
       
   644   BsInit(&m_Bitstream, syncBuf, syncBufLen);
       
   645 
       
   646   if(tHandle->offsetBits)
       
   647     BsSkipNBits(&m_Bitstream, tHandle->offsetBits);
       
   648   tHandle->offsetBits = 0;
       
   649 
       
   650   while(hitExit == FALSE)
       
   651   {
       
   652     uint32 tmp;
       
   653     uint8 syncByte(0);
       
   654 
       
   655     switch(tHandle->transportType)
       
   656     {
       
   657       case INIT_MP_STREAM:
       
   658         frameStatus = SYNC_LOST;
       
   659         tHandle->transportType = GET_1ST_MPSYNC_STREAM;
       
   660         break;
       
   661 
       
   662       case GET_1ST_MPSYNC_STREAM:
       
   663         /*
       
   664          * Locate sync and on succes, switch to read
       
   665          * the headers values.
       
   666          */
       
   667         frameStatus = SeekSync(tHandle, &m_Bitstream, execState);
       
   668         if((frameStatus == SYNC_FOUND) && IsMP3FreeFormat(tHandle))
       
   669         {
       
   670           hitExit = TRUE;
       
   671           frameStatus = SYNC_MP3_FREE;
       
   672           tHandle->offsetBits = (int16) (BsGetBitsRead(&m_Bitstream) & 0x7);
       
   673         }
       
   674         else if(frameStatus == SYNC_FOUND)
       
   675           tHandle->transportType = GET_MPHEADER_STREAM;
       
   676         else
       
   677         {
       
   678           hitExit = TRUE;
       
   679           if(frameStatus != SYNC_LOST)
       
   680           {
       
   681             /*
       
   682              * The sync search locates the syncword which is at the
       
   683              * start of the header (1st 12 bits). Also in order to 
       
   684              * make the search reliable, the rest of the header bits
       
   685              * are also checked via lookahead by the sync routine.
       
   686              * Because of this it is possible that the input buffer
       
   687              * may run out of bits in the lookahead part. In that case
       
   688              * the input buffer needs to be updated. The number of bytes
       
   689              * to be updated are calculated based on the number of read 
       
   690              * bits. Thus, in the worst case, the update process will 
       
   691              * throw away the 1st 8 bits from the syncword. This is 
       
   692              * something we don't want to experience since subsequent 
       
   693              * processing relies on the fact that the whole header can 
       
   694              * be read from the input buffer once the start of the frame 
       
   695              * has been found. That's why we reduce the update size of the 
       
   696              * input buffer (shown below).
       
   697              */
       
   698             tmp = BsGetBitsRead(&m_Bitstream);
       
   699             syncByte = syncBuf[MAX(0, ((int32) (tmp >> 3) - 1))];
       
   700             if((tmp & 0x7) && syncByte == 0xFF)
       
   701             {
       
   702               /*-- Keep the previous byte in the buffer as it may be part of header. --*/  
       
   703               tHandle->offsetBits = (int16) (8 + (tmp & 0x7));
       
   704 
       
   705               tmp -= 8;
       
   706               BsClearBitsRead(&m_Bitstream);
       
   707               BsSetBitsRead(&m_Bitstream, tmp);
       
   708             }
       
   709             else tHandle->offsetBits = (int16) (tmp & 0x7);
       
   710           }
       
   711         }
       
   712         break;
       
   713     
       
   714       case GET_MPSYNC_STREAM:
       
   715         /*
       
   716          * Locate sync and on succes, switch to read
       
   717          * the headers values.
       
   718          */
       
   719         frameStatus = SeekSync(tHandle, &m_Bitstream, execState);
       
   720         if(frameStatus == SYNC_FOUND)
       
   721           tHandle->transportType = GET_MPHEADER_STREAM;
       
   722         else
       
   723         {
       
   724           hitExit = TRUE;
       
   725           if(frameStatus != SYNC_LOST)
       
   726           {
       
   727             /*-- See explanation above. --*/
       
   728             tmp = BsGetBitsRead(&m_Bitstream);
       
   729             syncByte = syncBuf[MAX(0, ((int32) (tmp >> 3) - 1))];
       
   730             if((tmp & 0x7) && syncByte == 0xFF)
       
   731             {
       
   732               /*-- Keep the previous byte in the buffer as it may be part of header. --*/
       
   733               tHandle->offsetBits = (int16) (8 + (tmp & 0x7));
       
   734 
       
   735               tmp -= 8;
       
   736               BsClearBitsRead(&m_Bitstream);
       
   737               BsSetBitsRead(&m_Bitstream, tmp);
       
   738             }
       
   739             else tHandle->offsetBits = (int16) (tmp & 0x7);
       
   740           }
       
   741         }
       
   742         break;
       
   743     
       
   744       case GET_MPHEADER_STREAM:
       
   745         /*
       
   746          * Read headers values and on success, switch the state back
       
   747          * to sync search for next frame.
       
   748          */
       
   749         hitExit = TRUE;
       
   750         frameStatus = decode_header(tHandle, &m_Bitstream);
       
   751         if(frameStatus == SYNC_FOUND)
       
   752           tHandle->transportType = GET_MPSYNC_STREAM;
       
   753         else if(frameStatus != SYNC_LOST)
       
   754         {
       
   755           /*-- Don't loose the syncword... --*/
       
   756           tmp = BsGetBitsRead(&m_Bitstream);
       
   757           syncByte = syncBuf[MAX(0, ((int32) (tmp >> 3) - 1))];
       
   758           if((tmp & 0x7) && syncByte == 0xFF)
       
   759           {
       
   760             /*-- Keep the previous byte in the buffer as it may be part of header. --*/
       
   761             tHandle->offsetBits = (int16) (8 + (tmp & 0x7));
       
   762 
       
   763             tmp -= 8;
       
   764             BsClearBitsRead(&m_Bitstream);
       
   765             BsSetBitsRead(&m_Bitstream, tmp);
       
   766           }
       
   767           else tHandle->offsetBits = (int16) (tmp & 0x7);
       
   768         }
       
   769         break;
       
   770     
       
   771       default:
       
   772         hitExit = TRUE;
       
   773         frameStatus = SYNC_LOST;
       
   774         break;
       
   775     }
       
   776   }
       
   777 
       
   778   *readBits = BsGetBitsRead(&m_Bitstream);
       
   779   
       
   780   return (frameStatus);
       
   781 }
       
   782 
       
   783 /*
       
   784  * Returns the # of bytes reserved for the Layer I/II/III payload part of current frame.
       
   785  */
       
   786 INLINE int16
       
   787 mpGetTranportFrameLength(TMpTransportHandle *tHandle)
       
   788 {
       
   789   int16 frameBytes;
       
   790 
       
   791   tHandle->mainDataSlots = 0;
       
   792 
       
   793   switch(tHandle->transportType)
       
   794   {
       
   795     case GET_MPSYNC_STREAM:
       
   796     case GET_MPHEADER_STREAM:
       
   797       tHandle->mainDataSlots = (int16) main_data_slots(tHandle);
       
   798       frameBytes = (int16) (tHandle->mainDataSlots + GetSideInfoSlots(tHandle));
       
   799       break;
       
   800       
       
   801     default:
       
   802       frameBytes = 0;
       
   803       break;
       
   804   }
       
   805   
       
   806   return (frameBytes);
       
   807 }
       
   808 
       
   809 /*
       
   810  * Initializes MPEG Layer I/II/III transport handle.
       
   811  */
       
   812 void
       
   813 mpInitTransport(TMpTransportHandle *tHandle)
       
   814 {
       
   815   ZERO_MEMORY(tHandle, sizeof(TMpTransportHandle));
       
   816 
       
   817   tHandle->syncInfo.sync_word = (int16) SYNC_WORD;
       
   818   tHandle->syncInfo.sync_length = (int16) MP_SYNC_WORD_LENGTH;
       
   819   tHandle->syncInfo.sync_mask = (uint16) ((1 << tHandle->syncInfo.sync_length) - 1);
       
   820   tHandle->syncInfo.sync_status = INIT_LAYER3_STREAM;
       
   821   tHandle->transportType = INIT_MP_STREAM;
       
   822   tHandle->execState.execMode = GLITCH_FREE;
       
   823   tHandle->offsetBits = 0;
       
   824 }
       
   825 
       
   826 /**************************************************************************
       
   827   Title        : MP_SeekSync
       
   828 
       
   829   Purpose      : Interface to layer I/II/III frame search implementation.
       
   830 
       
   831   Usage        : y = MP_SeekSync(tHandle, syncBuf, syncBufLen, readBytes, 
       
   832                                  frameBytes, headerBytes, initMode)
       
   833 
       
   834   Input        : tHandle     - layer I/II/III transport handle
       
   835                  syncBuf     - input buffer
       
   836                  syncBufLen  - length of 'sync_buf'
       
   837                  initMode    - '1' when searching the 1st frame, '0' otherwise
       
   838 
       
   839   Output       : y           - status of operation
       
   840                  frameBytes  - # of bytes reserved for the payload part of the frame
       
   841                  readBytes   - # of bytes read from the buffer
       
   842                  headerBytes - # of bytes reserved for the header part of the frame
       
   843 
       
   844   Author(s)    : Juha Ojanpera
       
   845   *************************************************************************/
       
   846 
       
   847 int16
       
   848 MP_SeekSync(TMpTransportHandle *tHandle, uint8 *syncBuf, uint32 syncBufLen, 
       
   849             int16 *readBytes, int16 *frameBytes, int16 *headerBytes,
       
   850             uint8 initMode)
       
   851 {
       
   852   uint32 readBits;
       
   853   SEEK_STATUS syncSeekStatus;
       
   854  
       
   855   syncSeekStatus = mpSyncTransport(tHandle, syncBuf, syncBufLen, &readBits);
       
   856   if(initMode && syncSeekStatus == SYNC_FOUND)
       
   857     FillDataSlotTable(tHandle);
       
   858 
       
   859   *readBytes = (int16) (readBits >> 3);
       
   860   *frameBytes = (int16) mpGetTranportFrameLength(tHandle);
       
   861   *headerBytes = (int16) ((error_protection(&tHandle->header) ? 2 : 0) + 4);
       
   862 
       
   863   return (int16) (syncSeekStatus);
       
   864 }
       
   865 
       
   866 /**************************************************************************
       
   867   Title        : MP_FreeMode
       
   868 
       
   869   Purpose      : Interface for determining the frame/payload size of free format
       
   870                  layer III bitstream.
       
   871 
       
   872   Usage        : y = MP_FreeMode(tHandle, syncBuf, syncBufLen, readBytes, 
       
   873                                  frameBytes, headerBytes)
       
   874 
       
   875   Input        : tHandle     - layer I/II/III transport handle
       
   876                  syncBuf     - input buffer
       
   877                  syncBufLen  - length of 'sync_buf'
       
   878 
       
   879   Output       : y           - status of operation
       
   880                  frameBytes  - # of bytes reserved for the payload part of the frames
       
   881                  readBytes   - # of bytes read from the buffer
       
   882                  headerBytes - # of bytes reserved for the header part of the frame
       
   883 
       
   884   Author(s)    : Juha Ojanpera
       
   885   *************************************************************************/
       
   886 
       
   887 int16
       
   888 MP_FreeMode(TMpTransportHandle *tHandle, uint8 *syncBuf, uint32 syncBufLen, 
       
   889             int16 *readBytes, int16 *frameBytes, int16 *headerBytes)
       
   890 {
       
   891   TBitStream m_Bitstream;
       
   892   SEEK_STATUS syncSeekStatus;
       
   893 
       
   894   BsInit(&m_Bitstream, syncBuf, syncBufLen);
       
   895 
       
   896   if(tHandle->offsetBits)
       
   897     BsSkipNBits(&m_Bitstream, tHandle->offsetBits);
       
   898   tHandle->offsetBits = 0;
       
   899  
       
   900   syncSeekStatus = FreeFormat(tHandle, &m_Bitstream, &tHandle->execState);
       
   901   if(syncSeekStatus == SYNC_BITS_OUT)
       
   902     tHandle->offsetBits = (int16) (BsGetBitsRead(&m_Bitstream) & 0x7);
       
   903 
       
   904   *readBytes = (int16) (BsGetBitsRead(&m_Bitstream) >> 3);
       
   905   *frameBytes = (int16) mpGetTranportFrameLength(tHandle);
       
   906   *headerBytes = (int16) ((error_protection(&tHandle->header) ? 2 : 0) + 4);
       
   907 
       
   908   return (int16) (syncSeekStatus);
       
   909 }