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