• 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 // 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