[FFmpeg-devel] [PATCH] QCELP decoder

Vitor Sessak vitor1001
Tue Dec 2 17:52:27 CET 2008


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.

-Vitor

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





More information about the ffmpeg-devel mailing list