[soc]: r5949 - in wtvmuxer: Makefile_diff.patch allformats_diff.patch wtvenc.c
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, +};
participants (1)
-
spyfeng