• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /* Parse for Sc code of pattern 0x00 0x00 0xXX in the current buffer. Returns either sc found or success.
15    The conext is updated with current phase and sc_code position in the buffer.
16 */
viddec_parse_sc(void * in,void * pcxt,void * sc_state)17 uint32_t viddec_parse_sc(void *in, void *pcxt, void *sc_state)
18 {
19     uint8_t *ptr;
20     uint32_t size;
21     uint32_t data_left=0, phase = 0, ret = 0;
22     viddec_sc_parse_cubby_cxt_t *cxt;
23     /* What is phase?: phase is a value between [0-4], we keep track of consecutive '0's with this.
24        Any time a '0' is found its incremented by 1(uptp 2) and reset to '0' if a zero not found.
25        if 0xXX code is found and current phase is 2, its changed to 3 which means we found the pattern
26        we are looking for. Its incremented to 4 once we see a byte after this pattern */
27     cxt = ( viddec_sc_parse_cubby_cxt_t *)in;
28     size = 0;
29     data_left = cxt->size;
30     ptr = cxt->buf;
31     phase = cxt->phase;
32     cxt->sc_end_pos = -1;
33     pcxt=pcxt;
34 
35     /* parse until there is more data and start code not found */
36     while((data_left > 0) &&(phase < 3))
37     {
38         /* Check if we are byte aligned & phase=0, if thats the case we can check
39            work at a time instead of byte*/
40         if(((((uint32_t)ptr) & 0x3) == 0) && (phase == 0))
41         {
42             while(data_left > 3)
43             {
44                 uint32_t data;
45                 char mask1 = 0, mask2=0;
46 
47                 data = *((uint32_t *)ptr);
48 #ifndef MFDBIGENDIAN
49                 data = SWAP_WORD(data);
50 #endif
51                 mask1 = (FIRST_STARTCODE_BYTE != (data & SC_BYTE_MASK0));
52                 mask2 = (FIRST_STARTCODE_BYTE != (data & SC_BYTE_MASK1));
53                 /* If second byte and fourth byte are not zero's then we cannot have a start code here as we need
54                    two consecutive zero bytes for a start code pattern */
55                 if(mask1 && mask2)
56                 {/* Success so skip 4 bytes and start over */
57                     ptr+=4;size+=4;data_left-=4;
58                     continue;
59                 }
60                 else
61                 {
62                     break;
63                 }
64             }
65         }
66 
67         /* At this point either data is not on a word boundary or phase > 0 or On a word boundary but we detected
68            two zero bytes in the word so we look one byte at a time*/
69         if(data_left > 0)
70         {
71             if(*ptr == FIRST_STARTCODE_BYTE)
72             {/* Phase can be 3 only if third start code byte is found */
73                 phase++;
74                 ptr++;size++;data_left--;
75                 if(phase > 2)
76                 {
77                     phase = 2;
78 
79                     if ( (((uint32_t)ptr) & 0x3) == 0 )
80                     {
81                        while( data_left > 3 )
82                        {
83                            if(*((uint32_t *)ptr) != 0)
84                            {
85                                break;
86                            }
87                            ptr+=4;size+=4;data_left-=4;
88                        }
89                     }
90                 }
91             }
92             else
93             {
94                 if((*ptr == THIRD_STARTCODE_BYTE) && (phase == 2))
95                 {/* Match for start code so update context with byte position */
96                     phase = 3;
97                     cxt->sc_end_pos = size;
98                 }
99                 else
100                 {
101                     phase = 0;
102                 }
103                 ptr++;size++;data_left--;
104             }
105         }
106     }
107     if((data_left > 0) && (phase == 3))
108     {
109         viddec_sc_prefix_state_t *state = (viddec_sc_prefix_state_t *)sc_state;
110         cxt->sc_end_pos++;
111         state->next_sc = cxt->buf[cxt->sc_end_pos];
112         state->second_scprfx_length = 3;
113         phase++;
114         ret = 1;
115     }
116     cxt->phase = phase;
117     /* Return SC found only if phase is 4, else always success */
118     return ret;
119 }
120