📄 bitstream.c
字号:
cw_info[0].cw_offset = 0; for (i = 0; i < num_cw; i++) { cur_cw_len = 0; for (j = 0; j < num_data[i]; j++) { cur_cw_len += len[cur_data++]; } cw_info[i].num_data = num_data[i]; cw_info[i].cw_len = cur_cw_len; if (i > 0) /* calculate offset (codeword info parameter) */ cw_info[i].cw_offset = cw_info[i - 1].cw_offset + num_data[i - 1]; } /* presort codewords ------------------------------------------------ */ /* classify codewords first */ sfb_cnt = win_cnt = win_grp_cnt = coeff_cnt = last_sfb = acc_win_cnt = 0; cur_sfb_len = sfb_offset[1] / window_group_length[0]; cur_cb = coderInfo->book_vector[0]; for (i = 0; i < num_cw; i++) { /* Set codeword info parameters */ cw_info[i].cb = cur_cb; cw_info[i].num_sl_cw = (cur_cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN; cw_info[i].window = acc_win_cnt + win_cnt; cw_info[i].cw_nr = window_cw_cnt[cw_info[i].window]; window_cw_cnt[cw_info[i].window]++; coeff_cnt += cw_info[i].num_sl_cw; if (coeff_cnt - last_sfb >= cur_sfb_len) { last_sfb += cur_sfb_len; win_cnt++; /* next window */ if (win_cnt == window_group_length[win_grp_cnt]) { win_cnt = 0; sfb_cnt++; /* next sfb */ if (sfb_cnt == coderInfo->all_sfb) { sfb_cnt = 0; acc_win_cnt += window_group_length[win_grp_cnt]; win_grp_cnt++; /* next window group */ } /* new codebook and sfb length */ cur_cb = coderInfo->book_vector[sfb_cnt]; if (last_sfb < FRAME_LEN) { cur_sfb_len = (sfb_offset[sfb_cnt + 1] - sfb_offset[sfb_cnt]) / window_group_length[win_grp_cnt]; } } } } /* presorting (first presorting step) */ /* only needed for short windows *//* Somehow the second presorting step does not give expected results. Disabling the following code surprisingly gives good results. TODO: find the bug */ if (0) {//coderInfo->block_type == ONLY_SHORT_WINDOW) { for (i = 0; i < MAX_SHORT_WINDOWS; i++) window_cw_cnt[i] = 0; /* reset all counters */ win_cnt = 0; cw_cnt = 0; for (i = 0; i < num_cw; i++) { for (j = 0; j < num_cw; j++) { if (cw_info[j].window == win_cnt) { if (cw_info[j].cw_nr == window_cw_cnt[win_cnt]) { cw_info_preso[cw_cnt++] = cw_info[j]; window_cw_cnt[win_cnt]++; /* check if two one-dimensional codewords */ if (cw_info[j].num_sl_cw == PAIR_LEN) { cw_info_preso[cw_cnt++] = cw_info[j + 1]; window_cw_cnt[win_cnt]++; } win_cnt++; /* next window */ if (win_cnt == MAX_SHORT_WINDOWS) win_cnt = 0; } } } } } else { for (i = 0; i < num_cw; i++) { cw_info_preso[i] = cw_info[i]; /* just copy */ } } /* presorting (second presorting step) */ cw_cnt = 0; for (presort = 0; presort < LEN_PRESORT_CODEBOOK; presort++) { /* next codebook that has to be processed according to presorting */ unsigned short nextCB = PresortedCodebook_VCB11[presort]; for (i = 0; i < num_cw; i++) { /* process only codewords that are due now */ if ((cw_info_preso[i].cb == nextCB) || ((nextCB < ESC_HCB) && (cw_info_preso[i].cb == nextCB + 1))) { cw_info[cw_cnt++] = cw_info_preso[i]; } } } /* init segments */ accsegmsize = 0; for (i = 0; i < num_cw; i++) { /* 8.5.3.3.3.2 Derivation of segment width */ cursegmsize = min(maxCwLen[cw_info[i].cb], coderInfo->iLenLongestCW); if (accsegmsize + cursegmsize > coderInfo->iLenReordSpData) { /* the last segment is extended until iLenReordSpData */ segment[segmcnt - 1].right = coderInfo->iLenReordSpData - 1; segment[segmcnt - 1].len = coderInfo->iLenReordSpData - segment[segmcnt - 1].left; break; } segment[segmcnt].left = accsegmsize; segment[segmcnt].right = accsegmsize + cursegmsize - 1; segment[segmcnt++].len = cursegmsize; accsegmsize += cursegmsize; } /* store current bit position */ startbitpos = bitStream->currentBit; /* write write priority codewords (PCWs) and nonPCWs ---------------- */ num_sets = num_cw / segmcnt; /* number of sets */ for (set = 0; set <= num_sets; set++) { int trial; /* ever second set the bit order is reversed */ is_backwards = set % 2; for (trial = 0; trial < segmcnt; trial++) { int codewordBase; int set_encoded = segmcnt; if (set == num_sets) set_encoded = num_cw - set * segmcnt; /* last set is shorter than the rest */ for (codewordBase = 0; codewordBase < segmcnt; codewordBase++) { int segment_index = (trial + codewordBase) % segmcnt; int codeword_index = codewordBase + set * segmcnt; if (codeword_index >= num_cw) break; if ((cw_info[codeword_index].cw_len > 0) && (segment[segment_index].len > 0)) { /* codeword is not yet written (completely) */ /* space left in this segment */ short tmplen; /* how many bits can be written? */ if (segment[segment_index].len >= cw_info[codeword_index].cw_len) { tmplen = cw_info[codeword_index].cw_len; set_encoded--; /* CW fits into segment */ } else { tmplen = segment[segment_index].len; } /* Adjust lengths */ cw_info[codeword_index].cw_len -= tmplen; segment[segment_index].len -= tmplen; /* write codewords to bitstream */ for (cw_part_cnt = 0; cw_part_cnt < cw_info[codeword_index].num_data; cw_part_cnt++) { cur_cw_part = cw_info[codeword_index].cw_offset + cw_part_cnt; if (len[cur_cw_part] <= tmplen) { /* write complete data, no partitioning */ if (is_backwards) { /* write data in reversed bit-order */ PutBitHcr(bitStream, startbitpos + segment[segment_index].right - len[cur_cw_part] + 1, rewind_word(data[cur_cw_part], len[cur_cw_part]), len[cur_cw_part]); segment[segment_index].right -= len[cur_cw_part]; } else { PutBitHcr(bitStream, startbitpos + segment[segment_index].left, data[cur_cw_part], len[cur_cw_part]); segment[segment_index].left += len[cur_cw_part]; } tmplen -= len[cur_cw_part]; len[cur_cw_part] = 0; } else { /* codeword part must be partitioned */ /* data must be taken from the left side */ tmp_data = data[cur_cw_part]; diff = len[cur_cw_part] - tmplen; tmp_data >>= diff; /* remove bits which are already used */ data[cur_cw_part] &= (1 << diff) - 1 /* diff number of ones */; len[cur_cw_part] = diff; if (is_backwards) { /* write data in reversed bit-order */ PutBitHcr(bitStream, startbitpos + segment[segment_index].right - tmplen + 1, rewind_word(tmp_data, tmplen), tmplen); segment[segment_index].right -= tmplen; } else { PutBitHcr(bitStream, startbitpos + segment[segment_index].left, tmp_data, tmplen); segment[segment_index].left += tmplen; } tmplen = 0; } if (tmplen == 0) break; /* all data written for this segment trial */ } } } /* of codewordBase */ if (set_encoded == 0) break; /* no unencoded codewords left in this set */ } /* of trial */ } /* set parameter for bit stream to current correct position */ bitStream->currentBit = startbitpos + coderInfo->iLenReordSpData; bitStream->numBit = bitStream->currentBit; } return coderInfo->iLenReordSpData;}/* CRC8 x^8 + x^4 + x^3 + x^2 + 1*/static const unsigned char _crctable[256] ={ 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4};static void calc_CRC(BitStream *bitStream, int len){ //int i; //unsigned char r = ~0; /* Initialize to all ones */ unsigned char crc = ~0; /* Initialize to all ones */ /* CRC polynome used x^8 + x^4 + x^3 + x^2 +1 */ unsigned int cb = len / 8; unsigned int taillen = len & 0x7; unsigned char* pb = &bitStream->data[1]; //compatible, but slower unsigned char b = ( bitStream->data[cb + 1] ) >> ( 8 - taillen ); unsigned char b = bitStream->data[cb + 1]; //#define GPOLY 0435//// for (i = 8; i < len + 8; i++) {// r = ( (r << 1) ^ (( (// ( bitStream->data[i / 8] >> (7 - (i % 8)) )// & 1) ^ ((r >> 7) & 1)) * GPOLY )) & 0xFF;// }#define GP 0x1d//fprintf( stderr, "\nfaac:" ); while ( cb-- ) {//fprintf( stderr, " %02X", *pb ); crc = _crctable[ crc ^ *pb++ ]; } //compatible, but slower switch ( taillen ) //{ //case 7: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 6 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 6: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 5 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 5: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 4 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 4: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 3 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 3: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 2 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 2: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 1 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 1: // crc = ( ( crc << 1 ) ^ ( ( ( b & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // break; //}//fprintf( stderr, " %02X", ( b >> ( 8 - taillen ) ) << 7 ); switch ( taillen ) { case 7: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 6: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 5: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 4: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 3: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 2: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 1: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; break; } //if ( crc != r ) //{ // fprintf( stderr, "%08X != %08X\n", crc, r ); //}//fprintf( stderr, " (%5d bits), CRC is %02X\n", len, ~crc & 0xFF ); /* CRC is stored inverted, per definition at first byte in stream */ bitStream->data[0] = ~crc;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -