Mercurial > libavcodec.hg
changeset 3818:6a737f2d852e libavcodec
Original Commit: r12 | ods15 | 2006-09-22 09:28:30 +0300 (Fri, 22 Sep 2006) | 5 lines
entry_t -> cb_entry_t
add float * dimentions, it will be needed for deciding the correct codebook entry
document blocksize
first steps to creating the context to be used
author | ods15 |
---|---|
date | Mon, 02 Oct 2006 05:55:33 +0000 |
parents | 3ca15f0d4882 |
children | 92063e9b6728 |
files | vorbis_enc.c |
diffstat | 1 files changed, 110 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/vorbis_enc.c Mon Oct 02 05:55:30 2006 +0000 +++ b/vorbis_enc.c Mon Oct 02 05:55:33 2006 +0000 @@ -37,18 +37,18 @@ typedef struct { int len; uint32_t codeword; -} entry_t; +} cb_entry_t; typedef struct { int nentries; - entry_t * entries; + cb_entry_t * entries; int ndimentions; float min; float delta; int seq_p; int lookup; - //float * dimentions; int * quantlist; + float * dimentions; } codebook_t; typedef struct { @@ -94,7 +94,7 @@ typedef struct { int channels; int sample_rate; - int blocksize[2]; + int blocksize[2]; // in (1<<n) format int ncodebooks; codebook_t * codebooks; @@ -112,6 +112,109 @@ vorbis_mode_t * modes; } venc_context_t; +static int cb_lookup_vals(int lookup, int dimentions, int entries) { + if (lookup == 1) { + int tmp, i; + for (tmp = 0; ; tmp++) { + int n = 1; + for (i = 0; i < dimentions; i++) n *= tmp; + if (n > entries) break; + } + return tmp - 1; + } else if (lookup == 2) return dimentions * entries; + return 0; +} + +static void ready_codebook(codebook_t * cb) { + int h[33] = { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + int i; + + for (i = 0; i < cb->nentries; i++) { + cb_entry_t * e = &cb->entries[i]; + int j = 0; + if (h[0]) h[0] = 0; + else for (j = e->len; !h[j]; j--) assert(j); + e->codeword = h[j]; + h[j] = 0; + for (j++; j <= e->len; j++) h[j] = e->codeword | (1 << (j - 1)); + } + for (i = 0; i < 33; i++) assert(!h[i]); + + if (!cb->lookup) 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); + 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]; + div *= vals; + } + } + } + +} + +static void create_vorbis_context(venc_context_t * venc, AVCodecContext * avccontext) { + codebook_t * cb; + int i; + + venc->channels = avccontext->channels; + venc->sample_rate = avccontext->sample_rate; + venc->blocksize[0] = venc->blocksize[1] = 8; + + venc->ncodebooks = 3; + venc->codebooks = av_malloc(sizeof(codebook_t) * venc->ncodebooks); + + // codebook 1 - floor1 book, values 0..255 + cb = &venc->codebooks[0]; + cb->nentries = 256; + cb->entries = av_malloc(sizeof(cb_entry_t) * cb->nentries); + for (i = 0; i < cb->nentries; i++) cb->entries[i].len = 8; + cb->ndimentions = 0; + cb->min = 0.; + cb->delta = 0.; + cb->seq_p = 0; + cb->lookup = 0; + cb->quantlist = NULL; + ready_codebook(cb); + + // codebook 2 - classbook, values 0..0, dimentions 200 + cb = &venc->codebooks[1]; + cb->nentries = 1; + cb->entries = av_malloc(sizeof(cb_entry_t) * cb->nentries); + for (i = 0; i < cb->nentries; i++) cb->entries[i].len = 1; + cb->ndimentions = 200; + cb->min = 0.; + cb->delta = 0.; + cb->seq_p = 0; + cb->lookup = 0; + cb->quantlist = NULL; + ready_codebook(cb); + + // codebook 3 - vector, for the residue, dimentions 1. values -32768..32767 + cb = &venc->codebooks[2]; + cb->nentries = 32767 - (-32768); + cb->entries = av_malloc(sizeof(cb_entry_t) * cb->nentries); + for (i = 0; i < cb->nentries; i++) cb->entries[i].len = 16; + cb->ndimentions = 1; + cb->min = -32768.; + cb->delta = 1.; + cb->seq_p = 0; + cb->lookup = 2; + cb->quantlist = av_malloc(sizeof(int) * cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries)); + for (i = 0; i < cb->nentries; i++) cb->quantlist[i] = i; + ready_codebook(cb); + +} + static inline int ilog(unsigned int a) { int i; for (i = 0; a >> i; i++); @@ -165,16 +268,8 @@ put_bits(pb, 4, cb->lookup); if (cb->lookup) { - int tmp, bits = ilog(cb->quantlist[0]); - - if (cb->lookup == 1) { - for (tmp = 0; ; tmp++) { - int n = 1; - for (i = 0; i < cb->ndimentions; i++) n *= tmp; - if (n > cb->nentries) break; - } - tmp--; - } else tmp = cb->ndimentions * cb->nentries; + int tmp = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); + int bits = ilog(cb->quantlist[0]); for (i = 1; i < tmp; i++) bits = FFMIN(bits, ilog(cb->quantlist[i])); @@ -360,8 +455,7 @@ { venc_context_t * venc = avccontext->priv_data; - venc->channels = avccontext->channels; - venc->sample_rate = avccontext->sample_rate; + create_vorbis_context(venc, avccontext); //if (avccontext->flags & CODEC_FLAG_QSCALE) avccontext->global_quality / (float)FF_QP2LAMBDA); else avccontext->bit_rate; //if(avccontext->cutoff > 0) cfreq = avccontext->cutoff / 1000.0;