[FFmpeg-devel] [PATCH] QCELP decoder
Kenan Gillet
kenan.gillet
Thu Oct 2 22:39:42 CEST 2008
Hi,
On Sep 30, 2008, at 11:30 AM, Vitor Sessak wrote:
> Kenan Gillet wrote:
>> +static int qcelp_decode_frame(AVCodecContext *avctx,
>> + void *data, int *data_size,
>> + uint8_t *buf, const int buf_size) {
>> + QCELPContext *q = avctx->priv_data;
>> + const QCELPBitmap *order = NULL;
>> + int16_t *outbuffer = data;
>> + int i, bits;
>> + float qtzd_lspf[10], lpc[10];
>> + float cdn_vector[160], ppf_vector[160];
>> + float *formant_mem;
>> +
>> + if (determine_rate(avctx, q, buf_size, &buf) < 0) {
>> + av_log(avctx, AV_LOG_ERROR, "frame #%d: unknown framerate,
>> unsupported size: %d\n",
>> + q->frame_num++, buf_size);
>> + return -1;
>> + }
>> +
>> + if (q->rate == RATE_OCTAVE && buf[0] == 0xFF && buf[1] ==
>> 0xFF) {
>> + warn_insufficient_frame_quality(avctx, "rate is 1/8 and
>> first 16 bits are on.");
>> + goto erasure;
>> + }
>> +
>> + order = qcelp_unpacking_bitmpap_per_rate[q->rate];
>> + if (order) {
>> + bits = qcelp_bits_per_rate[q->rate];
>> +
>> + init_get_bits(&q->gb, buf, buf_size*8);
>> +
>> + memset(q->data, 0, sizeof(q->data));
>> + for (i=0; i < bits; i++) {
>> + q->data[ order[i].index ] |= get_bits1(&q-
>> >gb)<<order[i].bitpos;
>> + }
>> +
>> + // Check for erasures/blanks on rates 1, 1/4 and 1/8
>> + if (q->data[QCELP_RSRVD_POS]) {
>> + warn_insufficient_frame_quality(avctx, "wrong data in
>> reserved frame area.");
>> + goto erasure;
>> + }
>> + }
>> +
>> + if (decode_scaled_codebook_vector(q, cdn_vector) < 0) {
>> + warn_insufficient_frame_quality(avctx, "sanity check of
>> the codebook gain failed.");
>> + goto erasure;
>> + }
>> +
>> + if (decode_lspf(q, qtzd_lspf) < 0) {
>> + warn_insufficient_frame_quality(avctx, "badly received
>> packets in frame.");
>> + goto erasure;
>> + }
>> +
>> +
>> + if (apply_pitch_filters(q, cdn_vector, ppf_vector)) {
>> + warn_insufficient_frame_quality(avctx, "cannot initiliaze
>> pitch filter.");
>> + goto erasure;
>> + }
>> +
>> + if (q->rate == I_F_Q) {
>> +erasure:
>> + q->rate = I_F_Q;
>> + q->erasure_count++;
>> + decode_scaled_codebook_vector(q, cdn_vector);
>> + decode_lspf(q, qtzd_lspf);
>> + apply_pitch_filters(q, cdn_vector, ppf_vector);
>> + }
>> +
>> + formant_mem = q->formant_mem;
>> + for (i=0; i<4; i++) {
>> + interpolate_lpc(q, qtzd_lspf, lpc, i);
>> +
>> + do_formant(ppf_vector+i*40, lpc, formant_mem);
>> +
>> + // WIP Adaptive postfilter should be here
>> +
>> + formant_mem = ppf_vector + i * 40 + 30;
>> + }
>> + memcpy(q->formant_mem, ppf_vector + 150, 10 * sizeof(float));
>> +
>> + if (q->rate != I_F_Q) {
>> + q->erasure_count = 0;
>> + }
>> +
>> + for (i=0; i<160; i++) {
>> + outbuffer[i]=av_clip_int16(lrintf(4*ppf_vector[i]));
>> + }
>
> You could avoid this copying and get rid of the ppf_vector if you make
> the decoder output floats. See
> http://thread.gmane.org/gmane.comp.video.ffmpeg.cvs/17802 to see how
> it
> was done in the RA288 decoder.
I've been able to output float, but i had to divide each float value
by a 'big' constant value
(I settle on 4096) to make it work normally.
something like
for (i = 0; i < 160; i++) {
outbuffer[i] /= 4096.;
}
I looked at the sample for ra288, welcome288.ra and it seems the
decoder ouptut float bewtween -1 and 1.
So I was wondering if the output float needs to be in a certain range ?
Removing the extra loop can be done by incorporating it into the gain
table qcelp_g12ga, but I want to be sure
that I don't do anything wrong before doing so.
thanks
Kenan
More information about the ffmpeg-devel
mailing list