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

📄 vorbis_enc.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org> * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file vorbis_enc.c * Native Vorbis encoder. * @author Oded Shimon <ods15@ods15.dyndns.org> */#include <float.h>#include "avcodec.h"#include "dsputil.h"#include "vorbis.h"#include "vorbis_enc_data.h"#undef NDEBUG#include <assert.h>typedef struct {    int nentries;    uint8_t * lens;    uint32_t * codewords;    int ndimentions;    float min;    float delta;    int seq_p;    int lookup;    int * quantlist;    float * dimentions;    float * pow2;} codebook_t;typedef struct {    int dim;    int subclass;    int masterbook;    int * books;} floor_class_t;typedef struct {    int partitions;    int * partition_to_class;    int nclasses;    floor_class_t * classes;    int multiplier;    int rangebits;    int values;    floor1_entry_t * list;} floor_t;typedef struct {    int type;    int begin;    int end;    int partition_size;    int classifications;    int classbook;    int8_t (*books)[8];    float (*maxes)[2];} residue_t;typedef struct {    int submaps;    int * mux;    int * floor;    int * residue;    int coupling_steps;    int * magnitude;    int * angle;} mapping_t;typedef struct {    int blockflag;    int mapping;} vorbis_mode_t;typedef struct {    int channels;    int sample_rate;    int log2_blocksize[2];    MDCTContext mdct[2];    const float * win[2];    int have_saved;    float * saved;    float * samples;    float * floor; // also used for tmp values for mdct    float * coeffs; // also used for residue after floor    float quality;    int ncodebooks;    codebook_t * codebooks;    int nfloors;    floor_t * floors;    int nresidues;    residue_t * residues;    int nmappings;    mapping_t * mappings;    int nmodes;    vorbis_mode_t * modes;} venc_context_t;typedef struct {    int total;    int total_pos;    int pos;    uint8_t * buf_ptr;} PutBitContext;static inline void init_put_bits(PutBitContext * pb, uint8_t * buf, int buffer_len) {    pb->total = buffer_len * 8;    pb->total_pos = 0;    pb->pos = 0;    pb->buf_ptr = buf;}static void put_bits(PutBitContext * pb, int bits, uint64_t val) {    if ((pb->total_pos += bits) >= pb->total) return;    if (!bits) return;    if (pb->pos) {        if (pb->pos > bits) {            *pb->buf_ptr |= val << (8 - pb->pos);            pb->pos -= bits;            bits = 0;        } else {            *pb->buf_ptr++ |= (val << (8 - pb->pos)) & 0xFF;            val >>= pb->pos;            bits -= pb->pos;            pb->pos = 0;        }    }    for (; bits >= 8; bits -= 8) {        *pb->buf_ptr++ = val & 0xFF;        val >>= 8;    }    if (bits) {        *pb->buf_ptr = val;        pb->pos = 8 - bits;    }}static inline void flush_put_bits(PutBitContext * pb) {}static inline int put_bits_count(PutBitContext * pb) {    return pb->total_pos;}static inline void put_codeword(PutBitContext * pb, codebook_t * cb, int entry) {    assert(entry >= 0);    assert(entry < cb->nentries);    assert(cb->lens[entry]);    put_bits(pb, cb->lens[entry], cb->codewords[entry]);}static int cb_lookup_vals(int lookup, int dimentions, int entries) {    if      (lookup == 1) return ff_vorbis_nth_root(entries, dimentions);    else if (lookup == 2) return dimentions * entries;    return 0;}static void ready_codebook(codebook_t * cb) {    int i;    ff_vorbis_len2vlc(cb->lens, cb->codewords, cb->nentries);    if (!cb->lookup)        cb->pow2 = cb->dimentions = NULL;    else {        int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries);        cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions);        cb->pow2 = av_mallocz(sizeof(float) * cb->nentries);        for (i = 0; i < cb->nentries; i++) {            float last = 0;            int j;            int div = 1;            for (j = 0; j < cb->ndimentions; j++) {                int off;                if (cb->lookup == 1)                    off = (i / div) % vals; // lookup type 1                else                    off = i * cb->ndimentions + j; // lookup type 2                cb->dimentions[i * cb->ndimentions + j] = last + cb->min + cb->quantlist[off] * cb->delta;                if (cb->seq_p)                    last = cb->dimentions[i * cb->ndimentions + j];                cb->pow2[i] += cb->dimentions[i * cb->ndimentions + j]*cb->dimentions[i * cb->ndimentions + j];                div *= vals;            }            cb->pow2[i] /= 2.;        }    }}static void ready_residue(residue_t * rc, venc_context_t * venc) {    int i;    assert(rc->type == 2);    rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications);    for (i = 0; i < rc->classifications; i++) {        int j;        codebook_t * cb;        for (j = 0; j < 8; j++)            if (rc->books[i][j] != -1) break;        if (j == 8) continue; // zero        cb = &venc->codebooks[rc->books[i][j]];        assert(cb->ndimentions >= 2);        assert(cb->lookup);        for (j = 0; j < cb->nentries; j++) {            float a;            if (!cb->lens[j]) continue;            a = fabs(cb->dimentions[j * cb->ndimentions]);            if (a > rc->maxes[i][0])                rc->maxes[i][0] = a;            a = fabs(cb->dimentions[j * cb->ndimentions + 1]);            if (a > rc->maxes[i][1])                rc->maxes[i][1] = a;        }    }    // small bias    for (i = 0; i < rc->classifications; i++) {        rc->maxes[i][0] += 0.8;        rc->maxes[i][1] += 0.8;    }}static void create_vorbis_context(venc_context_t * venc, AVCodecContext * avccontext) {    floor_t * fc;    residue_t * rc;    mapping_t * mc;    int i, book;    venc->channels = avccontext->channels;    venc->sample_rate = avccontext->sample_rate;    venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11;    venc->ncodebooks = sizeof(cvectors)/sizeof(cvectors[0]);    venc->codebooks = av_malloc(sizeof(codebook_t) * venc->ncodebooks);    // codebook 0..14 - floor1 book, values 0..255    // codebook 15 residue masterbook    // codebook 16..29 residue    for (book = 0; book < venc->ncodebooks; book++) {        codebook_t * cb = &venc->codebooks[book];        int vals;        cb->ndimentions = cvectors[book].dim;        cb->nentries = cvectors[book].real_len;        cb->min = cvectors[book].min;        cb->delta = cvectors[book].delta;        cb->lookup = cvectors[book].lookup;        cb->seq_p = 0;        cb->lens = av_malloc(sizeof(uint8_t) * cb->nentries);        cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries);        memcpy(cb->lens, cvectors[book].clens, cvectors[book].len);        memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len);        if (cb->lookup) {            vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries);            cb->quantlist = av_malloc(sizeof(int) * vals);            for (i = 0; i < vals; i++)                cb->quantlist[i] = cvectors[book].quant[i];        } else {            cb->quantlist = NULL;        }        ready_codebook(cb);    }    venc->nfloors = 1;    venc->floors = av_malloc(sizeof(floor_t) * venc->nfloors);    // just 1 floor    fc = &venc->floors[0];    fc->partitions = 8;    fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions);    fc->nclasses = 0;    for (i = 0; i < fc->partitions; i++) {        static const int a[] = {0,1,2,2,3,3,4,4};        fc->partition_to_class[i] = a[i];        fc->nclasses = FFMAX(fc->nclasses, fc->partition_to_class[i]);    }    fc->nclasses++;    fc->classes = av_malloc(sizeof(floor_class_t) * fc->nclasses);    for (i = 0; i < fc->nclasses; i++) {        floor_class_t * c = &fc->classes[i];        int j, books;        c->dim = floor_classes[i].dim;        c->subclass = floor_classes[i].subclass;        c->masterbook = floor_classes[i].masterbook;        books = (1 << c->subclass);        c->books = av_malloc(sizeof(int) * books);        for (j = 0; j < books; j++)            c->books[j] = floor_classes[i].nbooks[j];    }    fc->multiplier = 2;    fc->rangebits = venc->log2_blocksize[0] - 1;    fc->values = 2;    for (i = 0; i < fc->partitions; i++)        fc->values += fc->classes[fc->partition_to_class[i]].dim;    fc->list = av_malloc(sizeof(floor1_entry_t) * fc->values);    fc->list[0].x = 0;    fc->list[1].x = 1 << fc->rangebits;    for (i = 2; i < fc->values; i++) {        static const int a[] = {             93, 23,372,  6, 46,186,750, 14, 33, 65,            130,260,556,  3, 10, 18, 28, 39, 55, 79,            111,158,220,312,464,650,850        };        fc->list[i].x = a[i - 2];    }    ff_vorbis_ready_floor1_list(fc->list, fc->values);    venc->nresidues = 1;    venc->residues = av_malloc(sizeof(residue_t) * venc->nresidues);    // single residue    rc = &venc->residues[0];    rc->type = 2;    rc->begin = 0;    rc->end = 1600;    rc->partition_size = 32;    rc->classifications = 10;    rc->classbook = 15;    rc->books = av_malloc(sizeof(*rc->books) * rc->classifications);    {        static const int8_t a[10][8] = {            { -1, -1, -1, -1, -1, -1, -1, -1, },            { -1, -1, 16, -1, -1, -1, -1, -1, },            { -1, -1, 17, -1, -1, -1, -1, -1, },            { -1, -1, 18, -1, -1, -1, -1, -1, },            { -1, -1, 19, -1, -1, -1, -1, -1, },            { -1, -1, 20, -1, -1, -1, -1, -1, },            { -1, -1, 21, -1, -1, -1, -1, -1, },            { 22, 23, -1, -1, -1, -1, -1, -1, },            { 24, 25, -1, -1, -1, -1, -1, -1, },            { 26, 27, 28, -1, -1, -1, -1, -1, },        };        memcpy(rc->books, a, sizeof a);    }    ready_residue(rc, venc);

⌨️ 快捷键说明

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