Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /*
     19 ------------------------------------------------------------------------------
     20 
     21    PacketVideo Corp.
     22    MP3 Decoder Library
     23 
     24    Filename: pvmp3_seek_synch.cpp
     25 
     26    Functions:
     27         pvmp3_seek_synch
     28         pvmp3_header_sync
     29 
     30 
     31      Date: 9/21/2007
     32 
     33 ------------------------------------------------------------------------------
     34  REVISION HISTORY
     35 
     36 
     37  Description:
     38 
     39 ------------------------------------------------------------------------------
     40  INPUT AND OUTPUT DEFINITIONS
     41 
     42 pvmp3_frame_synch
     43 
     44 Input
     45     pExt = pointer to the external interface structure. See the file
     46            pvmp3decoder_api.h for a description of each field.
     47            Data type of pointer to a tPVMP3DecoderExternal
     48            structure.
     49 
     50     pMem = void pointer to hide the internal implementation of the library
     51            It is cast back to a tmp3dec_file structure. This structure
     52            contains information that needs to persist between calls to
     53            this function, or is too big to be placed on the stack, even
     54            though the data is only needed during execution of this function
     55            Data type void pointer, internally pointer to a tmp3dec_file
     56            structure.
     57 
     58 
     59 ------------------------------------------------------------------------------
     60  FUNCTION DESCRIPTION
     61 
     62     search mp3 sync word, when found, it verifies, based on header parameters,
     63     the locations of the very next sync word,
     64     - if fails, then indicates a false sync,
     65     - otherwise, it confirm synchronization of at least 2 consecutives frames
     66 
     67 ------------------------------------------------------------------------------
     68  REQUIREMENTS
     69 
     70 
     71 ------------------------------------------------------------------------------
     72  REFERENCES
     73 
     74 ------------------------------------------------------------------------------
     75  PSEUDO-CODE
     76 
     77 ------------------------------------------------------------------------------
     78 */
     79 
     80 
     81 /*----------------------------------------------------------------------------
     82 ; INCLUDES
     83 ----------------------------------------------------------------------------*/
     84 
     85 #include "pvmp3_seek_synch.h"
     86 #include "pvmp3_getbits.h"
     87 #include "s_tmp3dec_file.h"
     88 #include "pv_mp3dec_fxd_op.h"
     89 #include "pvmp3_tables.h"
     90 
     91 
     92 /*----------------------------------------------------------------------------
     93 ; MACROS
     94 ; Define module specific macros here
     95 ----------------------------------------------------------------------------*/
     96 
     97 
     98 /*----------------------------------------------------------------------------
     99 ; DEFINES
    100 ; Include all pre-processor statements here. Include conditional
    101 ; compile variables also.
    102 ----------------------------------------------------------------------------*/
    103 
    104 /*----------------------------------------------------------------------------
    105 ; LOCAL FUNCTION DEFINITIONS
    106 ; Function Prototype declaration
    107 ----------------------------------------------------------------------------*/
    108 
    109 /*----------------------------------------------------------------------------
    110 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    111 ; Variable declaration - defined here and used outside this module
    112 ----------------------------------------------------------------------------*/
    113 
    114 /*----------------------------------------------------------------------------
    115 ; EXTERNAL FUNCTION REFERENCES
    116 ; Declare functions defined elsewhere and referenced in this module
    117 ----------------------------------------------------------------------------*/
    118 
    119 /*----------------------------------------------------------------------------
    120 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    121 ; Declare variables used in this module but defined elsewhere
    122 ----------------------------------------------------------------------------*/
    123 
    124 /*----------------------------------------------------------------------------
    125 ; FUNCTION CODE
    126 ----------------------------------------------------------------------------*/
    127 
    128 
    129 
    130 ERROR_CODE pvmp3_frame_synch(tPVMP3DecoderExternal *pExt,
    131                              void                  *pMem) /* bit stream structure */
    132 {
    133     uint16 val;
    134     ERROR_CODE err;
    135 
    136     tmp3dec_file      *pVars;
    137 
    138     pVars = (tmp3dec_file *)pMem;
    139 
    140     pVars->inputStream.pBuffer = pExt->pInputBuffer;
    141     pVars->inputStream.usedBits = (pExt->inputBufferUsedLength << 3); // in bits
    142 
    143 
    144     pVars->inputStream.inputBufferCurrentLength = (pExt->inputBufferCurrentLength); // in bits
    145 
    146     err = pvmp3_header_sync(&pVars->inputStream);
    147 
    148     if (err == NO_DECODING_ERROR)
    149     {
    150         /* validate synchronization by checking two consecutive sync words */
    151 
    152         // to avoid multiple bitstream accesses
    153         uint32 temp = getNbits(&pVars->inputStream, 21);
    154         // put back whole header
    155         pVars->inputStream.usedBits -= 21 + SYNC_WORD_LNGTH;
    156 
    157         int32  version;
    158 
    159         switch (temp >> 19)  /* 2 */
    160         {
    161             case 0:
    162                 version = MPEG_2_5;
    163                 break;
    164             case 2:
    165                 version = MPEG_2;
    166                 break;
    167             case 3:
    168                 version = MPEG_1;
    169                 break;
    170             default:
    171                 version = INVALID_VERSION;
    172                 break;
    173         }
    174 
    175         int32 freq_index = (temp << 20) >> 30;
    176 
    177         if (version != INVALID_VERSION && (freq_index != 3))
    178         {
    179             int32 numBytes = fxp_mul32_Q28(mp3_bitrate[version][(temp<<16)>>28] << 20,
    180                                            inv_sfreq[freq_index]);
    181 
    182             numBytes >>= (20 - version);
    183 
    184             if (version != MPEG_1)
    185             {
    186                 numBytes >>= 1;
    187             }
    188             if ((temp << 22) >> 31)
    189             {
    190                 numBytes++;
    191             }
    192 
    193             if (numBytes > (int32)pVars->inputStream.inputBufferCurrentLength)
    194             {
    195                 /* frame should account for padding and 2 bytes to check sync */
    196                 pExt->CurrentFrameLength = numBytes + 3;
    197                 return (SYNCH_LOST_ERROR);
    198             }
    199             else if (numBytes == (int32)pVars->inputStream.inputBufferCurrentLength)
    200             {
    201                 /* No enough data to validate, but current frame appears to be correct ( EOF case) */
    202                 pExt->inputBufferUsedLength = pVars->inputStream.usedBits >> 3;
    203                 return (NO_DECODING_ERROR);
    204             }
    205             else
    206             {
    207 
    208                 int32 offset = pVars->inputStream.usedBits + ((numBytes) << 3);
    209 
    210                 offset >>= INBUF_ARRAY_INDEX_SHIFT;
    211                 uint8    *pElem  = pVars->inputStream.pBuffer + offset;
    212                 uint16 tmp1 = *(pElem++);
    213                 uint16 tmp2 = *(pElem);
    214 
    215                 val = (tmp1 << 3);
    216                 val |= (tmp2 >> 5);
    217             }
    218         }
    219         else
    220         {
    221             val = 0; // force mismatch
    222         }
    223 
    224         if (val == SYNC_WORD)
    225         {
    226             pExt->inputBufferUsedLength = pVars->inputStream.usedBits >> 3; ///  !!!!!
    227             err = NO_DECODING_ERROR;
    228         }
    229         else
    230         {
    231             pExt->inputBufferCurrentLength = 0;
    232             err = SYNCH_LOST_ERROR;
    233         }
    234     }
    235     else
    236     {
    237         pExt->inputBufferCurrentLength = 0;
    238     }
    239 
    240     return(err);
    241 
    242 }
    243 
    244 /*
    245 ------------------------------------------------------------------------------
    246  REVISION HISTORY
    247 
    248 
    249  Description:
    250 
    251 ------------------------------------------------------------------------------
    252  INPUT AND OUTPUT DEFINITIONS
    253 
    254 pvmp3_header_sync
    255 
    256 Input
    257     tmp3Bits *inputStream,     structure holding the input stream parameters
    258 
    259 ------------------------------------------------------------------------------
    260  FUNCTION DESCRIPTION
    261 
    262     search mp3 sync word
    263 
    264 ------------------------------------------------------------------------------
    265  REQUIREMENTS
    266 
    267 
    268 ------------------------------------------------------------------------------
    269  REFERENCES
    270 
    271 ------------------------------------------------------------------------------
    272  PSEUDO-CODE
    273 
    274 ------------------------------------------------------------------------------
    275 */
    276 
    277 /*----------------------------------------------------------------------------
    278 ; FUNCTION CODE
    279 ----------------------------------------------------------------------------*/
    280 
    281 
    282 ERROR_CODE pvmp3_header_sync(tmp3Bits  *inputStream)
    283 {
    284     uint16 val;
    285     uint32 availableBits = (inputStream->inputBufferCurrentLength << 3); // in bits
    286 
    287     // byte aligment
    288     inputStream->usedBits = (inputStream->usedBits + 7) & 8;
    289 
    290     val = (uint16)getUpTo17bits(inputStream, SYNC_WORD_LNGTH);
    291 
    292     while (((val&SYNC_WORD) != SYNC_WORD) && (inputStream->usedBits < availableBits))
    293     {
    294         val <<= 8;
    295         val |= getUpTo9bits(inputStream, 8);
    296     }
    297 
    298     if ((val&SYNC_WORD) == SYNC_WORD && (inputStream->usedBits < availableBits))
    299     {
    300         return(NO_DECODING_ERROR);
    301     }
    302     else
    303     {
    304         return(SYNCH_LOST_ERROR);
    305     }
    306 
    307 }
    308 
    309