Home | History | Annotate | Download | only in parser
      1 #include "viddec_pm_parse.h"
      2 #include "viddec_fw_debug.h"
      3 
      4 #define FIRST_STARTCODE_BYTE        0x00
      5 #define SECOND_STARTCODE_BYTE       0x00
      6 #define THIRD_STARTCODE_BYTE        0x01
      7 
      8 /* BIG ENDIAN: Must be the second and fourth byte of the bytestream for this to work */
      9 /* LITTLE ENDIAN: Must be the second and fourth byte of the bytestream for this to work */
     10 /* these are little-endian defines */
     11 #define SC_BYTE_MASK0               0x00ff0000  /* little-endian */
     12 #define SC_BYTE_MASK1               0x000000ff  /* little-endian */
     13 
     14 // This is the 2.25 clocks per byte loop
     15 #define USE_2p25_CLOCK_PER_BYTE_LOOP
     16 
     17 #ifdef USE_2p25_CLOCK_PER_BYTE_LOOP
     18 static int parser_find_next_startcode(
     19    const unsigned char        *buf,
     20    int                         i,
     21    int                         len,
     22    unsigned int               *pphase )
     23 {
     24    int            sc_pos = -1;
     25    int            in_slow_loop;
     26    register unsigned int   scphase;
     27 
     28    scphase = *pphase;
     29 
     30    in_slow_loop = 1;
     31    if (  (0 == (0x3 & i)) &&  /* dword aligned */
     32          (0 == scphase) &&    /* no "potential" SC detected */
     33          ((len - i) >= 4) )   /* more than four bytes left */
     34    {
     35       in_slow_loop = 0; /* go to fast loop */
     36    }
     37 
     38    while( i < len )
     39    {
     40       if ( in_slow_loop )
     41       {
     42 /* ------- slow SC Detect Loop, used when 0 detected in stream --------*/
     43 sc_detect_slow_loop:
     44 
     45          while ( i < len )
     46          {
     47             unsigned char  ch;
     48 
     49             ch = buf[i];
     50 
     51             /* searching for a zero, ignore phase for now */
     52             if ( FIRST_STARTCODE_BYTE == ch )
     53             {
     54                /* if we've already got two zeros, hold at phase == 2 */
     55                if ( scphase < 2 )
     56                {
     57                   scphase++;
     58                }
     59                else if ( scphase > 2 )
     60                {
     61                   /* RARE Valid Condition, SC == 00 00 01 00 */
     62                   /* if we've already got two zeros hold at phase == 2
     63                    * we also enter here of we're at phase 3
     64                    * meaning we've got 00 00 01 00 which is a valid SC
     65                    */
     66                   /* 00 00 01 00 */
     67                   sc_pos = i;
     68                   *pphase = scphase;
     69                   return(sc_pos);
     70                }
     71                else  /* implies scphase == 2, holding receiving 0's */
     72                {
     73                }
     74             }
     75             else if ( THIRD_STARTCODE_BYTE == ch )
     76             {
     77                if ( 2 == scphase )
     78                {
     79                   /* next byte is the SC */
     80                   scphase++;
     81                }
     82                else if ( scphase < 2 )
     83                {
     84                   scphase = 0;   /* start over */
     85                }
     86                else if ( scphase > 2 )
     87                {
     88                   /* RARE Valid Condition, SC == 00 00 01 01 */
     89                   sc_pos = i;
     90                   *pphase = scphase;
     91                   return(sc_pos);
     92                }
     93             }
     94             else if ( 3 == scphase )
     95             {
     96                /* Valid Condition, SC == 00 00 01 xx */
     97                sc_pos = i;
     98                *pphase = scphase;
     99                return(sc_pos);
    100             }
    101             else
    102             {
    103                scphase = 0;
    104 
    105                if (  (3 == (0x3 & i)) &&  /* dword aligned? */
    106                      ((len - i) > 4) )   /* more than four bytes left */
    107                {
    108                   i++;
    109                   in_slow_loop = 0; /* go to fast loop */
    110 
    111                   /* WARNING: Performance GoTo */
    112                   goto sc_detect_fast_loop;
    113                }
    114             }
    115 
    116             i++;
    117          }
    118       }
    119       else  /* we're in the fast loop */
    120       {
    121 /* ------- FAST SC Detect Loop, used to skip at high bandwidth --------*/
    122 sc_detect_fast_loop:
    123 
    124          /* FAST start-code scanning loop (Krebs Algorithm) */
    125          while ( i <= (len - 4) )
    126          {
    127             register unsigned int      dw;
    128 
    129             dw = *((unsigned int *)&buf[i]);
    130 #ifndef MFDBIGENDIAN
    131             dw = SWAP_WORD(dw);
    132 #endif
    133             if ( 0 != (dw & SC_BYTE_MASK0) )
    134             {
    135                if ( 0 != (dw & SC_BYTE_MASK1) )
    136                {
    137                   /* most common code path */
    138                   i += 4;
    139                   continue;
    140                }
    141             }
    142 
    143             break;
    144          }
    145          /* potential SC detected or at end of loop */
    146          in_slow_loop = 1;
    147 
    148          /* WARNING: performance goto */
    149          goto sc_detect_slow_loop;
    150       }
    151    }
    152 
    153    *pphase = scphase;
    154    return(sc_pos);
    155 }
    156 unsigned int viddec_parse_sc(void *in, void *pcxt)
    157 {
    158    viddec_sc_parse_cubby_cxt_t *cxt;
    159    int                          boff;
    160    int                          retval=0;
    161 
    162    cxt = (viddec_sc_parse_cubby_cxt_t *)in;
    163 
    164    /* get to four-byte alignment */
    165    boff = (int)cxt->buf & 0x3;
    166 
    167    cxt->sc_end_pos = parser_find_next_startcode(
    168       (const unsigned char *)cxt->buf - boff,
    169       boff,
    170       cxt->size + boff,
    171       &cxt->phase );
    172 
    173    if ( (int)cxt->sc_end_pos >= 0 )
    174    {
    175       cxt->sc_end_pos -= boff;
    176 
    177       /* have not fully finished the buffer */
    178       if ( cxt->sc_end_pos < cxt->size )
    179          cxt->phase++;
    180 
    181       retval = 1;
    182    }
    183    else
    184    {
    185       /* No startcode found */
    186    }
    187 
    188    return(retval);
    189 }
    190 #endif
    191