aboutsummaryrefslogtreecommitdiff
path: root/Src/libvp6/include/AVI.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/libvp6/include/AVI.hpp')
-rw-r--r--Src/libvp6/include/AVI.hpp984
1 files changed, 984 insertions, 0 deletions
diff --git a/Src/libvp6/include/AVI.hpp b/Src/libvp6/include/AVI.hpp
new file mode 100644
index 00000000..3860db89
--- /dev/null
+++ b/Src/libvp6/include/AVI.hpp
@@ -0,0 +1,984 @@
+//=====================================================================
+//
+// Copyright (c) 1999-2003 On2 Technologies Inc. All Rights Reserved.
+//
+//---------------------------------------------------------------------
+//
+// File: $Workfile: AVI.hpp$
+//
+// Date: $Date: 2010/07/23 19:10:47 $
+//
+// Revision: $Revision: 1.1 $
+//
+//---------------------------------------------------------------------
+
+#ifndef AVI_HPP
+#define AVI_HPP
+
+#pragma warning(disable:4786)
+
+#include "FourCC.hpp"
+#include <exception>
+#include <iosfwd>
+#include <list>
+#include <deque>
+#include <string>
+#include <vector>
+
+#if defined WIN32
+#include <windows.h>
+#endif
+
+namespace AVI
+{
+#if defined WIN32
+ typedef unsigned __int64 size_type;
+ typedef DWORD dword;
+ typedef __int64 offset_t;
+ typedef unsigned __int32 length_t;
+#elif defined LINUX
+ typedef unsigned long long size_type;
+ typedef unsigned long dword;
+ typedef long long offset_t;
+ typedef unsigned int length_t;
+#endif
+
+ int asStreamId(const FourCC&);
+
+ enum ChunkType
+ {
+ waveform,
+ waveform_encrypted,
+ DIB_compressed,
+ DIB_uncompressed,
+ DIB_encrypted,
+ kChunkTypeUnknown
+ };
+
+ ChunkType asChunkType(const FourCC&);
+
+ const FourCC asChunkId(int stream, ChunkType type);
+ const FourCC asIndexChunkExId(int stream);
+
+ size_type estimatedFileSize(
+ int width,
+ int height,
+ int frameCount);
+
+ const std::string offtoa(offset_t);
+
+ class FileError : public std::exception
+ {
+ public:
+ FileError(dword messageId);
+ FileError(const char* message);
+ ~FileError() throw();
+ const char* what() const throw();
+ dword id() const;
+ private:
+ std::string message;
+ dword m_id;
+ };
+
+
+
+ struct MainHeader
+ {
+ enum Flag
+ {
+ hasIndex = 0x00000010,
+ mustUseIndex = 0x00000020,
+ isInterleaved = 0x00000100,
+ indexIsAbsolute = 0x00000800, //? "trust cktype"
+ wasCaptureFile = 0x00010000,
+ copyrighted = 0x00020000
+ };
+
+ dword microSecPerFrame;
+ dword maxBytesPerSec;
+ dword paddingGranularity;
+ dword flags;
+ dword totalFrames;
+ dword initialFrames;
+ dword streams;
+ dword suggestedBufferSize;
+ dword width;
+ dword height;
+ dword reserved[4];
+
+ const std::string flagsAsStr() const;
+ };
+
+ std::ostream& operator<<(std::ostream&, const MainHeader&);
+
+
+ class Chunk
+ {
+ public:
+
+ Chunk(const FourCC, length_t, const unsigned char* data = 0);
+
+ const FourCC fcc() const;
+
+ length_t length() const;
+
+ const unsigned char* data() const;
+ unsigned char* data();
+
+ void data(const unsigned char* d);
+
+ private:
+ FourCC m_fcc;
+// length_t m_length;
+// unsigned char* m_data;
+
+ typedef std::vector<unsigned char> data_t;
+ data_t m_data;
+ };
+
+ std::ostream& operator<<(std::ostream& os, const Chunk&);
+
+ typedef std::vector<Chunk> ExtraHeaderVector;
+
+
+
+ struct Rectangle
+ {
+ typedef unsigned short T;
+
+ T left;
+ T top;
+ T right;
+ T bottom;
+
+ Rectangle()
+ : left(0), top(0), right(0), bottom(0)
+ {
+ }
+
+ Rectangle(T l, T t, T r, T b)
+ : left(l), top(t), right(r), bottom(b)
+ {
+ }
+ };
+
+
+ struct StreamHeader
+ {
+ enum Flag
+ {
+ disabled = 0x00000001,
+ formatChanges = 0x00010000
+ };
+
+ FourCC fccType;
+ FourCC fccHandler;
+ dword flags;
+ unsigned short priority;
+ unsigned short language;
+ dword initialFrames;
+ dword scale;
+ dword rate;
+ dword start;
+ dword length;
+ dword suggestedBufferSize;
+ long quality;
+ dword sampleSize;
+ Rectangle frame;
+
+ const std::string flagsAsStr() const;
+ };
+
+ std::ostream& operator<<(std::ostream&, const StreamHeader&);
+
+
+ struct BitmapInfoHeader
+ {
+ dword size;
+ long width;
+ long height;
+ unsigned short planes;
+ unsigned short bitCount;
+ FourCC compression;
+ dword sizeImage;
+ long xPelsPerMeter;
+ long yPelsPerMeter;
+ dword clrUsed;
+ dword clrImportant;
+ };
+
+ std::ostream& operator<<(std::ostream&, const BitmapInfoHeader&);
+
+
+// namespace Compression
+// {
+// enum CompressionType
+// {
+// RGB,
+// RLE8,
+// RLE4,
+// bitfields,
+// unknown
+// };
+//
+// bool operator==(CompressionType, const FourCC&);
+// bool operator==(const FourCC&, CompressionType);
+//
+// CompressionType asCompression(const FourCC&);
+// const FourCC asFourCC(CompressionType);
+//
+// std::ostream& operator<<(std::ostream&, CompressionType);
+// }
+
+
+ struct PCMWaveFormat
+ {
+ unsigned short formatTag;
+ unsigned short nChannels;
+ dword samplesPerSec;
+ dword avgBytesPerSec;
+ unsigned short blockAlign;
+ unsigned short bitsPerSample;
+ };
+
+ struct WaveFormatEx : public PCMWaveFormat
+ {
+ typedef std::vector<unsigned char> ByteArray;
+ ByteArray extra;
+ };
+
+ std::ostream& operator<<(std::ostream&, const WaveFormatEx&);
+
+
+
+
+ //not currently used; it's for palette changes,
+ //which isn't implemented yet
+ struct RGBQuad
+ {
+ unsigned char blue;
+ unsigned char green;
+ unsigned char red;
+ unsigned char reserved;
+ };
+
+
+ struct IndexEntry
+ {
+ enum Flags
+ {
+ list = 0x00000001,
+ keyframe = 0x00000010,
+ notime = 0x00000100,
+ compuse = 0x0FFF0000
+ };
+
+ FourCC chunkId;
+ dword flags;
+ dword chunkOffset;
+ dword chunkLength;
+
+ const std::string flagsAsStr() const;
+ };
+
+ std::ostream& operator<<(std::ostream&, const IndexEntry&);
+
+ typedef std::vector<IndexEntry> IEVector;
+
+
+ struct FrameIndexEntry
+ {
+ union
+ {
+ offset_t offset;
+
+ struct
+ {
+ unsigned long offset_low;
+ unsigned long offset_high;
+ };
+ };
+
+ size_t size;
+ bool keyframe;
+ };
+
+ typedef std::vector<FrameIndexEntry> FrameIEVector;
+ typedef std::list<FrameIndexEntry> FrameIEList;
+
+ typedef std::deque<FrameIndexEntry> FrameIndex;
+
+
+ struct IndexChunkEx
+ {
+ FourCC code;
+ unsigned long length;
+ unsigned short longsPerEntry;
+ unsigned char subtype;
+ unsigned char type;
+ unsigned long entriesInUse;
+ FourCC chunkId;
+ unsigned long reserved[3];
+ };
+
+ std::ostream& operator<<(std::ostream&, const IndexChunkEx&);
+
+
+ struct StandardIndexChunk
+ {
+ FourCC code;
+ unsigned long length;
+ unsigned short longsPerEntry;
+ unsigned char subtype;
+ unsigned char type;
+ unsigned long entriesInUse;
+ FourCC chunkId;
+ unsigned long baseOffset_low;
+ unsigned long baseOffset_high;
+ unsigned long reserved;
+
+ struct Entry
+ {
+ unsigned long offset;
+ unsigned long size;
+ } index[1];
+ };
+
+ std::ostream& operator<<(std::ostream&, const StandardIndexChunk&);
+ std::ostream& operator<<(std::ostream&, const StandardIndexChunk::Entry&);
+
+
+ struct SuperIndexChunk
+ {
+ FourCC code;
+ unsigned long length;
+ unsigned short longsPerEntry;
+ unsigned char subtype;
+ unsigned char type;
+ unsigned long entriesInUse;
+ FourCC chunkId;
+ unsigned long reserved[3];
+
+ struct Entry
+ {
+ offset_t offset;
+ unsigned long size;
+ unsigned long duration;
+ } index[1];
+ };
+
+ std::ostream& operator<<(std::ostream&, const SuperIndexChunk&);
+ std::ostream& operator<<(std::ostream&, const SuperIndexChunk::Entry&);
+
+
+ class File
+ {
+ public:
+
+ enum mode_t {in, out, inout};
+
+ enum OutputType
+ {
+ OT_AVI,
+ OT_On2
+ };
+
+ File();
+ File(const char* name, mode_t mode);
+
+ ~File();
+
+ void open(const char* name, mode_t mode, dword flags = 0);
+ void outputType(OutputType ot);
+
+ void close();
+
+ bool isOpen() const;
+ mode_t mode() const;
+ const char* name() const;
+
+ void mapinit();
+ void mapfinal();
+
+ unsigned long map(
+ offset_t offset,
+ length_t size,
+ unsigned char*& base,
+ length_t& baseSize,
+ length_t& offsetInView) const;
+
+ void unmap(unsigned char* base, length_t size) const;
+
+ const MainHeader& mainHeader() const;
+ MainHeader& mainHeader();
+
+ int extraHeaderCount() const;
+ const Chunk& extraHeader(int nChunk) const;
+
+ void extraHeader(FourCC fcc, length_t length, unsigned char* data);
+ void extraHeader(int nStream, FourCC fcc, length_t length, unsigned char* data);
+
+ dword totalFrames() const;
+ dword& totalFrames();
+
+ int streamCount() const;
+
+ int makeStreamHeaderVideo(int superIndexEntryCount = 0);
+ int makeStreamHeaderAudio(int superIndexEntryCount = 0);
+
+ const StreamHeader& streamHeader(int stream) const;
+ StreamHeader& streamHeader(int stream);
+
+ const unsigned char* strf(int nStream) const;
+ size_t strfSize(int nStream) const;
+
+ const BitmapInfoHeader& videoFormat(int stream) const;
+ BitmapInfoHeader& videoFormat(int stream);
+
+ const WaveFormatEx& audioFormat(int stream) const;
+ WaveFormatEx& audioFormat(int stream);
+
+ dword streamDataSize(int stream) const;
+ const unsigned char* streamData(int stream) const;
+ void setStreamData(int nStream, dword sds, const unsigned char* psd);
+
+ const char* streamName(int stream) const;
+ void setStreamName(int nStream, const char* psn);
+
+ SuperIndexChunk& superIndexChunk(int stream);
+ const SuperIndexChunk& superIndexChunk(int stream) const;
+
+ int superIndexEntryCount(int stream) const;
+
+ offset_t tell() const;
+
+ void seek(offset_t) const;
+
+ void seekCurrent(offset_t) const;
+
+ offset_t dataOffset() const;
+
+ offset_t idx1Offset() const;
+ length_t idx1Size() const;
+
+ void rewriteHeaders();
+ //For use by header updaters, throws if position of movi list
+ //changes, positions at beginning of data.
+
+ void seekMainHeader();
+ void writeMainHeader();
+
+ length_t seekStreamHeader(int stream);
+ void writeStreamHeader(int stream);
+
+ void seekVideoFormat(int stream);
+ void writeVideoFormat(int stream);
+
+ void seekAudioFormat(int stream);
+ void writeAudioFormat(int stream);
+
+ void seekStreamData(int stream);
+ void writeStreamData(int stream);
+
+ void seekSuperIndexChunk(int stream);
+ void writeSuperIndexChunk(int stream);
+
+ int indexCount() const;
+ void seekIndex() const;
+ void read(IndexEntry&) const;
+
+ void load(int stream, IEVector& index) const;
+ void load(int stream, FrameIndex& index) const;
+
+ void loadIndex(int, FrameIndex&) const;
+ void loadIndexEx(int, FrameIndex&) const;
+
+ void writeIndexChunkHeader(int number_of_index_entries);
+
+ void write(const IndexEntry&) const;
+
+ void writeIndexChunk(const IEVector& index);
+
+ void writeIndexChunk(
+ const FourCC& chunkId,
+ const FrameIndex& index);
+
+ void writeStandardIndexChunk(
+ int stream,
+ const FrameIndex& index,
+ offset_t baseOffset);
+
+ void writeStandardIndexChunk(
+ int stream,
+ const FrameIndex& index);
+
+ size_t makeSegment();
+ int segmentCount() const;
+ offset_t segmentOffset() const;
+
+ const FourCC readFourCC() const;
+ void writeFourCC(const FourCC&);
+
+ const FourCC testFourCC() const;
+
+ length_t readLength() const;
+ void writeLength(length_t length);
+
+ void read(void* buffer, size_t size) const;
+ void write(const void* data, size_t size, bool adjust = true);
+
+ void writeJunkChunk(length_t);
+
+ int countIndexEntries(int stream) const;
+
+ bool indexIsRelative() const;
+
+ offset_t size() const;
+
+ private:
+
+ File(const File& rhs);
+ File& operator=(const File& rhs);
+
+ //void readUnknownChunk() const;
+ void readJunkChunk() const;
+
+ bool readInit();
+ bool readHeaderList();
+ void readMainHeader();
+ void readExtraHeaders();
+ void readStreamHeaderList();
+ void readStreamHeader(StreamHeader& h);
+ void readStreamVideoFormat(BitmapInfoHeader& f);
+ struct StreamInfoVideo;
+ void readStreamVideoFormat(StreamInfoVideo* psiv);
+ void readStreamAudioFormat(WaveFormatEx& f);
+ void readStreamName(std::string& name);
+
+ void readExtendedAVIHeader();
+ void writeExtendedAVIHeader();
+
+ bool readDataList();
+ void readDataRecChunk() const;
+ void readDataChunk() const;
+
+ void readIndexList();
+
+ void writeInit();
+ void writeFinal();
+
+ void writeHeader();
+ void writeStreamHeaderList(int stream);
+ void writeStreamHeader(const StreamHeader& h);
+
+ void writeStreamVideoFormatChunk(const BitmapInfoHeader& f);
+ void writeStreamVideoFormat(const BitmapInfoHeader& f);
+
+ void writeStreamVideoFormatChunk(const unsigned char* pData, size_t sizeData);
+ void writeStreamVideoFormat(const unsigned char* pData, size_t sizeData);
+
+ void writeStreamAudioFormatChunk(const WaveFormatEx&);
+ void writeStreamAudioFormat(const WaveFormatEx&);
+
+ int headerLength() const;
+ int streamHeaderLength(int stream) const;
+
+ void load(const SuperIndexChunk::Entry&, FrameIndex&) const;
+
+ class handle_t
+ {
+ public:
+
+ handle_t();
+
+ void open(const char*, mode_t, dword) throw (FileError);
+ void close();
+
+ bool isOpen() const;
+ offset_t size() const;
+
+ void read(void*, size_t) const;
+ void write(const void*, size_t) const;
+
+ void truncate() const;
+
+ void seekCurrent(offset_t) const;
+ void seek(offset_t) const;
+
+ offset_t tell() const;
+
+ void mapinit();
+ void mapfinal();
+
+ unsigned long map(
+ offset_t offset,
+ length_t size,
+ unsigned char*& view,
+ length_t& viewSize,
+ length_t& offsetWithinView) const;
+
+ void unmap(unsigned char*, length_t) const;
+
+ private:
+#if defined WIN32
+ HANDLE m_hFile;
+ HANDLE m_hFileMappingObject;
+#elif defined LINUX
+ int m_fd;
+#endif
+ };
+
+ handle_t m_handle;
+
+ mode_t m_mode;
+
+ std::string m_name;
+
+ OutputType m_ot;
+
+ MainHeader m_mainHeader;
+
+ ExtraHeaderVector m_extraHeaderVector;
+
+ class indx_t
+ {
+ public:
+
+ indx_t();
+ indx_t(int entryCount);
+
+ ~indx_t();
+
+ int entryCount() const;
+
+ size_t size() const;
+
+ operator SuperIndexChunk&() const;
+
+ void read(File&);
+ void write(File&) const;
+
+ private:
+
+ indx_t(const indx_t&);
+ indx_t& operator=(const indx_t&);
+
+ dword* m_rep;
+
+ };
+
+ struct StreamInfo
+ {
+ virtual ~StreamInfo();
+
+ void write(File&) const;
+
+ int length() const;
+
+ StreamHeader header;
+
+ typedef std::vector<unsigned char> data_t;
+
+ data_t m_data;
+
+ std::string m_name;
+
+ ExtraHeaderVector m_extraHeaderVector;
+
+ indx_t m_indx;
+
+ protected:
+
+ StreamInfo(int);
+ StreamInfo(const StreamHeader&);
+
+ virtual int strf_length() const = 0;
+ virtual void strf_write(File&) const = 0;
+
+ private:
+
+ StreamInfo(const StreamInfo&);
+ StreamInfo& operator=(const StreamInfo&);
+
+ };
+
+ struct StreamInfoVideo : public StreamInfo
+ {
+ StreamInfoVideo(int entryCount);
+ StreamInfoVideo(const StreamHeader&);
+
+ ~StreamInfoVideo();
+
+// BitmapInfoHeader m_strf;
+ unsigned char* m_strf;
+ size_t m_strfSize;
+ protected:
+ int strf_length() const;
+ void strf_write(File&) const;
+ };
+
+ struct StreamInfoAudio : public StreamInfo
+ {
+ StreamInfoAudio(int entryCount);
+ StreamInfoAudio(const StreamHeader&);
+
+ WaveFormatEx m_strf;
+ protected:
+ int strf_length() const;
+ void strf_write(File&) const;
+ };
+
+ friend struct StreamInfo;
+ friend struct StreamInfoVideo;
+ friend struct StreamInfoAudio;
+
+ void readStreamData(StreamInfo::data_t&);
+
+ typedef std::vector<StreamInfo*> infoVector_t;
+ infoVector_t infoVector;
+
+ dword m_totalFrames;
+
+ offset_t m_dataPosn;
+
+ offset_t m_indexPosn;
+ int m_indexCount;
+ length_t m_idx1Size;
+
+ struct SegmentInfo
+ {
+ offset_t offset;
+ size_t size;
+
+ SegmentInfo() {}
+ SegmentInfo(offset_t offset_) : offset(offset_) {}
+ };
+
+ typedef std::vector<SegmentInfo> SegmentInfoVector;
+ SegmentInfoVector m_segmentInfo;
+ };
+
+#if defined WIN32
+ class MappedFile
+ {
+ public:
+
+ enum { invalid_offset = -1 };
+
+ MappedFile();
+ MappedFile(const char* name);
+
+ ~MappedFile();
+
+ void open(const char* name);
+ void close();
+
+ bool isOpen() const;
+ const char* name() const;
+
+ const MainHeader& mainHeader() const;
+
+ const StreamHeader& streamHeader(int stream) const;
+
+ const BitmapInfoHeader& videoFormat(int stream) const;
+
+ const WaveFormatEx& audioFormat(int stream) const;
+
+ const char* streamName(int stream) const;
+
+ dword totalFrames() const;
+
+ offset_t dataOffset() const;
+
+ offset_t indexOffset() const;
+ size_t indexSize() const;
+
+ offset_t indexChunkExOffset(int stream) const;
+ size_t indexChunkExSize(int stream) const;
+
+ const void* map(offset_t, size_t) const;
+ void unmap(const void*) const;
+
+ void load(int stream, FrameIEVector& index) const;
+
+ private:
+
+ MappedFile(const MappedFile&);
+ MappedFile& operator=(const MappedFile&);
+
+ void init();
+ void unmapAllViews();
+
+ offset_t offset() const;
+ void setFilePointerCurrent(LONG) const;
+
+ const FourCC readFourCC() const;
+ const FourCC queryFourCC() const;
+
+ dword readLength() const;
+
+ void readHeaderList();
+ void readDataList();
+ void readIndexList();
+ void readJunkChunk() const;
+ void readUnknownChunk() const;
+ void readMainHeaderChunk();
+ void readStreamHeaderList(int stream);
+ void readStreamHeaderChunk(StreamHeader&) const;
+ void readStreamVideoFormatChunk(BitmapInfoHeader&) const;
+ void readStreamAudioFormatChunk(WaveFormatEx&) const;
+ void readStreamNameChunk(std::string&) const;
+ void readIndexChunkEx(offset_t&, size_t&) const;
+ void readExtendedAVIHeaderList() const;
+
+ std::string m_name;
+
+ HANDLE m_file;
+ HANDLE m_fileMappingObject;
+
+ DWORD m_allocationGranularity;
+
+ MainHeader m_mainHeader;
+
+ struct StreamInfo
+ {
+ StreamHeader streamHeader;
+
+ union
+ {
+ BitmapInfoHeader* videoFormat;
+ WaveFormatEx* audioFormat;
+ };
+
+ std::string name;
+
+ offset_t indexChunkExOffset;
+ size_t indexChunkExSize;
+ };
+
+
+ typedef std::vector<StreamInfo> StreamInfoVector;
+ StreamInfoVector m_streamInfoVector;
+
+ size_t readChunkSize(offset_t) const;
+ int countEntries(int, const IndexEntry*, int) const;
+ int countEntries(const SuperIndexChunk&) const;
+ void loadIndex(int, FrameIEVector&) const;
+ void loadIndexEx(int, FrameIEVector&) const;
+ void load(const SuperIndexChunk::Entry&, FrameIEVector&) const;
+
+ mutable dword m_totalFrames;
+
+ offset_t m_dataOffset;
+
+ offset_t m_indexOffset;
+ size_t m_indexSize;
+
+ struct ViewInfo
+ {
+ unsigned char* pView;
+ unsigned char* pChunk;
+ };
+
+ typedef std::list<ViewInfo> Views;
+ mutable Views m_views;
+
+ Views::iterator findView(const void*) const;
+ };
+#endif
+
+}
+
+//inline HANDLE AVI::File::handle() const
+//{
+// return m_handle;
+//}
+
+inline AVI::Chunk::Chunk(
+ const FourCC fcc,
+ length_t length,
+ const unsigned char* d)
+ : m_fcc(fcc)
+{
+// if (m_length > 0)
+// {
+// m_data = new unsigned char[m_length];
+// if (m_data == 0)
+// {
+// throw FileError("Error allocating Chunk data.");
+// }
+// if (data != 0)
+// {
+// memcpy(m_data, data, m_length);
+// }
+// }
+
+ if (length)
+ {
+ if (d)
+ {
+ //typedef data_t::const_iterator iter_t;
+
+ //const iter_t first = iter_t(d);
+
+ //const data_t::size_type n = length;
+
+ //const iter_t last = first + n;
+
+ m_data.assign(d, d + length);
+ }
+ else
+ {
+ const data_t::size_type n = length;
+
+ m_data.assign(n, 0);
+ }
+ }
+ else
+ {
+ m_data.assign(data_t::size_type(0), 0);
+ }
+}
+
+inline const FourCC AVI::Chunk::fcc() const
+{
+ return m_fcc;
+}
+
+inline AVI::length_t AVI::Chunk::length() const
+{
+ const data_t::size_type n = m_data.size();
+
+ return n;
+}
+
+inline const unsigned char* AVI::Chunk::data() const
+{
+ return &m_data[0];
+}
+
+inline unsigned char* AVI::Chunk::data()
+{
+ return &m_data[0];
+}
+
+inline void AVI::Chunk::data(const unsigned char* d)
+{
+ //typedef data_t::const_iterator iter_t;
+
+ //const iter_t first = iter_t(d);
+
+ //const data_t::size_type n = m_data.size();
+
+ //const iter_t last = first + n;
+
+ m_data.assign(d, d + m_data.size());
+}
+
+inline AVI::dword AVI::FileError::id() const
+{
+ return m_id;
+}
+
+
+#endif