1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,275 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 + 1.9 +#ifndef AUDIO_SESSION_H_ 1.10 +#define AUDIO_SESSION_H_ 1.11 + 1.12 +#include "mozilla/Attributes.h" 1.13 +#include "mozilla/TimeStamp.h" 1.14 +#include "nsTArray.h" 1.15 + 1.16 +#include "MediaConduitInterface.h" 1.17 +#include "MediaEngineWrapper.h" 1.18 + 1.19 +// Audio Engine Includes 1.20 +#include "webrtc/common_types.h" 1.21 +#include "webrtc/voice_engine/include/voe_base.h" 1.22 +#include "webrtc/voice_engine/include/voe_volume_control.h" 1.23 +#include "webrtc/voice_engine/include/voe_codec.h" 1.24 +#include "webrtc/voice_engine/include/voe_file.h" 1.25 +#include "webrtc/voice_engine/include/voe_network.h" 1.26 +#include "webrtc/voice_engine/include/voe_external_media.h" 1.27 +#include "webrtc/voice_engine/include/voe_audio_processing.h" 1.28 +#include "webrtc/voice_engine/include/voe_video_sync.h" 1.29 +#include "webrtc/voice_engine/include/voe_rtp_rtcp.h" 1.30 +//Some WebRTC types for short notations 1.31 + using webrtc::VoEBase; 1.32 + using webrtc::VoENetwork; 1.33 + using webrtc::VoECodec; 1.34 + using webrtc::VoEExternalMedia; 1.35 + using webrtc::VoEAudioProcessing; 1.36 + using webrtc::VoEVideoSync; 1.37 + using webrtc::VoERTP_RTCP; 1.38 +/** This file hosts several structures identifying different aspects 1.39 + * of a RTP Session. 1.40 + */ 1.41 +namespace mozilla { 1.42 +// Helper function 1.43 + 1.44 +DOMHighResTimeStamp 1.45 +NTPtoDOMHighResTimeStamp(uint32_t ntpHigh, uint32_t ntpLow); 1.46 + 1.47 +/** 1.48 + * Concrete class for Audio session. Hooks up 1.49 + * - media-source and target to external transport 1.50 + */ 1.51 +class WebrtcAudioConduit:public AudioSessionConduit 1.52 + ,public webrtc::Transport 1.53 +{ 1.54 +public: 1.55 + //VoiceEngine defined constant for Payload Name Size. 1.56 + static const unsigned int CODEC_PLNAME_SIZE; 1.57 + 1.58 + /** 1.59 + * APIs used by the registered external transport to this Conduit to 1.60 + * feed in received RTP Frames to the VoiceEngine for decoding 1.61 + */ 1.62 + virtual MediaConduitErrorCode ReceivedRTPPacket(const void *data, int len); 1.63 + 1.64 + /** 1.65 + * APIs used by the registered external transport to this Conduit to 1.66 + * feed in received RTCP Frames to the VoiceEngine for decoding 1.67 + */ 1.68 + virtual MediaConduitErrorCode ReceivedRTCPPacket(const void *data, int len); 1.69 + 1.70 + /** 1.71 + * Function to configure send codec for the audio session 1.72 + * @param sendSessionConfig: CodecConfiguration 1.73 + * @result: On Success, the audio engine is configured with passed in codec for send 1.74 + * On failure, audio engine transmit functionality is disabled. 1.75 + * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting 1.76 + * transmission sub-system on the engine. 1.77 + */ 1.78 + virtual MediaConduitErrorCode ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig); 1.79 + /** 1.80 + * Function to configure list of receive codecs for the audio session 1.81 + * @param sendSessionConfig: CodecConfiguration 1.82 + * @result: On Success, the audio engine is configured with passed in codec for send 1.83 + * Also the playout is enabled. 1.84 + * On failure, audio engine transmit functionality is disabled. 1.85 + * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting 1.86 + * transmission sub-system on the engine. 1.87 + */ 1.88 + virtual MediaConduitErrorCode ConfigureRecvMediaCodecs( 1.89 + const std::vector<AudioCodecConfig* >& codecConfigList); 1.90 + /** 1.91 + * Function to enable the audio level extension 1.92 + * @param enabled: enable extension 1.93 + */ 1.94 + virtual MediaConduitErrorCode EnableAudioLevelExtension(bool enabled, uint8_t id); 1.95 + 1.96 + /** 1.97 + * Register External Transport to this Conduit. RTP and RTCP frames from the VoiceEngine 1.98 + * shall be passed to the registered transport for transporting externally. 1.99 + */ 1.100 + virtual MediaConduitErrorCode AttachTransport(mozilla::RefPtr<TransportInterface> aTransport); 1.101 + /** 1.102 + * Function to deliver externally captured audio sample for encoding and transport 1.103 + * @param audioData [in]: Pointer to array containing a frame of audio 1.104 + * @param lengthSamples [in]: Length of audio frame in samples in multiple of 10 milliseconds 1.105 + * Ex: Frame length is 160, 320, 440 for 16, 32, 44 kHz sampling rates 1.106 + respectively. 1.107 + audioData[] should be of lengthSamples in size 1.108 + say, for 16kz sampling rate, audioData[] should contain 160 1.109 + samples of 16-bits each for a 10m audio frame. 1.110 + * @param samplingFreqHz [in]: Frequency/rate of the sampling in Hz ( 16000, 32000 ...) 1.111 + * @param capture_delay [in]: Approx Delay from recording until it is delivered to VoiceEngine 1.112 + in milliseconds. 1.113 + * NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can be invoked 1.114 + * This ensures the inserted audio-samples can be transmitted by the conduit 1.115 + * 1.116 + */ 1.117 + virtual MediaConduitErrorCode SendAudioFrame(const int16_t speechData[], 1.118 + int32_t lengthSamples, 1.119 + int32_t samplingFreqHz, 1.120 + int32_t capture_time); 1.121 + 1.122 + /** 1.123 + * Function to grab a decoded audio-sample from the media engine for rendering 1.124 + * / playoutof length 10 milliseconds. 1.125 + * 1.126 + * @param speechData [in]: Pointer to a array to which a 10ms frame of audio will be copied 1.127 + * @param samplingFreqHz [in]: Frequency of the sampling for playback in Hertz (16000, 32000,..) 1.128 + * @param capture_delay [in]: Estimated Time between reading of the samples to rendering/playback 1.129 + * @param lengthSamples [out]: Will contain length of the audio frame in samples at return. 1.130 + Ex: A value of 160 implies 160 samples each of 16-bits was copied 1.131 + into speechData 1.132 + * NOTE: This function should be invoked every 10 milliseconds for the best 1.133 + * peformance 1.134 + * NOTE: ConfigureRecvMediaCodec() SHOULD be called before this function can be invoked 1.135 + * This ensures the decoded samples are ready for reading and playout is enabled. 1.136 + * 1.137 + */ 1.138 + virtual MediaConduitErrorCode GetAudioFrame(int16_t speechData[], 1.139 + int32_t samplingFreqHz, 1.140 + int32_t capture_delay, 1.141 + int& lengthSamples); 1.142 + 1.143 + 1.144 + /** 1.145 + * Webrtc transport implementation to send and receive RTP packet. 1.146 + * AudioConduit registers itself as ExternalTransport to the VoiceEngine 1.147 + */ 1.148 + virtual int SendPacket(int channel, const void *data, int len) ; 1.149 + 1.150 + /** 1.151 + * Webrtc transport implementation to send and receive RTCP packet. 1.152 + * AudioConduit registers itself as ExternalTransport to the VoiceEngine 1.153 + */ 1.154 + virtual int SendRTCPPacket(int channel, const void *data, int len) ; 1.155 + 1.156 + 1.157 + 1.158 + WebrtcAudioConduit(): 1.159 + mOtherDirection(nullptr), 1.160 + mShutDown(false), 1.161 + mVoiceEngine(nullptr), 1.162 + mTransport(nullptr), 1.163 + mEngineTransmitting(false), 1.164 + mEngineReceiving(false), 1.165 + mChannel(-1), 1.166 + mCurSendCodecConfig(nullptr), 1.167 + mCaptureDelay(150), 1.168 +#ifdef MOZILLA_INTERNAL_API 1.169 + mLastTimestamp(0), 1.170 +#endif // MOZILLA_INTERNAL_API 1.171 + mSamples(0), 1.172 + mLastSyncLog(0) 1.173 + { 1.174 + } 1.175 + 1.176 + virtual ~WebrtcAudioConduit(); 1.177 + 1.178 + MediaConduitErrorCode Init(WebrtcAudioConduit *other); 1.179 + 1.180 + int GetChannel() { return mChannel; } 1.181 + webrtc::VoiceEngine* GetVoiceEngine() { return mVoiceEngine; } 1.182 + bool GetLocalSSRC(unsigned int* ssrc); 1.183 + bool GetRemoteSSRC(unsigned int* ssrc); 1.184 + bool GetAVStats(int32_t* jitterBufferDelayMs, 1.185 + int32_t* playoutBufferDelayMs, 1.186 + int32_t* avSyncOffsetMs); 1.187 + bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost); 1.188 + bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, 1.189 + uint32_t* jitterMs, 1.190 + uint32_t* packetsReceived, 1.191 + uint64_t* bytesReceived, 1.192 + uint32_t *cumulativeLost, 1.193 + int32_t* rttMs); 1.194 + bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, 1.195 + unsigned int* packetsSent, 1.196 + uint64_t* bytesSent); 1.197 + 1.198 +private: 1.199 + WebrtcAudioConduit(const WebrtcAudioConduit& other) MOZ_DELETE; 1.200 + void operator=(const WebrtcAudioConduit& other) MOZ_DELETE; 1.201 + 1.202 + //Local database of currently applied receive codecs 1.203 + typedef std::vector<AudioCodecConfig* > RecvCodecList; 1.204 + 1.205 + //Function to convert between WebRTC and Conduit codec structures 1.206 + bool CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo, 1.207 + webrtc::CodecInst& cinst); 1.208 + 1.209 + //Checks if given sampling frequency is supported 1.210 + bool IsSamplingFreqSupported(int freq) const; 1.211 + 1.212 + //Generate block size in sample lenght for a given sampling frequency 1.213 + unsigned int GetNum10msSamplesForFrequency(int samplingFreqHz) const; 1.214 + 1.215 + // Function to copy a codec structure to Conduit's database 1.216 + bool CopyCodecToDB(const AudioCodecConfig* codecInfo); 1.217 + 1.218 + // Functions to verify if the codec passed is already in 1.219 + // conduits database 1.220 + bool CheckCodecForMatch(const AudioCodecConfig* codecInfo) const; 1.221 + bool CheckCodecsForMatch(const AudioCodecConfig* curCodecConfig, 1.222 + const AudioCodecConfig* codecInfo) const; 1.223 + //Checks the codec to be applied 1.224 + MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send) const; 1.225 + 1.226 + //Utility function to dump recv codec database 1.227 + void DumpCodecDB() const; 1.228 + 1.229 + // The two sides of a send/receive pair of conduits each keep a pointer to the other. 1.230 + // The also share a single VoiceEngine and mChannel. Shutdown must be coordinated 1.231 + // carefully to avoid double-freeing or accessing after one frees. 1.232 + WebrtcAudioConduit* mOtherDirection; 1.233 + // Other side has shut down our channel and related items already 1.234 + bool mShutDown; 1.235 + 1.236 + // These are shared by both directions. They're released by the last 1.237 + // conduit to die 1.238 + webrtc::VoiceEngine* mVoiceEngine; 1.239 + mozilla::RefPtr<TransportInterface> mTransport; 1.240 + ScopedCustomReleasePtr<webrtc::VoENetwork> mPtrVoENetwork; 1.241 + ScopedCustomReleasePtr<webrtc::VoEBase> mPtrVoEBase; 1.242 + ScopedCustomReleasePtr<webrtc::VoECodec> mPtrVoECodec; 1.243 + ScopedCustomReleasePtr<webrtc::VoEExternalMedia> mPtrVoEXmedia; 1.244 + ScopedCustomReleasePtr<webrtc::VoEAudioProcessing> mPtrVoEProcessing; 1.245 + ScopedCustomReleasePtr<webrtc::VoEVideoSync> mPtrVoEVideoSync; 1.246 + ScopedCustomReleasePtr<webrtc::VoERTP_RTCP> mPtrVoERTP_RTCP; 1.247 + ScopedCustomReleasePtr<webrtc::VoERTP_RTCP> mPtrRTP; 1.248 + //engine states of our interets 1.249 + bool mEngineTransmitting; // If true => VoiceEngine Send-subsystem is up 1.250 + bool mEngineReceiving; // If true => VoiceEngine Receive-subsystem is up 1.251 + // and playout is enabled 1.252 + // Keep track of each inserted RTP block and the time it was inserted 1.253 + // so we can estimate the clock time for a specific TimeStamp coming out 1.254 + // (for when we send data to MediaStreamTracks). Blocks are aged out as needed. 1.255 + struct Processing { 1.256 + TimeStamp mTimeStamp; 1.257 + uint32_t mRTPTimeStamp; // RTP timestamps received 1.258 + }; 1.259 + nsAutoTArray<Processing,8> mProcessing; 1.260 + 1.261 + int mChannel; 1.262 + RecvCodecList mRecvCodecList; 1.263 + AudioCodecConfig* mCurSendCodecConfig; 1.264 + 1.265 + // Current "capture" delay (really output plus input delay) 1.266 + int32_t mCaptureDelay; 1.267 + 1.268 +#ifdef MOZILLA_INTERNAL_API 1.269 + uint32_t mLastTimestamp; 1.270 +#endif // MOZILLA_INTERNAL_API 1.271 + 1.272 + uint32_t mSamples; 1.273 + uint32_t mLastSyncLog; 1.274 +}; 1.275 + 1.276 +} // end namespace 1.277 + 1.278 +#endif