|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 |
|
6 #ifndef AUDIO_SESSION_H_ |
|
7 #define AUDIO_SESSION_H_ |
|
8 |
|
9 #include "mozilla/Attributes.h" |
|
10 #include "mozilla/TimeStamp.h" |
|
11 #include "nsTArray.h" |
|
12 |
|
13 #include "MediaConduitInterface.h" |
|
14 #include "MediaEngineWrapper.h" |
|
15 |
|
16 // Audio Engine Includes |
|
17 #include "webrtc/common_types.h" |
|
18 #include "webrtc/voice_engine/include/voe_base.h" |
|
19 #include "webrtc/voice_engine/include/voe_volume_control.h" |
|
20 #include "webrtc/voice_engine/include/voe_codec.h" |
|
21 #include "webrtc/voice_engine/include/voe_file.h" |
|
22 #include "webrtc/voice_engine/include/voe_network.h" |
|
23 #include "webrtc/voice_engine/include/voe_external_media.h" |
|
24 #include "webrtc/voice_engine/include/voe_audio_processing.h" |
|
25 #include "webrtc/voice_engine/include/voe_video_sync.h" |
|
26 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" |
|
27 //Some WebRTC types for short notations |
|
28 using webrtc::VoEBase; |
|
29 using webrtc::VoENetwork; |
|
30 using webrtc::VoECodec; |
|
31 using webrtc::VoEExternalMedia; |
|
32 using webrtc::VoEAudioProcessing; |
|
33 using webrtc::VoEVideoSync; |
|
34 using webrtc::VoERTP_RTCP; |
|
35 /** This file hosts several structures identifying different aspects |
|
36 * of a RTP Session. |
|
37 */ |
|
38 namespace mozilla { |
|
39 // Helper function |
|
40 |
|
41 DOMHighResTimeStamp |
|
42 NTPtoDOMHighResTimeStamp(uint32_t ntpHigh, uint32_t ntpLow); |
|
43 |
|
44 /** |
|
45 * Concrete class for Audio session. Hooks up |
|
46 * - media-source and target to external transport |
|
47 */ |
|
48 class WebrtcAudioConduit:public AudioSessionConduit |
|
49 ,public webrtc::Transport |
|
50 { |
|
51 public: |
|
52 //VoiceEngine defined constant for Payload Name Size. |
|
53 static const unsigned int CODEC_PLNAME_SIZE; |
|
54 |
|
55 /** |
|
56 * APIs used by the registered external transport to this Conduit to |
|
57 * feed in received RTP Frames to the VoiceEngine for decoding |
|
58 */ |
|
59 virtual MediaConduitErrorCode ReceivedRTPPacket(const void *data, int len); |
|
60 |
|
61 /** |
|
62 * APIs used by the registered external transport to this Conduit to |
|
63 * feed in received RTCP Frames to the VoiceEngine for decoding |
|
64 */ |
|
65 virtual MediaConduitErrorCode ReceivedRTCPPacket(const void *data, int len); |
|
66 |
|
67 /** |
|
68 * Function to configure send codec for the audio session |
|
69 * @param sendSessionConfig: CodecConfiguration |
|
70 * @result: On Success, the audio engine is configured with passed in codec for send |
|
71 * On failure, audio engine transmit functionality is disabled. |
|
72 * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting |
|
73 * transmission sub-system on the engine. |
|
74 */ |
|
75 virtual MediaConduitErrorCode ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig); |
|
76 /** |
|
77 * Function to configure list of receive codecs for the audio session |
|
78 * @param sendSessionConfig: CodecConfiguration |
|
79 * @result: On Success, the audio engine is configured with passed in codec for send |
|
80 * Also the playout is enabled. |
|
81 * On failure, audio engine transmit functionality is disabled. |
|
82 * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting |
|
83 * transmission sub-system on the engine. |
|
84 */ |
|
85 virtual MediaConduitErrorCode ConfigureRecvMediaCodecs( |
|
86 const std::vector<AudioCodecConfig* >& codecConfigList); |
|
87 /** |
|
88 * Function to enable the audio level extension |
|
89 * @param enabled: enable extension |
|
90 */ |
|
91 virtual MediaConduitErrorCode EnableAudioLevelExtension(bool enabled, uint8_t id); |
|
92 |
|
93 /** |
|
94 * Register External Transport to this Conduit. RTP and RTCP frames from the VoiceEngine |
|
95 * shall be passed to the registered transport for transporting externally. |
|
96 */ |
|
97 virtual MediaConduitErrorCode AttachTransport(mozilla::RefPtr<TransportInterface> aTransport); |
|
98 /** |
|
99 * Function to deliver externally captured audio sample for encoding and transport |
|
100 * @param audioData [in]: Pointer to array containing a frame of audio |
|
101 * @param lengthSamples [in]: Length of audio frame in samples in multiple of 10 milliseconds |
|
102 * Ex: Frame length is 160, 320, 440 for 16, 32, 44 kHz sampling rates |
|
103 respectively. |
|
104 audioData[] should be of lengthSamples in size |
|
105 say, for 16kz sampling rate, audioData[] should contain 160 |
|
106 samples of 16-bits each for a 10m audio frame. |
|
107 * @param samplingFreqHz [in]: Frequency/rate of the sampling in Hz ( 16000, 32000 ...) |
|
108 * @param capture_delay [in]: Approx Delay from recording until it is delivered to VoiceEngine |
|
109 in milliseconds. |
|
110 * NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can be invoked |
|
111 * This ensures the inserted audio-samples can be transmitted by the conduit |
|
112 * |
|
113 */ |
|
114 virtual MediaConduitErrorCode SendAudioFrame(const int16_t speechData[], |
|
115 int32_t lengthSamples, |
|
116 int32_t samplingFreqHz, |
|
117 int32_t capture_time); |
|
118 |
|
119 /** |
|
120 * Function to grab a decoded audio-sample from the media engine for rendering |
|
121 * / playoutof length 10 milliseconds. |
|
122 * |
|
123 * @param speechData [in]: Pointer to a array to which a 10ms frame of audio will be copied |
|
124 * @param samplingFreqHz [in]: Frequency of the sampling for playback in Hertz (16000, 32000,..) |
|
125 * @param capture_delay [in]: Estimated Time between reading of the samples to rendering/playback |
|
126 * @param lengthSamples [out]: Will contain length of the audio frame in samples at return. |
|
127 Ex: A value of 160 implies 160 samples each of 16-bits was copied |
|
128 into speechData |
|
129 * NOTE: This function should be invoked every 10 milliseconds for the best |
|
130 * peformance |
|
131 * NOTE: ConfigureRecvMediaCodec() SHOULD be called before this function can be invoked |
|
132 * This ensures the decoded samples are ready for reading and playout is enabled. |
|
133 * |
|
134 */ |
|
135 virtual MediaConduitErrorCode GetAudioFrame(int16_t speechData[], |
|
136 int32_t samplingFreqHz, |
|
137 int32_t capture_delay, |
|
138 int& lengthSamples); |
|
139 |
|
140 |
|
141 /** |
|
142 * Webrtc transport implementation to send and receive RTP packet. |
|
143 * AudioConduit registers itself as ExternalTransport to the VoiceEngine |
|
144 */ |
|
145 virtual int SendPacket(int channel, const void *data, int len) ; |
|
146 |
|
147 /** |
|
148 * Webrtc transport implementation to send and receive RTCP packet. |
|
149 * AudioConduit registers itself as ExternalTransport to the VoiceEngine |
|
150 */ |
|
151 virtual int SendRTCPPacket(int channel, const void *data, int len) ; |
|
152 |
|
153 |
|
154 |
|
155 WebrtcAudioConduit(): |
|
156 mOtherDirection(nullptr), |
|
157 mShutDown(false), |
|
158 mVoiceEngine(nullptr), |
|
159 mTransport(nullptr), |
|
160 mEngineTransmitting(false), |
|
161 mEngineReceiving(false), |
|
162 mChannel(-1), |
|
163 mCurSendCodecConfig(nullptr), |
|
164 mCaptureDelay(150), |
|
165 #ifdef MOZILLA_INTERNAL_API |
|
166 mLastTimestamp(0), |
|
167 #endif // MOZILLA_INTERNAL_API |
|
168 mSamples(0), |
|
169 mLastSyncLog(0) |
|
170 { |
|
171 } |
|
172 |
|
173 virtual ~WebrtcAudioConduit(); |
|
174 |
|
175 MediaConduitErrorCode Init(WebrtcAudioConduit *other); |
|
176 |
|
177 int GetChannel() { return mChannel; } |
|
178 webrtc::VoiceEngine* GetVoiceEngine() { return mVoiceEngine; } |
|
179 bool GetLocalSSRC(unsigned int* ssrc); |
|
180 bool GetRemoteSSRC(unsigned int* ssrc); |
|
181 bool GetAVStats(int32_t* jitterBufferDelayMs, |
|
182 int32_t* playoutBufferDelayMs, |
|
183 int32_t* avSyncOffsetMs); |
|
184 bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost); |
|
185 bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, |
|
186 uint32_t* jitterMs, |
|
187 uint32_t* packetsReceived, |
|
188 uint64_t* bytesReceived, |
|
189 uint32_t *cumulativeLost, |
|
190 int32_t* rttMs); |
|
191 bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, |
|
192 unsigned int* packetsSent, |
|
193 uint64_t* bytesSent); |
|
194 |
|
195 private: |
|
196 WebrtcAudioConduit(const WebrtcAudioConduit& other) MOZ_DELETE; |
|
197 void operator=(const WebrtcAudioConduit& other) MOZ_DELETE; |
|
198 |
|
199 //Local database of currently applied receive codecs |
|
200 typedef std::vector<AudioCodecConfig* > RecvCodecList; |
|
201 |
|
202 //Function to convert between WebRTC and Conduit codec structures |
|
203 bool CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo, |
|
204 webrtc::CodecInst& cinst); |
|
205 |
|
206 //Checks if given sampling frequency is supported |
|
207 bool IsSamplingFreqSupported(int freq) const; |
|
208 |
|
209 //Generate block size in sample lenght for a given sampling frequency |
|
210 unsigned int GetNum10msSamplesForFrequency(int samplingFreqHz) const; |
|
211 |
|
212 // Function to copy a codec structure to Conduit's database |
|
213 bool CopyCodecToDB(const AudioCodecConfig* codecInfo); |
|
214 |
|
215 // Functions to verify if the codec passed is already in |
|
216 // conduits database |
|
217 bool CheckCodecForMatch(const AudioCodecConfig* codecInfo) const; |
|
218 bool CheckCodecsForMatch(const AudioCodecConfig* curCodecConfig, |
|
219 const AudioCodecConfig* codecInfo) const; |
|
220 //Checks the codec to be applied |
|
221 MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send) const; |
|
222 |
|
223 //Utility function to dump recv codec database |
|
224 void DumpCodecDB() const; |
|
225 |
|
226 // The two sides of a send/receive pair of conduits each keep a pointer to the other. |
|
227 // The also share a single VoiceEngine and mChannel. Shutdown must be coordinated |
|
228 // carefully to avoid double-freeing or accessing after one frees. |
|
229 WebrtcAudioConduit* mOtherDirection; |
|
230 // Other side has shut down our channel and related items already |
|
231 bool mShutDown; |
|
232 |
|
233 // These are shared by both directions. They're released by the last |
|
234 // conduit to die |
|
235 webrtc::VoiceEngine* mVoiceEngine; |
|
236 mozilla::RefPtr<TransportInterface> mTransport; |
|
237 ScopedCustomReleasePtr<webrtc::VoENetwork> mPtrVoENetwork; |
|
238 ScopedCustomReleasePtr<webrtc::VoEBase> mPtrVoEBase; |
|
239 ScopedCustomReleasePtr<webrtc::VoECodec> mPtrVoECodec; |
|
240 ScopedCustomReleasePtr<webrtc::VoEExternalMedia> mPtrVoEXmedia; |
|
241 ScopedCustomReleasePtr<webrtc::VoEAudioProcessing> mPtrVoEProcessing; |
|
242 ScopedCustomReleasePtr<webrtc::VoEVideoSync> mPtrVoEVideoSync; |
|
243 ScopedCustomReleasePtr<webrtc::VoERTP_RTCP> mPtrVoERTP_RTCP; |
|
244 ScopedCustomReleasePtr<webrtc::VoERTP_RTCP> mPtrRTP; |
|
245 //engine states of our interets |
|
246 bool mEngineTransmitting; // If true => VoiceEngine Send-subsystem is up |
|
247 bool mEngineReceiving; // If true => VoiceEngine Receive-subsystem is up |
|
248 // and playout is enabled |
|
249 // Keep track of each inserted RTP block and the time it was inserted |
|
250 // so we can estimate the clock time for a specific TimeStamp coming out |
|
251 // (for when we send data to MediaStreamTracks). Blocks are aged out as needed. |
|
252 struct Processing { |
|
253 TimeStamp mTimeStamp; |
|
254 uint32_t mRTPTimeStamp; // RTP timestamps received |
|
255 }; |
|
256 nsAutoTArray<Processing,8> mProcessing; |
|
257 |
|
258 int mChannel; |
|
259 RecvCodecList mRecvCodecList; |
|
260 AudioCodecConfig* mCurSendCodecConfig; |
|
261 |
|
262 // Current "capture" delay (really output plus input delay) |
|
263 int32_t mCaptureDelay; |
|
264 |
|
265 #ifdef MOZILLA_INTERNAL_API |
|
266 uint32_t mLastTimestamp; |
|
267 #endif // MOZILLA_INTERNAL_API |
|
268 |
|
269 uint32_t mSamples; |
|
270 uint32_t mLastSyncLog; |
|
271 }; |
|
272 |
|
273 } // end namespace |
|
274 |
|
275 #endif |