blob: 5729cace578d1bba5bd6002be5a0da2baddda842 [file] [log] [blame]
/*
* Copyright (c) 2011 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 <stdio.h>
#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 WebRtc_Word8* 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,
WebRtc_Word8* 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();
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_Word32 _videoStreamNameLength;
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_