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