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