• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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