[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