[FFmpeg-devel] [PATCH] IRCAM Sound Format demuxer
Jai Menon
jmenon86
Tue Apr 20 08:02:55 CEST 2010
On Tue, Apr 20, 2010 at 9:29 AM, Daniel Verkamp <daniel at drv.nu> wrote:
> ---
> ?Changelog ? ? ? ? ? ? ? ?| ? ?1 +
> ?doc/general.texi ? ? ? ? | ? ?1 +
> ?libavformat/Makefile ? ? | ? ?1 +
> ?libavformat/allformats.c | ? ?1 +
> ?libavformat/avformat.h ? | ? ?2 +-
> ?libavformat/ircamsf.c ? ?| ?200 ++++++++++++++++++++++++++++++++++++++++++++++
> ?6 files changed, 205 insertions(+), 1 deletions(-)
[...]
> ?create mode 100644 libavformat/ircamsf.c
> diff --git a/libavformat/ircamsf.c b/libavformat/ircamsf.c
> new file mode 100644
> index 0000000..3ce97f6
> --- /dev/null
> +++ b/libavformat/ircamsf.c
> @@ -0,0 +1,200 @@
> +/*
> + * IRCAM SF demuxer
> + * Copyright (c) 2010 Daniel Verkamp
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * IRCAM SF demuxer
> + * @file libavformat/ircamsf.c
> + * @author Daniel Verkamp
> + * @sa http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/IRCAM/IRCAM.html
> + */
> +
> +#include "avformat.h"
> +#include "raw.h"
> +#include "riff.h"
> +#include "libavutil/intreadwrite.h"
> +
> +static const AVCodecTag generic_codec_tags[] = {
> + ? ?{ CODEC_ID_PCM_S8, ? ?0x00001 },
> + ? ?{ CODEC_ID_PCM_ALAW, ?0x10001 },
> + ? ?{ CODEC_ID_PCM_MULAW, 0x20001 },
> +};
> +
> +static const AVCodecTag le_codec_tags[] = {
> + ? ?{ CODEC_ID_PCM_S16LE, 0x00002 },
> + ? ?{ CODEC_ID_PCM_S24LE, 0x00003 },
> + ? ?{ CODEC_ID_PCM_S32LE, 0x40004 },
> + ? ?{ CODEC_ID_PCM_F32LE, 0x00004 },
> + ? ?{ CODEC_ID_PCM_F64LE, 0x00008 },
> +};
> +
> +static const AVCodecTag be_codec_tags[] = {
> + ? ?{ CODEC_ID_PCM_S16BE, 0x00002 },
> + ? ?{ CODEC_ID_PCM_S24BE, 0x00003 },
> + ? ?{ CODEC_ID_PCM_S32BE, 0x40004 },
> + ? ?{ CODEC_ID_PCM_F32BE, 0x00004 },
> + ? ?{ CODEC_ID_PCM_F64BE, 0x00008 },
> +};
an additional CODEC_ID_NONE,0 is required in these tables.
[...]
> +static int identify(uint32_t tag)
> +{
> + ? ?int i;
> +
> + ? ?for (i = 0; i < sizeof(be_tags) / sizeof(*be_tags); i++)
FF_ARRAY_ELEMS here and below
[...]
> +static int probe(AVProbeData *p)
> +{
> + ? ?unsigned char *buf = p->buf;
> + ? ?if (p->buf_size <= 16)
> + ? ? ? ?return 0;
> +
> + ? ?if (identify(AV_RB32(buf)) < 0)
> + ? ? ? ?return 0;
> +
> + ? ?if (!AV_RB32(buf + 4) || !AV_RB32(buf + 8) || !AV_RB32(buf + 12))
> + ? ? ? ?return 0;
> +
> + ? ?return AVPROBE_SCORE_MAX;
Could be fragile, is there anything else we could check? stream
parameters perhaps?
> +}
> +
> +static int read_header(AVFormatContext *s, AVFormatParameters *ap)
> +{
> + ? ?ByteIOContext *pb = s->pb;
> + ? ?AVStream *st;
> + ? ?AVCodecContext *dec;
> + ? ?const AVCodecTag *tags;
> + ? ?uint32_t tag;
> + ? ?int be, bits_per_frame, chunk, sz;
> + ? ?char *comment;
> +
> + ? ?be = identify(get_be32(pb));
> + ? ?if (be < 0)
> + ? ? ? ?return AVERROR_INVALIDDATA;
> +
> + ? ?st = av_new_stream(s, 0);
> + ? ?if (!st)
> + ? ? ? ?return AVERROR(ENOMEM);
> +
> + ? ?dec = st->codec;
> + ? ?dec->codec_type = AVMEDIA_TYPE_AUDIO;
> +
> + ? ?if (be) {
> + ? ? ? ?dec->sample_rate = av_int2flt(get_be32(pb));
> + ? ? ? ?dec->channels ? ?= get_be32(pb);
> + ? ? ? ?tag ? ? ? ? ? ? ?= get_be32(pb);
> + ? ? ? ?tags ? ? ? ? ? ? = be_codec_tags;
> + ? ?} else {
> + ? ? ? ?dec->sample_rate = av_int2flt(get_le32(pb));
> + ? ? ? ?dec->channels ? ?= get_le32(pb);
> + ? ? ? ?tag ? ? ? ? ? ? ?= get_le32(pb);
> + ? ? ? ?tags ? ? ? ? ? ? = le_codec_tags;
> + ? ?}
> +
> + ? ?if (dec->sample_rate <= 0) {
> + ? ? ? ?av_log(s, AV_LOG_ERROR, "invalid sample rate %d\n", dec->sample_rate);
> + ? ? ? ?return AVERROR_INVALIDDATA;
> + ? ?}
> +
> + ? ?dec->codec_id = ff_codec_get_id(tags, tag);
> + ? ?if (dec->codec_id == CODEC_ID_NONE)
> + ? ? ? ?dec->codec_id = ff_codec_get_id(generic_codec_tags, tag);
> +
> + ? ?av_set_pts_info(st, 64, 1, dec->sample_rate);
> +
> + ? ?while (url_ftell(pb) < 1024) {
> + ? ? ? ?if (be) {
> + ? ? ? ? ? ?chunk = get_be16(pb);
> + ? ? ? ? ? ?sz ? ?= get_be16(pb);
> + ? ? ? ?} else {
> + ? ? ? ? ? ?chunk = get_le16(pb);
> + ? ? ? ? ? ?sz ? ?= get_le16(pb);
> + ? ? ? ?}
> +
> + ? ? ? ?if (!chunk) // end chunk
> + ? ? ? ? ? ?break;
> +
> + ? ? ? ?switch (chunk) {
> + ? ? ? ?case 2: // comment
> + ? ? ? ? ? ?comment = av_malloc(sz + 1);
> + ? ? ? ? ? ?if (get_buffer(pb, comment, sz) != sz) {
> + ? ? ? ? ? ? ? ?av_freep(&comment);
> + ? ? ? ? ? ? ? ?return AVERROR(EIO);
> + ? ? ? ? ? ?}
> + ? ? ? ? ? ?comment[sz] = 0;
> + ? ? ? ? ? ?av_metadata_set2(&s->metadata, "comment", comment,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? AV_METADATA_DONT_STRDUP_VAL);
> + ? ? ? ? ? ?break;
> + ? ? ? ?default:
> + ? ? ? ? ? ?url_fskip(pb, sz);
> + ? ? ? ? ? ?break;
> + ? ? ? ?}
> + ? ?}
> +
> + ? ?url_fseek(pb, 1024, SEEK_SET);
Could this be avoided, by skipping the padding bytes instead?
> +
> + ? ?dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id);
> + ? ?bits_per_frame ? = dec->channels * dec->bits_per_coded_sample;
> + ? ?dec->block_align = bits_per_frame >> 3;
> + ? ?dec->bit_rate ? ?= bits_per_frame * dec->sample_rate;
> +
> + ? ?return 0;
> +}
> +
> +#define NUM_SAMPLES 1024
> +
> +static int read_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> + ? ?return av_get_packet(s->pb, pkt,
> + ? ? ? ? ? ? ? ? ? ? ? ? NUM_SAMPLES * s->streams[0]->codec->block_align);
> +}
looks like raw_read_packet could be used but maybe I'm missing something
[...]
--
Jai Menon
More information about the ffmpeg-devel
mailing list