Home | History | Annotate | Download | only in source
      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