📄 vorbis_enc.c
字号:
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 + -