Hi On Fri, Jan 23, 2026 at 01:35:29PM +0100, 9mmilly via ffmpeg-devel wrote: [...] > diff --git a/libavformat/rot.c b/libavformat/rot.c > new file mode 100644 > index 0000000000..520f038f8b > --- /dev/null > +++ b/libavformat/rot.c > @@ -0,0 +1,230 @@ > +/* > +* Copyright (c) 2014 9mmilly > +* > +* This file is part of FFmpeg. > +* > +* Permission to use, copy, modify, and/or distribute this software for any > +* purpose with or without fee is hereby granted, provided that the above > +* copyright notice and this permission notice appear in all copies. > +* > +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > +*/ > + > +#include > +#include > + > +#include "avformat.h" > +#include "demux.h" > +#include "internal.h" > +#include "libavcodec/codec_id.h" > +#include "mux.h" > +#include "pcm.h" > +#include "rawenc.h" > + > +#define ROT_IDENTIFIER "frot" > + > +typedef enum { > + ROT_FORMAT_S8, > + ROT_FORMAT_S16, > + ROT_FORMAT_S24, > + ROT_FORMAT_S32, > + ROT_FORMAT_FLOAT, > + ROT_FORMAT_DOUBLE > +} rot_format; > + > +/* demuxer */ > + > +static int rot_probe(const AVProbeData *probe) { > + if (probe->buf_size <= 32) > + return 0; > + > + if (probe->buf_size >= 36) { > + if (memcmp(probe->buf, ROT_IDENTIFIER, 4) == 0) > + return AVPROBE_SCORE_MAX; > + } > + return 0; > +} the probe->buf_size <= 32 block is redundant > + > +static int rot_read_header(AVFormatContext *context) { > + uint8_t header_buffer[8]; > + > + if (avio_read(context->pb, header_buffer, sizeof(header_buffer)) != 8) > + return AVERROR_INVALIDDATA; > + > + uint16_t sample_rate; > + memcpy(&sample_rate, (header_buffer + 4), 2); will fail on big endian > + > + uint8_t channels; > + memcpy(&channels, (header_buffer + 6), 1); > + > + uint8_t format; > + memcpy(&format, (header_buffer + 7), 1); > + > + if (sample_rate <= 0 || channels <= 0) > + return AVERROR_INVALIDDATA; > + > + AVStream *stream = avformat_new_stream(context, NULL); > + if (!stream) { > + av_log(stream, AV_LOG_ERROR, "invalid audio parameters\n"); > + return AVERROR(ENOMEM); > + } > + > + stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; > + stream->codecpar->ch_layout.nb_channels = channels; > + stream->codecpar->sample_rate = sample_rate; > + > + switch (format) { > + case ROT_FORMAT_S8: > + stream->codecpar->codec_id = AV_CODEC_ID_PCM_S8; > + stream->codecpar->bits_per_coded_sample = 8; > + stream->codecpar->block_align = 8 * channels / 8; > + stream->codecpar->bit_rate = (int64_t)sample_rate * channels * 8; > + break; > + > + case ROT_FORMAT_S16: > + stream->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; > + stream->codecpar->bits_per_coded_sample = 16; > + stream->codecpar->block_align = 16 * channels / 8; > + stream->codecpar->bit_rate = (int64_t)sample_rate * channels * 16; > + break; > + > + case ROT_FORMAT_S24: > + stream->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE; > + stream->codecpar->bits_per_coded_sample = 24; > + stream->codecpar->block_align = 24 * channels / 8; > + stream->codecpar->bit_rate = (int64_t)sample_rate * channels * 24; > + break; > + > + case ROT_FORMAT_S32: > + stream->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE; > + stream->codecpar->bits_per_coded_sample = 32; > + stream->codecpar->block_align = 32 * channels / 8; > + stream->codecpar->bit_rate = (int64_t)sample_rate * channels * 32; > + break; > + > + case ROT_FORMAT_FLOAT: > + stream->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE; > + stream->codecpar->bits_per_coded_sample = 32; > + stream->codecpar->block_align = 32 * channels / 8; > + stream->codecpar->bit_rate = (int64_t)sample_rate * channels * 32; > + break; > + > + case ROT_FORMAT_DOUBLE: > + stream->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE; > + stream->codecpar->bits_per_coded_sample = 64; > + stream->codecpar->block_align = 64 * channels / 8; > + stream->codecpar->bit_rate = (int64_t)sample_rate * channels * 64; > + break; the computation of block_align and bit_rate can be factored out using bits_per_coded_sample > + > + default: > + return AVERROR_INVALIDDATA; > + } > + avpriv_set_pts_info(stream, 64, 1, sample_rate); > + > + return 0; > +} > + > +const FFInputFormat ff_rot_demuxer = { > + .p.name = "rot", > + .p.long_name = NULL_IF_CONFIG_SMALL("rot pcm header"), > + .priv_data_size = 0, > + .p.extensions = "rot", > + .read_probe = rot_probe, > + .read_header = rot_read_header, > + .read_packet = ff_pcm_read_packet}; > + > +/* muxer */ > + > +static int rot_write_header(AVFormatContext *context) { its probably cleaner to have this in a seperate file thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Those who are too smart to engage in politics are punished by being governed by those who are dumber. -- Plato