[FFmpeg-devel] [PATCH] ALS decoder

Thilo Borgmann thilo.borgmann
Sun Sep 6 13:52:57 CEST 2009


Michael Niedermayer schrieb:
> On Fri, Sep 04, 2009 at 09:48:46PM +0200, Thilo Borgmann wrote:
>> Michael Niedermayer schrieb:
>>> On Thu, Sep 03, 2009 at 09:44:25PM +0200, Thilo Borgmann wrote:
>>>> Revision 16 attached.
> 
> [...]
> 
> 
>>
>>> [...]
>>>> +typedef struct {
>>>> +    int resolution;           ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit
>>>> +    int floating;             ///< 1 = IEEE 32-bit floating-point, 0 = integer
>>>> +    int frame_length;         ///< frame length for each frame (last frame may differ)
>>>> +    int ra_distance;          ///< distance between RA frames (in frames, 0...255)
>>> if each frame is a RA frame that would be 1 i  assume, but then 0...255
>>> makes no sense as 0 makes no sense
>> Makes sense. If ra_distance == 0, there are no RA frames at all.
> 
> ra frames are keyframes, can the decoder even start decoding on non ra
> frames? is this even allowed by the spec? and well defined?
> 
> 
> [...]
> 
>>
>>> [...]
>>>> +/** Decodes an ALS frame.
>>>> + */
>>>> +static int decode_frame(AVCodecContext *avctx,
>>>> +                        void *data, int *data_size,
>>>> +                        AVPacket *avpkt)
>>>> +{
>>>> +    ALSDecContext *ctx       = avctx->priv_data;
>>>> +    ALSSpecificConfig *sconf = &ctx->sconf;
>>>> +    const uint8_t *buffer    = avpkt->data;
>>>> +    int buffer_size          = avpkt->size;
>>>> +    int invalid_frame, size;
>>>> +    unsigned int c, sample, ra_frame, bytes_read, shift;
>>>> +
>>>> +    init_get_bits(&ctx->gb, buffer, buffer_size * 8);
>>>> +    ra_frame = sconf->ra_distance && !(ctx->frame_id % sconf->ra_distance);
>>> is it true that if ra_distance == 0 then no frame is a ra frame?
>>> seems odd
>>>
>> As mentioned above, this is the specified behaviour.
>> And that is the reason for using av_mallocz() for the raw_buffer buffer,
>> to have fake 0's for prediction in the carryover samples from frame "-1".
> 
> does the spec say they should be 0 ?
> 

This whole case is not mentioned explicitly in the spec (as fas as I can
see). But this is produced by the reference encoder and can be followed
implicitly - before the first frame, there is silence (0). Until we
figured that out, we had some "randomly" broken files because of
non-zero memory chunks allocated for the first carryover buffer.

If we would not implicitly assume this from the specs and treat the very
first frame to be a RA frame (keyframe) in all cases, decoding fails.


>>
>>
>>
>>>> +    if (sconf->bgmc) {
>>>> +        // TODO: BGMC mode
>>>> +    } else {
>>>> +        s[0] = get_bits(gb, 4 + (sconf->resolution > 1));
>>>> +        for (k = 1; k < sub_blocks; k++)
>>>> +            s[k] = s[k - 1] + decode_rice(gb, 0);
>>>> +    }
>>>> +
>>>> +    if (get_bits1(gb))
>>>> +        *shift_lsbs = get_bits(gb, 4) + 1;
>>>> +
>>>> +
>>>> +    if (!sconf->rlslms) {
>>>> +        if (sconf->adapt_order) {
>>>> +            int opt_order_length = FFMAX(av_ceil_log2((block_length >> 3) - 1), 1);
>>>> +            opt_order_length     = FFMIN(av_ceil_log2(sconf->max_order+1), opt_order_length);
>>> this can be calculated as
>>> av_ceil_log2(av_clip(...))
>>>
>>> which should be simpler and faster
>> Justin mentioned this during his GSoC review and we agreed that this is
>> not an av_clip() case. I could not find an equal solution, can you?
> 
> a quick try: (entirely untested, might contain errors)
> 
> a = FFMAX(av_ceil_log2((block_length >> 3) - 1), 1);
> opt_order_length = FFMIN(av_ceil_log2(sconf->max_order+1), a);
> 
> a = FFMAX((block_length >> 3) - 1, 2);
> opt_order_length = av_ceil_log2(FFMIN(sconf->max_order+1, a));
> 
> opt_order_length = av_ceil_log2(FFMIN(sconf->max_order+1, FFMAX((block_length >> 3) - 1, 2)));
> 
> opt_order_length = av_ceil_log2(FFMIN(sconf->max_order+1, FFMAX((block_length >> 3) - 1, 2)));
> 
> opt_order_length = av_ceil_log2(av_clip((block_length >> 3) - 1, 2, sconf->max_order+1))

This can be assumed by the values we see here, but mathematically this
is not equal - a block_length == 16 proves this wrong (opt_order_length
== 1 which is not possible in the av_clip case).

Also the specs explicitly shows a block_length == 16 case.


>>
>>
>>>> +    // reconstruct all samples from residuals
>>>> +    if (ra_block) {
>>>> +        unsigned int progressive = FFMIN(block_length, opt_order);
>>> useless, you can just use opt_order instead of progressive in te following
>>> code
>> If block_length < opt_order, max would have a wrong value and y would
>> not be correct any more.
> 
> nonsense
> if block_length < opt_order, smp < block_length -> smp < opt_order -> 
> dequant = 1 -> max = smp
> 
> 
>> I think the specs don't say anything about it but I think this weird
>> case might be true for small last frames + block switching + high
>> prediction order. The reference decoder does this, too.
> 
> the reference is of no relevance, anything that is equivalent is correct,
> actually anything that follows the spec is correct even if its not equivalent
> to what the reference does.
> but we dont need that reasoning here anyway ...

You're right here, opt_order will be used only in the next revision :)

Thanks!

-Thilo



More information about the ffmpeg-devel mailing list