• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
pvmp3_frame_synch(tPVMP3DecoderExternal * pExt,void * pMem)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 
pvmp3_header_sync(tmp3Bits * inputStream)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