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

📄 wmadec.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
                        nb_coefs[ch] -= s->exponent_high_bands[bsize][i];                }            }        }        for(ch = 0; ch < s->nb_channels; ch++) {            if (s->channel_coded[ch]) {                int i, n, val, code;                n = s->exponent_high_sizes[bsize];                val = (int)0x80000000;                for(i=0;i<n;i++) {                    if (s->high_band_coded[ch][i]) {                        if (val == (int)0x80000000) {                            val = get_bits(&s->gb, 7) - 19;                        } else {                            code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX);                            if (code < 0)                                return -1;                            val += code - 18;                        }                        s->high_band_values[ch][i] = val;                    }                }            }        }    }    /* exponents can be reused in short blocks. */    if ((s->block_len_bits == s->frame_len_bits) ||        get_bits1(&s->gb)) {        for(ch = 0; ch < s->nb_channels; ch++) {            if (s->channel_coded[ch]) {                if (s->use_exp_vlc) {                    if (decode_exp_vlc(s, ch) < 0)                        return -1;                } else {                    decode_exp_lsp(s, ch);                }                s->exponents_bsize[ch] = bsize;            }        }    }    /* parse spectral coefficients : just RLE encoding */    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            VLC *coef_vlc;            int level, run, sign, tindex;            int16_t *ptr, *eptr;            const uint16_t *level_table, *run_table;            /* special VLC tables are used for ms stereo because               there is potentially less energy there */            tindex = (ch == 1 && s->ms_stereo);            coef_vlc = &s->coef_vlc[tindex];            run_table = s->run_table[tindex];            level_table = s->level_table[tindex];            /* XXX: optimize */            ptr = &s->coefs1[ch][0];            eptr = ptr + nb_coefs[ch];            memset(ptr, 0, s->block_len * sizeof(int16_t));            for(;;) {                code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX);                if (code < 0)                    return -1;                if (code == 1) {                    /* EOB */                    break;                } else if (code == 0) {                    /* escape */                    level = get_bits(&s->gb, coef_nb_bits);                    /* NOTE: this is rather suboptimal. reading                       block_len_bits would be better */                    run = get_bits(&s->gb, s->frame_len_bits);                } else {                    /* normal code */                    run = run_table[code];                    level = level_table[code];                }                sign = get_bits1(&s->gb);                if (!sign)                    level = -level;                ptr += run;                if (ptr >= eptr)                {                    av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");                    break;                }                *ptr++ = level;                /* NOTE: EOB can be omitted */                if (ptr >= eptr)                    break;            }        }        if (s->version == 1 && s->nb_channels >= 2) {            align_get_bits(&s->gb);        }    }    /* normalize */    {        int n4 = s->block_len / 2;        mdct_norm = 1.0 / (float)n4;        if (s->version == 1) {            mdct_norm *= sqrt(n4);        }    }    /* finally compute the MDCT coefficients */    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            int16_t *coefs1;            float *coefs, *exponents, mult, mult1, noise;            int i, j, n, n1, last_high_band, esize;            float exp_power[HIGH_BAND_MAX_SIZE];            coefs1 = s->coefs1[ch];            exponents = s->exponents[ch];            esize = s->exponents_bsize[ch];            mult = pow(10, total_gain * 0.05) / s->max_exponent[ch];            mult *= mdct_norm;            coefs = s->coefs[ch];            if (s->use_noise_coding) {                mult1 = mult;                /* very low freqs : noise */                for(i = 0;i < s->coefs_start; i++) {                    *coefs++ = s->noise_table[s->noise_index] *                      exponents[i<<bsize>>esize] * mult1;                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                }                n1 = s->exponent_high_sizes[bsize];                /* compute power of high bands */                exponents = s->exponents[ch] +                    (s->high_band_start[bsize]<<bsize);                last_high_band = 0; /* avoid warning */                for(j=0;j<n1;j++) {                    n = s->exponent_high_bands[s->frame_len_bits -                                              s->block_len_bits][j];                    if (s->high_band_coded[ch][j]) {                        float e2, v;                        e2 = 0;                        for(i = 0;i < n; i++) {                            v = exponents[i<<bsize>>esize];                            e2 += v * v;                        }                        exp_power[j] = e2 / n;                        last_high_band = j;                        tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n);                    }                    exponents += n<<bsize;                }                /* main freqs and high freqs */                exponents = s->exponents[ch] + (s->coefs_start<<bsize);                for(j=-1;j<n1;j++) {                    if (j < 0) {                        n = s->high_band_start[bsize] -                            s->coefs_start;                    } else {                        n = s->exponent_high_bands[s->frame_len_bits -                                                  s->block_len_bits][j];                    }                    if (j >= 0 && s->high_band_coded[ch][j]) {                        /* use noise with specified power */                        mult1 = sqrt(exp_power[j] / exp_power[last_high_band]);                        /* XXX: use a table */                        mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05);                        mult1 = mult1 / (s->max_exponent[ch] * s->noise_mult);                        mult1 *= mdct_norm;                        for(i = 0;i < n; i++) {                            noise = s->noise_table[s->noise_index];                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                            *coefs++ =  noise *                                exponents[i<<bsize>>esize] * mult1;                        }                        exponents += n<<bsize;                    } else {                        /* coded values + small noise */                        for(i = 0;i < n; i++) {                            noise = s->noise_table[s->noise_index];                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                            *coefs++ = ((*coefs1++) + noise) *                                exponents[i<<bsize>>esize] * mult;                        }                        exponents += n<<bsize;                    }                }                /* very high freqs : noise */                n = s->block_len - s->coefs_end[bsize];                mult1 = mult * exponents[((-1<<bsize))>>esize];                for(i = 0; i < n; i++) {                    *coefs++ = s->noise_table[s->noise_index] * mult1;                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                }            } else {                /* XXX: optimize more */                for(i = 0;i < s->coefs_start; i++)                    *coefs++ = 0.0;                n = nb_coefs[ch];                for(i = 0;i < n; i++) {                    *coefs++ = coefs1[i] * exponents[i<<bsize>>esize] * mult;                }                n = s->block_len - s->coefs_end[bsize];                for(i = 0;i < n; i++)                    *coefs++ = 0.0;            }        }    }#ifdef TRACE    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            dump_floats(s, "exponents", 3, s->exponents[ch], s->block_len);            dump_floats(s, "coefs", 1, s->coefs[ch], s->block_len);        }    }#endif    if (s->ms_stereo && s->channel_coded[1]) {        float a, b;        int i;        /* nominal case for ms stereo: we do it before mdct */        /* no need to optimize this case because it should almost           never happen */        if (!s->channel_coded[0]) {            tprintf(s->avctx, "rare ms-stereo case happened\n");            memset(s->coefs[0], 0, sizeof(float) * s->block_len);            s->channel_coded[0] = 1;        }        for(i = 0; i < s->block_len; i++) {            a = s->coefs[0][i];            b = s->coefs[1][i];            s->coefs[0][i] = a + b;            s->coefs[1][i] = a - b;        }    }    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            int n4, index, n;            n = s->block_len;            n4 = s->block_len / 2;            s->mdct_ctx[bsize].fft.imdct_calc(&s->mdct_ctx[bsize],                          s->output, s->coefs[ch], s->mdct_tmp);            /* multiply by the window and add in the frame */            index = (s->frame_len / 2) + s->block_pos - n4;            wma_window(s, &s->frame_out[ch][index]);            /* specific fast case for ms-stereo : add to second               channel if it is not coded */            if (s->ms_stereo && !s->channel_coded[1]) {                wma_window(s, &s->frame_out[1][index]);            }        }    } next:    /* update block number */    s->block_num++;    s->block_pos += s->block_len;    if (s->block_pos >= s->frame_len)        return 1;    else        return 0;}/* decode a frame of frame_len samples */static int wma_decode_frame(WMACodecContext *s, int16_t *samples){    int ret, i, n, ch, incr;    int16_t *ptr;    float *iptr;#ifdef TRACE    tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len);#endif    /* read each block */    s->block_num = 0;    s->block_pos = 0;    for(;;) {        ret = wma_decode_block(s);        if (ret < 0)            return -1;        if (ret)            break;    }    /* convert frame to integer */    n = s->frame_len;    incr = s->nb_channels;    for(ch = 0; ch < s->nb_channels; ch++) {        ptr = samples + ch;        iptr = s->frame_out[ch];        for(i=0;i<n;i++) {            *ptr = av_clip_int16(lrintf(*iptr++));            ptr += incr;        }        /* prepare for next block */        memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len],                s->frame_len * sizeof(float));    }#ifdef TRACE    dump_shorts(s, "samples", samples, n * s->nb_channels);#endif    return 0;}static int wma_decode_superframe(AVCodecContext *avctx,                                 void *data, int *data_size,                                 const uint8_t *buf, int buf_size){    WMACodecContext *s = avctx->priv_data;    int nb_frames, bit_offset, i, pos, len;    uint8_t *q;    int16_t *samples;    tprintf(avctx, "***decode_superframe:\n");    if(buf_size==0){        s->last_superframe_len = 0;        return 0;    }    if (buf_size < s->block_align)        return 0;    buf_size = s->block_align;    samples = data;    init_get_bits(&s->gb, buf, buf_size*8);    if (s->use_bit_reservoir) {        /* read super frame header */        skip_bits(&s->gb, 4); /* super frame index */        nb_frames = get_bits(&s->gb, 4) - 1;        bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);        if (s->last_superframe_len > 0) {            //        printf("skip=%d\n", s->last_bitoffset);            /* add bit_offset bits to last frame */            if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) >                MAX_CODED_SUPERFRAME_SIZE)                goto fail;            q = s->last_superframe + s->last_superframe_len;            len = bit_offset;            while (len > 7) {                *q++ = (get_bits)(&s->gb, 8);                len -= 8;            }            if (len > 0) {                *q++ = (get_bits)(&s->gb, len) << (8 - len);            }            /* XXX: bit_offset bits into last frame */            init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8);            /* skip unused bits */            if (s->last_bitoffset > 0)                skip_bits(&s->gb, s->last_bitoffset);            /* this frame is stored in the last superframe and in the               current one */            if (wma_decode_frame(s, samples) < 0)                goto fail;            samples += s->nb_channels * s->frame_len;        }        /* read each frame starting from bit_offset */        pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3;        init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8);        len = pos & 7;        if (len > 0)            skip_bits(&s->gb, len);        s->reset_block_lengths = 1;        for(i=0;i<nb_frames;i++) {            if (wma_decode_frame(s, samples) < 0)                goto fail;            samples += s->nb_channels * s->frame_len;        }        /* we copy the end of the frame in the last frame buffer */        pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7);        s->last_bitoffset = pos & 7;        pos >>= 3;        len = buf_size - pos;        if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) {            goto fail;        }        s->last_superframe_len = len;        memcpy(s->last_superframe, buf + pos, len);    } else {        /* single frame decode */        if (wma_decode_frame(s, samples) < 0)            goto fail;        samples += s->nb_channels * s->frame_len;    }//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d outbytes:%d eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len,        (int8_t *)samples - (int8_t *)data, s->block_align);    *data_size = (int8_t *)samples - (int8_t *)data;    return s->block_align; fail:    /* when error, we reset the bit reservoir */    s->last_superframe_len = 0;    return -1;}AVCodec wmav1_decoder ={    "wmav1",    CODEC_TYPE_AUDIO,    CODEC_ID_WMAV1,    sizeof(WMACodecContext),    wma_decode_init,    NULL,    ff_wma_end,    wma_decode_superframe,};AVCodec wmav2_decoder ={    "wmav2",    CODEC_TYPE_AUDIO,    CODEC_ID_WMAV2,    sizeof(WMACodecContext),    wma_decode_init,    NULL,    ff_wma_end,    wma_decode_superframe,};

⌨️ 快捷键说明

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