/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ // Class for reading (x)or writing to an AVI file. // Note: the class cannot be used for reading and writing at the same time. #ifndef WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_ #define WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_ #include #include "typedefs.h" namespace webrtc { class CriticalSectionWrapper; class ListWrapper; struct AVISTREAMHEADER { AVISTREAMHEADER(); WebRtc_UWord32 fcc; WebRtc_UWord32 cb; WebRtc_UWord32 fccType; WebRtc_UWord32 fccHandler; WebRtc_UWord32 dwFlags; WebRtc_UWord16 wPriority; WebRtc_UWord16 wLanguage; WebRtc_UWord32 dwInitialFrames; WebRtc_UWord32 dwScale; WebRtc_UWord32 dwRate; WebRtc_UWord32 dwStart; WebRtc_UWord32 dwLength; WebRtc_UWord32 dwSuggestedBufferSize; WebRtc_UWord32 dwQuality; WebRtc_UWord32 dwSampleSize; struct { WebRtc_Word16 left; WebRtc_Word16 top; WebRtc_Word16 right; WebRtc_Word16 bottom; } rcFrame; }; struct BITMAPINFOHEADER { BITMAPINFOHEADER(); WebRtc_UWord32 biSize; WebRtc_UWord32 biWidth; WebRtc_UWord32 biHeight; WebRtc_UWord16 biPlanes; WebRtc_UWord16 biBitCount; WebRtc_UWord32 biCompression; WebRtc_UWord32 biSizeImage; WebRtc_UWord32 biXPelsPerMeter; WebRtc_UWord32 biYPelsPerMeter; WebRtc_UWord32 biClrUsed; WebRtc_UWord32 biClrImportant; }; struct WAVEFORMATEX { WAVEFORMATEX(); WebRtc_UWord16 wFormatTag; WebRtc_UWord16 nChannels; WebRtc_UWord32 nSamplesPerSec; WebRtc_UWord32 nAvgBytesPerSec; WebRtc_UWord16 nBlockAlign; WebRtc_UWord16 wBitsPerSample; WebRtc_UWord16 cbSize; }; class AviFile { public: enum AVIStreamType { AVI_AUDIO = 0, AVI_VIDEO = 1 }; // Unsigned, for comparison with must-be-unsigned types. static const unsigned int CODEC_CONFIG_LENGTH = 64; static const unsigned int STREAM_NAME_LENGTH = 32; AviFile(); ~AviFile(); WebRtc_Word32 Open(AVIStreamType streamType, const char* fileName, bool loop = false); WebRtc_Word32 CreateVideoStream(const AVISTREAMHEADER& videoStreamHeader, const BITMAPINFOHEADER& bitMapInfoHeader, const WebRtc_UWord8* codecConfigParams, WebRtc_Word32 codecConfigParamsLength); WebRtc_Word32 CreateAudioStream(const AVISTREAMHEADER& audioStreamHeader, const WAVEFORMATEX& waveFormatHeader); WebRtc_Word32 Create(const char* fileName); WebRtc_Word32 WriteAudio(const WebRtc_UWord8* data, WebRtc_Word32 length); WebRtc_Word32 WriteVideo(const WebRtc_UWord8* data, WebRtc_Word32 length); WebRtc_Word32 GetVideoStreamInfo(AVISTREAMHEADER& videoStreamHeader, BITMAPINFOHEADER& bitmapInfo, char* codecConfigParameters, WebRtc_Word32& configLength); WebRtc_Word32 GetDuration(WebRtc_Word32& durationMs); WebRtc_Word32 GetAudioStreamInfo(WAVEFORMATEX& waveHeader); WebRtc_Word32 ReadAudio(WebRtc_UWord8* data, WebRtc_Word32& length); WebRtc_Word32 ReadVideo(WebRtc_UWord8* data, WebRtc_Word32& length); WebRtc_Word32 Close(); static WebRtc_UWord32 MakeFourCc(WebRtc_UWord8 ch0, WebRtc_UWord8 ch1, WebRtc_UWord8 ch2, WebRtc_UWord8 ch3); private: enum AVIFileMode { NotSet, Read, Write }; struct AVIINDEXENTRY { AVIINDEXENTRY(WebRtc_UWord32 inckid, WebRtc_UWord32 indwFlags, WebRtc_UWord32 indwChunkOffset, WebRtc_UWord32 indwChunkLength); WebRtc_UWord32 ckid; WebRtc_UWord32 dwFlags; WebRtc_UWord32 dwChunkOffset; WebRtc_UWord32 dwChunkLength; }; WebRtc_Word32 PrepareDataChunkHeaders(); WebRtc_Word32 ReadMoviSubChunk(WebRtc_UWord8* data, WebRtc_Word32& length, WebRtc_UWord32 tag1, WebRtc_UWord32 tag2 = 0); WebRtc_Word32 WriteRIFF(); WebRtc_Word32 WriteHeaders(); WebRtc_Word32 WriteAVIMainHeader(); WebRtc_Word32 WriteAVIStreamHeaders(); WebRtc_Word32 WriteAVIVideoStreamHeaders(); WebRtc_Word32 WriteAVIVideoStreamHeaderChunks(); WebRtc_Word32 WriteAVIAudioStreamHeaders(); WebRtc_Word32 WriteAVIAudioStreamHeaderChunks(); WebRtc_Word32 WriteMoviStart(); size_t PutByte(WebRtc_UWord8 byte); size_t PutLE16(WebRtc_UWord16 word); size_t PutLE32(WebRtc_UWord32 word); size_t PutBuffer(const WebRtc_UWord8* str, size_t size); size_t PutBufferZ(const char* str); long PutLE32LengthFromCurrent(long startPos); void PutLE32AtPos(long pos, WebRtc_UWord32 word); size_t GetByte(WebRtc_UWord8& word); size_t GetLE16(WebRtc_UWord16& word); size_t GetLE32(WebRtc_UWord32& word); size_t GetBuffer(WebRtc_UWord8* str, size_t size); void CloseRead(); void CloseWrite(); void ResetMembers(); void ResetComplexMembers(); WebRtc_Word32 ReadRIFF(); WebRtc_Word32 ReadHeaders(); WebRtc_Word32 ReadAVIMainHeader(); WebRtc_Word32 ReadAVIVideoStreamHeader(WebRtc_Word32 endpos); WebRtc_Word32 ReadAVIAudioStreamHeader(WebRtc_Word32 endpos); WebRtc_UWord32 StreamAndTwoCharCodeToTag(WebRtc_Word32 streamNum, const char* twoCharCode); void ClearIndexList(); void AddChunkToIndexList(WebRtc_UWord32 inChunkId, WebRtc_UWord32 inFlags, WebRtc_UWord32 inOffset, WebRtc_UWord32 inSize); void WriteIndex(); private: struct AVIMAINHEADER { AVIMAINHEADER(); WebRtc_UWord32 fcc; WebRtc_UWord32 cb; WebRtc_UWord32 dwMicroSecPerFrame; WebRtc_UWord32 dwMaxBytesPerSec; WebRtc_UWord32 dwPaddingGranularity; WebRtc_UWord32 dwFlags; WebRtc_UWord32 dwTotalFrames; WebRtc_UWord32 dwInitialFrames; WebRtc_UWord32 dwStreams; WebRtc_UWord32 dwSuggestedBufferSize; WebRtc_UWord32 dwWidth; WebRtc_UWord32 dwHeight; WebRtc_UWord32 dwReserved[4]; }; struct AVIStream { AVIStreamType streamType; int streamNumber; }; CriticalSectionWrapper* _crit; FILE* _aviFile; AVIMAINHEADER _aviHeader; AVISTREAMHEADER _videoStreamHeader; AVISTREAMHEADER _audioStreamHeader; BITMAPINFOHEADER _videoFormatHeader; WAVEFORMATEX _audioFormatHeader; WebRtc_Word8 _videoConfigParameters[CODEC_CONFIG_LENGTH]; WebRtc_Word32 _videoConfigLength; WebRtc_Word8 _videoStreamName[STREAM_NAME_LENGTH]; WebRtc_Word8 _audioConfigParameters[CODEC_CONFIG_LENGTH]; WebRtc_Word8 _audioStreamName[STREAM_NAME_LENGTH]; AVIStream _videoStream; AVIStream _audioStream; WebRtc_Word32 _nrStreams; WebRtc_Word32 _aviLength; WebRtc_Word32 _dataLength; size_t _bytesRead; size_t _dataStartByte; WebRtc_Word32 _framesRead; WebRtc_Word32 _videoFrames; WebRtc_Word32 _audioFrames; bool _reading; AVIStreamType _openedAs; bool _loop; bool _writing; size_t _bytesWritten; size_t _riffSizeMark; size_t _moviSizeMark; size_t _totNumFramesMark; size_t _videoStreamLengthMark; size_t _audioStreamLengthMark; WebRtc_Word32 _moviListOffset; bool _writeAudioStream; bool _writeVideoStream; AVIFileMode _aviMode; WebRtc_UWord8* _videoCodecConfigParams; WebRtc_Word32 _videoCodecConfigParamsLength; WebRtc_UWord32 _videoStreamDataChunkPrefix; WebRtc_UWord32 _audioStreamDataChunkPrefix; bool _created; ListWrapper* _indexList; // Elements are of type AVIINDEXENTRY. }; } // namespace webrtc #endif // WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_