[FFmpeg-soc] [soc]: r4545 - in spdif: checkout.sh ffmpeg.patch spdif.c todo
bwolowiec
subversion at mplayerhq.hu
Sun Jun 28 23:03:17 CEST 2009
Author: bwolowiec
Date: Sun Jun 28 23:03:17 2009
New Revision: 4545
Log:
initial commit
Added:
spdif/checkout.sh (contents, props changed)
spdif/ffmpeg.patch
spdif/spdif.c
spdif/todo
Added: spdif/checkout.sh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ spdif/checkout.sh Sun Jun 28 23:03:17 2009 (r4545)
@@ -0,0 +1,13 @@
+echo "checking out ffmpeg svn"
+for i in libavformat/allformats.c libavformat/Makefile libavformat/spdif.c; do
+ rm -f $i
+done
+svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk/ ffmpeg -r 19244
+echo "patching ffmpeg"
+cd ffmpeg
+patch -p0 <../ffmpeg.patch
+for i in spdif.c; do
+ rm -f libavformat/$i
+ ln -s ../../$i libavformat/$i
+done
+echo "Done, now just do a regular configure and make to build."
Added: spdif/ffmpeg.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ spdif/ffmpeg.patch Sun Jun 28 23:03:17 2009 (r4545)
@@ -0,0 +1,24 @@
+Index: libavformat/Makefile
+===================================================================
+--- libavformat/Makefile (wersja 19244)
++++ libavformat/Makefile (kopia robocza)
+@@ -206,6 +206,7 @@
+ OBJS-$(CONFIG_SOL_DEMUXER) += sol.o raw.o
+ OBJS-$(CONFIG_SOX_DEMUXER) += soxdec.o
+ OBJS-$(CONFIG_SOX_MUXER) += soxenc.o
++OBJS-$(CONFIG_SPDIF_MUXER) += spdif.o
+ OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o
+ OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o
+ OBJS-$(CONFIG_SWF_MUXER) += swfenc.o
+Index: libavformat/allformats.c
+===================================================================
+--- libavformat/allformats.c (wersja 19244)
++++ libavformat/allformats.c (kopia robocza)
+@@ -178,6 +178,7 @@
+ REGISTER_DEMUXER (SMACKER, smacker);
+ REGISTER_DEMUXER (SOL, sol);
+ REGISTER_MUXDEMUX (SOX, sox);
++ REGISTER_MUXER (SPDIF, spdif);
+ REGISTER_DEMUXER (STR, str);
+ REGISTER_MUXDEMUX (SWF, swf);
+ REGISTER_MUXER (TG2, tg2);
Added: spdif/spdif.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ spdif/spdif.c Sun Jun 28 23:03:17 2009 (r4545)
@@ -0,0 +1,186 @@
+/*
+ * IEC958 muxer
+ * Copyright (c) 2009 Bartlomiej Wolowiec
+ *
+ * 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
+ */
+
+#include "avformat.h"
+#include "libavcodec/ac3.h"
+#include "libavcodec/dca.h"
+
+#define SYNCWORD1 0xF872
+#define SYNCWORD2 0x4E1F
+#define BURST_HEADER_SIZE 0x8
+
+#define IEC958_AC3 0x01
+#define IEC958_MPEG1_LAYER1 0x04
+#define IEC958_MPEG1_LAYER23 0x05
+//#define IEC958_MPEG2_NO_EXT 0x05 /* No extension */
+//#define IEC958_MPEG2_EXT 0x06 /* With extension */
+//#define IEC958_MPEG2_AAC 0x07
+//#define IEC958_MPEG2_LAYER1_LSW 0x08 /* Low Sampling Frequency */
+//#define IEC958_MPEG2_LAYER2_LSW 0x09 /* Low Sampling Frequency */
+//#define IEC958_MPEG2_LAYER3_LSW 0x0A /* Low Sampling Frequency */
+#define IEC958_DTS1 0x0B
+#define IEC958_DTS2 0x0C
+#define IEC958_DTS3 0x0D
+//#define IEC958_EAC3 0x15
+
+typedef struct IEC958Context{
+ int data_type;
+ int pkt_size;
+ int pkt_offset; // bytes
+ int (*header_info)(AVFormatContext *s, AVPacket *pkt);
+} IEC958Context;
+
+static int spdif_header_ac3(AVFormatContext *s, AVPacket *pkt){
+ IEC958Context *ctx = s->priv_data;
+ int bitstream_mode = pkt->data[6] & 0x7;
+
+ ctx->data_type = IEC958_AC3 | (bitstream_mode << 8);
+ ctx->pkt_offset = AC3_FRAME_SIZE<<2;
+ return 0;
+}
+
+static int spdif_header_dts(AVFormatContext *s, AVPacket *pkt){
+ IEC958Context *ctx = s->priv_data;
+ uint32_t syncword_dts = (pkt->data[0] << 24) | (pkt->data[1]<<16) | (pkt->data[2]<<8) | pkt->data[3];
+ int samples;
+
+ if(syncword_dts != DCA_MARKER_RAW_BE){
+ av_log(NULL, AV_LOG_ERROR, "bad DTS syncword\n");
+ return -1;
+ }
+ samples = ((((pkt->data[4] & 0x01) << 6) | (pkt->data[5] >> 2)) + 1) << 5; // :)
+ av_log(NULL, AV_LOG_DEBUG, "samples=%i\n", samples);
+ switch(samples){
+ case 512:
+ ctx->data_type = IEC958_DTS1;
+ break;
+ case 1024:
+ ctx->data_type = IEC958_DTS2;
+ break;
+ case 2048:
+ ctx->data_type = IEC958_DTS3;
+ break;
+ default:
+ av_log(NULL, AV_LOG_ERROR, "%i samples in DTS frame not supported\n", samples);
+ return -1;
+ }
+ ctx->pkt_offset = samples<<2;
+
+ return 0;
+}
+
+static int spdif_header_mpeg1_layer1(AVFormatContext *s, AVPacket *pkt){
+ IEC958Context *ctx = s->priv_data;
+
+ ctx->data_type = IEC958_MPEG1_LAYER1;
+ ctx->pkt_offset = 384<<2; //TODO
+ return 0;
+}
+
+static int spdif_header_mpeg1_layer23(AVFormatContext *s, AVPacket *pkt){
+ IEC958Context *ctx = s->priv_data;
+
+ ctx->data_type = IEC958_MPEG1_LAYER23;
+ // TODO Data type dependant info (normal/karaoke, dynamic range control)
+ ctx->pkt_offset = 1152<<2; //TODO
+ return 0;
+}
+
+static int spdif_write_header(AVFormatContext *s){
+ IEC958Context *ctx = s->priv_data;
+
+ switch(s->streams[0]->codec->codec_id){
+ case CODEC_ID_AC3:
+ ctx->header_info = spdif_header_ac3;
+ break;
+ case CODEC_ID_MP1:
+ ctx->header_info = spdif_header_mpeg1_layer1;
+ break;
+ case CODEC_ID_MP2:
+ case CODEC_ID_MP3:
+ ctx->header_info = spdif_header_mpeg1_layer23;
+ break;
+ case CODEC_ID_DTS:
+ ctx->header_info = spdif_header_dts;
+ break;
+
+ default:
+ av_log(NULL, AV_LOG_ERROR, "codec not supported\n");
+ return -1;
+ }
+ put_le16(s->pb, 0);
+ put_le16(s->pb, 0);
+ put_le16(s->pb, 0);
+ put_le16(s->pb, 0);
+ return 0;
+}
+
+static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt){
+ IEC958Context *ctx = s->priv_data;
+ uint16_t *data = (uint16_t *)pkt->data;
+ int i;
+
+ ctx->pkt_size = pkt->size << 3;
+
+ (*ctx->header_info)(s, pkt);
+
+ put_le16(s->pb, SYNCWORD1); //Pa
+ put_le16(s->pb, SYNCWORD2); //Pb
+ put_le16(s->pb, ctx->data_type); //Pc
+ put_le16(s->pb, ctx->pkt_size); //Pd
+
+ //put_buffer(s->pb, pkt->data, pkt->size);
+ //XXX memcpy... ?
+ for(i=0; i<pkt->size>>1; i++)
+ put_be16(s->pb, data[i]); //XXX be?
+
+ if(pkt->size&1)
+ put_be16(s->pb, pkt->data[pkt->size-1]); //XXX be?
+
+ i=(ctx->pkt_offset - BURST_HEADER_SIZE - pkt->size) >> 1;
+ if(i < 0){
+ av_log(NULL, AV_LOG_ERROR, "bitrate is too high\n");
+ return -1;
+ }
+
+ for(; i>0; i--)
+ put_le16(s->pb, 0);
+
+ av_log(NULL, AV_LOG_DEBUG, "type=%x len=%i pkt_offset=%i\n", ctx->data_type, pkt->size, ctx->pkt_offset);
+
+ put_flush_packet(s->pb);
+ return 0;
+}
+
+AVOutputFormat spdif_muxer = {
+ "spdif",
+ NULL_IF_CONFIG_SMALL("IEC958 (IEC-61937)"),
+ NULL,
+ "spdif",
+ sizeof(IEC958Context),
+ CODEC_ID_AC3,
+ CODEC_ID_NONE,
+ spdif_write_header,
+ spdif_write_packet,
+ NULL,
+ //.flags=
+};
+
Added: spdif/todo
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ spdif/todo Sun Jun 28 23:03:17 2009 (r4545)
@@ -0,0 +1,21 @@
+-add support/test on big-endian machine ?
+
+-test AC3 - tested with TomorrowNeverDies-2.1-48khz-192kbit.ac3, Canyon-5.1-48khz-448kbit.ac3,
+ Broadway-5.1-48khz-448kbit.ac3 and FFmpeg AC3 encoder
+-test DTS - tested with (only RAW_BE version) 5.1 24bit.dts, ES 6.1 - 5.1 16bit.dts and FFmpeg DCA encoder
+
+-add support for little-endian DTS
+-add support for 14-bit DTS
+
+-add support for mpeg
+-add support for wma
+-add support for aac
+-add support for eac3
+
+-sending data stream direct to spdif
+
+-control latency
+-frequency sampling
+
+usage:
+./ffmpeg -y -i test_48khz.dts -acodec copy -f spdif test.spdif && ./ffmpeg -ar 48000 -f s16le -ac 2 -i test.spdif -f alsa plughw:0
More information about the FFmpeg-soc
mailing list