123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984 |
- //=====================================================================
- //
- // 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
|