[FFmpeg-devel] [PATCH] RK Audio demuxer and decoder

James Almer jamrial at gmail.com
Wed Feb 15 13:59:43 EET 2023


On 2/5/2023 4:17 PM, Paul B Mahol wrote:
> On 2/4/23, Paul B Mahol <onemda at gmail.com> wrote:
>> Hi,
>>
>> Patches attached, decoder is not bit by bit exact yet for lossless
>> mode because some samples are not properly rounded.
>>
> 
> Now lossless mode is bit exact.

[...]

> +static av_cold int rka_decode_init(AVCodecContext *avctx)
> +{
> +    RKAContext *s = avctx->priv_data;
> +    int cmode;
> +
> +    if (avctx->extradata_size < 16)
> +        return AVERROR_INVALIDDATA;
> +
> +    s->bps = avctx->bits_per_raw_sample = avctx->extradata[13];
> +
> +    switch (s->bps) {
> +    case 8:
> +        avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
> +        break;
> +    case 16:
> +        avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
> +        break;
> +    default:
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    s->channels = avctx->ch_layout.nb_channels;

You're ignoring the channels reported by the extradata despite flagging 
this decoder as AV_CODEC_CAP_CHANNEL_CONF. It should be the other way 
around, and ignore the user set layout, if any, with

av_channel_layout_uninit(&avctx->ch_layout);
s->channels = avctx->ch_layout.nb_channels = avctx->extradata[12];

Because the stream may not necessarily come from the lavf demuxer. 
Extradata presence is required given you check for it above, but the 
avctx fields could be set to whatever if the source is not the lavf rka 
demuxer.

> +    if (s->channels < 1 || s->channels > 2)
> +        return AVERROR_INVALIDDATA;
> +
> +    s->align = (s->channels * (avctx->bits_per_raw_sample >> 3));
> +    s->samples_left = s->total_nb_samples = (AV_RL32(avctx->extradata + 4)) / s->align;
> +    s->frame_samples = 131072 / s->align;
> +    s->last_nb_samples = s->total_nb_samples % s->frame_samples;
> +
> +    cmode = avctx->extradata[14] & 0xf;
> +    if ((avctx->extradata[15] & 4) != 0)
> +        cmode = -cmode;
> +
> +    s->ch[0].cmode = s->ch[1].cmode = cmode;
> +    s->ch[0].cmode2 = -s->ch[0].cmode;
> +    s->ch[1].cmode2 = -s->ch[1].cmode;
> +    av_log(avctx, AV_LOG_DEBUG, "cmode: %d\n", cmode);
> +
> +    return 0;
> +}


More information about the ffmpeg-devel mailing list