[Ffmpeg-devel] [PATCH] demuxer for dcinema audio
Reimar Döffinger
Reimar.Doeffinger
Sat Aug 27 17:08:38 CEST 2005
Hi,
I'd like to suggest the attached patch for demuxing D-Cinema audio. It's
not exactly beautiful since it does something like decoding (changing
the bit order), but I though it to be the easier solution over adding a
special decoder (since it isn't used anywhere else).
The smil file that came with it said it was of the format "audio/302m",
and I assume it is SMPTE 302M uncompressed audio, but I don't have the
specs.
Please tell me what you think about it...
Oh, some samples (I already extended the MPlayer mpeg demuxer to play
the gxf file):
Address: ftp://www.ropa-net.de
Username: web49f4
Password: 123456
Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: libavformat/Makefile
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/Makefile,v
retrieving revision 1.98
diff -u -r1.98 Makefile
--- libavformat/Makefile 13 Aug 2005 13:45:42 -0000 1.98
+++ libavformat/Makefile 27 Aug 2005 14:51:27 -0000
@@ -17,7 +17,7 @@
yuv4mpeg.o 4xm.o flvenc.o flvdec.o movenc.o psxstr.o idroq.o ipmovie.o \
nut.o wc3movie.o mp3.o westwood.o segafilm.o idcin.o flic.o \
sierravmd.o matroska.o sol.o electronicarts.o nsvdec.o asf.o asf-enc.o \
- ogg2.o oggparsevorbis.o oggparsetheora.o oggparseflac.o
+ ogg2.o oggparsevorbis.o oggparsetheora.o oggparseflac.o s302m.o
AMROBJS=
ifeq ($(AMR_NB),yes)
AMROBJS= amr.o
Index: libavformat/allformats.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/allformats.c,v
retrieving revision 1.48
diff -u -r1.48 allformats.c
--- libavformat/allformats.c 15 Jul 2005 12:50:00 -0000 1.48
+++ libavformat/allformats.c 27 Aug 2005 14:51:27 -0000
@@ -109,6 +109,7 @@
sol_init();
ea_init();
nsvdec_init();
+ s302m_init();
#ifdef CONFIG_ENCODERS
/* image formats */
Index: libavformat/avformat.h
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/avformat.h,v
retrieving revision 1.132
diff -u -r1.132 avformat.h
--- libavformat/avformat.h 21 Aug 2005 22:31:00 -0000 1.132
+++ libavformat/avformat.h 27 Aug 2005 14:51:30 -0000
@@ -546,6 +546,9 @@
/* nsvdec.c */
int nsvdec_init(void);
+/* s302m.c */
+int s302m_init(void);
+
#include "rtp.h"
#include "rtsp.h"
Index: libavformat/s302m.c
===================================================================
RCS file: libavformat/s302m.c
diff -N libavformat/s302m.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libavformat/s302m.c 27 Aug 2005 14:51:30 -0000
@@ -0,0 +1,99 @@
+/*
+ * SMPTE 302M decoder.
+ * Copyright (c) 2005 Reimar D?ffinger.
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "avformat.h"
+
+static int s302m_header(AVFormatContext *s, AVFormatParameters *ap) {
+ AVStream *st = av_new_stream(s, 0);
+ st->codec->codec_type = CODEC_TYPE_AUDIO;
+ st->codec->codec_tag = 0x1;
+ st->codec->channels = 6;
+ st->codec->sample_rate = 96000;
+ st->codec->bit_rate = 3 * 6 * 96000 * 8;
+ st->codec->block_align = 4 * 6;
+ // we internally convert to 32 bit since that's easier and faster
+ st->codec->bits_per_sample = 32;
+ return 0;
+}
+
+// This bitorder is the result of pure guesswork (counting how often
+// the bits flip), so it might be wrong.
+static inline uint32_t get_sample(ByteIOContext *pb) {
+ int i;
+ uint32_t in = (get_be16(pb) << 8) | get_byte(pb);
+ uint32_t out = 0;
+ uint32_t in_back = in;
+ uint8_t sync = in & 0x0f; // sync flags
+ in >>= 4;
+ for (i = 0; i < 20; i++) {
+ out <<= 1;
+ out |= (in & 1);
+ in >>= 1;
+ }
+ out <<= 12;
+ out |= sync; // sync flags go into lowest bits
+ // It seems those might also contain audio data,
+ // don't know where they belong then, samples welcome.
+ // These might be also useful to detect the number
+ // of channels in case there are files with != 6 channels
+ return out;
+}
+
+static int s302m_packet(AVFormatContext *s, AVPacket *pkt) {
+ ByteIOContext *pb = &s->pb;
+ uint32_t *buf;
+ int i;
+ int size = get_be16(pb);
+ get_be16(pb); // unkown
+ if (size % 3) {
+ av_log(s, AV_LOG_ERROR, "Packet size must be divisible by sample size.\n");
+ return AVERROR_IO;
+ }
+ size /= 3;
+ if (av_new_packet(pkt, size * 4))
+ return AVERROR_IO;
+ pkt->flags |= PKT_FLAG_KEY;
+ pkt->stream_index = 0;
+
+ buf = (uint32_t *)pkt->data;
+ for (i = 0; i < size; i++) {
+ buf[i] = get_sample(pb);
+ if (url_feof(pb))
+ break;
+ }
+ return i * 4;
+}
+
+static AVInputFormat s302m_iformat = {
+ "302",
+ "SMPTE 302M format",
+ 0,
+ NULL,
+ s302m_header,
+ s302m_packet,
+ NULL,
+ NULL,
+ .extensions = "302",
+};
+
+int s302m_init(void)
+{
+ av_register_input_format(&s302m_iformat);
+ return 0;
+}
+
More information about the ffmpeg-devel
mailing list