[FFmpeg-devel] [PATCH] OSQ lossless audio format support
James Almer
jamrial at gmail.com
Thu Aug 24 22:54:28 EEST 2023
On 8/24/2023 6:52 AM, Paul B Mahol wrote:
> Patches attached.
>
> Stereo decoding have some issues with some predictors so not yet bitexact.
>
> Please comment.
> +static av_cold int osq_close(AVCodecContext *avctx)
> +{
> + OSQContext *s = avctx->priv_data;
> +
> + av_freep(&s->bitstream);
> + s->bitstream_size = 0;
> +
> + for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++)
FFMIN(avctx->ch_layout.nb_channels, 2);
This being a FF_CODEC_CAP_INIT_CLEANUP decoder, osq_close() could be
called before osq_init() has a chance to validate nb_channels.
> + av_freep(&s->decode_buffer[ch]);
> +
> + return 0;
> +}
> +
> static av_cold int osq_init(AVCodecContext *avctx)
> +{
> + OSQContext *s = avctx->priv_data;
> +
> + if (avctx->extradata_size < 48)
> + return AVERROR(EINVAL);
> +
> + if (avctx->extradata[0] != 1) {
> + av_log(avctx, AV_LOG_ERROR, "Unsupported version.\n");
> + return AVERROR_INVALIDDATA;
> + }
> +
> + avctx->sample_rate = AV_RL32(avctx->extradata + 4);
> + if (avctx->sample_rate < 1)
> + return AVERROR_INVALIDDATA;
> +
> + avctx->ch_layout.nb_channels = avctx->extradata[3];
You'd need to uninit ch_layout first, as the user may have filled it
with something (as is the case with the lavf demuxer).
> + if (avctx->ch_layout.nb_channels < 1)
> + return AVERROR_INVALIDDATA;
> +
> + switch (avctx->extradata[2]) {
> + case 8: avctx->sample_fmt = AV_SAMPLE_FMT_U8P; break;
> + case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break;
> + case 20:
> + case 24:
> + case 28:
> + case 32: avctx->sample_fmt = AV_SAMPLE_FMT_S32P; break;
> + default: return AVERROR_INVALIDDATA;
> + }
> +
> + s->nb_samples = AV_RL64(avctx->extradata + 16);
> + s->frame_samples = AV_RL16(avctx->extradata + 8);
> + s->max_framesize = (s->frame_samples * 16 + 1024) * avctx->ch_layout.nb_channels;
Do you even need to propagate this header using extradata? You can set
codecpar's sample_fmt and frame_size in the demuxer, much like you're
doing for sample_rate and ch_layout.
There doesn't seem to be a value that can't be propagated using the
proper existing fields here.
> +
> + s->bitstream = av_calloc(s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE, sizeof(*s->bitstream));
av_mallocz(). sizeof(*s->bitstream) is 1.
> + if (!s->bitstream)
> + return AVERROR(ENOMEM);
> +
> + for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
> + s->decode_buffer[ch] = av_calloc(s->frame_samples + 4,
> + sizeof(*s->decode_buffer[ch]));
> + if (!s->decode_buffer[ch])
> + return AVERROR(ENOMEM);
> + }
> +
> + s->pkt = avctx->internal->in_pkt;
> +
> + return 0;
> +}
More information about the ffmpeg-devel
mailing list