277 lines
8.2 KiB
C++
277 lines
8.2 KiB
C++
/*
|
|
* 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
|
|
};
|
|
|
|
static const WebRtc_UWord32 CODEC_CONFIG_LENGTH = 64;
|
|
static const WebRtc_UWord32 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_
|