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

📄 cook.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
    if(bits_left > q->samples_per_channel) {        bits_left = q->samples_per_channel +                    ((bits_left - q->samples_per_channel)*5)/8;        //av_log(NULL, AV_LOG_ERROR, "bits_left = %d\n",bits_left);    }    memset(&exp_index1,0,102*sizeof(int));    memset(&exp_index2,0,102*sizeof(int));    memset(&tmp_categorize_array1,0,128*sizeof(int));    memset(&tmp_categorize_array2,0,128*sizeof(int));    bias=-32;    /* Estimate bias. */    for (i=32 ; i>0 ; i=i/2){        num_bits = 0;        index = 0;        for (j=q->total_subbands ; j>0 ; j--){            exp_idx = (i - quant_index_table[index] + bias) / 2;            if (exp_idx<0){                exp_idx=0;            } else if(exp_idx >7) {                exp_idx=7;            }            index++;            num_bits+=expbits_tab[exp_idx];        }        if(num_bits >= bits_left - 32){            bias+=i;        }    }    /* Calculate total number of bits. */    num_bits=0;    for (i=0 ; i<q->total_subbands ; i++) {        exp_idx = (bias - quant_index_table[i]) / 2;        if (exp_idx<0) {            exp_idx=0;        } else if(exp_idx >7) {            exp_idx=7;        }        num_bits += expbits_tab[exp_idx];        exp_index1[i] = exp_idx;        exp_index2[i] = exp_idx;    }    tmpbias = bias = num_bits;    for (j = 1 ; j < q->numvector_size ; j++) {        if (tmpbias + bias > 2*bits_left) {  /* ---> */            int max = -999999;            index=-1;            for (i=0 ; i<q->total_subbands ; i++){                if (exp_index1[i] < 7) {                    v = (-2*exp_index1[i]) - quant_index_table[i] - 32;                    if ( v >= max) {                        max = v;                        index = i;                    }                }            }            if(index==-1)break;            tmp_categorize_array1[tmp_categorize_array1_idx++] = index;            tmpbias -= expbits_tab[exp_index1[index]] -                       expbits_tab[exp_index1[index]+1];            ++exp_index1[index];        } else {  /* <--- */            int min = 999999;            index=-1;            for (i=0 ; i<q->total_subbands ; i++){                if(exp_index2[i] > 0){                    v = (-2*exp_index2[i])-quant_index_table[i];                    if ( v < min) {                        min = v;                        index = i;                    }                }            }            if(index == -1)break;            tmp_categorize_array2[tmp_categorize_array2_idx++] = index;            tmpbias -= expbits_tab[exp_index2[index]] -                       expbits_tab[exp_index2[index]-1];            --exp_index2[index];        }    }    for(i=0 ; i<q->total_subbands ; i++)        category[i] = exp_index2[i];    /* Concatenate the two arrays. */    for(i=tmp_categorize_array2_idx-1 ; i >= 0; i--)        category_index[category_index_size++] =  tmp_categorize_array2[i];    for(i=0;i<tmp_categorize_array1_idx;i++)        category_index[category_index_size++ ] =  tmp_categorize_array1[i];    /* FIXME: mc_sich_ra8_20.rm triggers this, not sure with what we       should fill the remaining bytes. */    for(i=category_index_size;i<q->numvector_size;i++)        category_index[i]=0;}/** * Expand the category vector. * * @param q                     pointer to the COOKContext * @param category              pointer to the category array * @param category_index        pointer to the category_index array */static void inline expand_category(COOKContext *q, int* category,                                   int* category_index){    int i;    for(i=0 ; i<q->num_vectors ; i++){        ++category[category_index[i]];    }}/** * The real requantization of the mltcoefs * * @param q                     pointer to the COOKContext * @param index                 index * @param band                  current subband * @param quant_value_table     pointer to the array * @param subband_coef_index    array of indexes to quant_centroid_tab * @param subband_coef_noise    use random noise instead of predetermined value * @param mlt_buffer            pointer to the mlt buffer */static void scalar_dequant(COOKContext *q, int index, int band,                           float* quant_value_table, int* subband_coef_index,                           int* subband_coef_noise, float* mlt_buffer){    int i;    float f1;    for(i=0 ; i<SUBBAND_SIZE ; i++) {        if (subband_coef_index[i]) {            if (subband_coef_noise[i]) {                f1 = -quant_centroid_tab[index][subband_coef_index[i]];            } else {                f1 = quant_centroid_tab[index][subband_coef_index[i]];            }        } else {            /* noise coding if subband_coef_noise[i] == 0 */            q->random_state = q->random_state * 214013 + 2531011;    //typical RNG numbers            f1 = randsign[(q->random_state/0x1000000)&1] * dither_tab[index]; //>>31        }        mlt_buffer[band*20+ i] = f1 * quant_value_table[band];    }}/** * Unpack the subband_coef_index and subband_coef_noise vectors. * * @param q                     pointer to the COOKContext * @param category              pointer to the category array * @param subband_coef_index    array of indexes to quant_centroid_tab * @param subband_coef_noise    use random noise instead of predetermined value */static int unpack_SQVH(COOKContext *q, int category, int* subband_coef_index,                       int* subband_coef_noise) {    int i,j;    int vlc, vd ,tmp, result;    int ub;    int cb;    vd = vd_tab[category];    result = 0;    for(i=0 ; i<vpr_tab[category] ; i++){        ub = get_bits_count(&q->gb);        vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3);        cb = get_bits_count(&q->gb);        if (q->bits_per_subpacket < get_bits_count(&q->gb)){            vlc = 0;            result = 1;        }        for(j=vd-1 ; j>=0 ; j--){            tmp = (vlc * invradix_tab[category])/0x100000;            subband_coef_index[vd*i+j] = vlc - tmp * (kmax_tab[category]+1);            vlc = tmp;        }        for(j=0 ; j<vd ; j++){            if (subband_coef_index[i*vd + j]) {                if(get_bits_count(&q->gb) < q->bits_per_subpacket){                    subband_coef_noise[i*vd+j] = get_bits1(&q->gb);                } else {                    result=1;                    subband_coef_noise[i*vd+j]=0;                }            } else {                subband_coef_noise[i*vd+j]=0;            }        }    }    return result;}/** * Fill the mlt_buffer with mlt coefficients. * * @param q                 pointer to the COOKContext * @param category          pointer to the category array * @param quant_value_table pointer to the array * @param mlt_buffer        pointer to mlt coefficients */static void decode_vectors(COOKContext* q, int* category,                           float* quant_value_table, float* mlt_buffer){    /* A zero in this table means that the subband coefficient is       random noise coded. */    int subband_coef_noise[SUBBAND_SIZE];    /* A zero in this table means that the subband coefficient is a       positive multiplicator. */    int subband_coef_index[SUBBAND_SIZE];    int band, j;    int index=0;    for(band=0 ; band<q->total_subbands ; band++){        index = category[band];        if(category[band] < 7){            if(unpack_SQVH(q, category[band], subband_coef_index, subband_coef_noise)){                index=7;                for(j=0 ; j<q->total_subbands ; j++) category[band+j]=7;            }        }        if(index==7) {            memset(subband_coef_index, 0, sizeof(subband_coef_index));            memset(subband_coef_noise, 0, sizeof(subband_coef_noise));        }        scalar_dequant(q, index, band, quant_value_table, subband_coef_index,                       subband_coef_noise, mlt_buffer);    }    if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){        return;    }}/** * function for decoding mono data * * @param q                 pointer to the COOKContext * @param mlt_buffer1       pointer to left channel mlt coefficients * @param mlt_buffer2       pointer to right channel mlt coefficients */static void mono_decode(COOKContext *q, float* mlt_buffer) {    int category_index[128];    float quant_value_table[102];    int quant_index_table[102];    int category[128];    memset(&category, 0, 128*sizeof(int));    memset(&quant_value_table, 0, 102*sizeof(int));    memset(&category_index, 0, 128*sizeof(int));    decode_envelope(q, quant_index_table);    q->num_vectors = get_bits(&q->gb,q->log2_numvector_size);    dequant_envelope(q, quant_index_table, quant_value_table);    categorize(q, quant_index_table, category, category_index);    expand_category(q, category, category_index);    decode_vectors(q, category, quant_value_table, mlt_buffer);}/** * The modulated lapped transform, this takes transform coefficients * and transforms them into timedomain samples. This is done through * an FFT-based algorithm with pre- and postrotation steps. * A window and reorder step is also included. * * @param q                 pointer to the COOKContext * @param inbuffer          pointer to the mltcoefficients * @param outbuffer         pointer to the timedomain buffer * @param mlt_tmp           pointer to temporary storage space */static void cook_imlt(COOKContext *q, float* inbuffer, float* outbuffer,                      float* mlt_tmp){    int i;    /* prerotation */    for(i=0 ; i<q->mlt_size ; i+=2){        outbuffer[i] = (q->mlt_presin[i/2] * inbuffer[q->mlt_size-1-i]) +                       (q->mlt_precos[i/2] * inbuffer[i]);        outbuffer[i+1] = (q->mlt_precos[i/2] * inbuffer[q->mlt_size-1-i]) -                         (q->mlt_presin[i/2] * inbuffer[i]);    }    /* FFT */    ff_fft_permute(&q->fft_ctx, (FFTComplex *) outbuffer);    ff_fft_calc (&q->fft_ctx, (FFTComplex *) outbuffer);    /* postrotation */    for(i=0 ; i<q->mlt_size ; i+=2){        mlt_tmp[i] =               (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i+1]) +                                   (q->mlt_postcos[i/2] * outbuffer[i]);        mlt_tmp[q->mlt_size-1-i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i]) -                                   (q->mlt_postcos[i/2] * outbuffer[i+1]);    }    /* window and reorder */    for(i=0 ; i<q->mlt_size/2 ; i++){        outbuffer[i] = mlt_tmp[q->mlt_size/2-1-i] * q->mlt_window[i];        outbuffer[q->mlt_size-1-i]= mlt_tmp[q->mlt_size/2-1-i] *                                    q->mlt_window[q->mlt_size-1-i];        outbuffer[q->mlt_size+i]= mlt_tmp[q->mlt_size/2+i] *                                  q->mlt_window[q->mlt_size-1-i];        outbuffer[2*q->mlt_size-1-i]= -(mlt_tmp[q->mlt_size/2+i] *                                      q->mlt_window[i]);    }}/** * the actual requantization of the timedomain samples * * @param q                 pointer to the COOKContext * @param buffer            pointer to the timedomain buffer * @param gain_index        index for the block multiplier * @param gain_index_next   index for the next block multiplier */static void interpolate(COOKContext *q, float* buffer,                        int gain_index, int gain_index_next){    int i;    float fc1, fc2;    fc1 = q->pow2tab[gain_index+63];    if(gain_index == gain_index_next){              //static gain        for(i=0 ; i<q->gain_size_factor ; i++){            buffer[i]*=fc1;        }        return;    } else {                                        //smooth gain        fc2 = q->gain_table[11 + (gain_index_next-gain_index)];        for(i=0 ; i<q->gain_size_factor ; i++){            buffer[i]*=fc1;            fc1*=fc2;        }        return;    }}/** * timedomain requantization of the timedomain samples * * @param q                 pointer to the COOKContext * @param buffer            pointer to the timedomain buffer * @param gain_now          current gain structure * @param gain_previous     previous gain structure */static void gain_window(COOKContext *q, float* buffer, COOKgain* gain_now,                        COOKgain* gain_previous){    int i, index;    int gain_index[9];    int tmp_gain_index;    gain_index[8]=0;    index = gain_previous->size;    for (i=7 ; i>=0 ; i--) {        if(index && gain_previous->qidx_table1[index-1]==i) {            gain_index[i] = gain_previous->qidx_table2[index-1];            index--;        } else {            gain_index[i]=gain_index[i+1];        }    }    /* This is applied to the to be previous data buffer. */    for(i=0;i<8;i++){        interpolate(q, &buffer[q->samples_per_channel+q->gain_size_factor*i],                    gain_index[i], gain_index[i+1]);    }    tmp_gain_index = gain_index[0];    index = gain_now->size;    for (i=7 ; i>=0 ; i--) {        if(index && gain_now->qidx_table1[index-1]==i) {            gain_index[i]= gain_now->qidx_table2[index-1];            index--;        } else {            gain_index[i]=gain_index[i+1];        }    }    /* This is applied to the to be current block. */    for(i=0;i<8;i++){        interpolate(q, &buffer[i*q->gain_size_factor],                    tmp_gain_index+gain_index[i],                    tmp_gain_index+gain_index[i+1]);    }}/** * mlt overlapping and buffer management * * @param q                 pointer to the COOKContext * @param buffer            pointer to the timedomain buffer * @param gain_now          current gain structure * @param gain_previous     previous gain structure * @param previous_buffer   pointer to the previous buffer to be used for overlapping * */static void gain_compensate(COOKContext *q, float* buffer, COOKgain* gain_now,                            COOKgain* gain_previous, float* previous_buffer) {    int i;    if((gain_now->size  || gain_previous->size)) {        gain_window(q, buffer, gain_now, gain_previous);    }    /* Overlap with the previous block. */    for(i=0 ; i<q->samples_per_channel ; i++) buffer[i]+=previous_buffer[i];    /* Save away the current to be previous block. */    memcpy(previous_buffer, buffer+q->samples_per_channel,           sizeof(float)*q->samples_per_channel);}/** * function for getting the jointstereo coupling information * * @param q                 pointer to the COOKContext * @param decouple_tab      decoupling array * */

⌨️ 快捷键说明

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