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

📄 vorbis_enc.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 3 页
字号:
    venc->nmappings = 1;    venc->mappings = av_malloc(sizeof(mapping_t) * venc->nmappings);    // single mapping    mc = &venc->mappings[0];    mc->submaps = 1;    mc->mux = av_malloc(sizeof(int) * venc->channels);    for (i = 0; i < venc->channels; i++)        mc->mux[i] = 0;    mc->floor = av_malloc(sizeof(int) * mc->submaps);    mc->residue = av_malloc(sizeof(int) * mc->submaps);    for (i = 0; i < mc->submaps; i++) {        mc->floor[i] = 0;        mc->residue[i] = 0;    }    mc->coupling_steps = venc->channels == 2 ? 1 : 0;    mc->magnitude = av_malloc(sizeof(int) * mc->coupling_steps);    mc->angle = av_malloc(sizeof(int) * mc->coupling_steps);    if (mc->coupling_steps) {        mc->magnitude[0] = 0;        mc->angle[0] = 1;    }    venc->nmodes = 1;    venc->modes = av_malloc(sizeof(vorbis_mode_t) * venc->nmodes);    // single mode    venc->modes[0].blockflag = 0;    venc->modes[0].mapping = 0;    venc->have_saved = 0;    venc->saved = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);    venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]));    venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);    venc->coeffs = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);    venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6];    venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6];    ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0);    ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0);}static void put_float(PutBitContext * pb, float f) {    int exp, mant;    uint32_t res = 0;    mant = (int)ldexp(frexp(f, &exp), 20);    exp += 788 - 20;    if (mant < 0) { res |= (1 << 31); mant = -mant; }    res |= mant | (exp << 21);    put_bits(pb, 32, res);}static void put_codebook_header(PutBitContext * pb, codebook_t * cb) {    int i;    int ordered = 0;    put_bits(pb, 24, 0x564342); //magic    put_bits(pb, 16, cb->ndimentions);    put_bits(pb, 24, cb->nentries);    for (i = 1; i < cb->nentries; i++)        if (cb->lens[i] < cb->lens[i-1]) break;    if (i == cb->nentries)        ordered = 1;    put_bits(pb, 1, ordered);    if (ordered) {        int len = cb->lens[0];        put_bits(pb, 5, len - 1);        i = 0;        while (i < cb->nentries) {            int j;            for (j = 0; j+i < cb->nentries; j++)                if (cb->lens[j+i] != len) break;            put_bits(pb, ilog(cb->nentries - i), j);            i += j;            len++;        }    } else {        int sparse = 0;        for (i = 0; i < cb->nentries; i++)            if (!cb->lens[i]) break;        if (i != cb->nentries)            sparse = 1;        put_bits(pb, 1, sparse);        for (i = 0; i < cb->nentries; i++) {            if (sparse) put_bits(pb, 1, !!cb->lens[i]);            if (cb->lens[i]) put_bits(pb, 5, cb->lens[i] - 1);        }    }    put_bits(pb, 4, cb->lookup);    if (cb->lookup) {        int tmp = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries);        int bits = ilog(cb->quantlist[0]);        for (i = 1; i < tmp; i++)            bits = FFMAX(bits, ilog(cb->quantlist[i]));        put_float(pb, cb->min);        put_float(pb, cb->delta);        put_bits(pb, 4, bits - 1);        put_bits(pb, 1, cb->seq_p);        for (i = 0; i < tmp; i++)            put_bits(pb, bits, cb->quantlist[i]);    }}static void put_floor_header(PutBitContext * pb, floor_t * fc) {    int i;    put_bits(pb, 16, 1); // type, only floor1 is supported    put_bits(pb, 5, fc->partitions);    for (i = 0; i < fc->partitions; i++)        put_bits(pb, 4, fc->partition_to_class[i]);    for (i = 0; i < fc->nclasses; i++) {        int j, books;        put_bits(pb, 3, fc->classes[i].dim - 1);        put_bits(pb, 2, fc->classes[i].subclass);        if (fc->classes[i].subclass)            put_bits(pb, 8, fc->classes[i].masterbook);        books = (1 << fc->classes[i].subclass);        for (j = 0; j < books; j++)            put_bits(pb, 8, fc->classes[i].books[j] + 1);    }    put_bits(pb, 2, fc->multiplier - 1);    put_bits(pb, 4, fc->rangebits);    for (i = 2; i < fc->values; i++)        put_bits(pb, fc->rangebits, fc->list[i].x);}static void put_residue_header(PutBitContext * pb, residue_t * rc) {    int i;    put_bits(pb, 16, rc->type);    put_bits(pb, 24, rc->begin);    put_bits(pb, 24, rc->end);    put_bits(pb, 24, rc->partition_size - 1);    put_bits(pb, 6, rc->classifications - 1);    put_bits(pb, 8, rc->classbook);    for (i = 0; i < rc->classifications; i++) {        int j, tmp = 0;        for (j = 0; j < 8; j++)            tmp |= (rc->books[i][j] != -1) << j;        put_bits(pb, 3, tmp & 7);        put_bits(pb, 1, tmp > 7);        if (tmp > 7)            put_bits(pb, 5, tmp >> 3);    }    for (i = 0; i < rc->classifications; i++) {        int j;        for (j = 0; j < 8; j++)            if (rc->books[i][j] != -1)                put_bits(pb, 8, rc->books[i][j]);    }}static int put_main_header(venc_context_t * venc, uint8_t ** out) {    int i;    PutBitContext pb;    uint8_t buffer[50000] = {0}, * p = buffer;    int buffer_len = sizeof buffer;    int len, hlens[3];    // identification header    init_put_bits(&pb, p, buffer_len);    put_bits(&pb, 8, 1); //magic    for (i = 0; "vorbis"[i]; i++)        put_bits(&pb, 8, "vorbis"[i]);    put_bits(&pb, 32, 0); // version    put_bits(&pb, 8, venc->channels);    put_bits(&pb, 32, venc->sample_rate);    put_bits(&pb, 32, 0); // bitrate    put_bits(&pb, 32, 0); // bitrate    put_bits(&pb, 32, 0); // bitrate    put_bits(&pb, 4, venc->log2_blocksize[0]);    put_bits(&pb, 4, venc->log2_blocksize[1]);    put_bits(&pb, 1, 1); // framing    flush_put_bits(&pb);    hlens[0] = (put_bits_count(&pb) + 7) / 8;    buffer_len -= hlens[0];    p += hlens[0];    // comment header    init_put_bits(&pb, p, buffer_len);    put_bits(&pb, 8, 3); //magic    for (i = 0; "vorbis"[i]; i++)        put_bits(&pb, 8, "vorbis"[i]);    put_bits(&pb, 32, 0); // vendor length TODO    put_bits(&pb, 32, 0); // amount of comments    put_bits(&pb, 1, 1); // framing    flush_put_bits(&pb);    hlens[1] = (put_bits_count(&pb) + 7) / 8;    buffer_len -= hlens[1];    p += hlens[1];    // setup header    init_put_bits(&pb, p, buffer_len);    put_bits(&pb, 8, 5); //magic    for (i = 0; "vorbis"[i]; i++)        put_bits(&pb, 8, "vorbis"[i]);    // codebooks    put_bits(&pb, 8, venc->ncodebooks - 1);    for (i = 0; i < venc->ncodebooks; i++)        put_codebook_header(&pb, &venc->codebooks[i]);    // time domain, reserved, zero    put_bits(&pb, 6, 0);    put_bits(&pb, 16, 0);    // floors    put_bits(&pb, 6, venc->nfloors - 1);    for (i = 0; i < venc->nfloors; i++)        put_floor_header(&pb, &venc->floors[i]);    // residues    put_bits(&pb, 6, venc->nresidues - 1);    for (i = 0; i < venc->nresidues; i++)        put_residue_header(&pb, &venc->residues[i]);    // mappings    put_bits(&pb, 6, venc->nmappings - 1);    for (i = 0; i < venc->nmappings; i++) {        mapping_t * mc = &venc->mappings[i];        int j;        put_bits(&pb, 16, 0); // mapping type        put_bits(&pb, 1, mc->submaps > 1);        if (mc->submaps > 1)            put_bits(&pb, 4, mc->submaps - 1);        put_bits(&pb, 1, !!mc->coupling_steps);        if (mc->coupling_steps) {            put_bits(&pb, 8, mc->coupling_steps - 1);            for (j = 0; j < mc->coupling_steps; j++) {                put_bits(&pb, ilog(venc->channels - 1), mc->magnitude[j]);                put_bits(&pb, ilog(venc->channels - 1), mc->angle[j]);            }        }        put_bits(&pb, 2, 0); // reserved        if (mc->submaps > 1)            for (j = 0; j < venc->channels; j++)                put_bits(&pb, 4, mc->mux[j]);        for (j = 0; j < mc->submaps; j++) {            put_bits(&pb, 8, 0); // reserved time configuration            put_bits(&pb, 8, mc->floor[j]);            put_bits(&pb, 8, mc->residue[j]);        }    }    // modes    put_bits(&pb, 6, venc->nmodes - 1);    for (i = 0; i < venc->nmodes; i++) {        put_bits(&pb, 1, venc->modes[i].blockflag);        put_bits(&pb, 16, 0); // reserved window type        put_bits(&pb, 16, 0); // reserved transform type        put_bits(&pb, 8, venc->modes[i].mapping);    }    put_bits(&pb, 1, 1); // framing    flush_put_bits(&pb);    hlens[2] = (put_bits_count(&pb) + 7) / 8;    len = hlens[0] + hlens[1] + hlens[2];    p = *out = av_mallocz(64 + len + len/255);    *p++ = 2;    p += av_xiphlacing(p, hlens[0]);    p += av_xiphlacing(p, hlens[1]);    buffer_len = 0;    for (i = 0; i < 3; i++) {        memcpy(p, buffer + buffer_len, hlens[i]);        p += hlens[i];        buffer_len += hlens[i];    }    return p - *out;}static float get_floor_average(floor_t * fc, float * coeffs, int i) {    int begin = fc->list[fc->list[FFMAX(i-1, 0)].sort].x;    int end   = fc->list[fc->list[FFMIN(i+1, fc->values - 1)].sort].x;    int j;    float average = 0;    for (j = begin; j < end; j++)        average += fabs(coeffs[j]);    return average / (end - begin);}static void floor_fit(venc_context_t * venc, floor_t * fc, float * coeffs, uint_fast16_t * posts, int samples) {    int range = 255 / fc->multiplier + 1;    int i;    float tot_average = 0.;    float averages[fc->values];    for (i = 0; i < fc->values; i++){        averages[i] = get_floor_average(fc, coeffs, i);        tot_average += averages[i];    }    tot_average /= fc->values;    tot_average /= venc->quality;    for (i = 0; i < fc->values; i++) {        int position = fc->list[fc->list[i].sort].x;        float average = averages[i];        int j;        average *= pow(tot_average / average, 0.5) * pow(1.25, position/200.); // MAGIC!        for (j = 0; j < range - 1; j++)            if (ff_vorbis_floor1_inverse_db_table[j * fc->multiplier] > average) break;        posts[fc->list[i].sort] = j;    }}static int render_point(int x0, int y0, int x1, int y1, int x) {    return y0 +  (x - x0) * (y1 - y0) / (x1 - x0);}static void floor_encode(venc_context_t * venc, floor_t * fc, PutBitContext * pb, uint_fast16_t * posts, float * floor, int samples) {    int range = 255 / fc->multiplier + 1;    int coded[fc->values]; // first 2 values are unused    int i, counter;    put_bits(pb, 1, 1); // non zero    put_bits(pb, ilog(range - 1), posts[0]);    put_bits(pb, ilog(range - 1), posts[1]);    coded[0] = coded[1] = 1;    for (i = 2; i < fc->values; i++) {        int predicted = render_point(fc->list[fc->list[i].low].x,                                     posts[fc->list[i].low],                                     fc->list[fc->list[i].high].x,                                     posts[fc->list[i].high],                                     fc->list[i].x);        int highroom = range - predicted;        int lowroom = predicted;        int room = FFMIN(highroom, lowroom);        if (predicted == posts[i]) {

⌨️ 快捷键说明

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