[FFmpeg-devel] [PATCH] RF64 demuxer
Daniel Verkamp
daniel
Fri Oct 2 01:07:45 CEST 2009
Hi,
Attached is a patch for a RF64 demuxer. This is an extension of the
normal WAV format that allows files larger than 4 GB. Specs are
available at:
http://tech.ebu.ch/docs/tech/tech3306-2009.pdf
I've tested the demuxer with files generated by this closed-source Windows app:
ftp://infomaterial:infomaterial at ftp.david-gmbh.de/2_applications/RF64Generator.zip
It only creates RF64 for the >4GB case, so it is not easy to upload a
full sample, but I have uploaded the first megabyte of one here:
http://drv.nu/temp/rf64-cut.wav
I have not tested with any other samples, so if you have some
(apparently at least Adobe Audition can write RF64), please test.
Thanks,
-- Daniel Verkamp
-------------- next part --------------
>From 1eac1a163ec8659ef97a6b9c55d8e37696bb0cab Mon Sep 17 00:00:00 2001
From: Daniel Verkamp <daniel at drv.nu>
Date: Thu, 1 Oct 2009 18:55:49 -0400
Subject: [PATCH] RF64 demuxer
---
Changelog | 1 +
doc/general.texi | 2 +
libavformat/Makefile | 1 +
libavformat/allformats.c | 1 +
libavformat/wav.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/Changelog b/Changelog
index b2a65c6..b05fd85 100644
--- a/Changelog
+++ b/Changelog
@@ -40,6 +40,7 @@ version <next>:
- Core Audio Format demuxer
- Atrac1 decoder
- MD STUDIO audio demuxer
+- RF64 demuxer
diff --git a/doc/general.texi b/doc/general.texi
index dc86207..79bb08b 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -196,6 +196,8 @@ library:
@item RealMedia @tab X @tab X
@item Redirector @tab @tab X
@item Renderware TeXture Dictionary @tab @tab X
+ at item RF64 @tab @tab X
+ @tab EBU - TECH 3306
@item RL2 @tab @tab X
@tab Audio and video format used in some games by Entertainment Software Partners.
@item RPL/ARMovie @tab @tab X
diff --git a/libavformat/Makefile b/libavformat/Makefile
index c0ec8dd..b018f7d 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -177,6 +177,7 @@ OBJS-$(CONFIG_R3D_DEMUXER) += r3d.o
OBJS-$(CONFIG_RAWVIDEO_DEMUXER) += raw.o
OBJS-$(CONFIG_RAWVIDEO_MUXER) += raw.o
OBJS-$(CONFIG_REDIR_DEMUXER) += rtsp.o
+OBJS-$(CONFIG_RF64_DEMUXER) += wav.o riff.o raw.o
OBJS-$(CONFIG_RL2_DEMUXER) += rl2.o
OBJS-$(CONFIG_RM_DEMUXER) += rmdec.o rm.o
OBJS-$(CONFIG_RM_MUXER) += rmenc.o rm.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index c35b060..e914558 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -163,6 +163,7 @@ void av_register_all(void)
REGISTER_DEMUXER (R3D, r3d);
REGISTER_MUXDEMUX (RAWVIDEO, rawvideo);
REGISTER_DEMUXER (REDIR, redir);
+ REGISTER_DEMUXER (RF64, rf64);
REGISTER_DEMUXER (RL2, rl2);
REGISTER_MUXDEMUX (RM, rm);
REGISTER_MUXDEMUX (ROQ, roq);
diff --git a/libavformat/wav.c b/libavformat/wav.c
index f9163b4..802b960 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -3,6 +3,7 @@
* Copyright (c) 2001, 2002 Fabrice Bellard
*
* Sony Wave64 demuxer
+ * RF64 demuxer
* Copyright (c) 2009 Daniel Verkamp
*
* This file is part of FFmpeg.
@@ -398,3 +399,82 @@ AVInputFormat w64_demuxer = {
.codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
#endif /* CONFIG_W64_DEMUXER */
+
+#if CONFIG_RF64_DEMUXER
+static int rf64_probe(AVProbeData *p)
+{
+ if (p->buf_size < 16)
+ return 0;
+
+ if (!memcmp(p->buf, "RF64", 4) &&
+ !memcmp(p->buf + 8, "WAVE", 4) &&
+ !memcmp(p->buf + 12, "ds64", 4))
+ return AVPROBE_SCORE_MAX;
+ else
+ return 0;
+}
+
+/** Get RF64-style 64-bit integer */
+static int64_t get_rf64(ByteIOContext *pb)
+{
+ int64_t val;
+ val = get_le32(pb);
+ val |= (int64_t)get_le32(pb) << 32;
+ return val;
+}
+
+static int rf64_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ int64_t size, data_size;
+ unsigned int ds64_size;
+ ByteIOContext *pb = s->pb;
+ AVStream *st;
+ WAVContext *wav = s->priv_data;
+
+ get_le32(pb); /* 'RF64' */
+ get_le32(pb); /* file size */
+ get_le32(pb); /* 'WAVE' */
+
+ if (get_le32(pb) != MKTAG('d', 's', '6', '4')) /* 'ds64' */
+ return -1;
+
+ ds64_size = get_le32(pb); /* ds64 chunk size */
+ if (ds64_size < 0)
+ return -1;
+
+ get_rf64(pb); /* RIFF size */
+ data_size = get_rf64(pb);
+ get_rf64(pb); /* fact chunk sample count */
+
+ url_fskip(pb, ds64_size - 24); /* skip rest of ds64 chunk */
+
+ size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
+ if (size < 0)
+ return -1;
+
+ st = av_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ ff_get_wav_header(pb, st->codec, size);
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+
+ find_tag(pb, MKTAG('d', 'a', 't', 'a')); /* size overriden by ds64 */
+ wav->data_end = url_ftell(pb) + data_size;
+
+ return 0;
+}
+
+AVInputFormat rf64_demuxer = {
+ "rf64",
+ NULL_IF_CONFIG_SMALL("RF64 format"),
+ sizeof(WAVContext),
+ rf64_probe,
+ rf64_read_header,
+ wav_read_packet,
+ NULL,
+ wav_read_seek,
+ .flags = AVFMT_GENERIC_INDEX,
+ .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
+};
+#endif /* CONFIG_RF64_DEMUXER */
--
1.6.4.2
More information about the ffmpeg-devel
mailing list