[FFmpeg-devel] [PATCH] QCELP decoder

Kenan Gillet kenan.gillet
Tue Dec 2 19:21:45 CET 2008


On Dec 2, 2008, at 8:52 AM, Vitor Sessak wrote:

> Michael Niedermayer wrote:
>> On Mon, Dec 01, 2008 at 03:15:40PM -0800, Kenan Gillet wrote:
>>> Hi,
>>>
>>> On Mon, Dec 1, 2008 at 1:39 PM, Michael Niedermayer <michaelni at gmx.at 
>>> > wrote:
>>>> On Mon, Dec 01, 2008 at 12:45:09PM -0800, Kenan Gillet wrote:
>>>>> Hi,
>>>>> On Mon, Dec 1, 2008 at 8:24 AM, Michael Niedermayer <michaelni at gmx.at 
>>>>> > wrote:
>>> [...]
>>>
>>>
>>>>> Index: libavcodec/qcelpdec.c
>>>>> = 
>>>>> ==================================================================
>>>>> --- libavcodec/qcelpdec.c     (revision 15972)
>>>>> +++ libavcodec/qcelpdec.c     (working copy)
>>> [...]
>>>
>>>
>>>>> @@ -476,6 +495,64 @@
>>>>> }
>>>>>
>>>>> /**
>>>>> + * Apply pitch synthesis filter and pitch prefilter to the  
>>>>> scaled codebook vector.
>>>>> + * TIA/EIA/IS-733 2.4.5.2
>>>>> + *
>>>>> + * @param q the context
>>>>> + * @param cdn_vector the scaled codebook vector
>>>>> + */
>>>>> +static void apply_pitch_filters(QCELPContext *q,
>>>>> +                                float *cdn_vector) {
>>>>> +    int         i;
>>>>> +    float       gain[4];
>>>>> +    const float *v_synthesis_filtered, *v_pre_filtered;
>>>>> +
>>>>> +    if (q->bitrate >= RATE_HALF ||
>>>>> +       (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) {
>>>>> +
>>>>> +        if (q->bitrate >= RATE_HALF) {
>>>>> +
>>>>> +            // Compute gain & lag for the whole frame.
>>>>> +            for (i = 0; i < 4; i++) {
>>>>> +                gain[i] = q->frame.plag[i] ? (q->frame.pgain[i]  
>>>>> + 1) * 0.25 : 0.0;
>>>>> +
>>>>> +                q->frame.plag[i] += 16;
>>>>> +            }
>>>>> +            memcpy(q->prev_pitch_lag, q->frame.plag, sizeof(q- 
>>>>> >frame.plag));
>>>>> +        } else {
>>>>> +            gain[3] = q->erasure_count < 3 ? 0.9 - 0.3 * (q- 
>>>>> >erasure_count - 1)
>>>>> +                                           : 0.0;
>>>>> +            for (i = 0; i < 4; i++)
>>>>> +                gain[i] = FFMIN(q->prev_pitch_gain[i], gain[3]);
>>>>> +
>>>>> +            memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac));
>>>>> +            memcpy(q->frame.plag, q->prev_pitch_lag, sizeof(q- 
>>>>> >frame.plag));
>>>> i think if prev_pitch_lag was used in the surrounding code then  
>>>> this memcpy
>>>> would be unneeded
>>> done, and var renamed to pitch_lag
>>>
>>>
>>>>> +        }
>>>>> +
>>>>> +        // pitch synthesis filter
>>>>> +        v_synthesis_filtered = do_pitchfilter(q- 
>>>>> >pitch_synthesis_filter_mem, cdn_vector,
>>>>> +                                              gain, q- 
>>>>> >frame.plag, q->frame.pfrac);
>>>>> +
>>>>> +        // pitch prefilter update
>>>>> +        for (i = 0; i < 4; i++)
>>>>> +            gain[i] = 0.5 * FFMIN(gain[i], 1.0);
>>>>> +
>>>>> +        v_pre_filtered = do_pitchfilter(q- 
>>>>> >pitch_pre_filter_mem, v_synthesis_filtered,
>>>>> +                                        gain, q->frame.plag, q- 
>>>>> >frame.pfrac);
>>>>> +
>>>>> +        apply_gain_ctrl(cdn_vector, v_synthesis_filtered,  
>>>>> v_pre_filtered);
>>>>> +
>>>>> +        memcpy(q->prev_pitch_gain, gain, sizeof(q- 
>>>>> >prev_pitch_gain));
>>>> cant prev_pitch_gain be directly used instead of gain that then  
>>>> is copied
>>>> back?
>>>> (possibly with a better var name than prev_pitch_gain)
>>> done, and var renamed to pitch_gain
>>>
>>>
>>>>
>>>>> +
>>>>> +    } else {
>>>>> +        memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17,  
>>>>> 143 * sizeof(float));
>>>>> +        memcpy(q->pitch_pre_filter_mem,       cdn_vector + 17,  
>>>>> 143 * sizeof(float));
>>>>> +        memset(q->prev_pitch_gain, 0, sizeof(q- 
>>>>> >prev_pitch_gain));
>>>>> +        memset(q->prev_pitch_lag,  0, sizeof(q->prev_pitch_lag));
>>>>> +    }
>>>>> +}
>>>>> +
>>>>> +/**
>>>>>  * Interpolates LSP frequencies and computes LPC coefficients
>>>>>  * for a given bitrate & pitch subframe.
>>>>>  *
>>> [...]
>>>
>>>
>>>> [...]
>>>>> Index: libavformat/mov.c
>>>>> = 
>>>>> ==================================================================
>>>>> --- libavformat/mov.c (revision 15972)
>>>>> +++ libavformat/mov.c (working copy)
>>>>> @@ -988,6 +988,10 @@
>>>>> #endif
>>>>>     /* no ifdef since parameters are always those */
>>>>>     case CODEC_ID_QCELP:
>>>>> +        st->need_parsing = AVSTREAM_PARSE_FULL;
>>>>> +        st->codec->frame_size= 160;
>>>>
>>>>> +        st->codec->channels= 1; /* really needed */
>>>> if this is really needed then its ok
>>> when removed, some samples wav output changes,
>>> plus QCELP only handles mono.
>>>
>>>>
>>>>> +        break;
>>>>>     case CODEC_ID_AMR_NB:
>>>>>     case CODEC_ID_AMR_WB:
>>>>>         st->codec->frame_size= sc->samples_per_frame;
>>>> [...]
>>>>
>>> round 15 attached.
>>>
>>> note: there is a small update to the glue code in libavformat/mov.c
>>> so I repost the doc-glue patch for this particular round but it  
>>> has not
>>> changed otherwise.
>>>
>>> thanks for all your help,
>
> Commited the last remaining parts. The following chunk
>
>> +        st->codec->frame_size= 160;
>>         st->codec->channels= 1; /* really needed */
>> +        break;
>>
>
> was never ok'ed but I considered it harmless enough.

was oked long ago :)



>
> -Vitor
>
> PS @Kenan: missing patch to
> svn://svn.ffmpeg.org/ffmpeg.org/trunk/src/index =)


will wait for Reynaldo on that :)

Should we also modified the FAQ ?
3.4 I get "Unsupported codec (id=86043) for input stream #0.1". What  
is the problem?

something like: only supported in mov variants , send us samples ?

thanks again





More information about the ffmpeg-devel mailing list