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 /* 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 */
     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