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
18static 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 --------*/
43sc_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 --------*/
122sc_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}
156unsigned 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