videoeditorengine/h263decoder/src/sync_mpeg.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     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