[FFmpeg-devel] [PATCH] QCELP decoder

Vitor Sessak vitor1001
Tue Dec 2 19:29:38 CET 2008


Kenan Gillet wrote:
> 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 ?

I think you can remove it from FAQ. I think "Frequently asked" do not go 
very well with "samples welcome"...

-Vitor




More information about the ffmpeg-devel mailing list