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 // This file contains a class that can write audio and/or video to file in 12 // multiple file formats. The unencoded input data is written to file in the 13 // encoded format specified. 14 15 #ifndef WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_ 16 #define WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_ 17 18 #include <list> 19 20 #include "webrtc/common_audio/resampler/include/resampler.h" 21 #include "webrtc/common_types.h" 22 #include "webrtc/engine_configurations.h" 23 #include "webrtc/modules/interface/module_common_types.h" 24 #include "webrtc/modules/media_file/interface/media_file.h" 25 #include "webrtc/modules/media_file/interface/media_file_defines.h" 26 #include "webrtc/modules/utility/interface/file_recorder.h" 27 #include "webrtc/modules/utility/source/coder.h" 28 #include "webrtc/system_wrappers/interface/event_wrapper.h" 29 #include "webrtc/system_wrappers/interface/thread_wrapper.h" 30 #include "webrtc/system_wrappers/interface/tick_util.h" 31 #include "webrtc/typedefs.h" 32 33 #ifdef WEBRTC_MODULE_UTILITY_VIDEO 34 #include "frame_scaler.h" 35 #include "video_coder.h" 36 #include "video_frames_queue.h" 37 #endif 38 39 namespace webrtc { 40 // The largest decoded frame size in samples (60ms with 32kHz sample rate). 41 enum { MAX_AUDIO_BUFFER_IN_SAMPLES = 60*32}; 42 enum { MAX_AUDIO_BUFFER_IN_BYTES = MAX_AUDIO_BUFFER_IN_SAMPLES*2}; 43 enum { kMaxAudioBufferQueueLength = 100 }; 44 45 class CriticalSectionWrapper; 46 47 class FileRecorderImpl : public FileRecorder 48 { 49 public: 50 FileRecorderImpl(uint32_t instanceID, FileFormats fileFormat); 51 virtual ~FileRecorderImpl(); 52 53 // FileRecorder functions. 54 virtual int32_t RegisterModuleFileCallback(FileCallback* callback); 55 virtual FileFormats RecordingFileFormat() const; 56 virtual int32_t StartRecordingAudioFile( 57 const char* fileName, 58 const CodecInst& codecInst, 59 uint32_t notificationTimeMs, 60 ACMAMRPackingFormat amrFormat = AMRFileStorage); 61 virtual int32_t StartRecordingAudioFile( 62 OutStream& destStream, 63 const CodecInst& codecInst, 64 uint32_t notificationTimeMs, 65 ACMAMRPackingFormat amrFormat = AMRFileStorage); 66 virtual int32_t StopRecording(); 67 virtual bool IsRecording() const; 68 virtual int32_t codec_info(CodecInst& codecInst) const; 69 virtual int32_t RecordAudioToFile( 70 const AudioFrame& frame, 71 const TickTime* playoutTS = NULL); 72 virtual int32_t StartRecordingVideoFile( 73 const char* fileName, 74 const CodecInst& audioCodecInst, 75 const VideoCodec& videoCodecInst, 76 ACMAMRPackingFormat amrFormat = AMRFileStorage, 77 bool videoOnly = false) 78 { 79 return -1; 80 } 81 virtual int32_t RecordVideoToFile(const I420VideoFrame& videoFrame) 82 { 83 return -1; 84 } 85 86 protected: 87 virtual int32_t WriteEncodedAudioData( 88 const int8_t* audioBuffer, 89 uint16_t bufferLength, 90 uint16_t millisecondsOfData, 91 const TickTime* playoutTS); 92 93 int32_t SetUpAudioEncoder(); 94 95 uint32_t _instanceID; 96 FileFormats _fileFormat; 97 MediaFile* _moduleFile; 98 99 private: 100 CodecInst codec_info_; 101 ACMAMRPackingFormat _amrFormat; 102 103 int8_t _audioBuffer[MAX_AUDIO_BUFFER_IN_BYTES]; 104 AudioCoder _audioEncoder; 105 Resampler _audioResampler; 106 }; 107 108 109 #ifdef WEBRTC_MODULE_UTILITY_VIDEO 110 class AudioFrameFileInfo 111 { 112 public: 113 AudioFrameFileInfo(const int8_t* audioData, 114 const uint16_t audioSize, 115 const uint16_t audioMS, 116 const TickTime& playoutTS) 117 : _audioData(), _audioSize(audioSize), _audioMS(audioMS), 118 _playoutTS(playoutTS) 119 { 120 if(audioSize > MAX_AUDIO_BUFFER_IN_BYTES) 121 { 122 assert(false); 123 _audioSize = 0; 124 return; 125 } 126 memcpy(_audioData, audioData, audioSize); 127 }; 128 // TODO (hellner): either turn into a struct or provide get/set functions. 129 int8_t _audioData[MAX_AUDIO_BUFFER_IN_BYTES]; 130 uint16_t _audioSize; 131 uint16_t _audioMS; 132 TickTime _playoutTS; 133 }; 134 135 class AviRecorder : public FileRecorderImpl 136 { 137 public: 138 AviRecorder(uint32_t instanceID, FileFormats fileFormat); 139 virtual ~AviRecorder(); 140 141 // FileRecorder functions. 142 virtual int32_t StartRecordingVideoFile( 143 const char* fileName, 144 const CodecInst& audioCodecInst, 145 const VideoCodec& videoCodecInst, 146 ACMAMRPackingFormat amrFormat = AMRFileStorage, 147 bool videoOnly = false); 148 virtual int32_t StopRecording(); 149 virtual int32_t RecordVideoToFile(const I420VideoFrame& videoFrame); 150 151 protected: 152 virtual int32_t WriteEncodedAudioData( 153 const int8_t* audioBuffer, 154 uint16_t bufferLength, 155 uint16_t millisecondsOfData, 156 const TickTime* playoutTS); 157 private: 158 typedef std::list<AudioFrameFileInfo*> AudioInfoList; 159 static bool Run(ThreadObj threadObj); 160 bool Process(); 161 162 bool StartThread(); 163 bool StopThread(); 164 165 int32_t EncodeAndWriteVideoToFile(I420VideoFrame& videoFrame); 166 int32_t ProcessAudio(); 167 168 int32_t CalcI420FrameSize() const; 169 int32_t SetUpVideoEncoder(); 170 171 VideoCodec _videoCodecInst; 172 bool _videoOnly; 173 174 AudioInfoList _audioFramesToWrite; 175 bool _firstAudioFrameReceived; 176 177 VideoFramesQueue* _videoFramesQueue; 178 179 FrameScaler* _frameScaler; 180 VideoCoder* _videoEncoder; 181 int32_t _videoMaxPayloadSize; 182 EncodedVideoData _videoEncodedData; 183 184 ThreadWrapper* _thread; 185 EventWrapper& _timeEvent; 186 CriticalSectionWrapper* _critSec; 187 int64_t _writtenVideoFramesCounter; 188 int64_t _writtenAudioMS; 189 int64_t _writtenVideoMS; 190 }; 191 #endif // WEBRTC_MODULE_UTILITY_VIDEO 192 } // namespace webrtc 193 #endif // WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_ 194