1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // Class for reading (x)or writing to an AVI file. 12 // Note: the class cannot be used for reading and writing at the same time. 13 #ifndef WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_ 14 #define WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_ 15 16 #include <stdio.h> 17 #include <list> 18 19 #include "webrtc/typedefs.h" 20 21 namespace webrtc { 22 class CriticalSectionWrapper; 23 24 struct AVISTREAMHEADER 25 { 26 AVISTREAMHEADER(); 27 uint32_t fcc; 28 uint32_t cb; 29 uint32_t fccType; 30 uint32_t fccHandler; 31 uint32_t dwFlags; 32 uint16_t wPriority; 33 uint16_t wLanguage; 34 uint32_t dwInitialFrames; 35 uint32_t dwScale; 36 uint32_t dwRate; 37 uint32_t dwStart; 38 uint32_t dwLength; 39 uint32_t dwSuggestedBufferSize; 40 uint32_t dwQuality; 41 uint32_t dwSampleSize; 42 struct 43 { 44 int16_t left; 45 int16_t top; 46 int16_t right; 47 int16_t bottom; 48 } rcFrame; 49 }; 50 51 struct BITMAPINFOHEADER 52 { 53 BITMAPINFOHEADER(); 54 uint32_t biSize; 55 uint32_t biWidth; 56 uint32_t biHeight; 57 uint16_t biPlanes; 58 uint16_t biBitCount; 59 uint32_t biCompression; 60 uint32_t biSizeImage; 61 uint32_t biXPelsPerMeter; 62 uint32_t biYPelsPerMeter; 63 uint32_t biClrUsed; 64 uint32_t biClrImportant; 65 }; 66 67 struct WAVEFORMATEX 68 { 69 WAVEFORMATEX(); 70 uint16_t wFormatTag; 71 uint16_t nChannels; 72 uint32_t nSamplesPerSec; 73 uint32_t nAvgBytesPerSec; 74 uint16_t nBlockAlign; 75 uint16_t wBitsPerSample; 76 uint16_t cbSize; 77 }; 78 79 class AviFile 80 { 81 public: 82 enum AVIStreamType 83 { 84 AVI_AUDIO = 0, 85 AVI_VIDEO = 1 86 }; 87 88 // Unsigned, for comparison with must-be-unsigned types. 89 static const unsigned int CODEC_CONFIG_LENGTH = 64; 90 static const unsigned int STREAM_NAME_LENGTH = 32; 91 92 AviFile(); 93 ~AviFile(); 94 95 int32_t Open(AVIStreamType streamType, const char* fileName, 96 bool loop = false); 97 98 int32_t CreateVideoStream(const AVISTREAMHEADER& videoStreamHeader, 99 const BITMAPINFOHEADER& bitMapInfoHeader, 100 const uint8_t* codecConfigParams, 101 int32_t codecConfigParamsLength); 102 103 int32_t CreateAudioStream(const AVISTREAMHEADER& audioStreamHeader, 104 const WAVEFORMATEX& waveFormatHeader); 105 int32_t Create(const char* fileName); 106 107 int32_t WriteAudio(const uint8_t* data, int32_t length); 108 int32_t WriteVideo(const uint8_t* data, int32_t length); 109 110 int32_t GetVideoStreamInfo(AVISTREAMHEADER& videoStreamHeader, 111 BITMAPINFOHEADER& bitmapInfo, 112 char* codecConfigParameters, 113 int32_t& configLength); 114 115 int32_t GetDuration(int32_t& durationMs); 116 117 int32_t GetAudioStreamInfo(WAVEFORMATEX& waveHeader); 118 119 int32_t ReadAudio(uint8_t* data, int32_t& length); 120 int32_t ReadVideo(uint8_t* data, int32_t& length); 121 122 int32_t Close(); 123 124 static uint32_t MakeFourCc(uint8_t ch0, uint8_t ch1, uint8_t ch2, 125 uint8_t ch3); 126 127 private: 128 enum AVIFileMode 129 { 130 NotSet, 131 Read, 132 Write 133 }; 134 135 struct AVIINDEXENTRY 136 { 137 AVIINDEXENTRY(uint32_t inckid, uint32_t indwFlags, 138 uint32_t indwChunkOffset, 139 uint32_t indwChunkLength); 140 uint32_t ckid; 141 uint32_t dwFlags; 142 uint32_t dwChunkOffset; 143 uint32_t dwChunkLength; 144 }; 145 146 int32_t PrepareDataChunkHeaders(); 147 148 int32_t ReadMoviSubChunk(uint8_t* data, int32_t& length, uint32_t tag1, 149 uint32_t tag2 = 0); 150 151 int32_t WriteRIFF(); 152 int32_t WriteHeaders(); 153 int32_t WriteAVIMainHeader(); 154 int32_t WriteAVIStreamHeaders(); 155 int32_t WriteAVIVideoStreamHeaders(); 156 int32_t WriteAVIVideoStreamHeaderChunks(); 157 int32_t WriteAVIAudioStreamHeaders(); 158 int32_t WriteAVIAudioStreamHeaderChunks(); 159 160 int32_t WriteMoviStart(); 161 162 size_t PutByte(uint8_t byte); 163 size_t PutLE16(uint16_t word); 164 size_t PutLE32(uint32_t word); 165 size_t PutBuffer(const uint8_t* str, size_t size); 166 size_t PutBufferZ(const char* str); 167 long PutLE32LengthFromCurrent(long startPos); 168 void PutLE32AtPos(long pos, uint32_t word); 169 170 size_t GetByte(uint8_t& word); 171 size_t GetLE16(uint16_t& word); 172 size_t GetLE32(uint32_t& word); 173 size_t GetBuffer(uint8_t* str, size_t size); 174 175 void CloseRead(); 176 void CloseWrite(); 177 178 void ResetMembers(); 179 void ResetComplexMembers(); 180 181 int32_t ReadRIFF(); 182 int32_t ReadHeaders(); 183 int32_t ReadAVIMainHeader(); 184 int32_t ReadAVIVideoStreamHeader(int32_t endpos); 185 int32_t ReadAVIAudioStreamHeader(int32_t endpos); 186 187 uint32_t StreamAndTwoCharCodeToTag(int32_t streamNum, 188 const char* twoCharCode); 189 190 void ClearIndexList(); 191 void AddChunkToIndexList(uint32_t inChunkId, uint32_t inFlags, 192 uint32_t inOffset, uint32_t inSize); 193 194 void WriteIndex(); 195 196 private: 197 typedef std::list<AVIINDEXENTRY*> IndexList; 198 struct AVIMAINHEADER 199 { 200 AVIMAINHEADER(); 201 uint32_t fcc; 202 uint32_t cb; 203 uint32_t dwMicroSecPerFrame; 204 uint32_t dwMaxBytesPerSec; 205 uint32_t dwPaddingGranularity; 206 uint32_t dwFlags; 207 uint32_t dwTotalFrames; 208 uint32_t dwInitialFrames; 209 uint32_t dwStreams; 210 uint32_t dwSuggestedBufferSize; 211 uint32_t dwWidth; 212 uint32_t dwHeight; 213 uint32_t dwReserved[4]; 214 }; 215 216 struct AVIStream 217 { 218 AVIStreamType streamType; 219 int streamNumber; 220 }; 221 222 CriticalSectionWrapper* _crit; 223 FILE* _aviFile; 224 AVIMAINHEADER _aviHeader; 225 AVISTREAMHEADER _videoStreamHeader; 226 AVISTREAMHEADER _audioStreamHeader; 227 BITMAPINFOHEADER _videoFormatHeader; 228 WAVEFORMATEX _audioFormatHeader; 229 230 int8_t _videoConfigParameters[CODEC_CONFIG_LENGTH]; 231 int32_t _videoConfigLength; 232 int8_t _videoStreamName[STREAM_NAME_LENGTH]; 233 int8_t _audioConfigParameters[CODEC_CONFIG_LENGTH]; 234 int8_t _audioStreamName[STREAM_NAME_LENGTH]; 235 236 AVIStream _videoStream; 237 AVIStream _audioStream; 238 239 int32_t _nrStreams; 240 int32_t _aviLength; 241 int32_t _dataLength; 242 size_t _bytesRead; 243 size_t _dataStartByte; 244 int32_t _framesRead; 245 int32_t _videoFrames; 246 int32_t _audioFrames; 247 248 bool _reading; 249 AVIStreamType _openedAs; 250 bool _loop; 251 bool _writing; 252 253 size_t _bytesWritten; 254 255 size_t _riffSizeMark; 256 size_t _moviSizeMark; 257 size_t _totNumFramesMark; 258 size_t _videoStreamLengthMark; 259 size_t _audioStreamLengthMark; 260 int32_t _moviListOffset; 261 262 bool _writeAudioStream; 263 bool _writeVideoStream; 264 265 AVIFileMode _aviMode; 266 uint8_t* _videoCodecConfigParams; 267 int32_t _videoCodecConfigParamsLength; 268 269 uint32_t _videoStreamDataChunkPrefix; 270 uint32_t _audioStreamDataChunkPrefix; 271 bool _created; 272 273 IndexList _indexList; 274 }; 275 } // namespace webrtc 276 277 #endif // WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_ 278