[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