|
|
|
@ -598,23 +598,65 @@ static int put_main_header(venc_context_t * venc, uint8_t ** out) { |
|
|
|
|
return p - *out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int vorbis_encode_init(AVCodecContext * avccontext) |
|
|
|
|
{ |
|
|
|
|
venc_context_t * venc = avccontext->priv_data; |
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
static float * put_vector(codebook_t * book, PutBitContext * pb, float * num) { |
|
|
|
|
int i; |
|
|
|
|
int entry = -1; |
|
|
|
|
float distance = 0; |
|
|
|
|
assert(book->dimentions); |
|
|
|
|
for (i = 0; i < book->nentries; i++) { |
|
|
|
|
float d = 0.; |
|
|
|
|
int j; |
|
|
|
|
for (j = 0; j < book->ndimentions; j++) { |
|
|
|
|
float a = (book->dimentions[i * book->ndimentions + j] - num[j]); |
|
|
|
|
d += a*a; |
|
|
|
|
} |
|
|
|
|
if (entry == -1 || distance > d) { |
|
|
|
|
entry = i; |
|
|
|
|
distance = d; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
put_bits(pb, book->entries[entry].len, book->entries[entry].codeword); |
|
|
|
|
return &book->dimentions[entry * book->ndimentions]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata); |
|
|
|
|
static void residue_encode(venc_context_t * venc, residue_t * rc, PutBitContext * pb, float * coeffs, int samples, int channels) { |
|
|
|
|
int pass, i, j, p, k; |
|
|
|
|
int psize = rc->partition_size; |
|
|
|
|
int partitions = (rc->end - rc->begin) / psize; |
|
|
|
|
int classes[channels][partitions]; |
|
|
|
|
int classwords = venc->codebooks[rc->classbook].ndimentions; |
|
|
|
|
|
|
|
|
|
avccontext->frame_size = 1 << (venc->blocksize[0] - 1); |
|
|
|
|
for (pass = 0; pass < 8; pass++) { |
|
|
|
|
p = 0; |
|
|
|
|
while (p < partitions) { |
|
|
|
|
if (pass == 0) for (j = 0; j < channels; j++) { |
|
|
|
|
codebook_t * book = &venc->codebooks[rc->classbook]; |
|
|
|
|
int entry = 0; |
|
|
|
|
put_bits(pb, book->entries[entry].len, book->entries[entry].codeword); |
|
|
|
|
for (i = classwords; i--; ) { |
|
|
|
|
classes[j][p + i] = entry % rc->classifications; |
|
|
|
|
entry /= rc->classifications; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (i = 0; i < classwords && p < partitions; i++, p++) { |
|
|
|
|
for (j = 0; j < channels; j++) { |
|
|
|
|
int nbook = rc->books[classes[j][p]][pass]; |
|
|
|
|
codebook_t * book = &venc->codebooks[nbook]; |
|
|
|
|
float * buf = coeffs + samples*j + rc->begin + p*psize; |
|
|
|
|
if (nbook == -1) continue; |
|
|
|
|
|
|
|
|
|
avccontext->coded_frame = avcodec_alloc_frame(); |
|
|
|
|
avccontext->coded_frame->key_frame = 1; |
|
|
|
|
assert(rc->type == 0); |
|
|
|
|
assert(!(psize % book->ndimentions)); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
for (k = 0; k < psize; k += book->ndimentions) { |
|
|
|
|
float * a = put_vector(book, pb, &buf[k]); |
|
|
|
|
int l; |
|
|
|
|
for (l = 0; l < book->ndimentions; l++) buf[k + l] -= a[l]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int window(venc_context_t * venc, signed short * audio, int samples) { |
|
|
|
@ -667,65 +709,23 @@ static int window(venc_context_t * venc, signed short * audio, int samples) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static float * put_vector(codebook_t * book, PutBitContext * pb, float * num) { |
|
|
|
|
int i; |
|
|
|
|
int entry = -1; |
|
|
|
|
float distance = 0; |
|
|
|
|
assert(book->dimentions); |
|
|
|
|
for (i = 0; i < book->nentries; i++) { |
|
|
|
|
float d = 0.; |
|
|
|
|
int j; |
|
|
|
|
for (j = 0; j < book->ndimentions; j++) { |
|
|
|
|
float a = (book->dimentions[i * book->ndimentions + j] - num[j]); |
|
|
|
|
d += a*a; |
|
|
|
|
} |
|
|
|
|
if (entry == -1 || distance > d) { |
|
|
|
|
entry = i; |
|
|
|
|
distance = d; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
put_bits(pb, book->entries[entry].len, book->entries[entry].codeword); |
|
|
|
|
return &book->dimentions[entry * book->ndimentions]; |
|
|
|
|
} |
|
|
|
|
static int vorbis_encode_init(AVCodecContext * avccontext) |
|
|
|
|
{ |
|
|
|
|
venc_context_t * venc = avccontext->priv_data; |
|
|
|
|
|
|
|
|
|
static void residue_encode(venc_context_t * venc, residue_t * rc, PutBitContext * pb, float * coeffs, int samples, int channels) { |
|
|
|
|
int pass, i, j, p, k; |
|
|
|
|
int psize = rc->partition_size; |
|
|
|
|
int partitions = (rc->end - rc->begin) / psize; |
|
|
|
|
int classes[channels][partitions]; |
|
|
|
|
int classwords = venc->codebooks[rc->classbook].ndimentions; |
|
|
|
|
create_vorbis_context(venc, avccontext); |
|
|
|
|
|
|
|
|
|
for (pass = 0; pass < 8; pass++) { |
|
|
|
|
p = 0; |
|
|
|
|
while (p < partitions) { |
|
|
|
|
if (pass == 0) for (j = 0; j < channels; j++) { |
|
|
|
|
codebook_t * book = &venc->codebooks[rc->classbook]; |
|
|
|
|
int entry = 0; |
|
|
|
|
put_bits(pb, book->entries[entry].len, book->entries[entry].codeword); |
|
|
|
|
for (i = classwords; i--; ) { |
|
|
|
|
classes[j][p + i] = entry % rc->classifications; |
|
|
|
|
entry /= rc->classifications; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (i = 0; i < classwords && p < partitions; i++, p++) { |
|
|
|
|
for (j = 0; j < channels; j++) { |
|
|
|
|
int nbook = rc->books[classes[j][p]][pass]; |
|
|
|
|
codebook_t * book = &venc->codebooks[nbook]; |
|
|
|
|
float * buf = coeffs + samples*j + rc->begin + p*psize; |
|
|
|
|
if (nbook == -1) continue; |
|
|
|
|
//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;
|
|
|
|
|
|
|
|
|
|
assert(rc->type == 0); |
|
|
|
|
assert(!(psize % book->ndimentions)); |
|
|
|
|
avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata); |
|
|
|
|
|
|
|
|
|
for (k = 0; k < psize; k += book->ndimentions) { |
|
|
|
|
float * a = put_vector(book, pb, &buf[k]); |
|
|
|
|
int l; |
|
|
|
|
for (l = 0; l < book->ndimentions; l++) buf[k + l] -= a[l]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
avccontext->frame_size = 1 << (venc->blocksize[0] - 1); |
|
|
|
|
|
|
|
|
|
avccontext->coded_frame = avcodec_alloc_frame(); |
|
|
|
|
avccontext->coded_frame->key_frame = 1; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int vorbis_encode_frame(AVCodecContext * avccontext, unsigned char * packets, int buf_size, void *data) |
|
|
|
|