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

📄 wavpack.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
        }        pos = (pos + 1) & 7;        if(s->joint)            L += (R -= (L >> 1));        crc = (crc * 3 + L) * 3 + R;        bit = (L & s->and) | s->or;        *dst++ = ((L + bit) << s->shift) - bit;        bit = (R & s->and) | s->or;        *dst++ = ((R + bit) << s->shift) - bit;        count++;    }while(!last && count < s->samples);    if(crc != s->CRC){        av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");        return -1;    }    return count * 2;}static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst){    int i, j, count = 0;    int last, t;    int A, S, T, bit;    int pos = 0;    uint32_t crc = 0xFFFFFFFF;    s->one = s->zero = s->zeroes = 0;    do{        T = wv_get_value(s, gb, s->median, &last);        S = 0;        if(last) break;        for(i = 0; i < s->terms; i++){            t = s->decorr[i].value;            if(t > 8){                if(t & 1)                    A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];                else                    A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;                s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];                j = 0;            }else{                A = s->decorr[i].samplesA[pos];                j = (pos + t) & 7;            }            S = T + ((s->decorr[i].weightA * A + 512) >> 10);            if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;            s->decorr[i].samplesA[j] = T = S;        }        pos = (pos + 1) & 7;        crc = crc * 3 + S;        bit = (S & s->and) | s->or;        *dst++ = ((S + bit) << s->shift) - bit;        count++;    }while(!last && count < s->samples);    if(crc != s->CRC){        av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");        return -1;    }    return count;}static int wavpack_decode_init(AVCodecContext *avctx){    WavpackContext *s = avctx->priv_data;    s->avctx = avctx;    s->stereo = (avctx->channels == 2);    return 0;}static int wavpack_decode_frame(AVCodecContext *avctx,                            void *data, int *data_size,                            const uint8_t *buf, int buf_size){    WavpackContext *s = avctx->priv_data;    int16_t *samples = data;    int samplecount;    int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0;    const uint8_t* buf_end = buf + buf_size;    int i, j, id, size, ssize, weights, t;    if (buf_size == 0){        *data_size = 0;        return 0;    }    memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));    memset(s->median, 0, sizeof(s->median));    s->and = s->or = s->shift = 0;    s->samples = AV_RL32(buf); buf += 4;    if(!s->samples){        *data_size = 0;        return buf_size;    }    /* should not happen but who knows */    if(s->samples * 2 * avctx->channels > *data_size){        av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n");        return -1;    }    s->stereo_in = (AV_RL32(buf) & WV_FALSE_STEREO) ? 0 : s->stereo;    s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4;    s->CRC = AV_RL32(buf); buf += 4;    // parse metadata blocks    while(buf < buf_end){        id = *buf++;        size = *buf++;        if(id & WP_IDF_LONG) {            size |= (*buf++) << 8;            size |= (*buf++) << 16;        }        size <<= 1; // size is specified in words        ssize = size;        if(id & WP_IDF_ODD) size--;        if(size < 0){            av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size);            break;        }        if(buf + ssize > buf_end){            av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size);            break;        }        if(id & WP_IDF_IGNORE){            buf += ssize;            continue;        }        switch(id & WP_IDF_MASK){        case WP_ID_DECTERMS:            s->terms = size;            if(s->terms > MAX_TERMS){                av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");                buf += ssize;                continue;            }            for(i = 0; i < s->terms; i++) {                s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5;                s->decorr[s->terms - i - 1].delta = *buf >> 5;                buf++;            }            got_terms = 1;            break;        case WP_ID_DECWEIGHTS:            if(!got_terms){                av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");                continue;            }            weights = size >> s->stereo_in;            if(weights > MAX_TERMS || weights > s->terms){                av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");                buf += ssize;                continue;            }            for(i = 0; i < weights; i++) {                t = (int8_t)(*buf++);                s->decorr[s->terms - i - 1].weightA = t << 3;                if(s->decorr[s->terms - i - 1].weightA > 0)                    s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7;                if(s->stereo_in){                    t = (int8_t)(*buf++);                    s->decorr[s->terms - i - 1].weightB = t << 3;                    if(s->decorr[s->terms - i - 1].weightB > 0)                        s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7;                }            }            got_weights = 1;            break;        case WP_ID_DECSAMPLES:            if(!got_terms){                av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");                continue;            }            t = 0;            for(i = s->terms - 1; (i >= 0) && (t < size); i--) {                if(s->decorr[i].value > 8){                    s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;                    s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2;                    if(s->stereo_in){                        s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;                        s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2;                        t += 4;                    }                    t += 4;                }else if(s->decorr[i].value < 0){                    s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;                    s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;                    t += 4;                }else{                    for(j = 0; j < s->decorr[i].value; j++){                        s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2;                        if(s->stereo_in){                            s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;                        }                    }                    t += s->decorr[i].value * 2 * (s->stereo_in + 1);                }            }            got_samples = 1;            break;        case WP_ID_ENTROPY:            if(size != 6 * (s->stereo_in + 1)){                av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size);                buf += ssize;                continue;            }            for(i = 0; i < 3 * (s->stereo_in + 1); i++){                s->median[i] = wp_exp2(AV_RL16(buf));                buf += 2;            }            got_entropy = 1;            break;        case WP_ID_INT32INFO:            if(size != 4 || *buf){                av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf);                buf += ssize;                continue;            }            if(buf[1])                s->shift = buf[1];            else if(buf[2]){                s->and = s->or = 1;                s->shift = buf[2];            }else if(buf[3]){                s->and = 1;                s->shift = buf[3];            }            buf += 4;            break;        case WP_ID_DATA:            init_get_bits(&s->gb, buf, size * 8);            s->data_size = size * 8;            buf += size;            got_bs = 1;            break;        default:            buf += size;        }        if(id & WP_IDF_ODD) buf++;    }    if(!got_terms){        av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");        return -1;    }    if(!got_weights){        av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");        return -1;    }    if(!got_samples){        av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");        return -1;    }    if(!got_entropy){        av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");        return -1;    }    if(!got_bs){        av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");        return -1;    }    if(s->stereo_in)        samplecount = wv_unpack_stereo(s, &s->gb, samples);    else{        samplecount = wv_unpack_mono(s, &s->gb, samples);        if(s->stereo){            int16_t *dst = samples + samplecount * 2;            int16_t *src = samples + samplecount;            int cnt = samplecount;            while(cnt--){                *--dst = *--src;                *--dst = *src;            }            samplecount *= 2;        }    }    *data_size = samplecount * 2;    return buf_size;}AVCodec wavpack_decoder = {    "wavpack",    CODEC_TYPE_AUDIO,    CODEC_ID_WAVPACK,    sizeof(WavpackContext),    wavpack_decode_init,    NULL,    NULL,    wavpack_decode_frame,};

⌨️ 快捷键说明

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