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 // Note: the class cannot be used for reading and writing at the same time.
     12 #ifndef WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_UTILITY_H_
     13 #define WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_UTILITY_H_
     14 
     15 #include <stdio.h>
     16 
     17 #include "webrtc/common_types.h"
     18 #include "webrtc/modules/media_file/interface/media_file_defines.h"
     19 
     20 namespace webrtc {
     21 class AviFile;
     22 class InStream;
     23 class OutStream;
     24 
     25 class ModuleFileUtility
     26 {
     27 public:
     28 
     29     ModuleFileUtility(const int32_t id);
     30     ~ModuleFileUtility();
     31 
     32 #ifdef WEBRTC_MODULE_UTILITY_VIDEO
     33     // Open the file specified by fileName for reading (relative path is
     34     // allowed). If loop is true the file will be played until StopPlaying() is
     35     // called. When end of file is reached the file is read from the start.
     36     // Only video will be read if videoOnly is true.
     37     int32_t InitAviReading(const char* fileName, bool videoOnly, bool loop);
     38 
     39     // Put 10-60ms of audio data from file into the outBuffer depending on
     40     // codec frame size. bufferLengthInBytes indicates the size of outBuffer.
     41     // The return value is the number of bytes written to audioBuffer.
     42     // Note: This API only play mono audio but can be used on file containing
     43     // audio with more channels (in which case the audio will be coverted to
     44     // mono).
     45     int32_t ReadAviAudioData(int8_t* outBuffer,
     46                              const uint32_t bufferLengthInBytes);
     47 
     48     // Put one video frame into outBuffer. bufferLengthInBytes indicates the
     49     // size of outBuffer.
     50     // The return value is the number of bytes written to videoBuffer.
     51     int32_t ReadAviVideoData(int8_t* videoBuffer,
     52                              const uint32_t bufferLengthInBytes);
     53 
     54     // Open/create the file specified by fileName for writing audio/video data
     55     // (relative path is allowed). codecInst specifies the encoding of the audio
     56     // data. videoCodecInst specifies the encoding of the video data. Only video
     57     // data will be recorded if videoOnly is true.
     58     int32_t InitAviWriting(const char* filename,
     59                            const CodecInst& codecInst,
     60                            const VideoCodec& videoCodecInst,
     61                            const bool videoOnly);
     62 
     63     // Write one audio frame, i.e. the bufferLengthinBytes first bytes of
     64     // audioBuffer, to file. The audio frame size is determined by the
     65     // codecInst.pacsize parameter of the last sucessfull
     66     // InitAviWriting(..) call.
     67     // Note: bufferLength must be exactly one frame.
     68     int32_t WriteAviAudioData(const int8_t* audioBuffer,
     69                               uint32_t bufferLengthInBytes);
     70 
     71 
     72     // Write one video frame, i.e. the bufferLength first bytes of videoBuffer,
     73     // to file.
     74     // Note: videoBuffer can contain encoded data. The codec used must be the
     75     // same as what was specified by videoCodecInst for the last successfull
     76     // InitAviWriting(..) call. The videoBuffer must contain exactly
     77     // one video frame.
     78     int32_t WriteAviVideoData(const int8_t* videoBuffer,
     79                               uint32_t bufferLengthInBytes);
     80 
     81     // Stop recording to file or stream.
     82     int32_t CloseAviFile();
     83 
     84     int32_t VideoCodecInst(VideoCodec& codecInst);
     85 #endif // #ifdef WEBRTC_MODULE_UTILITY_VIDEO
     86 
     87     // Prepare for playing audio from stream.
     88     // startPointMs and stopPointMs, unless zero, specify what part of the file
     89     // should be read. From startPointMs ms to stopPointMs ms.
     90     int32_t InitWavReading(InStream& stream,
     91                            const uint32_t startPointMs = 0,
     92                            const uint32_t stopPointMs = 0);
     93 
     94     // Put 10-60ms of audio data from stream into the audioBuffer depending on
     95     // codec frame size. dataLengthInBytes indicates the size of audioBuffer.
     96     // The return value is the number of bytes written to audioBuffer.
     97     // Note: This API only play mono audio but can be used on file containing
     98     // audio with more channels (in which case the audio will be converted to
     99     // mono).
    100     int32_t ReadWavDataAsMono(InStream& stream, int8_t* audioBuffer,
    101                               const uint32_t dataLengthInBytes);
    102 
    103     // Put 10-60ms, depending on codec frame size, of audio data from file into
    104     // audioBufferLeft and audioBufferRight. The buffers contain the left and
    105     // right channel of played out stereo audio.
    106     // dataLengthInBytes  indicates the size of both audioBufferLeft and
    107     // audioBufferRight.
    108     // The return value is the number of bytes read for each buffer.
    109     // Note: This API can only be successfully called for WAV files with stereo
    110     // audio.
    111     int32_t ReadWavDataAsStereo(InStream& wav,
    112                                 int8_t* audioBufferLeft,
    113                                 int8_t* audioBufferRight,
    114                                 const uint32_t bufferLength);
    115 
    116     // Prepare for recording audio to stream.
    117     // codecInst specifies the encoding of the audio data.
    118     // Note: codecInst.channels should be set to 2 for stereo (and 1 for
    119     // mono). Stereo is only supported for WAV files.
    120     int32_t InitWavWriting(OutStream& stream, const CodecInst& codecInst);
    121 
    122     // Write one audio frame, i.e. the bufferLength first bytes of audioBuffer,
    123     // to file. The audio frame size is determined by the codecInst.pacsize
    124     // parameter of the last sucessfull StartRecordingAudioFile(..) call.
    125     // The return value is the number of bytes written to audioBuffer.
    126     int32_t WriteWavData(OutStream& stream,
    127                          const int8_t* audioBuffer,
    128                          const uint32_t bufferLength);
    129 
    130     // Finalizes the WAV header so that it is correct if nothing more will be
    131     // written to stream.
    132     // Note: this API must be called before closing stream to ensure that the
    133     //       WAVE header is updated with the file size. Don't call this API
    134     //       if more samples are to be written to stream.
    135     int32_t UpdateWavHeader(OutStream& stream);
    136 
    137     // Prepare for playing audio from stream.
    138     // startPointMs and stopPointMs, unless zero, specify what part of the file
    139     // should be read. From startPointMs ms to stopPointMs ms.
    140     // freqInHz is the PCM sampling frequency.
    141     // NOTE, allowed frequencies are 8000, 16000 and 32000 (Hz)
    142     int32_t InitPCMReading(InStream& stream,
    143                            const uint32_t startPointMs = 0,
    144                            const uint32_t stopPointMs = 0,
    145                            const uint32_t freqInHz = 16000);
    146 
    147     // Put 10-60ms of audio data from stream into the audioBuffer depending on
    148     // codec frame size. dataLengthInBytes indicates the size of audioBuffer.
    149     // The return value is the number of bytes written to audioBuffer.
    150     int32_t ReadPCMData(InStream& stream, int8_t* audioBuffer,
    151                         const uint32_t dataLengthInBytes);
    152 
    153     // Prepare for recording audio to stream.
    154     // freqInHz is the PCM sampling frequency.
    155     // NOTE, allowed frequencies are 8000, 16000 and 32000 (Hz)
    156     int32_t InitPCMWriting(OutStream& stream, const uint32_t freqInHz = 16000);
    157 
    158     // Write one 10ms audio frame, i.e. the bufferLength first bytes of
    159     // audioBuffer, to file. The audio frame size is determined by the freqInHz
    160     // parameter of the last sucessfull InitPCMWriting(..) call.
    161     // The return value is the number of bytes written to audioBuffer.
    162     int32_t WritePCMData(OutStream& stream,
    163                          const int8_t* audioBuffer,
    164                          uint32_t bufferLength);
    165 
    166     // Prepare for playing audio from stream.
    167     // startPointMs and stopPointMs, unless zero, specify what part of the file
    168     // should be read. From startPointMs ms to stopPointMs ms.
    169     int32_t InitCompressedReading(InStream& stream,
    170                                   const uint32_t startPointMs = 0,
    171                                   const uint32_t stopPointMs = 0);
    172 
    173     // Put 10-60ms of audio data from stream into the audioBuffer depending on
    174     // codec frame size. dataLengthInBytes indicates the size of audioBuffer.
    175     // The return value is the number of bytes written to audioBuffer.
    176     int32_t ReadCompressedData(InStream& stream,
    177                                int8_t* audioBuffer,
    178                                const uint32_t dataLengthInBytes);
    179 
    180     // Prepare for recording audio to stream.
    181     // codecInst specifies the encoding of the audio data.
    182     int32_t InitCompressedWriting(OutStream& stream,
    183                                   const CodecInst& codecInst);
    184 
    185     // Write one audio frame, i.e. the bufferLength first bytes of audioBuffer,
    186     // to file. The audio frame size is determined by the codecInst.pacsize
    187     // parameter of the last sucessfull InitCompressedWriting(..) call.
    188     // The return value is the number of bytes written to stream.
    189     // Note: bufferLength must be exactly one frame.
    190     int32_t WriteCompressedData(OutStream& stream,
    191                                 const int8_t* audioBuffer,
    192                                 const uint32_t bufferLength);
    193 
    194     // Prepare for playing audio from stream.
    195     // codecInst specifies the encoding of the audio data.
    196     int32_t InitPreEncodedReading(InStream& stream,
    197                                   const CodecInst& codecInst);
    198 
    199     // Put 10-60ms of audio data from stream into the audioBuffer depending on
    200     // codec frame size. dataLengthInBytes indicates the size of audioBuffer.
    201     // The return value is the number of bytes written to audioBuffer.
    202     int32_t ReadPreEncodedData(InStream& stream,
    203                                int8_t* audioBuffer,
    204                                const uint32_t dataLengthInBytes);
    205 
    206     // Prepare for recording audio to stream.
    207     // codecInst specifies the encoding of the audio data.
    208     int32_t InitPreEncodedWriting(OutStream& stream,
    209                                   const CodecInst& codecInst);
    210 
    211     // Write one audio frame, i.e. the bufferLength first bytes of audioBuffer,
    212     // to stream. The audio frame size is determined by the codecInst.pacsize
    213     // parameter of the last sucessfull InitPreEncodedWriting(..) call.
    214    // The return value is the number of bytes written to stream.
    215     // Note: bufferLength must be exactly one frame.
    216     int32_t WritePreEncodedData(OutStream& stream,
    217                                 const int8_t* inData,
    218                                 const uint32_t dataLengthInBytes);
    219 
    220     // Set durationMs to the size of the file (in ms) specified by fileName.
    221     // freqInHz specifies the sampling frequency of the file.
    222     int32_t FileDurationMs(const char* fileName,
    223                            const FileFormats fileFormat,
    224                            const uint32_t freqInHz = 16000);
    225 
    226     // Return the number of ms that have been played so far.
    227     uint32_t PlayoutPositionMs();
    228 
    229     // Update codecInst according to the current audio codec being used for
    230     // reading or writing.
    231     int32_t codec_info(CodecInst& codecInst);
    232 
    233 private:
    234     // Biggest WAV frame supported is 10 ms at 48kHz of 2 channel, 16 bit audio.
    235     enum{WAV_MAX_BUFFER_SIZE = 480*2*2};
    236 
    237 
    238     int32_t InitWavCodec(uint32_t samplesPerSec,
    239                          uint32_t channels,
    240                          uint32_t bitsPerSample,
    241                          uint32_t formatTag);
    242 
    243     // Parse the WAV header in stream.
    244     int32_t ReadWavHeader(InStream& stream);
    245 
    246     // Update the WAV header. freqInHz, bytesPerSample, channels, format,
    247     // lengthInBytes specify characterists of the audio data.
    248     // freqInHz is the sampling frequency. bytesPerSample is the sample size in
    249     // bytes. channels is the number of channels, e.g. 1 is mono and 2 is
    250     // stereo. format is the encode format (e.g. PCMU, PCMA, PCM etc).
    251     // lengthInBytes is the number of bytes the audio samples are using up.
    252     int32_t WriteWavHeader(OutStream& stream,
    253                            const uint32_t freqInHz,
    254                            const uint32_t bytesPerSample,
    255                            const uint32_t channels,
    256                            const uint32_t format,
    257                            const uint32_t lengthInBytes);
    258 
    259     // Put dataLengthInBytes of audio data from stream into the audioBuffer.
    260     // The return value is the number of bytes written to audioBuffer.
    261     int32_t ReadWavData(InStream& stream, uint8_t* audioBuffer,
    262                         const uint32_t dataLengthInBytes);
    263 
    264     // Update the current audio codec being used for reading or writing
    265     // according to codecInst.
    266     int32_t set_codec_info(const CodecInst& codecInst);
    267 
    268     struct WAVE_FMTINFO_header
    269     {
    270         int16_t formatTag;
    271         int16_t nChannels;
    272         int32_t nSamplesPerSec;
    273         int32_t nAvgBytesPerSec;
    274         int16_t nBlockAlign;
    275         int16_t nBitsPerSample;
    276     };
    277     // Identifiers for preencoded files.
    278     enum MediaFileUtility_CodecType
    279     {
    280         kCodecNoCodec  = 0,
    281         kCodecIsac,
    282         kCodecIsacSwb,
    283         kCodecIsacLc,
    284         kCodecL16_8Khz,
    285         kCodecL16_16kHz,
    286         kCodecL16_32Khz,
    287         kCodecPcmu,
    288         kCodecPcma,
    289         kCodecIlbc20Ms,
    290         kCodecIlbc30Ms,
    291         kCodecG722,
    292         kCodecG722_1_32Kbps,
    293         kCodecG722_1_24Kbps,
    294         kCodecG722_1_16Kbps,
    295         kCodecG722_1c_48,
    296         kCodecG722_1c_32,
    297         kCodecG722_1c_24,
    298         kCodecAmr,
    299         kCodecAmrWb,
    300         kCodecG729,
    301         kCodecG729_1,
    302         kCodecG726_40,
    303         kCodecG726_32,
    304         kCodecG726_24,
    305         kCodecG726_16,
    306         kCodecSpeex8Khz,
    307         kCodecSpeex16Khz
    308     };
    309 
    310     // TODO (hellner): why store multiple formats. Just store either codec_info_
    311     //                 or _wavFormatObj and supply conversion functions.
    312     WAVE_FMTINFO_header _wavFormatObj;
    313     int32_t _dataSize;      // Chunk size if reading a WAV file
    314     // Number of bytes to read. I.e. frame size in bytes. May be multiple
    315     // chunks if reading WAV.
    316     int32_t _readSizeBytes;
    317 
    318     int32_t _id;
    319 
    320     uint32_t _stopPointInMs;
    321     uint32_t _startPointInMs;
    322     uint32_t _playoutPositionMs;
    323     uint32_t _bytesWritten;
    324 
    325     CodecInst codec_info_;
    326     MediaFileUtility_CodecType _codecId;
    327 
    328     // The amount of bytes, on average, used for one audio sample.
    329     int32_t  _bytesPerSample;
    330     int32_t  _readPos;
    331 
    332     // Only reading or writing can be enabled, not both.
    333     bool _reading;
    334     bool _writing;
    335 
    336     // Scratch buffer used for turning stereo audio to mono.
    337     uint8_t _tempData[WAV_MAX_BUFFER_SIZE];
    338 
    339 #ifdef WEBRTC_MODULE_UTILITY_VIDEO
    340     AviFile* _aviAudioInFile;
    341     AviFile* _aviVideoInFile;
    342     AviFile* _aviOutFile;
    343     VideoCodec _videoCodec;
    344 #endif
    345 };
    346 }  // namespace webrtc
    347 #endif // WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_UTILITY_H_
    348