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