[FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

James Almer jamrial at gmail.com
Wed Feb 19 19:58:39 EET 2020


On 2/19/2020 1:50 PM, Paul B Mahol wrote:
> On 2/19/20, James Almer <jamrial at gmail.com> wrote:
>> On 2/19/2020 7:30 AM, Paul B Mahol wrote:
>>> Signed-off-by: Paul B Mahol <onemda at gmail.com>
>>> +static int siren_decode(AVCodecContext *avctx, void *data,
>>> +                        int *got_frame, AVPacket *avpkt)
>>> +{
>>> +    SirenContext *s = avctx->priv_data;
>>> +    GetBitContext *gb = &s->gb;
>>> +    AVFrame *frame = data;
>>> +    int ret, number_of_valid_coefs = 20 * s->number_of_regions;
>>> +    int frame_error = 0, rate_control = 0;
>>> +
>>> +    if ((ret = init_get_bits8(gb, avpkt->data, avpkt->size)) < 0)
>>> +        return ret;
>>> +
>>> +    decode_envelope(s, gb, s->number_of_regions,
>>> +                    s->decoder_standard_deviation,
>>> +                    s->absolute_region_power_index, s->esf_adjustment);
>>> +
>>> +    rate_control = get_bits(gb, 4);
>>> +
>>> +    categorize_regions(s->number_of_regions, get_bits_left(gb),
>>> +                       s->absolute_region_power_index,
>>> s->power_categories,
>>> +                       s->category_balance);
>>> +
>>> +    for (int i = 0; i < rate_control; i++) {
>>> +        s->power_categories[s->category_balance[i]]++;
>>> +    }
>>> +
>>> +    ret = decode_vector(s, s->number_of_regions, get_bits_left(gb),
>>> +                        s->decoder_standard_deviation,
>>> s->power_categories,
>>> +                        s->imdct_in, s->scale_factor);
>>> +    if (ret < 0)
>>> +        return ret;
>>> +
>>> +    if (get_bits_left(gb) > 0) {
>>> +        do {
>>> +            if (!get_bits1(gb))
>>> +                frame_error = 1;
>>> +        } while (get_bits_left(gb) > 0);
>>> +    } else if (get_bits_left(gb) < 0 &&
>>> +               rate_control + 1 < s->rate_control_possibilities) {
>>> +        frame_error |= 2;
>>> +    }
>>> +
>>> +    for (int i = 0; i < s->number_of_regions; i++) {
>>> +        if (s->absolute_region_power_index[i] > 33 ||
>>> +            s->absolute_region_power_index[i] < -31)
>>> +            frame_error |= 4;
>>> +    }
>>> +
>>> +    if (frame_error) {
>>
>> You're not really doing anything different depending on the kind of
>> error you saw above, so may as well just make frame_error 0 or 1.
> 
> DO not like that.
> 
>>
>> Also, you may want to abort decoding if err_detect is set to explode.
> 
> DO not like that.
> 
>>
>>> +        for (int i = 0; i < number_of_valid_coefs; i++) {
>>> +            s->imdct_in[i] = s->backup_frame[i];
>>> +            s->backup_frame[i] = 0;
>>> +        }
>>> +    } else {
>>> +        for (int i = 0; i < number_of_valid_coefs; i++)
>>> +            s->backup_frame[i] = s->imdct_in[i];
>>> +    }
>>> +
>>> +    frame->nb_samples = FRAME_SIZE;
>>> +    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
>>> +        return ret;
>>> +
>>> +    for (int i = 0; i < 320; i += 2)
>>> +        s->imdct_in[i] *= -1;
>>> +
>>> +    s->tx_fn(s->tx_ctx, s->imdct_out, s->imdct_in, sizeof(float));
>>> +    s->fdsp->vector_fmul_window((float *)frame->data[0],
>>> +                                s->imdct_prev + (FRAME_SIZE >> 1),
>>> +                                s->imdct_out, s->window,
>>> +                                FRAME_SIZE >> 1);
>>> +    FFSWAP(float *, s->imdct_out, s->imdct_prev);
>>
>> Instead of this, can't you keep an AVFrame reference in SirenContext and
>> use ff_reget_buffer()? With or without read only flag depending on
>> frame_error.
> 
> DO not like that.
> 
>>
>>> +
>>> +    *got_frame = 1;
>>> +
>>> +    return avpkt->size;
>>> +}
>>> +
>>> +static av_cold int siren_close(AVCodecContext *avctx)
>>> +{
>>> +    SirenContext *s = avctx->priv_data;
>>> +
>>> +    av_freep(&s->fdsp);
>>> +    av_tx_uninit(&s->tx_ctx);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +AVCodec ff_siren_decoder = {
>>> +    .name           = "siren",
>>> +    .long_name      = NULL_IF_CONFIG_SMALL("Siren"),
>>> +    .priv_data_size = sizeof(SirenContext),
>>> +    .type           = AVMEDIA_TYPE_AUDIO,
>>> +    .id             = AV_CODEC_ID_SIREN,
>>> +    .init           = siren_init,
>>> +    .close          = siren_close,
>>> +    .decode         = siren_decode,
>>
>> Missing a flush() function to clear s->backup_frame, s->imdct_in,
>> s->imdct_out and s->imdct_prev.
> 
> DO not like that.
>>
>>> +    .capabilities   = AV_CODEC_CAP_DR1,
>>
>> Also init thread safe caps_internal.
> DO not like that.

At some point you'll have to realize there's a difference between being
funny and being insufferable.


More information about the ffmpeg-devel mailing list