The settings used for initializing the floor and residue codebooks are separated so that they aren't coupled for later changes for arbitrary channel configurations.
Signed-off-by: Tyler Jones <tdjones...@gmail.com> --- libavcodec/vorbis_enc_data.h | 112 ++++++++++++++++++----------- libavcodec/vorbisenc.c | 167 ++++++++++++++++++++++++------------------- 2 files changed, 166 insertions(+), 113 deletions(-) diff --git a/libavcodec/vorbis_enc_data.h b/libavcodec/vorbis_enc_data.h index eca43dfded..6f2b10feb9 100644 --- a/libavcodec/vorbis_enc_data.h +++ b/libavcodec/vorbis_enc_data.h @@ -23,6 +23,26 @@ #include <stdint.h> +typedef const struct { + int dim; + int len; + int real_len; + const uint8_t *clens; + int lookup; + float min; + float delta; + const uint8_t *quant; +} codebook_setup; + +typedef const struct { + const int type; + const int end[2]; + const int classifications; + const int nbooks; + const codebook_setup *config; + const int8_t books[10][8]; +} res_setup; + static const uint8_t floor_128_c0[] = { 10, 7, 8, 13, 9, 6, 7, 11, 10, 8, 8, 12, 17, 17, 17, 17, 7, 5, 5, 9, 6, 4, 4, 8, 8, 5, 5, 8, 16, 14, @@ -219,7 +239,7 @@ static const uint8_t floor_1024_4sub3[] = { 11, 11, 10, 10, 10, 10, 10, 10, }; -static const uint8_t res_long_master[] = { +static const uint8_t res_stereo_long_master[] = { 5, 6, 11, 11, 11, 11, 10, 10, 12, 11, 5, 2, 11, 5, 6, 6, 7, 9, 11, 13, 13, 10, 7, 11, 6, 7, 8, 9, 10, 12, 11, 5, 11, 6, 8, 7, 9, 11, 14, 15, 11, 6, 6, 8, 4, @@ -229,7 +249,7 @@ static const uint8_t res_long_master[] = { 11, 13, 12, 15, 12, 11, 9, 8, 8, 8, }; -static const uint8_t res_short_master[] = { +static const uint8_t res_stereo_short_master[] = { 10, 9, 13, 11, 14, 10, 12, 13, 13, 14, 7, 2, 12, 5, 10, 5, 7, 10, 12, 14, 12, 6, 9, 8, 7, 7, 9, 11, 13, 16, 10, 4, 12, 5, 10, 6, 8, 12, 14, 16, 12, 6, 8, 7, 6, @@ -239,7 +259,7 @@ static const uint8_t res_short_master[] = { 15, 13, 11, 10, 6, 5, 6, 8, 9, 11, }; -static const uint8_t res_p1_0[] = { +static const uint8_t res_stereo_p1_0[] = { 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -352,7 +372,7 @@ static const uint8_t res_p1_0[] = { 0, 0, 0, 8, 9, 8, }; -static const uint8_t res_p2_0[] = { +static const uint8_t res_stereo_p2_0[] = { 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 10, 10, 0, 0, @@ -385,7 +405,7 @@ static const uint8_t res_p2_0[] = { 0, 9, 9, 0, 0, 0, 10, 10, }; -static const uint8_t res_p3_0[] = { +static const uint8_t res_stereo_p3_0[] = { 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -395,7 +415,7 @@ static const uint8_t res_p3_0[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 7, 9, 9, }; -static const uint8_t res_p4_0[] = { +static const uint8_t res_stereo_p4_0[] = { 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, @@ -403,7 +423,7 @@ static const uint8_t res_p4_0[] = { 0, 0, 0, 0, 0, 0, 9, 9, }; -static const uint8_t res_p5_0[] = { +static const uint8_t res_stereo_p5_0[] = { 1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7, 8, 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8, 8, 8, 10, 10, 0, 0, 0, 8, 8, 8, 8, 10, 10, @@ -412,7 +432,7 @@ static const uint8_t res_p5_0[] = { 0, 0, 10, 10, 11, 11, }; -static const uint8_t res_p6_0[] = { +static const uint8_t res_stereo_p6_0[] = { 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 11, 10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, @@ -435,7 +455,7 @@ static const uint8_t res_p6_0[] = { 13, 13, 13, 13, }; -static const uint8_t res_p7_0[] = { +static const uint8_t res_stereo_p7_0[] = { 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7, 10, 9, 9, 11, 9, 9, 4, 7, 7, 10, 9, 9, 11, 9, 9, 7, 10, 10, 11, 11, 10, 12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10, @@ -444,7 +464,7 @@ static const uint8_t res_p7_0[] = { 11, 10, 10, 11, 10, 10, }; -static const uint8_t res_p7_1[] = { +static const uint8_t res_stereo_p7_1[] = { 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 10, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 10, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 10, @@ -456,7 +476,7 @@ static const uint8_t res_p7_1[] = { 8, }; -static const uint8_t res_p8_0[] = { +static const uint8_t res_stereo_p8_0[] = { 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 6, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 7, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9, 11, 10, 0, 8, 8, 8, 8, 9, @@ -471,12 +491,12 @@ static const uint8_t res_p8_0[] = { 13, 12, 14, 13, }; -static const uint8_t res_p8_1[] = { +static const uint8_t res_stereo_p8_1[] = { 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, }; -static const uint8_t res_p9_0[] = { +static const uint8_t res_stereo_p9_0[] = { 1, 4, 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 9, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 9, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, @@ -491,7 +511,7 @@ static const uint8_t res_p9_0[] = { 11, 11, 11, 11, }; -static const uint8_t res_p9_1[] = { +static const uint8_t res_stereo_p9_1[] = { 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9, 10, 10, 10, 10, 6, 5, 5, 7, 7, 8, 8, 10, 8, 11, 10, 12, 12, 13, 13, 6, 5, 5, 7, 7, 8, 8, 10, 9, 11, 11, 12, 12, 13, 12, @@ -509,7 +529,7 @@ static const uint8_t res_p9_1[] = { 18, 18, 18, 16, 17, 16, 14, 12, 11, 13, 10, 13, 13, 14, 15, }; -static const uint8_t res_p9_2[] = { +static const uint8_t res_stereo_p9_2[] = { 2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, @@ -532,16 +552,7 @@ static const uint8_t res_p9_2[] = { 9, 10, 10, 10, }; -static const struct { - int dim; - int len; - int real_len; - const uint8_t *clens; - int lookup; - float min; - float delta; - const uint8_t *quant; -} cvectors[] = { +codebook_setup floor_config[] = { { 2, 64, 64, floor_128_c0, 0 }, { 2, 256, 256, floor_128_c1, 0 }, { 2, 16, 16, floor_1024_c1, 0 }, @@ -565,21 +576,24 @@ static const struct { { 2, 18, 18, floor_1024_4sub1, 0 }, { 2, 50, 50, floor_1024_4sub2, 0 }, { 2, 128, 128, floor_1024_4sub3, 0 }, - { 2, 100, 100, res_short_master, 0 }, - { 2, 100, 100, res_long_master, 0 }, - { 8, 1641, 6561, res_p1_0, 1, -1.0, 1.0, (const uint8_t[]){ 1, 0, 2, } }, - { 4, 443, 625, res_p2_0, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, - { 4, 105, 625, res_p3_0, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, - { 2, 68, 81, res_p4_0, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, - { 2, 81, 81, res_p5_0, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, - { 2, 289, 289, res_p6_0, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, - { 4, 81, 81, res_p7_0, 1, -11.0, 11.0, (const uint8_t[]){ 1, 0, 2, } }, - { 2, 121, 121, res_p7_1, 1, -5.0, 1.0, (const uint8_t[]){ 5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, } }, - { 2, 169, 169, res_p8_0, 1, -30.0, 5.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, - { 2, 25, 25, res_p8_1, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, - { 2, 169, 169, res_p9_0, 1, -1530.0, 255.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, - { 2, 225, 225, res_p9_1, 1, -119.0, 17.0, (const uint8_t[]){ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13, 0, 14, } }, - { 2, 289, 289, res_p9_2, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, +}; + +static codebook_setup res_stereo_config[] = { + { 2, 100, 100, res_stereo_short_master, 0 }, + { 2, 100, 100, res_stereo_long_master, 0 }, + { 8, 1641, 6561, res_stereo_p1_0, 1, -1.0, 1.0, (const uint8_t[]){ 1, 0, 2, } }, + { 4, 443, 625, res_stereo_p2_0, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, + { 4, 105, 625, res_stereo_p3_0, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, + { 2, 68, 81, res_stereo_p4_0, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, + { 2, 81, 81, res_stereo_p5_0, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, + { 2, 289, 289, res_stereo_p6_0, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, + { 4, 81, 81, res_stereo_p7_0, 1, -11.0, 11.0, (const uint8_t[]){ 1, 0, 2, } }, + { 2, 121, 121, res_stereo_p7_1, 1, -5.0, 1.0, (const uint8_t[]){ 5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, } }, + { 2, 169, 169, res_stereo_p8_0, 1, -30.0, 5.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, + { 2, 25, 25, res_stereo_p8_1, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, + { 2, 169, 169, res_stereo_p9_0, 1, -1530.0, 255.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, + { 2, 225, 225, res_stereo_p9_1, 1, -119.0, 17.0, (const uint8_t[]){ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13, 0, 14, } }, + { 2, 289, 289, res_stereo_p9_2, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, }; static const struct { @@ -598,4 +612,22 @@ static const struct { { 3, 2, 5, { -1, 20, 21, 22 } },}, }; +res_setup res_class = { + .type = 2, + .end = { 208, 1600 }, + .classifications = 10, + .nbooks = 15, + .config = res_stereo_config, + .books = { { -1, -1, -1, -1, -1, -1, -1, -1, }, + { -1, -1, 2, -1, -1, -1, -1, -1, }, + { -1, -1, 3, -1, -1, -1, -1, -1, }, + { -1, -1, 4, -1, -1, -1, -1, -1, }, + { -1, -1, 5, -1, -1, -1, -1, -1, }, + { -1, -1, 6, -1, -1, -1, -1, -1, }, + { -1, -1, 7, -1, -1, -1, -1, -1, }, + { 8, 9, -1, -1, -1, -1, -1, -1, }, + { 10, 11, -1, -1, -1, -1, -1, -1, }, + { 12, 13, 14, -1, -1, -1, -1, -1, }, }, +}; + #endif /* AVCODEC_VORBIS_ENC_DATA_H */ diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index fae90c4a30..c2c6e1b7d8 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -111,7 +111,7 @@ static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) break; if (j == 8) // zero continue; - cb = &venc->codebooks[rc->books[i][j]]; + cb = &venc->res_books[rc->books[i][j]]; assert(cb->ndimensions >= 2); assert(cb->lookup); @@ -155,7 +155,7 @@ static av_cold int dsp_init(AVCodecContext *avctx, vorbis_enc_context *venc) return 0; } -static int create_residues(vorbis_enc_context *venc) +static int create_residues(vorbis_enc_context *venc, res_setup setup) { int res, ret; vorbis_enc_residue *rc; @@ -167,30 +167,17 @@ static int create_residues(vorbis_enc_context *venc) for (res = 0; res < venc->nresidues; res++) { rc = &venc->residues[res]; - rc->type = 2; + rc->type = setup.type; rc->begin = 0; - rc->end = res ? 1600 : 208; + rc->end = setup.end[res]; rc->partition_size = res ? 32 : 16; - rc->classbook = res ? 24 : 23; - rc->classifications = 10; + rc->classbook = res ? 1 : 0; + rc->classifications = setup.classifications; rc->books = av_malloc(sizeof(*rc->books) * rc->classifications); if (!rc->books) return AVERROR(ENOMEM); - { - static const int8_t a[10][8] = { - { -1, -1, -1, -1, -1, -1, -1, -1, }, - { -1, -1, 25, -1, -1, -1, -1, -1, }, - { -1, -1, 26, -1, -1, -1, -1, -1, }, - { -1, -1, 27, -1, -1, -1, -1, -1, }, - { -1, -1, 28, -1, -1, -1, -1, -1, }, - { -1, -1, 29, -1, -1, -1, -1, -1, }, - { -1, -1, 30, -1, -1, -1, -1, -1, }, - { 31, 32, -1, -1, -1, -1, -1, -1, }, - { 33, 34, -1, -1, -1, -1, -1, -1, }, - { 35, 36, 37, -1, -1, -1, -1, -1, }, - }; - memcpy(rc->books, a, sizeof a); - } + + memcpy(rc->books, setup.books, sizeof(setup.books)); if ((ret = ready_residue(rc, venc)) < 0) return ret; } @@ -264,49 +251,38 @@ static int create_floors(vorbis_enc_context *venc, AVCodecContext *avctx) return 0; } -static int create_vorbis_context(vorbis_enc_context *venc, - AVCodecContext *avctx) +/** + * Copy the codebooks from the hardcoded configurations into the vorbis context + */ +static int copy_codebooks(vorbis_enc_codebook *dest, + const codebook_setup *source, + const int num_books) { - vorbis_enc_mapping *mc; - int i, map, book, ret, blocks; - - venc->channels = avctx->channels; - venc->sample_rate = avctx->sample_rate; - venc->log2_blocksize[0] = 8; - venc->log2_blocksize[1] = 11; - venc->blockflags[0] = venc->blockflags[1] = venc->blockflags[2] = 1; - venc->transient = -1; - venc->num_transient = 1 << (venc->log2_blocksize[1] - venc->log2_blocksize[0]); - - venc->ncodebooks = FF_ARRAY_ELEMS(cvectors); - venc->codebooks = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks); - if (!venc->codebooks) - return AVERROR(ENOMEM); - - for (book = 0; book < venc->ncodebooks; book++) { - vorbis_enc_codebook *cb = &venc->codebooks[book]; - int vals; - cb->ndimensions = cvectors[book].dim; - cb->nentries = cvectors[book].real_len; - cb->min = cvectors[book].min; - cb->delta = cvectors[book].delta; - cb->lookup = cvectors[book].lookup; + int book; + for (book = 0; book < num_books; book++) { + int ret; + vorbis_enc_codebook *cb = &dest[book]; + cb->ndimensions = source[book].dim; + cb->nentries = source[book].real_len; + cb->min = source[book].min; + cb->delta = source[book].delta; + cb->lookup = source[book].lookup; cb->seq_p = 0; cb->lens = av_malloc_array(cb->nentries, sizeof(uint8_t)); cb->codewords = av_malloc_array(cb->nentries, sizeof(uint32_t)); if (!cb->lens || !cb->codewords) return AVERROR(ENOMEM); - memcpy(cb->lens, cvectors[book].clens, cvectors[book].len); - memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); + memcpy(cb->lens, source[book].clens, source[book].len); + memset(cb->lens + source[book].len, 0, cb->nentries - source[book].len); if (cb->lookup) { - vals = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries); + int i, vals = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries); cb->quantlist = av_malloc_array(vals, sizeof(int)); if (!cb->quantlist) return AVERROR(ENOMEM); for (i = 0; i < vals; i++) - cb->quantlist[i] = cvectors[book].quant[i]; + cb->quantlist[i] = source[book].quant[i]; } else { cb->quantlist = NULL; } @@ -314,10 +290,41 @@ static int create_vorbis_context(vorbis_enc_context *venc, return ret; } + return 0; +} + +static int create_vorbis_context(vorbis_enc_context *venc, + AVCodecContext *avctx) +{ + vorbis_enc_mapping *mc; + int i, map, ret, blocks; + + venc->channels = avctx->channels; + venc->sample_rate = avctx->sample_rate; + venc->log2_blocksize[0] = 8; + venc->log2_blocksize[1] = 11; + venc->blockflags[0] = venc->blockflags[1] = venc->blockflags[2] = 1; + venc->transient = -1; + venc->num_transient = 1 << (venc->log2_blocksize[1] - venc->log2_blocksize[0]); + + // Setup and configure our floors + venc->nfloor_books = FF_ARRAY_ELEMS(floor_config); + venc->floor_books = av_malloc(sizeof(vorbis_enc_codebook) * venc->nfloor_books); + if (!venc->floor_books) + return AVERROR(ENOMEM); + + copy_codebooks(venc->floor_books, floor_config, venc->nfloor_books); if ((ret = create_floors(venc, avctx)) < 0) return ret; - if ((ret = create_residues(venc)) < 0) + // Setup and configure our residues + venc->nres_books = res_class.nbooks; + venc->res_books = av_malloc(sizeof(vorbis_enc_codebook) * venc->nres_books); + if (!venc->res_books) + return AVERROR(ENOMEM); + + copy_codebooks(venc->res_books, res_class.config, venc->nres_books); + if ((ret = create_residues(venc, res_class)) < 0) return ret; venc->nmappings = 2; @@ -497,7 +504,8 @@ static void put_floor_header(PutBitContext *pb, vorbis_enc_floor *fc) put_bits(pb, fc->rangebits, fc->list[i].x); } -static void put_residue_header(PutBitContext *pb, vorbis_enc_residue *rc) +static void put_residue_header(PutBitContext *pb, vorbis_enc_residue *rc, + const int book_offset) { int i; @@ -507,7 +515,7 @@ static void put_residue_header(PutBitContext *pb, vorbis_enc_residue *rc) 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); + put_bits(pb, 8, book_offset + rc->classbook); for (i = 0; i < rc->classifications; i++) { int j, tmp = 0; @@ -525,7 +533,7 @@ static void put_residue_header(PutBitContext *pb, vorbis_enc_residue *rc) int j; for (j = 0; j < 8; j++) if (rc->books[i][j] != -1) - put_bits(pb, 8, rc->books[i][j]); + put_bits(pb, 8, book_offset + rc->books[i][j]); } } @@ -580,9 +588,12 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) 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]); + put_bits(&pb, 8, venc->nfloor_books + venc->nres_books - 1); + for (i = 0; i < venc->nfloor_books; i++) + put_codebook_header(&pb, &venc->floor_books[i]); + + for (i = 0; i < venc->nres_books; i++) + put_codebook_header(&pb, &venc->res_books[i]); // time domain, reserved, zero put_bits(&pb, 6, 0); @@ -596,7 +607,7 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) // residues put_bits(&pb, 6, venc->nresidues - 1); for (i = 0; i < venc->nresidues; i++) - put_residue_header(&pb, &venc->residues[i]); + put_residue_header(&pb, &venc->residues[i], venc->nfloor_books); // mappings put_bits(&pb, 6, venc->nmappings - 1); @@ -759,14 +770,14 @@ static int floor_encode(vorbis_enc_context *venc, vorbis_enc_floor *fc, vorbis_enc_floor_class * c = &fc->classes[fc->partition_to_class[i]]; int k, cval = 0, csub = 1<<c->subclass; if (c->subclass) { - vorbis_enc_codebook * book = &venc->codebooks[c->masterbook]; + vorbis_enc_codebook * book = &venc->floor_books[c->masterbook]; int cshift = 0; for (k = 0; k < c->dim; k++) { int l; for (l = 0; l < csub; l++) { int maxval = 1; if (c->books[l] != -1) - maxval = venc->codebooks[c->books[l]].nentries; + maxval = venc->floor_books[c->books[l]].nentries; // coded could be -1, but this still works, cause that is 0 if (coded[counter + k] < maxval) break; @@ -786,7 +797,7 @@ static int floor_encode(vorbis_enc_context *venc, vorbis_enc_floor *fc, continue; if (entry == -1) entry = 0; - if (put_codeword(pb, &venc->codebooks[book], entry)) + if (put_codeword(pb, &venc->floor_books[book], entry)) return AVERROR(EINVAL); } } @@ -829,7 +840,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, int partitions = (rc->end - rc->begin) / psize; int channels = (rc->type == 2) ? 1 : real_ch; int classes[MAX_CHANNELS][NUM_RESIDUE_PARTITIONS]; - int classwords = venc->codebooks[rc->classbook].ndimensions; + int classwords = venc->res_books[rc->classbook].ndimensions; av_assert0(rc->type == 2); av_assert0(real_ch == 2); @@ -852,7 +863,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, while (p < partitions) { if (pass == 0) for (j = 0; j < channels; j++) { - vorbis_enc_codebook * book = &venc->codebooks[rc->classbook]; + vorbis_enc_codebook * book = &venc->res_books[rc->classbook]; int entry = classes[j][p]; for (i = 1; i < classwords; i++) { entry *= rc->classifications; @@ -865,7 +876,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, for (i = 0; i < classwords && p < partitions; i++, p++) { for (j = 0; j < channels; j++) { int nbook = rc->books[classes[j][p]][pass]; - vorbis_enc_codebook * book = &venc->codebooks[nbook]; + vorbis_enc_codebook * book = &venc->res_books[nbook]; float *buf = coeffs + samples*j + rc->begin + p*psize; if (nbook == -1) continue; @@ -1186,15 +1197,25 @@ static av_cold int vorbis_encode_close(AVCodecContext *avctx) vorbis_enc_context *venc = avctx->priv_data; int i; - if (venc->codebooks) - for (i = 0; i < venc->ncodebooks; i++) { - av_freep(&venc->codebooks[i].lens); - av_freep(&venc->codebooks[i].codewords); - av_freep(&venc->codebooks[i].quantlist); - av_freep(&venc->codebooks[i].dimensions); - av_freep(&venc->codebooks[i].pow2); + if (venc->floor_books) + for (i = 0; i < venc->nfloor_books; i++) { + av_freep(&venc->floor_books[i].lens); + av_freep(&venc->floor_books[i].codewords); + av_freep(&venc->floor_books[i].quantlist); + av_freep(&venc->floor_books[i].dimensions); + av_freep(&venc->floor_books[i].pow2); + } + av_freep(&venc->floor_books); + + if (venc->res_books) + for (i = 0; i < venc->nres_books; i++) { + av_freep(&venc->res_books[i].lens); + av_freep(&venc->res_books[i].codewords); + av_freep(&venc->res_books[i].quantlist); + av_freep(&venc->res_books[i].dimensions); + av_freep(&venc->res_books[i].pow2); } - av_freep(&venc->codebooks); + av_freep(&venc->res_books); if (venc->floors) for (i = 0; i < venc->nfloors; i++) { -- 2.14.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel