[FFmpeg-soc] [soc]: r5949 - in wtvmuxer: Makefile_diff.patch allformats_diff.patch wtvenc.c
spyfeng
subversion at mplayerhq.hu
Sat Apr 16 11:32:11 CEST 2011
Author: spyfeng
Date: Sat Apr 16 11:32:11 2011
New Revision: 5949
Log:
add base version for WTV muxer.
Only complie passed, does not work.
Added:
wtvmuxer/Makefile_diff.patch
wtvmuxer/allformats_diff.patch
wtvmuxer/wtvenc.c
Added: wtvmuxer/Makefile_diff.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ wtvmuxer/Makefile_diff.patch Sat Apr 16 11:32:11 2011 (r5949)
@@ -0,0 +1,12 @@
+diff --git a/libavformat/Makefile b/libavformat/Makefile
+index c521cd3..f9a3830 100644
+--- a/libavformat/Makefile
++++ b/libavformat/Makefile
+@@ -296,6 +296,7 @@ OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \
+ OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood.o
+ OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood.o
+ OBJS-$(CONFIG_WTV_DEMUXER) += wtv.o asf.o asfdec.o mpegts.o riff.o
++OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o asf.o riff.o
+ OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o
+ OBJS-$(CONFIG_XA_DEMUXER) += xa.o
+ OBJS-$(CONFIG_YOP_DEMUXER) += yop.o
Added: wtvmuxer/allformats_diff.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ wtvmuxer/allformats_diff.patch Sat Apr 16 11:32:11 2011 (r5949)
@@ -0,0 +1,13 @@
+diff --git a/libavformat/allformats.c b/libavformat/allformats.c
+index bca968a..9440402 100644
+--- a/libavformat/allformats.c
++++ b/libavformat/allformats.c
+@@ -220,7 +220,7 @@ void av_register_all(void)
+ REGISTER_MUXER (WEBM, webm);
+ REGISTER_DEMUXER (WSAUD, wsaud);
+ REGISTER_DEMUXER (WSVQA, wsvqa);
+- REGISTER_DEMUXER (WTV, wtv);
++ REGISTER_MUXDEMUX (WTV, wtv);
+ REGISTER_DEMUXER (WV, wv);
+ REGISTER_DEMUXER (XA, xa);
+ REGISTER_DEMUXER (YOP, yop);
Added: wtvmuxer/wtvenc.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ wtvmuxer/wtvenc.c Sat Apr 16 11:32:11 2011 (r5949)
@@ -0,0 +1,236 @@
+/*
+ * WTV muxer
+ * Copyright (c) 2011 Zhentan Feng <spyfeng at gmail dot com>
+ *
+ * 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 "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "riff.h"
+#include "asf.h"
+//#include "mpegts.h"
+//#include <strings.h>
+
+#define WTV_SECTOR_BITS 12
+#define WTV_BIGSECTOR_BITS 18
+#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
+#define WTV_BIGSECTOR_SIZE (1 << WTV_BIGSECTOR_BITS)
+#define WTV_PAD8(x) (((x) + 7) & ~7)
+
+/* declare utf16le strings */
+#define _ , 0,
+static const uint8_t timeline_le16[] =
+ {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e', 0};
+#undef _
+
+static const ff_asf_guid wtv_guid =
+ {0xB7,0xD8,0x00,0x20,0x37,0x49,0xDA,0x11,0xA6,0x4E,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid sub_wtv_guid =
+ {0x8C,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid data_guid =
+ {0x95,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid dir_entry_guid =
+ {0x92,0xB7,0x74,0x91,0x59,0x70,0x70,0x44,0x88,0xDF,0x06,0x3B,0x82,0xCC,0x21,0x3D};
+
+typedef struct WtvContext {
+ int64_t init_root_pos;
+ int64_t sector_pos;
+ int64_t fat_table_pos;
+ int64_t timeline_start_pos;
+ int depth;
+} WtvContext;
+
+static int wtv_write_pad(AVIOContext *pb, int size)
+{
+ for(; size > 0; size--)
+ avio_w8(pb, 0);
+ return 0;
+}
+
+static void put_guid(AVIOContext *s, const ff_asf_guid *g)
+{
+ assert(sizeof(*g) == 16);
+ avio_write(s, *g, sizeof(*g));
+}
+
+static int wtv_write_header(AVFormatContext *s)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ put_guid(pb, &wtv_guid);
+ put_guid(pb, &sub_wtv_guid);
+ wtv_write_pad(pb, 16);
+
+ //write initial root fields
+ wctx->init_root_pos = avio_tell(pb);
+ avio_wl32(pb, 0); // root_size, update later
+ wtv_write_pad(pb, 4);
+ avio_wl32(pb, 0); // root_sector, update it later.
+ wctx->timeline_start_pos = avio_tell(pb);
+ return 0;
+}
+
+static int wtv_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIOContext *pb = s->pb;
+ int chunk_len = pkt->size + 32;
+
+ // write chunk header
+ put_guid(pb, &data_guid);
+ avio_wl32(pb, chunk_len);
+ avio_wl32(pb, pkt->stream_index);
+ wtv_write_pad(pb, 8);
+
+ // write packet data
+ avio_write(pb, pkt->data, pkt->size);
+
+ // write padding data
+ wtv_write_pad(pb, WTV_PAD8(chunk_len) - chunk_len);
+
+ avio_flush(pb);
+ return 0;
+}
+
+static int wtv_write_root_table(AVFormatContext *s)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int size, pad;
+
+ put_guid(pb, &dir_entry_guid);
+ avio_wl16(pb, 0); // dir_length, update later
+ avio_wl64(pb, 0); // file length, update later
+
+ avio_wl32(pb, sizeof(timeline_le16) >> 1); // name size
+ wtv_write_pad(pb, 4);
+ avio_write(pb, timeline_le16, sizeof(timeline_le16)); // name
+
+ avio_wl32(pb, wctx->fat_table_pos); // first sector pointer
+ avio_wl32(pb, wctx->depth); // depth
+
+ size = avio_tell(pb) - wctx->sector_pos;
+ pad = WTV_BIGSECTOR_SIZE- size;
+ wtv_write_pad(pb, pad);
+
+ return size;
+}
+
+static int wtv_write_sector(AVFormatContext *s, int nb_sectors, int depth)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int pad;
+
+ if(depth == 0) {
+ avio_wl32(pb, wctx->timeline_start_pos >> WTV_SECTOR_BITS);
+ } else if(depth == 1) {
+ int i = 0;
+ int64_t sector_pos = wctx->timeline_start_pos;
+ int sector_pointer;
+
+ // write sector pointer
+ for(; i < nb_sectors; i++) {
+ sector_pointer = sector_pos >> WTV_SECTOR_BITS;
+ avio_wl32(pb, sector_pointer);
+ sector_pos += 1 << WTV_BIGSECTOR_BITS;
+ }
+
+ // write left sector pointers
+ wtv_write_pad(pb, (WTV_SECTOR_SIZE >> 2) - nb_sectors);
+ } else if(depth == 2) {
+ // size is nb_sectors1 << WTV_SECTOR_BITS
+ // TODO
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (0x%x)\n", wctx->depth);
+ }
+
+ pad = WTV_BIGSECTOR_SIZE - (avio_tell(pb) - wctx->fat_table_pos);
+ wtv_write_pad(pb, pad);
+
+ return 0;
+}
+
+static int wtv_write_trailer(AVFormatContext *s)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int pad;
+ int depth;
+ int root_szie;
+ int file_len;
+
+ int64_t end_pos = avio_tell(pb);
+ int timeline_file_size = (end_pos - wctx->timeline_start_pos);
+ int nb_sectors = timeline_file_size >> WTV_BIGSECTOR_BITS;
+ pad = WTV_SECTOR_SIZE - (timeline_file_size % WTV_SECTOR_SIZE);
+ if (pad)
+ nb_sectors++;
+ wtv_write_pad(pb, pad);
+
+ // determine the depth of fat table
+ if (nb_sectors == 1) {
+ depth = 0;
+ } else if (nb_sectors > (WTV_SECTOR_SIZE >> 2)) {
+ depth = 2;
+ } else if (nb_sectors <= (WTV_SECTOR_SIZE << 2)) {
+ depth = 1;
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (0x%x)\n", depth);
+ return -1;
+ }
+
+ wctx->depth = depth;
+ // write fat table for data
+ wctx->fat_table_pos = avio_tell(pb);
+ wtv_write_sector(s, nb_sectors, depth);
+
+ // write root table
+ wctx->sector_pos = avio_tell(pb);
+ root_szie = wtv_write_root_table(s);
+
+ // calculate the file length
+ file_len = avio_tell(pb);
+ file_len = 1ULL<<63 | file_len; // use WTV_BIGSECTION_BITS
+
+ // update root value
+ avio_seek(pb, wctx->init_root_pos, SEEK_SET);
+ avio_wl32(pb + 16, root_szie);
+ avio_wl32(pb + 24, wctx->sector_pos >> WTV_SECTOR_BITS);
+
+ // update sector value
+ avio_seek(pb, wctx->sector_pos, SEEK_SET);
+ avio_wl32(pb + 16, root_szie);
+ avio_wl64(pb + 20, file_len);
+
+ return 0;
+}
+
+
+AVOutputFormat ff_wtv_muxer = {
+ "wtv",
+ NULL_IF_CONFIG_SMALL("Window TeleVision format"),
+ NULL,
+ "wtv",
+ sizeof(WtvContext),
+ CODEC_ID_PCM_S16LE,
+ CODEC_ID_MPEG2VIDEO,
+ wtv_write_header,
+ wtv_write_packet,
+ wtv_write_trailer,
+};
More information about the FFmpeg-soc
mailing list