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