⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitstream.c

📁 mpeg4 video codec mpeg4 video codec
💻 C
📖 第 1 页 / 共 3 页
字号:
        }    }    for(i = 1; i < 8; i++){        grouping_bits = grouping_bits << 1;        if(tmp[i] == tmp[i-1]) {            grouping_bits++;        }    }    return grouping_bits;}/* size in bytes! */BitStream *OpenBitStream(int size, unsigned char *buffer){    BitStream *bitStream;    bitStream = AllocMemory(sizeof(BitStream));    bitStream->size = size;#ifdef DRM    /* skip first byte for CRC */    bitStream->numBit = 8;    bitStream->currentBit = 8;#else    bitStream->numBit = 0;    bitStream->currentBit = 0;#endif    bitStream->data = buffer;    SetMemory(bitStream->data, 0, size);    return bitStream;}int CloseBitStream(BitStream *bitStream){    int bytes = bit2byte(bitStream->numBit);    FreeMemory(bitStream);    return bytes;}static long BufferNumBit(BitStream *bitStream){    return bitStream->numBit;}static int WriteByte(BitStream *bitStream,                     unsigned long data,                     int numBit){    long numUsed,idx;    idx = (bitStream->currentBit / BYTE_NUMBIT) % bitStream->size;    numUsed = bitStream->currentBit % BYTE_NUMBIT;#ifndef DRM    if (numUsed == 0)        bitStream->data[idx] = 0;#endif    bitStream->data[idx] |= (data & ((1<<numBit)-1)) <<        (BYTE_NUMBIT-numUsed-numBit);    bitStream->currentBit += numBit;    bitStream->numBit = bitStream->currentBit;    return 0;}int PutBit(BitStream *bitStream,           unsigned long data,           int numBit){    int num,maxNum,curNum;    unsigned long bits;    if (numBit == 0)        return 0;    /* write bits in packets according to buffer byte boundaries */    num = 0;    maxNum = BYTE_NUMBIT - bitStream->currentBit % BYTE_NUMBIT;    while (num < numBit) {        curNum = min(numBit-num,maxNum);        bits = data>>(numBit-num-curNum);        if (WriteByte(bitStream, bits, curNum)) {            return 1;        }        num += curNum;        maxNum = BYTE_NUMBIT;    }    return 0;}static int ByteAlign(BitStream *bitStream, int writeFlag){    int len, i,j;    len = BufferNumBit(bitStream);    j = (8 - (len%8))%8;    if ((len % 8) == 0) j = 0;    if (writeFlag) {        for( i=0; i<j; i++ ) {            PutBit(bitStream, 0, 1);        }    }    return j;}#ifdef DRM/*    ****************************************************************************    The following code was written by Volker Fischer (c) 2004    The GNU Lesser General Public License as published by the    Free Software Foundation applies to this code.    *****************************************************************************/#define LEN_PRESORT_CODEBOOK 22static const unsigned short PresortedCodebook_VCB11[] = {11, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 9, 7, 5, 3, 1};static const int maxCwLen[32] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, 49,    0, 0, 0, 0, 14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41}; /* 8.5.3.3.3.1 */typedef struct { /* segment parameters */    unsigned int left; /* left start of free space in segment */    unsigned int right; /* right position of free space in segment */    unsigned int len; /* length of free space in segment */} segment_t;typedef struct { /* codeword parameters */    unsigned int   cw_offset; /* offset in actual codeword data vector */    unsigned short window; /* which window belongs to this codeword */    unsigned short cb; /* codebook */    unsigned short num_sl_cw; /* number of spectral lines per codeword */    unsigned int   cw_nr; /* codeword number in the window */    unsigned short cw_len; /* codeword lenght */    unsigned short num_data; /* number of data cells for codeword */} cw_info_t;static int PutBitHcr(BitStream *bitStream,                     unsigned long curpos,                     unsigned long data,                     int numBit){ /* data can be written at an arbitrary position in the bitstream */    bitStream->currentBit = curpos;    return PutBit(bitStream, data, numBit);}static int rewind_word(int W, int len){ /* rewind len (max. 32) bits so that the MSB becomes LSB */    short i;    int tmp_W = 0;    for (i = 0; i < len; i++) {        tmp_W <<= 1;        if (W & (1<<i)) tmp_W |= 1;    }    return tmp_W;}static int WriteReorderedSpectralData(CoderInfo *coderInfo,                                      BitStream *bitStream,                                      int writeFlag){    int i, j;    int cursegmsize, accsegmsize = 0;    int segmcnt = 0;    long startbitpos;    segment_t segment[FRAME_LEN];    int* window_group_length = coderInfo->window_group_length;    int* sfb_offset = coderInfo->sfb_offset;    cw_info_t cw_info[FRAME_LEN];    cw_info_t cw_info_preso[FRAME_LEN];    int num_cw = coderInfo->cur_cw;    int window_cw_cnt[MAX_SHORT_WINDOWS] = {0,0,0,0,0,0,0,0};    int presort, set, num_sets;    unsigned short cur_cb, cw_cnt;    short is_backwards;    int diff, tmp_data, cw_part_cnt, cur_cw_part;    int cur_cw_len, cur_data;    int sfb_cnt, win_cnt, acc_win_cnt, win_grp_cnt;    int coeff_cnt, last_sfb, cur_sfb_len;    /* set up local pointers to data and len */    /* data array contains data to be written */    /* len array contains lengths of data words */    int* data = coderInfo->data;    int* len  = coderInfo->len;    int* num_data = coderInfo->num_data_cw;    if (writeFlag) {        /* build offset table */        cur_data = 0;        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;}static void calc_CRC(BitStream *bitStream, int len){    int i;    unsigned char r = 255;  /* Initialize to all ones */    /* CRC polynome used x^8 + x^4 + x^3 + x^2 +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;    }    /* CRC is stored inverted, per definition at first byte in stream */    bitStream->data[0] = ~r;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -