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 * MPEG-4 sync code functions. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 #include "h263dConfig.h" |
|
22 |
|
23 #include "sync.h" |
|
24 #include "errcodes.h" |
|
25 #include "debug.h" |
|
26 #include "mpegcons.h" |
|
27 #include "biblin.h" |
|
28 |
|
29 |
|
30 /* |
|
31 * Global functions |
|
32 */ |
|
33 |
|
34 /* {{-output"sncCheckMpegVOP.txt"}} */ |
|
35 /* |
|
36 * |
|
37 * sncCheckMpegVOP |
|
38 * |
|
39 * Parameters: |
|
40 * buffer a pointer to a bit buffer structure |
|
41 * error error code |
|
42 * |
|
43 * Function: |
|
44 * This function checks if the GOV, VOP start codes |
|
45 * are the next codes in the bit buffer. |
|
46 * NO stuffing is allowed before the code, the routine checks from the |
|
47 * current position in the buffer- |
|
48 * The code is not flushed from the buffer. |
|
49 * |
|
50 * Returns: |
|
51 * SNC_NO_SYNC if no sync code is found |
|
52 * SNC_PSC if GOV or VOP start code is found |
|
53 * |
|
54 * Error codes: |
|
55 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
56 * |
|
57 * |
|
58 * |
|
59 */ |
|
60 |
|
61 int sncCheckMpegVOP(bibBuffer_t *buffer, int16 *error) |
|
62 /* {{-output"sncCheckMpegVOP.txt"}} */ |
|
63 { |
|
64 u_int32 bits; |
|
65 int16 newError = 0; |
|
66 int numBitsGot, bitErrorIndication = 0; |
|
67 |
|
68 bits = bibShowBits(32, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
69 |
|
70 if ((newError == ERR_BIB_NOT_ENOUGH_DATA) && (numBitsGot > 0 )) { |
|
71 /* Still bits in the buffer */ |
|
72 deb("sncCheckSync: bibShowReturned not enough data but there are " |
|
73 "still bits in the buffer --> error cleared.\n"); |
|
74 return SNC_NO_SYNC; |
|
75 } else if (newError) { |
|
76 *error = newError; |
|
77 return SNC_NO_SYNC; |
|
78 } |
|
79 |
|
80 if (bits == MP4_GROUP_START_CODE || bits == MP4_VOP_START_CODE || bits == MP4_EOB_CODE) |
|
81 return SNC_PSC; |
|
82 else |
|
83 return SNC_NO_SYNC; |
|
84 } |
|
85 |
|
86 /* {{-output"sncCheckMpegSync.txt"}} */ |
|
87 /* |
|
88 * |
|
89 * sncCheckMpegSync |
|
90 * |
|
91 * Parameters: |
|
92 * buffer a pointer to a bit buffer structure |
|
93 * f_code f_code of the last P-vop |
|
94 * error error code |
|
95 * |
|
96 * Function: |
|
97 * This function checks if the GOV, VOP or Video Pcaket start codes |
|
98 * are the next codes in the bit buffer. |
|
99 * Stuffing is needed before the code and the number of stuffing bits |
|
100 * is returned in numStuffBits parameter. |
|
101 * The code is not flushed from the buffer. |
|
102 * |
|
103 * Returns: |
|
104 * SNC_NO_SYNC if no sync code is found |
|
105 * SNC_GOV if GOV start code is found |
|
106 * SNC_VOP if VOP start code is found |
|
107 * SNC_VOS if VOS start code is found |
|
108 * SNC_VIDPACK if Video Packet start code is found |
|
109 * SNC_STUFFING if there is a bit with the value zero |
|
110 * followed by less than 7 bits with the |
|
111 * value one starting from the current position |
|
112 * and after them the buffer (picture segment) ends |
|
113 * |
|
114 * Error codes: |
|
115 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
116 * |
|
117 * |
|
118 * |
|
119 * |
|
120 * |
|
121 * |
|
122 */ |
|
123 |
|
124 int sncCheckMpegSync(bibBuffer_t *buffer, int f_code, int16 *error) |
|
125 /* {{-output"sncCheckMpegSync.txt"}} */ |
|
126 { |
|
127 u_int32 result, bits, start_code_val; |
|
128 int numBitsGot, i, shift_bits; |
|
129 int16 newError = 0; |
|
130 int bitErrorIndication = 0; |
|
131 |
|
132 shift_bits = 32-(16+f_code); |
|
133 |
|
134 bits = bibShowBits(32, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
135 |
|
136 if ( buffer->error ) |
|
137 { |
|
138 // out of bits |
|
139 *error = (int16)buffer->error; |
|
140 return SNC_NO_SYNC; |
|
141 } |
|
142 |
|
143 |
|
144 for(i = 0; i <= 8; i++) { |
|
145 |
|
146 /* if stuffing is correct */ |
|
147 if ( (i==0) || ((bits >> (32-i)) == (u_int32) ((1 << (i-1))-1)) ) { |
|
148 |
|
149 result = bits << i; |
|
150 |
|
151 if ((result >> 8) == 1) { |
|
152 |
|
153 /* Stuff start code */ |
|
154 if (i != 0) { |
|
155 bibFlushBits(i, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
156 if (newError) { |
|
157 *error = newError; |
|
158 return SNC_NO_SYNC; |
|
159 } |
|
160 } |
|
161 |
|
162 /* Check start code */ |
|
163 start_code_val = |
|
164 bibShowBits(32, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
165 if ((newError == ERR_BIB_NOT_ENOUGH_DATA) && (numBitsGot > 0 )) { |
|
166 /* Still bits in the buffer */ |
|
167 deb("sncCheckSync: bibShowReturned not enough data but there are " |
|
168 "still bits in the buffer --> error cleared.\n"); |
|
169 if (i) bibRewindBits(i, buffer, &newError); |
|
170 return SNC_NO_SYNC; |
|
171 } else if (newError) { |
|
172 *error = newError; |
|
173 if (i) bibRewindBits(i, buffer, &newError); |
|
174 return SNC_NO_SYNC; |
|
175 } |
|
176 |
|
177 if (start_code_val == MP4_VOP_START_CODE) { |
|
178 return SNC_VOP; |
|
179 } else if (start_code_val == MP4_VOS_START_CODE) { |
|
180 return SNC_VOS; |
|
181 } else if (start_code_val == MP4_GROUP_START_CODE) { |
|
182 return SNC_GOV; |
|
183 } else if (start_code_val == MP4_USER_DATA_START_CODE) { |
|
184 return SNC_USERDATA; |
|
185 } else if (start_code_val == MP4_EOB_CODE) { |
|
186 return SNC_EOB; |
|
187 } else if (((start_code_val >> (32-MP4_VID_START_CODE_LENGTH)) == MP4_VID_START_CODE) || |
|
188 ((start_code_val >> (32-MP4_VOL_START_CODE_LENGTH)) == MP4_VOL_START_CODE)) { |
|
189 return SNC_VID; |
|
190 } else { |
|
191 if (i) bibRewindBits(i, buffer, &newError); |
|
192 continue; |
|
193 } |
|
194 |
|
195 } else if (f_code && ((result >> shift_bits) == 1)) { |
|
196 if (i != 0) { |
|
197 /* Stuff start code */ |
|
198 bibFlushBits(i, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
199 if (newError) { |
|
200 *error = newError; |
|
201 return SNC_NO_SYNC; |
|
202 } |
|
203 } |
|
204 return SNC_VIDPACK; |
|
205 } |
|
206 } |
|
207 } |
|
208 |
|
209 return SNC_NO_SYNC; |
|
210 } |
|
211 |
|
212 |
|
213 /* {{-output"sncRewindAndSeekNewMPEGSync.txt"}} */ |
|
214 /* |
|
215 * sncRewindAndSeekNewMPEGSync |
|
216 * |
|
217 * |
|
218 * Parameters: |
|
219 * numBitsToRewind the number of bits to rewind before seeking |
|
220 * the synchronization code, |
|
221 * if negative, a default number of bits is |
|
222 * rewinded. It is recommended to use |
|
223 * the SNC_DEFAULT_REWIND definition to represent |
|
224 * negative values in order to increase code |
|
225 * readability. |
|
226 * buffer a pointer to a bit buffer structure |
|
227 * f_code f_code of the last P-vop |
|
228 * error error code |
|
229 * |
|
230 * Function: |
|
231 * This function is intended to be called after bit error detection. |
|
232 * It rewinds some (already read) bits in order not to miss any sync code. |
|
233 * Then, this function finds the next GOV, VOP or Video Packet start code |
|
234 * which is not within the rewinded bits. The function discards the bits |
|
235 * before the synchronization code but does not remove the found code from |
|
236 * the buffer. |
|
237 * |
|
238 * |
|
239 * Returns: |
|
240 * SNC_NO_SYNC if no sync code was found and |
|
241 * no more bits are available |
|
242 * SNC_GOV if GOV start code is found |
|
243 * SNC_VOP if VOP start code is found |
|
244 * SNC_VIDPACK if Video Packet start code is found |
|
245 * |
|
246 * Error codes: |
|
247 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
248 * |
|
249 * |
|
250 * |
|
251 */ |
|
252 |
|
253 int sncRewindAndSeekNewMPEGSync(int numBitsToRewind, bibBuffer_t *buffer, |
|
254 int f_code, int16 *error) |
|
255 /* {{-output"sncRewindAndSeekNewMPEGSync.txt"}} */ |
|
256 { |
|
257 int sncCode; /* found sync code */ |
|
258 u_int32 numRewindableBits; /* number of bits which can be rewinded */ |
|
259 u_int32 bitPosBeforeRewinding; /* initial buffer bit index */ |
|
260 u_int32 syncStartBitPos; /* 1st bit index in found sync code */ |
|
261 u_int32 syncEndBitPos; |
|
262 int nb = 0; |
|
263 int bei = 0; |
|
264 |
|
265 *error = 0; |
|
266 |
|
267 /* If default number of rewinded bits requested */ |
|
268 if (numBitsToRewind < 0) |
|
269 /* 32 bits is considered to be enough */ |
|
270 numBitsToRewind = 32; |
|
271 |
|
272 numRewindableBits = bibNumberOfRewBits(buffer); |
|
273 |
|
274 if (numRewindableBits < (u_int32) numBitsToRewind) |
|
275 numBitsToRewind = (int) numRewindableBits; |
|
276 |
|
277 bitPosBeforeRewinding = bibNumberOfFlushedBits(buffer); |
|
278 |
|
279 if (numBitsToRewind) bibRewindBits(numBitsToRewind, buffer, error); |
|
280 if (*error) |
|
281 return SNC_NO_SYNC; |
|
282 |
|
283 /* Loop */ |
|
284 do { |
|
285 |
|
286 /* Seek the next synchronization code */ |
|
287 sncCode = sncSeekMPEGStartCode (buffer, f_code, 0 /* this method used with DP and VP => VP resync is relevant */, 0, error); |
|
288 if (*error) |
|
289 return sncCode; |
|
290 |
|
291 syncStartBitPos = bibNumberOfFlushedBits(buffer); |
|
292 |
|
293 syncEndBitPos = syncStartBitPos + |
|
294 (u_int32) ((sncCode == SNC_VIDPACK) ? (16 + f_code) : 32); |
|
295 |
|
296 if (syncEndBitPos <= bitPosBeforeRewinding) |
|
297 bibFlushBits( 1, buffer, &nb, &bei, error ); |
|
298 |
|
299 /* While the found sync code has been previously read */ |
|
300 } while (syncEndBitPos <= bitPosBeforeRewinding); |
|
301 |
|
302 return sncCode; |
|
303 } |
|
304 |
|
305 /* {{-output"sncSeekMPEGSync.txt"}} */ |
|
306 /* |
|
307 * sncSeekMPEGSync |
|
308 * |
|
309 * |
|
310 * Parameters: |
|
311 * buffer a pointer to a bit buffer structure |
|
312 * f_code f_code of the last P-vop |
|
313 * error error code |
|
314 * |
|
315 * Function: |
|
316 * Then, this function finds the next GOV, VOP or Video Packet start code |
|
317 * from the buffer. The function discards the bits before the sync code |
|
318 * but does not remove the found code from the buffer. |
|
319 * |
|
320 * Returns: |
|
321 * SNC_NO_SYNC if no sync code was found and |
|
322 * no more bits are available |
|
323 * SNC_GOV if GOV start code is found |
|
324 * SNC_VOP if VOP start code is found |
|
325 * SNC_VOS if VOS start code is found |
|
326 * SNC_VIDPACK if Video Packet start code is found |
|
327 * |
|
328 * Error codes: |
|
329 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
330 * |
|
331 * |
|
332 */ |
|
333 |
|
334 int sncSeekMPEGSync(bibBuffer_t *buffer, int f_code, int16 *error) |
|
335 /* {{-output"sncSeekMPEGSync.txt"}} */ |
|
336 { |
|
337 u_int32 result; |
|
338 int numBitsGot, shift_bits; |
|
339 int16 newError = 0; |
|
340 int bitErrorIndication = 0; |
|
341 |
|
342 shift_bits = 32-(16+f_code); |
|
343 |
|
344 for (;;) { |
|
345 |
|
346 bitErrorIndication = 0; |
|
347 |
|
348 result = bibShowBits(32, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
349 |
|
350 |
|
351 if (newError == ERR_BIB_NOT_ENOUGH_DATA && numBitsGot) { |
|
352 /* Use the available bits */ |
|
353 result <<= (32 - numBitsGot); |
|
354 newError = 0; |
|
355 } else if (newError) { |
|
356 deb("sncSeekSync: ERROR - bibShowBits failed.\n"); |
|
357 *error = newError; |
|
358 return SNC_NO_SYNC; |
|
359 } |
|
360 |
|
361 if (result == MP4_GROUP_START_CODE) |
|
362 return SNC_GOV; |
|
363 else if (result == MP4_VOP_START_CODE) |
|
364 return SNC_VOP; |
|
365 else if (result == MP4_VOS_START_CODE) |
|
366 return SNC_VOS; |
|
367 else if (result == MP4_EOB_CODE) |
|
368 return SNC_EOB; |
|
369 else if (f_code && ((result >> shift_bits) == 1)) |
|
370 return SNC_VIDPACK; |
|
371 else if ( buffer->error ) |
|
372 { |
|
373 // out of bits |
|
374 *error = (int16)buffer->error; |
|
375 return SNC_NO_SYNC; |
|
376 } |
|
377 |
|
378 |
|
379 bibFlushBits(1, buffer, &numBitsGot, &bitErrorIndication, error); |
|
380 } |
|
381 } |
|
382 |
|
383 /* {{-output"sncSeekMPEGStartCode.txt"}} */ |
|
384 /* |
|
385 * sncSeekMPEGStartCode |
|
386 * |
|
387 * |
|
388 * Parameters: |
|
389 * buffer a pointer to a bit buffer structure |
|
390 * f_code f_code of the last P-vop |
|
391 * skipVPSync nonzero if Video Packet sync codes can be skipped |
|
392 * error error code |
|
393 * |
|
394 * Function: |
|
395 * This function finds the next GOV, VOP or Video Packet start code |
|
396 * from the buffer in byte-aligned positions. The function discards the bits before the sync code |
|
397 * but does not remove the found code from the buffer. |
|
398 * |
|
399 * Returns: |
|
400 * SNC_NO_SYNC if no sync code was found and |
|
401 * no more bits are available |
|
402 * SNC_GOV if GOV start code is found |
|
403 * SNC_VOP if VOP start code is found |
|
404 * SNC_VOS if VOS start code is found |
|
405 * SNC_VIDPACK if Video Packet start code is found |
|
406 * |
|
407 * Error codes: |
|
408 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
409 * |
|
410 * |
|
411 */ |
|
412 |
|
413 int sncSeekMPEGStartCode(bibBuffer_t *buffer, int f_code, int skipVPSync, int checkUD, int16 *error) |
|
414 /* {{-output"sncSeekMPEGSync.txt"}} */ |
|
415 { |
|
416 u_int32 result; |
|
417 int numBitsGot, shift_bits; |
|
418 int16 newError = 0; |
|
419 int bitErrorIndication = 0; |
|
420 int flush = 8; |
|
421 const u_int32 MAX_MPEG4_START_CODE = 0x000001ff; |
|
422 shift_bits = 32-(16+f_code); |
|
423 |
|
424 /* start codes are always byte aligned */ |
|
425 /* move to the next byte aligned position, if not already there */ |
|
426 if (buffer->bitIndex != 7) |
|
427 { |
|
428 bibForwardBits(buffer->bitIndex + 1, buffer); |
|
429 } |
|
430 |
|
431 for (;;) |
|
432 { |
|
433 bitErrorIndication = 0; |
|
434 result = bibShowBits(32, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
435 |
|
436 |
|
437 if ( buffer->error ) |
|
438 { |
|
439 // out of bits |
|
440 *error = (int16)buffer->error; |
|
441 return SNC_NO_SYNC; |
|
442 } |
|
443 |
|
444 /* don't check all start codes, if it is not one of them */ |
|
445 if (result <= MAX_MPEG4_START_CODE) |
|
446 { |
|
447 if (result == MP4_GROUP_START_CODE) |
|
448 return SNC_GOV; |
|
449 else if (result == MP4_VOP_START_CODE) |
|
450 return SNC_VOP; |
|
451 else if (result == MP4_VOS_START_CODE) |
|
452 return SNC_VOS; |
|
453 else if (result == MP4_EOB_CODE) |
|
454 return SNC_EOB; |
|
455 else if ( checkUD && (result == MP4_USER_DATA_START_CODE) ) |
|
456 return SNC_USERDATA; |
|
457 |
|
458 } |
|
459 else if (!skipVPSync && f_code && ((result >> shift_bits) == 1)) |
|
460 { |
|
461 return SNC_VIDPACK; |
|
462 } |
|
463 |
|
464 // we continue here after either if all the if-else's inside the if above are false or if the last else-if is false |
|
465 |
|
466 // Note! the following optimization is based on MPEG-4 sync code prefix 0x000001. It doesn't work with any other prefixes. |
|
467 if ( !skipVPSync ) |
|
468 { |
|
469 flush = 8; |
|
470 // a small optimization could be reached also with video packet sync markers, but is probably not worth the effort since |
|
471 // it seems that it could be used to shift at most 16 bits at least in cases with typical f_code values |
|
472 // idea: |
|
473 // at least if fcode == 15, possible vp resync markers are in the form |
|
474 // 00008xxx, 00009xxx, 0000axxx, 0000bxxx, 0000cxxx, 0000dxxx, 0000exxx, 0000fxxx |
|
475 // the shifting above already removes the 15 lowest bits => 16th bit must be 1 and 16 highest bits |
|
476 // should be 0 |
|
477 // in the old way, the sync code from 00008xxx is found in the following steps |
|
478 // 8xxxyyyy, 008xxxyy, => match |
|
479 // hence we can skip 16 bits (or f-code dependent nr of bits) if |
|
480 // a) 32nd bit is 1 |
|
481 // If 32nd bit is 0, we can skip the 16-(nr of successive 0-MSB bits) |
|
482 } |
|
483 |
|
484 // then check for the other sync codes |
|
485 |
|
486 // the 1st check here is needed to optimize the checking: in hopeless cases only a single check is needed |
|
487 else if ( (result & 0x000000ff) <= 1 ) |
|
488 { |
|
489 // the 1st check is needed to optimize the checking: in hopeless cases only a single check is needed |
|
490 if ( ((result & 0x000000ff ) == 1) && ((result & 0x00ffff00 ) > 0)) |
|
491 { |
|
492 // yyxxxx01, where one of the x != 0 => hopeless |
|
493 flush = 32; |
|
494 } |
|
495 else if ( (result & 0x0000ffff ) == 0 ) |
|
496 { |
|
497 // xxxx0000 => could be the 1st 2 bytes of sync code |
|
498 flush = 16; |
|
499 } |
|
500 else if ( (result & 0x000000ff) == 0 ) |
|
501 { |
|
502 // yyyyxx00, where xx != 00 (checked above), could be the 1st byte of sync code |
|
503 flush = 24; |
|
504 } |
|
505 else if ( (result & 0x00ffffff) == 1 ) |
|
506 { |
|
507 // xx000001 => shift 1 byte |
|
508 flush = 8; |
|
509 } |
|
510 else |
|
511 { |
|
512 // this looks duplicate to the 1st one, but is kept here for simplicity. The 1st one is there since it is the most probable and |
|
513 // hence most cases fall under it. If it was not there, then in most cases all the if's were evaluated and that means extra processing |
|
514 flush = 32; |
|
515 } |
|
516 } |
|
517 else |
|
518 { |
|
519 // hopeless |
|
520 flush = 32; |
|
521 } |
|
522 |
|
523 // flush bits |
|
524 bibFlushBits(flush, buffer, &numBitsGot, &bitErrorIndication, error); |
|
525 } |
|
526 } |
|
527 |
|
528 |
|
529 /* {{-output"sncSeekBitPattern.txt"}} */ |
|
530 /* |
|
531 * sncSeekBitPattern |
|
532 * |
|
533 * |
|
534 * Parameters: |
|
535 * buffer a pointer to a bit buffer structure |
|
536 * error error code |
|
537 * BitPattern to bit pattern to be found |
|
538 * BitPatternLength length of the bit pattern to be found |
|
539 * |
|
540 * Function: |
|
541 * This function finds the next occurance of the given BitPattern |
|
542 * from the buffer. The function discards the bits before the BitPattern |
|
543 * but does not remove the found code from the buffer. |
|
544 * |
|
545 * Returns: |
|
546 * SNC_NO_SYNC if the bit pattern was not found and |
|
547 * no more bits are available |
|
548 * SNC_PATTERN if the BitPattern is found |
|
549 * |
|
550 * Error codes: |
|
551 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
552 * |
|
553 * |
|
554 */ |
|
555 |
|
556 int sncSeekBitPattern(bibBuffer_t *buffer, u_int32 BitPattern, int BitPatternLength, int16 *error) |
|
557 /* {{-output"sncSeekBitPattern.txt"}} */ |
|
558 { |
|
559 u_int32 result; |
|
560 int numBitsGot; |
|
561 int16 newError = 0; |
|
562 int bitErrorIndication = 0; |
|
563 |
|
564 for (;;) { |
|
565 |
|
566 bitErrorIndication = 0; |
|
567 |
|
568 result = bibShowBits(32, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
569 |
|
570 if (newError == ERR_BIB_NOT_ENOUGH_DATA && numBitsGot >= BitPatternLength) { |
|
571 /* Use the available bits */ |
|
572 result <<= (32 - numBitsGot); |
|
573 newError = 0; |
|
574 } else if (newError) { |
|
575 deb("sncSeekBitPattern: ERROR - bibShowBits failed.\n"); |
|
576 *error = newError; |
|
577 return SNC_NO_SYNC; |
|
578 } |
|
579 |
|
580 if ((result >> (32 - BitPatternLength)) == BitPattern) |
|
581 return SNC_PATTERN; |
|
582 else if (result == MP4_GROUP_START_CODE) |
|
583 return SNC_GOV; |
|
584 else if (result == MP4_VOP_START_CODE) |
|
585 return SNC_VOP; |
|
586 else if (result == MP4_EOB_CODE) |
|
587 return SNC_EOB; |
|
588 else if ( buffer->error ) |
|
589 { |
|
590 // out of bits |
|
591 *error = (int16)buffer->error; |
|
592 return SNC_NO_SYNC; |
|
593 } |
|
594 |
|
595 bibFlushBits(1, buffer, &numBitsGot, &bitErrorIndication, error); |
|
596 } |
|
597 } |
|
598 |
|
599 /* {{-output"sncRewindStuffing.txt"}} */ |
|
600 /* |
|
601 * sncRewindStuffing |
|
602 * |
|
603 * |
|
604 * Parameters: |
|
605 * buffer a pointer to a bit buffer structure |
|
606 * error error code |
|
607 * |
|
608 * Function: |
|
609 * This function recognizes and rewinds the stuffing bits (1..8) from |
|
610 * the current position of the buffer. |
|
611 * |
|
612 * Returns: |
|
613 * SNC_NO_SYNC if the stuffing was not found |
|
614 * SNC_PATTERN if the stuffing has been rewinded successfully |
|
615 * |
|
616 * Error codes: |
|
617 * Error codes returned by bibFlushBits/bibGetBits/bibShowBits. |
|
618 * |
|
619 * |
|
620 */ |
|
621 |
|
622 int sncRewindStuffing(bibBuffer_t *buffer, int16 *error) |
|
623 /* {{-output"sncRewindStuffing.txt"}} */ |
|
624 { |
|
625 u_int32 result; |
|
626 int numBitsGot, i; |
|
627 int16 newError = 0; |
|
628 int bitErrorIndication = 0; |
|
629 |
|
630 bibRewindBits(8, buffer, &newError); |
|
631 result = bibGetBits(8, buffer, &numBitsGot, &bitErrorIndication, &newError); |
|
632 if (newError) { |
|
633 deb("sncRewindStuffing: ERROR - bibShowBits failed.\n"); |
|
634 *error = newError; |
|
635 return SNC_NO_SYNC; |
|
636 } |
|
637 |
|
638 for(i = 1; i <= 8; i++) { |
|
639 /* if stuffing is correct */ |
|
640 if ((result & (1 << (i-1))) == 0) { |
|
641 bibRewindBits(i, buffer, &newError); |
|
642 return SNC_PATTERN; |
|
643 } |
|
644 } |
|
645 |
|
646 return SNC_NO_SYNC; |
|
647 } |
|
648 // End of File |
|