|
|
@ -41,13 +41,13 @@ typedef struct { |
|
|
|
int nentries; |
|
|
|
int nentries; |
|
|
|
uint8_t *lens; |
|
|
|
uint8_t *lens; |
|
|
|
uint32_t *codewords; |
|
|
|
uint32_t *codewords; |
|
|
|
int ndimentions; |
|
|
|
int ndimensions; |
|
|
|
float min; |
|
|
|
float min; |
|
|
|
float delta; |
|
|
|
float delta; |
|
|
|
int seq_p; |
|
|
|
int seq_p; |
|
|
|
int lookup; |
|
|
|
int lookup; |
|
|
|
int *quantlist; |
|
|
|
int *quantlist; |
|
|
|
float *dimentions; |
|
|
|
float *dimensions; |
|
|
|
float *pow2; |
|
|
|
float *pow2; |
|
|
|
} vorbis_enc_codebook; |
|
|
|
} vorbis_enc_codebook; |
|
|
|
|
|
|
|
|
|
|
@ -149,12 +149,12 @@ static inline int put_codeword(PutBitContext *pb, vorbis_enc_codebook *cb, |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int cb_lookup_vals(int lookup, int dimentions, int entries) |
|
|
|
static int cb_lookup_vals(int lookup, int dimensions, int entries) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (lookup == 1) |
|
|
|
if (lookup == 1) |
|
|
|
return ff_vorbis_nth_root(entries, dimentions); |
|
|
|
return ff_vorbis_nth_root(entries, dimensions); |
|
|
|
else if (lookup == 2) |
|
|
|
else if (lookup == 2) |
|
|
|
return dimentions *entries; |
|
|
|
return dimensions *entries; |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -165,28 +165,28 @@ static int ready_codebook(vorbis_enc_codebook *cb) |
|
|
|
ff_vorbis_len2vlc(cb->lens, cb->codewords, cb->nentries); |
|
|
|
ff_vorbis_len2vlc(cb->lens, cb->codewords, cb->nentries); |
|
|
|
|
|
|
|
|
|
|
|
if (!cb->lookup) { |
|
|
|
if (!cb->lookup) { |
|
|
|
cb->pow2 = cb->dimentions = NULL; |
|
|
|
cb->pow2 = cb->dimensions = NULL; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); |
|
|
|
int vals = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries); |
|
|
|
cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions); |
|
|
|
cb->dimensions = av_malloc(sizeof(float) * cb->nentries * cb->ndimensions); |
|
|
|
cb->pow2 = av_mallocz(sizeof(float) * cb->nentries); |
|
|
|
cb->pow2 = av_mallocz(sizeof(float) * cb->nentries); |
|
|
|
if (!cb->dimentions || !cb->pow2) |
|
|
|
if (!cb->dimensions || !cb->pow2) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
for (i = 0; i < cb->nentries; i++) { |
|
|
|
for (i = 0; i < cb->nentries; i++) { |
|
|
|
float last = 0; |
|
|
|
float last = 0; |
|
|
|
int j; |
|
|
|
int j; |
|
|
|
int div = 1; |
|
|
|
int div = 1; |
|
|
|
for (j = 0; j < cb->ndimentions; j++) { |
|
|
|
for (j = 0; j < cb->ndimensions; j++) { |
|
|
|
int off; |
|
|
|
int off; |
|
|
|
if (cb->lookup == 1) |
|
|
|
if (cb->lookup == 1) |
|
|
|
off = (i / div) % vals; // lookup type 1
|
|
|
|
off = (i / div) % vals; // lookup type 1
|
|
|
|
else |
|
|
|
else |
|
|
|
off = i * cb->ndimentions + j; // lookup type 2
|
|
|
|
off = i * cb->ndimensions + j; // lookup type 2
|
|
|
|
|
|
|
|
|
|
|
|
cb->dimentions[i * cb->ndimentions + j] = last + cb->min + cb->quantlist[off] * cb->delta; |
|
|
|
cb->dimensions[i * cb->ndimensions + j] = last + cb->min + cb->quantlist[off] * cb->delta; |
|
|
|
if (cb->seq_p) |
|
|
|
if (cb->seq_p) |
|
|
|
last = cb->dimentions[i * cb->ndimentions + j]; |
|
|
|
last = cb->dimensions[i * cb->ndimensions + j]; |
|
|
|
cb->pow2[i] += cb->dimentions[i * cb->ndimentions + j] * cb->dimentions[i * cb->ndimentions + j]; |
|
|
|
cb->pow2[i] += cb->dimensions[i * cb->ndimensions + j] * cb->dimensions[i * cb->ndimensions + j]; |
|
|
|
div *= vals; |
|
|
|
div *= vals; |
|
|
|
} |
|
|
|
} |
|
|
|
cb->pow2[i] /= 2.; |
|
|
|
cb->pow2[i] /= 2.; |
|
|
@ -211,17 +211,17 @@ static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) |
|
|
|
if (j == 8) // zero
|
|
|
|
if (j == 8) // zero
|
|
|
|
continue; |
|
|
|
continue; |
|
|
|
cb = &venc->codebooks[rc->books[i][j]]; |
|
|
|
cb = &venc->codebooks[rc->books[i][j]]; |
|
|
|
assert(cb->ndimentions >= 2); |
|
|
|
assert(cb->ndimensions >= 2); |
|
|
|
assert(cb->lookup); |
|
|
|
assert(cb->lookup); |
|
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < cb->nentries; j++) { |
|
|
|
for (j = 0; j < cb->nentries; j++) { |
|
|
|
float a; |
|
|
|
float a; |
|
|
|
if (!cb->lens[j]) |
|
|
|
if (!cb->lens[j]) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
a = fabs(cb->dimentions[j * cb->ndimentions]); |
|
|
|
a = fabs(cb->dimensions[j * cb->ndimensions]); |
|
|
|
if (a > rc->maxes[i][0]) |
|
|
|
if (a > rc->maxes[i][0]) |
|
|
|
rc->maxes[i][0] = a; |
|
|
|
rc->maxes[i][0] = a; |
|
|
|
a = fabs(cb->dimentions[j * cb->ndimentions + 1]); |
|
|
|
a = fabs(cb->dimensions[j * cb->ndimensions + 1]); |
|
|
|
if (a > rc->maxes[i][1]) |
|
|
|
if (a > rc->maxes[i][1]) |
|
|
|
rc->maxes[i][1] = a; |
|
|
|
rc->maxes[i][1] = a; |
|
|
|
} |
|
|
|
} |
|
|
@ -257,7 +257,7 @@ static int create_vorbis_context(vorbis_enc_context *venc, |
|
|
|
for (book = 0; book < venc->ncodebooks; book++) { |
|
|
|
for (book = 0; book < venc->ncodebooks; book++) { |
|
|
|
vorbis_enc_codebook *cb = &venc->codebooks[book]; |
|
|
|
vorbis_enc_codebook *cb = &venc->codebooks[book]; |
|
|
|
int vals; |
|
|
|
int vals; |
|
|
|
cb->ndimentions = cvectors[book].dim; |
|
|
|
cb->ndimensions = cvectors[book].dim; |
|
|
|
cb->nentries = cvectors[book].real_len; |
|
|
|
cb->nentries = cvectors[book].real_len; |
|
|
|
cb->min = cvectors[book].min; |
|
|
|
cb->min = cvectors[book].min; |
|
|
|
cb->delta = cvectors[book].delta; |
|
|
|
cb->delta = cvectors[book].delta; |
|
|
@ -272,7 +272,7 @@ static int create_vorbis_context(vorbis_enc_context *venc, |
|
|
|
memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); |
|
|
|
memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); |
|
|
|
|
|
|
|
|
|
|
|
if (cb->lookup) { |
|
|
|
if (cb->lookup) { |
|
|
|
vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); |
|
|
|
vals = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries); |
|
|
|
cb->quantlist = av_malloc(sizeof(int) * vals); |
|
|
|
cb->quantlist = av_malloc(sizeof(int) * vals); |
|
|
|
if (!cb->quantlist) |
|
|
|
if (!cb->quantlist) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
@ -454,7 +454,7 @@ static void put_codebook_header(PutBitContext *pb, vorbis_enc_codebook *cb) |
|
|
|
int ordered = 0; |
|
|
|
int ordered = 0; |
|
|
|
|
|
|
|
|
|
|
|
put_bits(pb, 24, 0x564342); //magic
|
|
|
|
put_bits(pb, 24, 0x564342); //magic
|
|
|
|
put_bits(pb, 16, cb->ndimentions); |
|
|
|
put_bits(pb, 16, cb->ndimensions); |
|
|
|
put_bits(pb, 24, cb->nentries); |
|
|
|
put_bits(pb, 24, cb->nentries); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < cb->nentries; i++) |
|
|
|
for (i = 1; i < cb->nentries; i++) |
|
|
@ -496,7 +496,7 @@ static void put_codebook_header(PutBitContext *pb, vorbis_enc_codebook *cb) |
|
|
|
|
|
|
|
|
|
|
|
put_bits(pb, 4, cb->lookup); |
|
|
|
put_bits(pb, 4, cb->lookup); |
|
|
|
if (cb->lookup) { |
|
|
|
if (cb->lookup) { |
|
|
|
int tmp = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); |
|
|
|
int tmp = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries); |
|
|
|
int bits = ilog(cb->quantlist[0]); |
|
|
|
int bits = ilog(cb->quantlist[0]); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < tmp; i++) |
|
|
|
for (i = 1; i < tmp; i++) |
|
|
@ -848,13 +848,13 @@ static float *put_vector(vorbis_enc_codebook *book, PutBitContext *pb, |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i, entry = -1; |
|
|
|
int i, entry = -1; |
|
|
|
float distance = FLT_MAX; |
|
|
|
float distance = FLT_MAX; |
|
|
|
assert(book->dimentions); |
|
|
|
assert(book->dimensions); |
|
|
|
for (i = 0; i < book->nentries; i++) { |
|
|
|
for (i = 0; i < book->nentries; i++) { |
|
|
|
float * vec = book->dimentions + i * book->ndimentions, d = book->pow2[i]; |
|
|
|
float * vec = book->dimensions + i * book->ndimensions, d = book->pow2[i]; |
|
|
|
int j; |
|
|
|
int j; |
|
|
|
if (!book->lens[i]) |
|
|
|
if (!book->lens[i]) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
for (j = 0; j < book->ndimentions; j++) |
|
|
|
for (j = 0; j < book->ndimensions; j++) |
|
|
|
d -= vec[j] * num[j]; |
|
|
|
d -= vec[j] * num[j]; |
|
|
|
if (distance > d) { |
|
|
|
if (distance > d) { |
|
|
|
entry = i; |
|
|
|
entry = i; |
|
|
@ -863,7 +863,7 @@ static float *put_vector(vorbis_enc_codebook *book, PutBitContext *pb, |
|
|
|
} |
|
|
|
} |
|
|
|
if (put_codeword(pb, book, entry)) |
|
|
|
if (put_codeword(pb, book, entry)) |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
return &book->dimentions[entry * book->ndimentions]; |
|
|
|
return &book->dimensions[entry * book->ndimensions]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, |
|
|
|
static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, |
|
|
@ -875,7 +875,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, |
|
|
|
int partitions = (rc->end - rc->begin) / psize; |
|
|
|
int partitions = (rc->end - rc->begin) / psize; |
|
|
|
int channels = (rc->type == 2) ? 1 : real_ch; |
|
|
|
int channels = (rc->type == 2) ? 1 : real_ch; |
|
|
|
int classes[MAX_CHANNELS][NUM_RESIDUE_PARTITIONS]; |
|
|
|
int classes[MAX_CHANNELS][NUM_RESIDUE_PARTITIONS]; |
|
|
|
int classwords = venc->codebooks[rc->classbook].ndimentions; |
|
|
|
int classwords = venc->codebooks[rc->classbook].ndimensions; |
|
|
|
|
|
|
|
|
|
|
|
assert(rc->type == 2); |
|
|
|
assert(rc->type == 2); |
|
|
|
assert(real_ch == 2); |
|
|
|
assert(real_ch == 2); |
|
|
@ -916,15 +916,15 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
assert(rc->type == 0 || rc->type == 2); |
|
|
|
assert(rc->type == 0 || rc->type == 2); |
|
|
|
assert(!(psize % book->ndimentions)); |
|
|
|
assert(!(psize % book->ndimensions)); |
|
|
|
|
|
|
|
|
|
|
|
if (rc->type == 0) { |
|
|
|
if (rc->type == 0) { |
|
|
|
for (k = 0; k < psize; k += book->ndimentions) { |
|
|
|
for (k = 0; k < psize; k += book->ndimensions) { |
|
|
|
int l; |
|
|
|
int l; |
|
|
|
float *a = put_vector(book, pb, &buf[k]); |
|
|
|
float *a = put_vector(book, pb, &buf[k]); |
|
|
|
if (!a) |
|
|
|
if (!a) |
|
|
|
return AVERROR(EINVAL); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
for (l = 0; l < book->ndimentions; l++) |
|
|
|
for (l = 0; l < book->ndimensions; l++) |
|
|
|
buf[k + l] -= a[l]; |
|
|
|
buf[k + l] -= a[l]; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -932,10 +932,10 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, |
|
|
|
a1 = (s % real_ch) * samples; |
|
|
|
a1 = (s % real_ch) * samples; |
|
|
|
b1 = s / real_ch; |
|
|
|
b1 = s / real_ch; |
|
|
|
s = real_ch * samples; |
|
|
|
s = real_ch * samples; |
|
|
|
for (k = 0; k < psize; k += book->ndimentions) { |
|
|
|
for (k = 0; k < psize; k += book->ndimensions) { |
|
|
|
int dim, a2 = a1, b2 = b1; |
|
|
|
int dim, a2 = a1, b2 = b1; |
|
|
|
float vec[MAX_CODEBOOK_DIM], *pv = vec; |
|
|
|
float vec[MAX_CODEBOOK_DIM], *pv = vec; |
|
|
|
for (dim = book->ndimentions; dim--; ) { |
|
|
|
for (dim = book->ndimensions; dim--; ) { |
|
|
|
*pv++ = coeffs[a2 + b2]; |
|
|
|
*pv++ = coeffs[a2 + b2]; |
|
|
|
if ((a2 += samples) == s) { |
|
|
|
if ((a2 += samples) == s) { |
|
|
|
a2 = 0; |
|
|
|
a2 = 0; |
|
|
@ -945,7 +945,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, |
|
|
|
pv = put_vector(book, pb, vec); |
|
|
|
pv = put_vector(book, pb, vec); |
|
|
|
if (!pv) |
|
|
|
if (!pv) |
|
|
|
return AVERROR(EINVAL); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
for (dim = book->ndimentions; dim--; ) { |
|
|
|
for (dim = book->ndimensions; dim--; ) { |
|
|
|
coeffs[a1 + b1] -= *pv++; |
|
|
|
coeffs[a1 + b1] -= *pv++; |
|
|
|
if ((a1 += samples) == s) { |
|
|
|
if ((a1 += samples) == s) { |
|
|
|
a1 = 0; |
|
|
|
a1 = 0; |
|
|
@ -1099,7 +1099,7 @@ static av_cold int vorbis_encode_close(AVCodecContext *avccontext) |
|
|
|
av_freep(&venc->codebooks[i].lens); |
|
|
|
av_freep(&venc->codebooks[i].lens); |
|
|
|
av_freep(&venc->codebooks[i].codewords); |
|
|
|
av_freep(&venc->codebooks[i].codewords); |
|
|
|
av_freep(&venc->codebooks[i].quantlist); |
|
|
|
av_freep(&venc->codebooks[i].quantlist); |
|
|
|
av_freep(&venc->codebooks[i].dimentions); |
|
|
|
av_freep(&venc->codebooks[i].dimensions); |
|
|
|
av_freep(&venc->codebooks[i].pow2); |
|
|
|
av_freep(&venc->codebooks[i].pow2); |
|
|
|
} |
|
|
|
} |
|
|
|
av_freep(&venc->codebooks); |
|
|
|
av_freep(&venc->codebooks); |
|
|
|