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